Improve import parser and evaluator

This commit is contained in:
2020-03-13 10:04:55 +01:00
parent e9ddb92ee2
commit b603c9f2c5
3 changed files with 23 additions and 40 deletions

View File

@@ -2,11 +2,7 @@ package io.smnp.dsl.ast.model.node
import io.smnp.dsl.token.model.entity.TokenPosition import io.smnp.dsl.token.model.entity.TokenPosition
class ImportNode(path: Node, position: TokenPosition) : Node(1, position) { class ImportNode(path: List<Node>, position: TokenPosition) : Node(path, position) {
val path: Node val path: List<Node>
get() = children[0] get() = children
init {
children[0] = path
}
} }

View File

@@ -2,21 +2,29 @@ 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.ImportNode import io.smnp.dsl.ast.model.node.ImportNode
import io.smnp.dsl.ast.model.node.Node
import io.smnp.dsl.token.model.entity.TokenList import io.smnp.dsl.token.model.entity.TokenList
import io.smnp.dsl.token.model.enumeration.TokenType import io.smnp.dsl.token.model.enumeration.TokenType
class ImportParser : Parser() { class ImportParser : Parser() {
override fun tryToParse(input: TokenList): ParserOutput { override fun tryToParse(input: TokenList): ParserOutput {
val pathParser = oneOf( val pathParser = allOf(
UnitParser(), SimpleIdentifierParser(),
optional(repeat(allOf(
terminal(TokenType.DOT),
SimpleIdentifierParser() SimpleIdentifierParser()
) ) { (_, child) -> child }) { segments, position ->
object : Node(segments, position) {}
})) { (firstSegment, otherSegments) ->
object : Node(listOf(firstSegment) + otherSegments.children, firstSegment.position) {}
}
return allOf( return allOf(
terminal(TokenType.IMPORT), terminal(TokenType.IMPORT),
pathParser pathParser
) { ) { (import, path) ->
ImportNode(it[1], it[0].position) ImportNode(path.children, import.position)
}.parse(input) }.parse(input)
} }
} }

View File

@@ -1,39 +1,18 @@
package io.smnp.evaluation.evaluator 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.IdentifierNode
import io.smnp.dsl.ast.model.node.ImportNode import io.smnp.dsl.ast.model.node.ImportNode
import io.smnp.dsl.ast.model.node.Node import io.smnp.dsl.ast.model.node.Node
import io.smnp.environment.Environment import io.smnp.environment.Environment
import io.smnp.error.ShouldNeverReachThisLineException
import io.smnp.evaluation.model.entity.EvaluatorOutput import io.smnp.evaluation.model.entity.EvaluatorOutput
class ImportEvaluator : Evaluator() { class ImportEvaluator : Evaluator() {
override fun supportedNodes() = listOf(ImportNode::class) override fun supportedNodes() = listOf(ImportNode::class)
override fun tryToEvaluate(node: Node, environment: Environment): EvaluatorOutput { override fun tryToEvaluate(node: Node, environment: Environment): EvaluatorOutput {
val path = when (val pathNode = (node as ImportNode).path) { val path = (node as ImportNode).path.joinToString(".") { (it as IdentifierNode).token.rawValue }
is AccessOperatorNode -> complexPath(pathNode).joinToString(".")
is IdentifierNode -> pathNode.token.rawValue
else -> throw ShouldNeverReachThisLineException()
}
environment.loadModule(path) environment.loadModule(path)
return EvaluatorOutput.ok() 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()
}
} }