diff options
author | Tavian Barnes <tavianator@gmail.com> | 2010-02-05 11:58:41 -0500 |
---|---|---|
committer | Tavian Barnes <tavianator@gmail.com> | 2010-02-05 11:58:41 -0500 |
commit | 7eef42c72cc172a1ed8087e842905f42e737131d (patch) | |
tree | f48e27bbb5cc74cc23b1f3fc5f87bf90256d4072 /dimension/tokenize.c | |
parent | 6db4b9c77718c0d5346301815283a6dcbe28689d (diff) | |
download | dimension-7eef42c72cc172a1ed8087e842905f42e737131d.tar.xz |
"Support" the #version directive.
Diffstat (limited to 'dimension/tokenize.c')
-rw-r--r-- | dimension/tokenize.c | 66 |
1 files changed, 66 insertions, 0 deletions
diff --git a/dimension/tokenize.c b/dimension/tokenize.c index 5d18eea..63435c9 100644 --- a/dimension/tokenize.c +++ b/dimension/tokenize.c @@ -381,6 +381,50 @@ dmnsn_while_buffer(int token, dmnsn_token_buffer *prev, return tbuffer; } +static dmnsn_token_buffer * +dmnsn_version_buffer(int token, dmnsn_token_buffer *prev, + dmnsn_parse_item *lvalp, dmnsn_parse_location *llocp, + const char *filename, dmnsn_symbol_table *symtable, + void *yyscanner) +{ + dmnsn_token_buffer *tbuffer + = dmnsn_new_token_buffer(DMNSN_T_LEX_VERBATIM, prev); + + /* Buffer the current token */ + dmnsn_buffered_token buffered = { + .type = token, + .lval = *lvalp, + .lloc = *llocp + }; + dmnsn_array_push(tbuffer->buffered, &buffered); + + while (buffered.type != DMNSN_T_SEMICOLON) { + /* Recursive call */ + buffered.type = dmnsn_yylex(&buffered.lval, &buffered.lloc, + filename, symtable, yyscanner); + + if (buffered.type == DMNSN_T_EOF) { + dmnsn_diagnostic(filename, buffered.lloc.first_line, + buffered.lloc.first_column, + "syntax error, unexpected end-of-file"); + dmnsn_delete_token_buffer(tbuffer); + return NULL; + } else if (buffered.type == DMNSN_T_LEX_ERROR) { + dmnsn_delete_token_buffer(tbuffer); + return NULL; + } + + dmnsn_array_push(tbuffer->buffered, &buffered); + } + + /* Fake EOF */ + buffered.type = DMNSN_T_EOF; + buffered.lval.value = NULL; + dmnsn_array_push(tbuffer->buffered, &buffered); + + return tbuffer; +} + int dmnsn_yylex_impl(dmnsn_parse_item *lvalp, dmnsn_parse_location *llocp, const char *filename, void *yyscanner); @@ -533,6 +577,28 @@ dmnsn_yylex(dmnsn_parse_item *lvalp, dmnsn_parse_location *llocp, continue; } + case DMNSN_T_VERSION: + { + dmnsn_token_buffer *tb = dmnsn_version_buffer( + token, tbuffer, lvalp, llocp, filename, symtable, yyscanner + ); + if (!tb) { + return DMNSN_T_LEX_ERROR; + } + + dmnsn_yyset_extra(tb, yyscanner); + if (dmnsn_ld_yyparse(filename, yyscanner, symtable) != 0) { + dmnsn_yyset_extra(tb->prev, yyscanner); + dmnsn_delete_token_buffer(tb); + return DMNSN_T_LEX_ERROR; + } + + /* Restore the previous extra pointer */ + dmnsn_yyset_extra(tb->prev, yyscanner); + dmnsn_delete_token_buffer(tb); + break; + } + default: return token; } |