diff options
| -rw-r--r-- | src/lib/symtab.c | 3 | ||||
| -rw-r--r-- | src/lib/syntax.c | 117 |
2 files changed, 65 insertions, 55 deletions
diff --git a/src/lib/symtab.c b/src/lib/symtab.c index d81414d..f59e726 100644 --- a/src/lib/symtab.c +++ b/src/lib/symtab.c @@ -45,7 +45,8 @@ getsym(struct aplwc *aplwc, struct string *string, symbol_t *id) aplwc->symtab = sym; end: - *id = sym->id; + if(sym) + *id = sym->id; MEMPTRS_EXIT(aplwc); return rc; } diff --git a/src/lib/syntax.c b/src/lib/syntax.c index 2a613c8..5c340bc 100644 --- a/src/lib/syntax.c +++ b/src/lib/syntax.c @@ -67,20 +67,14 @@ advance(struct scan_state *state) return peek(state); } -static symbol_t -newsym(struct scan_state *state, size_t from, size_t length) +static enum aplwc_rc +newsym(struct scan_state *state, size_t from, size_t length, symbol_t *id) { struct string *s; - symbol_t id; - enum aplwc_rc rc; - - s = substring(state->aplwc, *state->text, from, length); - assert(s); /* I know this is wrong */ - rc = getsym(state->aplwc, s, &id); - assert(rc == APLWC_OK); /* I know this is wrong */ - - return id; + if((s = substring(state->aplwc, *state->text, from, length)) == NULL) + return state->aplwc->last_error; + return getsym(state->aplwc, s, id); } static void @@ -92,16 +86,18 @@ skip_space(struct scan_state *state) #define T tokens->tokens[token_index] -static int +static enum aplwc_rc single_sym(struct scan_state *state, struct token_list *tokens, size_t token_index, int check_only) { uint32_t c; size_t start; symbol_t sym; + enum aplwc_rc rc; MEMPTRS(state->aplwc, 1); MEMPTR(0, tokens); + rc = APLWC_OK; c = peek(state); start = state->offset; @@ -117,29 +113,31 @@ single_sym(struct scan_state *state, struct token_list *tokens, size_t token_ind default: T.tag = TOKEN_TAG_UNKNOWN_SYM; if(!check_only){ - sym = newsym(state, start, 1); + if((rc = newsym(state, start, 1, &sym)) != APLWC_OK) + goto end; T.data.symbol = sym; } break; } advance(state); +end: MEMPTRS_EXIT(state->aplwc); - return 1; + return rc; } -static int +static enum aplwc_rc identifier(struct scan_state *state, struct token_list *tokens, size_t token_index, int check_only) { uint32_t c; size_t start, len; - int ok; + enum aplwc_rc rc; symbol_t sym; MEMPTRS(state->aplwc, 1); MEMPTR(0, tokens); - ok = 0; + rc = APLWC_INVALID_SYNTAX; if(state->skip_number_and_identifier || (!is_letter(peek(state)))) goto end; @@ -153,30 +151,31 @@ identifier(struct scan_state *state, struct token_list *tokens, size_t token_ind T.tag = TOKEN_TAG_IDENTIFIER; if(!check_only){ - sym = newsym(state, start, len); + if((rc = newsym(state, start, len, &sym)) != APLWC_OK) + goto end; T.data.symbol = sym; } state->skip_number_and_identifier = 1; - ok = 1; + rc = APLWC_OK; end: MEMPTRS_EXIT(state->aplwc); - return ok; + return rc; } -static int +static enum aplwc_rc keyword(struct scan_state *state, struct token_list *tokens, size_t token_index, int check_only) { uint32_t c; size_t start, len; - int ok; + enum aplwc_rc rc; symbol_t sym; enum keyword kw; MEMPTRS(state->aplwc, 1); MEMPTR(0, tokens); - ok = 0; + rc = APLWC_INVALID_SYNTAX; if(peek(state) != ':') goto end; @@ -189,9 +188,11 @@ keyword(struct scan_state *state, struct token_list *tokens, size_t token_index, len++; }while(is_letter(c)); + rc = APLWC_OK; T.tag = TOKEN_TAG_KEYWORD; if(!check_only){ - sym = newsym(state, start, len); + if((rc = newsym(state, start, len, &sym)) != APLWC_OK) + goto end; for(kw = 0; kw < N_KWDS; kw++){ if(sym == state->aplwc->keyword_symbols[kw]){ @@ -200,28 +201,27 @@ keyword(struct scan_state *state, struct token_list *tokens, size_t token_index, } } if(kw == N_KWDS) - ok = 0; + rc = APLWC_INVALID_SYNTAX; } - - ok = 1; end: MEMPTRS_EXIT(state->aplwc); - return ok; + return rc; } -static int +static enum aplwc_rc number(struct scan_state *state, struct token_list *tokens, size_t token_index, int check_only) { uint32_t c; - int has_digits, ok; + int has_digits; + enum aplwc_rc rc; MEMPTRS(state->aplwc, 1); MEMPTR(0, tokens); UNUSED_PARAMETER(check_only); - ok = 0; + rc = APLWC_INVALID_SYNTAX; c = peek(state); if(state->skip_number_and_identifier) @@ -255,24 +255,24 @@ number(struct scan_state *state, struct token_list *tokens, size_t token_index, T.tag = TOKEN_TAG_NUMBER; state->skip_number_and_identifier = 1; - ok = 1; + rc = APLWC_OK; end: MEMPTRS_EXIT(state->aplwc); - return ok; + return rc; } -static int +static enum aplwc_rc text(struct scan_state *state, struct token_list *tokens, size_t token_index, int check_only) { uint32_t c; - int ok; + enum aplwc_rc rc; MEMPTRS(state->aplwc, 1); MEMPTR(0, tokens); UNUSED_PARAMETER(check_only); - ok = 0; + rc = APLWC_INVALID_SYNTAX;; c = peek(state); if(c != '\'') goto end; @@ -287,24 +287,24 @@ text(struct scan_state *state, struct token_list *tokens, size_t token_index, in goto end; T.tag = TOKEN_TAG_TEXT; - ok = 1; + rc = APLWC_OK; end: MEMPTRS_EXIT(state->aplwc); - return ok; + return rc; } -static int +static enum aplwc_rc comment(struct scan_state *state, struct token_list *tokens, size_t token_index, int check_only) { uint32_t c; - int ok; + enum aplwc_rc rc; MEMPTRS(state->aplwc, 1); MEMPTR(0, tokens); UNUSED_PARAMETER(check_only); - ok = 0; + rc = APLWC_INVALID_SYNTAX; c = peek(state); if(c != 0x235D) goto end; @@ -314,10 +314,10 @@ comment(struct scan_state *state, struct token_list *tokens, size_t token_index, while(c != '\n'); T.tag = TOKEN_TAG_COMMENT; - ok = 1; + rc = APLWC_OK; end: MEMPTRS_EXIT(state->aplwc); - return ok; + return rc; } static enum aplwc_rc @@ -325,7 +325,7 @@ next_token(struct scan_state *state, struct token_list *tokens, size_t token_ind { enum aplwc_rc rc; size_t i; - int (*scans[])(struct scan_state *, struct token_list *, size_t, int) = { + enum aplwc_rc (*scans[])(struct scan_state *, struct token_list *, size_t, int) = { identifier, keyword, number, @@ -338,14 +338,22 @@ next_token(struct scan_state *state, struct token_list *tokens, size_t token_ind skip_space(state); T.start = state->offset; - for(i = 0; i < NELEM(scans); i++){ - if(scans[i](state, tokens, token_index, check_only)) + rc = APLWC_INVALID_SYNTAX; + for(i = 0; (rc == APLWC_INVALID_SYNTAX) && (i < NELEM(scans)); i++){ + rc = scans[i](state, tokens, token_index, check_only); + switch(rc){ + case APLWC_OK: break; - state->offset = tokens->tokens[token_index].start; + case APLWC_INVALID_SYNTAX: + state->offset = tokens->tokens[token_index].start; + break; + default: + goto end; + } } T.end = state->offset; skip_space(state); - rc = (T.start == T.end) ? APLWC_INVALID_SYNTAX : APLWC_OK; +end: MEMPTRS_EXIT(state->aplwc); return rc; } @@ -384,7 +392,7 @@ end: return ret; } -static void +static enum aplwc_rc scan(struct aplwc *aplwc, struct string *text, struct token_list *tokens) { struct scan_state state; @@ -397,12 +405,13 @@ scan(struct aplwc *aplwc, struct string *text, struct token_list *tokens) init_scan_state(&state, aplwc, &text); - for(count = 0; peek(&state); count++){ + ret = APLWC_OK; + for(count = 0; (ret == APLWC_OK) && peek(&state); count++){ ret = next_token(&state, tokens, count, 0); - assert(ret == APLWC_OK); } MEMPTRS_EXIT(aplwc); + return ret; } struct token_list * @@ -416,8 +425,7 @@ scan_string(struct aplwc *aplwc, struct string *text, int oneline) MEMPTR(0, text); tokens = NULL; - rc = check(aplwc, text, &n); - if(rc != APLWC_OK) + if((rc = check(aplwc, text, &n)) != APLWC_OK) goto end; tokens = memory_alloc_token_list(aplwc, n); @@ -429,7 +437,8 @@ scan_string(struct aplwc *aplwc, struct string *text, int oneline) tokens->text = text; tokens->length = n; - scan(aplwc, text, tokens); + if((rc = scan(aplwc, text, tokens)) != APLWC_OK) + goto end; for(i = 0; oneline && (i < n); i++){ if(tokens->tokens[i].tag != TOKEN_TAG_NEWLINE) |