Create working PoC of loop statement
This commit is contained in:
@@ -7,7 +7,7 @@ from smnp.program.interpreter import Interpreter
|
|||||||
def main():
|
def main():
|
||||||
try:
|
try:
|
||||||
#stdLibraryEnv = loadStandardLibrary()
|
#stdLibraryEnv = loadStandardLibrary()
|
||||||
Interpreter.interpretFile(sys.argv[1], printTokens=False, printAst=True, execute=True, baseEnvironment=None)
|
Interpreter.interpretFile(sys.argv[1], printTokens=False, printAst=False, execute=True, baseEnvironment=None)
|
||||||
#draft()
|
#draft()
|
||||||
#tokens = tokenize(['function a(b...) { x+y}'])
|
#tokens = tokenize(['function a(b...) { x+y}'])
|
||||||
#FunctionDefinitionParser(tokens).node.print()
|
#FunctionDefinitionParser(tokens).node.print()
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
from smnp.error.runtime import RuntimeException
|
|
||||||
from smnp.runtime.evaluator import Evaluator
|
from smnp.runtime.evaluator import Evaluator
|
||||||
from smnp.runtime.evaluators.expression import expressionEvaluator
|
from smnp.runtime.evaluators.expression import expressionEvaluator
|
||||||
|
|
||||||
@@ -7,11 +6,8 @@ class AssignmentEvaluator(Evaluator):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def evaluator(cls, node, environment):
|
def evaluator(cls, node, environment):
|
||||||
target = node.target.value
|
target = node.left.value
|
||||||
if target.startswith("_"):
|
value = expressionEvaluator(doAssert=True)(node.right, environment).value #TODO check if it isn't necessary to verify 'result' attr of EvaluatioNResult
|
||||||
raise RuntimeException("Declaration and assignation variables with names starting with '_' is not allowed", node.target.pos)
|
|
||||||
|
|
||||||
value = expressionEvaluator(doAssert=True)(node.value, environment).value #TODO check if it isn't necessary to verify 'result' attr of EvaluatioNResult
|
|
||||||
scopeOfExistingVariable = environment.findVariableScope(target)
|
scopeOfExistingVariable = environment.findVariableScope(target)
|
||||||
if scopeOfExistingVariable is None:
|
if scopeOfExistingVariable is None:
|
||||||
environment.scopes[-1][target] = value
|
environment.scopes[-1][target] = value
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
from smnp.ast.node.factor import NotOperator, Power
|
from smnp.ast.node.factor import NotOperator, Power, Loop
|
||||||
from smnp.ast.node.identifier import FunctionCall
|
from smnp.ast.node.identifier import FunctionCall, Assignment
|
||||||
from smnp.ast.node.unit import MinusOperator, Access
|
from smnp.ast.node.unit import MinusOperator, Access
|
||||||
from smnp.error.runtime import RuntimeException
|
from smnp.error.runtime import RuntimeException
|
||||||
from smnp.runtime.evaluator import Evaluator
|
from smnp.runtime.evaluator import Evaluator
|
||||||
@@ -10,17 +10,21 @@ def expressionEvaluator(doAssert=False):
|
|||||||
def evaluateExpression(node, environment):
|
def evaluateExpression(node, environment):
|
||||||
from smnp.runtime.evaluators.function import FunctionCallEvaluator
|
from smnp.runtime.evaluators.function import FunctionCallEvaluator
|
||||||
from smnp.runtime.evaluators.minus import MinusEvaluator
|
from smnp.runtime.evaluators.minus import MinusEvaluator
|
||||||
|
|
||||||
from smnp.runtime.evaluators.atom import AtomEvaluator
|
from smnp.runtime.evaluators.atom import AtomEvaluator
|
||||||
from smnp.runtime.evaluators.access import AccessEvaluator
|
from smnp.runtime.evaluators.access import AccessEvaluator
|
||||||
from smnp.runtime.evaluators.negation import NotEvaluator
|
from smnp.runtime.evaluators.negation import NotEvaluator
|
||||||
from smnp.runtime.evaluators.power import PowerEvaluator
|
from smnp.runtime.evaluators.power import PowerEvaluator
|
||||||
|
|
||||||
|
from smnp.runtime.evaluators.loop import LoopEvaluator
|
||||||
|
from smnp.runtime.evaluators.assignment import AssignmentEvaluator
|
||||||
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),
|
||||||
Evaluator.forNodes(AccessEvaluator.evaluate, Access),
|
Evaluator.forNodes(AccessEvaluator.evaluate, Access),
|
||||||
Evaluator.forNodes(NotEvaluator.evaluate, NotOperator),
|
Evaluator.forNodes(NotEvaluator.evaluate, NotOperator),
|
||||||
Evaluator.forNodes(PowerEvaluator.evaluate, Power),
|
Evaluator.forNodes(PowerEvaluator.evaluate, Power),
|
||||||
|
Evaluator.forNodes(LoopEvaluator.evaluate, Loop),
|
||||||
|
Evaluator.forNodes(AssignmentEvaluator.evaluate, Assignment),
|
||||||
AtomEvaluator.evaluate
|
AtomEvaluator.evaluate
|
||||||
)(node, environment)
|
)(node, environment)
|
||||||
|
|
||||||
|
|||||||
109
smnp/runtime/evaluators/loop.py
Normal file
109
smnp/runtime/evaluators/loop.py
Normal file
@@ -0,0 +1,109 @@
|
|||||||
|
from smnp.ast.node.none import NoneNode
|
||||||
|
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 LoopEvaluator(Evaluator):
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def evaluator(cls, node, environment):
|
||||||
|
iterator = expressionEvaluator(doAssert=True)(node.left, environment).value
|
||||||
|
parameters = [ identifier.value for identifier in node.parameters ] if type(node.parameters) != NoneNode() else []
|
||||||
|
|
||||||
|
try:
|
||||||
|
output = {
|
||||||
|
Type.INTEGER: cls.numberEvaluator,
|
||||||
|
Type.BOOL: cls.boolEvaluator,
|
||||||
|
Type.LIST: cls.listEvaluator,
|
||||||
|
Type.MAP: cls.mapEvaluator
|
||||||
|
}[iterator.type](node, environment, iterator, parameters)
|
||||||
|
except KeyError:
|
||||||
|
raise RuntimeException(f"The {iterator.type.name.lower()} type cannot stand as an iterator for loop statement", node.left.pos)
|
||||||
|
|
||||||
|
return Type.list(output)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def numberEvaluator(cls, node, environment, evaluatedIterator, parameters):
|
||||||
|
output = []
|
||||||
|
|
||||||
|
environment.scopes.append({})
|
||||||
|
|
||||||
|
if len(parameters) > 1:
|
||||||
|
raise RuntimeException(f"Loop with numeric iterator can handle only one parameter", node.parameters.pos)
|
||||||
|
|
||||||
|
for i in range(evaluatedIterator.value):
|
||||||
|
if len(parameters) > 0:
|
||||||
|
environment.scopes[-1][parameters[0]] = Type.integer(i)
|
||||||
|
|
||||||
|
output.append(evaluate(node.right, environment).value)
|
||||||
|
|
||||||
|
environment.scopes.pop(-1)
|
||||||
|
|
||||||
|
return output
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def boolEvaluator(cls, node, environment, evaluatedIterator, parameters):
|
||||||
|
output = []
|
||||||
|
|
||||||
|
environment.scopes.append({})
|
||||||
|
|
||||||
|
if len(parameters) > 0:
|
||||||
|
raise RuntimeException(f"Loop with logic iterator can't' handle any parameters", node.parameters.pos)
|
||||||
|
|
||||||
|
condition = evaluatedIterator
|
||||||
|
while condition.value:
|
||||||
|
output.append(evaluate(node.right, environment).value)
|
||||||
|
condition = expressionEvaluator(doAssert=True)(node.left, environment).value
|
||||||
|
|
||||||
|
environment.scopes.pop(-1)
|
||||||
|
|
||||||
|
return output
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def listEvaluator(cls, node, environment, evaluatedIterator, parameters):
|
||||||
|
output = []
|
||||||
|
|
||||||
|
if len(parameters) > 2:
|
||||||
|
raise RuntimeException(f"Loop with list iterator can handle only two parameters", node.parameters.pos)
|
||||||
|
|
||||||
|
for i, value in enumerate(evaluatedIterator.value):
|
||||||
|
if len(parameters) == 1:
|
||||||
|
environment.scopes[-1][parameters[0]] = value
|
||||||
|
if len(parameters) == 2:
|
||||||
|
environment.scopes[-1][parameters[0]] = Type.integer(i)
|
||||||
|
environment.scopes[-1][parameters[1]] = value
|
||||||
|
|
||||||
|
output.append(evaluate(node.right, environment).value)
|
||||||
|
|
||||||
|
environment.scopes.pop(-1)
|
||||||
|
|
||||||
|
return output
|
||||||
|
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def mapEvaluator(cls, node, environment, evaluatedIterator, parameters):
|
||||||
|
output = []
|
||||||
|
|
||||||
|
if len(parameters) > 3:
|
||||||
|
raise RuntimeException(f"Loop with map iterator can handle only three parameters", node.parameters.pos)
|
||||||
|
|
||||||
|
i = 0
|
||||||
|
for key, value in evaluatedIterator.value.items():
|
||||||
|
if len(parameters) == 1:
|
||||||
|
environment.scopes[-1][parameters[0]] = value
|
||||||
|
if len(parameters) == 2:
|
||||||
|
environment.scopes[-1][parameters[0]] = key
|
||||||
|
environment.scopes[-1][parameters[1]] = value
|
||||||
|
if len(parameters) == 3:
|
||||||
|
environment.scopes[-1][parameters[0]] = Type.integer(i)
|
||||||
|
environment.scopes[-1][parameters[1]] = key
|
||||||
|
environment.scopes[-1][parameters[2]] = value
|
||||||
|
i += 1
|
||||||
|
|
||||||
|
output.append(evaluate(node.right, environment).value)
|
||||||
|
|
||||||
|
environment.scopes.pop(-1)
|
||||||
|
|
||||||
|
return output
|
||||||
@@ -73,6 +73,7 @@ class Type(Enum):
|
|||||||
def void():
|
def void():
|
||||||
return Value(Type.VOID, None)
|
return Value(Type.VOID, None)
|
||||||
|
|
||||||
|
|
||||||
def _failStringify(t):
|
def _failStringify(t):
|
||||||
raise RuntimeException(f"Not able to interpret {t.name}'", None)
|
raise RuntimeException(f"Not able to interpret {t.name}'", None)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user