Migrate import evaluator to Kotlin
This commit is contained in:
@@ -24,7 +24,7 @@ data class CallStackFrame(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun getVariable(name: String): Value {
|
fun getVariable(name: String): Value {
|
||||||
return scopes.lastOrNull { it.containsKey(name) }?.get(name) ?: throw RuntimeException("Variable `$name` not found")
|
return scopes.lastOrNull { it.containsKey(name) }?.get(name) ?: throw RuntimeException("Undefined variable `$name`")
|
||||||
}
|
}
|
||||||
|
|
||||||
fun prettyScope() {
|
fun prettyScope() {
|
||||||
|
|||||||
@@ -9,8 +9,7 @@ class ImportParser : Parser() {
|
|||||||
override fun tryToParse(input: TokenList): ParserOutput {
|
override fun tryToParse(input: TokenList): ParserOutput {
|
||||||
val pathParser = oneOf(
|
val pathParser = oneOf(
|
||||||
UnitParser(),
|
UnitParser(),
|
||||||
SimpleIdentifierParser(),
|
SimpleIdentifierParser()
|
||||||
StringLiteralParser()
|
|
||||||
)
|
)
|
||||||
|
|
||||||
return allOf(
|
return allOf(
|
||||||
|
|||||||
@@ -3,12 +3,13 @@ package io.smnp.dsl.ast.parser
|
|||||||
import io.smnp.dsl.ast.model.entity.ParserOutput
|
import io.smnp.dsl.ast.model.entity.ParserOutput
|
||||||
import io.smnp.dsl.ast.model.node.RootNode
|
import io.smnp.dsl.ast.model.node.RootNode
|
||||||
import io.smnp.dsl.token.model.entity.TokenList
|
import io.smnp.dsl.token.model.entity.TokenList
|
||||||
|
import io.smnp.dsl.token.model.enumeration.TokenType
|
||||||
|
|
||||||
class RootParser : Parser() {
|
class RootParser : Parser() {
|
||||||
override fun tryToParse(input: TokenList): ParserOutput {
|
override fun tryToParse(input: TokenList): ParserOutput {
|
||||||
return repeat(
|
return repeat(
|
||||||
oneOf(
|
oneOf(
|
||||||
ImportParser(),
|
allOf(ImportParser(), optional(terminal(TokenType.SEMICOLON))) { (import, _) -> import },
|
||||||
FunctionDefinitionParser(),
|
FunctionDefinitionParser(),
|
||||||
ExtendParser(),
|
ExtendParser(),
|
||||||
StatementParser()
|
StatementParser()
|
||||||
|
|||||||
@@ -0,0 +1,39 @@
|
|||||||
|
package io.smnp.evaluation.evaluator
|
||||||
|
|
||||||
|
import io.smnp.dsl.ast.model.node.AccessOperatorNode
|
||||||
|
import io.smnp.dsl.ast.model.node.IdentifierNode
|
||||||
|
import io.smnp.dsl.ast.model.node.ImportNode
|
||||||
|
import io.smnp.dsl.ast.model.node.Node
|
||||||
|
import io.smnp.environment.Environment
|
||||||
|
import io.smnp.error.ShouldNeverReachThisLineException
|
||||||
|
import io.smnp.evaluation.model.entity.EvaluatorOutput
|
||||||
|
|
||||||
|
class ImportEvaluator : Evaluator() {
|
||||||
|
override fun supportedNodes() = listOf(ImportNode::class)
|
||||||
|
|
||||||
|
override fun tryToEvaluate(node: Node, environment: Environment): EvaluatorOutput {
|
||||||
|
val path = when (val pathNode = (node as ImportNode).path) {
|
||||||
|
is AccessOperatorNode -> complexPath(pathNode).joinToString(".")
|
||||||
|
is IdentifierNode -> pathNode.token.rawValue
|
||||||
|
else -> throw ShouldNeverReachThisLineException()
|
||||||
|
}
|
||||||
|
|
||||||
|
environment.loadModule(path)
|
||||||
|
|
||||||
|
return EvaluatorOutput.ok()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun complexPath(segment: AccessOperatorNode): List<String> {
|
||||||
|
val segments = mutableListOf<String>()
|
||||||
|
val (lhs, _, rhs) = segment
|
||||||
|
|
||||||
|
segments.add((rhs as IdentifierNode).token.rawValue)
|
||||||
|
|
||||||
|
when(lhs) {
|
||||||
|
is AccessOperatorNode -> segments.addAll(complexPath(lhs))
|
||||||
|
is IdentifierNode -> segments.add(lhs.token.rawValue)
|
||||||
|
}
|
||||||
|
|
||||||
|
return segments.reversed()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -11,8 +11,10 @@ class RootEvaluator : Evaluator() {
|
|||||||
|
|
||||||
override fun tryToEvaluate(node: Node, environment: Environment): EvaluatorOutput {
|
override fun tryToEvaluate(node: Node, environment: Environment): EvaluatorOutput {
|
||||||
val evaluator = oneOf(
|
val evaluator = oneOf(
|
||||||
|
ImportEvaluator(),
|
||||||
ExpressionEvaluator(),
|
ExpressionEvaluator(),
|
||||||
FunctionDefinitionEvaluator()
|
FunctionDefinitionEvaluator(),
|
||||||
|
DefaultEvaluator()
|
||||||
)
|
)
|
||||||
|
|
||||||
for(child in node.children) {
|
for(child in node.children) {
|
||||||
|
|||||||
@@ -2,30 +2,38 @@ package io.smnp.interpreter
|
|||||||
|
|
||||||
import io.smnp.dsl.ast.parser.RootParser
|
import io.smnp.dsl.ast.parser.RootParser
|
||||||
import io.smnp.dsl.token.tokenizer.DefaultTokenizer
|
import io.smnp.dsl.token.tokenizer.DefaultTokenizer
|
||||||
|
import io.smnp.environment.DefaultEnvironment
|
||||||
|
import io.smnp.environment.Environment
|
||||||
|
import io.smnp.evaluation.evaluator.RootEvaluator
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
class Interpreter {
|
class Interpreter {
|
||||||
fun run(code: String) {
|
private val tokenizer = DefaultTokenizer()
|
||||||
val tokenizer = DefaultTokenizer()
|
private val parser = RootParser()
|
||||||
val parser = RootParser()
|
private val evaluator = RootEvaluator()
|
||||||
|
|
||||||
|
fun run(code: String) {
|
||||||
val lines = code.split("\n")
|
val lines = code.split("\n")
|
||||||
val tokens = tokenizer.tokenize(lines)
|
val tokens = tokenizer.tokenize(lines)
|
||||||
val ast = parser.parse(tokens)
|
val ast = parser.parse(tokens)
|
||||||
|
|
||||||
ast.node.pretty()
|
val environment = createEnvironment()
|
||||||
println(tokens)
|
evaluator.evaluate(ast.node, environment)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createEnvironment(): Environment {
|
||||||
|
val environment = DefaultEnvironment()
|
||||||
|
environment.loadModule("smnp.lang")
|
||||||
|
|
||||||
|
return environment
|
||||||
}
|
}
|
||||||
|
|
||||||
fun run(file: File) {
|
fun run(file: File) {
|
||||||
val tokenizer = DefaultTokenizer()
|
|
||||||
val parser = RootParser()
|
|
||||||
|
|
||||||
val lines = file.readLines()
|
val lines = file.readLines()
|
||||||
val tokens = tokenizer.tokenize(lines)
|
val tokens = tokenizer.tokenize(lines)
|
||||||
val ast = parser.parse(tokens)
|
val ast = parser.parse(tokens)
|
||||||
|
|
||||||
ast.node.pretty()
|
val environment = createEnvironment()
|
||||||
println(tokens)
|
evaluator.evaluate(ast.node, environment)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user