Przeglądaj źródła

Moved command-line arguments to parameterized type

Taddeus Kroes 12 lat temu
rodzic
commit
cebd145125
8 zmienionych plików z 71 dodań i 59 usunięć
  1. 1 1
      Makefile
  2. 1 3
      README.md
  3. 13 7
      ast.ml
  4. 25 18
      main.ml
  5. 6 6
      phases/context_analysis.ml
  6. 6 6
      phases/desug.ml
  7. 10 9
      phases/parse.ml
  8. 9 9
      phases/print.ml

+ 1 - 1
Makefile

@@ -2,7 +2,7 @@ RESULT := civicc
 SOURCES := ast.ml util.mli util.ml lexer.mll parser.mly stringify.mli \
 	stringify.ml \
 	phases/parse.ml phases/print.ml phases/desug.ml \
-	phases/context_analysis.ml phases/test.ml \
+	phases/context_analysis.ml \
 	main.ml
 PRE_TARGETS := ast.cmi util.cmi
 LIBS := str

+ 1 - 3
README.md

@@ -7,6 +7,4 @@ CiviCaml is a compiler for the CiviC language, written in OCaml.
 Issues & TODO
 -------------
 
-- Run C preprocessor in parse phase
-- Create arguments record to pass to phases, instead of separate variables
-  (e.g. verbose -> args.verbose).
+- Load file content and run C preprocessor in load phase

+ 13 - 7
ast.ml

@@ -45,19 +45,25 @@ and node =
     | TypeCast of ctype * node * loc
     | FunCall of string * node list * loc
 
+(* container for command-line arguments *)
+type args = {
+    mutable filename : string option;
+    mutable verbose : int
+}
+
 (* intermediate representations between phases *)
-type repr =
-    | Inputfile of string option * int  (* filename, verbose *)
-    | Node of node * int                (* ast, verbose *)
-    | Assembly of string list * int     (* instructions *)
+type intermediate =
+    | Args of args
+    | FileContent of string * args
+    | Ast of node * args
+    | Assembly of string list * args
 
+(* exceptions *)
 exception LocError of loc * string
-
 exception NodeError of node * string
-
 exception CompileError of string
-
 exception InvalidNode
+exception InvalidInput of string
 
 
 (*

+ 25 - 18
main.ml

@@ -2,14 +2,14 @@ open Lexing
 open Printf
 open Ast
 
-(* Compile infile to assembly code
+(* Compile CVC file to assembly code
  * in_channel -> int -> repr *)
-let compile infile verbose =
-    let rec run_phases ir = function
-        | [] -> ir
-        | h::t -> run_phases (h ir) t
+let compile args =
+    let rec run_phases input = function
+        | [] -> input
+        | h::t -> run_phases (h input) t
     in
-    run_phases (Inputfile (infile, verbose)) [
+    run_phases (Args args) [
         Parse.phase;
         Print.phase;
         Desug.phase;
@@ -64,26 +64,33 @@ let print_fancy_error msg loc verbose =
 (* Main function, returns exit status
  * () -> int *)
 let main () =
-    let filename = ref None in
-    let verbose = ref 2 in
-    let args = [
-        ("-v", Arg.Int (fun i -> verbose := i), "Set verbosity")
+    let args = {
+        filename = None;
+        verbose = 2
+    } in
+    let args_spec = [
+        ("-v", Arg.Int (fun i -> args.verbose <- i), "Set verbosity")
     ] in
     let usage = "Usage: " ^ Sys.argv.(0) ^ " [ -v VERBOSITY ] FILE" in
 
     try
-        Arg.parse args (fun s -> filename := Some s) usage;
-        let _ = compile !filename !verbose in
-        0
+        try
+            Arg.parse args_spec (fun s -> args.filename <- Some s) usage;
+            compile args;
+            0
+        with
+        | InvalidNode ->
+            raise (CompileError "invalid node")
+        | InvalidInput name ->
+            raise (CompileError ("invalid input for phase \"" ^ name ^ "\""))
+        | NodeError (node, msg) ->
+            raise (LocError (Util.locof node, msg))
     with
     | CompileError msg ->
-        prerr_endline ("Error: " ^ msg);
-        1
-    | NodeError (node, msg) ->
-        print_fancy_error msg (Util.locof node) !verbose;
+        eprintf "Error: %s\n" msg;
         1
     | LocError (loc, msg) ->
-        print_fancy_error msg loc !verbose;
+        print_fancy_error msg loc args.verbose;
         1
 
 let _ = exit (main ())

+ 6 - 6
phases/context_analysis.ml

@@ -50,9 +50,9 @@ let analyse_context node =
     in
     analyse 0 node
 
-let rec phase repr =
-    let _ = prerr_endline "- Context analysis" in
-    match repr with
-    | Node (node, verbose) ->
-        Node (analyse_context node, verbose)
-    | _ -> raise (CompileError "invalid input for this phase")
+let rec phase input =
+    prerr_endline "- Context analysis";
+    match input with
+    | Ast (node, args) ->
+        Ast (analyse_context node, args)
+    | _ -> raise (InvalidInput "context analysis")

+ 6 - 6
phases/desug.ml

@@ -88,9 +88,9 @@ let rec array_init = function
     | node -> transform array_init node
 *)
 
-let rec phase repr =
-    let _ = print_endline "- Desugaring" in
-    match repr with
-    | Node (node, verbose) ->
-        Node (var_init node, verbose)
-    | _ -> raise (CompileError "invalid input for this phase")
+let rec phase input =
+    print_endline "- Desugaring";
+    match input with
+    | Ast (node, args) ->
+        Ast (var_init node, args)
+    | _ -> raise (InvalidInput "desugar")

+ 10 - 9
phases/parse.ml

@@ -12,24 +12,25 @@ let parse_with_error lexbuf =
     | Parser.Error ->
         raise (LocError (get_loc lexbuf, "syntax error"))
 
-let phase repr =
-    let _ = print_endline "- Parse input" in
-    match repr with
-    | Inputfile (filename, verbose) ->
-        (* TODO: run preprocessor *)
-        let infile = match filename with
+let phase input =
+    print_endline "- Parse input";
+    match input with
+    | Args args ->
+        let infile = match args.filename with
             | Some value -> open_in value
             | None -> stdin
         in
-        let display_name = match filename with
+        let display_name = match args.filename with
             | Some value -> value
             | None -> "stdin"
         in
+
         let lexbuf = Lexing.from_channel infile in
         lexbuf.lex_curr_p <- { lexbuf.lex_curr_p with pos_fname = display_name };
         let ast = parse_with_error lexbuf in
         close_in infile;
+
         (match ast with
             | None -> raise (CompileError "error during parsing")
-            | Some ast -> Node (ast, verbose))
-    | _ -> raise (CompileError "invalid input for this phase")
+            | Some ast -> Ast (ast, args))
+    | _ -> raise (InvalidInput "parse")

+ 9 - 9
phases/print.ml

@@ -1,12 +1,12 @@
 open Ast
 open Stringify
 
-let phase repr =
-    (* TODO: check verbosity *)
-    match repr with
-    | Node (node, verbose) ->
-        prerr_endline "-------------------------------------------------------";
-        prerr_endline (node2str node);
-        prerr_endline "-------------------------------------------------------";
-        repr
-    | _ -> raise (CompileError "invalid input for this phase")
+let phase = function
+    | Ast (node, args) as input ->
+        if args.verbose >= 2 then (
+            prerr_endline "--------------------------------------------------";
+            prerr_endline (node2str node);
+            prerr_endline "--------------------------------------------------"
+        );
+        input
+    | _ -> raise (InvalidInput "print")