mirror of
https://github.com/yhirose/cpp-peglib.git
synced 2024-12-22 20:05:31 +00:00
Fixed problem with environment.
This commit is contained in:
parent
5d5468857b
commit
f9fea06e74
9
language/interpreter.cc
Executable file → Normal file
9
language/interpreter.cc
Executable file → Normal 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
40
language/interpreter.hpp
Executable file → Normal 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
0
language/main.cc
Executable file → Normal file
0
language/repl.cc
Executable file → Normal file
0
language/repl.cc
Executable file → Normal file
0
language/repl.hpp
Executable file → Normal file
0
language/repl.hpp
Executable file → Normal file
Loading…
Reference in New Issue
Block a user