diff --git a/smnp/ast/node/access.py b/smnp/ast/node/access.py deleted file mode 100644 index 66ee2c3..0000000 --- a/smnp/ast/node/access.py +++ /dev/null @@ -1,65 +0,0 @@ -from smnp.ast.node.expression import ExpressionNode -from smnp.ast.node.none import NoneNode -from smnp.ast.parser import Parser -from smnp.error.syntax import SyntaxException -from smnp.token.type import TokenType - - -class LeftAssociativeOperatorNode(ExpressionNode): - def __init__(self, pos): - super().__init__(pos) - self.children = [NoneNode(), NoneNode(), NoneNode()] - - @property - def left(self): - return self[0] - - @left.setter - def left(self, value): - self[0] = value - - @property - def operator(self): - return self[1] - - @operator.setter - def operator(self, value): - self[1] = value - - @property - def right(self): - return self[2] - - @right.setter - def right(self, value): - self[2] = value - - @classmethod - def _parse(cls, input): - def createNode(left, operator, right): - node = LeftAssociativeOperatorNode(right.pos) - node.left = left - node.operator = operator - node.right = right - return node - - return Parser.leftAssociativeOperatorParser( - cls._literalParser(), - TokenType.DOT, - cls._parseAccessingProperty(), - createNode=createNode - )(input) - - @classmethod - def _literalParser(cls): - pass - - @staticmethod - def _parseAccessingProperty(): - from smnp.ast.node.identifier import IdentifierNode - - return Parser.oneOf( - IdentifierNode._literalParser(), - IdentifierNode._functionCallParser(), - exception=lambda input: SyntaxException(f"Expected property name or method call, found '{input.current().rawValue}'", input.currentPos()) - ) diff --git a/smnp/ast/node/bool.py b/smnp/ast/node/bool.py index a45f2de..5d8491a 100644 --- a/smnp/ast/node/bool.py +++ b/smnp/ast/node/bool.py @@ -1,5 +1,5 @@ -from smnp.ast.node.access import LeftAssociativeOperatorNode from smnp.ast.node.literal import LiteralNode +from smnp.ast.node.operator import LeftAssociativeOperatorNode from smnp.token.type import TokenType diff --git a/smnp/ast/node/identifier.py b/smnp/ast/node/identifier.py index 66d0716..18db58d 100644 --- a/smnp/ast/node/identifier.py +++ b/smnp/ast/node/identifier.py @@ -1,7 +1,7 @@ -from smnp.ast.node.access import LeftAssociativeOperatorNode from smnp.ast.node.assignment import AssignmentNode from smnp.ast.node.expression import ExpressionNode from smnp.ast.node.invocation import FunctionCallNode, ArgumentsListNode +from smnp.ast.node.operator import LeftAssociativeOperatorNode from smnp.ast.parser import Parser from smnp.token.type import TokenType diff --git a/smnp/ast/node/integer.py b/smnp/ast/node/integer.py index bb4275d..18a964e 100644 --- a/smnp/ast/node/integer.py +++ b/smnp/ast/node/integer.py @@ -1,4 +1,4 @@ -from smnp.ast.node.access import LeftAssociativeOperatorNode +from smnp.ast.node.operator import LeftAssociativeOperatorNode from smnp.ast.parser import Parser from smnp.token.type import TokenType diff --git a/smnp/ast/node/invocation.py b/smnp/ast/node/invocation.py index bee76b2..858d417 100644 --- a/smnp/ast/node/invocation.py +++ b/smnp/ast/node/invocation.py @@ -1,8 +1,8 @@ -from smnp.ast.node.access import LeftAssociativeOperatorNode from smnp.ast.node.expression import ExpressionNode from smnp.ast.node.iterable import abstractIterableParser from smnp.ast.node.model import Node from smnp.ast.node.none import NoneNode +from smnp.ast.node.operator import LeftAssociativeOperatorNode from smnp.ast.parser import Parser from smnp.token.type import TokenType diff --git a/smnp/ast/node/list.py b/smnp/ast/node/list.py index f4d1951..b617c48 100644 --- a/smnp/ast/node/list.py +++ b/smnp/ast/node/list.py @@ -1,6 +1,6 @@ -from smnp.ast.node.access import LeftAssociativeOperatorNode from smnp.ast.node.expression import ExpressionNode from smnp.ast.node.iterable import abstractIterableParser +from smnp.ast.node.operator import LeftAssociativeOperatorNode from smnp.ast.parser import Parser from smnp.token.type import TokenType diff --git a/smnp/ast/node/map.py b/smnp/ast/node/map.py index 7a2f90b..a01b84a 100644 --- a/smnp/ast/node/map.py +++ b/smnp/ast/node/map.py @@ -1,15 +1,16 @@ -from smnp.ast.node.access import LeftAssociativeOperatorNode from smnp.ast.node.bool import BoolLiteralNode from smnp.ast.node.expression import ExpressionNode from smnp.ast.node.integer import IntegerLiteralNode from smnp.ast.node.iterable import abstractIterableParser from smnp.ast.node.none import NoneNode from smnp.ast.node.note import NoteLiteralNode +from smnp.ast.node.operator import LeftAssociativeOperatorNode from smnp.ast.node.string import StringLiteralNode from smnp.ast.node.type import TypeNode from smnp.ast.parser import Parser from smnp.token.type import TokenType + class MapEntry(ExpressionNode): def __init__(self, pos): super().__init__(pos) diff --git a/smnp/ast/node/note.py b/smnp/ast/node/note.py index 47489ed..ad9726b 100644 --- a/smnp/ast/node/note.py +++ b/smnp/ast/node/note.py @@ -1,5 +1,5 @@ -from smnp.ast.node.access import LeftAssociativeOperatorNode from smnp.ast.node.literal import LiteralNode +from smnp.ast.node.operator import LeftAssociativeOperatorNode from smnp.token.type import TokenType diff --git a/smnp/ast/node/operator.py b/smnp/ast/node/operator.py index c23f320..e94a95b 100644 --- a/smnp/ast/node/operator.py +++ b/smnp/ast/node/operator.py @@ -1,4 +1,69 @@ +from smnp.ast.node.expression import ExpressionNode from smnp.ast.node.model import Node +from smnp.ast.node.none import NoneNode +from smnp.ast.parser import Parser +from smnp.error.syntax import SyntaxException +from smnp.token.type import TokenType + + +class LeftAssociativeOperatorNode(ExpressionNode): + def __init__(self, pos): + super().__init__(pos) + self.children = [NoneNode(), NoneNode(), NoneNode()] + + @property + def left(self): + return self[0] + + @left.setter + def left(self, value): + self[0] = value + + @property + def operator(self): + return self[1] + + @operator.setter + def operator(self, value): + self[1] = value + + @property + def right(self): + return self[2] + + @right.setter + def right(self, value): + self[2] = value + + @classmethod + def _parse(cls, input): + def createNode(left, operator, right): + node = LeftAssociativeOperatorNode(right.pos) + node.left = left + node.operator = operator + node.right = right + return node + + return Parser.leftAssociativeOperatorParser( + cls._literalParser(), + TokenType.DOT, + cls._parseAccessingProperty(), + createNode=createNode + )(input) + + @classmethod + def _literalParser(cls): + pass + + @staticmethod + def _parseAccessingProperty(): + from smnp.ast.node.identifier import IdentifierNode + + return Parser.oneOf( + IdentifierNode._literalParser(), + IdentifierNode._functionCallParser(), + exception=lambda input: SyntaxException(f"Expected property name or method call, found '{input.current().rawValue}'", input.currentPos()) + ) class OperatorNode(Node): diff --git a/smnp/ast/node/string.py b/smnp/ast/node/string.py index 3df2fe8..010e376 100644 --- a/smnp/ast/node/string.py +++ b/smnp/ast/node/string.py @@ -1,5 +1,5 @@ -from smnp.ast.node.access import LeftAssociativeOperatorNode from smnp.ast.node.literal import LiteralNode +from smnp.ast.node.operator import LeftAssociativeOperatorNode from smnp.token.type import TokenType diff --git a/smnp/ast/node/type.py b/smnp/ast/node/type.py index 691db17..c469489 100644 --- a/smnp/ast/node/type.py +++ b/smnp/ast/node/type.py @@ -1,6 +1,6 @@ -from smnp.ast.node.access import LeftAssociativeOperatorNode from smnp.ast.node.iterable import abstractIterableParser from smnp.ast.node.model import Node +from smnp.ast.node.operator import LeftAssociativeOperatorNode from smnp.ast.parser import Parser from smnp.token.type import TokenType from smnp.type.model import Type diff --git a/smnp/ast/parser.py b/smnp/ast/parser.py index f6a2903..d54b1e8 100644 --- a/smnp/ast/parser.py +++ b/smnp/ast/parser.py @@ -1,7 +1,6 @@ from smnp.ast.node.ignore import IgnoredNode from smnp.ast.node.model import ParseResult, Node from smnp.ast.node.none import NoneNode -from smnp.ast.node.operator import OperatorNode from smnp.error.syntax import SyntaxException @@ -95,6 +94,7 @@ class Parser: # leftAssociative -> left | left OP right @staticmethod def leftAssociativeOperatorParser(leftParser, operatorTokenType, rightParser, createNode): + from smnp.ast.node.operator import OperatorNode def parse(input): left = leftParser(input) if left.result: diff --git a/smnp/runtime/evaluators/expression.py b/smnp/runtime/evaluators/expression.py index b78615a..35ff34e 100644 --- a/smnp/runtime/evaluators/expression.py +++ b/smnp/runtime/evaluators/expression.py @@ -1,4 +1,3 @@ -from smnp.ast.node.access import LeftAssociativeOperatorNode from smnp.ast.node.assignment import AssignmentNode from smnp.ast.node.asterisk import AsteriskNode from smnp.ast.node.bool import BoolLiteralNode @@ -8,6 +7,7 @@ from smnp.ast.node.invocation import FunctionCallNode from smnp.ast.node.list import ListNode from smnp.ast.node.map import MapNode from smnp.ast.node.note import NoteLiteralNode +from smnp.ast.node.operator import LeftAssociativeOperatorNode from smnp.ast.node.string import StringLiteralNode from smnp.ast.node.type import TypeNode from smnp.error.runtime import RuntimeException