From ef7f406379dd807eebb7fb3843e34eb6edc9eb66 Mon Sep 17 00:00:00 2001 From: Zhirkevich Alexander Y Date: Thu, 5 Sep 2024 17:23:01 +0300 Subject: [PATCH] wip --- .../skriptie/common/{Erorrs.kt => Errors.kt} | 0 .../ecmascript/ESInterpretationContext.kt | 12 +++ ...ascriptInterpreter.kt => ESInterpreter.kt} | 0 ...nterpreterImpl.kt => ESInterpreterImpl.kt} | 98 ++++++++++++++++--- .../EcmascriptInterpretationContext.kt | 9 -- .../skriptie/javascript/JSGlobalContext.kt | 41 -------- 6 files changed, 96 insertions(+), 64 deletions(-) rename skriptie/src/commonMain/kotlin/io/github/alexzhirkevich/skriptie/common/{Erorrs.kt => Errors.kt} (100%) create mode 100644 skriptie/src/commonMain/kotlin/io/github/alexzhirkevich/skriptie/ecmascript/ESInterpretationContext.kt rename skriptie/src/commonMain/kotlin/io/github/alexzhirkevich/skriptie/ecmascript/{EcmascriptInterpreter.kt => ESInterpreter.kt} (100%) rename skriptie/src/commonMain/kotlin/io/github/alexzhirkevich/skriptie/ecmascript/{EcmascriptInterpreterImpl.kt => ESInterpreterImpl.kt} (92%) delete mode 100644 skriptie/src/commonMain/kotlin/io/github/alexzhirkevich/skriptie/ecmascript/EcmascriptInterpretationContext.kt delete mode 100644 skriptie/src/commonMain/kotlin/io/github/alexzhirkevich/skriptie/javascript/JSGlobalContext.kt diff --git a/skriptie/src/commonMain/kotlin/io/github/alexzhirkevich/skriptie/common/Erorrs.kt b/skriptie/src/commonMain/kotlin/io/github/alexzhirkevich/skriptie/common/Errors.kt similarity index 100% rename from skriptie/src/commonMain/kotlin/io/github/alexzhirkevich/skriptie/common/Erorrs.kt rename to skriptie/src/commonMain/kotlin/io/github/alexzhirkevich/skriptie/common/Errors.kt diff --git a/skriptie/src/commonMain/kotlin/io/github/alexzhirkevich/skriptie/ecmascript/ESInterpretationContext.kt b/skriptie/src/commonMain/kotlin/io/github/alexzhirkevich/skriptie/ecmascript/ESInterpretationContext.kt new file mode 100644 index 00000000..ae9f7e99 --- /dev/null +++ b/skriptie/src/commonMain/kotlin/io/github/alexzhirkevich/skriptie/ecmascript/ESInterpretationContext.kt @@ -0,0 +1,12 @@ +package io.github.alexzhirkevich.skriptie.ecmascript + +import io.github.alexzhirkevich.skriptie.Expression +import io.github.alexzhirkevich.skriptie.InterpretationContext + +public open class EcmascriptInterpretationContext( + public val namedArgumentsEnabled : Boolean = false +) : InterpretationContext { + override fun interpret(callable: String?, args: List?): Expression? { + return null + } +} \ No newline at end of file diff --git a/skriptie/src/commonMain/kotlin/io/github/alexzhirkevich/skriptie/ecmascript/EcmascriptInterpreter.kt b/skriptie/src/commonMain/kotlin/io/github/alexzhirkevich/skriptie/ecmascript/ESInterpreter.kt similarity index 100% rename from skriptie/src/commonMain/kotlin/io/github/alexzhirkevich/skriptie/ecmascript/EcmascriptInterpreter.kt rename to skriptie/src/commonMain/kotlin/io/github/alexzhirkevich/skriptie/ecmascript/ESInterpreter.kt diff --git a/skriptie/src/commonMain/kotlin/io/github/alexzhirkevich/skriptie/ecmascript/EcmascriptInterpreterImpl.kt b/skriptie/src/commonMain/kotlin/io/github/alexzhirkevich/skriptie/ecmascript/ESInterpreterImpl.kt similarity index 92% rename from skriptie/src/commonMain/kotlin/io/github/alexzhirkevich/skriptie/ecmascript/EcmascriptInterpreterImpl.kt rename to skriptie/src/commonMain/kotlin/io/github/alexzhirkevich/skriptie/ecmascript/ESInterpreterImpl.kt index d8546f0b..01aa81fc 100644 --- a/skriptie/src/commonMain/kotlin/io/github/alexzhirkevich/skriptie/ecmascript/EcmascriptInterpreterImpl.kt +++ b/skriptie/src/commonMain/kotlin/io/github/alexzhirkevich/skriptie/ecmascript/ESInterpreterImpl.kt @@ -39,7 +39,7 @@ import io.github.alexzhirkevich.skriptie.isAssignable import kotlin.contracts.ExperimentalContracts import kotlin.contracts.contract -internal val EXPR_DEBUG_PRINT_ENABLED = true +internal val EXPR_DEBUG_PRINT_ENABLED = false internal enum class LogicalContext { And, Or, Compare @@ -150,21 +150,54 @@ internal class EcmascriptInterpreterImpl( } } - private fun parseAssignment(context: Expression, blockContext: List): Expression { + private fun parseAssignment( + context: Expression, + blockContext: List, + unaryOnly : Boolean = false + ): Expression { var x = parseExpressionOp(context, blockContext = blockContext) if (EXPR_DEBUG_PRINT_ENABLED) { println("Parsing assignment for $x") } + + val checkAssignment = { + if (unaryOnly) + throw SyntaxError("Invalid left-hand side in assignment") + } + while (true) { prepareNextChar() x = when { - eatSequence("+=") -> parseAssignmentValue(x, langContext::sum) - eatSequence("-=") -> parseAssignmentValue(x, langContext::sub) - eatSequence("*=") -> parseAssignmentValue(x, langContext::mul) - eatSequence("/=") -> parseAssignmentValue(x, langContext::div) - eatSequence("%=") -> parseAssignmentValue(x, langContext::mod) + eatSequence("+=") -> { + checkAssignment() + parseAssignmentValue(x, langContext::sum) + } + + eatSequence("-=") -> { + checkAssignment() + parseAssignmentValue(x, langContext::sub) + } + + eatSequence("*=") -> { + checkAssignment() + parseAssignmentValue(x, langContext::mul) + } + + eatSequence("/=") -> { + checkAssignment() + parseAssignmentValue(x, langContext::div) + } + + eatSequence("%=") -> { + checkAssignment() + parseAssignmentValue(x, langContext::mod) + } + eatSequence("=>") -> OpConstant(parseArrowFunction(listOf(x), blockContext)) - eat('=') -> parseAssignmentValue(x, null) + eat('=') -> { + checkAssignment() + parseAssignmentValue(x, null) + } eatSequence("++") -> { check(x.isAssignable()) { "Not assignable" @@ -187,6 +220,29 @@ internal class EcmascriptInterpreterImpl( ) } + eat('?') -> { + if (EXPR_DEBUG_PRINT_ENABLED){ + println("making ternary operator: onTrue...") + } + + val onTrue = parseAssignment(globalContext, blockContext) + + if (!eat(':')){ + throw SyntaxError("Unexpected end of input") + } + if (EXPR_DEBUG_PRINT_ENABLED) { + println("making ternary operator: onFalse...") + } + val onFalse = parseAssignment(globalContext, blockContext) + + OpIfCondition( + condition = x, + onTrue = onTrue, + onFalse = onFalse, + expressible = true + ) + } + else -> return x } } @@ -384,7 +440,7 @@ internal class EcmascriptInterpreterImpl( return@buildList } do { - add(parseExpressionOp(context, blockContext = blockContext)) + add(parseAssignment(context, blockContext = blockContext)) } while (eat(',')) check(eat(')')) { @@ -491,8 +547,8 @@ internal class EcmascriptInterpreterImpl( println("making index... ") } OpIndex( - context, - parseExpressionOp(globalContext, blockContext = blockContext) + variable = context, + index = parseExpressionOp(globalContext, blockContext = blockContext) ).also { require(eat(']')) { "Bad expression: Missing ']'" @@ -632,6 +688,23 @@ internal class EcmascriptInterpreterImpl( } } + "typeof" -> { + val expr = parseAssignment( + context = globalContext, + blockContext = emptyList(), + unaryOnly = true + ) + Expression { + when (val v = expr(it)) { + null -> "object" + Unit -> "undefined" + true, false -> "boolean" + + is ESAny -> v.type + else -> v::class.simpleName + } + } + } "null" -> OpConstant(null) "true" -> OpConstant(true) @@ -856,15 +929,12 @@ internal class EcmascriptInterpreterImpl( if (assign != null) { check(eat(';')) } - println(assign) val comparison = if (eat(';')) null else parseAssignment(globalContext, emptyList()) if (comparison != null) { check(eat(';')) } - println(comparison) val increment = if (eat(')')) null else parseAssignment(globalContext, emptyList()) - println(increment) if (increment != null) { check(eat(')')) } diff --git a/skriptie/src/commonMain/kotlin/io/github/alexzhirkevich/skriptie/ecmascript/EcmascriptInterpretationContext.kt b/skriptie/src/commonMain/kotlin/io/github/alexzhirkevich/skriptie/ecmascript/EcmascriptInterpretationContext.kt deleted file mode 100644 index 81524d9d..00000000 --- a/skriptie/src/commonMain/kotlin/io/github/alexzhirkevich/skriptie/ecmascript/EcmascriptInterpretationContext.kt +++ /dev/null @@ -1,9 +0,0 @@ -package io.github.alexzhirkevich.skriptie.ecmascript - -import io.github.alexzhirkevich.skriptie.InterpretationContext - -public abstract class EcmascriptInterpretationContext( - public val namedArgumentsEnabled : Boolean = false -) : InterpretationContext { - -} \ No newline at end of file diff --git a/skriptie/src/commonMain/kotlin/io/github/alexzhirkevich/skriptie/javascript/JSGlobalContext.kt b/skriptie/src/commonMain/kotlin/io/github/alexzhirkevich/skriptie/javascript/JSGlobalContext.kt deleted file mode 100644 index b7e929f1..00000000 --- a/skriptie/src/commonMain/kotlin/io/github/alexzhirkevich/skriptie/javascript/JSGlobalContext.kt +++ /dev/null @@ -1,41 +0,0 @@ -package io.github.alexzhirkevich.skriptie.javascript - -import io.github.alexzhirkevich.skriptie.Expression -import io.github.alexzhirkevich.skriptie.argAt -import io.github.alexzhirkevich.skriptie.ecmascript.ESAny -import io.github.alexzhirkevich.skriptie.ecmascript.EcmascriptInterpretationContext -import io.github.alexzhirkevich.skriptie.ecmascript.checkArgs -import io.github.alexzhirkevich.skriptie.invoke - -public open class JSGlobalContext( - namedArgumentsEnabled : Boolean = false -) : EcmascriptInterpretationContext(namedArgumentsEnabled) { - - override fun interpret( - callable: String?, - args: List? - ): Expression? { - return if (args != null){ - when (callable) { - "typeof" -> { - checkArgs(args, 1, callable) - JsTypeof(args.argAt(0)) - } - else -> null - } - } else null - } -} - - - -private fun JsTypeof(value : Expression) = Expression { - value(it).let { - when (it) { - null -> "object" - Unit -> "undefined" - is ESAny -> it.type - else -> it::class.simpleName - } - } -} \ No newline at end of file