From bb71a70253ae5bf91e99dcd2809471abebea1b69 Mon Sep 17 00:00:00 2001 From: Tavian Barnes Date: Mon, 22 Mar 2010 13:19:45 -0400 Subject: Support logical ! operator. --- dimension/common.terminals | 1 + dimension/directives.rules | 3 +++ dimension/grammar.epilogue | 1 + dimension/parse.c | 9 +++++++++ dimension/parse.h | 1 + tests/dimension/directives.pov | 2 +- tests/dimension/directives.sh | 2 +- 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 { -- cgit v1.2.3