Add environment to store variables and goals.
[goals.git] / src / main.ml
1 (* Goalfile parser
2  * Copyright (C) 2019 Richard W.M. Jones
3  * Copyright (C) 2019 Red Hat Inc.
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License along
16  * with this program; if not, write to the Free Software Foundation, Inc.,
17  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18  *)
19
20 open Printf
21
22 open Utils
23
24 (* See also "let id" in [lexer.mll]. *)
25 let var_regexp =
26   Str.regexp "\\([a-zA-Z_][a-zA-Z0-9_]*\\)[ \t]*=[ \t]*\\(.*\\)"
27
28 let usage =
29   "\
30 goals: Build software.
31
32  goals [-f Goalfile] ['var=value' ...] ['target' ...]
33
34 For detailed help see goals(1).
35
36 Options:"
37
38 let main () =
39   (* Command line arguments. *)
40   let filename = ref "Goalfile" in
41
42   let argspec = [
43     "-f",        Arg.Set_string filename,
44                  "filename Set name of Goalfile";
45     "--file",    Arg.Set_string filename,
46                  "filename Set name of Goalfile";
47   ] in
48   let argspec = Arg.align argspec in
49   let args = ref [] in
50   let anon_fun s = args := s :: !args in
51   Arg.parse argspec anon_fun usage;
52
53   (*let args = List.rev !args in*)
54   let filename = !filename in
55
56   (* Parse the input file. *)
57   let env = Parse.parse_goalfile filename in
58
59   (* Parse the command line anon args.  Each parameter has the
60    * form "name=<expr>" to assign a value to a variable, or
61    * "<expr>" to indicate a target to build.
62    *)
63   let targets = ref [] in
64   let env = ref env in
65   List.iter (
66     fun arg ->
67       if Str.string_match var_regexp arg 0 then (
68         (* assignment *)
69         let name = Str.matched_group 1 arg in
70         let expr = Parse.parse_cli_expr (Str.matched_group 2 arg) in
71         env := Ast.StringMap.add name expr !env
72       )
73       else (
74         (* target *)
75         let expr = Parse.parse_cli_expr arg in
76         targets := expr :: !targets
77       )
78   ) !args;
79   let targets = List.rev !targets and env = !env in
80
81   (* If no target was set on the command line, use "all ()". *)
82   let targets =
83     if targets <> [] then targets
84     else [Ast.ECall ("all", [])] in
85
86   (*Ast.print_env stdout env;*)
87
88   (* Evaluate the target expressions in turn. *)
89   Eval.evaluate env targets
90
91 let () = main ()