Split 'run' api to 'parse' and 'interpret'.

This commit is contained in:
yhirose 2015-09-16 11:59:19 -04:00
parent a773ceb725
commit 6a6fb4a262
2 changed files with 62 additions and 50 deletions

View File

@ -667,8 +667,8 @@ private:
callEnv->initialize("__COLUMN__", Value((long)ast.column), false); callEnv->initialize("__COLUMN__", Value((long)ast.column), false);
try { try {
return f.eval(callEnv); return f.eval(callEnv);
} catch (const Value& val) { } catch (const Value& e) {
return val; return e;
} }
} }
@ -929,30 +929,41 @@ private:
Debugger debugger_; Debugger debugger_;
}; };
inline bool run( inline std::shared_ptr<peg::Ast> parse(
const std::string& path, const std::string& path,
std::shared_ptr<Environment> env, const char* expr,
const char* expr, size_t len,
size_t len, std::vector<std::string>& msgs)
Value& val, {
std::vector<std::string>& msgs, auto& parser = get_parser();
std::shared_ptr<peg::Ast>& ast,
Debugger debugger = nullptr) parser.log = [&](size_t ln, size_t col, const std::string& err_msg) {
std::stringstream ss;
ss << path << ":" << ln << ":" << col << ": " << err_msg << std::endl;
msgs.push_back(ss.str());
};
std::shared_ptr<peg::Ast> ast;
if (parser.parse_n(expr, len, ast, path.c_str())) {
return peg::AstOptimizer(true, { "PARAMETERS", "ARGUMENTS", "OBJECT", "ARRAY", "RETURN" }).optimize(ast);
}
return nullptr;
}
inline bool interpret(
const std::shared_ptr<peg::Ast>& ast,
std::shared_ptr<Environment> env,
Value& val,
std::vector<std::string>& msgs,
Debugger debugger = nullptr)
{ {
try { try {
auto& parser = get_parser(); val = Interpreter(debugger).eval(*ast, env);
return true;
parser.log = [&](size_t ln, size_t col, const std::string& err_msg) { } catch (const Value& e) {
std::stringstream ss; val = e;
ss << path << ":" << ln << ":" << col << ": " << err_msg << std::endl; return true;
msgs.push_back(ss.str());
};
if (parser.parse_n(expr, len, ast, path.c_str())) {
ast = peg::AstOptimizer(true, { "PARAMETERS", "ARGUMENTS", "OBJECT", "ARRAY", "RETURN" }).optimize(ast);
val = Interpreter(debugger).eval(*ast, env);
return true;
}
} catch (std::runtime_error& e) { } catch (std::runtime_error& e) {
msgs.push_back(e.what()); msgs.push_back(e.what());
} }

View File

@ -222,21 +222,24 @@ int repl(shared_ptr<Environment> env, bool print_ast)
} }
if (!line.empty()) { if (!line.empty()) {
Value val;
vector<string> msgs; vector<string> msgs;
shared_ptr<Ast> ast; auto ast = parse("(repl)", line.data(), line.size(), msgs);
auto ret = run("(repl)", env, line.c_str(), line.size(), val, msgs, ast); if (ast) {
if (ret) {
if (print_ast) { if (print_ast) {
peg::print_ast(ast); peg::print_ast(ast);
} }
cout << val << endl;
linenoise::AddHistory(line.c_str()); Value val;
} else if (!msgs.empty()) { if (interpret(ast, env, val, msgs)) {
for (const auto& msg: msgs) { cout << val << endl;
cout << msg << endl;; linenoise::AddHistory(line.c_str());
continue;
} }
} }
for (const auto& msg : msgs) {
cout << msg << endl;;
}
} }
} }
@ -279,26 +282,24 @@ int main(int argc, const char** argv)
return -1; return -1;
} }
Value val;
vector<string> msgs; vector<string> msgs;
shared_ptr<Ast> ast; auto ast = parse(path, buff.data(), buff.size(), msgs);
Debugger dbg; if (ast) {
if (print_ast) {
CommandLineDebugger debugger; peg::print_ast(ast);
if (debug) { }
dbg = debugger;
} Value val;
auto dbg = debug ? CommandLineDebugger() : Debugger();
auto ret = run(path, env, buff.data(), buff.size(), val, msgs, ast, dbg); if (interpret(ast, env, val, msgs, dbg)) {
return 0;
if (!ret) {
for (const auto& msg: msgs) {
cerr << msg << endl;
} }
return -1;
} else if (print_ast) {
peg::print_ast(ast);
} }
for (const auto& msg : msgs) {
cerr << msg << endl;
}
return -1;
} }
if (shell) { if (shell) {