summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTavian Barnes <tavianator@gmail.com>2010-03-20 15:30:40 -0400
committerTavian Barnes <tavianator@gmail.com>2010-03-20 15:30:40 -0400
commit5da32d0dce6b8ade0b636b83f67b6244e6a56494 (patch)
tree49d15326afa1a2bdde55b5cc37620e68bb4b5a20
parent4566f4e34afaab1c47120e8a377859d88a142ffe (diff)
downloaddimension-5da32d0dce6b8ade0b636b83f67b6244e6a56494.tar.xz
Implement almost all float functions.
-rw-r--r--dimension/common.rules48
-rw-r--r--dimension/common.terminals32
-rw-r--r--dimension/grammar.epilogue46
-rw-r--r--dimension/lexer.l18
-rw-r--r--dimension/parse.c191
-rw-r--r--dimension/parse.h16
-rw-r--r--tests/dimension/arithexp.pov72
7 files changed, 386 insertions, 37 deletions
diff --git a/dimension/common.rules b/dimension/common.rules
index fb38039..e5b9e67 100644
--- a/dimension/common.rules
+++ b/dimension/common.rules
@@ -444,6 +444,54 @@ ARITH_EXPR: FLOAT_LITERAL
| "floor" "(" ARITH_EXPR ")" {
$$ = dmnsn_new_astnode1(DMNSN_AST_FLOOR, @$, $3);
}
+ | "int" "(" ARITH_EXPR ")" {
+ $$ = dmnsn_new_astnode1(DMNSN_AST_INT, @$, $3);
+ }
+ | "ln" "(" ARITH_EXPR ")" {
+ $$ = dmnsn_new_astnode1(DMNSN_AST_LN, @$, $3);
+ }
+ | "log" "(" ARITH_EXPR ")" {
+ $$ = dmnsn_new_astnode1(DMNSN_AST_LOG, @$, $3);
+ }
+ | "mod" "(" ARITH_EXPR "," ARITH_EXPR ")" {
+ $$ = dmnsn_new_astnode2(DMNSN_AST_MOD, @$, $3, $5);
+ }
+ | "pow" "(" ARITH_EXPR "," ARITH_EXPR ")" {
+ $$ = dmnsn_new_astnode2(DMNSN_AST_POW, @$, $3, $5);
+ }
+ | "radians" "(" ARITH_EXPR ")" {
+ $$ = dmnsn_new_astnode1(DMNSN_AST_RADIANS, @$, $3);
+ }
+ | "sin" "(" ARITH_EXPR ")" {
+ $$ = dmnsn_new_astnode1(DMNSN_AST_SIN, @$, $3);
+ }
+ | "sinh" "(" ARITH_EXPR ")" {
+ $$ = dmnsn_new_astnode1(DMNSN_AST_SINH, @$, $3);
+ }
+ | "sqrt" "(" ARITH_EXPR ")" {
+ $$ = dmnsn_new_astnode1(DMNSN_AST_SQRT, @$, $3);
+ }
+ | "strcmp" "(" STRING "," STRING ")" {
+ $$ = dmnsn_new_astnode2(DMNSN_AST_STRCMP, @$, $3, $5);
+ }
+ | "strlen" "(" STRING ")" {
+ $$ = dmnsn_new_astnode1(DMNSN_AST_STRLEN, @$, $3);
+ }
+ | "tan" "(" ARITH_EXPR ")" {
+ $$ = dmnsn_new_astnode1(DMNSN_AST_TAN, @$, $3);
+ }
+ | "tanh" "(" ARITH_EXPR ")" {
+ $$ = dmnsn_new_astnode1(DMNSN_AST_TANH, @$, $3);
+ }
+ | "val" "(" STRING ")" {
+ $$ = dmnsn_new_astnode1(DMNSN_AST_VAL, @$, $3);
+ }
+ | "vdot" "(" ARITH_EXPR "," ARITH_EXPR ")" {
+ $$ = dmnsn_new_astnode2(DMNSN_AST_VDOT, @$, $3, $5);
+ }
+ | "vlength" "(" ARITH_EXPR ")" {
+ $$ = dmnsn_new_astnode1(DMNSN_AST_VLENGTH, @$, $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 b468a69..a877ac1 100644
--- a/dimension/common.terminals
+++ b/dimension/common.terminals
@@ -232,7 +232,7 @@
%token DMNSN_T_INITIAL_FRAME
%token DMNSN_T_INSIDE
%token DMNSN_T_INSIDE_VECTOR
-%token DMNSN_T_INT
+%token DMNSN_T_INT "int"
%token DMNSN_T_INTERIOR "interior"
%token DMNSN_T_INTERIOR_TEXTURE
%token DMNSN_T_INTERNAL
@@ -255,10 +255,10 @@
%token DMNSN_T_LIGHT_SOURCE "light_source"
%token DMNSN_T_LINEAR_SPLINE
%token DMNSN_T_LINEAR_SWEEP
-%token DMNSN_T_LN
+%token DMNSN_T_LN "ln"
%token DMNSN_T_LOAD_FILE
%token DMNSN_T_LOCATION "location"
-%token DMNSN_T_LOG
+%token DMNSN_T_LOG "log"
%token DMNSN_T_LOOK_AT "look_at"
%token DMNSN_T_LOOKS_LIKE
%token DMNSN_T_LOW_ERROR_FACTOR
@@ -290,7 +290,7 @@
%token DMNSN_T_MIN
%token DMNSN_T_MIN_EXTENT
%token DMNSN_T_MINIMUM_REUSE
-%token DMNSN_T_MOD
+%token DMNSN_T_MOD "mod"
%token DMNSN_T_MORTAR
%token DMNSN_T_NATURAL_SPLINE
%token DMNSN_T_NEAREST_COUNT
@@ -341,7 +341,7 @@
%token DMNSN_T_POLY_WAVE
%token DMNSN_T_POLYGON
%token DMNSN_T_POT
-%token DMNSN_T_POW
+%token DMNSN_T_POW "pow"
%token DMNSN_T_PPM
%token DMNSN_T_PRECISION
%token DMNSN_T_PRECOMPUTE
@@ -358,7 +358,7 @@
%token DMNSN_T_QUICK_COLOR
%token DMNSN_T_QUILTED
%token DMNSN_T_RADIAL
-%token DMNSN_T_RADIANS
+%token DMNSN_T_RADIANS "radians"
%token DMNSN_T_RADIOSITY
%token DMNSN_T_RADIUS
%token DMNSN_T_RAINBOW
@@ -388,9 +388,9 @@
%token DMNSN_T_SEED
%token DMNSN_T_SELECT
%token DMNSN_T_SHADOWLESS
-%token DMNSN_T_SIN
+%token DMNSN_T_SIN "sin"
%token DMNSN_T_SINE_WAVE
-%token DMNSN_T_SINH
+%token DMNSN_T_SINH "sinh"
%token DMNSN_T_SIZE
%token DMNSN_T_SKY "sky"
%token DMNSN_T_SKY_SPHERE
@@ -413,11 +413,11 @@
%token DMNSN_T_SPOTLIGHT
%token DMNSN_T_SPOTTED
%token DMNSN_T_SQR
-%token DMNSN_T_SQRT
+%token DMNSN_T_SQRT "sqrt"
%token DMNSN_T_STR
-%token DMNSN_T_STRCMP
+%token DMNSN_T_STRCMP "strcmp"
%token DMNSN_T_STRENGTH
-%token DMNSN_T_STRLEN
+%token DMNSN_T_STRLEN "strlen"
%token DMNSN_T_STRLWR
%token DMNSN_T_STRUPR
%token DMNSN_T_STURM
@@ -426,8 +426,8 @@
%token DMNSN_T_SUPERELLIPSOID
%token DMNSN_T_SYS
%token DMNSN_T_T "t"
-%token DMNSN_T_TAN
-%token DMNSN_T_TANH
+%token DMNSN_T_TAN "tan"
+%token DMNSN_T_TANH "tanh"
%token DMNSN_T_TARGET
%token DMNSN_T_TEXT
%token DMNSN_T_TEXTURE "texture"
@@ -468,13 +468,13 @@
%token DMNSN_T_UV_VECTORS
%token DMNSN_T_V "v"
%token DMNSN_T_V_STEPS
-%token DMNSN_T_VAL
+%token DMNSN_T_VAL "val"
%token DMNSN_T_VARIANCE
%token DMNSN_T_VAXIS_ROTATE
%token DMNSN_T_VCROSS
-%token DMNSN_T_VDOT
+%token DMNSN_T_VDOT "vdot"
%token DMNSN_T_VERTEX_VECTORS
-%token DMNSN_T_VLENGTH
+%token DMNSN_T_VLENGTH "vlength"
%token DMNSN_T_VNORMALIZE
%token DMNSN_T_VROTATE
%token DMNSN_T_VSTR
diff --git a/dimension/grammar.epilogue b/dimension/grammar.epilogue
index 1ff7137..05e9741 100644
--- a/dimension/grammar.epilogue
+++ b/dimension/grammar.epilogue
@@ -178,22 +178,38 @@ 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_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_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_INT_DIV, "div" );
+ dmnsn_astnode_map(DMNSN_AST_EXP, "exp" );
+ dmnsn_astnode_map(DMNSN_AST_FLOOR, "floor" );
+ 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_MOD, "mod" );
+ dmnsn_astnode_map(DMNSN_AST_POW, "pow" );
+ dmnsn_astnode_map(DMNSN_AST_RADIANS, "radians");
+ dmnsn_astnode_map(DMNSN_AST_SIN, "sin" );
+ dmnsn_astnode_map(DMNSN_AST_SINH, "sinh" );
+ dmnsn_astnode_map(DMNSN_AST_SQRT, "sqrt" );
+ dmnsn_astnode_map(DMNSN_AST_STRCMP, "strcmp" );
+ dmnsn_astnode_map(DMNSN_AST_STRLEN, "strlen" );
+ dmnsn_astnode_map(DMNSN_AST_TAN, "tan" );
+ dmnsn_astnode_map(DMNSN_AST_TANH, "tanh" );
+ dmnsn_astnode_map(DMNSN_AST_VAL, "val" );
+ dmnsn_astnode_map(DMNSN_AST_VDOT, "vdot" );
+ dmnsn_astnode_map(DMNSN_AST_VLENGTH, "vlength");
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 3d30f0b..79d0a51 100644
--- a/dimension/lexer.l
+++ b/dimension/lexer.l
@@ -206,16 +206,22 @@ unsigned long wchar;
"gray" RETURN_TOKEN(DMNSN_T_GRAY);
"grey" RETURN_TOKEN(DMNSN_T_GRAY);
"green" RETURN_TOKEN(DMNSN_T_GREEN);
+"int" RETURN_TOKEN(DMNSN_T_INT);
"interior" RETURN_TOKEN(DMNSN_T_INTERIOR);
"ior" RETURN_TOKEN(DMNSN_T_IOR);
+"ln" RETURN_TOKEN(DMNSN_T_LN);
"location" RETURN_TOKEN(DMNSN_T_LOCATION);
+"log" RETURN_TOKEN(DMNSN_T_LOG);
"look_at" RETURN_TOKEN(DMNSN_T_LOOK_AT);
"light_source" RETURN_TOKEN(DMNSN_T_LIGHT_SOURCE);
"max_trace_level" RETURN_TOKEN(DMNSN_T_MAX_TRACE_LEVEL);
+"mod" RETURN_TOKEN(DMNSN_T_MOD);
"perspective" RETURN_TOKEN(DMNSN_T_PERSPECTIVE);
"phong" RETURN_TOKEN(DMNSN_T_PHONG);
"phong_size" RETURN_TOKEN(DMNSN_T_PHONG_SIZE);
"pigment" RETURN_TOKEN(DMNSN_T_PIGMENT);
+"pow" RETURN_TOKEN(DMNSN_T_POW);
+"radians" RETURN_TOKEN(DMNSN_T_RADIANS);
"red" RETURN_TOKEN(DMNSN_T_RED);
"reflection" RETURN_TOKEN(DMNSN_T_REFLECTION);
"rgb" RETURN_TOKEN(DMNSN_T_RGB);
@@ -224,14 +230,24 @@ unsigned long wchar;
"rgbt" RETURN_TOKEN(DMNSN_T_RGBT);
"right" RETURN_TOKEN(DMNSN_T_RIGHT);
"rotate" RETURN_TOKEN(DMNSN_T_ROTATE);
-"sphere" RETURN_TOKEN(DMNSN_T_SPHERE);
+"sin" RETURN_TOKEN(DMNSN_T_SIN);
+"sinh" RETURN_TOKEN(DMNSN_T_SINH);
"sky" RETURN_TOKEN(DMNSN_T_SKY);
+"sphere" RETURN_TOKEN(DMNSN_T_SPHERE);
+"sqrt" RETURN_TOKEN(DMNSN_T_SQRT);
+"strcmp" RETURN_TOKEN(DMNSN_T_STRCMP);
+"strlen" RETURN_TOKEN(DMNSN_T_STRLEN);
"t" RETURN_TOKEN(DMNSN_T_T);
+"tan" RETURN_TOKEN(DMNSN_T_TAN);
+"tanh" RETURN_TOKEN(DMNSN_T_TANH);
"texture" RETURN_TOKEN(DMNSN_T_TEXTURE);
"transmit" RETURN_TOKEN(DMNSN_T_TRANSMIT);
"u" RETURN_TOKEN(DMNSN_T_U);
"up" RETURN_TOKEN(DMNSN_T_UP);
"v" RETURN_TOKEN(DMNSN_T_V);
+"val" RETURN_TOKEN(DMNSN_T_VAL);
+"vdot" RETURN_TOKEN(DMNSN_T_VDOT);
+"vlength" RETURN_TOKEN(DMNSN_T_VLENGTH);
"x" RETURN_TOKEN(DMNSN_T_X);
"y" RETURN_TOKEN(DMNSN_T_Y);
"z" RETURN_TOKEN(DMNSN_T_Z);
diff --git a/dimension/parse.c b/dimension/parse.c
index 1507f31..fb9de1c 100644
--- a/dimension/parse.c
+++ b/dimension/parse.c
@@ -591,27 +591,40 @@ dmnsn_eval_unary(dmnsn_astnode astnode, dmnsn_symbol_table *symtable)
dmnsn_array_get(rhs.children, 0, &ret);
++*ret.refcount;
break;
-
case DMNSN_AST_DOT_Y:
dmnsn_array_get(rhs.children, 1, &ret);
++*ret.refcount;
break;
-
case DMNSN_AST_DOT_Z:
dmnsn_array_get(rhs.children, 2, &ret);
++*ret.refcount;
break;
-
case DMNSN_AST_DOT_T:
dmnsn_array_get(rhs.children, 3, &ret);
++*ret.refcount;
break;
-
case DMNSN_AST_DOT_TRANSMIT:
dmnsn_array_get(rhs.children, 4, &ret);
++*ret.refcount;
break;
+ case DMNSN_AST_VLENGTH:
+ {
+ dmnsn_astnode dot = dmnsn_copy_astnode(astnode);
+ dot.type = DMNSN_AST_VDOT;
+ *rhs.refcount += 2;
+ dmnsn_array_push(dot.children, &rhs);
+ dmnsn_array_push(dot.children, &rhs);
+
+ dmnsn_astnode rewrite = dmnsn_copy_astnode(astnode);
+ rewrite.type = DMNSN_AST_SQRT;
+ dmnsn_array_push(rewrite.children, &dot);
+
+ ret = dmnsn_eval_unary(rewrite, symtable);
+ dmnsn_delete_astnode(rewrite);
+ break;
+ }
+
default:
{
ret = dmnsn_copy_astnode(astnode);
@@ -686,6 +699,36 @@ dmnsn_eval_unary(dmnsn_astnode astnode, dmnsn_symbol_table *symtable)
case DMNSN_AST_FLOOR:
dmnsn_make_ast_integer(&ret, n);
break;
+ case DMNSN_AST_INT:
+ dmnsn_make_ast_integer(&ret, n);
+ break;
+ case DMNSN_AST_LN:
+ dmnsn_make_ast_float(&ret, log(n));
+ break;
+ case DMNSN_AST_LOG:
+ dmnsn_make_ast_float(&ret, log(n)/log(10.0));
+ break;
+ case DMNSN_AST_RADIANS:
+ dmnsn_make_ast_float(&ret, n*atan(1.0)/45.0);
+ break;
+ case DMNSN_AST_SIN:
+ dmnsn_make_ast_float(&ret, sin(n));
+ break;
+ case DMNSN_AST_SINH:
+ dmnsn_make_ast_float(&ret, sinh(n));
+ break;
+ case DMNSN_AST_SQRT:
+ dmnsn_make_ast_float(&ret, sqrt(n));
+ break;
+ case DMNSN_AST_TAN:
+ dmnsn_make_ast_float(&ret, tan(n));
+ break;
+ case DMNSN_AST_TANH:
+ dmnsn_make_ast_float(&ret, tanh(n));
+ break;
+ case DMNSN_AST_VLENGTH:
+ dmnsn_make_ast_float(&ret, sqrt(3*n*n));
+ break;
default:
dmnsn_diagnostic(astnode.filename, astnode.line, astnode.col,
@@ -751,6 +794,36 @@ dmnsn_eval_unary(dmnsn_astnode astnode, dmnsn_symbol_table *symtable)
case DMNSN_AST_FLOOR:
dmnsn_make_ast_maybe_integer(&ret, floor(n));
break;
+ case DMNSN_AST_INT:
+ dmnsn_make_ast_maybe_integer(&ret, trunc(n));
+ break;
+ case DMNSN_AST_LN:
+ dmnsn_make_ast_float(&ret, log(n));
+ break;
+ case DMNSN_AST_LOG:
+ dmnsn_make_ast_float(&ret, log(n)/log(10.0));
+ break;
+ case DMNSN_AST_RADIANS:
+ dmnsn_make_ast_float(&ret, n*atan(1.0)/45.0);
+ break;
+ case DMNSN_AST_SIN:
+ dmnsn_make_ast_float(&ret, sin(n));
+ break;
+ case DMNSN_AST_SINH:
+ dmnsn_make_ast_float(&ret, sinh(n));
+ break;
+ case DMNSN_AST_SQRT:
+ dmnsn_make_ast_float(&ret, sqrt(n));
+ break;
+ case DMNSN_AST_TAN:
+ dmnsn_make_ast_float(&ret, tan(n));
+ break;
+ case DMNSN_AST_TANH:
+ dmnsn_make_ast_float(&ret, tanh(n));
+ break;
+ case DMNSN_AST_VLENGTH:
+ dmnsn_make_ast_float(&ret, sqrt(3.0*n*n));
+ break;
default:
dmnsn_diagnostic(astnode.filename, astnode.line, astnode.col,
@@ -767,6 +840,28 @@ dmnsn_eval_unary(dmnsn_astnode astnode, dmnsn_symbol_table *symtable)
case DMNSN_AST_ASC:
dmnsn_make_ast_integer(&ret, ((char *)rhs.ptr)[0]);
break;
+ case DMNSN_AST_STRLEN:
+ dmnsn_make_ast_integer(&ret, strlen(rhs.ptr));
+ break;
+ case DMNSN_AST_VAL:
+ {
+ char *endptr;
+ long l = strtol(rhs.ptr, &endptr, 0);
+ if (*endptr != '\0' || endptr == rhs.ptr) {
+ double d = strtod(rhs.ptr, &endptr);
+ if (*endptr != '\0' || endptr == rhs.ptr) {
+ dmnsn_diagnostic(astnode.filename, astnode.line, astnode.col,
+ "invalid numeric string '%s'",
+ (const char *)rhs.ptr);
+ ret.type = DMNSN_AST_NONE;
+ } else {
+ dmnsn_make_ast_float(&ret, d);
+ }
+ } else {
+ dmnsn_make_ast_integer(&ret, l);
+ }
+ break;
+ }
default:
dmnsn_diagnostic(astnode.filename, astnode.line, astnode.col,
@@ -962,6 +1057,41 @@ dmnsn_eval_binary(dmnsn_astnode astnode, dmnsn_symbol_table *symtable)
ret.type = DMNSN_AST_NONE;
break;
+ case DMNSN_AST_VDOT:
+ {
+ dmnsn_astnode rewrite = dmnsn_copy_astnode(astnode);
+ rewrite.type = DMNSN_AST_MUL;
+
+ dmnsn_astnode l, r;
+ dmnsn_array_get(lhs.children, 0, &l);
+ dmnsn_array_get(rhs.children, 0, &r);
+ ++*l.refcount;
+ ++*r.refcount;
+ dmnsn_array_push(rewrite.children, &l);
+ dmnsn_array_push(rewrite.children, &r);
+
+ for (i = 1; i < 3; ++i) {
+ dmnsn_astnode temp = dmnsn_copy_astnode(astnode);
+ temp.type = DMNSN_AST_MUL;
+ dmnsn_array_get(lhs.children, i, &l);
+ dmnsn_array_get(rhs.children, i, &r);
+ ++*l.refcount;
+ ++*r.refcount;
+ dmnsn_array_push(temp.children, &l);
+ dmnsn_array_push(temp.children, &r);
+
+ dmnsn_astnode next = dmnsn_copy_astnode(astnode);
+ next.type = DMNSN_AST_ADD;
+ dmnsn_array_push(next.children, &rewrite);
+ dmnsn_array_push(next.children, &temp);
+ rewrite = next;
+ }
+
+ ret = dmnsn_eval_binary(rewrite, symtable);
+ dmnsn_delete_astnode(rewrite);
+ break;
+ }
+
default:
{
ret = dmnsn_copy_astnode(astnode);
@@ -981,6 +1111,23 @@ dmnsn_eval_binary(dmnsn_astnode astnode, dmnsn_symbol_table *symtable)
break;
}
}
+ } else if (lhs.type == DMNSN_AST_STRING && rhs.type == DMNSN_AST_STRING) {
+ ret = dmnsn_copy_astnode(astnode);
+
+ switch (astnode.type) {
+ case DMNSN_AST_STRCMP:
+ dmnsn_make_ast_integer(&ret, strcmp(lhs.ptr, rhs.ptr));
+ break;
+
+ default:
+ dmnsn_diagnostic(astnode.filename, astnode.line, astnode.col,
+ "invalid binary operator '%s' on %s and %s",
+ dmnsn_astnode_string(astnode.type),
+ dmnsn_astnode_string(lhs.type),
+ dmnsn_astnode_string(rhs.type));
+ ret.type = DMNSN_AST_NONE;
+ break;
+ }
} else if (lhs.type == DMNSN_AST_INTEGER && rhs.type == DMNSN_AST_INTEGER) {
ret = dmnsn_copy_astnode(astnode);
@@ -1035,7 +1182,16 @@ dmnsn_eval_binary(dmnsn_astnode astnode, dmnsn_symbol_table *symtable)
dmnsn_make_ast_float(&ret, atan2(l, r));
break;
case DMNSN_AST_INT_DIV:
- dmnsn_make_ast_maybe_integer(&ret, trunc(l/r));
+ dmnsn_make_ast_integer(&ret, l/r);
+ break;
+ case DMNSN_AST_MOD:
+ dmnsn_make_ast_float(&ret, fmod(l, r));
+ break;
+ case DMNSN_AST_POW:
+ dmnsn_make_ast_float(&ret, pow(l, r));
+ break;
+ case DMNSN_AST_VDOT:
+ dmnsn_make_ast_integer(&ret, 3*l*r);
break;
default:
@@ -1131,6 +1287,15 @@ 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_MOD:
+ dmnsn_make_ast_float(&ret, fmod(l, r));
+ break;
+ case DMNSN_AST_POW:
+ dmnsn_make_ast_float(&ret, pow(l, r));
+ break;
+ case DMNSN_AST_VDOT:
+ dmnsn_make_ast_float(&ret, 3.0*l*r);
+ break;
default:
dmnsn_diagnostic(astnode.filename, astnode.line, astnode.col,
@@ -1202,6 +1367,18 @@ dmnsn_eval(dmnsn_astnode astnode, dmnsn_symbol_table *symtable)
case DMNSN_AST_DEGREES:
case DMNSN_AST_EXP:
case DMNSN_AST_FLOOR:
+ case DMNSN_AST_INT:
+ case DMNSN_AST_LN:
+ case DMNSN_AST_LOG:
+ case DMNSN_AST_RADIANS:
+ case DMNSN_AST_SIN:
+ case DMNSN_AST_SINH:
+ case DMNSN_AST_SQRT:
+ case DMNSN_AST_STRLEN:
+ case DMNSN_AST_TAN:
+ case DMNSN_AST_TANH:
+ case DMNSN_AST_VAL:
+ case DMNSN_AST_VLENGTH:
return dmnsn_eval_unary(astnode, symtable);
case DMNSN_AST_ADD:
@@ -1218,6 +1395,10 @@ 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_MOD:
+ case DMNSN_AST_POW:
+ case DMNSN_AST_STRCMP:
+ case DMNSN_AST_VDOT:
return dmnsn_eval_binary(astnode, symtable);
default:
diff --git a/dimension/parse.h b/dimension/parse.h
index f088115..4648c87 100644
--- a/dimension/parse.h
+++ b/dimension/parse.h
@@ -106,6 +106,22 @@ typedef enum {
DMNSN_AST_INT_DIV,
DMNSN_AST_EXP,
DMNSN_AST_FLOOR,
+ DMNSN_AST_INT,
+ DMNSN_AST_LN,
+ DMNSN_AST_LOG,
+ DMNSN_AST_MOD,
+ DMNSN_AST_POW,
+ DMNSN_AST_RADIANS,
+ DMNSN_AST_SIN,
+ DMNSN_AST_SINH,
+ DMNSN_AST_SQRT,
+ DMNSN_AST_STRCMP,
+ DMNSN_AST_STRLEN,
+ DMNSN_AST_TAN,
+ DMNSN_AST_TANH,
+ DMNSN_AST_VAL,
+ DMNSN_AST_VDOT,
+ DMNSN_AST_VLENGTH,
DMNSN_AST_EQUAL,
DMNSN_AST_NOT_EQUAL,
diff --git a/tests/dimension/arithexp.pov b/tests/dimension/arithexp.pov
index 0411e19..c891b1c 100644
--- a/tests/dimension/arithexp.pov
+++ b/tests/dimension/arithexp.pov
@@ -87,3 +87,75 @@ sphere {
#if (floor(-1.5) != -2)
#error "floor"
#end
+
+#if (int(-1.9) != -1)
+ #error "int"
+#end
+
+#if (ln(2.718281828459045) != 1)
+ #error "ln"
+#end
+
+#if (log(1000) != 3)
+ #error "log"
+#end
+
+#if (mod(3.5, 2) != 1.5)
+ #error "mod"
+#end
+
+#if (pow(2, 3) != 8)
+ #error "pow"
+#end
+
+#if (radians(90) != 1.570796326794897)
+ #error "radians"
+#end
+
+#if (sin(1.570796326794897) != 1)
+ #error "sin"
+#end
+
+#if (sinh(1.44363547517881) != 2)
+ #error "sinh"
+#end
+
+#if (strcmp("asdfjkl;", "jkl;asdf") >= 0)
+ #error "strcmp"
+#end
+
+#if (strlen("asdfjkl;") != 8)
+ #error "strlen"
+#end
+
+#if (sqrt(2) != 1.414213562373095)
+ #error "sqrt"
+#end
+
+#if (tan(0.7853981633974483) != 1)
+ #error "tan"
+#end
+
+#if (tanh(0.5493061443340548) != 0.5)
+ #error "tanh"
+#end
+
+#if (val("123.45") != 123.45)
+ #error "val"
+#end
+
+#if (vdot(<1, 2, 3>, 2) != 12)
+ #error "vdot"
+#end
+
+#if (vdot(2, 2) != 12)
+ #error "vdot"
+#end
+
+#if (vlength(<1, 1, 1>) != 1.732050807568877)
+ #error "vlength"
+#end
+
+#if (vlength(1) != 1.732050807568877)
+ #error "vlength"
+#end