You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

93 lines
4.0 KiB

#!/usr/bin/env python3
import json
import sys
tokens = dict()
program = './ast.json'
if len(sys.argv) > 1:
program = sys.argv[1]
with open(program, 'r') as json_tokens:
tokens = json.loads(json_tokens.read())
def throw(token: dict, message):
print("{} on line {} ".format(message, token['line_number']))
if token['variant'] == 'syntax_error':
print("\033[4m" + token['value'] + "\033[0m")
sys.exit(1)
def resolve_variabel(tokens, signifier):
for token in tokens:
if token['variant'] == "variable_declaration" and token['signifier'] == signifier:
return token
def parse_expression(variable_list, expression, all_tokens):
split_on_space = expression.split(" ")
if len(split_on_space) == 1:
for param in variable_list:
if param['signifier'] == expression:
if type(param['expression']) == type(dict()):
return param['expression']['expression']
match param['type']:
case 'string':
return str(param['expression'])
case 'number':
resolved = list()
for part in param['expression'].split(' '):
if part.isalpha():
variable = resolve_variabel(all_tokens, part)
resolved.append(variable)
elif part == '+':
resolved.append({"variant": "operator", "type": "addition"})
elif part == '-':
resolved.append({"variant": "operator", "type": "subtraction"})
elif part == '*':
resolved.append({"variant": "operator", "type": "multiplication"})
elif part == '/':
resolved.append({"variant": "operator", "type": "division"})
elif part == '%':
resolved.append({"variant": "operator", "type": "modulo"})
elif float(part):
resolved.append({"expression": part})
if len(resolved) == 3:
lhs = resolved[0]['expression']
operator = resolved[1]
rhs = resolved[2]['expression']
match operator['type']:
case "addition":
return str(float(lhs) + float(rhs))
case "subtraction":
return str(float(lhs) - float(rhs))
case "multiplication":
return str(float(lhs) * float(rhs))
case "division":
return str(float(lhs) / float(rhs))
case "modulo":
return str(float(lhs) % float(rhs))
else:
return "Unknown"
for token in tokens:
match token['variant']:
case "syntax_error":
throw(token, "Syntax error")
case "function_call":
args = token['params']
function = token['function']
params = function['params']
if len(args) != len(params):
print(params)
throw(token, "Wrong number of arguments")
for index in range(0, len(args)):
if args[index]['type'] != params[index]['type']:
throw(token, "Type missmatch on arguments")
signifier = params[index]['name']
params[index] = args[index]
params[index]['signifier'] = signifier
for part in function['body']:
if part['type'] == "stdout":
print(parse_expression(params, part['expression'], tokens), end = '')
case _:
pass # print(token)