Adding most operators
This commit is contained in:
parent
4db6081fc8
commit
5d21e611f0
17
examples/arithmetic.spf
Normal file
17
examples/arithmetic.spf
Normal file
@ -0,0 +1,17 @@
|
||||
# entier x = 3;
|
||||
# entier y = 4;
|
||||
#
|
||||
liste l = [3, 4, 5];
|
||||
|
||||
ajouter 3 dans l;
|
||||
|
||||
afficher l;
|
||||
|
||||
#
|
||||
# afficher x vaut y;
|
||||
# afficher x ne vaut pas y;
|
||||
# entier z;
|
||||
# afficher taille "test";
|
||||
# afficher x + 3, 3 + y;
|
||||
# x = -x;
|
||||
# afficher x;
|
@ -7,4 +7,4 @@ tant que nombre > 0 faire {
|
||||
nombre = nombre - 1;
|
||||
}
|
||||
|
||||
afficher "La factorielle vaut", factorielle;
|
||||
afficher "La factorielle vaut", factorielle;
|
||||
|
@ -9,7 +9,7 @@ majeur = faux;
|
||||
afficher nom, age, majeur;
|
||||
|
||||
|
||||
#TODO: Ces lignes devraient donner une erreur
|
||||
#Ces lignes devraient donner une erreur
|
||||
# majeur = 42;
|
||||
|
||||
# afficher majeur;
|
||||
|
@ -31,7 +31,6 @@ class Variables:
|
||||
return f"\"{self.value}\""
|
||||
return f"{self.value}"
|
||||
|
||||
|
||||
def checkType(self, value, typ) -> bool:
|
||||
return value is None or type(value) == self.types[typ]
|
||||
|
||||
@ -53,7 +52,7 @@ class Variables:
|
||||
assert name in self.variables, "la variable {name} n'éxiste pas"
|
||||
if self.trace:
|
||||
print(f"{trace_format}accède {name}{reset_format}", file=sys.stderr)
|
||||
return self.variables[name]
|
||||
return self.variables[name].value
|
||||
|
||||
def declare(self, typ, name, value=None):
|
||||
assert name not in self.variables, "la variable {name} existe déjà"
|
||||
@ -69,7 +68,9 @@ class Variables:
|
||||
|
||||
def dump(self):
|
||||
name_len = max(map(len, self.variables.keys()))
|
||||
name_len = name_len if name_len >= len("name") else len("name")
|
||||
var_len = max(map(len,map(str, self.variables.values())))
|
||||
var_len = var_len if var_len >= len("value") else len("value")
|
||||
print(f"┌{'─' * name_len}┬{'─' * var_len}┐", file=sys.stderr)
|
||||
print(f"│{'Name':>{name_len}}│{'Value':<{var_len}}│", file=sys.stderr)
|
||||
print(f"├{'─' * name_len}┼{'─' * var_len}┤", file=sys.stderr)
|
||||
|
43
spf.lark
43
spf.lark
@ -3,7 +3,7 @@ start: (instruction)*
|
||||
instruction: declaration ";"
|
||||
| assignation ";"
|
||||
| SHOW_KW expression ("," expression)* ";" -> afficher
|
||||
| ADD_KW expression "dans" VARIABLE ";"
|
||||
| ADD_KW expression "dans" VARIABLE ";" -> append
|
||||
| controls
|
||||
|
||||
expression: expressionleft // TODO: priorité des operator certainement fausse
|
||||
@ -16,26 +16,25 @@ expressionleft: literal
|
||||
| "(" expression ")"
|
||||
|
||||
//any -> bool
|
||||
operator: expressionleft SAME_OP expression
|
||||
| expressionleft DIFF_OP expression
|
||||
operator: expressionleft SAME_OP expression -> equal
|
||||
| expressionleft DIFF_OP expression -> unequal
|
||||
//bool -> bool
|
||||
| expressionleft AND_OP expression
|
||||
| expressionleft OR_OP expression
|
||||
| NOT_OP expression
|
||||
| expressionleft AND_OP expression -> and_op
|
||||
| expressionleft OR_OP expression -> or_op
|
||||
| NOT_OP expression -> not_op
|
||||
//int -> bool
|
||||
| expressionleft LT_OP expression
|
||||
| expressionleft LE_OP expression
|
||||
| expressionleft GT_OP expression
|
||||
| expressionleft GE_OP expression
|
||||
| expressionleft LT_OP expression -> lt
|
||||
| expressionleft LE_OP expression -> le
|
||||
| expressionleft GT_OP expression -> gt
|
||||
| expressionleft GE_OP expression -> ge
|
||||
//int -> int
|
||||
| expressionleft PLUS_OP expression
|
||||
| expressionleft MINUS_OP expression
|
||||
| expressionleft TIMES_OP expression
|
||||
| expressionleft DIVIDE_OP expression
|
||||
| NEG_OP expression
|
||||
| expressionleft PLUS_OP expression -> plus
|
||||
| expressionleft MINUS_OP expression -> minus
|
||||
| expressionleft TIMES_OP expression -> time
|
||||
| expressionleft DIVIDE_OP expression -> divide
|
||||
| NEG_OP expression -> neg
|
||||
// string/list -> string/list
|
||||
| expressionleft CONC_OP expression
|
||||
| SIZE_OP expression
|
||||
| SIZE_OP expression -> sizeof
|
||||
|
||||
?type: BOOL_TYPE
|
||||
| INT_TYPE
|
||||
@ -46,8 +45,8 @@ declaration: type VARIABLE (EQUAL_SIGN expression)?
|
||||
|
||||
assignation: VARIABLE EQUAL_SIGN expression
|
||||
|
||||
loop: /tant que/ expression "faire" "{" (instruction)* "}"
|
||||
| /pour chaque/ type VARIABLE "dans" expression "faire" "{" (instruction)* "}"
|
||||
loop: "tant" "que" expression "faire" "{" (instruction)* "}" -> while_loop
|
||||
| "pour" "chaque" type VARIABLE "dans" expression "faire" "{" (instruction)* "}" -> for_loop
|
||||
|
||||
?literal: ENTIER -> entier
|
||||
| booleen
|
||||
@ -62,6 +61,9 @@ controls: test
|
||||
|
||||
test: "si" expression "alors" "{" instruction* "}" ("sinon" "{" instruction* "}")?
|
||||
|
||||
?booleen: TRUE_KW -> true
|
||||
| FALSE_KW -> false
|
||||
|
||||
TERMINAL: ";"
|
||||
|
||||
VAR_CHARS: /[a-zA-Zçâêîôûéàèìòùëïü_]/
|
||||
@ -71,9 +73,6 @@ EQUAL_SIGN: "="
|
||||
|
||||
ENTIER: /0|[1-9][0-9]*/
|
||||
|
||||
?booleen: TRUE_KW -> true
|
||||
| FALSE_KW -> false
|
||||
|
||||
BOOL_TYPE: "booléen"
|
||||
INT_TYPE: "entier"
|
||||
STR_TYPE: "texte"
|
||||
|
85
spf.py
85
spf.py
@ -14,10 +14,23 @@ class SPFInterpreter(lark.visitors.Interpreter):
|
||||
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:]:
|
||||
print(self.visit_children(toprint)[0])
|
||||
return
|
||||
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
|
||||
@ -31,6 +44,67 @@ class SPFInterpreter(lark.visitors.Interpreter):
|
||||
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]
|
||||
|
||||
@ -57,6 +131,9 @@ def main():
|
||||
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:
|
||||
@ -66,6 +143,10 @@ def main():
|
||||
program = spf_input.read()
|
||||
parsed = spf_parser.parse(program)
|
||||
|
||||
if args.pretty:
|
||||
print(parsed.pretty())
|
||||
return
|
||||
|
||||
interpreter = SPFInterpreter(args.trace)
|
||||
interpreted = interpreter.visit(parsed)
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user