mirror of
https://github.com/yhirose/cpp-peglib.git
synced 2024-12-22 11:55:30 +00:00
Supported 'logical or/and'.
This commit is contained in:
parent
97235c313b
commit
7d08ed92d9
39
language/interpreter.cc
Executable file → Normal file
39
language/interpreter.cc
Executable file → Normal file
@ -15,6 +15,8 @@ struct Eval
|
||||
case Function: return eval_function(ast, env);
|
||||
case FunctionCall: return eval_function_call(ast, env);
|
||||
case Assignment: return eval_assignment(ast, env);
|
||||
case LogicalOr: return eval_logical_or(ast, env);
|
||||
case LogicalAnd: return eval_logical_and(ast, env);
|
||||
case Condition: return eval_condition(ast, env);
|
||||
case BinExpresion: return eval_bin_expression(ast, env);
|
||||
case Identifier: return eval_identifier(ast, env);
|
||||
@ -119,9 +121,37 @@ private:
|
||||
throw runtime_error(msg);
|
||||
}
|
||||
|
||||
static Value eval_logical_or(const Ast& ast, shared_ptr<Environment> env) {
|
||||
if (ast.nodes.size() == 1) {
|
||||
return eval(*ast.nodes[0], env);
|
||||
} else {
|
||||
Value ret;
|
||||
for (auto node: ast.nodes) {
|
||||
ret = eval(*node, env);
|
||||
if (ret.to_bool()) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
static Value eval_logical_and(const Ast& ast, shared_ptr<Environment> env) {
|
||||
Value ret;
|
||||
for (auto node: ast.nodes) {
|
||||
ret = eval(*node, env);
|
||||
if (!ret.to_bool()) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static Value eval_condition(const Ast& ast, shared_ptr<Environment> env) {
|
||||
auto lhs = eval(*ast.nodes[0], env);
|
||||
if (ast.nodes.size() > 1) {
|
||||
if (ast.nodes.size() == 1) {
|
||||
return eval(*ast.nodes[0], env);
|
||||
} else {
|
||||
auto lhs = eval(*ast.nodes[0], env);
|
||||
auto ope = eval(*ast.nodes[1], env).to_string();
|
||||
auto rhs = eval(*ast.nodes[2], env);
|
||||
|
||||
@ -137,11 +167,10 @@ private:
|
||||
return Value(lhs >= rhs);
|
||||
} else if (ope == ">") {
|
||||
return Value(lhs > rhs);
|
||||
} else {
|
||||
throw std::logic_error("invalid internal condition.");
|
||||
}
|
||||
|
||||
throw std::logic_error("invalid internal condition.");
|
||||
}
|
||||
return lhs; // Any
|
||||
}
|
||||
|
||||
static Value eval_bin_expression(const Ast& ast, shared_ptr<Environment> env) {
|
||||
|
0
language/interpreter.hpp
Executable file → Normal file
0
language/interpreter.hpp
Executable file → Normal file
0
language/main.cc
Executable file → Normal file
0
language/main.cc
Executable file → Normal file
8
language/parser.cc
Executable file → Normal file
8
language/parser.cc
Executable file → Normal file
@ -18,7 +18,9 @@ static auto g_grammar = R"(
|
||||
FUNCTION_CALL <- IDENTIFIER ARGUMENTS
|
||||
ARGUMENTS <- '(' _ (EXPRESSION (', ' _ EXPRESSION)*)? ')' _
|
||||
|
||||
PRIMARY <- CONDITION (CONDITION_OPERATOR CONDITION)?
|
||||
PRIMARY <- LOGICAL_OR ('||' _ LOGICAL_OR)*
|
||||
LOGICAL_OR <- LOGICAL_AND ('&&' _ LOGICAL_AND)*
|
||||
LOGICAL_AND <- CONDITION (CONDITION_OPERATOR CONDITION)*
|
||||
CONDITION <- TERM (TERM_OPERATOR TERM)*
|
||||
TERM <- FACTOR (FACTOR_OPERATOR FACTOR)*
|
||||
FACTOR <- WHILE / IF / FUNCTION / FUNCTION_CALL / NUMBER / BOOLEAN / STRING / INTERPOLATED_STRING / IDENTIFIER / '(' _ EXPRESSION ')' _
|
||||
@ -72,7 +74,9 @@ peg& get_parser()
|
||||
{ peg::AstNodeType::Regular, "PARAMETERS", Undefined },
|
||||
{ peg::AstNodeType::Regular, "FUNCTION_CALL", FunctionCall },
|
||||
{ peg::AstNodeType::Regular, "ARGUMENTS", Undefined },
|
||||
{ peg::AstNodeType::Optimizable, "PRIMARY", Condition },
|
||||
{ peg::AstNodeType::Optimizable, "PRIMARY", LogicalOr },
|
||||
{ peg::AstNodeType::Optimizable, "LOGICAL_OR", LogicalAnd },
|
||||
{ peg::AstNodeType::Optimizable, "LOGICAL_AND", Condition },
|
||||
{ peg::AstNodeType::Optimizable, "CONDITION", BinExpresion },
|
||||
{ peg::AstNodeType::Optimizable, "TERM", BinExpresion },
|
||||
{ peg::AstNodeType::Token, "CONDITION_OPERATOR", Undefined },
|
||||
|
@ -3,7 +3,8 @@
|
||||
enum AstTag
|
||||
{
|
||||
Undefined,
|
||||
Statements, While, If, FunctionCall, Assignment, Condition, BinExpresion,
|
||||
Statements, While, If, FunctionCall, Assignment,
|
||||
LogicalOr, LogicalAnd, Condition, BinExpresion,
|
||||
Identifier, InterpolatedString,
|
||||
Number, Boolean, Function
|
||||
};
|
||||
|
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