Shinichiro Hamaji | 1d545aa | 2015-06-23 15:29:13 +0900 | [diff] [blame] | 1 | // Copyright 2015 Google Inc. All rights reserved |
| 2 | // |
| 3 | // Licensed under the Apache License, Version 2.0 (the "License"); |
| 4 | // you may not use this file except in compliance with the License. |
| 5 | // You may obtain a copy of the License at |
| 6 | // |
| 7 | // http://www.apache.org/licenses/LICENSE-2.0 |
| 8 | // |
| 9 | // Unless required by applicable law or agreed to in writing, software |
| 10 | // distributed under the License is distributed on an "AS IS" BASIS, |
| 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 12 | // See the License for the specific language governing permissions and |
| 13 | // limitations under the License. |
| 14 | |
Fumitoshi Ukai | 744bb2b | 2015-06-25 00:10:52 +0900 | [diff] [blame] | 15 | // +build ignore |
| 16 | |
Shinichiro Hamaji | 776ca30 | 2015-06-06 03:52:48 +0900 | [diff] [blame] | 17 | #include "eval.h" |
| 18 | |
Shinichiro Hamaji | 861bd64 | 2015-06-19 16:59:13 +0900 | [diff] [blame] | 19 | #include <errno.h> |
Shinichiro Hamaji | 861bd64 | 2015-06-19 16:59:13 +0900 | [diff] [blame] | 20 | #include <string.h> |
Shinichiro Hamaji | 6e6de8d | 2015-06-18 11:12:58 +0900 | [diff] [blame] | 21 | |
Shinichiro Hamaji | 645cca7 | 2015-09-24 17:04:21 +0900 | [diff] [blame] | 22 | #include "expr.h" |
Shinichiro Hamaji | 776ca30 | 2015-06-06 03:52:48 +0900 | [diff] [blame] | 23 | #include "file.h" |
Shinichiro Hamaji | 6e6de8d | 2015-06-18 11:12:58 +0900 | [diff] [blame] | 24 | #include "file_cache.h" |
Shinichiro Hamaji | 0e3873a | 2015-07-05 15:48:28 +0900 | [diff] [blame] | 25 | #include "fileutil.h" |
Shinichiro Hamaji | 45a0c76 | 2015-06-26 06:47:10 +0900 | [diff] [blame] | 26 | #include "parser.h" |
Shinichiro Hamaji | 776ca30 | 2015-06-06 03:52:48 +0900 | [diff] [blame] | 27 | #include "rule.h" |
Shinichiro Hamaji | 645cca7 | 2015-09-24 17:04:21 +0900 | [diff] [blame] | 28 | #include "stmt.h" |
Shinichiro Hamaji | 776ca30 | 2015-06-06 03:52:48 +0900 | [diff] [blame] | 29 | #include "strutil.h" |
Shinichiro Hamaji | e799275 | 2015-06-29 18:38:35 +0900 | [diff] [blame] | 30 | #include "symtab.h" |
Shinichiro Hamaji | 776ca30 | 2015-06-06 03:52:48 +0900 | [diff] [blame] | 31 | #include "var.h" |
| 32 | |
Shinichiro Hamaji | c9b9e5e | 2016-02-18 18:18:54 +0900 | [diff] [blame] | 33 | Evaluator::Evaluator() |
| 34 | : last_rule_(NULL), |
Shinichiro Hamaji | fe00294 | 2015-07-02 03:42:27 +0900 | [diff] [blame] | 35 | current_scope_(NULL), |
Shinichiro Hamaji | 28da237 | 2015-11-30 19:03:53 +0900 | [diff] [blame] | 36 | avoid_io_(false), |
| 37 | eval_depth_(0) { |
Shinichiro Hamaji | 776ca30 | 2015-06-06 03:52:48 +0900 | [diff] [blame] | 38 | } |
| 39 | |
| 40 | Evaluator::~Evaluator() { |
Shinichiro Hamaji | ffc52c3 | 2015-06-23 16:51:07 +0900 | [diff] [blame] | 41 | // delete vars_; |
Shinichiro Hamaji | 776ca30 | 2015-06-06 03:52:48 +0900 | [diff] [blame] | 42 | // for (auto p : rule_vars) { |
| 43 | // delete p.second; |
| 44 | // } |
| 45 | } |
| 46 | |
Shinichiro Hamaji | e799275 | 2015-06-29 18:38:35 +0900 | [diff] [blame] | 47 | Var* Evaluator::EvalRHS(Symbol lhs, Value* rhs_v, StringPiece orig_rhs, |
Shinichiro Hamaji | 420f775 | 2015-06-26 04:02:02 +0900 | [diff] [blame] | 48 | AssignOp op, bool is_override) { |
Shinichiro Hamaji | f62e9a7 | 2015-06-26 04:18:21 +0900 | [diff] [blame] | 49 | VarOrigin origin = ( |
| 50 | (is_bootstrap_ ? VarOrigin::DEFAULT : |
| 51 | is_override ? VarOrigin::OVERRIDE : VarOrigin::FILE)); |
Shinichiro Hamaji | 776ca30 | 2015-06-06 03:52:48 +0900 | [diff] [blame] | 52 | |
Shinichiro Hamaji | 776ca30 | 2015-06-06 03:52:48 +0900 | [diff] [blame] | 53 | Var* rhs = NULL; |
Shinichiro Hamaji | 4c469b3 | 2015-06-15 19:53:36 +0900 | [diff] [blame] | 54 | bool needs_assign = true; |
Shinichiro Hamaji | 784b995 | 2015-06-23 14:29:32 +0900 | [diff] [blame] | 55 | switch (op) { |
Shinichiro Hamaji | 90e52ce | 2016-02-10 13:53:41 +0900 | [diff] [blame] | 56 | case AssignOp::COLON_EQ: { |
| 57 | SimpleVar* sv = new SimpleVar(origin); |
| 58 | rhs_v->Eval(this, sv->mutable_value()); |
| 59 | rhs = sv; |
Shinichiro Hamaji | 776ca30 | 2015-06-06 03:52:48 +0900 | [diff] [blame] | 60 | break; |
Shinichiro Hamaji | 90e52ce | 2016-02-10 13:53:41 +0900 | [diff] [blame] | 61 | } |
Shinichiro Hamaji | 776ca30 | 2015-06-06 03:52:48 +0900 | [diff] [blame] | 62 | case AssignOp::EQ: |
Shinichiro Hamaji | 784b995 | 2015-06-23 14:29:32 +0900 | [diff] [blame] | 63 | rhs = new RecursiveVar(rhs_v, origin, orig_rhs); |
Shinichiro Hamaji | 776ca30 | 2015-06-06 03:52:48 +0900 | [diff] [blame] | 64 | break; |
| 65 | case AssignOp::PLUS_EQ: { |
| 66 | Var* prev = LookupVarInCurrentScope(lhs); |
| 67 | if (!prev->IsDefined()) { |
Shinichiro Hamaji | 784b995 | 2015-06-23 14:29:32 +0900 | [diff] [blame] | 68 | rhs = new RecursiveVar(rhs_v, origin, orig_rhs); |
Shinichiro Hamaji | 776ca30 | 2015-06-06 03:52:48 +0900 | [diff] [blame] | 69 | } else { |
Shinichiro Hamaji | 784b995 | 2015-06-23 14:29:32 +0900 | [diff] [blame] | 70 | prev->AppendVar(this, rhs_v); |
Shinichiro Hamaji | 4c469b3 | 2015-06-15 19:53:36 +0900 | [diff] [blame] | 71 | rhs = prev; |
| 72 | needs_assign = false; |
Shinichiro Hamaji | 776ca30 | 2015-06-06 03:52:48 +0900 | [diff] [blame] | 73 | } |
| 74 | break; |
| 75 | } |
| 76 | case AssignOp::QUESTION_EQ: { |
| 77 | Var* prev = LookupVarInCurrentScope(lhs); |
| 78 | if (!prev->IsDefined()) { |
Shinichiro Hamaji | 784b995 | 2015-06-23 14:29:32 +0900 | [diff] [blame] | 79 | rhs = new RecursiveVar(rhs_v, origin, orig_rhs); |
Shinichiro Hamaji | 776ca30 | 2015-06-06 03:52:48 +0900 | [diff] [blame] | 80 | } else { |
Shinichiro Hamaji | bef3060 | 2015-06-18 17:14:01 +0900 | [diff] [blame] | 81 | rhs = prev; |
| 82 | needs_assign = false; |
Shinichiro Hamaji | 776ca30 | 2015-06-06 03:52:48 +0900 | [diff] [blame] | 83 | } |
| 84 | break; |
| 85 | } |
| 86 | } |
| 87 | |
Shinichiro Hamaji | e799275 | 2015-06-29 18:38:35 +0900 | [diff] [blame] | 88 | LOG("Assign: %s=%s", lhs.c_str(), rhs->DebugString().c_str()); |
Shinichiro Hamaji | ffc52c3 | 2015-06-23 16:51:07 +0900 | [diff] [blame] | 89 | if (needs_assign) { |
| 90 | return rhs; |
| 91 | } |
| 92 | return NULL; |
Shinichiro Hamaji | 776ca30 | 2015-06-06 03:52:48 +0900 | [diff] [blame] | 93 | } |
| 94 | |
Shinichiro Hamaji | 645cca7 | 2015-09-24 17:04:21 +0900 | [diff] [blame] | 95 | void Evaluator::EvalAssign(const AssignStmt* stmt) { |
| 96 | loc_ = stmt->loc(); |
Shinichiro Hamaji | 784b995 | 2015-06-23 14:29:32 +0900 | [diff] [blame] | 97 | last_rule_ = NULL; |
Shinichiro Hamaji | 92a4738 | 2016-02-17 17:19:21 +0900 | [diff] [blame] | 98 | Symbol lhs = stmt->GetLhsSymbol(this); |
Shinichiro Hamaji | 0d4deb6 | 2015-06-26 07:47:17 +0900 | [diff] [blame] | 99 | if (lhs.empty()) |
| 100 | Error("*** empty variable name."); |
Shinichiro Hamaji | 645cca7 | 2015-09-24 17:04:21 +0900 | [diff] [blame] | 101 | Var* rhs = EvalRHS(lhs, stmt->rhs, stmt->orig_rhs, stmt->op, |
| 102 | stmt->directive == AssignDirective::OVERRIDE); |
Shinichiro Hamaji | ffc52c3 | 2015-06-23 16:51:07 +0900 | [diff] [blame] | 103 | if (rhs) |
Shinichiro Hamaji | c9b9e5e | 2016-02-18 18:18:54 +0900 | [diff] [blame] | 104 | lhs.SetGlobalVar(rhs); |
Shinichiro Hamaji | 784b995 | 2015-06-23 14:29:32 +0900 | [diff] [blame] | 105 | } |
| 106 | |
Shinichiro Hamaji | 645cca7 | 2015-09-24 17:04:21 +0900 | [diff] [blame] | 107 | void Evaluator::EvalRule(const RuleStmt* stmt) { |
| 108 | loc_ = stmt->loc(); |
Shinichiro Hamaji | 776ca30 | 2015-06-06 03:52:48 +0900 | [diff] [blame] | 109 | last_rule_ = NULL; |
| 110 | |
Shinichiro Hamaji | 645cca7 | 2015-09-24 17:04:21 +0900 | [diff] [blame] | 111 | const string&& expr = stmt->expr->Eval(this); |
Shinichiro Hamaji | 776ca30 | 2015-06-06 03:52:48 +0900 | [diff] [blame] | 112 | // See semicolon.mk. |
Shinichiro Hamaji | ea54976 | 2015-12-07 14:24:23 +0900 | [diff] [blame] | 113 | if (expr.find_first_not_of(" \t;") == string::npos) { |
| 114 | if (stmt->term == ';') |
| 115 | Error("*** missing rule before commands."); |
Shinichiro Hamaji | 776ca30 | 2015-06-06 03:52:48 +0900 | [diff] [blame] | 116 | return; |
Shinichiro Hamaji | ea54976 | 2015-12-07 14:24:23 +0900 | [diff] [blame] | 117 | } |
Shinichiro Hamaji | 776ca30 | 2015-06-06 03:52:48 +0900 | [diff] [blame] | 118 | |
Shinichiro Hamaji | 9b16bda | 2015-06-19 14:25:17 +0900 | [diff] [blame] | 119 | Rule* rule; |
Shinichiro Hamaji | ffc52c3 | 2015-06-23 16:51:07 +0900 | [diff] [blame] | 120 | RuleVarAssignment rule_var; |
Shinichiro Hamaji | 645cca7 | 2015-09-24 17:04:21 +0900 | [diff] [blame] | 121 | ParseRule(loc_, expr, stmt->term, &rule, &rule_var); |
Shinichiro Hamaji | 776ca30 | 2015-06-06 03:52:48 +0900 | [diff] [blame] | 122 | |
Shinichiro Hamaji | 9b16bda | 2015-06-19 14:25:17 +0900 | [diff] [blame] | 123 | if (rule) { |
Shinichiro Hamaji | 645cca7 | 2015-09-24 17:04:21 +0900 | [diff] [blame] | 124 | if (stmt->term == ';') { |
| 125 | rule->cmds.push_back(stmt->after_term); |
Shinichiro Hamaji | 2928f46 | 2015-06-23 20:24:53 +0900 | [diff] [blame] | 126 | } |
| 127 | |
Shinichiro Hamaji | 9b16bda | 2015-06-19 14:25:17 +0900 | [diff] [blame] | 128 | LOG("Rule: %s", rule->DebugString().c_str()); |
Shinichiro Hamaji | 7a2659e | 2016-02-08 14:32:56 +0900 | [diff] [blame] | 129 | rules_.push_back(rule); |
Shinichiro Hamaji | 9b16bda | 2015-06-19 14:25:17 +0900 | [diff] [blame] | 130 | last_rule_ = rule; |
| 131 | return; |
| 132 | } |
| 133 | |
Shinichiro Hamaji | 772ff7f | 2016-02-08 18:33:54 +0900 | [diff] [blame] | 134 | Symbol lhs = Intern(rule_var.lhs); |
Shinichiro Hamaji | e799275 | 2015-06-29 18:38:35 +0900 | [diff] [blame] | 135 | for (Symbol output : rule_var.outputs) { |
Shinichiro Hamaji | 2a04789 | 2015-06-29 13:56:41 +0900 | [diff] [blame] | 136 | auto p = rule_vars_.emplace(output, nullptr); |
Shinichiro Hamaji | 784b995 | 2015-06-23 14:29:32 +0900 | [diff] [blame] | 137 | if (p.second) { |
| 138 | p.first->second = new Vars; |
| 139 | } |
| 140 | |
Shinichiro Hamaji | 645cca7 | 2015-09-24 17:04:21 +0900 | [diff] [blame] | 141 | Value* rhs = stmt->after_term; |
Shinichiro Hamaji | 784b995 | 2015-06-23 14:29:32 +0900 | [diff] [blame] | 142 | if (!rule_var.rhs.empty()) { |
| 143 | Value* lit = NewLiteral(rule_var.rhs); |
| 144 | if (rhs) { |
Shinichiro Hamaji | 5e3e3d2 | 2015-06-24 16:53:44 +0900 | [diff] [blame] | 145 | // TODO: We always insert two whitespaces around the |
| 146 | // terminator. Preserve whitespaces properly. |
Shinichiro Hamaji | 645cca7 | 2015-09-24 17:04:21 +0900 | [diff] [blame] | 147 | if (stmt->term == ';') { |
Shinichiro Hamaji | 388e858 | 2015-07-03 16:51:46 +0900 | [diff] [blame] | 148 | rhs = NewExpr3(lit, NewLiteral(StringPiece(" ; ")), rhs); |
Shinichiro Hamaji | 5e3e3d2 | 2015-06-24 16:53:44 +0900 | [diff] [blame] | 149 | } else { |
Shinichiro Hamaji | 388e858 | 2015-07-03 16:51:46 +0900 | [diff] [blame] | 150 | rhs = NewExpr3(lit, NewLiteral(StringPiece(" = ")), rhs); |
Shinichiro Hamaji | 5e3e3d2 | 2015-06-24 16:53:44 +0900 | [diff] [blame] | 151 | } |
Shinichiro Hamaji | 784b995 | 2015-06-23 14:29:32 +0900 | [diff] [blame] | 152 | } else { |
| 153 | rhs = lit; |
| 154 | } |
| 155 | } |
| 156 | |
| 157 | current_scope_ = p.first->second; |
Shinichiro Hamaji | 388e858 | 2015-07-03 16:51:46 +0900 | [diff] [blame] | 158 | Var* rhs_var = EvalRHS(lhs, rhs, StringPiece("*TODO*"), rule_var.op); |
Shinichiro Hamaji | ffc52c3 | 2015-06-23 16:51:07 +0900 | [diff] [blame] | 159 | if (rhs_var) |
| 160 | current_scope_->Assign(lhs, new RuleVar(rhs_var, rule_var.op)); |
Shinichiro Hamaji | 784b995 | 2015-06-23 14:29:32 +0900 | [diff] [blame] | 161 | current_scope_ = NULL; |
| 162 | } |
Shinichiro Hamaji | 776ca30 | 2015-06-06 03:52:48 +0900 | [diff] [blame] | 163 | } |
| 164 | |
Shinichiro Hamaji | 645cca7 | 2015-09-24 17:04:21 +0900 | [diff] [blame] | 165 | void Evaluator::EvalCommand(const CommandStmt* stmt) { |
| 166 | loc_ = stmt->loc(); |
Shinichiro Hamaji | 776ca30 | 2015-06-06 03:52:48 +0900 | [diff] [blame] | 167 | |
| 168 | if (!last_rule_) { |
Shinichiro Hamaji | 645cca7 | 2015-09-24 17:04:21 +0900 | [diff] [blame] | 169 | vector<Stmt*> stmts; |
| 170 | ParseNotAfterRule(stmt->orig, stmt->loc(), &stmts); |
| 171 | for (Stmt* a : stmts) |
Shinichiro Hamaji | 631a9f8 | 2015-07-05 14:18:15 +0900 | [diff] [blame] | 172 | a->Eval(this); |
| 173 | return; |
Shinichiro Hamaji | 776ca30 | 2015-06-06 03:52:48 +0900 | [diff] [blame] | 174 | } |
| 175 | |
Shinichiro Hamaji | 645cca7 | 2015-09-24 17:04:21 +0900 | [diff] [blame] | 176 | last_rule_->cmds.push_back(stmt->expr); |
Shinichiro Hamaji | ff4584d | 2015-06-24 17:45:14 +0900 | [diff] [blame] | 177 | if (last_rule_->cmd_lineno == 0) |
Shinichiro Hamaji | 645cca7 | 2015-09-24 17:04:21 +0900 | [diff] [blame] | 178 | last_rule_->cmd_lineno = stmt->loc().lineno; |
| 179 | LOG("Command: %s", stmt->expr->DebugString().c_str()); |
Shinichiro Hamaji | 776ca30 | 2015-06-06 03:52:48 +0900 | [diff] [blame] | 180 | } |
| 181 | |
Shinichiro Hamaji | 645cca7 | 2015-09-24 17:04:21 +0900 | [diff] [blame] | 182 | void Evaluator::EvalIf(const IfStmt* stmt) { |
| 183 | loc_ = stmt->loc(); |
Shinichiro Hamaji | 6e6de8d | 2015-06-18 11:12:58 +0900 | [diff] [blame] | 184 | |
Shinichiro Hamaji | 7e256df | 2015-06-17 15:33:11 +0900 | [diff] [blame] | 185 | bool is_true; |
Shinichiro Hamaji | 645cca7 | 2015-09-24 17:04:21 +0900 | [diff] [blame] | 186 | switch (stmt->op) { |
Shinichiro Hamaji | 7e256df | 2015-06-17 15:33:11 +0900 | [diff] [blame] | 187 | case CondOp::IFDEF: |
| 188 | case CondOp::IFNDEF: { |
Shinichiro Hamaji | 4421dda | 2015-10-21 13:36:50 +0900 | [diff] [blame] | 189 | string var_name; |
| 190 | stmt->lhs->Eval(this, &var_name); |
Shinichiro Hamaji | d236eb0 | 2015-10-27 10:02:15 +0900 | [diff] [blame] | 191 | Symbol lhs = Intern(TrimRightSpace(var_name)); |
| 192 | if (lhs.str().find_first_of(" \t") != string::npos) |
Shinichiro Hamaji | 4421dda | 2015-10-21 13:36:50 +0900 | [diff] [blame] | 193 | Error("*** invalid syntax in conditional."); |
Shinichiro Hamaji | 7e256df | 2015-06-17 15:33:11 +0900 | [diff] [blame] | 194 | Var* v = LookupVarInCurrentScope(lhs); |
Shinichiro Hamaji | fb415ad | 2015-08-14 17:19:34 +0900 | [diff] [blame] | 195 | const string&& s = v->Eval(this); |
Shinichiro Hamaji | 645cca7 | 2015-09-24 17:04:21 +0900 | [diff] [blame] | 196 | is_true = (s.empty() == (stmt->op == CondOp::IFNDEF)); |
Shinichiro Hamaji | 7e256df | 2015-06-17 15:33:11 +0900 | [diff] [blame] | 197 | break; |
| 198 | } |
| 199 | case CondOp::IFEQ: |
| 200 | case CondOp::IFNEQ: { |
Shinichiro Hamaji | 645cca7 | 2015-09-24 17:04:21 +0900 | [diff] [blame] | 201 | const string&& lhs = stmt->lhs->Eval(this); |
| 202 | const string&& rhs = stmt->rhs->Eval(this); |
| 203 | is_true = ((lhs == rhs) == (stmt->op == CondOp::IFEQ)); |
Shinichiro Hamaji | 7e256df | 2015-06-17 15:33:11 +0900 | [diff] [blame] | 204 | break; |
| 205 | } |
| 206 | default: |
| 207 | CHECK(false); |
Shinichiro Hamaji | 8d50301 | 2015-07-03 16:26:15 +0900 | [diff] [blame] | 208 | abort(); |
Shinichiro Hamaji | 7e256df | 2015-06-17 15:33:11 +0900 | [diff] [blame] | 209 | } |
| 210 | |
Shinichiro Hamaji | 645cca7 | 2015-09-24 17:04:21 +0900 | [diff] [blame] | 211 | const vector<Stmt*>* stmts; |
Shinichiro Hamaji | 7e256df | 2015-06-17 15:33:11 +0900 | [diff] [blame] | 212 | if (is_true) { |
Shinichiro Hamaji | 645cca7 | 2015-09-24 17:04:21 +0900 | [diff] [blame] | 213 | stmts = &stmt->true_stmts; |
Shinichiro Hamaji | 7e256df | 2015-06-17 15:33:11 +0900 | [diff] [blame] | 214 | } else { |
Shinichiro Hamaji | 645cca7 | 2015-09-24 17:04:21 +0900 | [diff] [blame] | 215 | stmts = &stmt->false_stmts; |
Shinichiro Hamaji | 7e256df | 2015-06-17 15:33:11 +0900 | [diff] [blame] | 216 | } |
Shinichiro Hamaji | 645cca7 | 2015-09-24 17:04:21 +0900 | [diff] [blame] | 217 | for (Stmt* a : *stmts) { |
Shinichiro Hamaji | 6cb1c25 | 2015-06-17 16:22:51 +0900 | [diff] [blame] | 218 | LOG("%s", a->DebugString().c_str()); |
Shinichiro Hamaji | 7e256df | 2015-06-17 15:33:11 +0900 | [diff] [blame] | 219 | a->Eval(this); |
| 220 | } |
Shinichiro Hamaji | 42b625f | 2015-06-16 23:07:21 +0900 | [diff] [blame] | 221 | } |
| 222 | |
Shinichiro Hamaji | 0e3873a | 2015-07-05 15:48:28 +0900 | [diff] [blame] | 223 | void Evaluator::DoInclude(const string& fname) { |
Shinichiro Hamaji | 6e6de8d | 2015-06-18 11:12:58 +0900 | [diff] [blame] | 224 | Makefile* mk = MakefileCacheManager::Get()->ReadMakefile(fname); |
Shinichiro Hamaji | 0e3873a | 2015-07-05 15:48:28 +0900 | [diff] [blame] | 225 | CHECK(mk->Exists()); |
Shinichiro Hamaji | 6e6de8d | 2015-06-18 11:12:58 +0900 | [diff] [blame] | 226 | |
Shinichiro Hamaji | e799275 | 2015-06-29 18:38:35 +0900 | [diff] [blame] | 227 | Var* var_list = LookupVar(Intern("MAKEFILE_LIST")); |
| 228 | var_list->AppendVar(this, NewLiteral(Intern(TrimLeadingCurdir(fname)).str())); |
Shinichiro Hamaji | 645cca7 | 2015-09-24 17:04:21 +0900 | [diff] [blame] | 229 | for (Stmt* stmt : mk->stmts()) { |
| 230 | LOG("%s", stmt->DebugString().c_str()); |
| 231 | stmt->Eval(this); |
Shinichiro Hamaji | 6e6de8d | 2015-06-18 11:12:58 +0900 | [diff] [blame] | 232 | } |
| 233 | } |
| 234 | |
Shinichiro Hamaji | 645cca7 | 2015-09-24 17:04:21 +0900 | [diff] [blame] | 235 | void Evaluator::EvalInclude(const IncludeStmt* stmt) { |
| 236 | loc_ = stmt->loc(); |
Shinichiro Hamaji | 6e6de8d | 2015-06-18 11:12:58 +0900 | [diff] [blame] | 237 | last_rule_ = NULL; |
| 238 | |
Shinichiro Hamaji | 645cca7 | 2015-09-24 17:04:21 +0900 | [diff] [blame] | 239 | const string&& pats = stmt->expr->Eval(this); |
Shinichiro Hamaji | fb415ad | 2015-08-14 17:19:34 +0900 | [diff] [blame] | 240 | for (StringPiece pat : WordScanner(pats)) { |
Shinichiro Hamaji | 6e6de8d | 2015-06-18 11:12:58 +0900 | [diff] [blame] | 241 | ScopedTerminator st(pat); |
Shinichiro Hamaji | 0e3873a | 2015-07-05 15:48:28 +0900 | [diff] [blame] | 242 | vector<string>* files; |
| 243 | Glob(pat.data(), &files); |
| 244 | |
Shinichiro Hamaji | 645cca7 | 2015-09-24 17:04:21 +0900 | [diff] [blame] | 245 | if (stmt->should_exist) { |
Shinichiro Hamaji | 0e3873a | 2015-07-05 15:48:28 +0900 | [diff] [blame] | 246 | if (files->empty()) { |
Shinichiro Hamaji | 85c74a2 | 2015-09-28 13:54:11 +0900 | [diff] [blame] | 247 | // TOOD: Kati does not support building a missing include file. |
| 248 | Error(StringPrintf("%s: %s", pat.data(), strerror(errno))); |
Shinichiro Hamaji | 6e6de8d | 2015-06-18 11:12:58 +0900 | [diff] [blame] | 249 | } |
Shinichiro Hamaji | 0e3873a | 2015-07-05 15:48:28 +0900 | [diff] [blame] | 250 | } |
| 251 | |
| 252 | for (const string& fname : *files) { |
Shinichiro Hamaji | 645cca7 | 2015-09-24 17:04:21 +0900 | [diff] [blame] | 253 | if (!stmt->should_exist && g_flags.ignore_optional_include_pattern && |
Shinichiro Hamaji | 003d06e | 2015-09-09 18:22:04 +0900 | [diff] [blame] | 254 | Pattern(g_flags.ignore_optional_include_pattern).Match(fname)) { |
Shinichiro Hamaji | 0e3873a | 2015-07-05 15:48:28 +0900 | [diff] [blame] | 255 | return; |
| 256 | } |
| 257 | DoInclude(fname); |
Shinichiro Hamaji | 6e6de8d | 2015-06-18 11:12:58 +0900 | [diff] [blame] | 258 | } |
| 259 | } |
Shinichiro Hamaji | 42b625f | 2015-06-16 23:07:21 +0900 | [diff] [blame] | 260 | } |
| 261 | |
Shinichiro Hamaji | 645cca7 | 2015-09-24 17:04:21 +0900 | [diff] [blame] | 262 | void Evaluator::EvalExport(const ExportStmt* stmt) { |
| 263 | loc_ = stmt->loc(); |
Shinichiro Hamaji | 6e6de8d | 2015-06-18 11:12:58 +0900 | [diff] [blame] | 264 | last_rule_ = NULL; |
| 265 | |
Shinichiro Hamaji | 645cca7 | 2015-09-24 17:04:21 +0900 | [diff] [blame] | 266 | const string&& exports = stmt->expr->Eval(this); |
Shinichiro Hamaji | fb415ad | 2015-08-14 17:19:34 +0900 | [diff] [blame] | 267 | for (StringPiece tok : WordScanner(exports)) { |
Shinichiro Hamaji | 45a0c76 | 2015-06-26 06:47:10 +0900 | [diff] [blame] | 268 | size_t equal_index = tok.find('='); |
| 269 | if (equal_index == string::npos) { |
Shinichiro Hamaji | 645cca7 | 2015-09-24 17:04:21 +0900 | [diff] [blame] | 270 | exports_[Intern(tok)] = stmt->is_export; |
Shinichiro Hamaji | 45a0c76 | 2015-06-26 06:47:10 +0900 | [diff] [blame] | 271 | } else if (equal_index == 0 || |
| 272 | (equal_index == 1 && |
| 273 | (tok[0] == ':' || tok[0] == '?' || tok[0] == '+'))) { |
| 274 | // Do not export tokens after an assignment. |
| 275 | break; |
| 276 | } else { |
| 277 | StringPiece lhs, rhs; |
| 278 | AssignOp op; |
| 279 | ParseAssignStatement(tok, equal_index, &lhs, &rhs, &op); |
Shinichiro Hamaji | 645cca7 | 2015-09-24 17:04:21 +0900 | [diff] [blame] | 280 | exports_[Intern(lhs)] = stmt->is_export; |
Shinichiro Hamaji | 45a0c76 | 2015-06-26 06:47:10 +0900 | [diff] [blame] | 281 | } |
| 282 | } |
Shinichiro Hamaji | 42b625f | 2015-06-16 23:07:21 +0900 | [diff] [blame] | 283 | } |
| 284 | |
Shinichiro Hamaji | 7e70801 | 2015-07-31 13:07:34 +0900 | [diff] [blame] | 285 | Var* Evaluator::LookupVarGlobal(Symbol name) { |
Shinichiro Hamaji | c9b9e5e | 2016-02-18 18:18:54 +0900 | [diff] [blame] | 286 | Var* v = name.GetGlobalVar(); |
Shinichiro Hamaji | 7e70801 | 2015-07-31 13:07:34 +0900 | [diff] [blame] | 287 | if (v->IsDefined()) |
| 288 | return v; |
Shinichiro Hamaji | 7e70801 | 2015-07-31 13:07:34 +0900 | [diff] [blame] | 289 | used_undefined_vars_.insert(name); |
| 290 | return v; |
| 291 | } |
| 292 | |
Shinichiro Hamaji | e799275 | 2015-06-29 18:38:35 +0900 | [diff] [blame] | 293 | Var* Evaluator::LookupVar(Symbol name) { |
Shinichiro Hamaji | 784b995 | 2015-06-23 14:29:32 +0900 | [diff] [blame] | 294 | if (current_scope_) { |
| 295 | Var* v = current_scope_->Lookup(name); |
| 296 | if (v->IsDefined()) |
| 297 | return v; |
| 298 | } |
Shinichiro Hamaji | 7e70801 | 2015-07-31 13:07:34 +0900 | [diff] [blame] | 299 | return LookupVarGlobal(name); |
Shinichiro Hamaji | 776ca30 | 2015-06-06 03:52:48 +0900 | [diff] [blame] | 300 | } |
| 301 | |
Shinichiro Hamaji | e799275 | 2015-06-29 18:38:35 +0900 | [diff] [blame] | 302 | Var* Evaluator::LookupVarInCurrentScope(Symbol name) { |
Shinichiro Hamaji | 784b995 | 2015-06-23 14:29:32 +0900 | [diff] [blame] | 303 | if (current_scope_) { |
| 304 | return current_scope_->Lookup(name); |
| 305 | } |
Shinichiro Hamaji | 7e70801 | 2015-07-31 13:07:34 +0900 | [diff] [blame] | 306 | return LookupVarGlobal(name); |
Shinichiro Hamaji | 776ca30 | 2015-06-06 03:52:48 +0900 | [diff] [blame] | 307 | } |
| 308 | |
Shinichiro Hamaji | fb415ad | 2015-08-14 17:19:34 +0900 | [diff] [blame] | 309 | string Evaluator::EvalVar(Symbol name) { |
Shinichiro Hamaji | 94d6f2a | 2015-07-05 05:32:25 +0900 | [diff] [blame] | 310 | return LookupVar(name)->Eval(this); |
| 311 | } |
| 312 | |
Shinichiro Hamaji | 9619b36 | 2015-06-16 16:13:25 +0900 | [diff] [blame] | 313 | void Evaluator::Error(const string& msg) { |
Shinichiro Hamaji | 8ee8c37 | 2015-06-16 16:19:40 +0900 | [diff] [blame] | 314 | ERROR("%s:%d: %s", LOCF(loc_), msg.c_str()); |
Shinichiro Hamaji | 9619b36 | 2015-06-16 16:13:25 +0900 | [diff] [blame] | 315 | } |
Shinichiro Hamaji | 7e70801 | 2015-07-31 13:07:34 +0900 | [diff] [blame] | 316 | |
| 317 | unordered_set<Symbol> Evaluator::used_undefined_vars_; |