Adding most operators
This commit is contained in:
		
							
								
								
									
										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) | ||||||
|  |  | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user