Enable extending existing types to add custom methods

This commit is contained in:
Bartłomiej Pluta
2019-07-06 00:36:54 +02:00
parent f11b3b67f2
commit bf40c5130c
8 changed files with 86 additions and 6 deletions

View File

@@ -13,7 +13,7 @@ def main():
lines = [line.rstrip('\n') for line in source.readlines()] lines = [line.rstrip('\n') for line in source.readlines()]
tokens = tokenize(lines) tokens = tokenize(lines)
print(tokens)
ast = Program.parse(tokens) ast = Program.parse(tokens)
ast.node.print() ast.node.print()

View File

@@ -0,0 +1,69 @@
from smnp.newast.node.block import BlockNode
from smnp.newast.node.function import FunctionDefinitionNode
from smnp.newast.node.identifier import IdentifierNode
from smnp.newast.node.none import NoneNode
from smnp.newast.node.statement import StatementNode
from smnp.newast.node.type import TypeNode
from smnp.newast.parser import Parser
from smnp.token.type import TokenType
class ExtendNode(StatementNode):
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 _parse(cls, input):
def createNode(extend, type, variable, methods):
node = ExtendNode(extend.pos)
node.type = type
node.variable = variable
node.methods = methods
return node
return Parser.allOf(
Parser.terminalParser(TokenType.EXTEND),
TypeNode.parse,
IdentifierNode.identifierParser(),
cls._methodsDeclarationsParser(),
createNode=createNode
)(input)
@classmethod
def _methodsDeclarationsParser(cls):
def createNode(openBracket, items, closeBracket):
node = BlockNode(openBracket.pos)
node.children = items
return node
return Parser.loop(
Parser.terminalParser(TokenType.OPEN_BRACKET),
FunctionDefinitionNode.parse,
Parser.terminalParser(TokenType.CLOSE_BRACKET),
createNode=createNode
)

View File

@@ -16,7 +16,7 @@ class ArgumentsDeclarationNode(Node):
raise RuntimeError("This class is not supposed to be automatically called") raise RuntimeError("This class is not supposed to be automatically called")
class FunctionDefinition(StatementNode): class FunctionDefinitionNode(StatementNode):
def __init__(self, pos): def __init__(self, pos):
super().__init__(pos) super().__init__(pos)
self.children = [NoneNode(), NoneNode(), NoneNode()] self.children = [NoneNode(), NoneNode(), NoneNode()]
@@ -48,7 +48,7 @@ class FunctionDefinition(StatementNode):
@classmethod @classmethod
def _parse(cls, input): def _parse(cls, input):
def createNode(function, name, arguments, body): def createNode(function, name, arguments, body):
node = FunctionDefinition(function.pos) node = FunctionDefinitionNode(function.pos)
node.name = name node.name = name
node.arguments = arguments node.arguments = arguments
node.body = body node.body = body

View File

@@ -1,5 +1,7 @@
from smnp.error.syntax import SyntaxException from smnp.error.syntax import SyntaxException
from smnp.newast.node.expression import ExpressionNode from smnp.newast.node.expression import ExpressionNode
from smnp.newast.node.extend import ExtendNode
from smnp.newast.node.function import FunctionDefinitionNode
from smnp.newast.node.model import Node, ParseResult from smnp.newast.node.model import Node, ParseResult
from smnp.newast.node.statement import StatementNode from smnp.newast.node.statement import StatementNode
from smnp.newast.parser import Parser from smnp.newast.parser import Parser
@@ -13,9 +15,11 @@ class Program(Node):
def _parse(cls, input): def _parse(cls, input):
def parseToken(input): def parseToken(input):
return Parser.oneOf( return Parser.oneOf(
FunctionDefinitionNode.parse,
ExtendNode.parse,
ExpressionNode.parse, ExpressionNode.parse,
StatementNode.parse, StatementNode.parse,
exception = SyntaxException("Unknown statement") exception = SyntaxException(f"Unknown statement: {input.current().pos}")
)(input) )(input)
root = Program() root = Program()

View File

@@ -7,13 +7,11 @@ class StatementNode(Node):
@classmethod @classmethod
def _parse(cls, input): def _parse(cls, input):
from smnp.newast.node.block import BlockNode from smnp.newast.node.block import BlockNode
from smnp.newast.node.function import FunctionDefinition
from smnp.newast.node.expression import ExpressionNode from smnp.newast.node.expression import ExpressionNode
from smnp.newast.node.ret import ReturnNode from smnp.newast.node.ret import ReturnNode
return Parser.oneOf( return Parser.oneOf(
BlockNode.parse, BlockNode.parse,
FunctionDefinition.parse,
ReturnNode.parse, ReturnNode.parse,
ExpressionNode.parse ExpressionNode.parse
)(input) )(input)

View File

@@ -6,6 +6,7 @@ from smnp.token.tokenizers.bracket import tokenizeOpenBracket, tokenizeCloseBrac
from smnp.token.tokenizers.comma import tokenizeComma from smnp.token.tokenizers.comma import tokenizeComma
from smnp.token.tokenizers.comment import tokenizeComment from smnp.token.tokenizers.comment import tokenizeComment
from smnp.token.tokenizers.dot import tokenizeDot from smnp.token.tokenizers.dot import tokenizeDot
from smnp.token.tokenizers.extend import tokenizeExtend
from smnp.token.tokenizers.function import tokenizeFunction from smnp.token.tokenizers.function import tokenizeFunction
from smnp.token.tokenizers.identifier import tokenizeIdentifier from smnp.token.tokenizers.identifier import tokenizeIdentifier
from smnp.token.tokenizers.integer import tokenizeInteger from smnp.token.tokenizers.integer import tokenizeInteger
@@ -30,6 +31,7 @@ tokenizers = (
tokenizeString, tokenizeString,
tokenizeFunction, tokenizeFunction,
tokenizeReturn, tokenizeReturn,
tokenizeExtend,
tokenizeInteger, tokenizeInteger,
tokenizeNote, tokenizeNote,
tokenizeIdentifier, tokenizeIdentifier,

View File

@@ -0,0 +1,6 @@
from smnp.token.tools import tokenizeKeyword
from smnp.token.type import TokenType
def tokenizeExtend(input, current, line):
return tokenizeKeyword(TokenType.EXTEND, "extend", input, current, line)

View File

@@ -22,3 +22,4 @@ class TokenType(Enum):
OPEN_SQUARE = auto() OPEN_SQUARE = auto()
CLOSE_SQUARE = auto() CLOSE_SQUARE = auto()
TYPE = auto() TYPE = auto()
EXTEND = auto()