summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTavian Barnes <tavianator@gmail.com>2010-02-02 22:45:20 -0500
committerTavian Barnes <tavianator@gmail.com>2010-02-02 22:49:26 -0500
commit3f660a9b219b03bd5188cd4f0da9a58f507a933a (patch)
tree57162550b6c390cb0bf1ab143cee5bebda3a6ed8
parent80555a542f522d70fd0cb98227db005805f0c184 (diff)
downloaddimension-3f660a9b219b03bd5188cd4f0da9a58f507a933a.tar.xz
Support #ifdef and #ifndef.
-rw-r--r--dimension/common.terminals4
-rw-r--r--dimension/directives.rules12
-rw-r--r--dimension/lexer.l2
-rw-r--r--dimension/tokenize.c4
-rw-r--r--tests/dimension/directives.pov4
-rwxr-xr-xtests/dimension/directives.sh3
6 files changed, 26 insertions, 3 deletions
diff --git a/dimension/common.terminals b/dimension/common.terminals
index c2ad2b4..86205b5 100644
--- a/dimension/common.terminals
+++ b/dimension/common.terminals
@@ -502,8 +502,8 @@
%token DMNSN_T_FCLOSE
%token DMNSN_T_FOPEN
%token DMNSN_T_IF "#if"
-%token DMNSN_T_IFDEF
-%token DMNSN_T_IFNDEF
+%token DMNSN_T_IFDEF "#ifdef"
+%token DMNSN_T_IFNDEF "#ifndef"
%token DMNSN_T_INCLUDE "#include"
%token DMNSN_T_LOCAL "#local"
%token DMNSN_T_MACRO
diff --git a/dimension/directives.rules b/dimension/directives.rules
index 392408d..5a30455 100644
--- a/dimension/directives.rules
+++ b/dimension/directives.rules
@@ -30,6 +30,18 @@ LANGUAGE_DIRECTIVE: "#declare" "identifier" "=" RVALUE {
dmnsn_local_symbol(symtable, "__cond__", cond);
dmnsn_delete_astnode(cond);
}
+ | "#ifdef" "(" "identifier" ")" {
+ dmnsn_astnode *node = dmnsn_find_symbol(symtable, $3);
+ dmnsn_local_symbol(symtable, "__cond__",
+ dmnsn_new_ast_integer(node ? 1 : 0));
+ free($3);
+ }
+ | "#ifndef" "(" "identifier" ")" {
+ dmnsn_astnode *node = dmnsn_find_symbol(symtable, $3);
+ dmnsn_local_symbol(symtable, "__cond__",
+ dmnsn_new_ast_integer(node ? 0 : 1));
+ free($3);
+ }
RVALUE: ARITH_EXPR ";" %dprec 2 {
$$ = dmnsn_eval($1, symtable);
diff --git a/dimension/lexer.l b/dimension/lexer.l
index eb5184c..14096d1 100644
--- a/dimension/lexer.l
+++ b/dimension/lexer.l
@@ -211,6 +211,8 @@ unsigned long wchar;
"#else" RETURN_TOKEN(DMNSN_T_ELSE);
"#end" RETURN_TOKEN(DMNSN_T_END);
"#if" RETURN_TOKEN(DMNSN_T_IF);
+"#ifdef" RETURN_TOKEN(DMNSN_T_IFDEF);
+"#ifndef" RETURN_TOKEN(DMNSN_T_IFNDEF);
"#include" RETURN_TOKEN(DMNSN_T_INCLUDE);
"#local" RETURN_TOKEN(DMNSN_T_LOCAL);
"#undef" RETURN_TOKEN(DMNSN_T_UNDEF);
diff --git a/dimension/tokenize.c b/dimension/tokenize.c
index cc912b6..84d5f5d 100644
--- a/dimension/tokenize.c
+++ b/dimension/tokenize.c
@@ -233,7 +233,7 @@ dmnsn_if_buffer(int token, dmnsn_token_buffer *prev,
dmnsn_yyset_extra(cond_buffer->prev, yyscanner);
dmnsn_delete_token_buffer(cond_buffer);
- dmnsn_token_buffer *tbuffer= dmnsn_new_token_buffer(DMNSN_T_IF, prev);
+ dmnsn_token_buffer *tbuffer = dmnsn_new_token_buffer(token, prev);
dmnsn_astnode *cnode = dmnsn_find_symbol(symtable, "__cond__");
if (!cnode) {
@@ -398,6 +398,8 @@ dmnsn_yylex(dmnsn_parse_item *lvalp, dmnsn_parse_location *llocp,
}
case DMNSN_T_IF:
+ case DMNSN_T_IFDEF:
+ case DMNSN_T_IFNDEF:
{
dmnsn_token_buffer *tb = dmnsn_if_buffer(
token, tbuffer, lvalp, llocp, filename, symtable, yyscanner
diff --git a/tests/dimension/directives.pov b/tests/dimension/directives.pov
index 187189f..94e613f 100644
--- a/tests/dimension/directives.pov
+++ b/tests/dimension/directives.pov
@@ -26,6 +26,10 @@
#declare Unused = -1;
#undef Unused
+#ifdef (Unused)
+ Illegal
+#end
+
#if (#if (1 = 1) 0 #end = 0 & 0)
`Illegal
#else
diff --git a/tests/dimension/directives.sh b/tests/dimension/directives.sh
index e24a62a..198e25b 100755
--- a/tests/dimension/directives.sh
+++ b/tests/dimension/directives.sh
@@ -26,6 +26,9 @@ directives_exp="$(echo -n \
#local (identifier "Color") = rgb < (integer "1") , (integer "0") , (integer "1") > ;
#declare (identifier "Unused") = - (integer "1") ;
#undef (identifier "Unused")
+ #ifdef \( (identifier "Unused") \)
+ (identifier "Illegal")
+ #end
#if \( #if \( (integer "1") = (integer "1") \) (integer "0") #end = (integer "0") & (integer "0") \)
error (identifier "Illegal")
#else