summaryrefslogtreecommitdiffstats
path: root/dimension/directives.rules
diff options
context:
space:
mode:
authorTavian Barnes <tavianator@gmail.com>2010-02-02 12:03:26 -0500
committerTavian Barnes <tavianator@gmail.com>2010-02-02 12:03:26 -0500
commit3da1fe6d2fb07f3f361482d8056e36636dcec3f5 (patch)
tree54ee1eaf680f7a97820f4a150f7d9679f3345d8b /dimension/directives.rules
parentc1f6c955de83cf35fb34cc1fcf9a276bf6dbd7c8 (diff)
downloaddimension-3da1fe6d2fb07f3f361482d8056e36636dcec3f5.tar.xz
Implement #if.
Diffstat (limited to 'dimension/directives.rules')
-rw-r--r--dimension/directives.rules51
1 files changed, 51 insertions, 0 deletions
diff --git a/dimension/directives.rules b/dimension/directives.rules
index 916039b..db47bb9 100644
--- a/dimension/directives.rules
+++ b/dimension/directives.rules
@@ -16,6 +16,18 @@ LANGUAGE_DIRECTIVE: "#declare" "identifier" "=" RVALUE {
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);
@@ -33,3 +45,42 @@ RVALUE: ARITH_EXPR ";" %dprec 2 {
| 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;
+ }