bugfix: elvis + throw

This commit is contained in:
Sergey Chernov 2025-08-18 01:19:49 +03:00
parent 95c1da60ed
commit fb6e2aa49e
2 changed files with 29 additions and 5 deletions

View File

@ -47,7 +47,7 @@ class Compiler(
private val codeContexts = mutableListOf<CodeContext>(CodeContext.Module(null)) private val codeContexts = mutableListOf<CodeContext>(CodeContext.Module(null))
private suspend fun <T>inCodeContext(context: CodeContext,f: suspend ()->T): T { private suspend fun <T> inCodeContext(context: CodeContext, f: suspend () -> T): T {
return try { return try {
codeContexts.add(context) codeContexts.add(context)
f() f()
@ -203,6 +203,10 @@ class Compiler(
val rvalue = parseExpressionLevel(level + 1) val rvalue = parseExpressionLevel(level + 1)
?: throw ScriptError(opToken.pos, "Expecting expression") ?: throw ScriptError(opToken.pos, "Expecting expression")
if( op.tokenType == Token.Type.ELVIS) {
println("elvis!!")
}
lvalue = op.generate(opToken.pos, lvalue!!, rvalue) lvalue = op.generate(opToken.pos, lvalue!!, rvalue)
} }
return lvalue return lvalue
@ -378,7 +382,9 @@ class Compiler(
"throw" -> { "throw" -> {
val s = parseThrowStatement() val s = parseThrowStatement()
operand = Accessor { s.execute(it).asReadonly } operand = Accessor {
s.execute(it).asReadonly
}
} }
else -> operand?.let { left -> else -> operand?.let { left ->
@ -1697,7 +1703,7 @@ class Compiler(
if (cc.current().type == Token.Type.COLON) parseTypeDeclaration() if (cc.current().type == Token.Type.COLON) parseTypeDeclaration()
return inCodeContext(CodeContext.Function(name)) { return inCodeContext(CodeContext.Function(name)) {
// Here we should be at open body // Here we should be at open body
val fnStatements = if (isExtern) val fnStatements = if (isExtern)
@ -1726,7 +1732,7 @@ class Compiler(
val fnCreateStatement = statement(start) { context -> val fnCreateStatement = statement(start) { context ->
// we added fn in the context. now we must save closure // we added fn in the context. now we must save closure
// for the function, unless we're in the class scope: // for the function, unless we're in the class scope:
if( isStatic || parentContext !is CodeContext.ClassBody) if (isStatic || parentContext !is CodeContext.ClassBody)
closure = context closure = context
val annotatedFnBody = annotation?.invoke(context, ObjString(name), fnBody) val annotatedFnBody = annotation?.invoke(context, ObjString(name), fnBody)
@ -1973,7 +1979,15 @@ class Compiler(
Operator.simple(Token.Type.IS, lastPriority) { _, a, b -> ObjBool(a.isInstanceOf(b)) }, Operator.simple(Token.Type.IS, lastPriority) { _, a, b -> ObjBool(a.isInstanceOf(b)) },
Operator.simple(Token.Type.NOTIS, lastPriority) { _, a, b -> ObjBool(!a.isInstanceOf(b)) }, Operator.simple(Token.Type.NOTIS, lastPriority) { _, a, b -> ObjBool(!a.isInstanceOf(b)) },
Operator.simple(Token.Type.ELVIS, ++lastPriority) { _, a, b -> if (a == ObjNull) b else a }, Operator(Token.Type.ELVIS, ++lastPriority, 2) { _: Pos, a: Accessor, b: Accessor ->
Accessor {
val aa = a.getter(it).value
(
if (aa != ObjNull) aa
else b.getter(it).value
).asReadonly
}
},
// shuttle <=> 6 // shuttle <=> 6
Operator.simple(Token.Type.SHUTTLE, ++lastPriority) { c, a, b -> Operator.simple(Token.Type.SHUTTLE, ++lastPriority) { c, a, b ->

View File

@ -2971,6 +2971,16 @@ class ScriptTest {
""".trimIndent()) """.trimIndent())
} }
@Test
fun testElvisAndThrow2() = runTest {
eval("""
val t = "112"
val x = t ?: run { throw "testx" }
}
assertEquals( "112", x)
""".trimIndent())
}
@Test @Test
fun testElvisAndRunThrow() = runTest { fun testElvisAndRunThrow() = runTest {
eval(""" eval("""