simplifier.ml (2462B)
1 open Ast 2 3 module Env = Map.Make(String) 4 5 let collect_constant_strings code = 6 let counter = ref 0 in 7 let env = ref Env.empty in 8 let rec ccs_expr = function 9 | IR.Bool b -> IR2.Bool b, [] 10 | IR.Void -> IR2.Nil, [] 11 | IR.Int n -> IR2.Int n, [] 12 | IR.Char c -> IR2.Char c.[0], [] 13 | IR.Float f -> IR2.Float f, [] 14 | IR.Str s -> 15 (match Env.find_opt s !env with 16 | Some l -> 17 IR2.Data l, [] 18 | None -> 19 incr counter ; 20 let l = "str" ^ (string_of_int !counter) in 21 env := Env.add s l !env ; 22 IR2.Data l, [ (l, s) ]) 23 | IR.Var v -> 24 IR2.Var v, [] 25 | IR.Call (f, args) -> 26 let args2 = List.map ccs_expr args in 27 let ccs = List.flatten (List.map (fun (_, s) -> s) args2) in 28 IR2.Call (f, List.map (fun (e, _) -> e) args2), ccs 29 in 30 (* let ccs_lvalue = function *) 31 (* | IR.LVar v -> *) 32 (* IR2.LVar v, [] *) 33 (* | IR.LAddr a -> *) 34 (* let a2, ccs = ccs_expr a in *) 35 (* IR2.LAddr a2, ccs *) 36 (* in *) 37 let rec ccs_instr = function 38 | IR.Decl v -> 39 IR2.Decl v, [] 40 | IR.Return e -> 41 let e2, ccs = ccs_expr e in 42 IR2.Return e2, ccs 43 | IR.Expr e -> 44 let e2, ccs = ccs_expr e in 45 IR2.Expr e2, ccs 46 47 | IR.Assign (lv, e) -> 48 let lv2, ccs_lv = ccs_expr (IR.Var lv) in 49 let e2, ccs_e = ccs_expr e in 50 IR2.Assign (lv2, e2), List.flatten [ ccs_lv; ccs_e ] 51 52 | IR.Cond (t, y, n) -> 53 let t2, ccs_t = ccs_expr t in 54 let y2, ccs_y = ccs_block y in 55 let n2, ccs_n = ccs_block n in 56 IR2.Cond (t2, y2, n2), List.flatten [ ccs_t ; ccs_y ; ccs_n ] 57 58 | IR.Loop (t, y) -> 59 let t2, ccs_t = ccs_expr t in 60 let y2, ccs_y = ccs_block y in 61 IR2.Loop (t2, y2), List.flatten [ ccs_t ; ccs_y ] 62 63 and ccs_block = function 64 | [] -> [], [] 65 | i :: r -> 66 let i2, ccs_i = ccs_instr i in 67 let r2, ccs_r = ccs_block r in 68 i2 :: r2, List.flatten [ ccs_i ; ccs_r ] 69 in 70 let ccs_def = function 71 | IR.Func (name, args, body) -> 72 let body2, ccs = ccs_block body in 73 IR2.Func (name, args, body2), ccs 74 in 75 let rec ccs_prog = function 76 | [] -> [], [] 77 | d :: r -> 78 let d2, ccs_d = ccs_def d in 79 let r2, ccs_r = ccs_prog r in 80 d2 :: r2, List.flatten [ ccs_d ; ccs_r ] 81 in ccs_prog code 82 83 let simplify code = 84 collect_constant_strings code