mirror of
https://github.com/yhirose/cpp-peglib.git
synced 2024-11-14 06:55:30 +00:00
Split 'run' api to 'parse' and 'interpret'.
This commit is contained in:
parent
a773ceb725
commit
6a6fb4a262
@ -667,8 +667,8 @@ private:
|
||||
callEnv->initialize("__COLUMN__", Value((long)ast.column), false);
|
||||
try {
|
||||
return f.eval(callEnv);
|
||||
} catch (const Value& val) {
|
||||
return val;
|
||||
} catch (const Value& e) {
|
||||
return e;
|
||||
}
|
||||
}
|
||||
|
||||
@ -929,30 +929,41 @@ private:
|
||||
Debugger debugger_;
|
||||
};
|
||||
|
||||
inline bool run(
|
||||
const std::string& path,
|
||||
std::shared_ptr<Environment> env,
|
||||
const char* expr,
|
||||
size_t len,
|
||||
Value& val,
|
||||
std::vector<std::string>& msgs,
|
||||
std::shared_ptr<peg::Ast>& ast,
|
||||
Debugger debugger = nullptr)
|
||||
inline std::shared_ptr<peg::Ast> parse(
|
||||
const std::string& path,
|
||||
const char* expr,
|
||||
size_t len,
|
||||
std::vector<std::string>& msgs)
|
||||
{
|
||||
auto& parser = get_parser();
|
||||
|
||||
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 {
|
||||
auto& parser = get_parser();
|
||||
|
||||
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());
|
||||
};
|
||||
|
||||
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;
|
||||
}
|
||||
val = Interpreter(debugger).eval(*ast, env);
|
||||
return true;
|
||||
} catch (const Value& e) {
|
||||
val = e;
|
||||
return true;
|
||||
} catch (std::runtime_error& e) {
|
||||
msgs.push_back(e.what());
|
||||
}
|
||||
|
@ -222,21 +222,24 @@ int repl(shared_ptr<Environment> env, bool print_ast)
|
||||
}
|
||||
|
||||
if (!line.empty()) {
|
||||
Value val;
|
||||
vector<string> msgs;
|
||||
shared_ptr<Ast> ast;
|
||||
auto ret = run("(repl)", env, line.c_str(), line.size(), val, msgs, ast);
|
||||
if (ret) {
|
||||
auto ast = parse("(repl)", line.data(), line.size(), msgs);
|
||||
if (ast) {
|
||||
if (print_ast) {
|
||||
peg::print_ast(ast);
|
||||
}
|
||||
cout << val << endl;
|
||||
linenoise::AddHistory(line.c_str());
|
||||
} else if (!msgs.empty()) {
|
||||
for (const auto& msg: msgs) {
|
||||
cout << msg << endl;;
|
||||
|
||||
Value val;
|
||||
if (interpret(ast, env, val, msgs)) {
|
||||
cout << val << 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;
|
||||
}
|
||||
|
||||
Value val;
|
||||
vector<string> msgs;
|
||||
shared_ptr<Ast> ast;
|
||||
Debugger dbg;
|
||||
|
||||
CommandLineDebugger debugger;
|
||||
if (debug) {
|
||||
dbg = debugger;
|
||||
}
|
||||
|
||||
auto ret = run(path, env, buff.data(), buff.size(), val, msgs, ast, dbg);
|
||||
|
||||
if (!ret) {
|
||||
for (const auto& msg: msgs) {
|
||||
cerr << msg << endl;
|
||||
auto ast = parse(path, buff.data(), buff.size(), msgs);
|
||||
if (ast) {
|
||||
if (print_ast) {
|
||||
peg::print_ast(ast);
|
||||
}
|
||||
|
||||
Value val;
|
||||
auto dbg = debug ? CommandLineDebugger() : Debugger();
|
||||
if (interpret(ast, env, val, msgs, dbg)) {
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
} else if (print_ast) {
|
||||
peg::print_ast(ast);
|
||||
}
|
||||
|
||||
for (const auto& msg : msgs) {
|
||||
cerr << msg << endl;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (shell) {
|
||||
|
Loading…
Reference in New Issue
Block a user