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