Fixed problem with environment.

This commit is contained in:
yhirose 2015-06-02 23:15:25 -04:00
parent 5d5468857b
commit f9fea06e74
5 changed files with 18 additions and 31 deletions

9
language/interpreter.cc Executable file → Normal file
View File

@ -85,7 +85,7 @@ private:
return Value(Value::FunctionValue {
params,
[=](shared_ptr<Environment> 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<Environment> env, const char* expr, size_t len, Value& val, std::string& msg, bool print_ast)
{
try {

40
language/interpreter.hpp Executable file → Normal file
View File

@ -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<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
{
Environment() = default;
void push_outer(std::shared_ptr<Environment> outer) {
outers_.push_back(outer);
void set_outer(std::shared_ptr<Environment> 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<std::shared_ptr<Environment>> outers_;
std::shared_ptr<Environment> outer_;
std::map<std::string, Value> dic_;
};

0
language/main.cc Executable file → Normal file
View File

0
language/repl.cc Executable file → Normal file
View File

0
language/repl.hpp Executable file → Normal file
View File