#line 2 "directives.rules" /* * Start symbol */ LANGUAGE_DIRECTIVE: "#include" STRING { dmnsn_declare_symbol(symtable, "$include", $2); dmnsn_delete_astnode($2); } | "#declare" IDENTIFIER "=" RVALUE { dmnsn_declare_symbol(symtable, $2.ptr, $4); dmnsn_delete_astnode($2); dmnsn_delete_astnode($4); } | "#local" IDENTIFIER "=" RVALUE { dmnsn_local_symbol(symtable, $2.ptr, $4); dmnsn_delete_astnode($2); dmnsn_delete_astnode($4); } | "#undef" IDENTIFIER { dmnsn_undef_symbol(symtable, $2.ptr); dmnsn_delete_astnode($2); } | "#if" "(" CONDITIONAL ")" { dmnsn_astnode cond = dmnsn_eval($3, symtable); dmnsn_delete_astnode($3); if (cond.type == DMNSN_AST_NONE) { dmnsn_delete_astnode(cond); YYERROR; } dmnsn_local_symbol(symtable, "$cond", cond); dmnsn_delete_astnode(cond); } | "#ifdef" "(" IDENTIFIER ")" { dmnsn_astnode *node = dmnsn_find_symbol(symtable, $3.ptr); dmnsn_local_symbol(symtable, "$cond", dmnsn_new_ast_integer(node ? 1 : 0)); dmnsn_delete_astnode($3); } | "#ifndef" "(" IDENTIFIER ")" { dmnsn_astnode *node = dmnsn_find_symbol(symtable, $3.ptr); dmnsn_local_symbol(symtable, "$cond", dmnsn_new_ast_integer(node ? 0 : 1)); dmnsn_delete_astnode($3); } | "#version" FLOAT ";" { dmnsn_diagnostic(@$, "WARNING: POV-Ray #version backwards-" "compatibility not supported"); dmnsn_delete_astnode($2); } | "#debug" STRING { fprintf(stderr, "%s\n", (const char *)$2.ptr); dmnsn_delete_astnode($2); } | "#warning" STRING { dmnsn_diagnostic(@$, "WARNING: %s", (const char *)$2.ptr); dmnsn_delete_astnode($2); } | "#error" STRING { dmnsn_diagnostic(@$, "%s", (const char *)$2.ptr); dmnsn_delete_astnode($2); YYERROR; } | "#macro" IDENTIFIER "(" DECL_PARAMS ")" { dmnsn_declare_symbol(symtable, $2.ptr, $4); dmnsn_local_symbol(symtable, "$macro", dmnsn_new_ast_string($2.ptr)); dmnsn_delete_astnode($2); dmnsn_delete_astnode($4); } | IDENTIFIER "(" PARAMS ")" { dmnsn_astnode *node = dmnsn_find_symbol(symtable, $1.ptr); dmnsn_assert(node && node->type == DMNSN_AST_MACRO, "Attempt to expand non-macro."); dmnsn_delete_astnode($1); size_t nparams = dmnsn_array_size(node->children); size_t nparams_given = dmnsn_array_size($3.children); if (nparams_given != nparams) { dmnsn_diagnostic(@$, "wrong number of macro arguments" " (%zu; should be %zu)", nparams_given, nparams); dmnsn_delete_astnode($3); YYERROR; } for (size_t i = 0; i < nparams; ++i) { dmnsn_astnode id, param; dmnsn_array_get(node->children, i, &id); dmnsn_array_get($3.children, i, ¶m); dmnsn_local_symbol(symtable, id.ptr, param); } dmnsn_delete_astnode($3); } ; RVALUE: ARITH_EXPR ";" %dprec 2 { $$ = dmnsn_eval($1, symtable); dmnsn_delete_astnode($1); if ($$.type == DMNSN_AST_NONE) { dmnsn_delete_astnode($$); YYERROR; } } | COLOR ";" %dprec 1 | OBJECT | TEXTURE | PIGMENT | FINISH | INTERIOR | CAMERA | "transform" "{" TRANSFORMATION_ITEMS "}" { $$ = $3; } ; DECL_PARAMS: /* empty */ { $$ = dmnsn_new_astnode(DMNSN_AST_MACRO, @$); } | DECL_PARAM_LIST ; DECL_PARAM_LIST: IDENTIFIER { $$ = dmnsn_new_astnode1(DMNSN_AST_MACRO, @$, $1); } | DECL_PARAM_LIST "," IDENTIFIER { $$ = $1; dmnsn_array_push($$.children, &$3); } ; PARAMS: /* empty */ { $$ = dmnsn_new_astnode(DMNSN_AST_ARRAY, @$); } | PARAM_LIST ; PARAM_LIST: IDENTIFIER %dprec 2 { $$ = dmnsn_new_astnode1(DMNSN_AST_MACRO, @$, $1); } | PARAM %dprec 1 { $$ = dmnsn_new_astnode1(DMNSN_AST_MACRO, @$, $1); } | PARAM_LIST "," IDENTIFIER %dprec 2 { $$ = $1; dmnsn_array_push($$.children, &$3); } | PARAM_LIST "," PARAM %dprec 1 { $$ = $1; dmnsn_array_push($$.children, &$3); } ; PARAM: ARITH_EXPR %dprec 2 { $$ = dmnsn_eval($1, symtable); dmnsn_delete_astnode($1); if ($$.type == DMNSN_AST_NONE) { dmnsn_delete_astnode($$); YYERROR; } } | COLOR %dprec 1 | OBJECT | TEXTURE | PIGMENT | FINISH | INTERIOR | CAMERA | TRANSFORMATION ;