Fumitoshi Ukai | 119dc91 | 2015-03-30 16:52:41 +0900 | [diff] [blame] | 1 | package main |
| 2 | |
Shinichiro Hamaji | 52e83aa | 2015-04-06 17:20:28 +0900 | [diff] [blame] | 3 | import ( |
Fumitoshi Ukai | b06cd9d | 2015-05-07 12:56:12 +0900 | [diff] [blame] | 4 | "bytes" |
Shinichiro Hamaji | 52e83aa | 2015-04-06 17:20:28 +0900 | [diff] [blame] | 5 | "fmt" |
| 6 | "strings" |
| 7 | ) |
Fumitoshi Ukai | e1b813c | 2015-03-30 18:38:21 +0900 | [diff] [blame] | 8 | |
Fumitoshi Ukai | 103a796 | 2015-04-08 15:53:53 +0900 | [diff] [blame] | 9 | const BootstrapMakefile = "*bootstrap*" |
| 10 | |
Fumitoshi Ukai | 119dc91 | 2015-03-30 16:52:41 +0900 | [diff] [blame] | 11 | type AST interface { |
Fumitoshi Ukai | e34c179 | 2015-03-30 17:53:47 +0900 | [diff] [blame] | 12 | eval(*Evaluator) |
Fumitoshi Ukai | 119dc91 | 2015-03-30 16:52:41 +0900 | [diff] [blame] | 13 | show() |
| 14 | } |
| 15 | |
| 16 | type ASTBase struct { |
Shinichiro Hamaji | 685fecf | 2015-03-30 18:28:12 +0900 | [diff] [blame] | 17 | filename string |
| 18 | lineno int |
Fumitoshi Ukai | 119dc91 | 2015-03-30 16:52:41 +0900 | [diff] [blame] | 19 | } |
| 20 | |
| 21 | type AssignAST struct { |
| 22 | ASTBase |
Fumitoshi Ukai | b36f387 | 2015-04-10 15:06:38 +0900 | [diff] [blame] | 23 | // TODO(ukai): use Value. |
Fumitoshi Ukai | e1b813c | 2015-03-30 18:38:21 +0900 | [diff] [blame] | 24 | lhs string |
| 25 | rhs string |
| 26 | op string |
Fumitoshi Ukai | b2c300f | 2015-04-23 00:59:26 +0900 | [diff] [blame] | 27 | opt string // "override", "export" |
Fumitoshi Ukai | 119dc91 | 2015-03-30 16:52:41 +0900 | [diff] [blame] | 28 | } |
| 29 | |
Fumitoshi Ukai | e34c179 | 2015-03-30 17:53:47 +0900 | [diff] [blame] | 30 | func (ast *AssignAST) eval(ev *Evaluator) { |
| 31 | ev.evalAssign(ast) |
Fumitoshi Ukai | 119dc91 | 2015-03-30 16:52:41 +0900 | [diff] [blame] | 32 | } |
| 33 | |
Fumitoshi Ukai | 8edcb79 | 2015-04-02 11:23:23 +0900 | [diff] [blame] | 34 | func (ast *AssignAST) evalRHS(ev *Evaluator, lhs string) Var { |
Fumitoshi Ukai | 103a796 | 2015-04-08 15:53:53 +0900 | [diff] [blame] | 35 | origin := "file" |
| 36 | if ast.filename == BootstrapMakefile { |
| 37 | origin = "default" |
| 38 | } |
Fumitoshi Ukai | b2c300f | 2015-04-23 00:59:26 +0900 | [diff] [blame] | 39 | if ast.opt == "override" { |
| 40 | origin = "override" |
| 41 | } |
| 42 | // TODO(ukai): handle ast.opt == "export" |
Fumitoshi Ukai | e1b813c | 2015-03-30 18:38:21 +0900 | [diff] [blame] | 43 | switch ast.op { |
| 44 | case ":=": |
Fumitoshi Ukai | 00178d1 | 2015-04-18 00:11:05 +0900 | [diff] [blame] | 45 | rexpr, _, err := parseExpr([]byte(ast.rhs), nil) |
| 46 | if err != nil { |
| 47 | panic(fmt.Errorf("parse assign rhs %s:%d %v", ast.filename, ast.lineno, err)) |
| 48 | } |
Fumitoshi Ukai | b06cd9d | 2015-05-07 12:56:12 +0900 | [diff] [blame] | 49 | var buf bytes.Buffer |
| 50 | rexpr.Eval(&buf, ev) |
| 51 | return SimpleVar{value: buf.Bytes(), origin: origin} |
Fumitoshi Ukai | e1b813c | 2015-03-30 18:38:21 +0900 | [diff] [blame] | 52 | case "=": |
Fumitoshi Ukai | b36f387 | 2015-04-10 15:06:38 +0900 | [diff] [blame] | 53 | v, _, err := parseExpr([]byte(ast.rhs), nil) |
| 54 | if err != nil { |
| 55 | panic(err) |
| 56 | } |
| 57 | return RecursiveVar{expr: v, origin: origin} |
Shinichiro Hamaji | 69b7f65 | 2015-03-31 01:01:59 +0900 | [diff] [blame] | 58 | case "+=": |
Shinichiro Hamaji | a485d2f | 2015-04-16 14:03:24 +0900 | [diff] [blame] | 59 | prev := ev.LookupVarInCurrentScope(lhs) |
Fumitoshi Ukai | c184760 | 2015-04-02 16:18:02 +0900 | [diff] [blame] | 60 | if !prev.IsDefined() { |
Fumitoshi Ukai | b36f387 | 2015-04-10 15:06:38 +0900 | [diff] [blame] | 61 | v, _, err := parseExpr([]byte(ast.rhs), nil) |
| 62 | if err != nil { |
| 63 | panic(err) |
| 64 | } |
| 65 | return RecursiveVar{expr: v, origin: origin} |
Fumitoshi Ukai | 8edcb79 | 2015-04-02 11:23:23 +0900 | [diff] [blame] | 66 | } |
Fumitoshi Ukai | c184760 | 2015-04-02 16:18:02 +0900 | [diff] [blame] | 67 | return prev.Append(ev, ast.rhs) |
Shinichiro Hamaji | 69b7f65 | 2015-03-31 01:01:59 +0900 | [diff] [blame] | 68 | case "?=": |
Shinichiro Hamaji | a485d2f | 2015-04-16 14:03:24 +0900 | [diff] [blame] | 69 | prev := ev.LookupVarInCurrentScope(lhs) |
Fumitoshi Ukai | 8edcb79 | 2015-04-02 11:23:23 +0900 | [diff] [blame] | 70 | if prev.IsDefined() { |
Shinichiro Hamaji | 69b7f65 | 2015-03-31 01:01:59 +0900 | [diff] [blame] | 71 | return prev |
| 72 | } |
Fumitoshi Ukai | b36f387 | 2015-04-10 15:06:38 +0900 | [diff] [blame] | 73 | v, _, err := parseExpr([]byte(ast.rhs), nil) |
| 74 | if err != nil { |
| 75 | panic(err) |
| 76 | } |
| 77 | return RecursiveVar{expr: v, origin: origin} |
Shinichiro Hamaji | 69b7f65 | 2015-03-31 01:01:59 +0900 | [diff] [blame] | 78 | default: |
| 79 | panic(fmt.Sprintf("unknown assign op: %q", ast.op)) |
Fumitoshi Ukai | e1b813c | 2015-03-30 18:38:21 +0900 | [diff] [blame] | 80 | } |
| 81 | } |
| 82 | |
Fumitoshi Ukai | 119dc91 | 2015-03-30 16:52:41 +0900 | [diff] [blame] | 83 | func (ast *AssignAST) show() { |
Fumitoshi Ukai | b2c300f | 2015-04-23 00:59:26 +0900 | [diff] [blame] | 84 | Log("%s %s %s %q", ast.opt, ast.lhs, ast.op, ast.rhs) |
Fumitoshi Ukai | 119dc91 | 2015-03-30 16:52:41 +0900 | [diff] [blame] | 85 | } |
| 86 | |
Shinichiro Hamaji | de82971 | 2015-03-31 18:26:56 +0900 | [diff] [blame] | 87 | // Note we cannot be sure what this is, until all variables in |expr| |
| 88 | // are expanded. |
| 89 | type MaybeRuleAST struct { |
Fumitoshi Ukai | 119dc91 | 2015-03-30 16:52:41 +0900 | [diff] [blame] | 90 | ASTBase |
Shinichiro Hamaji | 486e9de | 2015-04-09 15:20:32 +0900 | [diff] [blame] | 91 | expr string |
Shinichiro Hamaji | e12e24d | 2015-04-11 23:09:20 +0900 | [diff] [blame] | 92 | equalIndex int |
Shinichiro Hamaji | 486e9de | 2015-04-09 15:20:32 +0900 | [diff] [blame] | 93 | semicolonIndex int |
Fumitoshi Ukai | 119dc91 | 2015-03-30 16:52:41 +0900 | [diff] [blame] | 94 | } |
| 95 | |
Shinichiro Hamaji | de82971 | 2015-03-31 18:26:56 +0900 | [diff] [blame] | 96 | func (ast *MaybeRuleAST) eval(ev *Evaluator) { |
| 97 | ev.evalMaybeRule(ast) |
Fumitoshi Ukai | 119dc91 | 2015-03-30 16:52:41 +0900 | [diff] [blame] | 98 | } |
| 99 | |
Shinichiro Hamaji | de82971 | 2015-03-31 18:26:56 +0900 | [diff] [blame] | 100 | func (ast *MaybeRuleAST) show() { |
| 101 | Log("%s", ast.expr) |
Fumitoshi Ukai | 119dc91 | 2015-03-30 16:52:41 +0900 | [diff] [blame] | 102 | } |
Shinichiro Hamaji | 685fecf | 2015-03-30 18:28:12 +0900 | [diff] [blame] | 103 | |
Shinichiro Hamaji | 0b93c86 | 2015-04-07 06:15:15 +0900 | [diff] [blame] | 104 | type CommandAST struct { |
| 105 | ASTBase |
Fumitoshi Ukai | 103a796 | 2015-04-08 15:53:53 +0900 | [diff] [blame] | 106 | cmd string |
Shinichiro Hamaji | 0b93c86 | 2015-04-07 06:15:15 +0900 | [diff] [blame] | 107 | } |
| 108 | |
| 109 | func (ast *CommandAST) eval(ev *Evaluator) { |
| 110 | ev.evalCommand(ast) |
| 111 | } |
| 112 | |
| 113 | func (ast *CommandAST) show() { |
| 114 | Log("\t%s", strings.Replace(ast.cmd, "\n", `\n`, -1)) |
| 115 | } |
| 116 | |
Shinichiro Hamaji | d7bef60 | 2015-03-30 19:55:32 +0900 | [diff] [blame] | 117 | type IncludeAST struct { |
| 118 | ASTBase |
| 119 | expr string |
| 120 | op string |
| 121 | } |
| 122 | |
| 123 | func (ast *IncludeAST) eval(ev *Evaluator) { |
| 124 | ev.evalInclude(ast) |
| 125 | } |
| 126 | |
| 127 | func (ast *IncludeAST) show() { |
| 128 | Log("include %s", ast.expr) |
| 129 | } |
Shinichiro Hamaji | 497754d | 2015-03-31 02:02:11 +0900 | [diff] [blame] | 130 | |
| 131 | type IfAST struct { |
| 132 | ASTBase |
Shinichiro Hamaji | ae32b78 | 2015-03-31 14:41:19 +0900 | [diff] [blame] | 133 | op string |
| 134 | lhs string |
| 135 | rhs string // Empty if |op| is ifdef or ifndef. |
| 136 | trueStmts []AST |
Shinichiro Hamaji | 497754d | 2015-03-31 02:02:11 +0900 | [diff] [blame] | 137 | falseStmts []AST |
| 138 | } |
| 139 | |
| 140 | func (ast *IfAST) eval(ev *Evaluator) { |
| 141 | ev.evalIf(ast) |
| 142 | } |
| 143 | |
| 144 | func (ast *IfAST) show() { |
| 145 | // TODO |
| 146 | Log("if") |
| 147 | } |
Shinichiro Hamaji | 7e52142 | 2015-05-29 14:23:30 +0900 | [diff] [blame] | 148 | |
| 149 | type ExportAST struct { |
| 150 | ASTBase |
Shinichiro Hamaji | f61033d | 2015-05-29 15:01:48 +0900 | [diff] [blame^] | 151 | expr []byte |
Shinichiro Hamaji | 7e52142 | 2015-05-29 14:23:30 +0900 | [diff] [blame] | 152 | export bool |
| 153 | } |
| 154 | |
| 155 | func (ast *ExportAST) eval(ev *Evaluator) { |
| 156 | ev.evalExport(ast) |
| 157 | } |
| 158 | |
| 159 | func (ast *ExportAST) show() { |
| 160 | // TODO |
Shinichiro Hamaji | f61033d | 2015-05-29 15:01:48 +0900 | [diff] [blame^] | 161 | Log("export") |
Shinichiro Hamaji | 7e52142 | 2015-05-29 14:23:30 +0900 | [diff] [blame] | 162 | } |