[C++] Implement foreach
diff --git a/eval.h b/eval.h
index 6a27c62..d99c778 100644
--- a/eval.h
+++ b/eval.h
@@ -50,13 +50,7 @@
 
   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);
 
diff --git a/func.cc b/func.cc
index 9d694b9..3118430 100644
--- a/func.cc
+++ b/func.cc
@@ -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 @@
   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*) {
diff --git a/var.cc b/var.cc
index ee708f4..be1db17 100644
--- a/var.cc
+++ b/var.cc
@@ -82,3 +82,21 @@
     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_);
+  }
+}
diff --git a/var.h b/var.h
index e1b9d11..1d35c8f 100644
--- a/var.h
+++ b/var.h
@@ -47,7 +47,7 @@
 
   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 @@
 
   virtual void AppendVar(Evaluator* ev, Value* v);
 
-  string DebugString() const override;
+  virtual string DebugString() const override;
 
  private:
   Value* v_;
@@ -90,7 +90,7 @@
 
   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 @@
   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_