⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 eval.c

📁 video linux conference
💻 C
📖 第 1 页 / 共 2 页
字号:
/***************************************************************************** * eval.c: ***************************************************************************** * Copyright (C) 2004 VideoLAN * $Id: eval.c 10101 2005-03-02 16:47:31Z robux4 $ * * Authors: Cyril Deguet <asmax@videolan.org> *          code from projectM http://xmms-projectm.sourceforge.net * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA. *****************************************************************************//* Evaluation Code */#include <stdio.h>#include <stdlib.h>#include "common.h"#include "fatal.h"#include "param_types.h"#include "func_types.h"#include "expr_types.h"#include "eval.h"#include "engine_vars.h"#include "builtin_funcs.h"#define EVAL_ERROR -1/* All infix operators (except '=') are prototyped here */infix_op_t * infix_add, * infix_minus, * infix_div, * infix_mult,  * infix_or, * infix_and, * infix_mod, * infix_negative, * infix_positive;int mesh_i=-1, mesh_j=-1;static inline double eval_tree_expr(tree_expr_t * tree_expr);static inline double eval_prefun_expr(prefun_expr_t * prefun_expr);static inline double eval_val_expr(val_expr_t * val_expr);inline double eval_gen_expr(gen_expr_t * gen_expr) {  double l;  if (gen_expr == NULL)     	return 0; 	  switch(gen_expr->type) {  case VAL_T:      return eval_val_expr(gen_expr->item);  case PREFUN_T:    l = eval_prefun_expr(gen_expr->item);    //if (EVAL_DEBUG) printf("eval_gen_expr: prefix function return value: %f\n", l);    return l;		  case TREE_T:    return eval_tree_expr(gen_expr->item);  default:    #ifdef EVAL_DEBUG    printf("eval_gen_expr: general expression matched no cases!\n");    #endif    return EVAL_ERROR;  }  	}/* 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);	}	/* Evaluates a value expression */static inline double eval_val_expr(val_expr_t * val_expr) {  /* Shouldn't happen */  if (val_expr == NULL)    return EVAL_ERROR;  /* Value is a constant, return the double value */  if (val_expr->type == CONSTANT_TERM_T) {    #ifdef EVAL_DEBUG 		printf("%.4f", val_expr->term.constant);		fflush(stdout);    #endif    return (val_expr->term.constant);  }  /* Value is variable, dereference it */  if (val_expr->type == PARAM_TERM_T) {   	switch (val_expr->term.param->type) {			case P_TYPE_BOOL:		#ifdef EVAL_DEBUG 			printf("(%s:%.4f)", val_expr->term.param->name, (double)(*((int*)(val_expr->term.param->engine_val))));			fflush(stdout);		#endif	       		  		return (double)(*((int*)(val_expr->term.param->engine_val)));	case P_TYPE_INT:		#ifdef EVAL_DEBUG 			printf("(%s:%.4f)", val_expr->term.param->name, (double)(*((int*)(val_expr->term.param->engine_val))));			fflush(stdout);		#endif	     		return (double)(*((int*)(val_expr->term.param->engine_val)));	case P_TYPE_DOUBLE:				#ifdef EVAL_DEBUG 			printf("(%s:%.4f)", val_expr->term.param->name, (*((double*)val_expr->term.param->engine_val)));			fflush(stdout);		#endif					if (val_expr->term.param->matrix_flag | (val_expr->term.param->flags & P_FLAG_ALWAYS_MATRIX)) {		  if (mesh_j >= 0) {		    return (((double**)val_expr->term.param->matrix)[mesh_i][mesh_j]);		  }		  else {		    return (((double*)val_expr->term.param->matrix)[mesh_i]);		  }		}		return *((double*)(val_expr->term.param->engine_val));	default:	  return ERROR;	    }  }  /* Unknown type, return failure */  return FAILURE;}/* 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;}	/* Converts a double value to a general expression */gen_expr_t * const_to_expr(double val) {  gen_expr_t * gen_expr;  val_expr_t * val_expr;  term_t term;    term.constant = val;      if ((val_expr = new_val_expr(CONSTANT_TERM_T, term)) == NULL)    return NULL;  gen_expr = new_gen_expr(VAL_T, (void*)val_expr);  if (gen_expr == NULL) {	free_val_expr(val_expr);  }    return gen_expr;}/* Converts a regular parameter to an expression */gen_expr_t * param_to_expr(param_t * param) {  gen_expr_t * gen_expr = NULL;  val_expr_t * val_expr = NULL;  term_t term;  if (param == NULL)    return NULL;   /* This code is still a work in progress. We need     to figure out if the initial condition is used for      each per frame equation or not. I am guessing that     it isn't, and it is thusly implemented this way */    /* Current guess of true behavior (08/01/03) note from carm     First try to use the per_pixel_expr (with cloning).      If it is null however, use the engine variable instead. */    /* 08/20/03 : Presets are now objects, as well as per pixel equations. This ends up     making the parser handle the case where parameters are essentially per pixel equation     substitutions */           term.param = param;  if ((val_expr = new_val_expr(PARAM_TERM_T, term)) == NULL)    return NULL;    if ((gen_expr = new_gen_expr(VAL_T, (void*)val_expr)) == NULL) {    free_val_expr(val_expr);	return NULL;	    }   return gen_expr;}/* Converts a prefix function to an expression */gen_expr_t * prefun_to_expr(double (*func_ptr)(), gen_expr_t ** expr_list, int num_args) {  gen_expr_t * gen_expr;  prefun_expr_t * prefun_expr;    /* Malloc a new prefix function expression */  prefun_expr = (prefun_expr_t*)malloc(sizeof(prefun_expr_t));  if (prefun_expr == NULL)	  return NULL;    prefun_expr->num_args = num_args;  prefun_expr->func_ptr = func_ptr;  prefun_expr->expr_list = expr_list;  gen_expr = new_gen_expr(PREFUN_T, (void*)prefun_expr);  if (gen_expr == NULL)	  free_prefun_expr(prefun_expr);    return gen_expr;}/* Creates a new tree expression */tree_expr_t * new_tree_expr(infix_op_t * infix_op, gen_expr_t * gen_expr, tree_expr_t * left, tree_expr_t * right) {		tree_expr_t * tree_expr;		tree_expr = (tree_expr_t*)malloc(sizeof(tree_expr_t));			if (tree_expr == NULL)			return NULL;		tree_expr->infix_op = infix_op;		tree_expr->gen_expr = gen_expr;		tree_expr->left = left;		tree_expr->right = right;		return tree_expr;}/* Creates a new value expression */val_expr_t * new_val_expr(int type, term_t term) {  val_expr_t * val_expr;  val_expr = (val_expr_t*)malloc(sizeof(val_expr_t));  if (val_expr == NULL)    return NULL;  val_expr->type = type;  val_expr->term = term;  return val_expr;}/* Creates a new general expression */gen_expr_t * new_gen_expr(int type, void * item) {	gen_expr_t * gen_expr;	gen_expr = (gen_expr_t*)malloc(sizeof(gen_expr_t));

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -