operators overriding missing files

This commit is contained in:
Sergey Chernov 2026-01-07 09:44:13 +01:00
parent 2c0a6c7b34
commit eda34c1b3d
2 changed files with 167 additions and 0 deletions

View File

@ -0,0 +1,63 @@
// Sample: Operator Overloading in Lyng
class Vector(val x, val y) {
// Overload +
fun plus(other) = Vector(x + other.x, y + other.y)
// Overload -
fun minus(other) = Vector(x - other.x, y - other.y)
// Overload unary -
fun negate() = Vector(-x, -y)
// Overload ==
fun equals(other) {
if (other is Vector) x == other.x && y == other.y
else false
}
// Overload * (scalar multiplication)
fun mul(scalar) = Vector(x * scalar, y * scalar)
override fun toString() = "Vector(${x}, ${y})"
}
val v1 = Vector(10, 20)
val v2 = Vector(5, 5)
println("v1: " + v1)
println("v2: " + v2)
// Test binary +
val v3 = v1 + v2
println("v1 + v2 = " + v3)
assertEquals(Vector(15, 25), v3)
// Test unary -
val v4 = -v1
println("-v1 = " + v4)
assertEquals(Vector(-10, -20), v4)
// Test scalar multiplication
val v5 = v1 * 2
println("v1 * 2 = " + v5)
assertEquals(Vector(20, 40), v5)
// Test += (falls back to plus)
var v6 = Vector(1, 1)
v6 += Vector(2, 2)
println("v6 += (2,2) -> " + v6)
assertEquals(Vector(3, 3), v6)
// Test in-place mutation with plusAssign
class Counter(var count) {
fun plusAssign(n) {
count = count + n
}
}
val c = Counter(0)
c += 10
c += 5
println("Counter: " + c.count)
assertEquals(15, c.count)

View File

@ -0,0 +1,104 @@
package net.sergeych.lyng
import kotlinx.coroutines.test.runTest
import kotlin.test.Test
class OperatorOverloadingTest {
@Test
fun testBinaryOverloading() = runTest {
eval("""
class Vector(x, y) {
fun plus(other) = Vector(this.x + other.x, this.y + other.y)
fun minus(other) = Vector(this.x - other.x, this.y - other.y)
fun equals(other) = this.x == other.x && this.y == other.y
override fun toString() = "Vector(" + this.x + ", " + this.y + ")"
}
val v1 = Vector(1, 2)
val v2 = Vector(3, 4)
val v3 = v1 + v2
assertEquals(Vector(4, 6), v3)
assertEquals(Vector(-2, -2), v1 - v2)
""".trimIndent())
}
@Test
fun testUnaryOverloading() = runTest {
eval("""
class Vector(x, y) {
fun negate() = Vector(-this.x, -this.y)
fun equals(other) = this.x == other.x && this.y == other.y
}
val v1 = Vector(1, 2)
assertEquals(Vector(-1, -2), -v1)
""".trimIndent())
}
@Test
fun testPlusAssignOverloading() = runTest {
eval("""
class Counter(n) {
fun plusAssign(x) { this.n = this.n + x }
}
val c = Counter(10)
c += 5
assertEquals(15, c.n)
""".trimIndent())
}
@Test
fun testPlusAssignFallback() = runTest {
eval("""
class Vector(x, y) {
fun plus(other) = Vector(this.x + other.x, this.y + other.y)
fun equals(other) = this.x == other.x && this.y == other.y
}
var v = Vector(1, 2)
v += Vector(3, 4)
assertEquals(Vector(4, 6), v)
""".trimIndent())
}
@Test
fun testCompareOverloading() = runTest {
eval("""
class Box(size) {
fun compareTo(other) = this.size - other.size
}
val b1 = Box(10)
val b2 = Box(20)
assertEquals(true, b1 < b2)
assertEquals(true, b2 > b1)
assertEquals(false, b1 > b2)
""".trimIndent())
}
@Test
fun testIncDecOverloading() = runTest {
eval("""
class Counter(n) {
fun plus(x) = Counter(this.n + x)
fun equals(other) = this.n == other.n
}
var c = Counter(10)
val oldC = c++
assertEquals(Counter(11), c)
assertEquals(Counter(10), oldC)
val newC = ++c
assertEquals(Counter(12), c)
assertEquals(Counter(12), newC)
""".trimIndent())
}
@Test
fun testContainsOverloading() = runTest {
eval("""
class MyRange(min, max) {
override fun contains(x) = x >= this.min && x <= this.max
}
val r = MyRange(1, 10)
assertEquals(true, 5 in r)
assertEquals(false, 15 in r)
""".trimIndent())
}
}