X-Git-Url: http://git.annexia.org/?a=blobdiff_plain;f=src%2Fmain.ml;h=bb2540275fbf0df0a1ece9a2ed0fa626e75fb598;hb=edf3fa931cfaff399ed05a3d223eecb2286e1353;hp=be1baff0728299e64f0c832a0b95114485300946;hpb=8e1d9182f7573112cb36c7d0ff0c8612f34ffd57;p=goals.git diff --git a/src/main.ml b/src/main.ml index be1baff..bb25402 100644 --- a/src/main.ml +++ b/src/main.ml @@ -21,11 +21,15 @@ open Printf open Utils +(* See also "let id" in [lexer.mll]. *) +let var_regexp = + Str.regexp "\\([a-zA-Z_][a-zA-Z0-9_]*\\)[ \t]*=[ \t]*\\(.*\\)" + let usage = "\ goals: Build software. - goals [-f Goalfile] ['var = value' ...] ['target' ...] + goals [-f Goalfile] ['var=value' ...] ['target' ...] For detailed help see goals(1). @@ -33,47 +37,64 @@ 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 - - Ast.print_file stdout file; + let env = Parse.parse_goalfile filename in - (* Find the target(s) to execute first. *) - let initial_targets = ref [] in - (* XXX Parse command line anon args here. XXX *) + (* Now we've read the input, change directory. *) + Sys.chdir directory; - (* If no initial target set on the command line, find - * the first goal in the file. + (* 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 targets = ref [] in + let env = ref env in List.iter ( - function - | Ast.Goal (name, [], _, _, _) -> - if !initial_targets = [] then - initial_targets := Ast.ECall (name, []) :: !initial_targets - | Ast.Goal (name, _, _, _, _) -> - if !initial_targets = [] then - failwithf "%s: first target ‘%s’ has parameters and so cannot be used as the default target" - filename name - | _ -> () - ) file; - - let initial_targets = List.rev !initial_targets in - ignore initial_targets + fun arg -> + 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 + env := Ast.StringMap.add name expr !env + ) + else ( + (* target *) + let expr = Parse.parse_cli_expr arg in + targets := expr :: !targets + ) + ) args; + let targets = List.rev !targets and env = !env in + + (* If no target was set on the command line, use "all ()". *) + let targets = + if targets <> [] then targets + else [Ast.ECall ("all", [])] in + + (*Ast.print_env stdout env;*) + + (* Evaluate the target expressions in turn. *) + Eval.evaluate env targets let () = main ()