Added assert function.

This commit is contained in:
yhirose 2015-07-07 15:44:33 -04:00
parent ebcaf2c0b9
commit 8b08ca3cca
4 changed files with 84 additions and 9 deletions

View File

@ -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);
} }

View File

@ -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
View 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()

View File

@ -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>>());
}; };
} }
} }