diff options
author | Tavian Barnes <tavianator@gmail.com> | 2010-03-20 15:55:52 -0400 |
---|---|---|
committer | Tavian Barnes <tavianator@gmail.com> | 2010-03-20 15:55:52 -0400 |
commit | ac3e97014885af00b5a2eb01df232221482db023 (patch) | |
tree | 39163e9eed2427580260d0097b1c7887bcc536a5 | |
parent | 5da32d0dce6b8ade0b636b83f67b6244e6a56494 (diff) | |
download | dimension-ac3e97014885af00b5a2eb01df232221482db023.tar.xz |
Support max() and min().
-rw-r--r-- | dimension/common.nonterminals | 2 | ||||
-rw-r--r-- | dimension/common.rules | 22 | ||||
-rw-r--r-- | dimension/common.terminals | 4 | ||||
-rw-r--r-- | dimension/grammar.epilogue | 2 | ||||
-rw-r--r-- | dimension/lexer.l | 2 | ||||
-rw-r--r-- | dimension/parse.c | 38 | ||||
-rw-r--r-- | dimension/parse.h | 2 | ||||
-rw-r--r-- | tests/dimension/arithexp.pov | 8 |
8 files changed, 78 insertions, 2 deletions
diff --git a/dimension/common.nonterminals b/dimension/common.nonterminals index c3b2b3f..2008290 100644 --- a/dimension/common.nonterminals +++ b/dimension/common.nonterminals @@ -73,6 +73,8 @@ /* Generalized arithmetic expressions */ %type <astnode> ARITH_EXPR +%type <astnode> MAX_LIST +%type <astnode> MIN_LIST /* Colors */ %type <astnode> COLOR diff --git a/dimension/common.rules b/dimension/common.rules index e5b9e67..c8e0767 100644 --- a/dimension/common.rules +++ b/dimension/common.rules @@ -453,6 +453,12 @@ ARITH_EXPR: FLOAT_LITERAL | "log" "(" ARITH_EXPR ")" { $$ = dmnsn_new_astnode1(DMNSN_AST_LOG, @$, $3); } + | "max" "(" MAX_LIST ")" { + $$ = $3; + } + | "min" "(" MIN_LIST ")" { + $$ = $3; + } | "mod" "(" ARITH_EXPR "," ARITH_EXPR ")" { $$ = dmnsn_new_astnode2(DMNSN_AST_MOD, @$, $3, $5); } @@ -501,6 +507,22 @@ ARITH_EXPR: FLOAT_LITERAL | "t" { $$ = dmnsn_new_ast_ivector(0, 0, 0, 1, 0); } ; +MAX_LIST: ARITH_EXPR "," ARITH_EXPR { + $$ = dmnsn_new_astnode2(DMNSN_AST_MAX, @$, $1, $3); + } + | MAX_LIST "," ARITH_EXPR { + $$ = dmnsn_new_astnode2(DMNSN_AST_MAX, @$, $1, $3); + } +; + +MIN_LIST: ARITH_EXPR "," ARITH_EXPR { + $$ = dmnsn_new_astnode2(DMNSN_AST_MIN, @$, $1, $3); + } + | MIN_LIST "," ARITH_EXPR { + $$ = dmnsn_new_astnode2(DMNSN_AST_MIN, @$, $1, $3); + } +; + /* Colors */ COLOR: COLOR_BODY { diff --git a/dimension/common.terminals b/dimension/common.terminals index a877ac1..b5308e4 100644 --- a/dimension/common.terminals +++ b/dimension/common.terminals @@ -270,7 +270,7 @@ %token DMNSN_T_MATERIAL %token DMNSN_T_MATERIAL_MAP %token DMNSN_T_MATRIX -%token DMNSN_T_MAX +%token DMNSN_T_MAX "max" %token DMNSN_T_MAX_EXTENT %token DMNSN_T_MAX_GRADIENT %token DMNSN_T_MAX_INTERSECTIONS @@ -287,7 +287,7 @@ %token DMNSN_T_METALLIC %token DMNSN_T_METHOD %token DMNSN_T_METRIC -%token DMNSN_T_MIN +%token DMNSN_T_MIN "min" %token DMNSN_T_MIN_EXTENT %token DMNSN_T_MINIMUM_REUSE %token DMNSN_T_MOD "mod" diff --git a/dimension/grammar.epilogue b/dimension/grammar.epilogue index 05e9741..6a4a85f 100644 --- a/dimension/grammar.epilogue +++ b/dimension/grammar.epilogue @@ -197,6 +197,8 @@ dmnsn_astnode_string(dmnsn_astnode_type astnode_type) dmnsn_astnode_map(DMNSN_AST_INT, "int" ); dmnsn_astnode_map(DMNSN_AST_LN, "ln" ); dmnsn_astnode_map(DMNSN_AST_LOG, "log" ); + dmnsn_astnode_map(DMNSN_AST_MAX, "max" ); + dmnsn_astnode_map(DMNSN_AST_MIN, "min" ); dmnsn_astnode_map(DMNSN_AST_MOD, "mod" ); dmnsn_astnode_map(DMNSN_AST_POW, "pow" ); dmnsn_astnode_map(DMNSN_AST_RADIANS, "radians"); diff --git a/dimension/lexer.l b/dimension/lexer.l index 79d0a51..a2cf342 100644 --- a/dimension/lexer.l +++ b/dimension/lexer.l @@ -214,7 +214,9 @@ unsigned long wchar; "log" RETURN_TOKEN(DMNSN_T_LOG); "look_at" RETURN_TOKEN(DMNSN_T_LOOK_AT); "light_source" RETURN_TOKEN(DMNSN_T_LIGHT_SOURCE); +"max" RETURN_TOKEN(DMNSN_T_MAX); "max_trace_level" RETURN_TOKEN(DMNSN_T_MAX_TRACE_LEVEL); +"min" RETURN_TOKEN(DMNSN_T_MIN); "mod" RETURN_TOKEN(DMNSN_T_MOD); "perspective" RETURN_TOKEN(DMNSN_T_PERSPECTIVE); "phong" RETURN_TOKEN(DMNSN_T_PHONG); diff --git a/dimension/parse.c b/dimension/parse.c index fb9de1c..177a96c 100644 --- a/dimension/parse.c +++ b/dimension/parse.c @@ -1184,6 +1184,12 @@ dmnsn_eval_binary(dmnsn_astnode astnode, dmnsn_symbol_table *symtable) case DMNSN_AST_INT_DIV: dmnsn_make_ast_integer(&ret, l/r); break; + case DMNSN_AST_MAX: + dmnsn_make_ast_integer(&ret, l > r ? l : r); + break; + case DMNSN_AST_MIN: + dmnsn_make_ast_integer(&ret, l < r ? l : r); + break; case DMNSN_AST_MOD: dmnsn_make_ast_float(&ret, fmod(l, r)); break; @@ -1287,6 +1293,36 @@ dmnsn_eval_binary(dmnsn_astnode astnode, dmnsn_symbol_table *symtable) case DMNSN_AST_INT_DIV: dmnsn_make_ast_float(&ret, trunc(l/r)); break; + case DMNSN_AST_MAX: + if (l > r) { + if (lhs.type == DMNSN_AST_INTEGER) { + dmnsn_make_ast_maybe_integer(&ret, l); + } else { + dmnsn_make_ast_float(&ret, l); + } + } else { + if (rhs.type == DMNSN_AST_INTEGER) { + dmnsn_make_ast_maybe_integer(&ret, r); + } else { + dmnsn_make_ast_float(&ret, r); + } + } + break; + case DMNSN_AST_MIN: + if (l < r) { + if (lhs.type == DMNSN_AST_INTEGER) { + dmnsn_make_ast_maybe_integer(&ret, l); + } else { + dmnsn_make_ast_float(&ret, l); + } + } else { + if (rhs.type == DMNSN_AST_INTEGER) { + dmnsn_make_ast_maybe_integer(&ret, r); + } else { + dmnsn_make_ast_float(&ret, r); + } + } + break; case DMNSN_AST_MOD: dmnsn_make_ast_float(&ret, fmod(l, r)); break; @@ -1395,6 +1431,8 @@ dmnsn_eval(dmnsn_astnode astnode, dmnsn_symbol_table *symtable) case DMNSN_AST_OR: case DMNSN_AST_ATAN2: case DMNSN_AST_INT_DIV: + case DMNSN_AST_MAX: + case DMNSN_AST_MIN: case DMNSN_AST_MOD: case DMNSN_AST_POW: case DMNSN_AST_STRCMP: diff --git a/dimension/parse.h b/dimension/parse.h index 4648c87..ddd5e7a 100644 --- a/dimension/parse.h +++ b/dimension/parse.h @@ -109,6 +109,8 @@ typedef enum { DMNSN_AST_INT, DMNSN_AST_LN, DMNSN_AST_LOG, + DMNSN_AST_MAX, + DMNSN_AST_MIN, DMNSN_AST_MOD, DMNSN_AST_POW, DMNSN_AST_RADIANS, diff --git a/tests/dimension/arithexp.pov b/tests/dimension/arithexp.pov index c891b1c..d25be7d 100644 --- a/tests/dimension/arithexp.pov +++ b/tests/dimension/arithexp.pov @@ -100,6 +100,14 @@ sphere { #error "log" #end +#if (max(-1.5, 0, 1) != 1) + #error "max" +#end + +#if (min(-1.5, 0, 1) != -1.5) + #error "min" +#end + #if (mod(3.5, 2) != 1.5) #error "mod" #end |