summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTavian Barnes <tavianator@gmail.com>2010-03-20 02:01:16 -0400
committerTavian Barnes <tavianator@gmail.com>2010-03-20 02:01:16 -0400
commit4566f4e34afaab1c47120e8a377859d88a142ffe (patch)
tree626541ad48efe078a4e6f86cf1af903d8225320b
parentfc06cb624d79788923ab2dedb3cd2ccab53cb2b4 (diff)
downloaddimension-4566f4e34afaab1c47120e8a377859d88a142ffe.tar.xz
A bunch more float functions.
-rw-r--r--dimension/common.rules45
-rw-r--r--dimension/common.terminals30
-rw-r--r--dimension/grammar.epilogue17
-rw-r--r--dimension/lexer.l17
-rw-r--r--dimension/parse.c157
-rw-r--r--dimension/parse.h15
-rw-r--r--tests/dimension/arithexp.pov64
-rwxr-xr-xtests/dimension/arithexp.sh13
8 files changed, 315 insertions, 43 deletions
diff --git a/dimension/common.rules b/dimension/common.rules
index bb03577..fb38039 100644
--- a/dimension/common.rules
+++ b/dimension/common.rules
@@ -396,9 +396,54 @@ ARITH_EXPR: FLOAT_LITERAL
$$ = dmnsn_new_astnode1(DMNSN_AST_DOT_TRANSMIT, @$, $1);
}
| "(" ARITH_EXPR ")" { $$ = $2; }
+ | "abs" "(" ARITH_EXPR ")" {
+ $$ = dmnsn_new_astnode1(DMNSN_AST_ABS, @$, $3);
+ }
+ | "acos" "(" ARITH_EXPR ")" {
+ $$ = dmnsn_new_astnode1(DMNSN_AST_ACOS, @$, $3);
+ }
+ | "acosh" "(" ARITH_EXPR ")" {
+ $$ = dmnsn_new_astnode1(DMNSN_AST_ACOSH, @$, $3);
+ }
+ | "asc" "(" STRING ")" {
+ $$ = dmnsn_new_astnode1(DMNSN_AST_ASC, @$, $3);
+ }
+ | "asin" "(" ARITH_EXPR ")" {
+ $$ = dmnsn_new_astnode1(DMNSN_AST_ASIN, @$, $3);
+ }
+ | "asinh" "(" ARITH_EXPR ")" {
+ $$ = dmnsn_new_astnode1(DMNSN_AST_ASINH, @$, $3);
+ }
+ | "atan" "(" ARITH_EXPR ")" {
+ $$ = dmnsn_new_astnode1(DMNSN_AST_ATAN, @$, $3);
+ }
+ | "atan2" "(" ARITH_EXPR "," ARITH_EXPR ")" {
+ $$ = dmnsn_new_astnode2(DMNSN_AST_ATAN2, @$, $3, $5);
+ }
+ | "atanh" "(" ARITH_EXPR ")" {
+ $$ = dmnsn_new_astnode1(DMNSN_AST_ATANH, @$, $3);
+ }
+ | "ceil" "(" ARITH_EXPR ")" {
+ $$ = dmnsn_new_astnode1(DMNSN_AST_CEIL, @$, $3);
+ }
+ | "cos" "(" ARITH_EXPR ")" {
+ $$ = dmnsn_new_astnode1(DMNSN_AST_COS, @$, $3);
+ }
+ | "cosh" "(" ARITH_EXPR ")" {
+ $$ = dmnsn_new_astnode1(DMNSN_AST_COSH, @$, $3);
+ }
+ | "degrees" "(" ARITH_EXPR ")" {
+ $$ = dmnsn_new_astnode1(DMNSN_AST_DEGREES, @$, $3);
+ }
+ | "div" "(" ARITH_EXPR "," ARITH_EXPR ")" {
+ $$ = dmnsn_new_astnode2(DMNSN_AST_INT_DIV, @$, $3, $5);
+ }
| "exp" "(" ARITH_EXPR ")" {
$$ = dmnsn_new_astnode1(DMNSN_AST_EXP, @$, $3);
}
+ | "floor" "(" ARITH_EXPR ")" {
+ $$ = dmnsn_new_astnode1(DMNSN_AST_FLOOR, @$, $3);
+ }
| IDENTIFIER
| "x" { $$ = dmnsn_new_ast_ivector(1, 0, 0, 0, 0); }
| "u" { $$ = dmnsn_new_ast_ivector(1, 0, 0, 0, 0); }
diff --git a/dimension/common.terminals b/dimension/common.terminals
index 02338c9..b468a69 100644
--- a/dimension/common.terminals
+++ b/dimension/common.terminals
@@ -64,11 +64,11 @@
/* Keywords */
%token DMNSN_T_AA_LEVEL
%token DMNSN_T_AA_THRESHOLD
-%token DMNSN_T_ABS
+%token DMNSN_T_ABS "abs"
%token DMNSN_T_ABSORPTION
%token DMNSN_T_ACCURACY
-%token DMNSN_T_ACOS
-%token DMNSN_T_ACOSH
+%token DMNSN_T_ACOS "acos"
+%token DMNSN_T_ACOSH "acosh"
%token DMNSN_T_ADAPTIVE
%token DMNSN_T_ADC_BAILOUT
%token DMNSN_T_AGATE
@@ -86,14 +86,14 @@
%token DMNSN_T_ARC_ANGLE
%token DMNSN_T_AREA_LIGHT
%token DMNSN_T_ARRAY
-%token DMNSN_T_ASC
+%token DMNSN_T_ASC "asc"
%token DMNSN_T_ASCII
-%token DMNSN_T_ASIN
-%token DMNSN_T_ASINH
+%token DMNSN_T_ASIN "asin"
+%token DMNSN_T_ASINH "asinh"
%token DMNSN_T_ASSUMED_GAMMA "assumed_gamma"
-%token DMNSN_T_ATAN
-%token DMNSN_T_ATAN2
-%token DMNSN_T_ATANH
+%token DMNSN_T_ATAN "atan"
+%token DMNSN_T_ATAN2 "atan2"
+%token DMNSN_T_ATANH "atanh"
%token DMNSN_T_AUTOSTOP
%token DMNSN_T_AVERAGE
%token DMNSN_T_B_SPLINE
@@ -117,7 +117,7 @@
%token DMNSN_T_BUMPS
%token DMNSN_T_CAMERA "camera"
%token DMNSN_T_CAUSTICS
-%token DMNSN_T_CEIL
+%token DMNSN_T_CEIL "ceil"
%token DMNSN_T_CELLS
%token DMNSN_T_CHARSET
%token DMNSN_T_CHECKER
@@ -141,8 +141,8 @@
%token DMNSN_T_CONTROL0
%token DMNSN_T_CONTROL1
%token DMNSN_T_COORDS
-%token DMNSN_T_COS
-%token DMNSN_T_COSH
+%token DMNSN_T_COS "cos"
+%token DMNSN_T_COSH "cosh"
%token DMNSN_T_COUNT
%token DMNSN_T_CRACKLE
%token DMNSN_T_CRAND
@@ -154,7 +154,7 @@
%token DMNSN_T_CYLINDER
%token DMNSN_T_CYLINDRICAL
%token DMNSN_T_DEFINED
-%token DMNSN_T_DEGREES
+%token DMNSN_T_DEGREES "degrees"
%token DMNSN_T_DENSITY
%token DMNSN_T_DENSITY_FILE
%token DMNSN_T_DENSITY_MAP
@@ -170,7 +170,7 @@
%token DMNSN_T_DISPERSION_SAMPLES
%token DMNSN_T_DIST_EXP
%token DMNSN_T_DISTANCE
-%token DMNSN_T_DIV
+%token DMNSN_T_DIV "div"
%token DMNSN_T_DOUBLE_ILLUMINATE
%token DMNSN_T_ECCENTRICITY
%token DMNSN_T_EMISSION
@@ -197,7 +197,7 @@
%token DMNSN_T_FISHEYE
%token DMNSN_T_FLATNESS
%token DMNSN_T_FLIP
-%token DMNSN_T_FLOOR
+%token DMNSN_T_FLOOR "floor"
%token DMNSN_T_FOCAL_POINT
%token DMNSN_T_FOG
%token DMNSN_T_FOG_ALT
diff --git a/dimension/grammar.epilogue b/dimension/grammar.epilogue
index 84141fb..1ff7137 100644
--- a/dimension/grammar.epilogue
+++ b/dimension/grammar.epilogue
@@ -178,7 +178,22 @@ dmnsn_astnode_string(dmnsn_astnode_type astnode_type)
dmnsn_astnode_map(DMNSN_AST_AND, "&" );
dmnsn_astnode_map(DMNSN_AST_OR, "|" );
- dmnsn_astnode_map(DMNSN_AST_EXP, "exp");
+ dmnsn_astnode_map(DMNSN_AST_ABS, "abs");
+ dmnsn_astnode_map(DMNSN_AST_ACOS, "acos");
+ dmnsn_astnode_map(DMNSN_AST_ACOSH, "acosh");
+ dmnsn_astnode_map(DMNSN_AST_ASC, "asc");
+ dmnsn_astnode_map(DMNSN_AST_ASIN, "asin");
+ dmnsn_astnode_map(DMNSN_AST_ASINH, "asinh");
+ dmnsn_astnode_map(DMNSN_AST_ATAN, "atan");
+ dmnsn_astnode_map(DMNSN_AST_ATAN2, "atan2");
+ dmnsn_astnode_map(DMNSN_AST_ATANH, "atanh");
+ dmnsn_astnode_map(DMNSN_AST_CEIL, "ceil");
+ dmnsn_astnode_map(DMNSN_AST_COS, "cos");
+ dmnsn_astnode_map(DMNSN_AST_COSH, "cosh");
+ dmnsn_astnode_map(DMNSN_AST_DEGREES, "degrees");
+ dmnsn_astnode_map(DMNSN_AST_INT_DIV, "div");
+ dmnsn_astnode_map(DMNSN_AST_EXP, "exp");
+ dmnsn_astnode_map(DMNSN_AST_FLOOR, "floor");
dmnsn_astnode_map(DMNSN_AST_NEGATE, "-");
dmnsn_astnode_map(DMNSN_AST_DOT_X, ".x");
diff --git a/dimension/lexer.l b/dimension/lexer.l
index 4f12f31..3d30f0b 100644
--- a/dimension/lexer.l
+++ b/dimension/lexer.l
@@ -172,21 +172,36 @@ unsigned long wchar;
}
(?# Keywords)
+"abs" RETURN_TOKEN(DMNSN_T_ABS);
+"acos" RETURN_TOKEN(DMNSN_T_ACOS);
+"acosh" RETURN_TOKEN(DMNSN_T_ACOSH);
"ambient" RETURN_TOKEN(DMNSN_T_AMBIENT);
"angle" RETURN_TOKEN(DMNSN_T_ANGLE);
+"asc" RETURN_TOKEN(DMNSN_T_ASC);
+"asin" RETURN_TOKEN(DMNSN_T_ASIN);
+"asinh" RETURN_TOKEN(DMNSN_T_ASINH);
"assumed_gamma" RETURN_TOKEN(DMNSN_T_ASSUMED_GAMMA);
+"atan" RETURN_TOKEN(DMNSN_T_ATAN);
+"atan2" RETURN_TOKEN(DMNSN_T_ATAN2);
+"atanh" RETURN_TOKEN(DMNSN_T_ATANH);
"background" RETURN_TOKEN(DMNSN_T_BACKGROUND);
"box" RETURN_TOKEN(DMNSN_T_BOX);
"blue" RETURN_TOKEN(DMNSN_T_BLUE);
+"ceil" RETURN_TOKEN(DMNSN_T_CEIL);
"camera" RETURN_TOKEN(DMNSN_T_CAMERA);
"color" RETURN_TOKEN(DMNSN_T_COLOR);
"colour" RETURN_TOKEN(DMNSN_T_COLOR);
-"direction" RETURN_TOKEN(DMNSN_T_DIRECTION);
+"cos" RETURN_TOKEN(DMNSN_T_COS);
+"cosh" RETURN_TOKEN(DMNSN_T_COSH);
+"degrees" RETURN_TOKEN(DMNSN_T_DEGREES);
"diffuse" RETURN_TOKEN(DMNSN_T_DIFFUSE);
+"direction" RETURN_TOKEN(DMNSN_T_DIRECTION);
+"div" RETURN_TOKEN(DMNSN_T_DIV);
"exp" RETURN_TOKEN(DMNSN_T_EXP);
"falloff" RETURN_TOKEN(DMNSN_T_FALLOFF);
"filter" RETURN_TOKEN(DMNSN_T_FILTER);
"finish" RETURN_TOKEN(DMNSN_T_FINISH);
+"floor" RETURN_TOKEN(DMNSN_T_FLOOR);
"global_settings" RETURN_TOKEN(DMNSN_T_GLOBAL_SETTINGS);
"gray" RETURN_TOKEN(DMNSN_T_GRAY);
"grey" RETURN_TOKEN(DMNSN_T_GRAY);
diff --git a/dimension/parse.c b/dimension/parse.c
index 7b4a35b..1507f31 100644
--- a/dimension/parse.c
+++ b/dimension/parse.c
@@ -19,6 +19,8 @@
#include "parse.h"
#include "utility.h"
+#include <math.h>
+#include <fenv.h>
/*
* Symbol table
@@ -557,6 +559,18 @@ dmnsn_vector_promote(dmnsn_astnode astnode, dmnsn_symbol_table *symtable)
return promoted;
}
+static void
+dmnsn_make_ast_maybe_integer(dmnsn_astnode *ret, double n)
+{
+ feclearexcept(FE_ALL_EXCEPT);
+ long l = lrint(n);
+ if (fetestexcept(FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW)) {
+ dmnsn_make_ast_float(ret, n);
+ } else {
+ dmnsn_make_ast_integer(ret, l);
+ }
+}
+
static dmnsn_astnode
dmnsn_eval_unary(dmnsn_astnode astnode, dmnsn_symbol_table *symtable)
{
@@ -633,13 +647,49 @@ dmnsn_eval_unary(dmnsn_astnode astnode, dmnsn_symbol_table *symtable)
dmnsn_make_ast_integer(&ret, -n);
break;
+ case DMNSN_AST_ABS:
+ dmnsn_make_ast_integer(&ret, labs(n));
+ break;
+ case DMNSN_AST_ACOS:
+ dmnsn_make_ast_float(&ret, acos(n));
+ break;
+ case DMNSN_AST_ACOSH:
+ dmnsn_make_ast_float(&ret, acosh(n));
+ break;
+ case DMNSN_AST_ASIN:
+ dmnsn_make_ast_float(&ret, asin(n));
+ break;
+ case DMNSN_AST_ASINH:
+ dmnsn_make_ast_float(&ret, asinh(n));
+ break;
+ case DMNSN_AST_ATAN:
+ dmnsn_make_ast_float(&ret, atan(n));
+ break;
+ case DMNSN_AST_ATANH:
+ dmnsn_make_ast_float(&ret, atanh(n));
+ break;
+ case DMNSN_AST_CEIL:
+ dmnsn_make_ast_integer(&ret, n);
+ break;
+ case DMNSN_AST_COS:
+ dmnsn_make_ast_float(&ret, cos(n));
+ break;
+ case DMNSN_AST_COSH:
+ dmnsn_make_ast_float(&ret, cosh(n));
+ break;
+ case DMNSN_AST_DEGREES:
+ dmnsn_make_ast_float(&ret, n*45.0/atan(1.0));
+ break;
case DMNSN_AST_EXP:
dmnsn_make_ast_float(&ret, exp(n));
break;
+ case DMNSN_AST_FLOOR:
+ dmnsn_make_ast_integer(&ret, n);
+ break;
default:
dmnsn_diagnostic(astnode.filename, astnode.line, astnode.col,
- "Invalid unary operator '%s' on %s",
+ "invalid unary operator '%s' on %s",
dmnsn_astnode_string(astnode.type),
dmnsn_astnode_string(rhs.type));
ret.type = DMNSN_AST_NONE;
@@ -662,13 +712,65 @@ dmnsn_eval_unary(dmnsn_astnode astnode, dmnsn_symbol_table *symtable)
dmnsn_make_ast_float(&ret, -n);
break;
+ case DMNSN_AST_ABS:
+ dmnsn_make_ast_float(&ret, fabs(n));
+ break;
+ case DMNSN_AST_ACOS:
+ dmnsn_make_ast_float(&ret, acos(n));
+ break;
+ case DMNSN_AST_ACOSH:
+ dmnsn_make_ast_float(&ret, acosh(n));
+ break;
+ case DMNSN_AST_ASIN:
+ dmnsn_make_ast_float(&ret, asin(n));
+ break;
+ case DMNSN_AST_ASINH:
+ dmnsn_make_ast_float(&ret, asinh(n));
+ break;
+ case DMNSN_AST_ATAN:
+ dmnsn_make_ast_float(&ret, atan(n));
+ break;
+ case DMNSN_AST_ATANH:
+ dmnsn_make_ast_float(&ret, atanh(n));
+ break;
+ case DMNSN_AST_CEIL:
+ dmnsn_make_ast_maybe_integer(&ret, ceil(n));
+ break;
+ case DMNSN_AST_COS:
+ dmnsn_make_ast_float(&ret, cos(n));
+ break;
+ case DMNSN_AST_COSH:
+ dmnsn_make_ast_float(&ret, cosh(n));
+ break;
+ case DMNSN_AST_DEGREES:
+ dmnsn_make_ast_float(&ret, n*45.0/atan(1.0));
+ break;
case DMNSN_AST_EXP:
dmnsn_make_ast_float(&ret, exp(n));
break;
+ case DMNSN_AST_FLOOR:
+ dmnsn_make_ast_maybe_integer(&ret, floor(n));
+ break;
+
+ default:
+ dmnsn_diagnostic(astnode.filename, astnode.line, astnode.col,
+ "invalid unary operator '%s' on %s",
+ dmnsn_astnode_string(astnode.type),
+ dmnsn_astnode_string(rhs.type));
+ ret.type = DMNSN_AST_NONE;
+ break;
+ }
+ } else if (rhs.type == DMNSN_AST_STRING) {
+ ret = dmnsn_copy_astnode(astnode);
+
+ switch(astnode.type) {
+ case DMNSN_AST_ASC:
+ dmnsn_make_ast_integer(&ret, ((char *)rhs.ptr)[0]);
+ break;
default:
dmnsn_diagnostic(astnode.filename, astnode.line, astnode.col,
- "Invalid unary operator '%s' on %s",
+ "invalid unary operator '%s' on %s",
dmnsn_astnode_string(astnode.type),
dmnsn_astnode_string(rhs.type));
ret.type = DMNSN_AST_NONE;
@@ -676,10 +778,10 @@ dmnsn_eval_unary(dmnsn_astnode astnode, dmnsn_symbol_table *symtable)
}
} else {
dmnsn_diagnostic(rhs.filename, rhs.line, rhs.col,
- "expected %s, %s, or %s; found %s",
+ "expected %s or %s or %s; found %s",
dmnsn_astnode_string(DMNSN_AST_INTEGER),
dmnsn_astnode_string(DMNSN_AST_FLOAT),
- dmnsn_astnode_string(DMNSN_AST_VECTOR),
+ dmnsn_astnode_string(DMNSN_AST_STRING),
dmnsn_astnode_string(rhs.type));
ret = dmnsn_copy_astnode(astnode);
ret.type = DMNSN_AST_NONE;
@@ -854,7 +956,7 @@ dmnsn_eval_binary(dmnsn_astnode astnode, dmnsn_symbol_table *symtable)
case DMNSN_AST_GREATER:
case DMNSN_AST_GREATER_EQUAL:
dmnsn_diagnostic(astnode.filename, astnode.line, astnode.col,
- "Invalid comparison operator '%s' between vectors",
+ "invalid comparison operator '%s' between vectors",
dmnsn_astnode_string(astnode.type));
ret = dmnsn_copy_astnode(astnode);
ret.type = DMNSN_AST_NONE;
@@ -929,9 +1031,16 @@ dmnsn_eval_binary(dmnsn_astnode astnode, dmnsn_symbol_table *symtable)
dmnsn_make_ast_integer(&ret, l || r);
break;
+ case DMNSN_AST_ATAN2:
+ dmnsn_make_ast_float(&ret, atan2(l, r));
+ break;
+ case DMNSN_AST_INT_DIV:
+ dmnsn_make_ast_maybe_integer(&ret, trunc(l/r));
+ break;
+
default:
dmnsn_diagnostic(astnode.filename, astnode.line, astnode.col,
- "Invalid binary operator '%s' on %s an %s",
+ "invalid binary operator '%s' on %s and %s",
dmnsn_astnode_string(astnode.type),
dmnsn_astnode_string(lhs.type),
dmnsn_astnode_string(rhs.type));
@@ -949,10 +1058,9 @@ dmnsn_eval_binary(dmnsn_astnode astnode, dmnsn_symbol_table *symtable)
l = *(double *)lhs.ptr;
} else {
dmnsn_diagnostic(lhs.filename, lhs.line, lhs.col,
- "expected %s, %s, or %s; found %s",
+ "expected %s or %s; found %s",
dmnsn_astnode_string(DMNSN_AST_INTEGER),
dmnsn_astnode_string(DMNSN_AST_FLOAT),
- dmnsn_astnode_string(DMNSN_AST_VECTOR),
dmnsn_astnode_string(lhs.type));
ret.type = DMNSN_AST_NONE;
dmnsn_delete_astnode(lhs);
@@ -966,10 +1074,9 @@ dmnsn_eval_binary(dmnsn_astnode astnode, dmnsn_symbol_table *symtable)
r = *(double *)rhs.ptr;
} else {
dmnsn_diagnostic(rhs.filename, rhs.line, rhs.col,
- "expected %s, %s, or %s; found %s",
+ "expected %s or %s; found %s",
dmnsn_astnode_string(DMNSN_AST_INTEGER),
dmnsn_astnode_string(DMNSN_AST_FLOAT),
- dmnsn_astnode_string(DMNSN_AST_VECTOR),
dmnsn_astnode_string(rhs.type));
ret.type = DMNSN_AST_NONE;
dmnsn_delete_astnode(lhs);
@@ -1018,9 +1125,16 @@ dmnsn_eval_binary(dmnsn_astnode astnode, dmnsn_symbol_table *symtable)
|| fabs(r) >= dmnsn_epsilon);
break;
+ case DMNSN_AST_ATAN2:
+ dmnsn_make_ast_float(&ret, atan2(l, r));
+ break;
+ case DMNSN_AST_INT_DIV:
+ dmnsn_make_ast_float(&ret, trunc(l/r));
+ break;
+
default:
dmnsn_diagnostic(astnode.filename, astnode.line, astnode.col,
- "Invalid binary operator '%s' on %s an %s",
+ "invalid binary operator '%s' on %s and %s",
dmnsn_astnode_string(astnode.type),
dmnsn_astnode_string(lhs.type),
dmnsn_astnode_string(rhs.type));
@@ -1041,6 +1155,7 @@ dmnsn_eval(dmnsn_astnode astnode, dmnsn_symbol_table *symtable)
case DMNSN_AST_NONE:
case DMNSN_AST_INTEGER:
case DMNSN_AST_FLOAT:
+ case DMNSN_AST_STRING:
do {
++*astnode.refcount;
} while (*astnode.refcount <= 1);
@@ -1060,7 +1175,7 @@ dmnsn_eval(dmnsn_astnode astnode, dmnsn_symbol_table *symtable)
return dmnsn_eval(id, symtable);
} else {
dmnsn_diagnostic(astnode.filename, astnode.line, astnode.col,
- "Unbound identifier '%s'", (const char *)astnode.ptr);
+ "unbound identifier '%s'", (const char *)astnode.ptr);
dmnsn_astnode error = dmnsn_new_astnode(DMNSN_AST_NONE);
++*error.refcount;
return error;
@@ -1073,7 +1188,20 @@ 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_ABS:
+ case DMNSN_AST_ACOS:
+ case DMNSN_AST_ACOSH:
+ case DMNSN_AST_ASC:
+ case DMNSN_AST_ASIN:
+ case DMNSN_AST_ASINH:
+ case DMNSN_AST_ATAN:
+ case DMNSN_AST_ATANH:
+ case DMNSN_AST_CEIL:
+ case DMNSN_AST_COS:
+ case DMNSN_AST_COSH:
+ case DMNSN_AST_DEGREES:
case DMNSN_AST_EXP:
+ case DMNSN_AST_FLOOR:
return dmnsn_eval_unary(astnode, symtable);
case DMNSN_AST_ADD:
@@ -1088,6 +1216,8 @@ dmnsn_eval(dmnsn_astnode astnode, dmnsn_symbol_table *symtable)
case DMNSN_AST_GREATER_EQUAL:
case DMNSN_AST_AND:
case DMNSN_AST_OR:
+ case DMNSN_AST_ATAN2:
+ case DMNSN_AST_INT_DIV:
return dmnsn_eval_binary(astnode, symtable);
default:
@@ -1106,7 +1236,7 @@ dmnsn_astnode
dmnsn_eval_scalar(dmnsn_astnode astnode, dmnsn_symbol_table *symtable)
{
dmnsn_astnode ret = dmnsn_eval(astnode, symtable);
- if (ret.type == DMNSN_AST_VECTOR) {
+ if (ret.type != DMNSN_AST_INTEGER && ret.type != DMNSN_AST_FLOAT) {
dmnsn_diagnostic(ret.filename, ret.line, ret.col,
"expected %s or %s; found %s",
dmnsn_astnode_string(DMNSN_AST_INTEGER),
@@ -1123,7 +1253,6 @@ dmnsn_eval_vector(dmnsn_astnode astnode, dmnsn_symbol_table *symtable)
{
dmnsn_astnode eval = dmnsn_eval(astnode, symtable);
dmnsn_astnode ret = dmnsn_vector_promote(eval, symtable);
-
dmnsn_delete_astnode(eval);
return ret;
}
diff --git a/dimension/parse.h b/dimension/parse.h
index 8a572f2..f088115 100644
--- a/dimension/parse.h
+++ b/dimension/parse.h
@@ -90,7 +90,22 @@ typedef enum {
DMNSN_AST_DOT_T,
DMNSN_AST_DOT_TRANSMIT,
+ DMNSN_AST_ABS,
+ DMNSN_AST_ACOS,
+ DMNSN_AST_ACOSH,
+ DMNSN_AST_ASC,
+ DMNSN_AST_ASIN,
+ DMNSN_AST_ASINH,
+ DMNSN_AST_ATAN,
+ DMNSN_AST_ATAN2,
+ DMNSN_AST_ATANH,
+ DMNSN_AST_CEIL,
+ DMNSN_AST_COS,
+ DMNSN_AST_COSH,
+ DMNSN_AST_DEGREES,
+ DMNSN_AST_INT_DIV,
DMNSN_AST_EXP,
+ DMNSN_AST_FLOOR,
DMNSN_AST_EQUAL,
DMNSN_AST_NOT_EQUAL,
diff --git a/tests/dimension/arithexp.pov b/tests/dimension/arithexp.pov
index 5e27612..0411e19 100644
--- a/tests/dimension/arithexp.pov
+++ b/tests/dimension/arithexp.pov
@@ -23,3 +23,67 @@ sphere {
2*<<2.0 - 1.0, 3.0, 4.0>.x, (1.0 + 2)*2 - 5, 1.0 + 2*2 - 4> - -<0, 0, 1>,
exp(1) - 1*2
}
+
+#if (abs(-1) != 1)
+ #error "abs"
+#end
+
+#if (acos(0) != 1.570796326794897)
+ #error "acos"
+#end
+
+#if (acosh(2) != 1.316957896924817)
+ #error "acosh"
+#end
+
+#if (asc("ABC") != 65)
+ #error "asc"
+#end
+
+#if (asin(1) != 1.570796326794897)
+ #error "asin"
+#end
+
+#if (asinh(2) != 1.44363547517881)
+ #error "asinh"
+#end
+
+#if (atan(1) != 0.7853981633974483)
+ #error "atan"
+#end
+
+#if (atan2(-1, -1) != -2.35619449019234)
+ #error "atan2"
+#end
+
+#if (atanh(0.5) != 0.5493061443340548)
+ #error "atanh"
+#end
+
+#if (ceil(-1.5) != -1)
+ #error "ceil"
+#end
+
+#if (cos(1.570796326794897) != 0)
+ #error "cos"
+#end
+
+#if (cosh(1.316957896924817) != 2)
+ #error "cosh"
+#end
+
+#if (degrees(1.570796326794897) != 90)
+ #error "degrees"
+#end
+
+#if (div(3,2) != 1)
+ #error "div"
+#end
+
+#if (exp(1) != 2.718281828459045)
+ #error "exp"
+#end
+
+#if (floor(-1.5) != -2)
+ #error "floor"
+#end
diff --git a/tests/dimension/arithexp.sh b/tests/dimension/arithexp.sh
index 6572646..0829e49 100755
--- a/tests/dimension/arithexp.sh
+++ b/tests/dimension/arithexp.sh
@@ -19,19 +19,8 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
#########################################################################
-arithexp=$(${top_builddir}/dimension/dimension --tokenize --parse ${srcdir}/arithexp.pov)
+arithexp=$(${top_builddir}/dimension/dimension --parse ${srcdir}/arithexp.pov)
arithexp_exp="$(echo -n \
-'(sphere {
- (integer "2") *
- < < (float "2.0") - (float "1.0") , (float "3.0") , (float "4.0") > . x ,
- \( (float "1.0") + (integer "2") \) * (integer "2") - (integer "5") ,
- (float "1.0") + (integer "2") * (integer "2") - (integer "4") >
- -
- - < (integer "0") , (integer "0") , (integer "1") > ,
- exp \( (integer "1") \) - (integer "1") * (integer "2")
- })' \
-| tr '\n' ' ' | sed -r 's/[[:space:]]+/ /g')
-$(echo -n \
'((sphere
(vector (float 2) (float 2) (float 3) (integer 0) (integer 0))
(float 0.718282)