Files
smnp-py/smnp/ast/node/extend.py
2019-07-12 17:10:47 +02:00

89 lines
2.6 KiB
Python

from smnp.ast.node.block import Block
from smnp.ast.node.function import FunctionDefinitionParser
from smnp.ast.node.identifier import IdentifierLiteralParser
from smnp.ast.node.model import Node
from smnp.ast.node.none import NoneNode
from smnp.ast.node.type import TypeParser
from smnp.ast.parser import Parser
from smnp.token.type import TokenType
class Extend(Node):
def __init__(self, pos):
super().__init__(pos)
self.children = [NoneNode(), NoneNode(), NoneNode()]
@property
def type(self):
return self[0]
@type.setter
def type(self, value):
self[0] = value
@property
def variable(self):
return self[1]
@variable.setter
def variable(self, value):
self[1] = value
@property
def methods(self):
return self[2]
@methods.setter
def methods(self, value):
self[2] = value
@classmethod
def withValues(cls, pos, type, variable, methods):
node = cls(pos)
node.type = type
node.variable = variable
node.methods = methods
return node
def ExtendParser(input):
simpleExtend = Parser.allOf(
Parser.terminal(TokenType.EXTEND),
TypeParser,
Parser.terminal(TokenType.AS),
IdentifierLiteralParser,
Parser.terminal(TokenType.WITH),
Parser.doAssert(Parser.wrap(FunctionDefinitionParser, lambda method: Block.withChildren([ method ], method.pos)), "method definition"),
createNode=lambda extend, type, _, variable, __, methods: Extend.withValues(extend.pos, type, variable, methods),
name="simple extend"
)
multiExtend = Parser.allOf(
Parser.terminal(TokenType.EXTEND),
Parser.doAssert(TypeParser, "type being extended"),
Parser.terminal(TokenType.AS, doAssert=True),
Parser.doAssert(IdentifierLiteralParser, "variable name"),
Parser.doAssert(MethodsDeclarationParser, f"block with methods definitions or '{TokenType.WITH.key}' keyword"),
createNode=lambda extend, type, _, variable, methods: Extend.withValues(extend.pos, type, variable, methods),
name="multiple extend"
)
return Parser.oneOf(
simpleExtend,
multiExtend,
name="extend"
)(input)
def MethodsDeclarationParser(input):
return Parser.loop(
Parser.terminal(TokenType.OPEN_CURLY),
Parser.doAssert(FunctionDefinitionParser, f"method definition or '{TokenType.CLOSE_CURLY.key}'"),
Parser.terminal(TokenType.CLOSE_CURLY),
createNode=lambda open, methods, close: Block.withChildren(methods, open.pos),
name="methods block"
)(input)