diff options
-rw-r--r-- | dimension/common.rules | 2 | ||||
-rw-r--r-- | dimension/common.terminals | 2 | ||||
-rw-r--r-- | dimension/directives.rules | 7 | ||||
-rw-r--r-- | dimension/lexer.l | 1 | ||||
-rw-r--r-- | dimension/tokenize.c | 66 | ||||
-rw-r--r-- | tests/dimension/directives.pov | 2 | ||||
-rwxr-xr-x | tests/dimension/directives.sh | 3 |
7 files changed, 80 insertions, 3 deletions
diff --git a/dimension/common.rules b/dimension/common.rules index 61c0bfd..0bf2557 100644 --- a/dimension/common.rules +++ b/dimension/common.rules @@ -450,7 +450,7 @@ COLOR_KEYWORD_ITEM: "identifier" { if (!symbol) { dmnsn_diagnostic(@1.first_filename, @1.first_line, @1.first_column, - "unbound identifier '%s'", $1); + "Unbound identifier '%s'", $1); free($1); YYERROR; } else if (symbol->type != DMNSN_AST_COLOR) { diff --git a/dimension/common.terminals b/dimension/common.terminals index eaeeba3..9da3b42 100644 --- a/dimension/common.terminals +++ b/dimension/common.terminals @@ -513,7 +513,7 @@ %token DMNSN_T_STATISTICS %token DMNSN_T_SWITCH %token DMNSN_T_UNDEF "#undef" -%token DMNSN_T_VERSION +%token DMNSN_T_VERSION "#version" %token DMNSN_T_WARNING %token DMNSN_T_WHILE "#while" %token DMNSN_T_WRITE diff --git a/dimension/directives.rules b/dimension/directives.rules index 4fa77df..eb03df4 100644 --- a/dimension/directives.rules +++ b/dimension/directives.rules @@ -42,6 +42,13 @@ LANGUAGE_DIRECTIVE: "#declare" "identifier" "=" RVALUE { dmnsn_new_ast_integer(node ? 0 : 1)); free($3); } + | "#version" FLOAT ";" { + dmnsn_diagnostic(@$.first_filename, @$.first_line, + @$.first_column, + "WARNING: POV-Ray #version" + " backwards-compatibility not supported"); + dmnsn_delete_astnode($2); + } RVALUE: ARITH_EXPR ";" %dprec 2 { $$ = dmnsn_eval($1, symtable); diff --git a/dimension/lexer.l b/dimension/lexer.l index 953ef9b..90c4807 100644 --- a/dimension/lexer.l +++ b/dimension/lexer.l @@ -216,6 +216,7 @@ unsigned long wchar; "#include" RETURN_TOKEN(DMNSN_T_INCLUDE); "#local" RETURN_TOKEN(DMNSN_T_LOCAL); "#undef" RETURN_TOKEN(DMNSN_T_UNDEF); +"#version" RETURN_TOKEN(DMNSN_T_VERSION); "#while" RETURN_TOKEN(DMNSN_T_WHILE); (?# Identifiers) 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; } diff --git a/tests/dimension/directives.pov b/tests/dimension/directives.pov index c6ac07b..b621709 100644 --- a/tests/dimension/directives.pov +++ b/tests/dimension/directives.pov @@ -19,6 +19,8 @@ // Test the language directives +#version 3.6; + #declare Center = 0; #declare R = 1; #local Color = rgb <1, 0, 1>; diff --git a/tests/dimension/directives.sh b/tests/dimension/directives.sh index 9152d2f..8d0bbb9 100755 --- a/tests/dimension/directives.sh +++ b/tests/dimension/directives.sh @@ -21,7 +21,8 @@ directives=$(${top_builddir}/dimension/dimension --tokenize --parse ${srcdir}/directives.pov) directives_exp="$(echo -n \ -'(#declare (identifier "Center") = (integer "0") ; +'(#version (float "3.6") ; + #declare (identifier "Center") = (integer "0") ; #declare (identifier "R") = (integer "1") ; #local (identifier "Color") = rgb < (integer "1") , (integer "0") , (integer "1") > ; #declare (identifier "Unused") = - (integer "1") ; |