Commit 02c17a4a authored by Armillon Damien's avatar Armillon Damien
Browse files

Elang pointer

parent 3825d2cb
......@@ -30,5 +30,5 @@ test: main.native
testFun: main.native
make -C tests DIR="type_funcall/*.e type_basic/*.e char/*.e"
testChar: main.native
make -C tests DIR=char/*.e
\ No newline at end of file
testP: main.native
make -C tests DIR=ptr/*.e
\ No newline at end of file
......@@ -2,7 +2,7 @@ tokens SYM_EOF SYM_IDENTIFIER<string> SYM_INTEGER<int> SYM_PLUS SYM_MINUS SYM_AS
tokens SYM_LPARENTHESIS SYM_RPARENTHESIS SYM_LBRACE SYM_RBRACE
tokens SYM_ASSIGN SYM_SEMICOLON SYM_RETURN SYM_IF SYM_WHILE SYM_ELSE SYM_COMMA
tokens SYM_EQUALITY SYM_NOTEQ SYM_LT SYM_LEQ SYM_GT SYM_GEQ
tokens SYM_VOID SYM_CHAR SYM_INT SYM_CHARACTER<char>
tokens SYM_VOID SYM_CHAR SYM_INT SYM_CHARACTER<char> SYM_AMPERSAND
non-terminals S INSTR INSTRS LINSTRS ELSE EXPR FACTOR
non-terminals LPARAMS REST_PARAMS
non-terminals IDENTIFIER INTEGER
......@@ -12,8 +12,9 @@ non-terminals MUL_EXPRS MUL_EXPR
non-terminals CMP_EXPRS CMP_EXPR
non-terminals EQ_EXPRS EQ_EXPR
non-terminals BLOC
non-terminals IN_INSTR L_CALL_PARAMS REST_CALL_PARAMS FACTORS FUN_CALL_EXPRS FUN_CALL_EXPR FACTOR_IDENTIFIER
non-terminals IN_INSTR L_CALL_PARAMS REST_CALL_PARAMS FACTORS FACTOR_IDENTIFIER
non-terminals SYM_TYPE ASSIGN_EXPR FUNBODY
non-terminals VAR TYPE_PT
axiom S
{
......@@ -39,22 +40,22 @@ FUNDEF -> SYM_TYPE SYM_IDENTIFIER SYM_LPARENTHESIS LPARAMS SYM_RPARENTHESIS FUNB
FUNBODY -> BLOC {$1}
FUNBODY -> SYM_SEMICOLON {NullLeaf}
LPARAMS -> {[]}
LPARAMS -> SYM_TYPE SYM_IDENTIFIER REST_PARAMS {(Node(Targ, [$1; StringLeaf($2)])) :: $3}
REST_PARAMS -> SYM_COMMA SYM_TYPE SYM_IDENTIFIER REST_PARAMS {(Node(Targ, [$2; StringLeaf($3)])):: $4}
LPARAMS -> SYM_TYPE SYM_IDENTIFIER REST_PARAMS {(Node(Targ, [$1; (StringLeaf $2)])) :: $3}
REST_PARAMS -> SYM_COMMA SYM_TYPE SYM_IDENTIFIER REST_PARAMS {(Node(Targ, [$2; (StringLeaf $3)])):: $4}
REST_PARAMS -> {[]}
L_CALL_PARAMS -> {[]}
L_CALL_PARAMS -> EXPR REST_CALL_PARAMS {[Node(Targs, $1::$2)]}
REST_CALL_PARAMS -> {[]}
REST_CALL_PARAMS -> SYM_COMMA EXPR REST_CALL_PARAMS {$2::$3}
IN_INSTR -> SYM_LPARENTHESIS L_CALL_PARAMS SYM_RPARENTHESIS SYM_SEMICOLON {fun x -> Node(Tcall, (StringLeaf x)::$2)}
IN_INSTR -> SYM_ASSIGN EXPR SYM_SEMICOLON {fun x -> Node(Tassign, [Node(Tassignvar,[StringLeaf(x); $2])])}
IN_INSTR -> SYM_LPARENTHESIS L_CALL_PARAMS SYM_RPARENTHESIS SYM_SEMICOLON {fun x -> Node(Tcall, x::$2)}
IN_INSTR -> SYM_ASSIGN EXPR SYM_SEMICOLON {fun x -> Node(Tassign, [Node(Tassignvar,[x; $2])])}
ASSIGN_EXPR -> SYM_ASSIGN EXPR {[$2]}
ASSIGN_EXPR -> {[NullLeaf]}
INSTRS -> {[]}
INSTRS -> INSTR INSTRS {$1::$2}
INSTR -> BLOC {$1}
INSTR -> SYM_IDENTIFIER IN_INSTR {$2 $1}
INSTR -> SYM_TYPE SYM_IDENTIFIER ASSIGN_EXPR SYM_SEMICOLON {Node(Tassign, [Node(Tassignvar ,(StringLeaf $2)::$3@[$1])])}
INSTR -> VAR IN_INSTR {$2 $1}
INSTR -> SYM_TYPE SYM_IDENTIFIER ASSIGN_EXPR SYM_SEMICOLON {Node(Tassign, [Node(Tassignvar , (StringLeaf $2)::$3@[$1])])}
INSTR -> SYM_IF SYM_LPARENTHESIS EXPR SYM_RPARENTHESIS BLOC ELSE {Node(Tif, $3::$5::$6)}
INSTR -> SYM_WHILE SYM_LPARENTHESIS EXPR SYM_RPARENTHESIS BLOC {Node(Twhile, [$3;$5])}
INSTR -> SYM_RETURN EXPR SYM_SEMICOLON {Node(Treturn, [$2])}
......@@ -80,17 +81,19 @@ MUL_EXPRS -> SYM_DIV MUL_EXPR MUL_EXPRS {(Tdiv, [$2])::$3}
MUL_EXPRS -> SYM_MOD MUL_EXPR MUL_EXPRS {(Tmod, [$2])::$3}
MUL_EXPRS -> {[]}
MUL_EXPR -> FACTORS { $1 }
FUN_CALL_EXPRS -> SYM_IDENTIFIER SYM_LPARENTHESIS SYM_RPARENTHESIS {[(Tcall,[])]}
FUN_CALL_EXPRS -> {[]}
FUN_CALL_EXPR -> FACTORS {$1}
FACTORS -> FACTOR {$1}
FACTORS -> SYM_MINUS FACTOR {Node(Tneg,[$2])}
FACTOR_IDENTIFIER -> {fun x -> StringLeaf(x)}
FACTOR_IDENTIFIER -> SYM_LPARENTHESIS L_CALL_PARAMS SYM_RPARENTHESIS {fun x -> Node(Tcall, (StringLeaf x)::$2)}
FACTOR_IDENTIFIER -> {fun x -> x}
FACTOR_IDENTIFIER -> SYM_LPARENTHESIS L_CALL_PARAMS SYM_RPARENTHESIS {fun x -> Node(Tcall, x::$2)}
FACTOR -> SYM_INTEGER {IntLeaf($1)}
FACTOR -> SYM_CHARACTER {CharLeaf($1)}
FACTOR -> SYM_IDENTIFIER FACTOR_IDENTIFIER {$2 $1}
FACTOR -> VAR FACTOR_IDENTIFIER {$2 $1}
FACTOR -> SYM_LPARENTHESIS EXPR SYM_RPARENTHESIS {$2}
SYM_TYPE -> SYM_INT {Node(Tint, [])}
SYM_TYPE -> SYM_CHAR {Node(Tchar,[])}
SYM_TYPE -> SYM_VOID {Node(Tvoid,[])}
SYM_TYPE -> SYM_INT TYPE_PT {$2 (Node(Tint,[]))}
SYM_TYPE -> SYM_CHAR TYPE_PT { $2 (Node(Tchar,[]))}
SYM_TYPE -> SYM_VOID TYPE_PT {$2 (Node(Tvoid,[]))}
TYPE_PT -> SYM_ASTERISK TYPE_PT {fun x -> $2 (Node(Tptr,[x]))}
TYPE_PT -> {fun x -> x}
VAR -> SYM_IDENTIFIER {StringLeaf($1)}
VAR -> SYM_ASTERISK VAR {Node(Tp,[$2])}
VAR -> SYM_AMPERSAND VAR {Node(Taddrof,[$2])}
......@@ -33,7 +33,8 @@ type tag = Tassign | Tif | Twhile | Tblock | Treturn | Tprint
| Tfundef | Tfunname | Tfunargs | Tfunbody
| Tassignvar
| Targ | Tcall | Targs
| Tvoid | Tint | Tchar
| Taddrof | Tp
| Tvoid | Tint | Tchar | Tptr
type tree = | Node of tag * tree list
| StringLeaf of string
......@@ -41,13 +42,6 @@ type tree = | Node of tag * tree list
| NullLeaf
| CharLeaf of char
let is_type (t:tag) : typ res =
match t with
| Tvoid -> OK(Tvoid)
| Tint -> OK(Tint)
| Tchar -> OK(Tchar)
| _ -> Error "Not a type"
let string_of_stringleaf = function
| StringLeaf s -> s
| _ -> failwith "string_of_stringleaf called on non-stringleaf nodes."
......@@ -87,6 +81,9 @@ let string_of_tag = function
| Targs -> "Targs"
| Tchar -> "Tchar"
| Tvoid -> "Tvoid"
| Tptr -> "Tptr"
| Taddrof -> "Taddrof"
| Tp -> "Tp"
(* Écrit un fichier .dot qui correspond à un AST *)
......@@ -129,3 +126,16 @@ let rec string_of_ast a =
| IntLeaf i -> Format.sprintf "%d" i
| CharLeaf i -> Format.sprintf "%c" i
| NullLeaf -> "null"
let rec is_type (tr:tree) : typ res =
match tr with
| Node(t,st) when List.length st <=1-> (match t with
| Tvoid -> OK(Tvoid)
| Tint -> OK(Tint)
| Tchar -> OK(Tchar)
| Tptr ->
let* subtype = is_type (List.hd st) in
OK(Prog.Tptr (subtype))
| _ -> Error "Not a type")
| _ ->Error (Format.sprintf "Not a type: %s" (string_of_ast tr))
\ No newline at end of file
......@@ -29,6 +29,7 @@ let rec cfg_expr_of_eexpr (e: Elang.expr) : expr res =
| Elang.Ecall(name, elist) ->
let* args_expr = list_map_res (cfg_expr_of_eexpr) elist in
OK(Cfg.Ecall(name, args_expr))
| _ -> Error "NO CFG YET"
(* [cfg_node_of_einstr next cfg succ i] builds the CFG node(s) that correspond
to the E instruction [i].
......@@ -77,6 +78,8 @@ let rec cfg_node_of_einstr (next: int) (cfg : (int, cfg_node) Hashtbl.t)
let* args_expr = list_map_res (cfg_expr_of_eexpr) elist in
Hashtbl.replace cfg next (Ccall(name, args_expr, succ));
OK (next,next+1)
| _ -> Error "NO CFG YET"
(* Some nodes may be unreachable after the CFG is entirely generated. The
......
......@@ -97,6 +97,7 @@ let list_regexp : (regexp * (string -> token option)) list =
(keyword_regexp ">", fun s -> Some (SYM_GT));
(keyword_regexp "<=", fun s -> Some (SYM_LEQ));
(keyword_regexp ">=", fun s -> Some (SYM_GEQ));
(keyword_regexp "&", fun s -> Some (SYM_AMPERSAND));
(Cat (letter_regexp,Star(identifier_material)), fun s -> Some (SYM_IDENTIFIER s));
(* end TODO *)
(Cat(keyword_regexp "//",
......
......@@ -14,6 +14,8 @@ type expr =
| Echar of char
| Evar of string
| Ecall of string * expr list
| Eaddrof of expr
| Eload of expr
type instr =
| Iassign of string * expr
......@@ -23,12 +25,15 @@ type instr =
| Ireturn of expr
| Iprint of expr
| Icall of string * expr list
| Istore of expr * expr
type efun = {
funargs: ( string * typ ) list;
funbody: instr;
funvartyp : (string, typ) Hashtbl.t;
funrettype : typ;
funvarinmem : (string, int) Hashtbl.t;
funstksz : int
}
type eprog = efun prog
......@@ -39,6 +39,17 @@ let binop_of_tag =
| Tne -> Ecne
| _ -> assert false
let tag_is_unop =
function
| Tneg -> true
| _ -> false
let unop_of_tag =
function
| Tneg -> Eneg
| _ -> assert false
let rec type_expr
(typ_var : (string,typ) Hashtbl.t)
(typ_fun : (string, typ list * typ) Hashtbl.t)
......@@ -59,6 +70,14 @@ let rec type_expr
| Some (_,t) -> OK t
| None -> Error (Format.sprintf "function %s not found (unknown type)" func)
)
| Eload (e) ->
let* type_e = type_expr typ_var typ_fun e in
OK(Tptr type_e)
| Eaddrof e ->
let* type_e = type_expr typ_var typ_fun e in
match type_e with
| Tptr t -> OK t
| _ -> Error "Can't deference a non pointer type"
let are_types_compatible (t1: typ) (t2:typ): typ res =
match t1 with
......@@ -68,7 +87,83 @@ let are_types_compatible (t1: typ) (t2:typ): typ res =
| Tint | Tchar -> OK(t1)
| _ -> Error (Format.sprintf "Incompatible type %s %s" (string_of_typ t1) (string_of_typ t2))
)
| Tptr t -> (
match t2 with
| Tint -> OK(Tint)
| _ -> Error "Incompatible type: pointers are integers"
)
| _ -> Error (Format.sprintf "Incompatible type %s %s" (string_of_typ t1) (string_of_typ t2))
let type_expr_binop (op:binop) (t1: typ) (t2:typ): typ res =
let error = Error (Format.sprintf "Incompatible type %s %s for op" (string_of_typ t1) (string_of_typ t2)) in
match t1 with
| Tint
| Tchar -> (
match t2 with
| Tint | Tchar -> OK(t1)
| Tptr t' -> (
match op with
| Eadd -> OK t2
| _ -> error
)
| _ -> error
)
| Tptr t' -> (
match t2 with
| Tint | Tchar when op = Eadd || op = Esub -> OK t1
| Tptr t'' when t' = t'' -> (
match op with
| Eclt | Ecle | Ecgt | Ecge | Eceq | Ecne -> OK Tint
| _ -> error
)
| _ -> error
)
| _ -> error
let type_expr_unop (op:unop) (t: typ) : typ res =
let error = Error (Format.sprintf "Incompatible type %s for unary op" (string_of_typ t)) in
match t with
| Tint
| Tchar -> OK t
| _ -> error
let rec addr_taken_expr (e: expr) : string Set.t =
match e with
| Ebinop (_,e1,e2) -> Set.union (addr_taken_expr e1) (addr_taken_expr e2)
| Eload (e)
| Eunop (_,e) -> addr_taken_expr e
| Ecall (_,el) -> List.fold_left (fun acc e -> Set.union acc (addr_taken_expr e)) Set.empty el
| Eaddrof (Evar(v)) -> Set.singleton v
| Eaddrof _
| Eint _
| Echar _
| Evar _ -> Set.empty
let rec addr_taken_instr (i: instr) : string Set.t =
match i with
| Iassign (_,e) -> addr_taken_expr e
| Iif (e,i1,i2) -> Set.union (Set.union (addr_taken_instr i1)(addr_taken_instr i2)) (addr_taken_expr e)
| Iwhile (e,i) -> Set.union (addr_taken_expr e) (addr_taken_instr i)
| Iblock (il) -> List.fold_left (fun acc i -> Set.union acc (addr_taken_instr i)) Set.empty il
| Ireturn e -> addr_taken_expr e
| Iprint e -> addr_taken_expr e
| Icall (_,el) -> List.fold_left (fun acc e -> Set.union acc (addr_taken_expr e)) Set.empty el
| Istore (e1,e2) -> Set.union (addr_taken_expr e1)(addr_taken_expr e2)
let gen_funvarinmem i funvartyp: ((string, int )Hashtbl.t * int) res=
let var_in_mem = addr_taken_instr i in
Set.fold (
fun var acc ->
let* (table, size) = acc in
let var_typ = Hashtbl.find funvartyp var in
let* offset = size_type var_typ in
Hashtbl.replace table var size;
OK (table, size + offset)
) var_in_mem (OK (Hashtbl.create (Set.cardinal var_in_mem), 0))
(* [make_eexpr_of_ast a] builds an expression corresponding to a tree [a]. If
the tree is not well-formed, fails with an [Error] message. *)
let rec make_eexpr_of_ast (a: tree)
......@@ -95,10 +190,13 @@ let rec make_eexpr_of_ast (a: tree)
| Node(t, [e1; e2]) when tag_is_binop t ->
make_eexpr_of_ast e1 typ_var typ_fun >>= fun (expr1,t1) ->
make_eexpr_of_ast e2 typ_var typ_fun >>= fun (expr2,t2) ->
let* t1 = are_types_compatible t1 t2 in
OK (Ebinop(binop_of_tag t, expr1 , expr2),t1)
| Node(t, [e1]) when t = Tneg -> make_eexpr_of_ast e1 typ_var typ_fun >>= fun (expr1,t1) ->
OK(Eunop(Eneg,expr1), t1)
let op = binop_of_tag t in
let* t1 = type_expr_binop op t1 t2 in
OK (Ebinop(op, expr1 , expr2),t1)
| Node(t, [e1]) when tag_is_unop t -> make_eexpr_of_ast e1 typ_var typ_fun >>= fun (expr1,t1) ->
let op = unop_of_tag t in
let* t1 = type_expr_unop op t1 in
OK(Eunop(op,expr1), t1)
| Node(t,[e1]) when t = Tint -> make_eexpr_of_ast e1 typ_var typ_fun
| IntLeaf(num) -> OK(Eint(num), Tint)
| StringLeaf(str) ->
......@@ -106,6 +204,14 @@ let rec make_eexpr_of_ast (a: tree)
let* t = type_expr typ_var typ_fun returned_expression in
OK(returned_expression, t)
| CharLeaf(c) -> OK(Echar(c),Tchar)
| Node(Tp, [e1]) ->
let* (expr, t) = make_eexpr_of_ast e1 typ_var typ_fun in
(match t with
| Tptr t -> OK(Eload(expr), t)
| _ -> Error (Printf.sprintf "Can't Load non pointer here %s" (string_of_ast a)))
| Node(Taddrof, [e1]) ->
let* (expr, t) = make_eexpr_of_ast e1 typ_var typ_fun in
OK(Eaddrof(expr), Tptr t)
| _ -> Error (Printf.sprintf "Unacceptable ast in make_eexpr_of_ast %s"
(string_of_ast a))
in
......@@ -144,7 +250,7 @@ let rec make_einstr_of_ast (a: tree) typ_var typ_fun ret_typ: instr res =
| Node(t,[i1]) when t = Tassign -> make_einstr_of_ast i1 typ_var typ_fun ret_typ
| Node(t,[StringLeaf(str);e1;Node(ty,[])]) when t = Tassignvar ->
| Node(t,[StringLeaf(str);e1;ty]) when t = Tassignvar ->
let* ty = is_type ty in
if ty = Tvoid then Error (Format.sprintf "variable %s cannot be void" str) else
(Hashtbl.replace typ_var str ty;
......@@ -155,13 +261,21 @@ let rec make_einstr_of_ast (a: tree) typ_var typ_fun ret_typ: instr res =
then OK(Iassign(str,expr1))
else Error (Format.sprintf "Can't assign %s to %s" (string_of_typ ty') str)
))
| Node(t,[StringLeaf(str);e1]) when t = Tassignvar ->
(match Hashtbl.find_option typ_var str with
| Some ty -> make_eexpr_of_ast e1 typ_var typ_fun >>= fun (expr1,ty') ->
if ty = ty'
then OK(Iassign(str,expr1))
else Error (Format.sprintf "Can't assign %s to %s" (string_of_typ ty') str)
| None -> Error (Format.sprintf "Can't assign untyped var %s" str))
| Node(t,[varTree;e1]) when t = Tassignvar ->
(match varTree with
| StringLeaf str -> (match Hashtbl.find_option typ_var str with
| Some ty -> make_eexpr_of_ast e1 typ_var typ_fun >>= fun (expr1,ty') ->
if ty = ty'
then OK(Iassign(str,expr1))
else Error (Format.sprintf "Can't assign %s to %s" (string_of_typ ty') str)
| None -> Error (Format.sprintf "Can't assign untyped var %s" str))
| Node(Tp,_) ->
let* (affected_expr, t1) = make_eexpr_of_ast varTree typ_var typ_fun in
let* (affectation, t2) = make_eexpr_of_ast e1 typ_var typ_fun in
let* _ = are_types_compatible t1 t2 in
OK(Istore(affected_expr, affectation))
| _ -> Error (Printf.sprintf "Unacceptable ast in make_einstr_of_ast %s" (string_of_ast a))
)
| Node(t,[e1;i1]) when t = Twhile ->
make_eexpr_of_ast e1 typ_var typ_fun>>= fun (expr1,_) ->
......@@ -178,8 +292,7 @@ let rec make_einstr_of_ast (a: tree) typ_var typ_fun ret_typ: instr res =
| OK(t) -> OK(Ireturn expr1)
| Error q-> Error (Format.sprintf "Bad return type"))
| _ -> Error (Printf.sprintf "Unacceptable ast in make_einstr_of_ast %s"
(string_of_ast a))
| _ -> Error (Printf.sprintf "Unacceptable ast in make_einstr_of_ast %s" (string_of_ast a))
in
match res with
OK o -> res
......@@ -188,7 +301,7 @@ let rec make_einstr_of_ast (a: tree) typ_var typ_fun ret_typ: instr res =
let make_ident (a: tree) : (string * typ) res =
match a with
| Node (Targ, [Node(t,[]);s]) ->
| Node (Targ, [t;s]) ->
let* t = is_type t in
OK (string_of_stringleaf s, t)
| a -> Error (Printf.sprintf "make_ident: unexpected AST: %s"
......@@ -196,20 +309,22 @@ let make_ident (a: tree) : (string * typ) res =
let make_fundef_of_ast (a: tree) (typ_fun: (string, typ list * typ) Hashtbl.t): (string * efun) option res =
match a with
| Node (Tfundef, [Node(retTyp,[]); StringLeaf fname; Node (Tfunargs, fargs); fbody]) ->
| Node (Tfundef, [retTyp; StringLeaf fname; Node (Tfunargs, fargs); fbody]) ->
is_type retTyp >>= fun retTyp ->
list_map_res make_ident fargs >>= fun fargs ->
let typ_var = Hashtbl.of_list fargs in
Hashtbl.replace typ_fun fname ((snd (List.split fargs)), retTyp);
(match fbody with
| NullLeaf -> OK(None)
| _ -> make_einstr_of_ast fbody typ_var typ_fun retTyp>>= fun fbodye ->
let* (funvarinmem, funstksz) = gen_funvarinmem fbodye typ_var in
OK(Some (fname, {
funargs= fargs;
funargs = fargs;
funbody = fbodye;
funvartyp = typ_var;
funrettype = retTyp;
funvarinmem = funvarinmem;
funstksz = funstksz;
})))
| _ ->
Error (Printf.sprintf "make_fundef_of_ast: Expected a Tfundef, got %s."
......
......@@ -28,6 +28,8 @@ let rec dump_eexpr = function
| Evar s -> Printf.sprintf "%s" s
| Ecall (name,expr_list) -> Printf.sprintf "%s(%s)" name (String.concat ", " (List.map dump_eexpr expr_list))
| Echar c -> Printf.sprintf "'%c'" c
| Eload e -> Printf.sprintf "*%s" (dump_eexpr e)
| Eaddrof e -> Printf.sprintf "&%s" (dump_eexpr e)
let indent_size = 2
let spaces n =
......@@ -61,7 +63,7 @@ let rec dump_einstr_rec indent oc i =
print_spaces oc indent;
Format.fprintf oc "print %s;\n" (dump_eexpr e)
| Icall (name,expr_list) -> Format.fprintf oc "%s(%s);\n" name (String.concat ", " (List.map dump_eexpr expr_list))
| Istore (e1,e2) -> Format.fprintf oc "%s = %s;\n" (dump_eexpr e1) (dump_eexpr e2)
let dump_einstr oc i = dump_einstr_rec 0 oc i
......
......@@ -66,6 +66,7 @@ let rec eval_eexpr oc (ep: eprog) st (e : expr) : (int * int Prog.state) res =
(match ret with
| Some n -> OK(n, st)
| None -> Error (Format.sprintf "Error: %s doesn't return anything" name)))
| _ -> Error "bababa"
(* [eval_einstr oc st ins] évalue l'instrution [ins] en partant de l'état [st].
......@@ -126,11 +127,12 @@ and eval_einstr oc (ep: eprog) (st: int state) (ins: instr) :
let* (arg_expr, st) = eval_eexpr oc ep st expr in
OK(expr_l@[arg_expr], st)
) (OK([], st)) expr_list in
match find_function ep name with
(match find_function ep name with
| OK f -> eval_efun oc ep st f name args
| Error _ ->
let* ret = do_builtin oc st.mem name args in
OK (ret, st)
OK (ret, st))
| _ -> Error("nananana")
(* [eval_efun oc st f fname vargs] évalue la fonction [f] (dont le nom est
......
......@@ -72,9 +72,18 @@ type typ =
Tint
| Tchar
| Tvoid
| Tptr of typ
let string_of_typ t =
let rec string_of_typ t =
match t with
| Tint -> "int"
| Tchar -> "char"
| Tvoid -> "void"
\ No newline at end of file
| Tvoid -> "void"
| Tptr ptt-> Printf.sprintf "%s*" (string_of_typ ptt)
let size_type (t: typ) : int res =
match t with
| Tint
| Tptr _ -> OK (Archi.nbits ())
| Tchar -> OK 8
| Tvoid -> Error "Void can't be stored in memory"
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment