Refactor extend statement: remove unnecessary "as" keyword and push "this" variable context to the extend-statement scope
This commit is contained in:
@@ -11,7 +11,7 @@ import io.smnp.type.matcher.Matcher
|
|||||||
import io.smnp.type.model.Value
|
import io.smnp.type.model.Value
|
||||||
|
|
||||||
object CustomMethod {
|
object CustomMethod {
|
||||||
fun create(type: Matcher, objectIdentifier: String, node: FunctionDefinitionNode): Method {
|
fun create(type: Matcher, node: FunctionDefinitionNode): Method {
|
||||||
val identifier = (node.identifier as IdentifierNode).token.rawValue
|
val identifier = (node.identifier as IdentifierNode).token.rawValue
|
||||||
|
|
||||||
return object : Method(type, identifier) {
|
return object : Method(type, identifier) {
|
||||||
@@ -23,7 +23,7 @@ object CustomMethod {
|
|||||||
new method signature body { env, obj, args ->
|
new method signature body { env, obj, args ->
|
||||||
val boundArguments =
|
val boundArguments =
|
||||||
FunctionEnvironmentProvider.provideEnvironment(argumentsNode, args, env).toMutableMap()
|
FunctionEnvironmentProvider.provideEnvironment(argumentsNode, args, env).toMutableMap()
|
||||||
boundArguments[objectIdentifier] = obj
|
boundArguments["this"] = obj
|
||||||
|
|
||||||
try {
|
try {
|
||||||
env.pushScope(boundArguments)
|
env.pushScope(boundArguments)
|
||||||
|
|||||||
@@ -2,23 +2,18 @@ package io.smnp.dsl.ast.model.node
|
|||||||
|
|
||||||
import io.smnp.dsl.token.model.entity.TokenPosition
|
import io.smnp.dsl.token.model.entity.TokenPosition
|
||||||
|
|
||||||
class ExtendNode(type: Node, identifier: Node, functions: Node, position: TokenPosition) : Node(3, position) {
|
class ExtendNode(type: Node, functions: Node, position: TokenPosition) : Node(2, position) {
|
||||||
operator fun component1(): Node = children[0]
|
operator fun component1(): Node = children[0]
|
||||||
operator fun component2(): Node = children[1]
|
operator fun component2(): Node = children[1]
|
||||||
operator fun component3(): Node = children[2]
|
|
||||||
|
|
||||||
val type: Node
|
val type: Node
|
||||||
get() = children[0]
|
get() = children[0]
|
||||||
|
|
||||||
val identifier: Node
|
|
||||||
get() = children[1]
|
|
||||||
|
|
||||||
val functions: Node
|
val functions: Node
|
||||||
get() = children[2]
|
get() = children[1]
|
||||||
|
|
||||||
init {
|
init {
|
||||||
children[0] = type
|
children[0] = type
|
||||||
children[1] = identifier
|
children[1] = functions
|
||||||
children[2] = functions
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -8,33 +8,38 @@ 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 ExtendParser : Parser() {
|
class ExtendParser : Parser() {
|
||||||
override fun tryToParse(input: TokenList): ParserOutput {
|
override fun tryToParse(input: TokenList): ParserOutput {
|
||||||
val simpleExtendParser = allOf(
|
val simpleExtendParser = allOf(
|
||||||
terminal(TokenType.EXTEND),
|
terminal(TokenType.EXTEND),
|
||||||
assert(SingleTypeParser(), "type to be extended"),
|
assert(SingleTypeParser(), "type to be extended"),
|
||||||
assert(terminal(TokenType.AS), "'as' keyword with identifier"),
|
terminal(TokenType.WITH),
|
||||||
assert(SimpleIdentifierParser(), "identifier"),
|
assert(
|
||||||
terminal(TokenType.WITH),
|
mapNode(FunctionDefinitionParser()) { BlockNode(Node.NONE, listOf(it), Node.NONE) },
|
||||||
assert(mapNode(FunctionDefinitionParser()) { BlockNode(Node.NONE, listOf(it), Node.NONE) }, "method definition")
|
"method definition"
|
||||||
) { (extendToken, targetType, identifier, method) ->
|
)
|
||||||
ExtendNode(targetType, identifier, method, extendToken.position)
|
) { (extendToken, targetType, _, method) ->
|
||||||
}
|
ExtendNode(targetType, method, extendToken.position)
|
||||||
|
}
|
||||||
|
|
||||||
val complexExtendParser = allOf(
|
val complexExtendParser = allOf(
|
||||||
terminal(TokenType.EXTEND),
|
terminal(TokenType.EXTEND),
|
||||||
assert(SingleTypeParser(), "type to be extended"),
|
assert(SingleTypeParser(), "type to be extended"),
|
||||||
assert(terminal(TokenType.AS), "'as' keyword with identifier"),
|
assert(
|
||||||
assert(SimpleIdentifierParser(), "identifier"),
|
loop(
|
||||||
assert(loop(terminal(TokenType.OPEN_CURLY), assert(FunctionDefinitionParser(), "method definition or }"), terminal(TokenType.CLOSE_CURLY)) {
|
terminal(TokenType.OPEN_CURLY),
|
||||||
begin, methods, end -> BlockNode(begin, methods, end)
|
assert(FunctionDefinitionParser(), "method definition or }"),
|
||||||
}, "block with methods' definitions or 'with' keyword with single method definition")
|
terminal(TokenType.CLOSE_CURLY)
|
||||||
) { (extendToken, targetType, _, identifier, methods) ->
|
) { begin, methods, end ->
|
||||||
ExtendNode(targetType, identifier, methods, extendToken.position)
|
BlockNode(begin, methods, end)
|
||||||
}
|
}, "block with methods' definitions or 'with' keyword with single method definition"
|
||||||
|
)
|
||||||
|
) { (extendToken, targetType, methods) ->
|
||||||
|
ExtendNode(targetType, methods, extendToken.position)
|
||||||
|
}
|
||||||
|
|
||||||
return oneOf(
|
return oneOf(
|
||||||
simpleExtendParser,
|
simpleExtendParser,
|
||||||
complexExtendParser
|
complexExtendParser
|
||||||
).parse(input)
|
).parse(input)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2,7 +2,10 @@ package io.smnp.evaluation.evaluator
|
|||||||
|
|
||||||
import io.smnp.callable.method.CustomMethod
|
import io.smnp.callable.method.CustomMethod
|
||||||
import io.smnp.callable.util.FunctionSignatureParser
|
import io.smnp.callable.util.FunctionSignatureParser
|
||||||
import io.smnp.dsl.ast.model.node.*
|
import io.smnp.dsl.ast.model.node.ExtendNode
|
||||||
|
import io.smnp.dsl.ast.model.node.FunctionDefinitionNode
|
||||||
|
import io.smnp.dsl.ast.model.node.Node
|
||||||
|
import io.smnp.dsl.ast.model.node.SingleTypeNode
|
||||||
import io.smnp.environment.Environment
|
import io.smnp.environment.Environment
|
||||||
import io.smnp.error.EnvironmentException
|
import io.smnp.error.EnvironmentException
|
||||||
import io.smnp.error.PositionException
|
import io.smnp.error.PositionException
|
||||||
@@ -13,12 +16,11 @@ class ExtendEvaluator : Evaluator() {
|
|||||||
override fun supportedNodes() = listOf(ExtendNode::class)
|
override fun supportedNodes() = listOf(ExtendNode::class)
|
||||||
|
|
||||||
override fun tryToEvaluate(node: Node, environment: Environment): EvaluatorOutput {
|
override fun tryToEvaluate(node: Node, environment: Environment): EvaluatorOutput {
|
||||||
val (typeNode, identifierNode, methodsNode) = node as ExtendNode
|
val (typeNode, methodsNode) = node as ExtendNode
|
||||||
val type = FunctionSignatureParser.matcherForSingleTypeNode(typeNode as SingleTypeNode)
|
val type = FunctionSignatureParser.matcherForSingleTypeNode(typeNode as SingleTypeNode)
|
||||||
val identifier = (identifierNode as IdentifierNode).token.rawValue
|
|
||||||
|
|
||||||
methodsNode.children
|
methodsNode.children
|
||||||
.map { it to CustomMethod.create(type, identifier, it as FunctionDefinitionNode) }
|
.map { it to CustomMethod.create(type, it as FunctionDefinitionNode) }
|
||||||
.forEach {
|
.forEach {
|
||||||
try {
|
try {
|
||||||
environment.defineMethod(it.second)
|
environment.defineMethod(it.second)
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ function _flatten(list: list, output: list) {
|
|||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
extend list as this {
|
extend list {
|
||||||
function flatten() {
|
function flatten() {
|
||||||
return flatten(this);
|
return flatten(this);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
extend map as this {
|
extend map {
|
||||||
function containsKey(key) {
|
function containsKey(key) {
|
||||||
return this.keys.contains(key);
|
return this.keys.contains(key);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
extend note as this {
|
extend note {
|
||||||
function withOctave(octave: int) {
|
function withOctave(octave: int) {
|
||||||
return Note(this.pitch, octave, this.duration.get("numerator"), this.duration.get("denominator"));
|
return Note(this.pitch, octave, this.duration.get("numerator"), this.duration.get("denominator"));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
extend string as this {
|
extend string {
|
||||||
function find(char: string) {
|
function find(char: string) {
|
||||||
if(char.length > 1) {
|
if(char.length > 1) {
|
||||||
throw "Only single character can act as a pattern to be found";
|
throw "Only single character can act as a pattern to be found";
|
||||||
|
|||||||
Reference in New Issue
Block a user