shuttle operator <=>

This commit is contained in:
Sergey Chernov 2025-06-04 08:29:09 +04:00
parent b331f4edaa
commit 75d90d7228
6 changed files with 68 additions and 8 deletions

View File

@ -16,6 +16,9 @@ fun naiveCountHappyNumbers() {
count count
} }
//
// After all optimizations it takes ~120ms.
//
val found = naiveCountHappyNumbers() val found = naiveCountHappyNumbers()
println("Found happy numbers: "+found) println("Found happy numbers: "+found)
assert( found == 55252 ) assert( found == 55252 )

View File

@ -749,9 +749,9 @@ class Compiler(
var result: Obj = ObjVoid var result: Obj = ObjVoid
val iVar = ObjInt(0) val iVar = ObjInt(0)
loopVar.value = iVar loopVar.value = iVar
for( i in start ..< end) { if( catchBreak) {
for (i in start..<end) {
iVar.value = i.toLong() iVar.value = i.toLong()
if (catchBreak)
try { try {
result = body.execute(forContext) result = body.execute(forContext)
} catch (lbe: LoopBreakContinueException) { } catch (lbe: LoopBreakContinueException) {
@ -760,7 +760,10 @@ class Compiler(
} }
return lbe.result return lbe.result
} }
else { }
} else {
for (i in start.toLong()..<end.toLong()) {
iVar.value = i
result = body.execute(forContext) result = body.execute(forContext)
} }
} }
@ -1181,6 +1184,8 @@ class Compiler(
Operator.simple(Token.Type.IS, lastPrty) { c, a, b -> ObjBool(a.isInstanceOf(b)) }, Operator.simple(Token.Type.IS, lastPrty) { c, a, b -> ObjBool(a.isInstanceOf(b)) },
Operator.simple(Token.Type.NOTIS, lastPrty) { c, a, b -> ObjBool(!a.isInstanceOf(b)) }, Operator.simple(Token.Type.NOTIS, lastPrty) { c, a, b -> ObjBool(!a.isInstanceOf(b)) },
// shuttle <=> 6 // shuttle <=> 6
Operator.simple(Token.Type.SHUTTLE, ++lastPrty) { c, a, b ->
ObjInt(a.compareTo(c, b).toLong()) },
// bit shifts 7 // bit shifts 7
Operator.simple(Token.Type.PLUS, ++lastPrty) { ctx, a, b -> a.plus(ctx, b) }, Operator.simple(Token.Type.PLUS, ++lastPrty) { ctx, a, b -> a.plus(ctx, b) },
Operator.simple(Token.Type.MINUS, lastPrty) { ctx, a, b -> a.minus(ctx, b) }, Operator.simple(Token.Type.MINUS, lastPrty) { ctx, a, b -> a.minus(ctx, b) },

View File

@ -153,7 +153,13 @@ private class Parser(fromPos: Pos) {
'<' -> { '<' -> {
if (currentChar == '=') { if (currentChar == '=') {
pos.advance() pos.advance()
if( currentChar == '>' ) {
pos.advance()
Token("<=>", from, Token.Type.SHUTTLE)
}
else {
Token("<=", from, Token.Type.LTE) Token("<=", from, Token.Type.LTE)
}
} else } else
Token("<", from, Token.Type.LT) Token("<", from, Token.Type.LT)
} }

View File

@ -13,6 +13,7 @@ data class Token(val value: String, val pos: Pos, val type: Type) {
PLUS2, MINUS2, PLUS2, MINUS2,
IN, NOTIN, IS, NOTIS, IN, NOTIN, IS, NOTIS,
EQ, NEQ, LT, LTE, GT, GTE, REF_EQ, REF_NEQ, EQ, NEQ, LT, LTE, GT, GTE, REF_EQ, REF_NEQ,
SHUTTLE,
AND, BITAND, OR, BITOR, NOT, BITNOT, DOT, ARROW, QUESTION, COLONCOLON, AND, BITAND, OR, BITOR, NOT, BITNOT, DOT, ARROW, QUESTION, COLONCOLON,
SINLGE_LINE_COMMENT, MULTILINE_COMMENT, SINLGE_LINE_COMMENT, MULTILINE_COMMENT,
LABEL, ATLABEL, // label@ at@label LABEL, ATLABEL, // label@ at@label

View File

@ -1192,6 +1192,52 @@ class ScriptTest {
fna(5,6) fna(5,6)
""" """
) )
}
@Test
fun testSpoilLamdaArgsBug() = runTest {
eval(
"""
val fnb = { a,b -> a + b }
val fna = { a, b ->
val a0 = a
val b0 = b
fnb(a + 1, b + 1)
assert( a0 == a )
assert( b0 == b )
}
fna(5,6)
"""
)
}
@Test
fun commentBlocksShouldNotAlterBehavior() = runTest {
eval(
"""
fun test() {
10
/*
*/
//val x = 11
}
assert( test() == 10 )
""".trimIndent()
)
}
@Test
fun testShuttle() = runTest {
eval(
"""
assert( 5 <=> 3 > 0 )
assert( 0 < 5 <=> 3 )
assert( 5 <=> 5 == 0 )
assert( 5 <=> 7 < 0 )
""".trimIndent()
)
} }
} }

View File

@ -14,13 +14,12 @@ suspend fun executeSampleTests(fileName: String) {
} }
runBlocking { runBlocking {
val c = Context() val c = Context()
for( i in 1..1) {
val start = Clock.System.now() val start = Clock.System.now()
c.eval(sample) c.eval(sample)
val time = Clock.System.now() - start val time = Clock.System.now() - start
println("$time: $fileName") println("$time: $fileName")
// delay(100) // delay(100)
} // }
} }
} }