Make access node more generic
This commit is contained in:
@@ -1,14 +1,14 @@
|
||||
from smnp.ast.node.expression import ExpressionNode
|
||||
from smnp.ast.node.ignore import IgnoredNode
|
||||
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 AccessNode(ExpressionNode):
|
||||
class LeftAssociativeOperatorNode(ExpressionNode):
|
||||
def __init__(self, pos):
|
||||
super().__init__(pos)
|
||||
self.children.append(IgnoredNode(pos))
|
||||
self.children = [NoneNode(), NoneNode(), NoneNode()]
|
||||
|
||||
@property
|
||||
def left(self):
|
||||
@@ -19,18 +19,27 @@ class AccessNode(ExpressionNode):
|
||||
self[0] = value
|
||||
|
||||
@property
|
||||
def right(self):
|
||||
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[1] = value
|
||||
self[2] = value
|
||||
|
||||
@classmethod
|
||||
def _parse(cls, input):
|
||||
def createNode(left, right):
|
||||
node = AccessNode(right.pos)
|
||||
def createNode(left, operator, right):
|
||||
node = LeftAssociativeOperatorNode(right.pos)
|
||||
node.left = left
|
||||
node.operator = operator
|
||||
node.right = right
|
||||
return node
|
||||
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
from smnp.ast.node.access import AccessNode
|
||||
from smnp.ast.node.access import LeftAssociativeOperatorNode
|
||||
from smnp.ast.node.literal import LiteralNode
|
||||
from smnp.token.type import TokenType
|
||||
|
||||
|
||||
class BoolLiteralNode(LiteralNode, AccessNode):
|
||||
class BoolLiteralNode(LiteralNode, LeftAssociativeOperatorNode):
|
||||
def __init__(self, pos):
|
||||
super().__init__(pos)
|
||||
del self.children[1]
|
||||
self.children = [None]
|
||||
|
||||
@classmethod
|
||||
def _getTokenType(cls):
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
from smnp.ast.node.access import AccessNode
|
||||
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
|
||||
@@ -6,10 +6,10 @@ from smnp.ast.parser import Parser
|
||||
from smnp.token.type import TokenType
|
||||
|
||||
|
||||
class IdentifierNode(AccessNode):
|
||||
class IdentifierNode(LeftAssociativeOperatorNode):
|
||||
def __init__(self, pos):
|
||||
super().__init__(pos)
|
||||
del self.children[1]
|
||||
self.children = [None]
|
||||
|
||||
@classmethod
|
||||
def _literalParser(cls):
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
from smnp.ast.node.access import AccessNode
|
||||
from smnp.ast.node.access import LeftAssociativeOperatorNode
|
||||
from smnp.ast.parser import Parser
|
||||
from smnp.token.type import TokenType
|
||||
|
||||
|
||||
class IntegerLiteralNode(AccessNode):
|
||||
class IntegerLiteralNode(LeftAssociativeOperatorNode):
|
||||
def __init__(self, pos):
|
||||
super().__init__(pos)
|
||||
del self.children[1]
|
||||
self.children = [None]
|
||||
|
||||
@classmethod
|
||||
def _literalParser(cls):
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
from smnp.ast.node.access import AccessNode
|
||||
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.parser import Parser
|
||||
from smnp.token.type import TokenType
|
||||
|
||||
@@ -14,9 +15,10 @@ class ArgumentsListNode(Node):
|
||||
Parser.doAssert(ExpressionNode.parse, "expression"))(input)
|
||||
|
||||
|
||||
class FunctionCallNode(AccessNode):
|
||||
class FunctionCallNode(LeftAssociativeOperatorNode):
|
||||
def __init__(self, pos):
|
||||
super().__init__(pos)
|
||||
self.children = [NoneNode(), NoneNode()]
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
from smnp.ast.node.access import AccessNode
|
||||
from smnp.ast.node.access import LeftAssociativeOperatorNode
|
||||
from smnp.ast.node.expression import ExpressionNode
|
||||
from smnp.ast.node.iterable import abstractIterableParser
|
||||
from smnp.ast.parser import Parser
|
||||
from smnp.token.type import TokenType
|
||||
|
||||
|
||||
class ListNode(AccessNode):
|
||||
class ListNode(LeftAssociativeOperatorNode):
|
||||
|
||||
@classmethod
|
||||
def _literalParser(cls):
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
from smnp.ast.node.access import AccessNode
|
||||
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
|
||||
@@ -31,7 +31,7 @@ class MapEntry(ExpressionNode):
|
||||
def value(self, value):
|
||||
self[1] = value
|
||||
|
||||
class MapNode(AccessNode):
|
||||
class MapNode(LeftAssociativeOperatorNode):
|
||||
|
||||
@classmethod
|
||||
def _literalParser(cls):
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
from smnp.ast.node.access import AccessNode
|
||||
from smnp.ast.node.access import LeftAssociativeOperatorNode
|
||||
from smnp.ast.node.literal import LiteralNode
|
||||
from smnp.token.type import TokenType
|
||||
|
||||
|
||||
class NoteLiteralNode(LiteralNode, AccessNode):
|
||||
class NoteLiteralNode(LiteralNode, LeftAssociativeOperatorNode):
|
||||
def __init__(self, pos):
|
||||
super().__init__(pos)
|
||||
del self.children[1]
|
||||
self.children = [None]
|
||||
|
||||
@classmethod
|
||||
def _getTokenType(cls):
|
||||
|
||||
15
smnp/ast/node/operator.py
Normal file
15
smnp/ast/node/operator.py
Normal file
@@ -0,0 +1,15 @@
|
||||
from smnp.ast.node.model import Node
|
||||
|
||||
|
||||
class OperatorNode(Node):
|
||||
def __init__(self, pos):
|
||||
super().__init__(pos)
|
||||
self.children = [None]
|
||||
|
||||
@property
|
||||
def value(self):
|
||||
return self[0]
|
||||
|
||||
@value.setter
|
||||
def value(self, value):
|
||||
self[0] = value
|
||||
@@ -1,12 +1,12 @@
|
||||
from smnp.ast.node.access import AccessNode
|
||||
from smnp.ast.node.access import LeftAssociativeOperatorNode
|
||||
from smnp.ast.node.literal import LiteralNode
|
||||
from smnp.token.type import TokenType
|
||||
|
||||
|
||||
class StringLiteralNode(LiteralNode, AccessNode):
|
||||
class StringLiteralNode(LiteralNode, LeftAssociativeOperatorNode):
|
||||
def __init__(self, pos):
|
||||
super().__init__(pos)
|
||||
del self.children[1]
|
||||
self.children = [None]
|
||||
|
||||
@classmethod
|
||||
def _getTokenType(cls):
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
from smnp.ast.node.access import AccessNode
|
||||
from smnp.ast.node.access import LeftAssociativeOperatorNode
|
||||
from smnp.ast.node.iterable import abstractIterableParser
|
||||
from smnp.ast.node.model import Node
|
||||
from smnp.ast.parser import Parser
|
||||
@@ -24,7 +24,7 @@ class TypeSpecifiers(Node):
|
||||
pass
|
||||
|
||||
|
||||
class TypeNode(AccessNode):
|
||||
class TypeNode(LeftAssociativeOperatorNode):
|
||||
def __init__(self, pos):
|
||||
super().__init__(pos)
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
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
|
||||
|
||||
|
||||
@@ -97,10 +98,11 @@ class Parser:
|
||||
def parse(input):
|
||||
left = leftParser(input)
|
||||
if left.result:
|
||||
while Parser.terminalParser(operatorTokenType)(input).result:
|
||||
operator = Parser.terminalParser(operatorTokenType, lambda val, pos: OperatorNode.withChildren([val], pos))(input)
|
||||
while operator.result:
|
||||
right = rightParser(input)
|
||||
left = ParseResult.OK(createNode(left.node, right.node))
|
||||
|
||||
left = ParseResult.OK(createNode(left.node, operator.node, right.node))
|
||||
operator = Parser.terminalParser(operatorTokenType, lambda val, pos: OperatorNode.withChildren([val], pos))(input)
|
||||
return left
|
||||
|
||||
return ParseResult.FAIL()
|
||||
|
||||
@@ -8,7 +8,7 @@ from smnp.program.interpreter import Interpreter
|
||||
def main():
|
||||
try:
|
||||
stdLibraryEnv = loadStandardLibrary()
|
||||
Interpreter.interpretFile(sys.argv[1], printTokens=False, printAst=True, baseEnvironment=stdLibraryEnv)
|
||||
Interpreter.interpretFile(sys.argv[1], printTokens=False, printAst=True, execute=False, baseEnvironment=stdLibraryEnv)
|
||||
|
||||
except SmnpException as e:
|
||||
print(e.message())
|
||||
|
||||
@@ -9,15 +9,15 @@ from smnp.token.tokenizer import tokenize
|
||||
class Interpreter:
|
||||
|
||||
@staticmethod
|
||||
def interpretString(string, printTokens=False, printAst=False, baseEnvironment=None):
|
||||
return Interpreter._interpret(string.splitlines(), printTokens, printAst, baseEnvironment)
|
||||
def interpretString(string, printTokens=False, printAst=False, execute=True, baseEnvironment=None):
|
||||
return Interpreter._interpret(string.splitlines(), printTokens, printAst, execute, baseEnvironment)
|
||||
|
||||
@staticmethod
|
||||
def interpretFile(file, printTokens=False, printAst=False, baseEnvironment=None):
|
||||
return Interpreter._interpret(readLines(file), printTokens, printAst, baseEnvironment)
|
||||
def interpretFile(file, printTokens=False, printAst=False, execute=True, baseEnvironment=None):
|
||||
return Interpreter._interpret(readLines(file), printTokens, printAst, execute, baseEnvironment)
|
||||
|
||||
@staticmethod
|
||||
def _interpret(lines, printTokens=False, printAst=False, baseEnvironment=None):
|
||||
def _interpret(lines, printTokens=False, printAst=False, execute=True, baseEnvironment=None):
|
||||
environment = createEnvironment()
|
||||
if baseEnvironment is not None:
|
||||
environment.extend(baseEnvironment)
|
||||
@@ -31,6 +31,7 @@ class Interpreter:
|
||||
if printAst:
|
||||
ast.print()
|
||||
|
||||
if execute:
|
||||
evaluate(ast, environment)
|
||||
|
||||
return environment
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
from smnp.ast.node.access import AccessNode
|
||||
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
|
||||
@@ -39,7 +39,7 @@ def expressionEvaluator(doAssert=False):
|
||||
Evaluator.forNodes(TypeEvaluator.evaluate, TypeNode),
|
||||
Evaluator.forNodes(IdentifierEvaluator.evaluate, IdentifierNode),
|
||||
Evaluator.forNodes(ListEvaluator.evaluate, ListNode),
|
||||
Evaluator.forNodes(AccessEvaluator.evaluate, AccessNode),
|
||||
Evaluator.forNodes(AccessEvaluator.evaluate, LeftAssociativeOperatorNode),
|
||||
Evaluator.forNodes(AssignmentEvaluator.evaluate, AssignmentNode),
|
||||
Evaluator.forNodes(AsteriskEvaluator.evaluate, AsteriskNode),
|
||||
Evaluator.forNodes(MapEvaluator.evaluate, MapNode)
|
||||
|
||||
Reference in New Issue
Block a user