160 lines
4.4 KiB
Python
Executable File
160 lines
4.4 KiB
Python
Executable File
#!/usr/bin/env python
|
|
|
|
# Projet de compilation Umons 2025
|
|
# Par Debucquoy Anthony (231687)
|
|
|
|
import argparse
|
|
import lark
|
|
import sys
|
|
from enum import Enum
|
|
from modules.Variables import Variables
|
|
|
|
class SPFInterpreter(lark.visitors.Interpreter):
|
|
def __init__(self, trace=False):
|
|
super().__init__()
|
|
self.variables = Variables(trace)
|
|
|
|
def while_loop(self, el):
|
|
print("TODO: while")
|
|
cond = el.children[0]
|
|
instr = el.children[1:]
|
|
print(cond.pretty())
|
|
|
|
def for_loop(self, el):
|
|
print("TODO: for")
|
|
|
|
def afficher(self, el):
|
|
ligne = ""
|
|
for toprint in el.children[1:]:
|
|
ligne += str(self.visit_children(toprint)[0]) + " "
|
|
print(ligne)
|
|
|
|
# def append(self, el):
|
|
# (_, toadd, var) = self.visit_children(el);
|
|
|
|
def declaration(self, el):
|
|
type = el.children[0].value
|
|
name = el.children[1].value
|
|
value = self.visit_children(el.children[3])[0] if len(el.children) >= 3 else None
|
|
self.variables.declare(type, name, value)
|
|
|
|
def assignation(self, el):
|
|
name = el.children[0].value
|
|
assert el.children[1].value == "=" and el.children[2].data == "expression", "Unexpected"
|
|
value = self.visit_children(el.children[2])[0]
|
|
self.variables.assign(name, value)
|
|
|
|
def equal(self, el):
|
|
(left, sign, right) = self.visit_children(el)
|
|
return left == right
|
|
|
|
def unequal(self, el):
|
|
(left, sign, right) = self.visit_children(el)
|
|
return left != right
|
|
|
|
def and_op(self, el):
|
|
(left, sign, right) = self.visit_children(el)
|
|
return left and right
|
|
|
|
def or_op(self, el):
|
|
(left, sign, right) = self.visit_children(el)
|
|
return left or right
|
|
|
|
def not_op(self, el):
|
|
(sign, right) = self.visit_children(el)
|
|
return not right
|
|
|
|
def lt(self, el):
|
|
(left, sign, right) = self.visit_children(el)
|
|
return left < right
|
|
|
|
def le(self, el):
|
|
(left, sign, right) = self.visit_children(el)
|
|
return left <= right
|
|
|
|
def gt(self, el):
|
|
(left, sign, right) = self.visit_children(el)
|
|
return left > right
|
|
|
|
def ge(self, el):
|
|
(left, sign, right) = self.visit_children(el)
|
|
return left >= right
|
|
|
|
|
|
def plus(self, el):
|
|
(left, sign, right) = self.visit_children(el)
|
|
return left + right # Cool ça fonctionne pour les str
|
|
|
|
def minus(self, el):
|
|
(left, sign, right) = self.visit_children(el)
|
|
return left - right
|
|
|
|
def time(self, el):
|
|
(left, sign, right) = self.visit_children(el)
|
|
return left * right
|
|
|
|
def divide(self, el):
|
|
(left, sign, right) = self.visit_children(el)
|
|
return left / right
|
|
|
|
neg = lambda self, el:-self.visit_children(el)[1]
|
|
|
|
sizeof = lambda self, el:len(self.visit_children(el)[1])
|
|
|
|
|
|
def expression(self, el):
|
|
return self.visit_children(el)[0]
|
|
|
|
def expressionleft(self, el):
|
|
return self.visit_children(el)[0]
|
|
|
|
def variable(self, el):
|
|
return self.variables.get(el.children[0].value)
|
|
|
|
# Literals
|
|
string = lambda self, el: el.children[0][1:-1]
|
|
entier = lambda self, el: int(el.children[0])
|
|
true = lambda self, _: True
|
|
false = lambda self, _: False
|
|
|
|
def dump(self):
|
|
self.variables.dump()
|
|
|
|
|
|
|
|
def main():
|
|
arg_parser = argparse.ArgumentParser()
|
|
arg_parser.add_argument("spf_file", help="Fichier source à interpréter")
|
|
arg_parser.add_argument("-d", "--dump",
|
|
help="affichage de la mémoire du programme",
|
|
action="store_true")
|
|
arg_parser.add_argument("-t", "--trace",
|
|
help="affichage de la mémoire au cours du programme",
|
|
action="store_true")
|
|
arg_parser.add_argument("-p", "--pretty",
|
|
help="affichage de l'arbre et quite",
|
|
action="store_true")
|
|
args = arg_parser.parse_args()
|
|
|
|
with open("spf.lark") as grammar:
|
|
spf_parser = lark.Lark(grammar, parser="lalr", strict=True, debug=True)
|
|
|
|
with open(args.spf_file) as spf_input:
|
|
program = spf_input.read()
|
|
parsed = spf_parser.parse(program)
|
|
|
|
if args.pretty:
|
|
print(parsed.pretty())
|
|
return
|
|
|
|
interpreter = SPFInterpreter(args.trace)
|
|
interpreted = interpreter.visit(parsed)
|
|
|
|
if args.dump:
|
|
interpreter.dump()
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|
|
|