open Ident open Ast open Static open Format open Misc let print_name ff n = fprintf ff "%s" n let rec print_list_r print lp sep rp ff = function | [] -> () | x :: l -> fprintf ff "%s%a" lp print x; List.iter (fprintf ff "%s %a" sep print) l; fprintf ff "%s" rp let rec print_list_nlr print lp sep rp ff = function | [] -> () | x :: l -> fprintf ff "%s%a" lp print x; List.iter (fprintf ff "%s@ %a" sep print) l; fprintf ff "%s" rp let print_bool ff b = if b then fprintf ff "1" else fprintf ff "0" let rec print_const ff v = match v with | VBit b -> print_bool ff b | VBitArray a when Array.length a = 0 -> fprintf ff "[]" | VBitArray l -> Array.iter (print_bool ff) l let rec print_static_exp ff se = match se.se_desc with | SInt i -> fprintf ff "%d" i | SBool b -> print_bool ff b | SVar n -> print_name ff n | SBinOp(op, se1, se2) -> let op_str = match op with | SAdd -> "+" | SMinus -> "-" | SMult -> "*" | SDiv -> "/" | SPower -> "^" | SEqual -> "=" | SLess -> "<" | SLeq -> "<=" | SGreater -> ">" | SGeq -> ">=" in fprintf ff "(%a %s %a)" print_static_exp se1 op_str print_static_exp se2 | SIf (c, se1, se2) -> fprintf ff "(%a ? %a : %a)" print_static_exp c print_static_exp se1 print_static_exp se2 let rec print_static_type ff sty = match sty with | STInt -> fprintf ff "int" | STBool -> fprintf ff "bool" let rec print_type ff ty = match ty with | TUnit -> fprintf ff "()" | TBit -> fprintf ff "bit" | TBitArray se -> fprintf ff "bit[%a]" print_static_exp se | TProd l -> print_list_r print_type "" "*" "" ff l | TVar _ -> fprintf ff "" let print_call_params ff params = match params with | [] -> () | _ -> print_list_r print_static_exp "<<"","">>" ff params let rec print_exp ff e = if !Cli_options.print_types then fprintf ff "(%a : %a)" print_edesc e.e_desc print_type e.e_ty else fprintf ff "%a" print_edesc e.e_desc and print_edesc ff ed = match ed with | Econst v -> print_const ff v | Evar n -> print_ident ff n | Ereg e -> fprintf ff "reg %a" print_exp e | Ecall("select", idx::_, args) -> let e1 = assert_1 args in fprintf ff "%a[%a]" print_exp e1 print_static_exp idx | Ecall("slice", low::high::_, args) -> let e1 = assert_1 args in fprintf ff "%a[%a..%a]" print_exp e1 print_static_exp low print_static_exp high | Ecall("concat", _, args) -> let e1, e2 = assert_2 args in fprintf ff "%a . %a" print_exp e1 print_exp e2 | Ecall(fn, params, args) -> fprintf ff "%a%a%a" print_name fn print_call_params params print_args args | Emem(MRom, addr_size, word_size, _, args) -> fprintf ff "rom<%a,%a>%a" print_static_exp addr_size print_static_exp word_size print_args args | Emem(MRam, addr_size, word_size, _, args) -> fprintf ff "ram<%a,%a>%a" print_static_exp addr_size print_static_exp word_size print_args args and print_args ff args = print_list_r print_exp "(" "," ")" ff args let rec print_pat ff pat = match pat with | Evarpat id -> print_ident ff id | Etuplepat l -> print_list_r print_ident "(" "," ")" ff l let print_eq ff (pat, e) = fprintf ff "%a = %a" print_pat pat print_exp e let print_eqs ff eqs = print_list_nlr print_eq """;""" ff eqs let print_var_dec ff vd = match vd.v_ty with | TUnit -> fprintf ff "@[%a : .@]" print_ident vd.v_ident | TBit -> fprintf ff "@[%a@]" print_ident vd.v_ident | TBitArray se -> fprintf ff "@[%a : [%a]@]" print_ident vd.v_ident print_static_exp se | TProd _ -> assert false | TVar _ -> fprintf ff "%a : " print_ident vd.v_ident let print_var_decs ff vds = print_list_r print_var_dec "("","")" ff vds let rec print_block ff b = match b with | BEqs (eqs, []) -> print_eqs ff eqs | BEqs (eqs, vds) -> fprintf ff "@[var %a@] in@,%a" print_var_decs vds print_eqs eqs | BIf(se, thenb, elseb) -> fprintf ff "@[if %a then@,%a@]@,@[else@,%a@]" print_static_exp se print_block thenb print_block elseb let print_param ff p = print_name ff p.p_name let print_params ff params = match params with | [] -> () | _ -> print_list_r print_param "<<"","">>" ff params let print_constraints ff cl = if !Cli_options.print_types then fprintf ff " with %a" (print_list_r print_static_exp "" " and " "") cl let print_node ff n = fprintf ff "@[@[%a%a%a = %a@] where@ %a@.end where%a;@]@\n@." print_name n.n_name print_params n.n_params print_var_decs n.n_inputs print_var_decs n.n_outputs print_block n.n_body print_constraints n.n_constraints let print_const_dec ff cd = fprintf ff "const %a = %a@\n@." print_name cd.c_name print_static_exp cd.c_value let print_program oc p = let ff = formatter_of_out_channel oc in List.iter (print_const_dec ff) p.p_consts; List.iter (print_node ff) p.p_nodes