Supported 'logical or/and'.

This commit is contained in:
yhirose 2015-06-03 21:16:20 -04:00
parent 97235c313b
commit 7d08ed92d9
7 changed files with 42 additions and 8 deletions

39
language/interpreter.cc Executable file → Normal file
View 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
View File

0
language/main.cc Executable file → Normal file
View File

8
language/parser.cc Executable file → Normal file
View 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 },

View File

@ -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
View File

0
language/repl.hpp Executable file → Normal file
View File