Skip to content

Commit

Permalink
basic interpreter functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
johncameronthomas committed Apr 14, 2023
1 parent 55aa019 commit d2c4ec1
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 24 deletions.
39 changes: 30 additions & 9 deletions scribe/Context.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from Error import Runtime_Error

class Context:
def __init__(self, name, parent):
self.name = name
Expand All @@ -10,13 +12,32 @@ def __repr__(self):
else:
return '{} -> {}'.format(self.parent, self.name)

def get(self, name):
value = self.symbol_table.get(name, None)
if value == None and self.parent:
return self.parent.get(name)
def define_symbol(self, identifier: str) -> bool:
if identifier in self.symbol_table.keys():
raise ValueError()
else:
self.symbol_table[identifier] = None

def delete_symbol(self, identifier: str) -> bool:
if identifier in self.symbol_table:
del self.symbol_table[identifier]
else:
raise ValueError()

def get_symbol(self, identifier: str):
if identifier not in self.symbol_table:
if self.parent != None:
return self.parent.get_symbol(identifier)
else:
raise ValueError()
else:
return self.symbol_table[identifier]

def set_symbol(self, identifier: str, data):
if identifier not in self.symbol_table:
if self.parent != None:
return self.parent.set_symbol(identifier, data)
else:
raise ValueError()
else:
return value

def set(self, name, value):
self.symbol_table.update({name: value})
return value
self.symbol_table[identifier] = data
36 changes: 24 additions & 12 deletions scribe/Interpreter.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import Error
from Error import Runtime_Error
from Context import Context
from Node import Data_Node

class Interpreter:
def __init__(self, node, context):
self.node = node
self.context = context

self.error = None

def interpret(self):
Expand All @@ -12,16 +15,25 @@ def interpret(self):
def evaluate_node(self, node):
match node.name:
case 'Integer':
return node.value
case 'Float':
return node.value
case 'Variable Assignment':
return self.context.set(node.middle_child.value, self.evaluate_node(node.right_child))
case 'Indentifier':
result = self.context.get(node.value)
if result == None:
self.error = Error.Runtime_Error('Undefined Variable', "'{}' is undefined.".format(node.value), node.location, self.context)
return 0
return node.data
case 'Rational':
return node.data
case 'Symbol Assignment':
try:
return self.context.set_symbol(self.evaluate_node(node.left_child).data, self.evaluate_node(node.right_child))
except:
self.error = Runtime_Error('Symbol Not Defined', node.left_child, node.location, self.context)
case 'Symbol Definition':
try:
self.context.define_symbol(node.child.data)
return Data_Node('Identifier', node.child.data, node.location)
except:
self.error = Runtime_Error('Symbol Already Defined', node.child.data, node.location, self.context)
case 'Identifier':
try:
result = self.context.get_symbol(node.data)
except:
self.error = Runtime_Error('Undefined Variable', node.data, node.location, self.context)
else:
return result
case 'Subtraction':
Expand All @@ -32,7 +44,7 @@ def evaluate_node(self, node):
try:
return self.evaluate_node(node.left_child) / self.evaluate_node(node.right_child)
except:
self.error = Error.Runtime_Error('Division by Zero', '', node.location, self.context)
self.error = Runtime_Error('Division by Zero', '', node.location, self.context)
return 0
case 'Multiplication':
return self.evaluate_node(node.left_child) * self.evaluate_node(node.right_child)
2 changes: 1 addition & 1 deletion scribe/Parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ def create_symbol_assignment_node(self):
token = self.token
self.advance()
right_child = self.create_symbol_definition_node()
left_child = Binary_Operation_Node('Symbol Assignment Node', left_child, right_child, token.location)
left_child = Binary_Operation_Node('Symbol Assignment', left_child, right_child, token.location)
return left_child

def create_symbol_definition_node(self):
Expand Down
12 changes: 10 additions & 2 deletions scribe/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,20 @@
error.print_error(code)
print()
continue

parser = Parser(tokens)
tree, error = parser.parse()
if error:
print(tree)
print()
error.print_error(code)
print()
continue
print(tree)

interpreter = Interpreter(tree, context)
result, error = interpreter.interpret()
if error:
print()
error.print_error(code)
print()
continue
print(result)

0 comments on commit d2c4ec1

Please sign in to comment.