allow h_bind's function argument to return NULL as a shortcut for h_nothing_p()

This commit is contained in:
Sven M. Hallberg 2015-01-23 22:06:43 +01:00
parent 42d51ed479
commit 78266af453
3 changed files with 21 additions and 11 deletions

View file

@ -675,7 +675,7 @@ HAMMER_FN_DECL(HParser*, h_get_value, const char* name);
* Sequencing where later parsers may depend on the result(s) of earlier ones. * Sequencing where later parsers may depend on the result(s) of earlier ones.
* *
* Run p and call the result x. Then run k(env,x). Fail if p fails or if * Run p and call the result x. Then run k(env,x). Fail if p fails or if
* k(env,x) fails. * k(env,x) fails or if k(env,x) is NULL.
* *
* Result: the result of k(x,env). * Result: the result of k(x,env).
*/ */

View file

@ -14,6 +14,9 @@ static HParseResult *parse_bind(void *be_, HParseState *state) {
return NULL; return NULL;
HParser *kx = be->k(res->ast, be->env); HParser *kx = be->k(res->ast, be->env);
if(!kx)
return NULL;
return h_do_parse(kx, state); return h_do_parse(kx, state);
} }

View file

@ -569,18 +569,23 @@ static void test_permutation(gconstpointer backend) {
} }
static HParser *f_test_bind(const HParsedToken *p, void *env) { static HParser *f_test_bind(const HParsedToken *p, void *env) {
uint8_t one = (uintptr_t)env; uint8_t one = (uintptr_t)env;
assert(p); assert(p);
assert(p->token_type == TT_SEQUENCE); assert(p->token_type == TT_SEQUENCE);
int v=0; int v=0;
for(size_t i=0; i<p->seq->used; i++) { for(size_t i=0; i<p->seq->used; i++) {
assert(p->seq->elements[i]->token_type == TT_UINT); assert(p->seq->elements[i]->token_type == TT_UINT);
v = v*10 + p->seq->elements[i]->uint - '0'; v = v*10 + p->seq->elements[i]->uint - '0';
} }
return h_ch(one - 1 + v); if(v > 26)
return h_nothing_p(); // fail
else if(v > 127)
return NULL; // equivalent to the above
else
return h_ch(one - 1 + v);
} }
static void test_bind(gconstpointer backend) { static void test_bind(gconstpointer backend) {
HParserBackend be = (HParserBackend)GPOINTER_TO_INT(backend); HParserBackend be = (HParserBackend)GPOINTER_TO_INT(backend);
@ -594,6 +599,8 @@ static void test_bind(gconstpointer backend) {
g_check_parse_failed(p, be, "1x", 2); g_check_parse_failed(p, be, "1x", 2);
g_check_parse_failed(p, be, "29y", 3); g_check_parse_failed(p, be, "29y", 3);
g_check_parse_failed(p, be, "@", 1); g_check_parse_failed(p, be, "@", 1);
g_check_parse_failed(p, be, "27{", 3);
g_check_parse_failed(p, be, "272{", 4);
} }
void register_parser_tests(void) { void register_parser_tests(void) {