fix #39 correct implementation of ++ and -- with indexing access

This commit is contained in:
sergeych committed 2025-07-10 15:54:53 +03:00
1 parent f1ae4b2d23
commit 5848adca61
8 files changed
+90 -36

No files matched your search

@@ -12,10 +12,6 @@ class Compiler(
settings: Settings = Settings()
) {
init {
println("Compiler initialized: $importManager")
}
var packageName: String? = null
class Settings
@@ -27,7 +23,7 @@ class Compiler(
// package level declarations
do {
val t = cc.current()
if(t.type == Token.Type.NEWLINE || t.type == Token.Type.SINLGE_LINE_COMMENT || t.type == Token.Type.MULTILINE_COMMENT) {
if (t.type == Token.Type.NEWLINE || t.type == Token.Type.SINLGE_LINE_COMMENT || t.type == Token.Type.MULTILINE_COMMENT) {
cc.next()
continue
}
@@ -44,6 +40,7 @@ class Compiler(
packageName = name
continue
}
"import" -> {
cc.next()
val pos = cc.currentPos()
@@ -349,17 +346,26 @@ class Compiler(
left.setter(startPos)
operand = Accessor { cxt ->
val x = left.getter(cxt)
if (x.isMutable)
x.value.getAndIncrement(cxt).asReadonly
else cxt.raiseError("Cannot increment immutable value")
if (x.isMutable) {
if (x.value.isConst) {
x.value.plus(cxt, ObjInt.One).also {
left.setter(startPos)(cxt, it)
}.asReadonly
} else
x.value.getAndIncrement(cxt).asReadonly
} else cxt.raiseError("Cannot increment immutable value")
}
} ?: run {
// no lvalue means pre-increment, expression to increment follows
val next = parseAccessor() ?: throw ScriptError(t.pos, "Expecting expression")
val next = parseTerm() ?: throw ScriptError(t.pos, "Expecting expression")
operand = Accessor { ctx ->
next.getter(ctx).also {
val x = next.getter(ctx).also {
if (!it.isMutable) ctx.raiseError("Cannot increment immutable value")
}.value.incrementAndGet(ctx).asReadonly
}.value
if (x.isConst) {
next.setter(startPos)(ctx, x.plus(ctx, ObjInt.One))
x.asReadonly
} else x.incrementAndGet(ctx).asReadonly
}
}
}
@@ -369,18 +375,28 @@ class Compiler(
operand?.let { left ->
// post decrement
left.setter(startPos)
operand = Accessor { ctx ->
left.getter(ctx).also {
if (!it.isMutable) ctx.raiseError("Cannot decrement immutable value")
}.value.getAndDecrement(ctx).asReadonly
operand = Accessor { cxt ->
val x = left.getter(cxt)
if (!x.isMutable) cxt.raiseError("Cannot decrement immutable value")
if (x.value.isConst) {
x.value.minus(cxt, ObjInt.One).also {
left.setter(startPos)(cxt, it)
}.asReadonly
} else
x.value.getAndDecrement(cxt).asReadonly
}
} ?: run {
// no lvalue means pre-decrement, expression to decrement follows
val next = parseAccessor() ?: throw ScriptError(t.pos, "Expecting expression")
operand = Accessor { ctx ->
next.getter(ctx).also {
if (!it.isMutable) ctx.raiseError("Cannot decrement immutable value")
}.value.decrementAndGet(ctx).asReadonly
val next = parseTerm() ?: throw ScriptError(t.pos, "Expecting expression")
operand = Accessor { cxt ->
val x = next.getter(cxt)
if (!x.isMutable) cxt.raiseError("Cannot decrement immutable value")
if (x.value.isConst) {
x.value.minus(cxt, ObjInt.One).also {
next.setter(startPos)(cxt, it)
}.asReadonly
} else
x.value.decrementAndGet(cxt).asReadonly
}
}
}
@@ -1623,8 +1639,8 @@ class Compiler(
companion object {
suspend fun compile(source: Source,importManager: ImportProvider): Script {
return Compiler(CompilerContext(parseLyng(source)),importManager).parseScript()
suspend fun compile(source: Source, importManager: ImportProvider): Script {
return Compiler(CompilerContext(parseLyng(source)), importManager).parseScript()
}
private var lastPriority = 0
@@ -48,6 +48,12 @@ data class Accessor(
open class Obj {
open val isConst: Boolean = false
fun ensureNotConst(scope: Scope) {
if( isConst ) scope.raiseError("can't assign to constant")
}
val isNull by lazy { this === ObjNull }
var isFrozen: Boolean = false
@@ -82,7 +82,6 @@ open class ObjClass(
override suspend fun readField(scope: Scope, name: String): ObjRecord {
classMembers[name]?.let {
println("class field $it")
return it
}
return super.readField(scope, name)
@@ -1,6 +1,6 @@
package net.sergeych.lyng
class ObjInt(var value: Long,val isConst: Boolean = false) : Obj(), Numeric {
class ObjInt(var value: Long,override val isConst: Boolean = false) : Obj(), Numeric {
override val asStr get() = ObjString(value.toString())
override val longValue get() = value
override val doubleValue get() = value.toDouble()
@@ -14,18 +14,22 @@ class ObjInt(var value: Long,val isConst: Boolean = false) : Obj(), Numeric {
}
override suspend fun getAndIncrement(scope: Scope): Obj {
ensureNotConst(scope)
return ObjInt(value).also { value++ }
}
override suspend fun getAndDecrement(scope: Scope): Obj {
ensureNotConst(scope)
return ObjInt(value).also { value-- }
}
override suspend fun incrementAndGet(scope: Scope): Obj {
ensureNotConst(scope)
return ObjInt(++value)
}
override suspend fun decrementAndGet(scope: Scope): Obj {
ensureNotConst(scope)
return ObjInt(--value)
}
@@ -101,7 +101,6 @@ class ImportManager(
*/
private suspend fun doImport(packageName: String, pos: Pos): ModuleScope {
val entry = imports[packageName] ?: throw ImportException(pos, "package not found: $packageName")
println("import enrty found: $packageName")
return entry.getScope(pos)
}
@@ -11,7 +11,7 @@ sealed class ObjType {
@Suppress("unused")
abstract class Statement(
val isStaticConst: Boolean = false,
val isConst: Boolean = false,
override val isConst: Boolean = false,
val returnType: ObjType = ObjType.Any
) : Obj() {