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

37
language/interpreter.cc Executable file → Normal file
View 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) {
if (ast.nodes.size() == 1) {
return eval(*ast.nodes[0], env);
} else {
auto lhs = eval(*ast.nodes[0], env);
if (ast.nodes.size() > 1) {
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.");
}
return lhs; // Any
}
}
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
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 },

View File

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

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