This commit is contained in:
aozhiwei 2023-03-29 16:06:30 +08:00
parent 50c04d6bc1
commit b6c896a7c5

View File

@ -161,7 +161,7 @@ namespace a8
std::shared_ptr<Value> Expr::Compile(const std::string& script, std::shared_ptr<Scope> env) std::shared_ptr<Value> Expr::Compile(const std::string& script, std::shared_ptr<Scope> env)
{ {
std::vector<List> stack; std::vector<std::tuple<List, int>> stack;
int pos = 0; int pos = 0;
int depth = -1; int depth = -1;
while (true) { while (true) {
@ -171,12 +171,17 @@ namespace a8
break; break;
} }
if (token == "(") { if (token == "(") {
List new_list = std::make_shared<std::vector<std::shared_ptr<Value>>>();
stack.push_back(new_list);
if (depth >= 0) {
stack.at(depth)->push_back(std::make_shared<Value>(new_list));
}
++depth; ++depth;
List new_list = std::make_shared<std::vector<std::shared_ptr<Value>>>();
stack.push_back(std::make_tuple(new_list, depth));
auto value = std::make_shared<Value>(new_list);
for (int i = stack.size() - 1; i >= 0; --i) {
auto& tuple = stack.at(i);
if (std::get<1>(tuple) < depth) {
std::get<0>(tuple)->push_back(value);
break;
}
}
} else if (token == ")") { } else if (token == ")") {
--depth; --depth;
} else { } else {
@ -184,17 +189,18 @@ namespace a8
abort(); abort();
} }
double val = 0.0f; double val = 0.0f;
auto& tuple = stack.at(stack.size() - 1);
if (sscanf(token.c_str(), "%lf", &val) == 1) { if (sscanf(token.c_str(), "%lf", &val) == 1) {
stack.at(depth)->push_back(std::make_shared<Value>(Atom(val))); std::get<0>(tuple)->push_back(std::make_shared<Value>(Atom(val)));
} else { } else {
auto symbol = env->Find(token); auto symbol = env->Find(token);
if (symbol) { if (symbol) {
if (!symbol->IsType(ValueType::kCProc)) { if (!symbol->IsType(ValueType::kCProc)) {
abort(); abort();
} }
stack.at(depth)->push_back(symbol); std::get<0>(tuple)->push_back(symbol);
} else { } else {
stack.at(depth)->push_back(std::make_shared<Value>(Symbol(token))); std::get<0>(tuple)->push_back(std::make_shared<Value>(Symbol(token)));
} }
} }
} }
@ -205,7 +211,7 @@ namespace a8
if (stack.empty()) { if (stack.empty()) {
abort(); abort();
} }
return std::make_shared<Value>(stack[0]); return std::make_shared<Value>(std::get<0>(stack[0]));
} }
bool Expr::MaybeExpr(const std::string& script) bool Expr::MaybeExpr(const std::string& script)