mirror of
https://github.com/yhirose/cpp-peglib.git
synced 2024-12-23 04:15:31 +00:00
Added assert function.
This commit is contained in:
parent
ebcaf2c0b9
commit
8b08ca3cca
@ -118,6 +118,9 @@ private:
|
|||||||
callEnv->initialize(param.name, val, param.mut);
|
callEnv->initialize(param.name, val, param.mut);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
callEnv->initialize("__LINE__", Value((long)ast.line), false);
|
||||||
|
callEnv->initialize("__COLUMN__", Value((long)ast.column), false);
|
||||||
|
|
||||||
return fv.eval(callEnv);
|
return fv.eval(callEnv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -269,6 +269,23 @@ struct Environment
|
|||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
false);
|
false);
|
||||||
|
|
||||||
|
initialize(
|
||||||
|
"assert",
|
||||||
|
Value(Value::FunctionValue {
|
||||||
|
{ {"arg", true} },
|
||||||
|
[](std::shared_ptr<Environment> env) {
|
||||||
|
auto cond = env->get("arg").to_bool();
|
||||||
|
if (!cond) {
|
||||||
|
auto line = env->get("__LINE__").to_long();
|
||||||
|
auto column = env->get("__COLUMN__").to_long();
|
||||||
|
std::string msg = "assert failed at " + std::to_string(line) + ":" + std::to_string(column) + ".";
|
||||||
|
throw std::runtime_error(msg);
|
||||||
|
}
|
||||||
|
return Value();
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
46
language/samples/test.cul
Normal file
46
language/samples/test.cul
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
|
||||||
|
test_sum = fn () {
|
||||||
|
mut i = 1
|
||||||
|
mut ret = 0
|
||||||
|
while i <= 10 {
|
||||||
|
ret = ret + i
|
||||||
|
i = i + 1
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(ret == 55)
|
||||||
|
}
|
||||||
|
|
||||||
|
test_fib = fn () {
|
||||||
|
fib = fn (x) {
|
||||||
|
if x < 2 {
|
||||||
|
x
|
||||||
|
} else {
|
||||||
|
self(x - 2) + self(x -1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = fib(15)
|
||||||
|
|
||||||
|
assert(ret == 610)
|
||||||
|
}
|
||||||
|
|
||||||
|
test_closure = fn () {
|
||||||
|
make_func = fn (mut x) {
|
||||||
|
mut n = 100
|
||||||
|
fn () {
|
||||||
|
n = n + 1
|
||||||
|
x = x + 1 + n
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
f = make_func(10)
|
||||||
|
f()
|
||||||
|
f()
|
||||||
|
ret = f()
|
||||||
|
|
||||||
|
assert(ret == 319)
|
||||||
|
}
|
||||||
|
|
||||||
|
test_sum()
|
||||||
|
test_fib()
|
||||||
|
test_closure()
|
27
peglib.h
27
peglib.h
@ -180,6 +180,7 @@ struct SemanticValue
|
|||||||
|
|
||||||
struct SemanticValues : protected std::vector<SemanticValue>
|
struct SemanticValues : protected std::vector<SemanticValue>
|
||||||
{
|
{
|
||||||
|
const char* ss;
|
||||||
const char* s;
|
const char* s;
|
||||||
size_t n;
|
size_t n;
|
||||||
size_t choice;
|
size_t choice;
|
||||||
@ -474,6 +475,7 @@ struct Context
|
|||||||
if (!sv.empty()) {
|
if (!sv.empty()) {
|
||||||
sv.clear();
|
sv.clear();
|
||||||
}
|
}
|
||||||
|
sv.ss = s;
|
||||||
sv.s = nullptr;
|
sv.s = nullptr;
|
||||||
sv.n = 0;
|
sv.n = 0;
|
||||||
return sv;
|
return sv;
|
||||||
@ -1941,14 +1943,16 @@ const int AstDefaultTag = -1;
|
|||||||
|
|
||||||
struct Ast
|
struct Ast
|
||||||
{
|
{
|
||||||
Ast(const char* _name, int _tag, const std::vector<std::shared_ptr<Ast>>& _nodes)
|
Ast(size_t _line, size_t _column, const char* _name, int _tag, const std::vector<std::shared_ptr<Ast>>& _nodes)
|
||||||
: name(_name), tag(_tag), is_token(false), nodes(_nodes) {}
|
: line(_line), column(_column), name(_name), tag(_tag), is_token(false), nodes(_nodes) {}
|
||||||
|
|
||||||
Ast(const char* _name, int _tag, const std::string& _token)
|
Ast(size_t _line, size_t _column, const char* _name, int _tag, const std::string& _token)
|
||||||
: name(_name), tag(_tag), is_token(true), token(_token) {}
|
: line(_line), column(_column), name(_name), tag(_tag), is_token(true), token(_token) {}
|
||||||
|
|
||||||
void print() const;
|
void print() const;
|
||||||
|
|
||||||
|
const size_t line;
|
||||||
|
const size_t column;
|
||||||
const std::string name;
|
const std::string name;
|
||||||
const int tag;
|
const int tag;
|
||||||
const bool is_token;
|
const bool is_token;
|
||||||
@ -2008,7 +2012,8 @@ public:
|
|||||||
|
|
||||||
bool load_grammar(const char* s, size_t n, const Rules& rules) {
|
bool load_grammar(const char* s, size_t n, const Rules& rules) {
|
||||||
grammar_ = PEGParser::parse(
|
grammar_ = PEGParser::parse(
|
||||||
s, n, rules,
|
s, n,
|
||||||
|
rules,
|
||||||
start_,
|
start_,
|
||||||
[&](const char* s, size_t n, size_t id, const std::string& name) {
|
[&](const char* s, size_t n, size_t id, const std::string& name) {
|
||||||
if (match_action) match_action(s, n, id, name);
|
if (match_action) match_action(s, n, id, name);
|
||||||
@ -2172,13 +2177,15 @@ private:
|
|||||||
auto is_token = rule.is_token;
|
auto is_token = rule.is_token;
|
||||||
rule = [info, is_token](const SemanticValues& sv) {
|
rule = [info, is_token](const SemanticValues& sv) {
|
||||||
if (is_token) {
|
if (is_token) {
|
||||||
return std::make_shared<Ast>(info.name, info.tag, std::string(sv.s, sv.n));
|
auto line = line_info(sv.ss, sv.s);
|
||||||
|
return std::make_shared<Ast>(line.first, line.second, info.name, info.tag, std::string(sv.s, sv.n));
|
||||||
}
|
}
|
||||||
if (info.optimize_nodes && sv.size() == 1) {
|
if (info.optimize_nodes && sv.size() == 1) {
|
||||||
std::shared_ptr<Ast> ast = sv[0].get<std::shared_ptr<Ast>>();
|
std::shared_ptr<Ast> ast = sv[0].get<std::shared_ptr<Ast>>();
|
||||||
return ast;
|
return ast;
|
||||||
}
|
}
|
||||||
return std::make_shared<Ast>(info.name, info.tag, sv.transform<std::shared_ptr<Ast>>());
|
auto line = line_info(sv.ss, sv.s);
|
||||||
|
return std::make_shared<Ast>(line.first, line.second, info.name, info.tag, sv.transform<std::shared_ptr<Ast>>());
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2190,13 +2197,15 @@ private:
|
|||||||
auto is_token = rule.is_token;
|
auto is_token = rule.is_token;
|
||||||
rule.action = [=](const SemanticValues& sv) {
|
rule.action = [=](const SemanticValues& sv) {
|
||||||
if (is_token) {
|
if (is_token) {
|
||||||
return std::make_shared<Ast>(name.c_str(), AstDefaultTag, std::string(sv.s, sv.n));
|
auto line = line_info(sv.ss, sv.s);
|
||||||
|
return std::make_shared<Ast>(line.first, line.second, name.c_str(), AstDefaultTag, std::string(sv.s, sv.n));
|
||||||
}
|
}
|
||||||
if (optimize_nodes && sv.size() == 1) {
|
if (optimize_nodes && sv.size() == 1) {
|
||||||
std::shared_ptr<Ast> ast = sv[0].get<std::shared_ptr<Ast>>();
|
std::shared_ptr<Ast> ast = sv[0].get<std::shared_ptr<Ast>>();
|
||||||
return ast;
|
return ast;
|
||||||
}
|
}
|
||||||
return std::make_shared<Ast>(name.c_str(), AstDefaultTag, sv.transform<std::shared_ptr<Ast>>());
|
auto line = line_info(sv.ss, sv.s);
|
||||||
|
return std::make_shared<Ast>(line.first, line.second, name.c_str(), AstDefaultTag, sv.transform<std::shared_ptr<Ast>>());
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user