mirror of
https://github.com/yhirose/cpp-peglib.git
synced 2024-12-22 20:05:31 +00:00
Supported 'undefined' type correctly.
This commit is contained in:
parent
e96336a463
commit
75399c2e19
@ -30,7 +30,7 @@ const auto grammar_ = R"(
|
||||
INDEX <- '[' _ EXPRESSION ']' _
|
||||
DOT <- '.' _ IDENTIFIER
|
||||
|
||||
PRIMARY <- WHILE / IF / FUNCTION / IDENTIFIER / OBJECT / ARRAY / NUMBER / BOOLEAN / STRING / INTERPOLATED_STRING / '(' _ EXPRESSION ')' _
|
||||
PRIMARY <- WHILE / IF / FUNCTION / OBJECT / ARRAY / UNDEFINED / BOOLEAN / NUMBER / IDENTIFIER / STRING / INTERPOLATED_STRING / '(' _ EXPRESSION ')' _
|
||||
|
||||
FUNCTION <- 'fn' _ PARAMETERS BLOCK
|
||||
PARAMETERS <- '(' _ (PARAMETER (',' _ PARAMETER)*)? ')' _
|
||||
@ -52,8 +52,9 @@ const auto grammar_ = R"(
|
||||
|
||||
ARRAY <- '[' _ (EXPRESSION (',' _ EXPRESSION)*)? ']' _
|
||||
|
||||
NUMBER <- < [0-9]+ > _
|
||||
UNDEFINED <- < 'undefined' > _
|
||||
BOOLEAN <- < ('true' / 'false') > _
|
||||
NUMBER <- < [0-9]+ > _
|
||||
STRING <- ['] < (!['] .)* > ['] _
|
||||
|
||||
INTERPOLATED_STRING <- '"' ('{' _ EXPRESSION '}' / INTERPOLATED_CONTENT)* '"' _
|
||||
@ -278,11 +279,11 @@ struct Value
|
||||
|
||||
bool operator==(const Value& rhs) const {
|
||||
switch (type) {
|
||||
case Undefined: return true;
|
||||
case Undefined: return rhs.type == Undefined;
|
||||
case Bool: return to_bool() == rhs.to_bool();
|
||||
case Long: return to_long() == rhs.to_long();
|
||||
case String: return to_string() == rhs.to_string();
|
||||
// TODO: Array support
|
||||
// TODO: Object and Array support
|
||||
default: throw std::logic_error("invalid internal condition.");
|
||||
}
|
||||
// NOTREACHED
|
||||
@ -290,11 +291,11 @@ struct Value
|
||||
|
||||
bool operator!=(const Value& rhs) const {
|
||||
switch (type) {
|
||||
case Undefined: return false;
|
||||
case Undefined: return rhs.type != Undefined;
|
||||
case Bool: return to_bool() != rhs.to_bool();
|
||||
case Long: return to_long() != rhs.to_long();
|
||||
case String: return to_string() != rhs.to_string();
|
||||
// TODO: Array support
|
||||
// TODO: Object and Array support
|
||||
default: throw std::logic_error("invalid internal condition.");
|
||||
}
|
||||
// NOTREACHED
|
||||
@ -306,7 +307,7 @@ struct Value
|
||||
case Bool: return to_bool() <= rhs.to_bool();
|
||||
case Long: return to_long() <= rhs.to_long();
|
||||
case String: return to_string() <= rhs.to_string();
|
||||
// TODO: Array support
|
||||
// TODO: Object and Array support
|
||||
default: throw std::logic_error("invalid internal condition.");
|
||||
}
|
||||
// NOTREACHED
|
||||
@ -318,7 +319,7 @@ struct Value
|
||||
case Bool: return to_bool() < rhs.to_bool();
|
||||
case Long: return to_long() < rhs.to_long();
|
||||
case String: return to_string() < rhs.to_string();
|
||||
// TODO: Array support
|
||||
// TODO: Object and Array support
|
||||
default: throw std::logic_error("invalid internal condition.");
|
||||
}
|
||||
// NOTREACHED
|
||||
@ -330,7 +331,7 @@ struct Value
|
||||
case Bool: return to_bool() >= rhs.to_bool();
|
||||
case Long: return to_long() >= rhs.to_long();
|
||||
case String: return to_string() >= rhs.to_string();
|
||||
// TODO: Array support
|
||||
// TODO: Object and Array support
|
||||
default: throw std::logic_error("invalid internal condition.");
|
||||
}
|
||||
// NOTREACHED
|
||||
@ -342,7 +343,7 @@ struct Value
|
||||
case Bool: return to_bool() > rhs.to_bool();
|
||||
case Long: return to_long() > rhs.to_long();
|
||||
case String: return to_string() > rhs.to_string();
|
||||
// TODO: Array support
|
||||
// TODO: Object and Array support
|
||||
default: throw std::logic_error("invalid internal condition.");
|
||||
}
|
||||
// NOTREACHED
|
||||
@ -555,8 +556,9 @@ struct Eval
|
||||
case "IDENTIFIER"_: return eval_identifier(ast, env);
|
||||
case "OBJECT"_: return eval_object(ast, env);
|
||||
case "ARRAY"_: return eval_array(ast, env);
|
||||
case "NUMBER"_: return eval_number(ast, env);
|
||||
case "UNDEFINED"_: return eval_undefined(ast, env);
|
||||
case "BOOLEAN"_: return eval_bool(ast, env);
|
||||
case "NUMBER"_: return eval_number(ast, env);
|
||||
case "INTERPOLATED_STRING"_: return eval_interpolated_string(ast, env);
|
||||
}
|
||||
|
||||
@ -836,14 +838,18 @@ private:
|
||||
return Value(std::move(arr));
|
||||
}
|
||||
|
||||
static Value eval_number(const peglib::Ast& ast, std::shared_ptr<Environment> env) {
|
||||
return Value(stol(ast.token));
|
||||
static Value eval_undefined(const peglib::Ast& ast, std::shared_ptr<Environment> env) {
|
||||
return Value();
|
||||
};
|
||||
|
||||
static Value eval_bool(const peglib::Ast& ast, std::shared_ptr<Environment> env) {
|
||||
return Value(ast.token == "true");
|
||||
};
|
||||
|
||||
static Value eval_number(const peglib::Ast& ast, std::shared_ptr<Environment> env) {
|
||||
return Value(stol(ast.token));
|
||||
};
|
||||
|
||||
static Value eval_interpolated_string(const peglib::Ast& ast, std::shared_ptr<Environment> env) {
|
||||
std::string s;
|
||||
for (auto node: ast.nodes) {
|
||||
|
@ -4,6 +4,25 @@ test_call = fn () {
|
||||
assert(ret == 5)
|
||||
}
|
||||
|
||||
test_undefined = fn () {
|
||||
assert(undefined == undefined)
|
||||
assert(!(undefined != undefined))
|
||||
|
||||
a = undefined
|
||||
assert(a == undefined)
|
||||
assert(!(a != undefined))
|
||||
assert(!(a <= undefined))
|
||||
assert(!(a < undefined))
|
||||
assert(!(a >= undefined))
|
||||
assert(!(a > undefined))
|
||||
assert(undefined == a)
|
||||
assert(!(undefined != a))
|
||||
assert(!(undefined <= a))
|
||||
assert(!(undefined < a))
|
||||
assert(!(undefined >= a))
|
||||
assert(!(undefined > a))
|
||||
}
|
||||
|
||||
test_closure = fn () {
|
||||
make_func = fn (mut x) {
|
||||
mut n = 100
|
||||
@ -117,6 +136,7 @@ test_interpolated_string = fn () {
|
||||
|
||||
test_call()
|
||||
test_closure()
|
||||
test_undefined()
|
||||
test_array()
|
||||
test_function()
|
||||
test_object()
|
||||
|
Loading…
Reference in New Issue
Block a user