summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/lib/symtab.c3
-rw-r--r--src/lib/syntax.c117
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)