mirror of
https://github.com/yhirose/cpp-peglib.git
synced 2025-07-01 22:52:07 +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 {
|
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 {
|
||||||
|
38
language/interpreter.hpp
Executable file → Normal file
38
language/interpreter.hpp
Executable file → Normal file
@ -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_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
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