Make access node more generic

This commit is contained in:
Bartłomiej Pluta
2019-07-10 16:51:11 +02:00
parent 823c5cb18f
commit 88b245dc05
15 changed files with 71 additions and 42 deletions

View File

@@ -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

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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
View 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

View File

@@ -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):

View File

@@ -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)

View File

@@ -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()

View File

@@ -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())

View File

@@ -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,7 +31,8 @@ class Interpreter:
if printAst:
ast.print()
evaluate(ast, environment)
if execute:
evaluate(ast, environment)
return environment
except RuntimeException as e:

View File

@@ -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)