Create evaluator for sum (sum, subtraction and string concatenation)
This commit is contained in:
@@ -1,11 +1,22 @@
|
|||||||
from smnp.ast.node.operator import BinaryOperator
|
from smnp.ast.node.operator import BinaryOperator
|
||||||
from smnp.ast.node.term import TermParser
|
from smnp.ast.node.term import TermParser
|
||||||
from smnp.ast.node.valuable import Valuable
|
|
||||||
from smnp.ast.parser import Parser
|
from smnp.ast.parser import Parser
|
||||||
from smnp.token.type import TokenType
|
from smnp.token.type import TokenType
|
||||||
|
|
||||||
|
|
||||||
class Expression(Valuable):
|
class Sum(BinaryOperator):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class Relation(BinaryOperator):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class And(BinaryOperator):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class Or(BinaryOperator):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
@@ -16,28 +27,28 @@ def ExpressionParser(input):
|
|||||||
TermParser,
|
TermParser,
|
||||||
[TokenType.PLUS, TokenType.MINUS],
|
[TokenType.PLUS, TokenType.MINUS],
|
||||||
TermParser,
|
TermParser,
|
||||||
lambda left, op, right: Expression.withValue(BinaryOperator.withValues(left, op, right))
|
lambda left, op, right: Sum.withValues(left, op, right)
|
||||||
)
|
)
|
||||||
|
|
||||||
expr2 = Parser.leftAssociativeOperatorParser(
|
expr2 = Parser.leftAssociativeOperatorParser(
|
||||||
expr1,
|
expr1,
|
||||||
[TokenType.RELATION, TokenType.OPEN_ANGLE, TokenType.CLOSE_ANGLE],
|
[TokenType.RELATION, TokenType.OPEN_ANGLE, TokenType.CLOSE_ANGLE],
|
||||||
expr1,
|
expr1,
|
||||||
lambda left, op, right: Expression.withValue(BinaryOperator.withValues(left, op, right))
|
lambda left, op, right: Relation.withValues(left, op, right)
|
||||||
)
|
)
|
||||||
|
|
||||||
expr3 = Parser.leftAssociativeOperatorParser(
|
expr3 = Parser.leftAssociativeOperatorParser(
|
||||||
expr2,
|
expr2,
|
||||||
[TokenType.AND],
|
[TokenType.AND],
|
||||||
expr2,
|
expr2,
|
||||||
lambda left, op, right: Expression.withValue(BinaryOperator.withValues(left, op, right))
|
lambda left, op, right: And.withValues(left, op, right)
|
||||||
)
|
)
|
||||||
|
|
||||||
expr4 = Parser.leftAssociativeOperatorParser(
|
expr4 = Parser.leftAssociativeOperatorParser(
|
||||||
expr3,
|
expr3,
|
||||||
[TokenType.OR],
|
[TokenType.OR],
|
||||||
expr3,
|
expr3,
|
||||||
lambda left, op, right: Expression.withValue(BinaryOperator.withValues(left, op, right))
|
lambda left, op, right: Or.withValues(left, op, right)
|
||||||
)
|
)
|
||||||
|
|
||||||
ifElseExpression = Parser.allOf(
|
ifElseExpression = Parser.allOf(
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
from smnp.ast.node.expression import Sum
|
||||||
from smnp.ast.node.factor import NotOperator, Power, Loop
|
from smnp.ast.node.factor import NotOperator, Power, Loop
|
||||||
from smnp.ast.node.identifier import FunctionCall, Assignment
|
from smnp.ast.node.identifier import FunctionCall, Assignment
|
||||||
from smnp.ast.node.term import Product
|
from smnp.ast.node.term import Product
|
||||||
@@ -19,6 +20,7 @@ def expressionEvaluator(doAssert=False):
|
|||||||
from smnp.runtime.evaluators.assignment import AssignmentEvaluator
|
from smnp.runtime.evaluators.assignment import AssignmentEvaluator
|
||||||
from smnp.runtime.evaluators.product import ProductEvaluator
|
from smnp.runtime.evaluators.product import ProductEvaluator
|
||||||
|
|
||||||
|
from smnp.runtime.evaluators.sum import SumEvaluator
|
||||||
result = Evaluator.oneOf(
|
result = Evaluator.oneOf(
|
||||||
Evaluator.forNodes(FunctionCallEvaluator.evaluate, FunctionCall),
|
Evaluator.forNodes(FunctionCallEvaluator.evaluate, FunctionCall),
|
||||||
Evaluator.forNodes(MinusEvaluator.evaluate, MinusOperator),
|
Evaluator.forNodes(MinusEvaluator.evaluate, MinusOperator),
|
||||||
@@ -28,6 +30,7 @@ def expressionEvaluator(doAssert=False):
|
|||||||
Evaluator.forNodes(LoopEvaluator.evaluate, Loop),
|
Evaluator.forNodes(LoopEvaluator.evaluate, Loop),
|
||||||
Evaluator.forNodes(AssignmentEvaluator.evaluate, Assignment),
|
Evaluator.forNodes(AssignmentEvaluator.evaluate, Assignment),
|
||||||
Evaluator.forNodes(ProductEvaluator.evaluate, Product),
|
Evaluator.forNodes(ProductEvaluator.evaluate, Product),
|
||||||
|
Evaluator.forNodes(SumEvaluator.evaluate, Sum),
|
||||||
AtomEvaluator.evaluate
|
AtomEvaluator.evaluate
|
||||||
)(node, environment)
|
)(node, environment)
|
||||||
|
|
||||||
|
|||||||
40
smnp/runtime/evaluators/sum.py
Normal file
40
smnp/runtime/evaluators/sum.py
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
from smnp.error.runtime import RuntimeException
|
||||||
|
from smnp.runtime.evaluator import Evaluator
|
||||||
|
from smnp.runtime.evaluators.expression import expressionEvaluator
|
||||||
|
from smnp.type.model import Type
|
||||||
|
|
||||||
|
|
||||||
|
class SumEvaluator(Evaluator):
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def evaluator(cls, node, environment):
|
||||||
|
left = expressionEvaluator(doAssert=True)(node.left, environment).value
|
||||||
|
right = expressionEvaluator(doAssert=True)(node.right, environment).value
|
||||||
|
|
||||||
|
if left.type == right.type == Type.INTEGER:
|
||||||
|
return cls.integerEvaluator(left, node.operator, right)
|
||||||
|
|
||||||
|
if left.type == right.type == Type.STRING:
|
||||||
|
return cls.stringEvaluator(left, node.operator, right)
|
||||||
|
|
||||||
|
raise RuntimeException(f"Operator {node.operator.value} is not supported by {left.type.name.lower()} and {right.type.name.lower()} types", node.operator.pos)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def integerEvaluator(cls, left, operator, right):
|
||||||
|
if operator.value == "+":
|
||||||
|
return Type.integer(left.value + right.value)
|
||||||
|
|
||||||
|
if operator.value == "-":
|
||||||
|
return Type.integer(left.value - right.value)
|
||||||
|
|
||||||
|
raise RuntimeError("This line should never be reached")
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def stringEvaluator(cls, left, operator, right):
|
||||||
|
if operator.value == "+":
|
||||||
|
return Type.string(left.value + right.value)
|
||||||
|
|
||||||
|
if operator.value == "-":
|
||||||
|
raise RuntimeException(f"Operator {operator.value} is not supported by string types", operator.pos)
|
||||||
|
|
||||||
|
raise RuntimeError("This line should never be reached")
|
||||||
Reference in New Issue
Block a user