blob: 56649975a242eff225cec9f104a851d37fc83ec4 [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 Ukai103a7962015-04-08 15:53:53 +09008const BootstrapMakefile = "*bootstrap*"
9
Fumitoshi Ukai119dc912015-03-30 16:52:41 +090010type AST interface {
Fumitoshi Ukaie34c1792015-03-30 17:53:47 +090011 eval(*Evaluator)
Fumitoshi Ukai119dc912015-03-30 16:52:41 +090012 show()
13}
14
15type ASTBase struct {
Shinichiro Hamaji685fecf2015-03-30 18:28:12 +090016 filename string
17 lineno int
Fumitoshi Ukai119dc912015-03-30 16:52:41 +090018}
19
20type AssignAST struct {
21 ASTBase
Fumitoshi Ukaie1b813c2015-03-30 18:38:21 +090022 lhs string
23 rhs string
24 op string
Fumitoshi Ukai119dc912015-03-30 16:52:41 +090025}
26
Fumitoshi Ukaie34c1792015-03-30 17:53:47 +090027func (ast *AssignAST) eval(ev *Evaluator) {
28 ev.evalAssign(ast)
Fumitoshi Ukai119dc912015-03-30 16:52:41 +090029}
30
Fumitoshi Ukai8edcb792015-04-02 11:23:23 +090031func (ast *AssignAST) evalRHS(ev *Evaluator, lhs string) Var {
Fumitoshi Ukai103a7962015-04-08 15:53:53 +090032 origin := "file"
33 if ast.filename == BootstrapMakefile {
34 origin = "default"
35 }
Fumitoshi Ukaie1b813c2015-03-30 18:38:21 +090036 switch ast.op {
37 case ":=":
Fumitoshi Ukai103a7962015-04-08 15:53:53 +090038 return SimpleVar{value: ev.evalExpr(ast.rhs), origin: origin}
Fumitoshi Ukaie1b813c2015-03-30 18:38:21 +090039 case "=":
Fumitoshi Ukai103a7962015-04-08 15:53:53 +090040 return RecursiveVar{expr: ast.rhs, origin: origin}
Shinichiro Hamaji69b7f652015-03-31 01:01:59 +090041 case "+=":
Fumitoshi Ukai8edcb792015-04-02 11:23:23 +090042 prev := ev.LookupVar(lhs)
Fumitoshi Ukaic1847602015-04-02 16:18:02 +090043 if !prev.IsDefined() {
Fumitoshi Ukai103a7962015-04-08 15:53:53 +090044 return RecursiveVar{expr: ast.rhs, origin: origin}
Fumitoshi Ukai8edcb792015-04-02 11:23:23 +090045 }
Fumitoshi Ukaic1847602015-04-02 16:18:02 +090046 return prev.Append(ev, ast.rhs)
Shinichiro Hamaji69b7f652015-03-31 01:01:59 +090047 case "?=":
Fumitoshi Ukai8edcb792015-04-02 11:23:23 +090048 prev := ev.LookupVar(lhs)
49 if prev.IsDefined() {
Shinichiro Hamaji69b7f652015-03-31 01:01:59 +090050 return prev
51 }
Fumitoshi Ukai103a7962015-04-08 15:53:53 +090052 return RecursiveVar{expr: ast.rhs, origin: origin}
Shinichiro Hamaji69b7f652015-03-31 01:01:59 +090053 default:
54 panic(fmt.Sprintf("unknown assign op: %q", ast.op))
Fumitoshi Ukaie1b813c2015-03-30 18:38:21 +090055 }
56}
57
Fumitoshi Ukai119dc912015-03-30 16:52:41 +090058func (ast *AssignAST) show() {
Fumitoshi Ukai8773e5e2015-04-01 11:23:18 +090059 Log("%s=%q", ast.lhs, ast.rhs)
Fumitoshi Ukai119dc912015-03-30 16:52:41 +090060}
61
Shinichiro Hamajide829712015-03-31 18:26:56 +090062// Note we cannot be sure what this is, until all variables in |expr|
63// are expanded.
64type MaybeRuleAST struct {
Fumitoshi Ukai119dc912015-03-30 16:52:41 +090065 ASTBase
Shinichiro Hamaji486e9de2015-04-09 15:20:32 +090066 expr string
67 semicolonIndex int
Fumitoshi Ukai119dc912015-03-30 16:52:41 +090068}
69
Shinichiro Hamajide829712015-03-31 18:26:56 +090070func (ast *MaybeRuleAST) eval(ev *Evaluator) {
71 ev.evalMaybeRule(ast)
Fumitoshi Ukai119dc912015-03-30 16:52:41 +090072}
73
Shinichiro Hamajide829712015-03-31 18:26:56 +090074func (ast *MaybeRuleAST) show() {
75 Log("%s", ast.expr)
Fumitoshi Ukai119dc912015-03-30 16:52:41 +090076}
Shinichiro Hamaji685fecf2015-03-30 18:28:12 +090077
Shinichiro Hamaji0b93c862015-04-07 06:15:15 +090078type CommandAST struct {
79 ASTBase
Fumitoshi Ukai103a7962015-04-08 15:53:53 +090080 cmd string
Shinichiro Hamaji0b93c862015-04-07 06:15:15 +090081}
82
83func (ast *CommandAST) eval(ev *Evaluator) {
84 ev.evalCommand(ast)
85}
86
87func (ast *CommandAST) show() {
88 Log("\t%s", strings.Replace(ast.cmd, "\n", `\n`, -1))
89}
90
Shinichiro Hamajid7bef602015-03-30 19:55:32 +090091type IncludeAST struct {
92 ASTBase
93 expr string
94 op string
95}
96
97func (ast *IncludeAST) eval(ev *Evaluator) {
98 ev.evalInclude(ast)
99}
100
101func (ast *IncludeAST) show() {
102 Log("include %s", ast.expr)
103}
Shinichiro Hamaji497754d2015-03-31 02:02:11 +0900104
105type IfAST struct {
106 ASTBase
Shinichiro Hamajiae32b782015-03-31 14:41:19 +0900107 op string
108 lhs string
109 rhs string // Empty if |op| is ifdef or ifndef.
110 trueStmts []AST
Shinichiro Hamaji497754d2015-03-31 02:02:11 +0900111 falseStmts []AST
112}
113
114func (ast *IfAST) eval(ev *Evaluator) {
115 ev.evalIf(ast)
116}
117
118func (ast *IfAST) show() {
119 // TODO
120 Log("if")
121}