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 | 6e6de8d | 2015-06-18 11:12:58 +0900 | [diff] [blame] | 20 | #include <glob.h> |
Shinichiro Hamaji | 861bd64 | 2015-06-19 16:59:13 +0900 | [diff] [blame] | 21 | #include <string.h> |
Shinichiro Hamaji | 6e6de8d | 2015-06-18 11:12:58 +0900 | [diff] [blame] | 22 | |
Shinichiro Hamaji | 776ca30 | 2015-06-06 03:52:48 +0900 | [diff] [blame] | 23 | #include "ast.h" |
| 24 | #include "file.h" |
Shinichiro Hamaji | 6e6de8d | 2015-06-18 11:12:58 +0900 | [diff] [blame] | 25 | #include "file_cache.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" |
| 28 | #include "strutil.h" |
Shinichiro Hamaji | e799275 | 2015-06-29 18:38:35 +0900 | [diff] [blame] | 29 | #include "symtab.h" |
Shinichiro Hamaji | 776ca30 | 2015-06-06 03:52:48 +0900 | [diff] [blame] | 30 | #include "value.h" |
| 31 | #include "var.h" |
| 32 | |
| 33 | EvalResult::~EvalResult() { |
Shinichiro Hamaji | 776ca30 | 2015-06-06 03:52:48 +0900 | [diff] [blame] | 34 | for (auto p : rule_vars) |
| 35 | delete p.second; |
| 36 | delete vars; |
| 37 | } |
| 38 | |
| 39 | Evaluator::Evaluator(const Vars* vars) |
| 40 | : in_vars_(vars), |
| 41 | vars_(new Vars()), |
Shinichiro Hamaji | 784b995 | 2015-06-23 14:29:32 +0900 | [diff] [blame] | 42 | last_rule_(NULL), |
Shinichiro Hamaji | fe00294 | 2015-07-02 03:42:27 +0900 | [diff] [blame] | 43 | current_scope_(NULL), |
| 44 | avoid_io_(false) { |
Shinichiro Hamaji | 776ca30 | 2015-06-06 03:52:48 +0900 | [diff] [blame] | 45 | } |
| 46 | |
| 47 | Evaluator::~Evaluator() { |
Shinichiro Hamaji | ffc52c3 | 2015-06-23 16:51:07 +0900 | [diff] [blame] | 48 | // delete vars_; |
Shinichiro Hamaji | 776ca30 | 2015-06-06 03:52:48 +0900 | [diff] [blame] | 49 | // for (auto p : rule_vars) { |
| 50 | // delete p.second; |
| 51 | // } |
| 52 | } |
| 53 | |
Shinichiro Hamaji | e799275 | 2015-06-29 18:38:35 +0900 | [diff] [blame] | 54 | Var* Evaluator::EvalRHS(Symbol lhs, Value* rhs_v, StringPiece orig_rhs, |
Shinichiro Hamaji | 420f775 | 2015-06-26 04:02:02 +0900 | [diff] [blame] | 55 | AssignOp op, bool is_override) { |
Shinichiro Hamaji | f62e9a7 | 2015-06-26 04:18:21 +0900 | [diff] [blame] | 56 | VarOrigin origin = ( |
| 57 | (is_bootstrap_ ? VarOrigin::DEFAULT : |
| 58 | is_override ? VarOrigin::OVERRIDE : VarOrigin::FILE)); |
Shinichiro Hamaji | 776ca30 | 2015-06-06 03:52:48 +0900 | [diff] [blame] | 59 | |
Shinichiro Hamaji | 776ca30 | 2015-06-06 03:52:48 +0900 | [diff] [blame] | 60 | Var* rhs = NULL; |
Shinichiro Hamaji | 4c469b3 | 2015-06-15 19:53:36 +0900 | [diff] [blame] | 61 | bool needs_assign = true; |
Shinichiro Hamaji | 784b995 | 2015-06-23 14:29:32 +0900 | [diff] [blame] | 62 | switch (op) { |
Shinichiro Hamaji | 776ca30 | 2015-06-06 03:52:48 +0900 | [diff] [blame] | 63 | case AssignOp::COLON_EQ: |
Shinichiro Hamaji | 784b995 | 2015-06-23 14:29:32 +0900 | [diff] [blame] | 64 | rhs = new SimpleVar(rhs_v->Eval(this), origin); |
Shinichiro Hamaji | 776ca30 | 2015-06-06 03:52:48 +0900 | [diff] [blame] | 65 | break; |
| 66 | case AssignOp::EQ: |
Shinichiro Hamaji | 784b995 | 2015-06-23 14:29:32 +0900 | [diff] [blame] | 67 | rhs = new RecursiveVar(rhs_v, origin, orig_rhs); |
Shinichiro Hamaji | 776ca30 | 2015-06-06 03:52:48 +0900 | [diff] [blame] | 68 | break; |
| 69 | case AssignOp::PLUS_EQ: { |
| 70 | Var* prev = LookupVarInCurrentScope(lhs); |
| 71 | if (!prev->IsDefined()) { |
Shinichiro Hamaji | 784b995 | 2015-06-23 14:29:32 +0900 | [diff] [blame] | 72 | rhs = new RecursiveVar(rhs_v, origin, orig_rhs); |
Shinichiro Hamaji | 776ca30 | 2015-06-06 03:52:48 +0900 | [diff] [blame] | 73 | } else { |
Shinichiro Hamaji | 784b995 | 2015-06-23 14:29:32 +0900 | [diff] [blame] | 74 | prev->AppendVar(this, rhs_v); |
Shinichiro Hamaji | 4c469b3 | 2015-06-15 19:53:36 +0900 | [diff] [blame] | 75 | rhs = prev; |
| 76 | needs_assign = false; |
Shinichiro Hamaji | 776ca30 | 2015-06-06 03:52:48 +0900 | [diff] [blame] | 77 | } |
| 78 | break; |
| 79 | } |
| 80 | case AssignOp::QUESTION_EQ: { |
| 81 | Var* prev = LookupVarInCurrentScope(lhs); |
| 82 | if (!prev->IsDefined()) { |
Shinichiro Hamaji | 784b995 | 2015-06-23 14:29:32 +0900 | [diff] [blame] | 83 | rhs = new RecursiveVar(rhs_v, origin, orig_rhs); |
Shinichiro Hamaji | 776ca30 | 2015-06-06 03:52:48 +0900 | [diff] [blame] | 84 | } else { |
Shinichiro Hamaji | bef3060 | 2015-06-18 17:14:01 +0900 | [diff] [blame] | 85 | rhs = prev; |
| 86 | needs_assign = false; |
Shinichiro Hamaji | 776ca30 | 2015-06-06 03:52:48 +0900 | [diff] [blame] | 87 | } |
| 88 | break; |
| 89 | } |
| 90 | } |
| 91 | |
Shinichiro Hamaji | e799275 | 2015-06-29 18:38:35 +0900 | [diff] [blame] | 92 | LOG("Assign: %s=%s", lhs.c_str(), rhs->DebugString().c_str()); |
Shinichiro Hamaji | ffc52c3 | 2015-06-23 16:51:07 +0900 | [diff] [blame] | 93 | if (needs_assign) { |
| 94 | return rhs; |
| 95 | } |
| 96 | return NULL; |
Shinichiro Hamaji | 776ca30 | 2015-06-06 03:52:48 +0900 | [diff] [blame] | 97 | } |
| 98 | |
Shinichiro Hamaji | 784b995 | 2015-06-23 14:29:32 +0900 | [diff] [blame] | 99 | void Evaluator::EvalAssign(const AssignAST* ast) { |
| 100 | loc_ = ast->loc(); |
| 101 | last_rule_ = NULL; |
Shinichiro Hamaji | e799275 | 2015-06-29 18:38:35 +0900 | [diff] [blame] | 102 | Symbol lhs = Intern(*ast->lhs->Eval(this)); |
Shinichiro Hamaji | 0d4deb6 | 2015-06-26 07:47:17 +0900 | [diff] [blame] | 103 | if (lhs.empty()) |
| 104 | Error("*** empty variable name."); |
Shinichiro Hamaji | 0ea9e91 | 2015-06-26 04:24:38 +0900 | [diff] [blame] | 105 | Var* rhs = EvalRHS(lhs, ast->rhs, ast->orig_rhs, ast->op, |
| 106 | ast->directive == AssignDirective::OVERRIDE); |
Shinichiro Hamaji | ffc52c3 | 2015-06-23 16:51:07 +0900 | [diff] [blame] | 107 | if (rhs) |
| 108 | vars_->Assign(lhs, rhs); |
Shinichiro Hamaji | 784b995 | 2015-06-23 14:29:32 +0900 | [diff] [blame] | 109 | } |
| 110 | |
Shinichiro Hamaji | 776ca30 | 2015-06-06 03:52:48 +0900 | [diff] [blame] | 111 | void Evaluator::EvalRule(const RuleAST* ast) { |
| 112 | loc_ = ast->loc(); |
| 113 | last_rule_ = NULL; |
| 114 | |
| 115 | shared_ptr<string> expr = ast->expr->Eval(this); |
| 116 | // See semicolon.mk. |
| 117 | if (expr->find_first_not_of(" \t\n;") == string::npos) |
| 118 | return; |
| 119 | |
Shinichiro Hamaji | 9b16bda | 2015-06-19 14:25:17 +0900 | [diff] [blame] | 120 | Rule* rule; |
Shinichiro Hamaji | ffc52c3 | 2015-06-23 16:51:07 +0900 | [diff] [blame] | 121 | RuleVarAssignment rule_var; |
Shinichiro Hamaji | 2928f46 | 2015-06-23 20:24:53 +0900 | [diff] [blame] | 122 | ParseRule(loc_, *expr, ast->term, &rule, &rule_var); |
Shinichiro Hamaji | 776ca30 | 2015-06-06 03:52:48 +0900 | [diff] [blame] | 123 | |
Shinichiro Hamaji | 9b16bda | 2015-06-19 14:25:17 +0900 | [diff] [blame] | 124 | if (rule) { |
Shinichiro Hamaji | 2928f46 | 2015-06-23 20:24:53 +0900 | [diff] [blame] | 125 | if (ast->term == ';') { |
| 126 | rule->cmds.push_back(ast->after_term); |
| 127 | } |
| 128 | |
Shinichiro Hamaji | 9b16bda | 2015-06-19 14:25:17 +0900 | [diff] [blame] | 129 | LOG("Rule: %s", rule->DebugString().c_str()); |
Shinichiro Hamaji | 0562c30 | 2015-06-19 15:30:49 +0900 | [diff] [blame] | 130 | rules_.push_back(shared_ptr<Rule>(rule)); |
Shinichiro Hamaji | 9b16bda | 2015-06-19 14:25:17 +0900 | [diff] [blame] | 131 | last_rule_ = rule; |
| 132 | return; |
| 133 | } |
| 134 | |
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 | |
| 141 | Value* rhs = ast->after_term; |
| 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. |
| 147 | if (ast->term == ';') { |
| 148 | rhs = NewExpr3(lit, NewLiteral(STRING_PIECE(" ; ")), rhs); |
| 149 | } else { |
| 150 | rhs = NewExpr3(lit, NewLiteral(STRING_PIECE(" = ")), rhs); |
| 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 | e799275 | 2015-06-29 18:38:35 +0900 | [diff] [blame] | 158 | Symbol lhs = Intern(rule_var.lhs); |
Shinichiro Hamaji | ffc52c3 | 2015-06-23 16:51:07 +0900 | [diff] [blame] | 159 | Var* rhs_var = EvalRHS(lhs, rhs, STRING_PIECE("*TODO*"), rule_var.op); |
| 160 | if (rhs_var) |
| 161 | current_scope_->Assign(lhs, new RuleVar(rhs_var, rule_var.op)); |
Shinichiro Hamaji | 784b995 | 2015-06-23 14:29:32 +0900 | [diff] [blame] | 162 | current_scope_ = NULL; |
| 163 | } |
Shinichiro Hamaji | 776ca30 | 2015-06-06 03:52:48 +0900 | [diff] [blame] | 164 | } |
| 165 | |
| 166 | void Evaluator::EvalCommand(const CommandAST* ast) { |
| 167 | loc_ = ast->loc(); |
| 168 | |
| 169 | if (!last_rule_) { |
| 170 | // TODO: |
| 171 | ERROR("TODO"); |
| 172 | } |
| 173 | |
| 174 | last_rule_->cmds.push_back(ast->expr); |
Shinichiro Hamaji | ff4584d | 2015-06-24 17:45:14 +0900 | [diff] [blame] | 175 | if (last_rule_->cmd_lineno == 0) |
| 176 | last_rule_->cmd_lineno = ast->loc().lineno; |
Shinichiro Hamaji | 776ca30 | 2015-06-06 03:52:48 +0900 | [diff] [blame] | 177 | LOG("Command: %s", ast->expr->DebugString().c_str()); |
| 178 | } |
| 179 | |
Shinichiro Hamaji | 42b625f | 2015-06-16 23:07:21 +0900 | [diff] [blame] | 180 | void Evaluator::EvalIf(const IfAST* ast) { |
Shinichiro Hamaji | 6e6de8d | 2015-06-18 11:12:58 +0900 | [diff] [blame] | 181 | loc_ = ast->loc(); |
Shinichiro Hamaji | 6e6de8d | 2015-06-18 11:12:58 +0900 | [diff] [blame] | 182 | |
Shinichiro Hamaji | 7e256df | 2015-06-17 15:33:11 +0900 | [diff] [blame] | 183 | bool is_true; |
Shinichiro Hamaji | 7e256df | 2015-06-17 15:33:11 +0900 | [diff] [blame] | 184 | switch (ast->op) { |
| 185 | case CondOp::IFDEF: |
| 186 | case CondOp::IFNDEF: { |
Shinichiro Hamaji | e799275 | 2015-06-29 18:38:35 +0900 | [diff] [blame] | 187 | Symbol lhs = Intern(*ast->lhs->Eval(this)); |
Shinichiro Hamaji | 7e256df | 2015-06-17 15:33:11 +0900 | [diff] [blame] | 188 | Var* v = LookupVarInCurrentScope(lhs); |
| 189 | shared_ptr<string> s = v->Eval(this); |
Shinichiro Hamaji | d146f4c | 2015-06-17 17:51:24 +0900 | [diff] [blame] | 190 | is_true = (s->empty() == (ast->op == CondOp::IFNDEF)); |
Shinichiro Hamaji | 7e256df | 2015-06-17 15:33:11 +0900 | [diff] [blame] | 191 | break; |
| 192 | } |
| 193 | case CondOp::IFEQ: |
| 194 | case CondOp::IFNEQ: { |
Shinichiro Hamaji | d146f4c | 2015-06-17 17:51:24 +0900 | [diff] [blame] | 195 | shared_ptr<string> lhs = ast->lhs->Eval(this); |
| 196 | shared_ptr<string> rhs = ast->rhs->Eval(this); |
| 197 | is_true = ((*lhs == *rhs) == (ast->op == CondOp::IFEQ)); |
Shinichiro Hamaji | 7e256df | 2015-06-17 15:33:11 +0900 | [diff] [blame] | 198 | break; |
| 199 | } |
| 200 | default: |
| 201 | CHECK(false); |
Shinichiro Hamaji | 8d50301 | 2015-07-03 16:26:15 +0900 | [diff] [blame] | 202 | abort(); |
Shinichiro Hamaji | 7e256df | 2015-06-17 15:33:11 +0900 | [diff] [blame] | 203 | } |
| 204 | |
| 205 | const vector<AST*>* asts; |
| 206 | if (is_true) { |
Shinichiro Hamaji | 2847f09 | 2015-06-17 15:48:37 +0900 | [diff] [blame] | 207 | asts = &ast->true_asts; |
Shinichiro Hamaji | 7e256df | 2015-06-17 15:33:11 +0900 | [diff] [blame] | 208 | } else { |
Shinichiro Hamaji | 2847f09 | 2015-06-17 15:48:37 +0900 | [diff] [blame] | 209 | asts = &ast->false_asts; |
Shinichiro Hamaji | 7e256df | 2015-06-17 15:33:11 +0900 | [diff] [blame] | 210 | } |
| 211 | for (AST* a : *asts) { |
Shinichiro Hamaji | 6cb1c25 | 2015-06-17 16:22:51 +0900 | [diff] [blame] | 212 | LOG("%s", a->DebugString().c_str()); |
Shinichiro Hamaji | 7e256df | 2015-06-17 15:33:11 +0900 | [diff] [blame] | 213 | a->Eval(this); |
| 214 | } |
Shinichiro Hamaji | 42b625f | 2015-06-16 23:07:21 +0900 | [diff] [blame] | 215 | } |
| 216 | |
Shinichiro Hamaji | 6e6de8d | 2015-06-18 11:12:58 +0900 | [diff] [blame] | 217 | void Evaluator::DoInclude(const char* fname, bool should_exist) { |
Shinichiro Hamaji | 94d7a61 | 2015-06-29 18:16:11 +0900 | [diff] [blame] | 218 | if (!should_exist && g_ignore_optional_include_pattern && |
| 219 | Pattern(g_ignore_optional_include_pattern).Match(fname)) { |
| 220 | return; |
| 221 | } |
| 222 | |
Shinichiro Hamaji | 6e6de8d | 2015-06-18 11:12:58 +0900 | [diff] [blame] | 223 | Makefile* mk = MakefileCacheManager::Get()->ReadMakefile(fname); |
| 224 | if (!mk->Exists()) { |
| 225 | if (should_exist) { |
| 226 | Error(StringPrintf( |
Shinichiro Hamaji | 861bd64 | 2015-06-19 16:59:13 +0900 | [diff] [blame] | 227 | "%s: %s\n" |
| 228 | "NOTE: kati does not support generating missing makefiles", |
| 229 | fname, strerror(errno))); |
Shinichiro Hamaji | 6e6de8d | 2015-06-18 11:12:58 +0900 | [diff] [blame] | 230 | } |
| 231 | return; |
| 232 | } |
| 233 | |
Shinichiro Hamaji | e799275 | 2015-06-29 18:38:35 +0900 | [diff] [blame] | 234 | Var* var_list = LookupVar(Intern("MAKEFILE_LIST")); |
| 235 | var_list->AppendVar(this, NewLiteral(Intern(TrimLeadingCurdir(fname)).str())); |
Shinichiro Hamaji | 6e6de8d | 2015-06-18 11:12:58 +0900 | [diff] [blame] | 236 | for (AST* ast : mk->asts()) { |
| 237 | LOG("%s", ast->DebugString().c_str()); |
| 238 | ast->Eval(this); |
| 239 | } |
| 240 | } |
| 241 | |
Shinichiro Hamaji | 42b625f | 2015-06-16 23:07:21 +0900 | [diff] [blame] | 242 | void Evaluator::EvalInclude(const IncludeAST* ast) { |
Shinichiro Hamaji | 6e6de8d | 2015-06-18 11:12:58 +0900 | [diff] [blame] | 243 | loc_ = ast->loc(); |
| 244 | last_rule_ = NULL; |
| 245 | |
| 246 | shared_ptr<string> pats = ast->expr->Eval(this); |
| 247 | for (StringPiece pat : WordScanner(*pats)) { |
| 248 | ScopedTerminator st(pat); |
| 249 | if (pat.find_first_of("?*[") != string::npos) { |
| 250 | glob_t gl; |
| 251 | glob(pat.data(), GLOB_NOSORT, NULL, &gl); |
| 252 | for (size_t i = 0; i < gl.gl_pathc; i++) { |
| 253 | DoInclude(gl.gl_pathv[i], ast->should_exist); |
| 254 | } |
| 255 | globfree(&gl); |
| 256 | } else { |
| 257 | DoInclude(pat.data(), ast->should_exist); |
| 258 | } |
| 259 | } |
Shinichiro Hamaji | 42b625f | 2015-06-16 23:07:21 +0900 | [diff] [blame] | 260 | } |
| 261 | |
| 262 | void Evaluator::EvalExport(const ExportAST* ast) { |
Shinichiro Hamaji | 6e6de8d | 2015-06-18 11:12:58 +0900 | [diff] [blame] | 263 | loc_ = ast->loc(); |
| 264 | last_rule_ = NULL; |
| 265 | |
Shinichiro Hamaji | 45a0c76 | 2015-06-26 06:47:10 +0900 | [diff] [blame] | 266 | shared_ptr<string> exports = ast->expr->Eval(this); |
| 267 | for (StringPiece tok : WordScanner(*exports)) { |
| 268 | size_t equal_index = tok.find('='); |
| 269 | if (equal_index == string::npos) { |
| 270 | exports_[Intern(tok)] = ast->is_export; |
| 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); |
| 280 | exports_[Intern(lhs)] = ast->is_export; |
| 281 | } |
| 282 | } |
Shinichiro Hamaji | 42b625f | 2015-06-16 23:07:21 +0900 | [diff] [blame] | 283 | } |
| 284 | |
Shinichiro Hamaji | e799275 | 2015-06-29 18:38:35 +0900 | [diff] [blame] | 285 | Var* Evaluator::LookupVar(Symbol name) { |
Shinichiro Hamaji | 784b995 | 2015-06-23 14:29:32 +0900 | [diff] [blame] | 286 | if (current_scope_) { |
| 287 | Var* v = current_scope_->Lookup(name); |
| 288 | if (v->IsDefined()) |
| 289 | return v; |
| 290 | } |
Shinichiro Hamaji | 776ca30 | 2015-06-06 03:52:48 +0900 | [diff] [blame] | 291 | Var* v = vars_->Lookup(name); |
| 292 | if (v->IsDefined()) |
| 293 | return v; |
| 294 | return in_vars_->Lookup(name); |
| 295 | } |
| 296 | |
Shinichiro Hamaji | e799275 | 2015-06-29 18:38:35 +0900 | [diff] [blame] | 297 | Var* Evaluator::LookupVarInCurrentScope(Symbol name) { |
Shinichiro Hamaji | 784b995 | 2015-06-23 14:29:32 +0900 | [diff] [blame] | 298 | if (current_scope_) { |
| 299 | return current_scope_->Lookup(name); |
| 300 | } |
Shinichiro Hamaji | 776ca30 | 2015-06-06 03:52:48 +0900 | [diff] [blame] | 301 | Var* v = vars_->Lookup(name); |
| 302 | if (v->IsDefined()) |
| 303 | return v; |
| 304 | return in_vars_->Lookup(name); |
| 305 | } |
| 306 | |
Shinichiro Hamaji | 9619b36 | 2015-06-16 16:13:25 +0900 | [diff] [blame] | 307 | void Evaluator::Error(const string& msg) { |
Shinichiro Hamaji | 8ee8c37 | 2015-06-16 16:19:40 +0900 | [diff] [blame] | 308 | ERROR("%s:%d: %s", LOCF(loc_), msg.c_str()); |
Shinichiro Hamaji | 9619b36 | 2015-06-16 16:13:25 +0900 | [diff] [blame] | 309 | } |