diff options
Diffstat (limited to 'dimension/grammar.y')
-rw-r--r-- | dimension/grammar.y | 269 |
1 files changed, 145 insertions, 124 deletions
diff --git a/dimension/grammar.y b/dimension/grammar.y index e52d668..00bc9cb 100644 --- a/dimension/grammar.y +++ b/dimension/grammar.y @@ -147,7 +147,7 @@ yyerror(YYLTYPE *locp, const char *filename, void *yyscanner, %name-prefix "dmnsn_yy" -%expect 0 +%expect 1 %parse-param {const char *filename} %parse-param {void *yyscanner} @@ -638,14 +638,14 @@ yyerror(YYLTYPE *locp, const char *filename, void *yyscanner, %token DMNSN_T_IFDEF %token DMNSN_T_IFNDEF %token DMNSN_T_INCLUDE "#include" -%token DMNSN_T_LOCAL +%token DMNSN_T_LOCAL "#local" %token DMNSN_T_MACRO %token DMNSN_T_RANGE %token DMNSN_T_READ %token DMNSN_T_RENDER %token DMNSN_T_STATISTICS %token DMNSN_T_SWITCH -%token DMNSN_T_UNDEF +%token DMNSN_T_UNDEF "#undef" %token DMNSN_T_VERSION %token DMNSN_T_WARNING %token DMNSN_T_WHILE @@ -660,6 +660,10 @@ yyerror(YYLTYPE *locp, const char *filename, void *yyscanner, /* Top-level items */ %type <astnode> SCENE_ITEM +/* Language directives */ +%type <astnode> RVALUE +%type <astnode> IDENTIFIER + /* Transformations */ %type <astnode> TRANSFORMATION @@ -696,14 +700,15 @@ yyerror(YYLTYPE *locp, const char *filename, void *yyscanner, /* Floats */ %type <astnode> FLOAT -%type <astnode> FLOAT_EXPR %type <astnode> FLOAT_LITERAL /* Vectors */ %type <astnode> VECTOR -%type <astnode> VECTOR_EXPR %type <astnode> VECTOR_LITERAL +/* Generalized arithmetic expressions */ +%type <astnode> ARITH_EXPR + /* Colors */ %type <astnode> COLOR %type <astnode> COLOR_BODY @@ -711,18 +716,60 @@ yyerror(YYLTYPE *locp, const char *filename, void *yyscanner, %type <astnode> COLOR_KEYWORD_GROUP %type <astnode> COLOR_KEYWORD_GROUP_INIT +%destructor { free($$); } <value> %destructor { dmnsn_delete_astnode($$); } <astnode> %% /* Start symbol */ -SCENE: /* empty */ { } +SCENE: /* empty */ + | SCENE LANGUAGE_DIRECTIVE | SCENE SCENE_ITEM { dmnsn_array_push(astree, &$2); } ; +/* Language directives */ + +LANGUAGE_DIRECTIVE: DECLARATION +; + +DECLARATION: "#declare" "identifier" "=" RVALUE { + dmnsn_declare_symbol(symtable, $2, $4); + free($2); + dmnsn_delete_astnode($4); + } + | "#local" "identifier" "=" RVALUE { + dmnsn_local_symbol(symtable, $2, $4); + free($2); + dmnsn_delete_astnode($4); + } + | "#undef" "identifier" { + dmnsn_undef_symbol(symtable, $2); + free($2); + } +; + +RVALUE: ARITH_EXPR ";" { + $$ = dmnsn_eval($1, symtable); + dmnsn_delete_astnode($1); + + if ($$.type == DMNSN_AST_NONE) { + dmnsn_delete_astnode($$); + YYERROR; + } + } + | COLOR ";" +; + +IDENTIFIER: "identifier" { + $$ = dmnsn_new_astnode(DMNSN_AST_IDENTIFIER, @$); + $$.ptr = $1; + } +; + +/* Top-level scene item */ SCENE_ITEM: ATMOSPHERIC_EFFECT | CAMERA | OBJECT @@ -758,14 +805,17 @@ CAMERA_ITEMS: /* empty */ { $$ = $1; dmnsn_array_push($$.children, &$2); } +; CAMERA_ITEM: CAMERA_TYPE | CAMERA_VECTOR | CAMERA_MODIFIER +; CAMERA_TYPE: "perspective" { $$ = dmnsn_new_astnode(DMNSN_AST_PERSPECTIVE, @$); } +; CAMERA_VECTOR: "location" VECTOR { $$ = dmnsn_new_astnode1(DMNSN_AST_LOCATION, @$, $2); @@ -782,6 +832,7 @@ CAMERA_VECTOR: "location" VECTOR { | "direction" VECTOR { $$ = dmnsn_new_astnode1(DMNSN_AST_DIRECTION, @$, $2); } +; CAMERA_MODIFIER: "angle" FLOAT { $$ = dmnsn_new_astnode1(DMNSN_AST_ANGLE, @$, $2); @@ -790,6 +841,7 @@ CAMERA_MODIFIER: "angle" FLOAT { $$ = dmnsn_new_astnode1(DMNSN_AST_LOOK_AT, @$, $2); } | TRANSFORMATION +; /* Atmospheric effects */ @@ -890,91 +942,15 @@ PIGMENT_TYPE: /* empty */ { /* Floats */ -FLOAT: FLOAT_EXPR { +FLOAT: ARITH_EXPR { $$ = dmnsn_eval_scalar($1, symtable); dmnsn_delete_astnode($1); - } -; - -FLOAT_EXPR: FLOAT_LITERAL - | FLOAT_EXPR "+" FLOAT_EXPR { - $$ = dmnsn_new_astnode2(DMNSN_AST_ADD, @$, $1, $3); - } - | FLOAT_EXPR "-" FLOAT_EXPR { - $$ = dmnsn_new_astnode2(DMNSN_AST_SUB, @$, $1, $3); - } - | FLOAT_EXPR "*" FLOAT_EXPR { - $$ = dmnsn_new_astnode2(DMNSN_AST_MUL, @$, $1, $3); - } - | FLOAT_EXPR "/" FLOAT_EXPR { - $$ = dmnsn_new_astnode2(DMNSN_AST_DIV, @$, $1, $3); - } - | "+" FLOAT_EXPR %prec DMNSN_T_NEGATE { $$ = $2; } - | "-" FLOAT_EXPR %prec DMNSN_T_NEGATE { - $$ = dmnsn_new_astnode1(DMNSN_AST_NEGATE, @$, $2); - } - - | VECTOR_EXPR "." "x" { - dmnsn_array_get($1.children, 0, &$$); - dmnsn_array_remove($1.children, 0); - dmnsn_delete_astnode($1); - } - | VECTOR_EXPR "." "u" { - dmnsn_array_get($1.children, 0, &$$); - dmnsn_array_remove($1.children, 0); - dmnsn_delete_astnode($1); - } - | VECTOR_EXPR "." "red" { - dmnsn_array_get($1.children, 0, &$$); - dmnsn_array_remove($1.children, 0); - dmnsn_delete_astnode($1); - } - - | VECTOR_EXPR "." "y" { - dmnsn_array_get($1.children, 1, &$$); - dmnsn_array_remove($1.children, 1); - dmnsn_delete_astnode($1); - } - | VECTOR_EXPR "." "v" { - dmnsn_array_get($1.children, 1, &$$); - dmnsn_array_remove($1.children, 1); - dmnsn_delete_astnode($1); - } - | VECTOR_EXPR "." "green" { - dmnsn_array_get($1.children, 1, &$$); - dmnsn_array_remove($1.children, 1); - dmnsn_delete_astnode($1); - } - - | VECTOR_EXPR "." "z" { - dmnsn_array_get($1.children, 2, &$$); - dmnsn_array_remove($1.children, 2); - dmnsn_delete_astnode($1); - } - | VECTOR_EXPR "." "blue" { - dmnsn_array_get($1.children, 2, &$$); - dmnsn_array_remove($1.children, 2); - dmnsn_delete_astnode($1); - } - - | VECTOR_EXPR "." "t" { - dmnsn_array_get($1.children, 3, &$$); - dmnsn_array_remove($1.children, 3); - dmnsn_delete_astnode($1); - } - | VECTOR_EXPR "." "filter" { - dmnsn_array_get($1.children, 3, &$$); - dmnsn_array_remove($1.children, 3); - dmnsn_delete_astnode($1); - } - - | VECTOR_EXPR "." "transmit" { - dmnsn_array_get($1.children, 4, &$$); - dmnsn_array_remove($1.children, 4); - dmnsn_delete_astnode($1); - } - | "(" FLOAT_EXPR ")" { $$ = $2; } + if ($$.type == DMNSN_AST_NONE) { + dmnsn_delete_astnode($$); + YYERROR; + } + } ; FLOAT_LITERAL: "integer" { @@ -1001,56 +977,93 @@ FLOAT_LITERAL: "integer" { /* Vectors */ -VECTOR: VECTOR_EXPR { +VECTOR: ARITH_EXPR { $$ = dmnsn_eval_vector($1, symtable); dmnsn_delete_astnode($1); - } - | FLOAT_EXPR { - $$ = dmnsn_eval_vector($1, symtable); - dmnsn_delete_astnode($1); - } -; -VECTOR_EXPR: VECTOR_LITERAL - | VECTOR_EXPR "+" VECTOR_EXPR { - $$ = dmnsn_new_astnode2(DMNSN_AST_ADD, @$, $1, $3); - } - | VECTOR_EXPR "-" VECTOR_EXPR { - $$ = dmnsn_new_astnode2(DMNSN_AST_SUB, @$, $1, $3); - } - | VECTOR_EXPR "*" FLOAT_EXPR { - $$ = dmnsn_new_astnode2(DMNSN_AST_MUL, @$, $1, $3); - } - | FLOAT_EXPR "*" VECTOR_EXPR { - $$ = dmnsn_new_astnode2(DMNSN_AST_MUL, @$, $1, $3); - } - | VECTOR_EXPR "/" FLOAT_EXPR { - $$ = dmnsn_new_astnode2(DMNSN_AST_DIV, @$, $1, $3); - } - | "+" VECTOR_EXPR %prec DMNSN_T_NEGATE { $$ = $2; } - | "-" VECTOR_EXPR %prec DMNSN_T_NEGATE { - $$ = dmnsn_new_astnode1(DMNSN_AST_NEGATE, @$, $2); - } - | "(" VECTOR_EXPR ")" { $$ = $2; } + if ($$.type == DMNSN_AST_NONE) { + dmnsn_delete_astnode($$); + YYERROR; + } + } ; -VECTOR_LITERAL: "<" FLOAT_EXPR "," FLOAT_EXPR ">" { +VECTOR_LITERAL: "<" ARITH_EXPR "," ARITH_EXPR ">" { $$ = dmnsn_new_astnode2(DMNSN_AST_VECTOR, @$, $2, $4); } - | "<" FLOAT_EXPR "," FLOAT_EXPR "," FLOAT_EXPR ">" { + | "<" ARITH_EXPR "," ARITH_EXPR "," ARITH_EXPR ">" { $$ = dmnsn_new_astnode3(DMNSN_AST_VECTOR, @$, $2, $4, $6); } - | "<" FLOAT_EXPR "," FLOAT_EXPR "," FLOAT_EXPR "," - FLOAT_EXPR ">" { + | "<" ARITH_EXPR "," ARITH_EXPR "," ARITH_EXPR "," + ARITH_EXPR ">" { $$ = dmnsn_new_astnode4(DMNSN_AST_VECTOR, @$, $2, $4, $6, $8); } - | "<" FLOAT_EXPR "," FLOAT_EXPR "," FLOAT_EXPR "," - FLOAT_EXPR "," FLOAT_EXPR ">" { + | "<" ARITH_EXPR "," ARITH_EXPR "," ARITH_EXPR "," + ARITH_EXPR "," ARITH_EXPR ">" { $$ = dmnsn_new_astnode5(DMNSN_AST_VECTOR, @$, $2, $4, $6, $8, $10); } ; +/* Generalized arithmetic expressions */ + +ARITH_EXPR: FLOAT_LITERAL + | VECTOR_LITERAL + | ARITH_EXPR "+" ARITH_EXPR { + $$ = dmnsn_new_astnode2(DMNSN_AST_ADD, @$, $1, $3); + } + | ARITH_EXPR "-" ARITH_EXPR { + $$ = dmnsn_new_astnode2(DMNSN_AST_SUB, @$, $1, $3); + } + | ARITH_EXPR "*" ARITH_EXPR { + $$ = dmnsn_new_astnode2(DMNSN_AST_MUL, @$, $1, $3); + } + | ARITH_EXPR "/" ARITH_EXPR { + $$ = dmnsn_new_astnode2(DMNSN_AST_DIV, @$, $1, $3); + } + | "+" ARITH_EXPR %prec DMNSN_T_NEGATE { $$ = $2; } + | "-" ARITH_EXPR %prec DMNSN_T_NEGATE { + $$ = dmnsn_new_astnode1(DMNSN_AST_NEGATE, @$, $2); + } + | ARITH_EXPR "." "x" { + $$ = dmnsn_new_astnode1(DMNSN_AST_DOT_X, @$, $1); + } + | ARITH_EXPR "." "u" { + $$ = dmnsn_new_astnode1(DMNSN_AST_DOT_X, @$, $1); + } + | ARITH_EXPR "." "red" { + $$ = dmnsn_new_astnode1(DMNSN_AST_DOT_X, @$, $1); + } + | ARITH_EXPR "." "y" { + $$ = dmnsn_new_astnode1(DMNSN_AST_DOT_Y, @$, $1); + } + | ARITH_EXPR "." "v" { + $$ = dmnsn_new_astnode1(DMNSN_AST_DOT_Y, @$, $1); + } + | ARITH_EXPR "." "green" { + $$ = dmnsn_new_astnode1(DMNSN_AST_DOT_Y, @$, $1); + } + | ARITH_EXPR "." "z" { + $$ = dmnsn_new_astnode1(DMNSN_AST_DOT_Z, @$, $1); + } + | ARITH_EXPR "." "blue" { + $$ = dmnsn_new_astnode1(DMNSN_AST_DOT_Z, @$, $1); + } + | ARITH_EXPR "." "t" { + $$ = dmnsn_new_astnode1(DMNSN_AST_DOT_T, @$, $1); + } + | ARITH_EXPR "." "filter" { + $$ = dmnsn_new_astnode1(DMNSN_AST_DOT_T, @$, $1); + } + | ARITH_EXPR "." "transmit" { + $$ = dmnsn_new_astnode1(DMNSN_AST_DOT_TRANSMIT, @$, $1); + } + | "(" ARITH_EXPR ")" { $$ = $2; } + | IDENTIFIER +; + +/* Colors */ + COLOR: COLOR_BODY | "color" COLOR_BODY { $$ = $2; } ; @@ -1145,7 +1158,7 @@ dmnsn_parse(FILE *file, dmnsn_symbol_table *symtable) if (yyparse(filename, scanner, astree, symtable) != 0) { dmnsn_delete_astree(astree); - return NULL; + astree = NULL; } dmnsn_yylex_destroy(scanner); @@ -1219,12 +1232,20 @@ dmnsn_astnode_string(dmnsn_astnode_type astnode_type) dmnsn_astnode_map(DMNSN_AST_VECTOR, "vector"); - dmnsn_astnode_map(DMNSN_AST_NEGATE, "-"); dmnsn_astnode_map(DMNSN_AST_ADD, "+"); dmnsn_astnode_map(DMNSN_AST_SUB, "-"); dmnsn_astnode_map(DMNSN_AST_MUL, "*"); dmnsn_astnode_map(DMNSN_AST_DIV, "/"); + dmnsn_astnode_map(DMNSN_AST_NEGATE, "-"); + dmnsn_astnode_map(DMNSN_AST_DOT_X, ".x"); + dmnsn_astnode_map(DMNSN_AST_DOT_Y, ".y"); + dmnsn_astnode_map(DMNSN_AST_DOT_Z, ".z"); + dmnsn_astnode_map(DMNSN_AST_DOT_T, ".t"); + dmnsn_astnode_map(DMNSN_AST_DOT_TRANSMIT, ".transmit"); + + dmnsn_astnode_map(DMNSN_AST_IDENTIFIER, "identifier"); + dmnsn_astnode_map(DMNSN_AST_STRING, "string"); default: |