diff options
Diffstat (limited to 'minijazz/src/main')
-rw-r--r-- | minijazz/src/main/cli_options.ml | 18 | ||||
-rw-r--r-- | minijazz/src/main/mj2net.ml | 94 | ||||
-rw-r--r-- | minijazz/src/main/mj_compiler.ml | 80 | ||||
-rw-r--r-- | minijazz/src/main/mjc.ml | 20 |
4 files changed, 212 insertions, 0 deletions
diff --git a/minijazz/src/main/cli_options.ml b/minijazz/src/main/cli_options.ml new file mode 100644 index 0000000..c5820a8 --- /dev/null +++ b/minijazz/src/main/cli_options.ml @@ -0,0 +1,18 @@ +(* version of the compiler *) +let version = "0.2.1" + +let verbose = ref false +let print_types = ref false +let no_inline_all = ref false +let main_node = ref "main" + +let base_path = ref "" + +let show_version () = + Format.printf "The MiniJazz compiler, version %s @." version +let errmsg = "Options are:" + +let doc_verbose = "\t\t\tSet verbose mode" +and doc_version = "\t\tThe version of the compiler" +and doc_full_type_info = "\t\tPrint full type information" +and doc_main_node = "\t\t\tSet the main node" diff --git a/minijazz/src/main/mj2net.ml b/minijazz/src/main/mj2net.ml new file mode 100644 index 0000000..9977a2d --- /dev/null +++ b/minijazz/src/main/mj2net.ml @@ -0,0 +1,94 @@ +open Ast +open Static +open Static_utils +open Ident + +let expect_int se = + let se = simplify NameEnv.empty se in + match se.se_desc with + | SInt v -> v + | _ -> + Format.eprintf "Unexpected static exp: %a@." Printer.print_static_exp se; + assert false + +let expect_ident e = match e.e_desc with + | Evar id -> string_of_ident id + | _ -> assert false + +let tr_value v = match v with + | VBit b -> Netlist_ast.VBit b + | VBitArray a -> Netlist_ast.VBitArray a + +let tr_ty ty = match ty with + | TBit -> Netlist_ast.TBit + | TBitArray se -> Netlist_ast.TBitArray (expect_int se) + | _ -> Format.eprintf "Unexpected type: %a@." Printer.print_type ty; assert false + +let tr_var_dec { v_ident = n; v_ty = ty } = + string_of_ident n, tr_ty ty + +let tr_pat pat = match pat with + | Evarpat id -> string_of_ident id + | Etuplepat ids -> + Format.eprintf "Unexpected pattern: %a@." Printer.print_pat pat; + assert false + +let expect_arg e = match e.e_desc with + | Evar id -> Netlist_ast.Avar (string_of_ident id) + | Econst v -> Netlist_ast.Aconst (tr_value v) + | _ -> Format.eprintf "Unexpected arg : %a@." Printer.print_exp e; assert false + +let rec tr_exp e = match e.e_desc with + | Evar id -> Netlist_ast.Earg (Netlist_ast.Avar (string_of_ident id)) + | Econst v -> Netlist_ast.Earg (Netlist_ast.Aconst (tr_value v)) + | Ereg e -> Netlist_ast.Ereg (expect_ident e) + | Ecall ("not", _, [e]) -> Netlist_ast.Enot (expect_arg e) + | Ecall (("or" | "xor" | "and" | "nand") as op, _, [e1; e2]) -> + let op = + match op with + | "or" -> Netlist_ast.Or + | "xor" -> Netlist_ast.Xor + | "and" -> Netlist_ast.And + | "nand" -> Netlist_ast.Nand + | _ -> assert false + in + Netlist_ast.Ebinop (op, expect_arg e1, expect_arg e2) + | Ecall ("mux", _, [e1; e2; e3]) -> + Netlist_ast.Emux (expect_arg e1, expect_arg e2, expect_arg e3) + | Ecall("select", idx::_, [e]) -> + Netlist_ast.Eselect (expect_int idx, expect_arg e) + | Ecall("slice", min::max::_, [e]) -> + Netlist_ast.Eslice (expect_int min, expect_int max, expect_arg e) + | Ecall("concat", _, [e1; e2]) -> + Netlist_ast.Econcat (expect_arg e1, expect_arg e2) + | Emem(MRom, addr_size, word_size, _, [e]) -> + Netlist_ast.Erom (expect_int addr_size, expect_int word_size, expect_arg e) + | Emem(MRam, addr_size, word_size, _, [ra; we; wa; data]) -> + Netlist_ast.Eram (expect_int addr_size, expect_int word_size, + expect_arg ra, expect_arg we, expect_arg wa, expect_arg data) + | _ -> assert false + +let tr_eq (pat, e) = + tr_pat pat, tr_exp e + +let tr_vds env vds = + List.fold_left + (fun env vd -> Netlist_ast.Env.add (string_of_ident vd.v_ident) (tr_ty vd.v_ty) env) + env vds + +let tr_block b = match b with + | BEqs (eqs, vds) -> + let env = tr_vds Netlist_ast.Env.empty vds in + let eqs = List.map tr_eq eqs in + env, eqs + | _ -> assert false + +let program p = + let n = match p.p_nodes with [n] -> n | _ -> assert false in + let vars, eqs = tr_block n.n_body in + let vars = tr_vds vars n.n_inputs in + let vars = tr_vds vars n.n_outputs in + let inputs = List.map (fun vd -> string_of_ident vd.v_ident) n.n_inputs in + let outputs = List.map (fun vd -> string_of_ident vd.v_ident) n.n_outputs in + { Netlist_ast.p_inputs = inputs; Netlist_ast.p_outputs = outputs; + Netlist_ast.p_vars = vars; Netlist_ast.p_eqs = eqs } diff --git a/minijazz/src/main/mj_compiler.ml b/minijazz/src/main/mj_compiler.ml new file mode 100644 index 0000000..c629e1c --- /dev/null +++ b/minijazz/src/main/mj_compiler.ml @@ -0,0 +1,80 @@ +open Errors +open Cli_options +open Location + +let separateur = "\n*********************************************\ + *********************************\n*** " + +let comment ?(sep=separateur) s = + if !verbose then Format.printf "%s%s@." sep s + +let do_pass d f p pp = + comment (d^" ...\n"); + let r = f p in + if !verbose then pp r; + comment ~sep:"*** " (d^" done."); + r + +let do_silent_pass d f p = do_pass d f p (fun _ -> ()) + +let pass d enabled f p pp = + if enabled + then do_pass d f p pp + else p + +let silent_pass d enabled f p = + if enabled + then do_silent_pass d f p + else p + +let parse lexbuf = + try + Parser.program Lexer.token lexbuf + with + | Lexer.Lexical_error(err, l) -> + lexical_error err l + | Parser.Error -> + let pos1 = Lexing.lexeme_start_p lexbuf + and pos2 = Lexing.lexeme_end_p lexbuf in + let l = Loc(pos1,pos2) in + syntax_error l + +let lexbuf_from_file file_name = + let ic = open_in file_name in + let lexbuf = Lexing.from_channel ic in + lexbuf.Lexing.lex_curr_p <- + { lexbuf.Lexing.lex_curr_p with Lexing.pos_fname = file_name }; + ic, lexbuf + +let compile_impl filename = + (* input and output files *) + let ic, lexbuf = lexbuf_from_file filename in + let net_name = (Filename.chop_suffix filename ".mj") ^ ".net" in + let net = open_out net_name in + let close_all_files () = + close_in ic; + close_out net + in + try + base_path := Filename.dirname filename; + + let pp = Printer.print_program stdout in + (* Parsing of the file *) + let p = do_pass "Parsing" parse lexbuf pp in + + let p = pass "Scoping" true Scoping.program p pp in + + let p = pass "Typing" true Typing.program p pp in + + let p = pass "Normalize" true Normalize.program p pp in + + let p = pass "Callgraph" true Callgraph.program p pp in + + let p = pass "Simplify" true Simplify.program p pp in + + let p = Mj2net.program p in + Netlist_printer.print_program net p; + + close_all_files () + with + | x -> close_all_files (); raise x diff --git a/minijazz/src/main/mjc.ml b/minijazz/src/main/mjc.ml new file mode 100644 index 0000000..ada6b34 --- /dev/null +++ b/minijazz/src/main/mjc.ml @@ -0,0 +1,20 @@ +open Cli_options +open Mj_compiler + +let main () = + try + Arg.parse + [ + "-v",Arg.Set verbose, doc_verbose; + "-version", Arg.Unit show_version, doc_version; + "-m", Arg.Set_string main_node, doc_main_node; + "-print-types", Arg.Set print_types, doc_full_type_info; + ] + compile_impl + errmsg; + with + | Errors.Error -> exit 2;; + +main () + + |