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;
|
nombre = nombre - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
afficher "La factorielle vaut", factorielle;
|
afficher "La factorielle vaut", factorielle;
|
||||||
|
@ -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;
|
||||||
|
@ -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)
|
||||||
|
43
spf.lark
43
spf.lark
@ -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
85
spf.py
@ -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)
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user