diff --git a/language/interpreter.cc b/language/interpreter.cc old mode 100755 new mode 100644 index 9fd67ac..68900ae --- a/language/interpreter.cc +++ b/language/interpreter.cc @@ -85,7 +85,7 @@ private: return Value(Value::FunctionValue { params, [=](shared_ptr callEnv) { - callEnv->push_outer(env); + callEnv->set_outer(env); return eval(*body, callEnv); } }); @@ -110,8 +110,6 @@ private: callEnv->set(var, val); } - callEnv->push_outer(env); - return fv.eval(callEnv); } @@ -198,11 +196,6 @@ private: }; }; -std::ostream& operator<<(std::ostream& os, const Value& val) -{ - return val.out(os); -} - bool run(const string& path, shared_ptr env, const char* expr, size_t len, Value& val, std::string& msg, bool print_ast) { try { diff --git a/language/interpreter.hpp b/language/interpreter.hpp old mode 100755 new mode 100644 index 90681a7..43599cb --- a/language/interpreter.hpp +++ b/language/interpreter.hpp @@ -27,6 +27,9 @@ struct Value Value(const Value&) = default; Value(Value&& rhs) : type(rhs.type), v(rhs.v) {} + Value& operator=(const Value&) = default; + Value& operator=(Value&&) = default; + bool to_bool() const { switch (type) { case Bool: return v.get(); @@ -164,41 +167,33 @@ private: }; -std::ostream& operator<<(std::ostream& os, const Value& val); +inline std::ostream& operator<<(std::ostream& os, const Value& val) +{ + return val.out(os); +} struct Environment { Environment() = default; - void push_outer(std::shared_ptr outer) { - outers_.push_back(outer); + void set_outer(std::shared_ptr outer) { + outer_ = outer; } bool has(const std::string& s) const { if (dic_.find(s) != dic_.end()) { return true; } - for (auto& outer: outers_) { - if (outer->has(s)) { - return true; - } - } - return false; + return outer_ && outer_->has(s); } Value get(const std::string& s) const { - assert(has(s)); - if (dic_.find(s) != dic_.end()) { return dic_.at(s); } - - for (auto& outer: outers_) { - if (outer->has(s)) { - return outer->get(s); - } + if (outer_) { + return outer_->get(s); } - // NOTREACHED throw std::logic_error("invalid internal condition."); } @@ -206,12 +201,11 @@ struct Environment void set(const std::string& s, const Value& val) { if (dic_.find(s) != dic_.end()) { dic_[s] = val; + return; } - for (auto& outer: outers_) { - if (outer->has(s)) { - outer->set(s, val); - return; - } + if (outer_ && outer_->has(s)) { + outer_->set(s, val); + return; } dic_[s] = val; } @@ -227,7 +221,7 @@ struct Environment } private: - std::vector> outers_; + std::shared_ptr outer_; std::map dic_; }; diff --git a/language/main.cc b/language/main.cc old mode 100755 new mode 100644 diff --git a/language/repl.cc b/language/repl.cc old mode 100755 new mode 100644 diff --git a/language/repl.hpp b/language/repl.hpp old mode 100755 new mode 100644