X-Git-Url: http://git.annexia.org/?a=blobdiff_plain;f=src%2Fmain.ml;h=33d91b6e6c7a048c823fd1dae38921314ef2b0f7;hb=24cc20b33e3d81ed7d754391bef929276c1f4f42;hp=2685160dedbde5ef27ca8206f61658a647c1a76b;hpb=4d0527cd7ced1d96720e3af56da29a19551944f7;p=goals.git diff --git a/src/main.ml b/src/main.ml index 2685160..33d91b6 100644 --- a/src/main.ml +++ b/src/main.ml @@ -22,7 +22,8 @@ open Printf open Utils (* See also "let id" in [lexer.mll]. *) -let var_regexp = Str.regexp "\\([a-zA-Z_][a-zA-Z0-9_]*\\)=\\(.*\\)" +let var_regexp = + Str.regexp "\\([a-zA-Z_][a-zA-Z0-9_]*\\)[ \t]*=[ \t]*\\(.*\\)" let usage = "\ @@ -36,75 +37,67 @@ Options:" let main () = (* Command line arguments. *) + let args = ref [] in + let directory = ref "." in let filename = ref "Goalfile" in let argspec = [ - "-f", Arg.Set_string filename, - "filename Set name of Goalfile"; - "--file", Arg.Set_string filename, - "filename Set name of Goalfile"; + "-C", Arg.Set_string directory, + "directory Change to directory before running"; + "--directory", Arg.Set_string directory, + "directory Change to directory before running"; + "-f", Arg.Set_string filename, + "filename Set name of Goalfile"; + "--file", Arg.Set_string filename, + "filename Set name of Goalfile"; ] in let argspec = Arg.align argspec in - let args = ref [] in let anon_fun s = args := s :: !args in Arg.parse argspec anon_fun usage; - (*let args = List.rev !args in*) + let args = List.rev !args in + let directory = !directory in let filename = !filename in (* Parse the input file. *) - let file = Parse.parse_goalfile filename in + let env = Parse.parse_goalfile filename in + + (* Now we've read the input, change directory. *) + Sys.chdir directory; (* Parse the command line anon args. Each parameter has the * form "name=" to assign a value to a variable, or * "" to indicate a target to build. *) - let assignments = ref [] in let targets = ref [] in + let env = ref env in List.iter ( fun arg -> - if Str.string_match var_regexp arg 0 then ( (* assignment *) + if Str.string_match var_regexp arg 0 then ( + (* assignment *) let name = Str.matched_group 1 arg in let expr = Parse.parse_cli_expr (Str.matched_group 2 arg) in - assignments := Ast.Let (name, expr) :: !assignments + env := Ast.Env.add name expr !env ) - else ( (* target *) + else ( + (* target *) let expr = Parse.parse_cli_expr arg in targets := expr :: !targets ) - ) !args; + ) args; + let targets = List.rev !targets and env = !env in - (* If no target was set on the command line, find - * the first goal in the file. - *) - if !targets = [] then ( - try - let first_goal = - List.find (function Ast.Goal _ -> true | _ -> false) file in - match first_goal with - | Ast.Goal (name, [], _, _, _) -> - targets := [Ast.ECall (name, [])] - | Ast.Goal (name, _, _, _, _) -> - failwithf "%s: first target ‘%s’ has parameters and so cannot be used as the default target" - filename name - | _ -> assert false - with - (* Actually this is fine. If there are no goals we'll do nothing. *) - Not_found -> () - ); - - let targets = List.rev !targets in - - (* Assignments are simply treated as statements added to the end of - * the file (so they override earlier assignments to the same variable, - * if any). - *) - let file = file @ List.rev !assignments in + (* If no target was set on the command line, use "all ()". *) + let targets = + if targets <> [] then targets + else [Ast.ECall (Ast.noloc, "all", [])] in - (* We start with an empty symbol table. *) - let vars = Hashtbl.create 13 in + Ast.print_env stderr env; (* Evaluate the target expressions in turn. *) - Eval.evaluate file vars targets + Eval.evaluate_targets env targets -let () = main () +let () = + try main () + with + Failure msg -> prerr_endline msg; exit 1