diff options
Diffstat (limited to 'src/lib/syntax.c')
| -rw-r--r-- | src/lib/syntax.c | 48 |
1 files changed, 34 insertions, 14 deletions
diff --git a/src/lib/syntax.c b/src/lib/syntax.c index d864bf4..3354050 100644 --- a/src/lib/syntax.c +++ b/src/lib/syntax.c @@ -446,7 +446,6 @@ scan_string(struct aplwc *aplwc, struct string *text, int oneline) for(i++; i < n; i++){ if(tokens->tokens[i].tag != TOKEN_TAG_NEWLINE){ rc = APLWC_INVALID_SYNTAX; - tokens = NULL; goto end; } } @@ -454,27 +453,40 @@ scan_string(struct aplwc *aplwc, struct string *text, int oneline) end: aplwc->last_error = rc; + if(aplwc->last_error != APLWC_OK) + tokens = NULL; MEMPTRS_EXIT(aplwc); return tokens; } static void -resolve_unknown(struct aplwc_module *module, struct token *t) +resolve_unknown(struct aplwc *aplwc, struct aplwc_module *module, struct token_list *tokens, size_t i) { symbol_t s; struct module_member *m; + struct string *boot; - assert(t && (t->tag == TOKEN_TAG_UNKNOWN_SYM)); - if(module == NULL) - return; + MEMPTRS(aplwc, 3); + MEMPTR(0, module); + MEMPTR(1, tokens); + + assert(tokens->tokens[i].tag == TOKEN_TAG_UNKNOWN_SYM); + if(module == NULL){ + /* Try to look into the Boot module */ + if((boot = chars_to_string(aplwc, "Boot", -1)) == NULL) + goto end; + MEMPTR(2, boot); + if((module = module_lookup(aplwc, boot)) == NULL) + goto end; + } - s = t->data.symbol; + s = tokens->tokens[i].data.symbol; for(m = module->members; m; m = m->link){ if(m->name == s){ found: - t->tag = TOKEN_TAG_IDENTIFIER; - return; + tokens->tokens[i].tag = TOKEN_TAG_IDENTIFIER; + goto end; } } @@ -482,27 +494,35 @@ found: if(m->name == s) goto found; } + + aplwc->last_error = APLWC_INVALID_SYNTAX; +end: + MEMPTRS_EXIT(aplwc); } enum aplwc_rc -check_tokens(struct aplwc_module *module, struct token_list *tokens) +check_tokens(struct aplwc *aplwc, struct aplwc_module *module, struct token_list *tokens) { size_t i; - enum aplwc_rc rc; - for(i = 0, rc = APLWC_OK; (rc == APLWC_OK) && (i < tokens->length); i++){ + MEMPTRS(aplwc, 2); + MEMPTR(0, module); + MEMPTR(1, tokens); + + for(i = 0, aplwc->last_error = APLWC_OK; (aplwc->last_error == APLWC_OK) && (i < tokens->length); i++){ switch(tokens->tokens[i].tag){ case TOKEN_TAG_UNKNOWN_SYM: - resolve_unknown(module, &tokens->tokens[i]); + resolve_unknown(aplwc, module, tokens, i); if(tokens->tokens[i].tag == TOKEN_TAG_UNKNOWN_SYM) - return APLWC_INVALID_SYNTAX; + assert(aplwc->last_error != APLWC_OK); break; default: break; } } - return rc; + MEMPTRS_EXIT(aplwc); + return aplwc->last_error; } enum aplwc_rc |