From ac3e97014885af00b5a2eb01df232221482db023 Mon Sep 17 00:00:00 2001 From: Tavian Barnes Date: Sat, 20 Mar 2010 15:55:52 -0400 Subject: Support max() and min(). --- dimension/common.nonterminals | 2 ++ dimension/common.rules | 22 ++++++++++++++++++++++ dimension/common.terminals | 4 ++-- dimension/grammar.epilogue | 2 ++ dimension/lexer.l | 2 ++ dimension/parse.c | 38 ++++++++++++++++++++++++++++++++++++++ dimension/parse.h | 2 ++ 7 files changed, 70 insertions(+), 2 deletions(-) (limited to 'dimension') 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 ARITH_EXPR +%type MAX_LIST +%type MIN_LIST /* Colors */ %type 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, -- cgit v1.2.3