fix #42 class static fields and methods

This commit is contained in:
Sergey Chernov 2025-08-06 22:48:32 +03:00
parent 2c2dae4d85
commit 53a6a88924
2 changed files with 42 additions and 12 deletions

View File

@ -19,10 +19,11 @@ class Compiler(
private val initStack = mutableListOf<MutableList<Statement>>() private val initStack = mutableListOf<MutableList<Statement>>()
val currentInitScope: MutableList<Statement> get() = val currentInitScope: MutableList<Statement>
initStack.lastOrNull() ?: cc.syntaxError("no initialization scope exists here") get() =
initStack.lastOrNull() ?: cc.syntaxError("no initialization scope exists here")
private fun pushInitScope(): MutableList<Statement> = mutableListOf<Statement>().also { initStack.add(it)} private fun pushInitScope(): MutableList<Statement> = mutableListOf<Statement>().also { initStack.add(it) }
private fun popInitScope(): MutableList<Statement> = initStack.removeLast() private fun popInitScope(): MutableList<Statement> = initStack.removeLast()
@ -832,6 +833,8 @@ class Compiler(
val isExtern = cc.skipId("extern") val isExtern = cc.skipId("extern")
when { when {
cc.matchQualifiers("fun", "private") -> parseFunctionDeclaration(Visibility.Private, isExtern) cc.matchQualifiers("fun", "private") -> parseFunctionDeclaration(Visibility.Private, isExtern)
cc.matchQualifiers("fun", "private", "static") -> parseFunctionDeclaration(Visibility.Private, isExtern, isStatic = true)
cc.matchQualifiers("fun", "static") -> parseFunctionDeclaration(Visibility.Public, isExtern, isStatic = true)
cc.matchQualifiers("fn", "private") -> parseFunctionDeclaration(Visibility.Private, isExtern) cc.matchQualifiers("fn", "private") -> parseFunctionDeclaration(Visibility.Private, isExtern)
cc.matchQualifiers("fun", "open") -> parseFunctionDeclaration(isOpen = true, isExtern = isExtern) cc.matchQualifiers("fun", "open") -> parseFunctionDeclaration(isOpen = true, isExtern = isExtern)
cc.matchQualifiers("fn", "open") -> parseFunctionDeclaration(isOpen = true, isExtern = isExtern) cc.matchQualifiers("fn", "open") -> parseFunctionDeclaration(isOpen = true, isExtern = isExtern)
@ -839,11 +842,21 @@ class Compiler(
cc.matchQualifiers("fun") -> parseFunctionDeclaration(isOpen = false, isExtern = isExtern) cc.matchQualifiers("fun") -> parseFunctionDeclaration(isOpen = false, isExtern = isExtern)
cc.matchQualifiers("fn") -> parseFunctionDeclaration(isOpen = false, isExtern = isExtern) cc.matchQualifiers("fn") -> parseFunctionDeclaration(isOpen = false, isExtern = isExtern)
cc.matchQualifiers("val", "private", "static") -> parseVarDeclaration(false, Visibility.Private, isStatic = true) cc.matchQualifiers("val", "private", "static") -> parseVarDeclaration(
false,
Visibility.Private,
isStatic = true
)
cc.matchQualifiers("val", "static") -> parseVarDeclaration(false, Visibility.Public, isStatic = true) cc.matchQualifiers("val", "static") -> parseVarDeclaration(false, Visibility.Public, isStatic = true)
cc.matchQualifiers("val", "private") -> parseVarDeclaration(false, Visibility.Private) cc.matchQualifiers("val", "private") -> parseVarDeclaration(false, Visibility.Private)
cc.matchQualifiers("var", "static") -> parseVarDeclaration(true, Visibility.Public, isStatic = true) cc.matchQualifiers("var", "static") -> parseVarDeclaration(true, Visibility.Public, isStatic = true)
cc.matchQualifiers("var", "static", "private" ) -> parseVarDeclaration(true, Visibility.Private, isStatic = true) cc.matchQualifiers("var", "static", "private") -> parseVarDeclaration(
true,
Visibility.Private,
isStatic = true
)
cc.matchQualifiers("var", "private") -> parseVarDeclaration(true, Visibility.Private) cc.matchQualifiers("var", "private") -> parseVarDeclaration(true, Visibility.Private)
cc.matchQualifiers("val", "open") -> parseVarDeclaration(false, Visibility.Private, true) cc.matchQualifiers("val", "open") -> parseVarDeclaration(false, Visibility.Private, true)
cc.matchQualifiers("var", "open") -> parseVarDeclaration(true, Visibility.Private, true) cc.matchQualifiers("var", "open") -> parseVarDeclaration(true, Visibility.Private, true)
@ -1148,12 +1161,12 @@ class Compiler(
// the main statement should create custom ObjClass instance with field // the main statement should create custom ObjClass instance with field
// accessors, constructor registration, etc. // accessors, constructor registration, etc.
addItem(className, false, newClass) addItem(className, false, newClass)
if( initScope.isNotEmpty()) { if (initScope.isNotEmpty()) {
val classScope = copy(newThisObj = newClass) val classScope = copy(newThisObj = newClass)
newClass.classScope = classScope newClass.classScope = classScope
for( s in initScope ) for (s in initScope)
s.execute(classScope) s.execute(classScope)
.also { println("executed, ${classScope.objects}")} .also { println("executed, ${classScope.objects}") }
} }
newClass newClass
} }
@ -1530,7 +1543,8 @@ class Compiler(
private suspend fun parseFunctionDeclaration( private suspend fun parseFunctionDeclaration(
visibility: Visibility = Visibility.Public, visibility: Visibility = Visibility.Public,
@Suppress("UNUSED_PARAMETER") isOpen: Boolean = false, @Suppress("UNUSED_PARAMETER") isOpen: Boolean = false,
isExtern: Boolean = false isExtern: Boolean = false,
isStatic: Boolean = false,
): Statement { ): Statement {
var t = cc.next() var t = cc.next()
val start = t.pos val start = t.pos
@ -1583,7 +1597,7 @@ class Compiler(
} }
fnStatements.execute(context) fnStatements.execute(context)
} }
return 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 // for the function
closure = context closure = context
@ -1601,6 +1615,11 @@ class Compiler(
// saved the proper context in the closure // saved the proper context in the closure
fnBody fnBody
} }
return if (isStatic) {
currentInitScope += fnCreatestatement
NopStatement
} else
fnCreatestatement
} }
private suspend fun parseBlock(skipLeadingBrace: Boolean = false): Statement { private suspend fun parseBlock(skipLeadingBrace: Boolean = false): Statement {
@ -1647,7 +1666,7 @@ class Compiler(
val initialExpression = if (setNull) null else parseStatement(true) val initialExpression = if (setNull) null else parseStatement(true)
?: throw ScriptError(eqToken.pos, "Expected initializer expression") ?: throw ScriptError(eqToken.pos, "Expected initializer expression")
if( isStatic) { if (isStatic) {
// find objclass instance: this is tricky: this code executes in object initializer, // find objclass instance: this is tricky: this code executes in object initializer,
// when creating instance, but we need to execute it in the class initializer which // when creating instance, but we need to execute it in the class initializer which
// is missing as for now. Add it to the compiler context? // is missing as for now. Add it to the compiler context?

View File

@ -27,9 +27,20 @@ class OOTest {
class Point(x,y) { class Point(x,y) {
private static var data = null private static var data = null
static fun getData() { data }
static fun setData(value) {
data = value
callFrom()
}
static fun callFrom() {
data = data + "!"
}
} }
assertEquals(Point(0,0), Point(0,0) ) assertEquals(Point(0,0), Point(0,0) )
assertEquals(null, Point.getData() )
Point.setData("foo")
assertEquals( "foo!", Point.getData() )
""".trimIndent()) """.trimIndent())
} }
} }