/* Evaluates functions in prefix form */ static inline double eval_prefun_expr(prefun_expr_t * prefun_expr) { int i; /* This is slightly less than safe, since who knows if the passed argument is valid. For speed purposes we'll go with this */ double arg_list[prefun_expr->num_args]; #ifdef EVAL_DEBUG printf("fn["); fflush(stdout); #endif /* Evaluate each argument before calling the function itself */ for (i = 0; i < prefun_expr->num_args; i++) { arg_list[i] = eval_gen_expr(prefun_expr->expr_list[i]); #ifdef EVAL_DEBUG if (i < (prefun_expr->num_args - 1)) printf(", "); fflush(stdout); #endif } #ifdef EVAL_DEBUG printf("]"); fflush(stdout); #endif /* Now we call the function, passing a list of doubles as its argument */ return (prefun_expr->func_ptr)(arg_list); }
/* Evaluate an equation */ void eval_per_frame_eqn(per_frame_eqn_t * per_frame_eqn) { if (per_frame_eqn == NULL) return; if (PER_FRAME_EQN_DEBUG) { printf("per_frame_%d=%s= ", per_frame_eqn->index, per_frame_eqn->param->name); fflush(stdout); } //*((double*)per_frame_eqn->param->engine_val) = eval_gen_expr(per_frame_eqn->gen_expr); set_param(per_frame_eqn->param, eval_gen_expr(per_frame_eqn->gen_expr)); if (PER_FRAME_EQN_DEBUG) printf(" = %.4f\n", *((double*)per_frame_eqn->param->engine_val)); }
/* Evaluates a per pixel equation */ void evalPerPixelEqn(per_pixel_eqn_t * per_pixel_eqn) { double ** param_matrix = NULL; gen_expr_t * eqn_ptr = NULL; int x,y; eqn_ptr = per_pixel_eqn->gen_expr; if (per_pixel_eqn->param->matrix == NULL) { if (PER_PIXEL_EQN_DEBUG) printf("evalPerPixelEqn: [begin initializing matrix] (index = %d) (name = %s)\n", per_pixel_eqn->index, per_pixel_eqn->param->name); param_matrix = per_pixel_eqn->param->matrix = (double**)malloc(gx*sizeof(double*)); for(x = 0; x < gx; x++) param_matrix[x] = (double *)malloc(gy * sizeof(double)); for (x = 0; x < gx; x++) for (y = 0; y < gy; y++) param_matrix[x][y] = 0.0; if (per_pixel_eqn->param->name == NULL) printf("null parameter?\n"); // printf("PARAM MATRIX: \"%s\" initialized.\n", per_pixel_eqn->param->name); } else param_matrix = (double**)per_pixel_eqn->param->matrix; if (eqn_ptr == NULL) printf("something is seriously wrong...\n"); for (mesh_i = 0; mesh_i < gx; mesh_i++) { for (mesh_j = 0; mesh_j < gy; mesh_j++) { param_matrix[mesh_i][mesh_j] = eval_gen_expr(eqn_ptr); } } /* Now that this parameter has been referenced with a per pixel equation, we let the evaluator know by setting this flag */ per_pixel_eqn->param->matrix_flag = 1; }
/* Evaluates an expression tree */ static inline double eval_tree_expr(tree_expr_t * tree_expr) { double left_arg, right_arg; infix_op_t * infix_op; /* Shouldn't happen */ if (tree_expr == NULL) return EVAL_ERROR; /* A leaf node, evaluate the general expression. If the expression is null as well, return zero */ if (tree_expr->infix_op == NULL) { if (tree_expr->gen_expr == NULL) return 0; else return eval_gen_expr(tree_expr->gen_expr); } /* Otherwise, this node is an infix operator. Evaluate accordingly */ infix_op = (infix_op_t*)tree_expr->infix_op; #ifdef EVAL_DEBUG printf("("); fflush(stdout); #endif left_arg = eval_tree_expr(tree_expr->left); #ifdef EVAL_DEBUG switch (infix_op->type) { case INFIX_ADD: printf("+"); break; case INFIX_MINUS: printf("-"); break; case INFIX_MULT: printf("*"); break; case INFIX_MOD: printf("%%"); break; case INFIX_OR: printf("|"); break; case INFIX_AND: printf("&"); break; case INFIX_DIV: printf("/"); break; default: printf("?"); } fflush(stdout); #endif right_arg = eval_tree_expr(tree_expr->right); #ifdef EVAL_DEBUG printf(")"); fflush(stdout); #endif switch (infix_op->type) { case INFIX_ADD: return (left_arg + right_arg); case INFIX_MINUS: return (left_arg - right_arg); case INFIX_MULT: return (left_arg * right_arg); case INFIX_MOD: if ((int)right_arg == 0) { #ifdef EVAL_DEBUG printf("eval_tree_expr: modulo zero!\n"); #endif return DIV_BY_ZERO; } return ((int)left_arg % (int)right_arg); case INFIX_OR: return ((int)left_arg | (int)right_arg); case INFIX_AND: return ((int)left_arg & (int)right_arg); case INFIX_DIV: if (right_arg == 0) { #ifdef EVAL_DEBUG printf("eval_tree_expr: division by zero!\n"); #endif return MAX_DOUBLE_SIZE; } return (left_arg / right_arg); default: #ifdef EVAL_DEBUG printf("eval_tree_expr: unknown infix operator!\n"); #endif return ERROR; } return ERROR; }