/* * Start symbol */ LANGUAGE_DIRECTIVE: "#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); } | "#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); } 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 | CAMERA | TRANSFORMATION CONDITIONAL: ARITH_EXPR { /* Force the expression to be evaluated logically */ dmnsn_astnode zero = dmnsn_new_astnode(DMNSN_AST_INTEGER, @$); zero.ptr = malloc(sizeof(long)); if (!zero.ptr) dmnsn_error(DMNSN_SEVERITY_HIGH, "Failed to allocate room for integer."); *(long *)zero.ptr = 0; $$ = dmnsn_new_astnode2(DMNSN_AST_OR, @$, zero, $1); } | ARITH_EXPR "=" ARITH_EXPR { $$ = dmnsn_new_astnode2(DMNSN_AST_EQUAL, @$, $1, $3); } | ARITH_EXPR "!=" ARITH_EXPR { $$ = dmnsn_new_astnode2(DMNSN_AST_NOT_EQUAL, @$, $1, $3); } | ARITH_EXPR "<" ARITH_EXPR { $$ = dmnsn_new_astnode2(DMNSN_AST_LESS, @$, $1, $3); } | ARITH_EXPR "<=" ARITH_EXPR { $$ = dmnsn_new_astnode2(DMNSN_AST_LESS_EQUAL, @$, $1, $3); } | ARITH_EXPR ">" ARITH_EXPR { $$ = dmnsn_new_astnode2(DMNSN_AST_GREATER, @$, $1, $3); } | ARITH_EXPR ">=" ARITH_EXPR { $$ = dmnsn_new_astnode2(DMNSN_AST_GREATER_EQUAL, @$, $1, $3); } | CONDITIONAL "&" CONDITIONAL { $$ = dmnsn_new_astnode2(DMNSN_AST_AND, @$, $1, $3); } | CONDITIONAL "|" CONDITIONAL { $$ = dmnsn_new_astnode2(DMNSN_AST_OR, @$, $1, $3); } | "(" CONDITIONAL ")" { $$ = $2; }