Adding most operators

This commit is contained in:
Anthony Debucquoy 2025-03-20 13:27:57 +01:00
parent 4db6081fc8
commit 5d21e611f0
Signed by: tonitch
GPG Key ID: A78D6421F083D42E
6 changed files with 126 additions and 28 deletions

17
examples/arithmetic.spf Normal file
View 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;

View File

@ -7,4 +7,4 @@ tant que nombre > 0 faire {
nombre = nombre - 1; nombre = nombre - 1;
} }
afficher "La factorielle vaut", factorielle; afficher "La factorielle vaut", factorielle;

View File

@ -9,7 +9,7 @@ majeur = faux;
afficher nom, age, majeur; afficher nom, age, majeur;
#TODO: Ces lignes devraient donner une erreur #Ces lignes devraient donner une erreur
# majeur = 42; # majeur = 42;
# afficher majeur; # afficher majeur;

View File

@ -31,7 +31,6 @@ class Variables:
return f"\"{self.value}\"" return f"\"{self.value}\""
return f"{self.value}" return f"{self.value}"
def checkType(self, value, typ) -> bool: def checkType(self, value, typ) -> bool:
return value is None or type(value) == self.types[typ] 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" assert name in self.variables, "la variable {name} n'éxiste pas"
if self.trace: if self.trace:
print(f"{trace_format}accède {name}{reset_format}", file=sys.stderr) 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): def declare(self, typ, name, value=None):
assert name not in self.variables, "la variable {name} existe déjà" assert name not in self.variables, "la variable {name} existe déjà"
@ -69,7 +68,9 @@ class Variables:
def dump(self): def dump(self):
name_len = max(map(len, self.variables.keys())) 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 = 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_len}{'' * var_len}", file=sys.stderr)
print(f"{'Name':>{name_len}}{'Value':<{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) print(f"{'' * name_len}{'' * var_len}", file=sys.stderr)

View File

@ -3,7 +3,7 @@ start: (instruction)*
instruction: declaration ";" instruction: declaration ";"
| assignation ";" | assignation ";"
| SHOW_KW expression ("," expression)* ";" -> afficher | SHOW_KW expression ("," expression)* ";" -> afficher
| ADD_KW expression "dans" VARIABLE ";" | ADD_KW expression "dans" VARIABLE ";" -> append
| controls | controls
expression: expressionleft // TODO: priorité des operator certainement fausse expression: expressionleft // TODO: priorité des operator certainement fausse
@ -16,26 +16,25 @@ expressionleft: literal
| "(" expression ")" | "(" expression ")"
//any -> bool //any -> bool
operator: expressionleft SAME_OP expression operator: expressionleft SAME_OP expression -> equal
| expressionleft DIFF_OP expression | expressionleft DIFF_OP expression -> unequal
//bool -> bool //bool -> bool
| expressionleft AND_OP expression | expressionleft AND_OP expression -> and_op
| expressionleft OR_OP expression | expressionleft OR_OP expression -> or_op
| NOT_OP expression | NOT_OP expression -> not_op
//int -> bool //int -> bool
| expressionleft LT_OP expression | expressionleft LT_OP expression -> lt
| expressionleft LE_OP expression | expressionleft LE_OP expression -> le
| expressionleft GT_OP expression | expressionleft GT_OP expression -> gt
| expressionleft GE_OP expression | expressionleft GE_OP expression -> ge
//int -> int //int -> int
| expressionleft PLUS_OP expression | expressionleft PLUS_OP expression -> plus
| expressionleft MINUS_OP expression | expressionleft MINUS_OP expression -> minus
| expressionleft TIMES_OP expression | expressionleft TIMES_OP expression -> time
| expressionleft DIVIDE_OP expression | expressionleft DIVIDE_OP expression -> divide
| NEG_OP expression | NEG_OP expression -> neg
// string/list -> string/list // string/list -> string/list
| expressionleft CONC_OP expression | SIZE_OP expression -> sizeof
| SIZE_OP expression
?type: BOOL_TYPE ?type: BOOL_TYPE
| INT_TYPE | INT_TYPE
@ -46,8 +45,8 @@ declaration: type VARIABLE (EQUAL_SIGN expression)?
assignation: VARIABLE EQUAL_SIGN expression assignation: VARIABLE EQUAL_SIGN expression
loop: /tant que/ expression "faire" "{" (instruction)* "}" loop: "tant" "que" expression "faire" "{" (instruction)* "}" -> while_loop
| /pour chaque/ type VARIABLE "dans" expression "faire" "{" (instruction)* "}" | "pour" "chaque" type VARIABLE "dans" expression "faire" "{" (instruction)* "}" -> for_loop
?literal: ENTIER -> entier ?literal: ENTIER -> entier
| booleen | booleen
@ -62,6 +61,9 @@ controls: test
test: "si" expression "alors" "{" instruction* "}" ("sinon" "{" instruction* "}")? test: "si" expression "alors" "{" instruction* "}" ("sinon" "{" instruction* "}")?
?booleen: TRUE_KW -> true
| FALSE_KW -> false
TERMINAL: ";" TERMINAL: ";"
VAR_CHARS: /[a-zA-Zçâêîôûéàèìòùëïü_]/ VAR_CHARS: /[a-zA-Zçâêîôûéàèìòùëïü_]/
@ -71,9 +73,6 @@ EQUAL_SIGN: "="
ENTIER: /0|[1-9][0-9]*/ ENTIER: /0|[1-9][0-9]*/
?booleen: TRUE_KW -> true
| FALSE_KW -> false
BOOL_TYPE: "booléen" BOOL_TYPE: "booléen"
INT_TYPE: "entier" INT_TYPE: "entier"
STR_TYPE: "texte" STR_TYPE: "texte"

85
spf.py
View File

@ -14,10 +14,23 @@ class SPFInterpreter(lark.visitors.Interpreter):
super().__init__() super().__init__()
self.variables = Variables(trace) 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): def afficher(self, el):
ligne = ""
for toprint in el.children[1:]: for toprint in el.children[1:]:
print(self.visit_children(toprint)[0]) ligne += str(self.visit_children(toprint)[0]) + " "
return print(ligne)
# def append(self, el):
# (_, toadd, var) = self.visit_children(el);
def declaration(self, el): def declaration(self, el):
type = el.children[0].value type = el.children[0].value
@ -31,6 +44,67 @@ class SPFInterpreter(lark.visitors.Interpreter):
value = self.visit_children(el.children[2])[0] value = self.visit_children(el.children[2])[0]
self.variables.assign(name, value) 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): def expressionleft(self, el):
return self.visit_children(el)[0] return self.visit_children(el)[0]
@ -57,6 +131,9 @@ def main():
arg_parser.add_argument("-t", "--trace", arg_parser.add_argument("-t", "--trace",
help="affichage de la mémoire au cours du programme", help="affichage de la mémoire au cours du programme",
action="store_true") action="store_true")
arg_parser.add_argument("-p", "--pretty",
help="affichage de l'arbre et quite",
action="store_true")
args = arg_parser.parse_args() args = arg_parser.parse_args()
with open("spf.lark") as grammar: with open("spf.lark") as grammar:
@ -66,6 +143,10 @@ def main():
program = spf_input.read() program = spf_input.read()
parsed = spf_parser.parse(program) parsed = spf_parser.parse(program)
if args.pretty:
print(parsed.pretty())
return
interpreter = SPFInterpreter(args.trace) interpreter = SPFInterpreter(args.trace)
interpreted = interpreter.visit(parsed) interpreted = interpreter.visit(parsed)