Fixed problem with environment.

pull/3/head
yhirose 9 years ago
parent 5d5468857b
commit f9fea06e74
  1. 9
      language/interpreter.cc
  2. 38
      language/interpreter.hpp
  3. 0
      language/main.cc
  4. 0
      language/repl.cc
  5. 0
      language/repl.hpp

@ -85,7 +85,7 @@ private:
return Value(Value::FunctionValue { return Value(Value::FunctionValue {
params, params,
[=](shared_ptr<Environment> callEnv) { [=](shared_ptr<Environment> callEnv) {
callEnv->push_outer(env); callEnv->set_outer(env);
return eval(*body, callEnv); return eval(*body, callEnv);
} }
}); });
@ -110,8 +110,6 @@ private:
callEnv->set(var, val); callEnv->set(var, val);
} }
callEnv->push_outer(env);
return fv.eval(callEnv); 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<Environment> env, const char* expr, size_t len, Value& val, std::string& msg, bool print_ast) bool run(const string& path, shared_ptr<Environment> env, const char* expr, size_t len, Value& val, std::string& msg, bool print_ast)
{ {
try { try {

@ -27,6 +27,9 @@ struct Value
Value(const Value&) = default; Value(const Value&) = default;
Value(Value&& rhs) : type(rhs.type), v(rhs.v) {} Value(Value&& rhs) : type(rhs.type), v(rhs.v) {}
Value& operator=(const Value&) = default;
Value& operator=(Value&&) = default;
bool to_bool() const { bool to_bool() const {
switch (type) { switch (type) {
case Bool: return v.get<bool>(); case Bool: return v.get<bool>();
@ -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 struct Environment
{ {
Environment() = default; Environment() = default;
void push_outer(std::shared_ptr<Environment> outer) { void set_outer(std::shared_ptr<Environment> outer) {
outers_.push_back(outer); outer_ = outer;
} }
bool has(const std::string& s) const { bool has(const std::string& s) const {
if (dic_.find(s) != dic_.end()) { if (dic_.find(s) != dic_.end()) {
return true; return true;
} }
for (auto& outer: outers_) { return outer_ && outer_->has(s);
if (outer->has(s)) {
return true;
}
}
return false;
} }
Value get(const std::string& s) const { Value get(const std::string& s) const {
assert(has(s));
if (dic_.find(s) != dic_.end()) { if (dic_.find(s) != dic_.end()) {
return dic_.at(s); return dic_.at(s);
} }
if (outer_) {
for (auto& outer: outers_) { return outer_->get(s);
if (outer->has(s)) {
return outer->get(s);
}
} }
// NOTREACHED // NOTREACHED
throw std::logic_error("invalid internal condition."); throw std::logic_error("invalid internal condition.");
} }
@ -206,12 +201,11 @@ struct Environment
void set(const std::string& s, const Value& val) { void set(const std::string& s, const Value& val) {
if (dic_.find(s) != dic_.end()) { if (dic_.find(s) != dic_.end()) {
dic_[s] = val; dic_[s] = val;
}
for (auto& outer: outers_) {
if (outer->has(s)) {
outer->set(s, val);
return; return;
} }
if (outer_ && outer_->has(s)) {
outer_->set(s, val);
return;
} }
dic_[s] = val; dic_[s] = val;
} }
@ -227,7 +221,7 @@ struct Environment
} }
private: private:
std::vector<std::shared_ptr<Environment>> outers_; std::shared_ptr<Environment> outer_;
std::map<std::string, Value> dic_; std::map<std::string, Value> dic_;
}; };

Loading…
Cancel
Save