From d793658b4103b64701a3f7d2ca4159a275b0d180 Mon Sep 17 00:00:00 2001
From: Youssef <youssef.sellami@student-cs.fr>
Date: Mon, 17 Mar 2025 00:53:44 +0100
Subject: [PATCH] Built-in functions

---
 expr_grammar_action.g                      |  3 +-
 src/ast.ml                                 |  3 +-
 src/cfg.ml                                 |  4 ---
 src/cfg_gen.ml                             |  5 ----
 src/cfg_liveness.ml                        |  1 -
 src/cfg_nop_elim.ml                        |  1 -
 src/cfg_print.ml                           |  2 --
 src/cfg_run.ml                             | 35 ++++++++++++++--------
 src/e_regexp.ml                            |  1 -
 src/elang.ml                               |  1 -
 src/elang_gen.ml                           |  5 ----
 src/elang_print.ml                         |  3 --
 src/elang_run.ml                           | 27 +++++++++--------
 src/lexer.mll                              |  1 -
 src/linear_liveness.ml                     |  2 --
 src/linear_run.ml                          | 27 +++++++++--------
 src/ltl_gen.ml                             | 20 -------------
 src/parser.ml                              |  1 -
 src/rtl.ml                                 |  2 --
 src/rtl_gen.ml                             |  3 --
 src/rtl_print.ml                           |  1 -
 src/rtl_run.ml                             | 28 +++++++++--------
 src/symbols.ml                             |  2 --
 src/yaccparser.mly                         |  3 +-
 tests/funcall/argswap.e.expect_lexer       |  8 ++---
 tests/funcall/print_and_fun.e.expect_lexer |  4 +--
 26 files changed, 74 insertions(+), 119 deletions(-)

diff --git a/expr_grammar_action.g b/expr_grammar_action.g
index 5ab84b3..60a5b34 100644
--- a/expr_grammar_action.g
+++ b/expr_grammar_action.g
@@ -1,6 +1,6 @@
 tokens SYM_EOF SYM_IDENTIFIER<string> SYM_INTEGER<int> SYM_PLUS SYM_MINUS SYM_ASTERISK SYM_DIV SYM_MOD
 tokens SYM_LPARENTHESIS SYM_RPARENTHESIS SYM_LBRACE SYM_RBRACE
-tokens SYM_ASSIGN SYM_SEMICOLON SYM_RETURN SYM_IF SYM_WHILE SYM_ELSE SYM_COMMA SYM_PRINT
+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
 non-terminals S INSTR<tree> INSTRS<tree list> LINSTRS ELSE EXPR FACTOR
 non-terminals LPARAMS REST_PARAMS
@@ -60,7 +60,6 @@ INSTRS -> { [] }
 INSTR -> SYM_IF SYM_LPARENTHESIS EXPR SYM_RPARENTHESIS SYM_LBRACE LINSTRS SYM_RBRACE ELSE { Node(Tif, [$3; $6; $8]) }
 INSTR -> SYM_WHILE SYM_LPARENTHESIS EXPR SYM_RPARENTHESIS INSTR { Node(Twhile, [$3; $5]) }
 INSTR -> SYM_RETURN EXPR SYM_SEMICOLON { Node(Treturn, [$2]) }
-INSTR -> SYM_PRINT SYM_LPARENTHESIS EXPR SYM_RPARENTHESIS SYM_SEMICOLON { Node(Tprint, [$3]) }
 INSTR -> IDENTIFIER AFTER_IDENTIFIER_INSTR SYM_SEMICOLON { 
   match $2 with
   | Assign exp -> Node(Tassign, [$1; exp]) 
diff --git a/src/ast.ml b/src/ast.ml
index cfb67d6..7560fa6 100644
--- a/src/ast.ml
+++ b/src/ast.ml
@@ -22,7 +22,7 @@ open Batteries
 
 *)
 
-type tag = Tassign | Tif | Twhile | Tblock | Treturn | Tprint
+type tag = Tassign | Tif | Twhile | Tblock | Treturn
          | Tint
          | Tadd | Tmul | Tdiv | Tmod | Txor | Tsub
          | Tclt | Tcgt | Tcle | Tcge | Tceq | Tne
@@ -51,7 +51,6 @@ let string_of_tag = function
   | Twhile -> "Twhile"
   | Tblock -> "Tblock"
   | Treturn -> "Treturn"
-  | Tprint -> "Tprint"
   | Tint -> "Tint"
   | Tadd -> "Tadd"
   | Tmul -> "Tmul"
diff --git a/src/cfg.ml b/src/cfg.ml
index 2a60c97..467b19b 100644
--- a/src/cfg.ml
+++ b/src/cfg.ml
@@ -13,7 +13,6 @@ type expr =
 type cfg_node =
   | Cassign of string * expr * int
   | Creturn of expr
-  | Cprint of expr * int
   | Ccmp of expr * int * int
   | Cnop of int
   | Ccall of string * expr list * int
@@ -32,7 +31,6 @@ type cprog = cfg_fun prog
 let succs cfg n =
   match Hashtbl.find_option cfg n with
   | None -> Set.empty
-  | Some (Cprint (_, s))
   | Some (Cassign (_, _, s)) -> Set.singleton s
   | Some (Creturn _) -> Set.empty
   | Some (Ccmp (_, s1, s2)) -> Set.of_list [s1;s2]
@@ -45,7 +43,6 @@ let preds cfgfunbody n =
   Hashtbl.fold (fun m m' acc ->
       match m' with
       | Cassign (_, _, s)
-      | Cprint (_, s)
       | Cnop s 
       | Ccall (_, _, s) -> if s = n then Set.add m acc else acc
       | Creturn _ -> acc
@@ -71,7 +68,6 @@ let size_instr (i: cfg_node) : int =
   match (i : cfg_node) with
   | Cassign (_, e, _) -> 1 + size_expr e
   | Creturn e -> 1 + (size_expr e)
-  | Cprint (e, _) -> 1 + (size_expr e)
   | Ccmp (e, _, _) -> 1 + size_expr e
   | Cnop _ -> 1
   | Ccall (_, args, _) -> 1 + List.fold_left (fun acc arg -> acc + size_expr arg) 0 args
diff --git a/src/cfg_gen.ml b/src/cfg_gen.ml
index ff2aa1b..f009b7b 100644
--- a/src/cfg_gen.ml
+++ b/src/cfg_gen.ml
@@ -69,10 +69,6 @@ let rec cfg_node_of_einstr (next: int) (cfg : (int, cfg_node) Hashtbl.t)
   | Elang.Ireturn e ->
     cfg_expr_of_eexpr e >>= fun e ->
     Hashtbl.replace cfg next (Creturn e); OK (next, next + 1)
-  | Elang.Iprint e ->
-    cfg_expr_of_eexpr e >>= fun e ->
-    Hashtbl.replace cfg next (Cprint (e,succ));
-    OK (next, next + 1)
   | Elang.Icall (f, args) ->
     list_map_res cfg_expr_of_eexpr args >>= fun es ->
     Hashtbl.replace cfg next (Ccall (f, es, succ));
@@ -89,7 +85,6 @@ let rec reachable_nodes n (cfg: (int,cfg_node) Hashtbl.t) =
       match Hashtbl.find_option cfg n with
       | None -> reach
       | Some (Cnop succ)
-      | Some (Cprint (_, succ))
       | Some (Cassign (_, _, succ)) -> reachable_aux succ reach
       | Some (Creturn _) -> reach
       | Some (Ccmp (_, s1, s2)) ->
diff --git a/src/cfg_liveness.ml b/src/cfg_liveness.ml
index aa40206..0ecbbc3 100644
--- a/src/cfg_liveness.ml
+++ b/src/cfg_liveness.ml
@@ -32,7 +32,6 @@ let live_cfg_node (node: cfg_node) (live_after: string Set.t) =
          match node with
          | Cassign (s, e, i) -> vars_in_expr e
          | Creturn e -> vars_in_expr e
-         | Cprint (e, i) -> vars_in_expr e
          | Ccmp (e, i1, i2) -> vars_in_expr e
          | Cnop (i) -> Set.empty
          | Ccall (f, args, i) -> vars_in_expr (Ecall (f, args))
diff --git a/src/cfg_nop_elim.ml b/src/cfg_nop_elim.ml
index dba2b51..4592c82 100644
--- a/src/cfg_nop_elim.ml
+++ b/src/cfg_nop_elim.ml
@@ -64,7 +64,6 @@ let replace_succs nop_succs (n: cfg_node) =
    (* TODO *)
    match n with
    | Cassign (s, e, i) -> Cassign (s, e, replace_succ nop_succs i)
-   | Cprint (e, i) -> Cprint (e, replace_succ nop_succs i)
    | Ccmp (e, i1, i2) -> Ccmp (e, replace_succ nop_succs i1, replace_succ nop_succs i2)
    | Cnop i -> Cnop (replace_succ nop_succs i)
    | Creturn e -> Creturn e
diff --git a/src/cfg_print.ml b/src/cfg_print.ml
index a452410..d7bc988 100644
--- a/src/cfg_print.ml
+++ b/src/cfg_print.ml
@@ -17,7 +17,6 @@ let dump_list_cfgexpr l =
 let dump_arrows oc fname n (node: cfg_node) =
   match node with
   | Cassign (_, _, succ)
-  | Cprint (_, succ)
   | Cnop succ 
   | Ccall (_, _, succ) ->
     Format.fprintf oc "n_%s_%d -> n_%s_%d\n" fname n fname succ
@@ -30,7 +29,6 @@ let dump_arrows oc fname n (node: cfg_node) =
 let dump_cfg_node oc (node: cfg_node) =
   match node with
   | Cassign (v, e, _) -> Format.fprintf oc "%s = %s" v (dump_cfgexpr e)
-  | Cprint (e, _) -> Format.fprintf oc "print %s" (dump_cfgexpr e)
   | Creturn e -> Format.fprintf oc "return %s" (dump_cfgexpr e)
   | Ccmp (e, _, _) -> Format.fprintf oc "%s" (dump_cfgexpr e)
   | Cnop _ -> Format.fprintf oc "nop"
diff --git a/src/cfg_run.ml b/src/cfg_run.ml
index e2e4212..a705b96 100644
--- a/src/cfg_run.ml
+++ b/src/cfg_run.ml
@@ -34,12 +34,18 @@ let rec eval_cfgexpr oc st cp (e: expr) : (int * int state) res =
             | Error msg -> Error msg
             | OK (i, st'') -> OK ((l@[i]), st'')
               ) (OK([], st)) args >>= fun (int_args, st') ->
-                find_function cp f >>= fun found_f ->
-                  match eval_cfgfun oc st' cp f found_f int_args with
-                  | Error msg -> Error msg
-                  | OK (None, st'') -> Error (Format.sprintf "CFG: Function %s doesn't have a return value.\n" f)
-                  | OK (Some ret, st'') -> OK (ret, st'')
-  
+                match find_function cp f with
+            | OK found_f -> 
+               (match eval_cfgfun oc st' cp f found_f int_args with
+               | Error msg -> Error msg
+               | OK (None, st'') -> Error (Format.sprintf "CFG: Function %s doesn't have a return value.\n" f)
+               | OK (Some ret, st'') -> OK (ret, st''))
+            | Error msg -> 
+               (match do_builtin oc st.mem f int_args with
+               | Error msg -> Error msg
+               | OK None -> Error (Format.sprintf "CFG: Function %s doesn't have a return value.\n" f)
+               | OK (Some ret) -> OK (ret, st'))
+
 and eval_cfginstr oc st cp ht (n: int): (int * int state) res =
   match Hashtbl.find_option ht n with
   | None -> Error (Printf.sprintf "Invalid node identifier\n")
@@ -57,10 +63,6 @@ and eval_cfginstr oc st cp ht (n: int): (int * int state) res =
     | Creturn(e) ->
       eval_cfgexpr oc st cp e >>= fun (e, st') ->
       OK (e, st')
-    | Cprint(e, succ) ->
-      eval_cfgexpr oc st cp e >>= fun (e, st') ->
-      Format.fprintf oc "%d\n" e;
-      eval_cfginstr oc st' cp ht succ
     | Ccall (f, args, succ) ->
       List.fold_left (
         fun (acc : (int list * int state) res) (arg : expr) -> 
@@ -72,9 +74,16 @@ and eval_cfginstr oc st cp ht (n: int): (int * int state) res =
             | OK (i, st'') -> OK ((l@[i]), st'')
               ) (OK([], st)) args 
               >>= fun (int_args, st') ->
-              find_function cp f >>= fun found_f ->
-              eval_cfgfun oc st' cp f found_f int_args >>= fun (ret, st'') -> 
-              eval_cfginstr oc st'' cp ht succ
+                match find_function cp f with
+                | OK found_f -> 
+                   (match eval_cfgfun oc st' cp f found_f int_args with
+                   | Error msg -> Error msg
+                   | OK (_, st'') -> eval_cfginstr oc st'' cp ht succ)
+                | Error msg -> 
+                   (match do_builtin oc st'.mem f int_args with
+                   | OK _ -> eval_cfginstr oc st' cp ht succ
+                   | Error msg -> Error msg )
+              
 
 and eval_cfgfun oc st cp cfgfunname { cfgfunargs;
                                       cfgfunbody;
diff --git a/src/e_regexp.ml b/src/e_regexp.ml
index a87413d..e909133 100644
--- a/src/e_regexp.ml
+++ b/src/e_regexp.ml
@@ -74,7 +74,6 @@ let list_regexp : (regexp * (string -> token option)) list =
     (keyword_regexp "if",       fun _ -> Some (SYM_IF));
     (keyword_regexp "else",       fun _ -> Some (SYM_ELSE));
     (keyword_regexp "return",       fun _ -> Some (SYM_RETURN));
-    (keyword_regexp "print",       fun _ -> Some (SYM_PRINT));
     (keyword_regexp "struct",       fun _ -> Some (SYM_STRUCT));
     (char_regexp '.',       fun _ -> Some (SYM_POINT));
     (char_regexp '+',       fun _ -> Some (SYM_PLUS));
diff --git a/src/elang.ml b/src/elang.ml
index 38b4f66..03d287f 100644
--- a/src/elang.ml
+++ b/src/elang.ml
@@ -17,7 +17,6 @@ type instr =
   | Iwhile of expr * instr
   | Iblock of instr list
   | Ireturn of expr
-  | Iprint of expr
   | Icall of string * expr list
 
 type efun = {
diff --git a/src/elang_gen.ml b/src/elang_gen.ml
index 1d4db2d..54e9203 100644
--- a/src/elang_gen.ml
+++ b/src/elang_gen.ml
@@ -108,11 +108,6 @@ let rec make_einstr_of_ast (a: tree) : instr res =
         in match res_of_e with 
         | OK exp -> OK (Ireturn exp)
         | Error msg -> Error msg)
-    | Node(Tprint, [e]) -> 
-      (let res_of_e = make_eexpr_of_ast e 
-        in match res_of_e with 
-        | OK exp -> OK (Iprint exp)
-        | Error msg -> Error msg)
     | Node(Tcall, [StringLeaf f; Node(Targs, args)]) -> 
       (let res = list_map_res make_eexpr_of_ast args 
         in match res with
diff --git a/src/elang_print.ml b/src/elang_print.ml
index 8f7f8cf..8e4d55d 100644
--- a/src/elang_print.ml
+++ b/src/elang_print.ml
@@ -56,9 +56,6 @@ let rec dump_einstr_rec indent oc i =
   | Ireturn(e) ->
     print_spaces oc indent;
     Format.fprintf oc "return %s;\n" (dump_eexpr e)
-  | Iprint(e) ->
-    print_spaces oc indent;
-    Format.fprintf oc "print %s;\n" (dump_eexpr e)
   | Icall(f, args) ->
     print_spaces oc indent;
     Format.fprintf oc "%s(%s);\n" f (String.concat ", " (List.map dump_eexpr args))
diff --git a/src/elang_run.ml b/src/elang_run.ml
index 880e938..4a5bd71 100644
--- a/src/elang_run.ml
+++ b/src/elang_run.ml
@@ -2,6 +2,7 @@ open Elang
 open Batteries
 open Prog
 open Utils
+open Builtins
 
 let binop_bool_to_int f x y = if f x y then 1 else 0
 
@@ -65,13 +66,16 @@ let rec eval_eexpr oc st (ep: eprog) (e : expr) : (int * int state) res =
          | Error msg -> Error msg
          | OK (int_args, st') -> 
             match find_function ep f with
-            | Error msg -> Error msg
             | OK found_f -> 
-               match eval_efun oc st' ep found_f f int_args with
+               (match eval_efun oc st' ep found_f f int_args with
                | Error msg -> Error msg
                | OK (None, st'') -> Error (Format.sprintf "E: Function %s doesn't have a return value.\n" f)
-               | OK (Some ret, st'') -> OK (ret, st'')
-         
+               | OK (Some ret, st'') -> OK (ret, st''))
+            | Error msg -> 
+               (match do_builtin oc st'.mem f int_args with
+               | Error msg -> Error msg
+               | OK None -> Error (Format.sprintf "E: Function %s doesn't have a return value.\n" f)
+               | OK (Some ret) -> OK (ret, st'))
          
 (* [eval_einstr oc st ins] évalue l'instrution [ins] en partant de l'état [st].
 
@@ -125,12 +129,6 @@ and eval_einstr oc (st: int state) (ep: eprog) (ins: instr) :
       (match eval_eexpr oc st ep e with
       | Error msg -> Error msg
       | OK (v, st') -> OK(Some v, st'))  
-   | Iprint e -> 
-      (match eval_eexpr oc st ep e with
-      | Error msg -> Error msg
-      | OK (v, st') -> 
-         Format.fprintf oc "%d\n" v;
-         OK(None, st'))
    | Icall (f, args) -> 
       let (res : (int list * int state) res) = List.fold_left (
             fun (acc : (int list * int state) res) (arg : expr) -> 
@@ -145,11 +143,14 @@ and eval_einstr oc (st: int state) (ep: eprog) (ins: instr) :
          | Error msg -> Error msg
          | OK (int_args, st') -> 
             match find_function ep f with
-            | Error msg -> Error msg
             | OK found_f -> 
-               match eval_efun oc st' ep found_f f int_args with
+               (match eval_efun oc st' ep found_f f int_args with
                | Error msg -> Error msg
-               | OK (_, st'') -> OK (None, st'')
+               | OK (_, st'') -> OK (None, st''))
+            | Error msg -> 
+               (match do_builtin oc st'.mem f int_args with
+               | OK _ -> OK (None, st')
+               | Error msg -> Error msg )
 
 (* [eval_efun oc st f fname vargs] évalue la fonction [f] (dont le nom est
    [fname]) en partant de l'état [st], avec les arguments [vargs].
diff --git a/src/lexer.mll b/src/lexer.mll
index 9aa999d..f4ac582 100644
--- a/src/lexer.mll
+++ b/src/lexer.mll
@@ -30,7 +30,6 @@ rule token = parse
   | "void" { SYM_VOID }
   | "char" { SYM_CHAR }
   | "int" { SYM_INT }
-  | "print" { SYM_PRINT }
   | "struct" { SYM_STRUCT }
   | "if" { SYM_IF }
   | "else" { SYM_ELSE }
diff --git a/src/linear_liveness.ml b/src/linear_liveness.ml
index 5082e7f..d8fe1aa 100644
--- a/src/linear_liveness.ml
+++ b/src/linear_liveness.ml
@@ -8,7 +8,6 @@ open Rtl
 let gen_live (i: rtl_instr) =
   match i with
   | Rbinop (b, rd, rs1, rs2) -> Set.of_list [rs1; rs2]
-  | Rprint rs
   | Runop (_, _, rs) -> Set.singleton rs
   | Rconst (_, _) -> Set.empty
   | Rbranch (_, rs1, rs2, _) -> Set.of_list [rs1; rs2]
@@ -26,7 +25,6 @@ let kill_live (i: rtl_instr) =
   | Rmov (rd,_)
   | Rcall (Some rd, _, _) -> Set.singleton rd
   | Rbranch (_, _, _, _)
-  | Rprint _
   | Rret _
   | Rjmp _
   | Rlabel _ 
diff --git a/src/linear_run.ml b/src/linear_run.ml
index 8051790..9551455 100644
--- a/src/linear_run.ml
+++ b/src/linear_run.ml
@@ -47,13 +47,6 @@ let rec exec_linear_instr oc lp fname f st (i: rtl_instr) =
       OK (None, st)
     | _ -> Error (Printf.sprintf "Mov on undefined register (%s)" (print_reg rs))
     end
-  | Rprint r ->
-    begin match Hashtbl.find_option st.regs r with
-      | Some s ->
-        Format.fprintf oc "%d\n" s;
-        OK (None, st)
-      | _ -> Error (Printf.sprintf "Print on undefined register (%s)" (print_reg r))
-    end
   | Rret r ->
     begin match Hashtbl.find_option st.regs r with
       | Some s -> OK (Some s, st)
@@ -71,12 +64,20 @@ let rec exec_linear_instr oc lp fname f st (i: rtl_instr) =
           | Some v -> Some (vs@[v]))) 
           (Some []) args 
       in match vs_opt with
-      | Some params -> find_function lp g >>= fun found_g ->
-        (match rd_opt, exec_linear_fun oc lp st g found_g params with
-        | _, Error msg -> Error msg
-        | Some rd, OK (Some ret, st') -> exec_linear_instr oc lp fname f st' (Rconst (rd, ret))
-        | Some rd, OK (None, st') -> Error (Printf.sprintf "Function %s doesn't have a return value" g)
-        | None, OK (_, st') -> OK(None, st'))
+      | Some params -> 
+          (match find_function lp g with
+          | OK found_g ->
+            (match rd_opt, exec_linear_fun oc lp st g found_g params with
+            | _, Error msg -> Error msg
+            | Some rd, OK (Some ret, st') -> exec_linear_instr oc lp fname f st' (Rconst (rd, ret))
+            | Some rd, OK (None, st') -> Error (Printf.sprintf "Function %s doesn't have a return value" g)
+            | None, OK (_, st') -> OK(None, st'))
+          | Error msg -> 
+            (match rd_opt, do_builtin oc st.mem g params with
+            | _, Error msg -> Error msg
+            | Some rd, OK None -> Error (Format.sprintf "RTL: Function %s doesn't have a return value.\n" g)
+            | Some rd, OK (Some ret) -> exec_linear_instr oc lp fname f st (Rconst (rd, ret))
+            | None, OK _ -> OK(None, st)))
       | _ -> Error (Printf.sprintf "Function %s applied on undefined register" g)
     end
 
diff --git a/src/ltl_gen.ml b/src/ltl_gen.ml
index 581f0c9..dbe0e57 100644
--- a/src/ltl_gen.ml
+++ b/src/ltl_gen.ml
@@ -217,7 +217,6 @@ let written_rtl_regs_instr (i: rtl_instr) =
   | Rconst (rd, _)
   | Rmov (rd, _) 
   | Rcall (Some rd, _, _)-> Set.singleton rd
-  | Rprint _
   | Rret _
   | Rlabel _
   | Rbranch (_, _, _, _)
@@ -228,7 +227,6 @@ let read_rtl_regs_instr (i: rtl_instr) =
   match i with
   | Rbinop (_, _, rs1, rs2)
   | Rbranch (_, rs1, rs2, _) -> Set.of_list [rs1; rs2]
-  | Rprint rs
   | Runop (_, _, rs)
   | Rmov (_, rs)
   | Rret rs -> Set.singleton rs
@@ -302,24 +300,6 @@ let ltl_instrs_of_linear_instr fname live_out allocation
     load_loc reg_tmp1 allocation rs >>= fun (ls, rs) ->
     store_loc reg_tmp1 allocation rd >>= fun (ld, rd) ->
     OK (ls @ LMov(rd, rs) :: ld)
-  | Rprint r ->
-    let (save_a_regs, arg_saved, ofs) =
-      save_caller_save
-        (range 32)
-        (- (numspilled+1)) in
-    let parameter_passing =
-      match Hashtbl.find_option allocation r with
-      | None -> Error (Format.sprintf "Could not find allocation for register %d\n" r)
-      | Some (Reg rs) -> OK [LMov(reg_a0, rs)]
-      | Some (Stk o) -> OK [LLoad(reg_a0, reg_fp, (Archi.wordsize ()) * o, (archi_mas ()))]
-    in
-    parameter_passing >>= fun parameter_passing ->
-    OK (LComment "Saving a0-a7,t0-t6" :: save_a_regs @
-        LAddi(reg_sp, reg_s0, (Archi.wordsize ()) * (ofs + 1)) ::
-        parameter_passing @
-        LCall "print" ::
-        LComment "Restoring a0-a7,t0-t6" :: restore_caller_save arg_saved)
-
   | Rret r ->
     load_loc reg_tmp1 allocation r >>= fun (l,r) ->
     OK (l @ [LMov (reg_ret, r) ; LJmp epilogue_label])
diff --git a/src/parser.ml b/src/parser.ml
index 2e2c5f0..44e6a89 100644
--- a/src/parser.ml
+++ b/src/parser.ml
@@ -53,7 +53,6 @@ let to_yacc_token = function
 | SYM_LBRACKET -> Yaccparser.SYM_LBRACKET
 | SYM_RBRACKET -> Yaccparser.SYM_RBRACKET
 | SYM_ALLOC -> Yaccparser.SYM_ALLOC
-| SYM_PRINT -> Yaccparser.SYM_PRINT
 | SYM_EXTERN -> Yaccparser.SYM_EXTERN
 | SYM_INCLUDE(s) -> Yaccparser.SYM_INCLUDE s
 | SYM_AMPERSAND -> Yaccparser.SYM_AMPERSAND
diff --git a/src/rtl.ml b/src/rtl.ml
index 0360732..18d5f7d 100644
--- a/src/rtl.ml
+++ b/src/rtl.ml
@@ -14,7 +14,6 @@ type rtl_instr = Rbinop of binop * reg * reg * reg
                | Rmov of reg * reg
                | Rret of reg
                | Rlabel of int
-               | Rprint of reg
                | Rcall of reg option * string * reg list
 
 type rtl_fun = { rtlfunargs: reg list;
@@ -29,7 +28,6 @@ let written_rtl_regs_instr (i: rtl_instr) =
   | Runop (_, rd, _)
   | Rconst (rd, _)
   | Rmov (rd, _) -> Set.singleton rd
-  | Rprint _
   | Rret _
   | Rlabel _
   | Rbranch (_, _, _, _)
diff --git a/src/rtl_gen.ml b/src/rtl_gen.ml
index e49d304..0dde9d9 100644
--- a/src/rtl_gen.ml
+++ b/src/rtl_gen.ml
@@ -90,9 +90,6 @@ let rtl_instrs_of_cfg_node ((next_reg:int), (var2reg: (string*int) list)) (c: cf
   | Creturn e ->
     let r_e, l, next_reg', var2reg' = rtl_instrs_of_cfg_expr (next_reg, var2reg) e
       in (l@[Rret r_e], next_reg', var2reg')
-  | Cprint (e, i) ->
-    let r_e, l, next_reg', var2reg' = rtl_instrs_of_cfg_expr (next_reg, var2reg) e
-      in (l@[Rprint r_e; Rjmp i], next_reg', var2reg')
   | Ccmp (e, i1, i2) ->
     let cmp, e1, e2 = rtl_cmp_of_cfg_expr e
       in let r1, l1, next_reg1, var2reg1 = rtl_instrs_of_cfg_expr (next_reg, var2reg) e1
diff --git a/src/rtl_print.ml b/src/rtl_print.ml
index a9c1224..a2837a7 100644
--- a/src/rtl_print.ml
+++ b/src/rtl_print.ml
@@ -39,7 +39,6 @@ let dump_rtl_instr name (live_in, live_out) ?(endl="\n") oc (i: rtl_instr) =
     Format.fprintf oc "jmp %s" (print_node s)
   | Rmov (rd, rs) -> Format.fprintf oc "%s <- %s" (print_reg rd) (print_reg rs)
   | Rret r -> Format.fprintf oc "ret %s" (print_reg r)
-  | Rprint r -> Format.fprintf oc "print %s" (print_reg r)
   | Rlabel n -> Format.fprintf oc "%s_%d:" name n
   | Rcall (rd_opt, f, regs) ->  
     match rd_opt with
diff --git a/src/rtl_run.ml b/src/rtl_run.ml
index fb7a809..8a1fa98 100644
--- a/src/rtl_run.ml
+++ b/src/rtl_run.ml
@@ -69,13 +69,6 @@ let rec exec_rtl_instr oc rp rtlfunname f st (i: rtl_instr) =
       | Some s -> OK (Some s, st)
       | _ -> Error (Printf.sprintf "Ret on undefined register (%s)" (print_reg r))
     end
-  | Rprint r ->
-    begin match Hashtbl.find_option st.regs r with
-      | Some s ->
-        Format.fprintf oc "%d\n" s;
-        OK (None, st)
-      | _ -> Error (Printf.sprintf "Print on undefined register (%s)" (print_reg r))
-    end
   | Rlabel n -> OK (None, st)
   | Rcall (rd_opt, g, args) -> 
     begin 
@@ -88,13 +81,22 @@ let rec exec_rtl_instr oc rp rtlfunname f st (i: rtl_instr) =
           | Some v -> Some (vs@[v]))) 
           (Some []) args 
       in match vs_opt with
-      | Some params -> find_function rp g >>= fun found_g ->
-        (match rd_opt, exec_rtl_fun oc rp st g found_g params with
-        | _, Error msg -> Error msg
-        | Some rd, OK (Some ret, st') -> exec_rtl_instr oc rp rtlfunname f st' (Rconst (rd, ret))
-        | Some rd, OK (None, st') -> Error (Printf.sprintf "Function %s doesn't have a return value" g)
-        | None, OK (_, st') -> OK(None, st'))
+      | Some params -> 
+        (match find_function rp g with
+        | OK found_g ->
+          (match rd_opt, exec_rtl_fun oc rp st g found_g params with
+          | _, Error msg -> Error msg
+          | Some rd, OK (Some ret, st') -> exec_rtl_instr oc rp rtlfunname f st' (Rconst (rd, ret))
+          | Some rd, OK (None, st') -> Error (Printf.sprintf "Function %s doesn't have a return value" g)
+          | None, OK (_, st') -> OK(None, st'))
+        | Error msg -> 
+          (match rd_opt, do_builtin oc st.mem g params with
+          | _, Error msg -> Error msg
+          | Some rd, OK None -> Error (Format.sprintf "RTL: Function %s doesn't have a return value.\n" g)
+          | Some rd, OK (Some ret) -> exec_rtl_instr oc rp rtlfunname f st (Rconst (rd, ret))
+          | None, OK _ -> OK(None, st)))
       | _ -> Error (Printf.sprintf "Function %s applied on undefined register" g)
+          
     end
 
 and exec_rtl_instr_at oc rp rtlfunname ({ rtlfunbody;  } as f: rtl_fun) st i =
diff --git a/src/symbols.ml b/src/symbols.ml
index 71760ef..ce80f81 100644
--- a/src/symbols.ml
+++ b/src/symbols.ml
@@ -50,7 +50,6 @@ type token =
  | SYM_LBRACKET
  | SYM_RBRACKET
  | SYM_ALLOC
- | SYM_PRINT
  | SYM_EXTERN
  | SYM_INCLUDE of string
  | SYM_AMPERSAND
@@ -99,7 +98,6 @@ let string_of_symbol = function
 | SYM_LBRACKET -> "SYM_LBRACKET"
 | SYM_RBRACKET -> "SYM_RBRACKET"
 | SYM_ALLOC -> "SYM_ALLOC"
-| SYM_PRINT -> "SYM_PRINT"
 | SYM_EXTERN -> "SYM_EXTERN"
 | SYM_INCLUDE(s) -> Printf.sprintf "SYM_INCLUDE(%s)" s
 | SYM_AMPERSAND -> "SYM_AMPERSAND"
diff --git a/src/yaccparser.mly b/src/yaccparser.mly
index 3c9a390..f335483 100644
--- a/src/yaccparser.mly
+++ b/src/yaccparser.mly
@@ -14,7 +14,7 @@
 %token<int> SYM_INTEGER
 %token SYM_PLUS SYM_MINUS SYM_ASTERISK SYM_DIV SYM_MOD
 %token SYM_LPARENTHESIS SYM_RPARENTHESIS SYM_LBRACE SYM_RBRACE
-%token SYM_ASSIGN SYM_SEMICOLON SYM_RETURN SYM_IF SYM_WHILE SYM_ELSE SYM_COMMA SYM_PRINT
+%token SYM_ASSIGN SYM_SEMICOLON SYM_RETURN SYM_IF SYM_WHILE SYM_ELSE SYM_COMMA
 %token SYM_EQUALITY SYM_NOTEQ SYM_LT SYM_LEQ SYM_GT SYM_GEQ
 
 %left SYM_EQUALITY SYM_NOTEQ
@@ -68,7 +68,6 @@
       | SYM_IF SYM_LPARENTHESIS expr SYM_RPARENTHESIS linstrs ntelse { Node (Tif, [$3; $5; $6]) }
       | SYM_WHILE SYM_LPARENTHESIS expr SYM_RPARENTHESIS instr { Node( Twhile, [$3; $5]) }
       | SYM_RETURN expr SYM_SEMICOLON { Node(Treturn, [$2]) }
-      | SYM_PRINT expr SYM_SEMICOLON { Node(Tprint, [$2]) }
       | linstrs { $1 };
       ntelse :
         SYM_ELSE linstrs { $2 }
diff --git a/tests/funcall/argswap.e.expect_lexer b/tests/funcall/argswap.e.expect_lexer
index 89b98c3..2c8a87d 100644
--- a/tests/funcall/argswap.e.expect_lexer
+++ b/tests/funcall/argswap.e.expect_lexer
@@ -5,12 +5,12 @@ SYM_COMMA
 SYM_IDENTIFIER(b)
 SYM_RPARENTHESIS
 SYM_LBRACE
-SYM_PRINT
+SYM_IDENTIFIER(print)
 SYM_LPARENTHESIS
 SYM_IDENTIFIER(a)
 SYM_RPARENTHESIS
 SYM_SEMICOLON
-SYM_PRINT
+SYM_IDENTIFIER(print)
 SYM_LPARENTHESIS
 SYM_IDENTIFIER(b)
 SYM_RPARENTHESIS
@@ -30,12 +30,12 @@ SYM_COMMA
 SYM_IDENTIFIER(b)
 SYM_RPARENTHESIS
 SYM_LBRACE
-SYM_PRINT
+SYM_IDENTIFIER(print)
 SYM_LPARENTHESIS
 SYM_IDENTIFIER(a)
 SYM_RPARENTHESIS
 SYM_SEMICOLON
-SYM_PRINT
+SYM_IDENTIFIER(print)
 SYM_LPARENTHESIS
 SYM_IDENTIFIER(b)
 SYM_RPARENTHESIS
diff --git a/tests/funcall/print_and_fun.e.expect_lexer b/tests/funcall/print_and_fun.e.expect_lexer
index d8e4934..834218f 100644
--- a/tests/funcall/print_and_fun.e.expect_lexer
+++ b/tests/funcall/print_and_fun.e.expect_lexer
@@ -21,12 +21,12 @@ SYM_LPARENTHESIS
 SYM_INTEGER(8)
 SYM_RPARENTHESIS
 SYM_SEMICOLON
-SYM_PRINT
+SYM_IDENTIFIER(print)
 SYM_LPARENTHESIS
 SYM_IDENTIFIER(a)
 SYM_RPARENTHESIS
 SYM_SEMICOLON
-SYM_PRINT
+SYM_IDENTIFIER(print)
 SYM_LPARENTHESIS
 SYM_IDENTIFIER(b)
 SYM_RPARENTHESIS
-- 
GitLab