blob: 9cc566e7862948a0614980b4b155b9862e49cb8d [file] [log] [blame]
Fumitoshi Ukai119dc912015-03-30 16:52:41 +09001package main
2
Shinichiro Hamaji52e83aa2015-04-06 17:20:28 +09003import (
4 "fmt"
5 "strings"
6)
Fumitoshi Ukaie1b813c2015-03-30 18:38:21 +09007
Fumitoshi Ukai119dc912015-03-30 16:52:41 +09008type AST interface {
Fumitoshi Ukaie34c1792015-03-30 17:53:47 +09009 eval(*Evaluator)
Fumitoshi Ukai119dc912015-03-30 16:52:41 +090010 show()
11}
12
13type ASTBase struct {
Shinichiro Hamaji685fecf2015-03-30 18:28:12 +090014 filename string
15 lineno int
Fumitoshi Ukai119dc912015-03-30 16:52:41 +090016}
17
18type AssignAST struct {
19 ASTBase
Fumitoshi Ukaie1b813c2015-03-30 18:38:21 +090020 lhs string
21 rhs string
22 op string
Fumitoshi Ukai119dc912015-03-30 16:52:41 +090023}
24
Fumitoshi Ukaie34c1792015-03-30 17:53:47 +090025func (ast *AssignAST) eval(ev *Evaluator) {
26 ev.evalAssign(ast)
Fumitoshi Ukai119dc912015-03-30 16:52:41 +090027}
28
Fumitoshi Ukai8edcb792015-04-02 11:23:23 +090029func (ast *AssignAST) evalRHS(ev *Evaluator, lhs string) Var {
Fumitoshi Ukaie1b813c2015-03-30 18:38:21 +090030 switch ast.op {
31 case ":=":
Shinichiro Hamaji7ff34db2015-04-04 18:55:20 +090032 return SimpleVar{value: ev.evalExpr(ast.rhs), origin: "file"}
Fumitoshi Ukaie1b813c2015-03-30 18:38:21 +090033 case "=":
Shinichiro Hamaji7ff34db2015-04-04 18:55:20 +090034 return RecursiveVar{expr: ast.rhs, origin: "file"}
Shinichiro Hamaji69b7f652015-03-31 01:01:59 +090035 case "+=":
Fumitoshi Ukai8edcb792015-04-02 11:23:23 +090036 prev := ev.LookupVar(lhs)
Fumitoshi Ukaic1847602015-04-02 16:18:02 +090037 if !prev.IsDefined() {
Shinichiro Hamaji7ff34db2015-04-04 18:55:20 +090038 return RecursiveVar{expr: ast.rhs, origin: "file"}
Fumitoshi Ukai8edcb792015-04-02 11:23:23 +090039 }
Fumitoshi Ukaic1847602015-04-02 16:18:02 +090040 return prev.Append(ev, ast.rhs)
Shinichiro Hamaji69b7f652015-03-31 01:01:59 +090041 case "?=":
Fumitoshi Ukai8edcb792015-04-02 11:23:23 +090042 prev := ev.LookupVar(lhs)
43 if prev.IsDefined() {
Shinichiro Hamaji69b7f652015-03-31 01:01:59 +090044 return prev
45 }
Shinichiro Hamaji7ff34db2015-04-04 18:55:20 +090046 return RecursiveVar{expr: ast.rhs, origin: "file"}
Shinichiro Hamaji69b7f652015-03-31 01:01:59 +090047 default:
48 panic(fmt.Sprintf("unknown assign op: %q", ast.op))
Fumitoshi Ukaie1b813c2015-03-30 18:38:21 +090049 }
50}
51
Fumitoshi Ukai119dc912015-03-30 16:52:41 +090052func (ast *AssignAST) show() {
Fumitoshi Ukai8773e5e2015-04-01 11:23:18 +090053 Log("%s=%q", ast.lhs, ast.rhs)
Fumitoshi Ukai119dc912015-03-30 16:52:41 +090054}
55
Shinichiro Hamajide829712015-03-31 18:26:56 +090056// Note we cannot be sure what this is, until all variables in |expr|
57// are expanded.
58type MaybeRuleAST struct {
Fumitoshi Ukai119dc912015-03-30 16:52:41 +090059 ASTBase
Shinichiro Hamajide829712015-03-31 18:26:56 +090060 expr string
Shinichiro Hamajiae32b782015-03-31 14:41:19 +090061 cmds []string
Shinichiro Hamaji7c4e3252015-03-30 23:04:25 +090062 cmdLineno int
Fumitoshi Ukai119dc912015-03-30 16:52:41 +090063}
64
Shinichiro Hamajide829712015-03-31 18:26:56 +090065func (ast *MaybeRuleAST) eval(ev *Evaluator) {
66 ev.evalMaybeRule(ast)
Fumitoshi Ukai119dc912015-03-30 16:52:41 +090067}
68
Shinichiro Hamajide829712015-03-31 18:26:56 +090069func (ast *MaybeRuleAST) show() {
70 Log("%s", ast.expr)
Fumitoshi Ukai119dc912015-03-30 16:52:41 +090071 for _, cmd := range ast.cmds {
Shinichiro Hamaji52e83aa2015-04-06 17:20:28 +090072 Log("\t%s", strings.Replace(cmd, "\n", `\n`, -1))
Fumitoshi Ukai119dc912015-03-30 16:52:41 +090073 }
74}
Shinichiro Hamaji685fecf2015-03-30 18:28:12 +090075
Shinichiro Hamajid7bef602015-03-30 19:55:32 +090076type IncludeAST struct {
77 ASTBase
78 expr string
79 op string
80}
81
82func (ast *IncludeAST) eval(ev *Evaluator) {
83 ev.evalInclude(ast)
84}
85
86func (ast *IncludeAST) show() {
87 Log("include %s", ast.expr)
88}
Shinichiro Hamaji497754d2015-03-31 02:02:11 +090089
90type IfAST struct {
91 ASTBase
Shinichiro Hamajiae32b782015-03-31 14:41:19 +090092 op string
93 lhs string
94 rhs string // Empty if |op| is ifdef or ifndef.
95 trueStmts []AST
Shinichiro Hamaji497754d2015-03-31 02:02:11 +090096 falseStmts []AST
97}
98
99func (ast *IfAST) eval(ev *Evaluator) {
100 ev.evalIf(ast)
101}
102
103func (ast *IfAST) show() {
104 // TODO
105 Log("if")
106}