Debut de typage

This commit is contained in:
Lucàs
2023-04-03 10:19:54 +02:00
parent a18db587ef
commit 6d9246c420
2 changed files with 108 additions and 25 deletions
+7 -3
View File
@@ -1,5 +1,5 @@
# Import lib + compile + clean folder # Import lib + compile
all: lib comp clean all: lib comp
# Compilation of Ocaml files # Compilation of Ocaml files
# Attention: order of object files important # Attention: order of object files important
@@ -51,10 +51,14 @@ parser.cmo: parser.ml parser.cmi lang.cmo
.PHONY: clean .PHONY: clean
### Import files from /lib ### Import files from /lib (temporarly)
lib: lib:
cp ../lib/* ./ cp ../lib/* ./
## Remove compiled modules and lib ## Remove compiled modules and lib
clean: clean:
rm -f lexer.ml parser.ml *.mli *.cmi *.cmo rm -f lexer.ml parser.ml *.mli *.cmi *.cmo
## Run tests
tests:
./comp ./../tests/rectangles.c ./../tests/out/rectangles.ps
+97 -18
View File
@@ -8,31 +8,110 @@ type environment = {
funbind: fundecl list funbind: fundecl list
} }
let find_var (var: vname) (env: environment) = (* Recherche dans l'environement *)
let rec aux local_vars = type 'a option = None| Some of 'a;;
match local_vars with
| [] -> failwith "Variable inconnue" let lookup_env (name: vname) (env: environment) =
| tete::reste -> let rec aux = function
let (name, _) = tete in | [] -> None
if name = var | (k, v)::reste ->
then tete if k = name then Some(v)
else aux reste else aux(reste)
in aux(env.localvars) in aux(env.localvars)
;; ;;
(* let rec tp_expr (expression: expr) (env: environment) = (* Ajoute dans l'environement *)
let rec add_env (key, valeur) env =
let paire = (key, valeur)
in {localvars: paire::(env.localvars); funbind: (env.funbind)}
;;
(* Enlève de l'environement *)
let rec remove_env key env =
let aux (liste) =
match liste with
| [] -> []
| (k, v)::reste when k = key -> remove_assoc key reste
| a::reste -> a::(remove_assoc key reste)
in {
localvars: (aux(env.localvars));
funbind: (env.funbind)
}
;;
(* Typage d'une expression *)
let rec tp_expr (env: environment) (expression: expr) =
match expression with match expression with
| Const(const) -> | Const(const) -> (
match const with match const with
| BoolV(_) -> BoolT | BoolV _ -> BoolT
| FloatV(_) -> FloatT | FloatV _ -> FloatT
| IntV(_) -> IntT | IntV _ -> IntT
| LitV(_) -> LitT | LitV _ -> LitT
| StringV(_) -> StringT | StringV _ -> StringT
| VarE(var) -> tp_expr (find_var var env) env )
| VarE(var) -> (
let var_value = (lookup_env var env) in
match var_value with
| Some(value) -> value
| None -> raise (Failure "Unknown var")
)
| BinOp(op, expr1, expr2) -> | BinOp(op, expr1, expr2) ->
let tp_expr1 = tp_expr env expr1
and tp_expr2 = tp_expr env expr2 in
if tp_expr1 = tp_expr2
then match op with
| BArith(barith) -> (
match barith with
| BAadd -> IntT
| BAsub -> IntT
| BAmul -> IntT
| BAdiv -> IntT
| BAmod -> IntT
| BAfadd -> FloatT
| BAfsub -> FloatT
| BAfmul -> FloatT
| BAfdiv -> FloatT
)
| BBool(_) -> BoolT
| BCompar(_) -> BoolT
else raise (Failure "Invalid type of Binary operation")
| CondE(expr1, expr2, expr3) -> | CondE(expr1, expr2, expr3) ->
| CallE(functionName, exprList) -> *) let tp_expr1 = tp_expr env expr1
and tp_expr2 = tp_expr env expr2
and tp_expr3 = tp_expr env expr3
in if tp_expr1 = BoolT && tp_expr2 = tp_expr3
then tp_expr2
else raise (Failure "Invalid type of Conditionnal Expression")
| CallE(name, list_expr) -> VoidT (* TODO *)
;;
let rec tp_cmd (env: environment) (cmd: com) =
match cmd with
| Skip -> VoidT
| Exit -> VoidT
| Assign(name, expr) -> VoidT (* TODO ajouter dans env *)
| Seq(cmd1, cmd2) ->
let tp_cmd1 = (tp_cmd env cmd1)
and tp_cmd2 = (tp_cmd env cmd2)
in if tp_cmd1 = Void
then tp_cmd2
else raise (Failure "Invalid type Sequence")
| CondC(expr1, cmd1, cmd2) ->
let tp_expr1 = tp_expr env expr1
and tp_cmd1 = tp_cmd env cmd1
and tp_cmd2 = tp_cmd env cmd2
in
if tp_expr1 = BoolT && tp_cmd1 = tp_cmd2
then tp_cmd1
else raise (Failure "Invalid type of Conditionnal Command")
| Loop(cmd1) ->
let _ = (tp_cmd env cmd1)
in VoidT
| CallC(name, list_expr) -> VoidT (* TODO Faire l'appel *)
| Return(expr) -> (tp_expr env expr)
;; ;;
let tp_prog (Prog (fundecls, fundefns)) = true let tp_prog (Prog (fundecls, fundefns)) = true