diff options
-rw-r--r-- | eval.h | 8 | ||||
-rw-r--r-- | func.cc | 15 | ||||
-rw-r--r-- | var.cc | 18 | ||||
-rw-r--r-- | var.h | 18 |
4 files changed, 47 insertions, 12 deletions
@@ -50,13 +50,7 @@ class Evaluator { const Loc& loc() const { return loc_; } -#if 0 - const vector<Rule*>& rules() const { return rules_; } - const Vars* vars() const { return vars_; } - const unordered_map<StringPiece, Vars*>& rule_vars() const { - return rule_vars_; - } -#endif + Vars* mutable_vars() { return vars_; } void Error(const string& msg); @@ -7,6 +7,7 @@ #include <algorithm> #include <iterator> +#include <memory> #include <unordered_map> #include "ast.h" @@ -14,6 +15,7 @@ #include "log.h" #include "parser.h" #include "strutil.h" +#include "var.h" namespace { @@ -389,8 +391,17 @@ void CallFunc(const vector<Value*>&, Evaluator*, string*) { printf("TODO(call)"); } -void ForeachFunc(const vector<Value*>&, Evaluator*, string*) { - printf("TODO(foreach)"); +void ForeachFunc(const vector<Value*>& args, Evaluator* ev, string* s) { + shared_ptr<string> varname = args[0]->Eval(ev); + shared_ptr<string> list = args[1]->Eval(ev); + WordWriter ww(s); + for (StringPiece tok : WordScanner(*list)) { + unique_ptr<SimpleVar> v(new SimpleVar( + make_shared<string>(tok.data(), tok.size()), "automatic")); + ScopedVar sv(ev->mutable_vars(), *varname, v.get()); + ww.MaybeAddWhitespace(); + args[2]->Eval(ev, s); + } } void OriginFunc(const vector<Value*>&, Evaluator*, string*) { @@ -82,3 +82,21 @@ void Vars::Assign(StringPiece name, Var* v) { p.first->second = v; } } + +ScopedVar::ScopedVar(Vars* vars, StringPiece name, Var* var) + : vars_(vars), orig_(NULL) { + auto p = vars->insert(make_pair(name, var)); + iter_ = p.first; + if (!p.second) { + orig_ = iter_->second; + iter_->second = var; + } +} + +ScopedVar::~ScopedVar() { + if (orig_) { + iter_->second = orig_; + } else { + vars_->erase(iter_); + } +} @@ -47,7 +47,7 @@ class SimpleVar : public Var { virtual void AppendVar(Evaluator* ev, Value* v); - string DebugString() const override; + virtual string DebugString() const override; private: shared_ptr<string> v_; @@ -69,7 +69,7 @@ class RecursiveVar : public Var { virtual void AppendVar(Evaluator* ev, Value* v); - string DebugString() const override; + virtual string DebugString() const override; private: Value* v_; @@ -90,7 +90,7 @@ class UndefinedVar : public Var { virtual void Eval(Evaluator* ev, string* s) const override; - string DebugString() const override; + virtual string DebugString() const override; }; extern UndefinedVar* kUndefined; @@ -104,4 +104,16 @@ class Vars : public unordered_map<StringPiece, Var*> { void Assign(StringPiece name, Var* v); }; +class ScopedVar { + public: + // Does not take ownerships of arguments. + ScopedVar(Vars* vars, StringPiece name, Var* var); + ~ScopedVar(); + + private: + Vars* vars_; + Var* orig_; + Vars::iterator iter_; +}; + #endif // VAR_H_ |