Create if-else statement evaluator

This commit is contained in:
Bartłomiej Pluta
2019-07-12 21:33:54 +02:00
parent 95e6a5f95d
commit b31e17d176
5 changed files with 46 additions and 18 deletions

View File

@@ -21,8 +21,6 @@ class Or(BinaryOperator):
def ExpressionParser(input):
from smnp.ast.node.condition import IfElse
expr1 = Parser.leftAssociativeOperatorParser(
TermParser,
[TokenType.PLUS, TokenType.MINUS],
@@ -44,24 +42,10 @@ def ExpressionParser(input):
lambda left, op, right: And.withValues(left, op, right)
)
expr4 = Parser.leftAssociativeOperatorParser(
return Parser.leftAssociativeOperatorParser(
expr3,
[TokenType.OR],
expr3,
lambda left, op, right: Or.withValues(left, op, right)
)
ifElseExpression = Parser.allOf(
expr4,
Parser.terminal(TokenType.IF),
Parser.doAssert(expr4, "expression"),
Parser.terminal(TokenType.ELSE, doAssert=True),
Parser.doAssert(expr4, "expression"),
createNode=lambda ifNode, _, condition, __, elseNode: IfElse.createNode(ifNode, condition, elseNode)
)
return Parser.oneOf(
ifElseExpression,
expr4,
)(input)

View File

@@ -7,7 +7,7 @@ from smnp.program.interpreter import Interpreter
def main():
try:
#stdLibraryEnv = loadStandardLibrary()
Interpreter.interpretFile(sys.argv[1], printTokens=False, printAst=False, execute=True, baseEnvironment=None)
Interpreter.interpretFile(sys.argv[1], printTokens=False, printAst=True, execute=True, baseEnvironment=None)
#draft()
#tokens = tokenize(['function a(b...) { x+y}'])
#FunctionDefinitionParser(tokens).node.print()

View File

@@ -1,3 +1,5 @@
from smnp.ast.node.block import Block
from smnp.ast.node.condition import IfElse
from smnp.ast.node.program import Program
from smnp.error.runtime import RuntimeException
from smnp.type.model import Type
@@ -65,8 +67,12 @@ def evaluate(node, environment):
from smnp.runtime.evaluators.program import ProgramEvaluator
from smnp.runtime.evaluators.expression import expressionEvaluator
from smnp.runtime.evaluators.condition import IfElseStatementEvaluator
from smnp.runtime.evaluators.block import BlockEvaluator
result = Evaluator.oneOf(
Evaluator.forNodes(ProgramEvaluator.evaluate, Program),
Evaluator.forNodes(IfElseStatementEvaluator.evaluate, IfElse),
Evaluator.forNodes(BlockEvaluator.evaluate, Block),
#Evaluator.forNodes(ImportEvaluator.evaluate, ImportNode),
#Evaluator.forNodes(FunctionDefinitionEvaluator.evaluate, FunctionDefinitionNode),
#Evaluator.forNodes(ExtendEvaluator.evaluate, ExtendNode),

View File

@@ -0,0 +1,35 @@
from smnp.error.runtime import RuntimeException
from smnp.runtime.evaluator import Evaluator, evaluate
from smnp.runtime.evaluators.expression import expressionEvaluator
from smnp.type.model import Type
class IfElseEvaluator(Evaluator):
@classmethod
def evaluator(cls, node, environment):
condition = expressionEvaluator(doAssert=True)(node.condition, environment).value
if condition.type != Type.BOOL:
raise RuntimeException(f"Only {Type.BOOL.name.lower()} types can be used as conditions in conditional expression", node.condition.pos)
if condition.value:
return expressionEvaluator(doAssert=True)(node.ifNode, environment).value
else:
return expressionEvaluator(doAssert=True)(node.elseNode, environment).value
class IfElseStatementEvaluator(Evaluator):
@classmethod
def evaluator(cls, node, environment):
condition = expressionEvaluator(doAssert=True)(node.condition, environment).value
if condition.type != Type.BOOL:
raise RuntimeException(
f"Only {Type.BOOL.name.lower()} types can be used as conditions in conditional expression", node.condition.pos)
if condition.value:
evaluate(node.ifNode, environment)
else:
evaluate(node.elseNode, environment)

View File

@@ -1,3 +1,4 @@
from smnp.ast.node.condition import IfElse
from smnp.ast.node.expression import Sum, Relation
from smnp.ast.node.factor import NotOperator, Power, Loop
from smnp.ast.node.identifier import FunctionCall, Assignment
@@ -22,6 +23,7 @@ def expressionEvaluator(doAssert=False):
from smnp.runtime.evaluators.sum import SumEvaluator
from smnp.runtime.evaluators.relation import RelationEvaluator
from smnp.runtime.evaluators.condition import IfElseEvaluator
result = Evaluator.oneOf(
Evaluator.forNodes(FunctionCallEvaluator.evaluate, FunctionCall),
Evaluator.forNodes(MinusEvaluator.evaluate, MinusOperator),
@@ -33,6 +35,7 @@ def expressionEvaluator(doAssert=False):
Evaluator.forNodes(ProductEvaluator.evaluate, Product),
Evaluator.forNodes(SumEvaluator.evaluate, Sum),
Evaluator.forNodes(RelationEvaluator.evaluate, Relation),
Evaluator.forNodes(IfElseEvaluator.evaluate, IfElse),
AtomEvaluator.evaluate
)(node, environment)