Files
femcode/src/interpreter.py

111 lines
3.4 KiB
Python
Raw Normal View History

class Interpreter:
def __init__(self, ast):
self.ast = ast
self.variables = {}
self.functions = {}
def interpret(self):
for node in self.ast:
self.visit(node)
def visit(self, node):
method_name = f'visit_{type(node).__name__}'
method = getattr(self, method_name, self.no_visit_method)
return method(node)
def no_visit_method(self, node):
raise Exception(f'No visit_{type(node).__name__} method defined')
def visit_Number(self, node):
return node.value
2025-07-22 16:17:32 +02:00
def visit_String(self, node):
return node.value
def visit_BinOp(self, node):
2025-07-22 16:17:32 +02:00
left_val = self.visit(node.left)
right_val = self.visit(node.right)
if node.op.type == 'PLUS':
2025-07-22 16:17:32 +02:00
return left_val + right_val
elif node.op.type == 'MINUS':
2025-07-22 16:17:32 +02:00
return left_val - right_val
elif node.op.type == 'MUL':
2025-07-22 16:17:32 +02:00
return left_val * right_val
elif node.op.type == 'DIV':
2025-07-22 16:17:32 +02:00
return left_val / right_val
def visit_Comparison(self, node):
left_val = self.visit(node.left)
right_val = self.visit(node.right)
if node.op.type == 'EQ':
return left_val == right_val
elif node.op.type == 'NEQ':
return left_val != right_val
elif node.op.type == 'GT':
return left_val > right_val
elif node.op.type == 'GTE':
return left_val >= right_val
elif node.op.type == 'LT':
return left_val < right_val
elif node.op.type == 'LTE':
return left_val <= right_val
def visit_Print(self, node):
value_to_print = self.visit(node.value)
print(value_to_print)
def visit_Assign(self, node):
var_name = node.left.value
value = self.visit(node.right)
self.variables[var_name] = value
def visit_Variable(self, node):
var_name = node.value
if var_name in self.variables:
return self.variables[var_name]
else:
raise NameError(f"name '{var_name}' is not defined")
2025-07-22 16:17:32 +02:00
def visit_Block(self, node):
for statement in node.statements:
self.visit(statement)
def visit_IfStatement(self, node):
condition_result = self.visit(node.condition)
if condition_result:
self.visit(node.if_block)
elif node.else_block:
self.visit(node.else_block)
2025-07-22 16:22:49 +02:00
def visit_WhileStatement(self, node):
while self.visit(node.condition):
self.visit(node.body)
def visit_FunctionDefinition(self, node):
self.functions[node.name] = {
'parameters': node.parameters,
'body': node.body
}
def visit_FunctionCall(self, node):
func_name = node.name
if func_name not in self.functions:
raise NameError(f"Function '{func_name}' is not defined")
func_info = self.functions[func_name]
# For simplicity, no arguments are passed for now
# In a real interpreter, you'd push a new scope and bind arguments to parameters
# Execute function body
try:
self.visit(func_info['body'])
except ReturnValue as e:
return e.value
def visit_ReturnStatement(self, node):
raise ReturnValue(self.visit(node.value))
class ReturnValue(Exception):
def __init__(self, value):
self.value = value