mirror of
https://github.com/yhirose/cpp-peglib.git
synced 2024-12-22 20:05:31 +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 Function: return eval_function(ast, env);
|
||||||
case FunctionCall: return eval_function_call(ast, env);
|
case FunctionCall: return eval_function_call(ast, env);
|
||||||
case Assignment: return eval_assignment(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 Condition: return eval_condition(ast, env);
|
||||||
case BinExpresion: return eval_bin_expression(ast, env);
|
case BinExpresion: return eval_bin_expression(ast, env);
|
||||||
case Identifier: return eval_identifier(ast, env);
|
case Identifier: return eval_identifier(ast, env);
|
||||||
@ -119,9 +121,37 @@ private:
|
|||||||
throw runtime_error(msg);
|
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) {
|
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 ope = eval(*ast.nodes[1], env).to_string();
|
||||||
auto rhs = eval(*ast.nodes[2], env);
|
auto rhs = eval(*ast.nodes[2], env);
|
||||||
|
|
||||||
@ -137,11 +167,10 @@ private:
|
|||||||
return Value(lhs >= rhs);
|
return Value(lhs >= rhs);
|
||||||
} else if (ope == ">") {
|
} else if (ope == ">") {
|
||||||
return Value(lhs > rhs);
|
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) {
|
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
|
FUNCTION_CALL <- IDENTIFIER ARGUMENTS
|
||||||
ARGUMENTS <- '(' _ (EXPRESSION (', ' _ EXPRESSION)*)? ')' _
|
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)*
|
CONDITION <- TERM (TERM_OPERATOR TERM)*
|
||||||
TERM <- FACTOR (FACTOR_OPERATOR FACTOR)*
|
TERM <- FACTOR (FACTOR_OPERATOR FACTOR)*
|
||||||
FACTOR <- WHILE / IF / FUNCTION / FUNCTION_CALL / NUMBER / BOOLEAN / STRING / INTERPOLATED_STRING / IDENTIFIER / '(' _ EXPRESSION ')' _
|
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, "PARAMETERS", Undefined },
|
||||||
{ peg::AstNodeType::Regular, "FUNCTION_CALL", FunctionCall },
|
{ peg::AstNodeType::Regular, "FUNCTION_CALL", FunctionCall },
|
||||||
{ peg::AstNodeType::Regular, "ARGUMENTS", Undefined },
|
{ 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, "CONDITION", BinExpresion },
|
||||||
{ peg::AstNodeType::Optimizable, "TERM", BinExpresion },
|
{ peg::AstNodeType::Optimizable, "TERM", BinExpresion },
|
||||||
{ peg::AstNodeType::Token, "CONDITION_OPERATOR", Undefined },
|
{ peg::AstNodeType::Token, "CONDITION_OPERATOR", Undefined },
|
||||||
|
@ -3,7 +3,8 @@
|
|||||||
enum AstTag
|
enum AstTag
|
||||||
{
|
{
|
||||||
Undefined,
|
Undefined,
|
||||||
Statements, While, If, FunctionCall, Assignment, Condition, BinExpresion,
|
Statements, While, If, FunctionCall, Assignment,
|
||||||
|
LogicalOr, LogicalAnd, Condition, BinExpresion,
|
||||||
Identifier, InterpolatedString,
|
Identifier, InterpolatedString,
|
||||||
Number, Boolean, Function
|
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