summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--dimension/common.terminals1
-rw-r--r--dimension/directives.rules3
-rw-r--r--dimension/grammar.epilogue1
-rw-r--r--dimension/parse.c9
-rw-r--r--dimension/parse.h1
-rw-r--r--tests/dimension/directives.pov2
-rwxr-xr-xtests/dimension/directives.sh2
7 files changed, 17 insertions, 2 deletions
diff --git a/dimension/common.terminals b/dimension/common.terminals
index b5308e4..b72e836 100644
--- a/dimension/common.terminals
+++ b/dimension/common.terminals
@@ -51,6 +51,7 @@
/* Operators */
%left "|"
%left "&"
+%left "!"
%left "=" "!=" "<" "<=" ">" ">="
%left "+" "-"
%left "*" "/"
diff --git a/dimension/directives.rules b/dimension/directives.rules
index f3f3e7a..a01ab9a 100644
--- a/dimension/directives.rules
+++ b/dimension/directives.rules
@@ -121,3 +121,6 @@ CONDITIONAL: ARITH_EXPR {
| "(" CONDITIONAL ")" {
$$ = $2;
}
+ | "!" CONDITIONAL {
+ $$ = dmnsn_new_astnode1(DMNSN_AST_NOT, @$, $2);
+ }
diff --git a/dimension/grammar.epilogue b/dimension/grammar.epilogue
index 6a4a85f..23e8504 100644
--- a/dimension/grammar.epilogue
+++ b/dimension/grammar.epilogue
@@ -177,6 +177,7 @@ dmnsn_astnode_string(dmnsn_astnode_type astnode_type)
dmnsn_astnode_map(DMNSN_AST_GREATER_EQUAL, ">=");
dmnsn_astnode_map(DMNSN_AST_AND, "&" );
dmnsn_astnode_map(DMNSN_AST_OR, "|" );
+ dmnsn_astnode_map(DMNSN_AST_NOT, "!" );
dmnsn_astnode_map(DMNSN_AST_ABS, "abs" );
dmnsn_astnode_map(DMNSN_AST_ACOS, "acos" );
diff --git a/dimension/parse.c b/dimension/parse.c
index 177a96c..6de30c9 100644
--- a/dimension/parse.c
+++ b/dimension/parse.c
@@ -660,6 +660,10 @@ dmnsn_eval_unary(dmnsn_astnode astnode, dmnsn_symbol_table *symtable)
dmnsn_make_ast_integer(&ret, -n);
break;
+ case DMNSN_AST_NOT:
+ dmnsn_make_ast_integer(&ret, !n);
+ break;
+
case DMNSN_AST_ABS:
dmnsn_make_ast_integer(&ret, labs(n));
break;
@@ -755,6 +759,10 @@ dmnsn_eval_unary(dmnsn_astnode astnode, dmnsn_symbol_table *symtable)
dmnsn_make_ast_float(&ret, -n);
break;
+ case DMNSN_AST_NOT:
+ dmnsn_make_ast_integer(&ret, !n);
+ break;
+
case DMNSN_AST_ABS:
dmnsn_make_ast_float(&ret, fabs(n));
break;
@@ -1389,6 +1397,7 @@ dmnsn_eval(dmnsn_astnode astnode, dmnsn_symbol_table *symtable)
case DMNSN_AST_DOT_T:
case DMNSN_AST_DOT_TRANSMIT:
case DMNSN_AST_NEGATE:
+ case DMNSN_AST_NOT:
case DMNSN_AST_ABS:
case DMNSN_AST_ACOS:
case DMNSN_AST_ACOSH:
diff --git a/dimension/parse.h b/dimension/parse.h
index ddd5e7a..2b5ecb7 100644
--- a/dimension/parse.h
+++ b/dimension/parse.h
@@ -133,6 +133,7 @@ typedef enum {
DMNSN_AST_GREATER_EQUAL,
DMNSN_AST_AND,
DMNSN_AST_OR,
+ DMNSN_AST_NOT,
DMNSN_AST_IDENTIFIER,
diff --git a/tests/dimension/directives.pov b/tests/dimension/directives.pov
index 5137cd2..416bbf5 100644
--- a/tests/dimension/directives.pov
+++ b/tests/dimension/directives.pov
@@ -42,7 +42,7 @@
#declare Counter = 0;
#while (Counter < 2)
- #if (#if (1 = 1) 0 #end = 0 & 0)
+ #if (#if (1 = 1) 0 #end = 0 & !1)
#error "Nested #if parsing failed"
#else
sphere {
diff --git a/tests/dimension/directives.sh b/tests/dimension/directives.sh
index 74bde02..42815a6 100755
--- a/tests/dimension/directives.sh
+++ b/tests/dimension/directives.sh
@@ -37,7 +37,7 @@ directives_exp="$(echo -n \
#end
#declare (identifier "Counter") = (integer "0") ;
#while \( (identifier "Counter") < (integer "2") \)
- #if \( #if \( (integer "1") = (integer "1") \) (integer "0") #end = (integer "0") & (integer "0") \)
+ #if \( #if \( (integer "1") = (integer "1") \) (integer "0") #end = (integer "0") & ! (integer "1") \)
#error (string "Nested #if parsing failed")
#else
sphere {