From eda34c1b3d590e46310930e2a08bbbf6e3d0ff7a Mon Sep 17 00:00:00 2001 From: sergeych Date: Wed, 7 Jan 2026 09:44:13 +0100 Subject: [PATCH] operators overriding missing files --- docs/samples/operator_overloading.lyng | 63 +++++++++++ .../sergeych/lyng/OperatorOverloadingTest.kt | 104 ++++++++++++++++++ 2 files changed, 167 insertions(+) create mode 100644 docs/samples/operator_overloading.lyng create mode 100644 lynglib/src/commonTest/kotlin/net/sergeych/lyng/OperatorOverloadingTest.kt diff --git a/docs/samples/operator_overloading.lyng b/docs/samples/operator_overloading.lyng new file mode 100644 index 0000000..b170c1b --- /dev/null +++ b/docs/samples/operator_overloading.lyng @@ -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) diff --git a/lynglib/src/commonTest/kotlin/net/sergeych/lyng/OperatorOverloadingTest.kt b/lynglib/src/commonTest/kotlin/net/sergeych/lyng/OperatorOverloadingTest.kt new file mode 100644 index 0000000..c4d1fee --- /dev/null +++ b/lynglib/src/commonTest/kotlin/net/sergeych/lyng/OperatorOverloadingTest.kt @@ -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()) + } +}