summaryrefslogtreecommitdiff
path: root/minijazz/src/main
diff options
context:
space:
mode:
Diffstat (limited to 'minijazz/src/main')
-rw-r--r--minijazz/src/main/cli_options.ml18
-rw-r--r--minijazz/src/main/mj2net.ml94
-rw-r--r--minijazz/src/main/mj_compiler.ml80
-rw-r--r--minijazz/src/main/mjc.ml20
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 ()
+
+