Max 5 API Reference
00001 /* 00002 jit.expr.c 00003 00004 Copyright 2001-2005 - Cycling '74 00005 Joshua Kit Clayton jkc@cycling74.com 00006 00007 */ 00008 00009 00010 #include "jit.common.h" 00011 #include "jit.tree.h" 00012 #include "ext_obex.h" 00013 #include "jit.functor.h" 00014 #include "pcre.h" 00015 00016 /* 00017 // EXPR = FUNCTION GROUP | EXPR INOP EXPR | GROUP | NUMBER | VARIABLE 00018 // GROUP = LPAREN EXPR RPAREN | LPAREN EXPR COMMA EXPR RPAREN 00019 // FUNCTION = WORD in JitterExprOps 00020 // INOP = SPECIAL in JitterExprInfixOps 00021 // COMMA = , 00022 // LPAREN = ( 00023 // RPAREN = ) 00024 // NUMBER = [0-9]+\.?[0-9]* | [0-9]*\.?[0-9]+ 00025 // WORD = [a-zA-Z]+(\w*)*(\[[0-9]+\])? (allow for indexing) 00026 // SPECIAL (\*|\/|\+|\-|%|&&|&|\|\||\||>\=|>|<\=|<|\=\=|\=|\!\=|\!) 00027 00028 // first pass: tokenize on COMMA, LPAREN, RPAREN, WORD, NUMBER, SPECIAL 00029 var tokens = e.match(/(\,)|(\()|(\))|(([a-z]|[A-Z])+\w*(\[[0-9]+\])?)|(([0-9]*\.?[0-9]+)|([0-9]+\.?[0-9]*))|(\*|\/|\+|\-|%|&&|&|\|\||\||>\=|>|<\=|<|\=\=|\=|\!\=|\!)/g); 00030 */ 00031 00032 #define STORAGE_VECTOR 512 00033 #define JIT_EXPR_NORM 0 00034 #define JIT_EXPR_SNORM 1 00035 #define JIT_EXPR_CELL 2 00036 00037 #define TOKEN_RE "(\\,)|(\\()|(\\))|((@?([a-z]|[A-Z])+\\w*(\\[[0-9]+\\])?)(\\.([a-z]|[A-Z])+\\w*(\\[[0-9]+\\])*)?)|(([0-9]*\\.?[0-9]+)|([0-9]+\\.?[0-9]*))|(\\*|\\/|\\+|\\-|%|&&|&|\\|\\||\\||>\\=|>|<\\=|<|\\=\\=|\\=|\\!\\=|\\!)" 00038 #define WORD_RE "((@?([a-z]|[A-Z])+\\w*(\\[[0-9]+\\])?)(\\.([a-z]|[A-Z])+\\w*(\\[[0-9]+\\])?)*)" 00039 #define NUMBER_RE "(([0-9]*\\.?[0-9]+)|([0-9]+\\.?[0-9]*))" 00040 #define SPECIAL_RE "(\\*|\\/|\\+|\\-|%|&&|&|\\|\\||\\||>\\=|>|<\\=|<|\\=\\=|\\=|\\!\\=|\\!)" 00041 00042 #define JIT_EXPR_TOKEN_FLAG_TEXT_VAL 0x00000001 00043 #define JIT_EXPR_TOKEN_FLAG_INT_VAL 0x00000002 00044 #define JIT_EXPR_TOKEN_FLAG_DOUBLE_VAL 0x00000004 00045 #define JIT_EXPR_TOKEN_FLAG_SYMBOL_VAL 0x00000008 00046 00047 #define JIT_EXPR_TOKEN_TYPE_UNKNOWN 0 00048 #define JIT_EXPR_TOKEN_TYPE_WORD 1 00049 #define JIT_EXPR_TOKEN_TYPE_NUMBER 2 00050 #define JIT_EXPR_TOKEN_TYPE_SPECIAL 3 00051 #define JIT_EXPR_TOKEN_TYPE_LPAREN 4 00052 #define JIT_EXPR_TOKEN_TYPE_RPAREN 5 00053 #define JIT_EXPR_TOKEN_TYPE_COMMA 6 00054 #define JIT_EXPR_TOKEN_TYPE_SEMI 7 00055 #define JIT_EXPR_TOKEN_TYPE_GROUP 8 00056 #define JIT_EXPR_TOKEN_TYPE_INOP 9 00057 #define JIT_EXPR_TOKEN_TYPE_OP 10 00058 #define JIT_EXPR_TOKEN_TYPE_VARIABLE 11 00059 #define JIT_EXPR_TOKEN_TYPE_CONSTANT 12 00060 #define JIT_EXPR_TOKEN_TYPE_ATTRIBUTE 13 //later for arbitrary jitter object support 00061 00062 00063 /* when we support ints 00064 #define JIT_EXPR_PRECEDENCE_MIN 1 00065 #define JIT_EXPR_PRECEDENCE_PREFIX 1 00066 #define JIT_EXPR_PRECEDENCE_MULT 2 00067 #define JIT_EXPR_PRECEDENCE_ADD 3 00068 #define JIT_EXPR_PRECEDENCE_SHIFT 4 00069 #define JIT_EXPR_PRECEDENCE_COMPARISON 5 00070 #define JIT_EXPR_PRECEDENCE_EQ 6 00071 #define JIT_EXPR_PRECEDENCE_BITAND 7 00072 #define JIT_EXPR_PRECEDENCE_BITXOR 8 00073 #define JIT_EXPR_PRECEDENCE_BITOR 9 00074 #define JIT_EXPR_PRECEDENCE_AND 10 00075 #define JIT_EXPR_PRECEDENCE_OR 11 00076 #define JIT_EXPR_PRECEDENCE_MAX 11 00077 */ 00078 00079 // float ops only 00080 #define JIT_EXPR_PRECEDENCE_MIN 1 00081 #define JIT_EXPR_PRECEDENCE_PREFIX 1 00082 #define JIT_EXPR_PRECEDENCE_MULT 2 00083 #define JIT_EXPR_PRECEDENCE_ADD 3 00084 #define JIT_EXPR_PRECEDENCE_COMPARISON 4 00085 #define JIT_EXPR_PRECEDENCE_EQ 5 00086 #define JIT_EXPR_PRECEDENCE_AND 6 00087 #define JIT_EXPR_PRECEDENCE_OR 7 00088 #define JIT_EXPR_PRECEDENCE_MAX 7 00089 00090 typedef struct _jit_expr 00091 { 00092 t_object ob; 00093 t_symbol *exprsyms[JIT_MATRIX_MAX_PLANECOUNT]; 00094 long exprcount; 00095 long exprindex; 00096 t_jit_tree *exprtrees[JIT_MATRIX_MAX_PLANECOUNT]; 00097 t_symbol *precision; 00098 t_hashtab *operators; 00099 t_hashtab *constants; 00100 t_hashtab *variables; 00101 long verbose; 00102 long execplane; 00103 long cache; 00104 } t_jit_expr; 00105 00106 typedef struct _jit_expr_token 00107 { 00108 t_object ob; 00109 long type; 00110 long cache; 00111 long didinfix; 00112 t_atom val; 00113 t_jit_object *data; 00114 t_jit_object *aux1; 00115 t_jit_object *aux2; 00116 // data could be matrix, vector data + operator objects, etc. 00117 // but should be object so it knows how to clean up 00118 } t_jit_expr_token; 00119 00120 typedef struct _jit_expr_mxfn 00121 { 00122 t_object ob; 00123 method mxfn; 00124 // index integers useful for quickly resolving dim[0], cell[0], etc. 00125 long a; 00126 long b; 00127 long c; 00128 long nocache; 00129 } t_jit_expr_mxfn; 00130 00131 typedef struct _jit_expr_infixop 00132 { 00133 t_object ob; 00134 t_symbol *special; 00135 t_symbol *prefix; 00136 long precedence; 00137 } t_jit_expr_infixop; 00138 00139 00140 void *_jit_expr_class=NULL; 00141 void *_jit_expr_token_class=NULL; 00142 void *_jit_expr_mxfn_class=NULL; 00143 void *_jit_expr_infixop_class=NULL; 00144 00145 t_jit_err jit_expr_init(void); 00146 t_jit_expr *jit_expr_new(void); 00147 void jit_expr_free(t_jit_expr *x); 00148 t_jit_err jit_expr_matrix_calc(t_jit_expr *x, void *inputs, void *outputs); 00149 void jit_expr_freetrees(t_jit_expr *x); 00150 void jit_expr_resetsyms(t_jit_expr *x); 00151 t_jit_err jit_expr_expr(t_jit_expr *x, t_jit_object *attr, long argc, t_atom *argv); 00152 t_jit_err jit_expr_parse(t_jit_expr *x); 00153 t_jit_err jit_expr_sym2tok(t_jit_expr *x, long i); 00154 long jit_expr_token2type(char *str); 00155 void jit_expr_append_token(t_jit_expr *x, long i, char *str); 00156 t_jit_err jit_expr_buildtree(t_jit_expr *x, t_jit_tree_node *node); 00157 t_jit_err jit_expr_infix2prefix(t_jit_expr *x, t_jit_tree_node *node); 00158 t_jit_err jit_expr_cleantree(t_jit_expr *x, t_jit_tree_node *node); 00159 t_jit_err jit_expr_flattenconstants(t_jit_expr *x, t_jit_tree_node *node); 00160 t_jit_err jit_expr_prepcalc(t_jit_expr *x, t_jit_tree_node *node, t_jit_object *inputlist, t_jit_matrix_info *info, long *pcache); 00161 t_jit_object *jit_expr_treecalc(t_jit_expr *x, t_jit_tree_node *node); 00162 long jit_expr_wordisoperator(t_jit_expr *x, t_symbol *s); 00163 t_jit_object *jit_expr_wordisexprop(t_jit_expr *x, t_symbol *s); 00164 long jit_expr_wordisfunctor(t_jit_expr *x, t_symbol *s); 00165 t_symbol *jit_expr_wordisattribute(t_jit_expr *x, t_symbol *s); 00166 t_class * jit_expr_wordisclass(t_jit_expr *x, t_symbol *s); 00167 long jit_expr_wordisconstant(t_jit_expr *x, t_symbol *s, double **val); 00168 long jit_expr_specialisinfix(t_jit_expr *x, t_symbol *s); 00169 void jit_expr_printtree(t_jit_expr *x, long i); 00170 void jit_expr_printtree_helper(t_jit_expr *x, t_jit_tree_node *node, long depth); 00171 00172 t_jit_expr_token *jit_expr_token_new(long type, t_atom *val); 00173 void jit_expr_token_free(t_jit_expr_token *x); 00174 void jit_expr_token_data(t_jit_expr_token *x, t_jit_object *data); 00175 t_jit_object *jit_expr_token_getdata(t_jit_expr_token *x); 00176 00177 t_jit_expr_mxfn *jit_expr_mxfn_new(method mxfn, long a, long b, long c, long nocache); 00178 void jit_expr_mxfn_free(t_jit_expr_mxfn *x); 00179 00180 t_jit_expr_infixop *jit_expr_infixop_new(t_symbol *special, t_symbol *prefix, long precedence); 00181 void jit_expr_infixop_free(t_jit_expr_infixop *x); 00182 00183 t_jit_err jit_expr_mxfn_default(t_jit_expr *x, t_jit_tree_node *node, t_jit_object *inputlist, t_jit_matrix_info *info); 00184 t_jit_err jit_expr_mxfn_dim(t_jit_expr *x, t_jit_tree_node *node, t_jit_object *inputlist, t_jit_matrix_info *info, long a, long b, long c); 00185 t_jit_err jit_expr_mxfn_norm(t_jit_expr *x, t_jit_tree_node *node, t_jit_object *inputlist, t_jit_matrix_info *info, long a, long b, long c); 00186 t_jit_err jit_expr_mxfn_input(t_jit_expr *x, t_jit_tree_node *node, t_jit_object *inputlist, t_jit_matrix_info *info, long a, long b, long c); 00187 t_jit_err jit_expr_mxfn_input_plane(t_jit_expr *x, t_jit_tree_node *node, t_jit_object *inputlist, t_jit_matrix_info *info, long a, long b, long c); 00188 00189 void jit_expr_pcre_init(void); 00190 void jit_expr_pcre_dispose(void); 00191 00192 static pcre *re_token=NULL; 00193 static pcre_extra *pe_token=NULL; 00194 static pcre *re_word=NULL; 00195 static pcre_extra *pe_word=NULL; 00196 static pcre *re_number=NULL; 00197 static pcre_extra *pe_number=NULL; 00198 static pcre *re_special=NULL; 00199 static pcre_extra *pe_special=NULL; 00200 00201 static t_hashtab *_jit_expr_mxfns=NULL; 00202 static t_hashtab *_jit_expr_constants=NULL; 00203 static t_hashtab *_jit_expr_infixmap=NULL; 00204 00205 static double _jit_expr_constant_pi = JIT_MATH_F64_PI; 00206 static double _jit_expr_constant_twopi = JIT_MATH_F64_TWO_PI; 00207 static double _jit_expr_constant_halfpi = JIT_MATH_F64_HALF_PI; 00208 static double _jit_expr_constant_invpi = JIT_MATH_F64_INV_PI; 00209 static double _jit_expr_constant_degtorad = JIT_MATH_F64_DEGTORAD; 00210 static double _jit_expr_constant_radtodeg = JIT_MATH_F64_RADTODEG; 00211 static double _jit_expr_constant_e = 2.71828182845905; 00212 static double _jit_expr_constant_ln2 = 0.6931471805599453; 00213 static double _jit_expr_constant_ln10 = 2.302585092994046; 00214 static double _jit_expr_constant_log10e = 0.4342944819032518; 00215 static double _jit_expr_constant_log2e = 1.442695040888963387; 00216 static double _jit_expr_constant_sqrt2 = 1.4142135623730951; 00217 static double _jit_expr_constant_sqrt1_2 = 0.7071067811865476; 00218 00219 static t_symbol *ps_sub,*ps_sub_char,*ps_op,*ps_basis,*ps_setattr,*ps_jitter; 00220 00221 static char *_jit_expr_token_str[] = 00222 { 00223 "UNKNOWN", 00224 "WORD", 00225 "NUMBER", 00226 "SPECIAL", 00227 "LPAREN", 00228 "RPAREN", 00229 "COMMA", 00230 "SEMI", 00231 "GROUP", 00232 "INOP", 00233 "OP", 00234 "VARIABLE", 00235 "CONSTANT", 00236 "ATTRIBUTE" 00237 }; 00238 00239 t_jit_err jit_expr_init() 00240 { 00241 void *attr,*mop; 00242 long attrflags,i,j; 00243 char tmpstr[256]; 00244 00245 // jit_expr class 00246 _jit_expr_class = jit_class_new("jit_expr",(method)jit_expr_new,(method)jit_expr_free, 00247 sizeof(t_jit_expr),0L); 00248 00249 //add mop 00250 mop = jit_object_new(_jit_sym_jit_mop,-1,1); 00251 jit_class_addadornment(_jit_expr_class,mop); 00252 00253 attrflags = JIT_ATTR_GET_DEFER_LOW | JIT_ATTR_SET_USURP_LOW ; 00254 attr = jit_object_new(_jit_sym_jit_attr_offset_array,"expr",_jit_sym_symbol,JIT_MATRIX_MAX_PLANECOUNT,attrflags, 00255 (method)0L,(method)jit_expr_expr,calcoffset(t_jit_expr,exprcount),calcoffset(t_jit_expr,exprsyms)); 00256 jit_class_addattr(_jit_expr_class,attr); 00257 attr = jit_object_new(_jit_sym_jit_attr_offset,"precision",_jit_sym_symbol,attrflags, 00258 (method)0L,(method)0L,calcoffset(t_jit_expr,precision)); 00259 jit_class_addattr(_jit_expr_class,attr); 00260 attr = jit_object_new(_jit_sym_jit_attr_offset,"verbose",_jit_sym_long,attrflags, 00261 (method)0L,(method)0L,calcoffset(t_jit_expr,verbose)); 00262 jit_class_addattr(_jit_expr_class,attr); 00263 attr = jit_object_new(_jit_sym_jit_attr_offset,"cache",_jit_sym_long,attrflags, 00264 (method)0L,(method)0L,calcoffset(t_jit_expr,cache)); 00265 jit_class_addattr(_jit_expr_class,attr); 00266 00267 jit_class_addmethod(_jit_expr_class, (method)jit_expr_matrix_calc, "matrix_calc", A_CANT, 0L); 00268 00269 jit_class_register(_jit_expr_class); 00270 00271 00272 // jit_expr_token class 00273 _jit_expr_token_class = jit_class_new("jit_expr_token",(method)jit_expr_token_new,(method)jit_expr_token_free, 00274 sizeof(t_jit_expr_token),A_CANT,0L); //A_CANT = untyped 00275 00276 attrflags = 0; 00277 attr = jit_object_new(_jit_sym_jit_attr_offset,"type",_jit_sym_long,attrflags, 00278 (method)0L,(method)0L,calcoffset(t_jit_expr_token,type)); 00279 jit_class_addattr(_jit_expr_token_class,attr); 00280 attr = jit_object_new(_jit_sym_jit_attr_offset,"val",_jit_sym_atom,attrflags, 00281 (method)0L,(method)0L,calcoffset(t_jit_expr_token,val)); 00282 jit_class_addattr(_jit_expr_token_class,attr); 00283 00284 //could add getvalueof/setvalueof methods? 00285 jit_class_addmethod(_jit_expr_token_class, (method)jit_expr_token_data, "data" , A_CANT, 0L); 00286 jit_class_addmethod(_jit_expr_token_class, (method)jit_expr_token_getdata, "getdata" , A_CANT, 0L); 00287 00288 jit_class_register(_jit_expr_token_class); 00289 00290 // jit_expr_mxfn class 00291 _jit_expr_mxfn_class = jit_class_new("jit_expr_mxfn",(method)jit_expr_mxfn_new,(method)jit_expr_mxfn_free, 00292 sizeof(t_jit_expr_mxfn),A_CANT,0L); //A_CANT = untyped 00293 00294 jit_class_register(_jit_expr_mxfn_class); 00295 00296 // jit_expr_infixop class 00297 _jit_expr_infixop_class = jit_class_new("jit_expr_infixop",(method)jit_expr_infixop_new,(method)jit_expr_infixop_free, 00298 sizeof(t_jit_expr_infixop),A_CANT,0L); //A_CANT = untyped 00299 00300 jit_class_register(_jit_expr_infixop_class); 00301 00302 00303 jit_expr_pcre_init(); 00304 00305 _jit_expr_mxfns = hashtab_new(0); 00306 for (i=0;i<JIT_MATRIX_MAX_DIMCOUNT;i++) { 00307 sprintf(tmpstr,"dim[%d]",i); 00308 hashtab_store(_jit_expr_mxfns,gensym(tmpstr),(t_object *)jit_expr_mxfn_new((method)jit_expr_mxfn_dim,i,0,0,0)); 00309 sprintf(tmpstr,"norm[%d]",i); 00310 hashtab_store(_jit_expr_mxfns,gensym(tmpstr),(t_object *)jit_expr_mxfn_new((method)jit_expr_mxfn_norm,i,JIT_EXPR_NORM,0,0)); 00311 sprintf(tmpstr,"snorm[%d]",i); 00312 hashtab_store(_jit_expr_mxfns,gensym(tmpstr),(t_object *)jit_expr_mxfn_new((method)jit_expr_mxfn_norm,i,JIT_EXPR_SNORM,0,0)); 00313 sprintf(tmpstr,"cell[%d]",i); 00314 hashtab_store(_jit_expr_mxfns,gensym(tmpstr),(t_object *)jit_expr_mxfn_new((method)jit_expr_mxfn_norm,i,JIT_EXPR_CELL,0,0)); 00315 sprintf(tmpstr,"in[%d]",i); 00316 hashtab_store(_jit_expr_mxfns,gensym(tmpstr),(t_object *)jit_expr_mxfn_new((method)jit_expr_mxfn_input,i,0,0,1)); 00317 for (j=0;j<JIT_MATRIX_MAX_DIMCOUNT;j++) { 00318 sprintf(tmpstr,"in[%d].p[%d]",i,j); 00319 hashtab_store(_jit_expr_mxfns,gensym(tmpstr),(t_object *)jit_expr_mxfn_new((method)jit_expr_mxfn_input_plane,i,j,0,1)); 00320 } 00321 } 00322 00323 _jit_expr_constants = hashtab_new(0); 00324 hashtab_store(_jit_expr_constants,gensym("PI"),(t_object *)&_jit_expr_constant_pi); 00325 hashtab_store(_jit_expr_constants,gensym("TWOPI"),(t_object *)&_jit_expr_constant_twopi); 00326 hashtab_store(_jit_expr_constants,gensym("HALFPI"),(t_object *)&_jit_expr_constant_halfpi); 00327 hashtab_store(_jit_expr_constants,gensym("INVPI"),(t_object *)&_jit_expr_constant_invpi); 00328 hashtab_store(_jit_expr_constants,gensym("DEGTORAD"),(t_object *)&_jit_expr_constant_degtorad); 00329 hashtab_store(_jit_expr_constants,gensym("RADTODEG"),(t_object *)&_jit_expr_constant_radtodeg); 00330 hashtab_store(_jit_expr_constants,gensym("E"),(t_object *)&_jit_expr_constant_e); 00331 hashtab_store(_jit_expr_constants,gensym("LN2"),(t_object *)&_jit_expr_constant_ln2); 00332 hashtab_store(_jit_expr_constants,gensym("LN10"),(t_object *)&_jit_expr_constant_ln10); 00333 hashtab_store(_jit_expr_constants,gensym("LOG10E"),(t_object *)&_jit_expr_constant_log10e); 00334 hashtab_store(_jit_expr_constants,gensym("LOG2E"),(t_object *)&_jit_expr_constant_log2e); 00335 hashtab_store(_jit_expr_constants,gensym("SQRT2"),(t_object *)&_jit_expr_constant_sqrt2); 00336 hashtab_store(_jit_expr_constants,gensym("SQRT1_2"),(t_object *)&_jit_expr_constant_sqrt1_2); 00337 00338 _jit_expr_infixmap = hashtab_new(0); 00339 hashtab_store(_jit_expr_infixmap,gensym("*"),(t_object *)jit_expr_infixop_new(gensym("*"),gensym("mult"),JIT_EXPR_PRECEDENCE_MULT)); 00340 hashtab_store(_jit_expr_infixmap,gensym("/"),(t_object *)jit_expr_infixop_new(gensym("/"),gensym("div"),JIT_EXPR_PRECEDENCE_MULT)); 00341 hashtab_store(_jit_expr_infixmap,gensym("%"),(t_object *)jit_expr_infixop_new(gensym("%"),gensym("mod"),JIT_EXPR_PRECEDENCE_MULT)); 00342 hashtab_store(_jit_expr_infixmap,gensym("+"),(t_object *)jit_expr_infixop_new(gensym("+"),gensym("add"),JIT_EXPR_PRECEDENCE_ADD)); 00343 hashtab_store(_jit_expr_infixmap,gensym("-"),(t_object *)jit_expr_infixop_new(gensym("-"),gensym("sub"),JIT_EXPR_PRECEDENCE_ADD)); 00344 // hashtab_store(_jit_expr_infixmap,gensym("&"),(t_object *)jit_expr_infixop_new(gensym("&"),gensym("bitand"),JIT_EXPR_PRECEDENCE_BITAND)); 00345 // hashtab_store(_jit_expr_infixmap,gensym("|"),(t_object *)jit_expr_infixop_new(gensym("|"),gensym("bitor"),JIT_EXPR_PRECEDENCE_BITOR)); 00346 // hashtab_store(_jit_expr_infixmap,gensym("^"),(t_object *)jit_expr_infixop_new(gensym("^"),gensym("bitxor"),JIT_EXPR_PRECEDENCE_BITXOR)); 00347 // hashtab_store(_jit_expr_infixmap,gensym("~"),(t_object *)jit_expr_infixop_new(gensym("~"),gensym("bitnot"),JIT_EXPR_PRECEDENCE_PREFIX)); 00348 // hashtab_store(_jit_expr_infixmap,gensym(">>"),(t_object *)jit_expr_infixop_new(gensym(">>"),gensym("rshift"),JIT_EXPR_PRECEDENCE_SHIFT)); 00349 // hashtab_store(_jit_expr_infixmap,gensym("<<"),(t_object *)jit_expr_infixop_new(gensym("<<"),gensym("lshift"),JIT_EXPR_PRECEDENCE_SHIFT)); 00350 hashtab_store(_jit_expr_infixmap,gensym("&&"),(t_object *)jit_expr_infixop_new(gensym("&&"),gensym("and"),JIT_EXPR_PRECEDENCE_AND)); 00351 hashtab_store(_jit_expr_infixmap,gensym("||"),(t_object *)jit_expr_infixop_new(gensym("||"),gensym("or"),JIT_EXPR_PRECEDENCE_OR)); 00352 hashtab_store(_jit_expr_infixmap,gensym("!"),(t_object *)jit_expr_infixop_new(gensym("!"),gensym("not"),JIT_EXPR_PRECEDENCE_PREFIX)); 00353 hashtab_store(_jit_expr_infixmap,gensym(">"),(t_object *)jit_expr_infixop_new(gensym(">"),gensym("gt"),JIT_EXPR_PRECEDENCE_COMPARISON)); 00354 hashtab_store(_jit_expr_infixmap,gensym("<"),(t_object *)jit_expr_infixop_new(gensym("<"),gensym("lt"),JIT_EXPR_PRECEDENCE_COMPARISON)); 00355 hashtab_store(_jit_expr_infixmap,gensym(">="),(t_object *)jit_expr_infixop_new(gensym(">="),gensym("gte"),JIT_EXPR_PRECEDENCE_COMPARISON)); 00356 hashtab_store(_jit_expr_infixmap,gensym("<="),(t_object *)jit_expr_infixop_new(gensym("<="),gensym("lte"),JIT_EXPR_PRECEDENCE_COMPARISON)); 00357 hashtab_store(_jit_expr_infixmap,gensym("=="),(t_object *)jit_expr_infixop_new(gensym("=="),gensym("eq"),JIT_EXPR_PRECEDENCE_EQ)); 00358 hashtab_store(_jit_expr_infixmap,gensym("!="),(t_object *)jit_expr_infixop_new(gensym("!="),gensym("neq"),JIT_EXPR_PRECEDENCE_EQ)); 00359 00360 ps_op = gensym("op"); 00361 ps_sub = gensym("sub"); 00362 ps_sub_char = gensym("-"); 00363 ps_basis = gensym("basis"); 00364 ps_setattr = gensym("setattr"); 00365 ps_jitter = gensym("jitter"); 00366 00367 return JIT_ERR_NONE; 00368 } 00369 00370 t_jit_expr *jit_expr_new() 00371 { 00372 t_jit_expr *x; 00373 long i; 00374 00375 if (x = (t_jit_expr *)jit_object_alloc(_jit_expr_class)) { 00376 jit_expr_resetsyms(x); 00377 x->exprcount = 0; 00378 x->exprindex = 0; 00379 for (i=0;i<JIT_MATRIX_MAX_PLANECOUNT;i++) 00380 x->exprtrees[i] = NULL; 00381 x->precision = _jit_sym_float32; 00382 x->operators = NULL; 00383 x->constants = NULL; 00384 x->variables = NULL; 00385 x->verbose = 0; 00386 x->cache = 1; 00387 00388 } 00389 return x; 00390 } 00391 00392 void jit_expr_free(t_jit_expr *x) 00393 { 00394 jit_expr_freetrees(x); 00395 if (x->operators) 00396 object_free(x->operators); 00397 if (x->constants) 00398 object_free(x->constants); 00399 if (x->variables) 00400 object_free(x->variables); 00401 } 00402 00403 t_jit_err jit_expr_matrix_calc(t_jit_expr *x, void *inputs, void *outputs) 00404 { 00405 t_jit_err err=JIT_ERR_NONE; 00406 long out_savelock; 00407 t_jit_matrix_info out_minfo,calcinfo; 00408 t_matrix_conv_info convinfo; 00409 char *out_bp; 00410 long i,j,cache,dimcount,planecount,dim[JIT_MATRIX_MAX_DIMCOUNT]; 00411 void *out_matrix,*result_matrix; 00412 00413 out_matrix = jit_object_method(outputs,_jit_sym_getindex,0); 00414 00415 if (x&&out_matrix) { 00416 out_savelock = (long) jit_object_method(out_matrix,_jit_sym_lock,1); 00417 jit_object_method(out_matrix,_jit_sym_getinfo,&out_minfo); 00418 jit_object_method(out_matrix,_jit_sym_getdata,&out_bp); 00419 if (!out_bp) { err=JIT_ERR_INVALID_OUTPUT; goto out;} 00420 //get dimensions/planecount 00421 dimcount = out_minfo.dimcount; 00422 planecount = out_minfo.planecount; 00423 for (i=0;i<dimcount;i++) { 00424 dim[i] = out_minfo.dim[i]; 00425 } 00426 calcinfo = out_minfo; 00427 calcinfo.type = x->precision; 00428 calcinfo.planecount = 1; 00429 00430 if (x->exprcount) { 00431 for (i=0;i<planecount;i++) { 00432 convinfo.flags = 0; 00433 for (j=0;j<JIT_MATRIX_MAX_PLANECOUNT;j++) { 00434 convinfo.planemap[j] = (i==j)?0:-1; 00435 } 00436 x->execplane = i; 00437 j = i%x->exprcount; 00438 if (!jit_expr_prepcalc(x,(t_jit_tree_node *)x->exprtrees[j],inputs,&calcinfo,&cache)) { 00439 result_matrix = jit_expr_treecalc(x,(t_jit_tree_node *)x->exprtrees[j]); 00440 if (result_matrix) { 00441 jit_object_method(out_matrix,_jit_sym_frommatrix,result_matrix,&convinfo); 00442 } 00443 } 00444 } 00445 } 00446 } else { 00447 return JIT_ERR_INVALID_PTR; 00448 } 00449 00450 out: 00451 jit_object_method(out_matrix,_jit_sym_lock,out_savelock); 00452 return err; 00453 } 00454 00455 void jit_expr_freetrees(t_jit_expr *x) 00456 { 00457 long i; 00458 00459 for (i=0;i<x->exprcount;i++) { 00460 if (x->exprtrees[i]) { 00461 jit_object_free(x->exprtrees[i]); 00462 x->exprtrees[i] = NULL; 00463 } 00464 } 00465 } 00466 00467 void jit_expr_resetsyms(t_jit_expr *x) 00468 { 00469 long i; 00470 00471 for (i=0;i<JIT_MATRIX_MAX_PLANECOUNT;i++) 00472 x->exprsyms[i] = _jit_sym_nothing; 00473 } 00474 00475 t_jit_err jit_expr_expr(t_jit_expr *x, t_jit_object *attr, long argc, t_atom *argv) 00476 { 00477 long i; 00478 char tmpstr[256]; 00479 00480 jit_expr_freetrees(x); 00481 jit_expr_resetsyms(x); 00482 x->exprcount = argc; 00483 for (i=0;i<argc;i++) { 00484 if (argv[i].a_type==A_FLOAT) { 00485 sprintf(tmpstr,"%f",jit_atom_getfloat(argv+i)); 00486 x->exprsyms[i] = gensym(tmpstr); 00487 } else if (argv[i].a_type==A_LONG) { 00488 sprintf(tmpstr,"%ld",jit_atom_getlong(argv+i)); 00489 x->exprsyms[i] = gensym(tmpstr); 00490 } else { 00491 x->exprsyms[i] = jit_atom_getsym(argv+i); 00492 } 00493 } 00494 jit_expr_parse(x); 00495 return JIT_ERR_NONE; 00496 } 00497 00498 t_jit_err jit_expr_parse(t_jit_expr *x) 00499 { 00500 long i; 00501 00502 // parse each expression 00503 for (i=0;i<x->exprcount;i++) { 00504 x->exprindex = i; 00505 // split into tokens (trees built in here) 00506 jit_expr_sym2tok(x,i); 00507 if (x->verbose) { 00508 jit_object_post((t_object *)x,"--------------------------"); 00509 jit_object_post((t_object *)x,"parsed tokens"); 00510 jit_expr_printtree(x,i); 00511 } 00512 if (x->exprtrees[i]) { 00513 if (jit_expr_buildtree(x,(t_jit_tree_node *)x->exprtrees[i])) { 00514 x->exprtrees[i] = NULL; // freed inside build tree 00515 continue; 00516 } 00517 if (x->verbose) { 00518 jit_object_post((t_object *)x,"--------------------------"); 00519 jit_object_post((t_object *)x,"built tree"); 00520 jit_expr_printtree(x,i); 00521 } 00522 00523 if (jit_expr_infix2prefix(x,(t_jit_tree_node *)x->exprtrees[i])) { 00524 jit_object_free(x->exprtrees[i]); 00525 x->exprtrees[i] = NULL; 00526 continue; 00527 } 00528 if (x->verbose) { 00529 jit_object_post((t_object *)x,"--------------------------"); 00530 jit_object_post((t_object *)x,"converted infix to prefix"); 00531 jit_expr_printtree(x,i); 00532 } 00533 00534 if (jit_expr_cleantree(x,(t_jit_tree_node *)x->exprtrees[i])) { 00535 jit_object_free(x->exprtrees[i]); 00536 x->exprtrees[i] = NULL; 00537 continue; 00538 } 00539 if (x->verbose) { 00540 jit_object_post((t_object *)x,"--------------------------"); 00541 jit_object_post((t_object *)x,"cleaned tree"); 00542 jit_expr_printtree(x,i); 00543 } 00544 00545 if (jit_expr_flattenconstants(x,(t_jit_tree_node *)x->exprtrees[i])) { 00546 jit_object_free(x->exprtrees[i]); 00547 x->exprtrees[i] = NULL; 00548 continue; 00549 } 00550 if (x->verbose) { 00551 jit_object_post((t_object *)x,"--------------------------"); 00552 jit_object_post((t_object *)x,"flattened constants"); 00553 jit_expr_printtree(x,i); 00554 } 00555 00556 } 00557 } 00558 return JIT_ERR_NONE; 00559 } 00560 00561 t_jit_err jit_expr_sym2tok(t_jit_expr *x, long i) 00562 { 00563 int ovector[STORAGE_VECTOR]; 00564 long count,size; 00565 long offset = 0; 00566 char *buf; 00567 char *str = x->exprsyms[i]->s_name; 00568 00569 x->exprtrees[i] = jit_tree_new(); 00570 00571 size = strlen(str); 00572 while (true) { 00573 count = pcre_exec(re_token, pe_token, str, size, offset, 0, ovector, STORAGE_VECTOR); 00574 if (count == -1) { // no match 00575 break; 00576 } 00577 else if (count < -1) { // error 00578 jit_object_error((t_object *)x,"jit.expr: PCRE error %d", count); 00579 break; 00580 } 00581 else if (count == 0) { 00582 jit_object_error((t_object *)x,"jit.expr: maximum substrings reached"); 00583 } 00584 // otherwise, we've found a match 00585 00586 pcre_get_substring(str, ovector, count, 0, (const char **)&buf); 00587 jit_expr_append_token(x,i,buf); 00588 pcre_free_substring((const char *)buf); 00589 offset = ovector[1]; 00590 } 00591 return JIT_ERR_NONE; 00592 } 00593 00594 long jit_expr_token2type(char *str) 00595 { 00596 int ovector[STORAGE_VECTOR]; 00597 long count,size; 00598 00599 size = strlen(str); 00600 if (size==1) { 00601 switch (str[0]) { 00602 case ',': 00603 return JIT_EXPR_TOKEN_TYPE_COMMA; 00604 case '(': 00605 return JIT_EXPR_TOKEN_TYPE_LPAREN; 00606 case ')': 00607 return JIT_EXPR_TOKEN_TYPE_RPAREN; 00608 } 00609 } 00610 count = pcre_exec(re_word, pe_word, str, size, 0, 0, ovector, STORAGE_VECTOR); 00611 if (count>=1) 00612 return JIT_EXPR_TOKEN_TYPE_WORD; 00613 count = pcre_exec(re_number, pe_number, str, size, 0, 0, ovector, STORAGE_VECTOR); 00614 if (count>=1) 00615 return JIT_EXPR_TOKEN_TYPE_NUMBER; 00616 count = pcre_exec(re_special, pe_special, str, size, 0, 0, ovector, STORAGE_VECTOR); 00617 if (count>=1) 00618 return JIT_EXPR_TOKEN_TYPE_SPECIAL; 00619 00620 return JIT_EXPR_TOKEN_TYPE_UNKNOWN; 00621 } 00622 00623 void jit_expr_append_token(t_jit_expr *x, long i, char *str) 00624 { 00625 long type; 00626 t_atom a; 00627 float f=0.; 00628 t_jit_expr_token *token; 00629 t_jit_tree_node *node; 00630 00631 if (x->exprtrees[i]) { 00632 type = jit_expr_token2type(str); 00633 if (type==JIT_EXPR_TOKEN_TYPE_NUMBER) { 00634 if (sscanf(str, "%f", &f) < 1) { 00635 jit_object_error((t_object *)x,"%s: bad number", str); 00636 } 00637 jit_atom_setfloat(&a,f); 00638 } else { 00639 jit_atom_setsym(&a,gensym(str)); 00640 } 00641 token = jit_expr_token_new(type,&a); 00642 node = jit_tree_node_new((t_jit_object *)token); 00643 jit_tree_node_appendchild((t_jit_tree_node *)x->exprtrees[i],node); 00644 } else { 00645 jit_object_error((t_object *)x,"jit.expr: no tree to append token"); 00646 } 00647 } 00648 00649 t_jit_err jit_expr_buildtree(t_jit_expr *x, t_jit_tree_node *node) 00650 { 00651 t_jit_tree_node *rootnode,*currentnode,*listnode,*listnodenext; 00652 t_jit_expr_token *listtoken,*listtokennext; 00653 t_jit_linklist *tokenlist; 00654 long i,depth,tokencount; 00655 t_symbol *wordsym; 00656 double *dval=NULL; 00657 t_jit_err err=JIT_ERR_NONE; 00658 00659 if (!node) 00660 return JIT_ERR_GENERIC; 00661 00662 // we are removing the flat list of children 00663 // and replacing "in place", chucking old list 00664 rootnode = node; 00665 tokenlist = rootnode->children; 00666 tokencount = jit_linklist_getsize(tokenlist); 00667 rootnode->children = jit_linklist_new(); 00668 currentnode = rootnode; 00669 depth = 0; 00670 for (i=0;i<tokencount;i++) { 00671 listnode = (t_jit_tree_node *)jit_linklist_getindex(tokenlist,0); 00672 listtoken = (t_jit_expr_token *)listnode->thing; 00673 switch (listtoken->type) { 00674 case JIT_EXPR_TOKEN_TYPE_LPAREN: 00675 // should only make here as a group, not from function 00676 depth++; 00677 listtoken->type = JIT_EXPR_TOKEN_TYPE_GROUP; 00678 jit_atom_setlong(&listtoken->val,0); 00679 jit_tree_node_appendchild(currentnode,listnode); 00680 currentnode = listnode; 00681 jit_linklist_chuckindex(tokenlist,0); 00682 break; 00683 case JIT_EXPR_TOKEN_TYPE_RPAREN: 00684 currentnode = currentnode->parent; 00685 if (!currentnode) { 00686 jit_object_error((t_object *)x,"jit.expr: unmatched parentheses at depth %d in %s", depth, x->exprsyms[x->exprindex]->s_name); 00687 err = JIT_ERR_GENERIC; 00688 goto out; 00689 } 00690 jit_linklist_deleteindex(tokenlist,0); 00691 depth--; 00692 break; 00693 case JIT_EXPR_TOKEN_TYPE_COMMA: 00694 jit_tree_node_appendchild(currentnode,listnode); 00695 jit_linklist_chuckindex(tokenlist,0); 00696 break; 00697 case JIT_EXPR_TOKEN_TYPE_WORD: 00698 dval=NULL; 00699 // if it is a function expect parens to follow 00700 wordsym = jit_atom_getsym(&listtoken->val); 00701 if (jit_expr_wordisoperator(x,wordsym)) { 00702 listnodenext = (t_jit_tree_node *)jit_linklist_getindex(tokenlist,1); 00703 if (!listnodenext) { 00704 jit_object_error((t_object *)x,"jit.expr: operator expects parentheses: %s", wordsym->s_name); 00705 err = JIT_ERR_GENERIC; 00706 goto out; 00707 } 00708 listtokennext = (t_jit_expr_token *)listnodenext->thing; 00709 if (listtokennext->type!=JIT_EXPR_TOKEN_TYPE_LPAREN) { 00710 jit_object_error((t_object *)x,"jit.expr: operator expects parentheses %s", wordsym->s_name); 00711 err = JIT_ERR_GENERIC; 00712 goto out; 00713 } 00714 depth++; 00715 listtoken->type = JIT_EXPR_TOKEN_TYPE_OP; 00716 jit_tree_node_appendchild(currentnode,listnode); 00717 currentnode = listnode; 00718 jit_linklist_chuckindex(tokenlist,0); 00719 jit_linklist_deleteindex(tokenlist,0); // operator already popped 00720 i++; 00721 } else if (jit_expr_wordisconstant(x,wordsym,&dval)) { 00722 listtoken->type = JIT_EXPR_TOKEN_TYPE_NUMBER; 00723 jit_atom_setfloat(&listtoken->val,*dval); 00724 jit_tree_node_appendchild(currentnode,listnode); 00725 jit_linklist_chuckindex(tokenlist,0); 00726 } else { 00727 listtoken->type = JIT_EXPR_TOKEN_TYPE_VARIABLE; 00728 jit_tree_node_appendchild(currentnode,listnode); 00729 jit_linklist_chuckindex(tokenlist,0); 00730 } 00731 break; 00732 case JIT_EXPR_TOKEN_TYPE_SPECIAL: 00733 wordsym = jit_atom_getsym(&listtoken->val); 00734 if (!jit_expr_specialisinfix(x,wordsym)) { 00735 jit_object_error((t_object *)x,"jit.expr: special is not infix: %s", wordsym->s_name); 00736 err = JIT_ERR_GENERIC; 00737 goto out; 00738 } 00739 listtoken->type = JIT_EXPR_TOKEN_TYPE_INOP; 00740 jit_tree_node_appendchild(currentnode,listnode); 00741 jit_linklist_chuckindex(tokenlist,0); 00742 break; 00743 case JIT_EXPR_TOKEN_TYPE_NUMBER: 00744 jit_tree_node_appendchild(currentnode,listnode); 00745 jit_linklist_chuckindex(tokenlist,0); 00746 break; 00747 default: 00748 jit_object_post((t_object *)x,"jit.expr: excountered token %d, ignoring",listtoken->type); 00749 jit_linklist_chuckindex(tokenlist,0); 00750 break; 00751 } 00752 } 00753 00754 out: 00755 if (err) { 00756 if (tokenlist) 00757 jit_object_free(tokenlist); 00758 if (rootnode) 00759 jit_object_free(rootnode); 00760 } else { 00761 if (tokenlist) 00762 jit_linklist_chuck(tokenlist); 00763 } 00764 return err; 00765 } 00766 00767 t_jit_err jit_expr_infix2prefix(t_jit_expr *x, t_jit_tree_node *node) 00768 { 00769 t_jit_tree_node *childnode,*prevnode,*nextnode,*tmpnode; 00770 t_jit_expr_token *childtoken,*prevtoken,*nexttoken,*tmptoken; 00771 long i,k,childcount; 00772 t_symbol *infixsym,*opsym; 00773 t_jit_err err=JIT_ERR_NONE,tmperr; 00774 t_atom a; 00775 t_jit_op_fn_object *o=NULL; 00776 t_jit_expr_infixop *infixop; 00777 00778 if (!node) 00779 return JIT_ERR_GENERIC; 00780 00781 childcount = jit_tree_node_getchildcount(node); 00782 // special case unary negation operator 00783 for (i=0;i<childcount;i++) { 00784 childnode = prevnode = nextnode = NULL; 00785 childtoken = prevtoken = nexttoken = NULL; 00786 00787 if (childnode=jit_tree_node_getchild(node,i)) 00788 childtoken = (t_jit_expr_token *)childnode->thing; 00789 00790 if (prevnode=jit_tree_node_getchild(node,i-1)) 00791 prevtoken = (t_jit_expr_token *)prevnode->thing; 00792 00793 if (nextnode=jit_tree_node_getchild(node,i+1)) 00794 nexttoken = (t_jit_expr_token *)nextnode->thing; 00795 00796 if (childtoken&&(jit_atom_getsym(&childtoken->val)==ps_sub_char)) { 00797 if ((i==0)||(prevtoken&&((prevtoken->type==JIT_EXPR_TOKEN_TYPE_INOP)||(prevtoken->type==JIT_EXPR_TOKEN_TYPE_COMMA)))) 00798 { 00799 childtoken->type = JIT_EXPR_TOKEN_TYPE_OP; 00800 jit_atom_setsym(&childtoken->val,ps_sub); 00801 00802 // add NUMBER zero as first child 00803 jit_atom_setfloat(&a,0.); 00804 tmptoken = jit_expr_token_new(JIT_EXPR_TOKEN_TYPE_NUMBER,&a); 00805 tmpnode = jit_tree_node_new((t_jit_object *)tmptoken); 00806 jit_tree_node_appendchild(childnode,tmpnode); 00807 00808 // add following sibling as child 00809 if (nextnode) { 00810 jit_tree_node_removechild(node,i+1); 00811 jit_tree_node_appendchild(childnode,nextnode); 00812 childcount--; 00813 } 00814 } 00815 } 00816 } 00817 00818 // infix operator precedence (could make more efficient...now do once for each precedence class) 00819 00820 for (k=JIT_EXPR_PRECEDENCE_MIN;k<=JIT_EXPR_PRECEDENCE_MAX;k++) 00821 { 00822 childcount = jit_tree_node_getchildcount(node); 00823 for (i=0;i<childcount;i++) 00824 { 00825 childnode = prevnode = nextnode = NULL; 00826 childtoken = prevtoken = nexttoken = NULL; 00827 00828 if (childnode=jit_tree_node_getchild(node,i)) 00829 childtoken = (t_jit_expr_token *)childnode->thing; 00830 00831 if (prevnode=jit_tree_node_getchild(node,i-1)) 00832 prevtoken = (t_jit_expr_token *)prevnode->thing; 00833 00834 if (nextnode=jit_tree_node_getchild(node,i+1)) 00835 nexttoken = (t_jit_expr_token *)nextnode->thing; 00836 00837 if (childtoken&&(childtoken->type==JIT_EXPR_TOKEN_TYPE_INOP)) { 00838 infixsym = jit_atom_getsym(&childtoken->val); 00839 infixop = NULL; 00840 hashtab_lookup(_jit_expr_infixmap,infixsym,(t_object **)&infixop); 00841 00842 if (infixop&&(infixop->precedence==k)) { 00843 if (o=jit_op_fn_lookup(infixop->prefix)) { 00844 // change type to "op" and value to corresponding prefix op string 00845 childtoken->type = JIT_EXPR_TOKEN_TYPE_OP; 00846 jit_atom_setsym(&childtoken->val,infixop->prefix); 00847 // not really INFIX, but special casing unary operators (e.g. !) 00848 if (o->argcount==1) { 00849 //add following sibling as child 00850 if (nextnode) { 00851 jit_tree_node_removechild(node,i+1); 00852 jit_tree_node_appendchild(childnode,nextnode); 00853 childcount--; 00854 } 00855 } else if ((i>0)&&prevnode&&nextnode&&prevtoken&&nexttoken) { 00856 // add previous + following siblings as child 00857 jit_tree_node_removechild(node,i+1); 00858 jit_tree_node_removechild(node,i-1); 00859 jit_tree_node_appendchild(childnode,prevnode); 00860 jit_tree_node_appendchild(childnode,nextnode); 00861 childcount -= 2; 00862 i -= 2; // taking into account i++ which happens at end of loop 00863 } else { 00864 jit_object_error((t_object *)x,"jit.expr: missing siblings converting infix to prefix (%s)",infixsym->s_name); 00865 return JIT_ERR_GENERIC; 00866 } 00867 } else { 00868 jit_object_error((t_object *)x,"jit.expr: no associated prefix op for infix (%s)",infixsym->s_name); 00869 return JIT_ERR_GENERIC; 00870 } 00871 } 00872 } else { 00873 if (childtoken&&!childtoken->didinfix) { 00874 tmperr = jit_expr_infix2prefix(x,childnode); 00875 if (tmperr) 00876 err = tmperr; 00877 childtoken->didinfix = 1; 00878 } else { 00879 //jit_object_error((t_object *)x,"jit.expr: nontoken child"); 00880 } 00881 } 00882 } 00883 } 00884 return err; 00885 } 00886 00887 t_jit_err jit_expr_cleantree(t_jit_expr *x, t_jit_tree_node *node) 00888 { 00889 t_jit_tree_node *childnode,*tmpnode; 00890 t_jit_expr_token *childtoken; 00891 long i,childcount; 00892 t_jit_err err=JIT_ERR_NONE,tmperr; 00893 00894 if (!node) 00895 return JIT_ERR_GENERIC; 00896 00897 childcount = jit_tree_node_getchildcount(node); 00898 for (i=0;i<childcount;i++) 00899 { 00900 if ((childnode=jit_tree_node_getchild(node,i))&& 00901 (childtoken=(t_jit_expr_token *)childnode->thing)) 00902 { 00903 switch (childtoken->type) { 00904 case JIT_EXPR_TOKEN_TYPE_COMMA: 00905 jit_tree_node_deletechild(node,i); 00906 i--; 00907 childcount--; 00908 break; 00909 case JIT_EXPR_TOKEN_TYPE_GROUP: 00910 if (jit_tree_node_getchildcount(childnode)>1) 00911 jit_object_error((t_object *)x,"jit.expr: GROUP node on clean pass has more than 1 child node"); 00912 tmpnode = jit_tree_node_getchild(childnode,0); 00913 if (tmpnode) { 00914 jit_tree_node_removechild(childnode,0); 00915 jit_tree_node_replacechild(node,tmpnode,i); 00916 i--; 00917 } else { 00918 jit_object_error((t_object *)x,"jit.expr: GROUP node on clean pass has no child node"); 00919 } 00920 childnode = tmpnode; // not sure about this -jkc, originally before i-- jkc 00921 break; 00922 default: 00923 jit_expr_cleantree(x,childnode); 00924 break; 00925 } 00926 } 00927 } 00928 return err; 00929 } 00930 00931 t_jit_err jit_expr_flattenconstants(t_jit_expr *x, t_jit_tree_node *node) 00932 { 00933 t_jit_tree_node *childnode,*tmpnode; 00934 t_jit_expr_token *childtoken,*token; 00935 long i,flat=1,childcount; 00936 t_jit_err err=JIT_ERR_NONE,tmperr; 00937 t_jit_matrix_info info; 00938 t_jit_object *tmpmatrix0,*tmpmatrix1; 00939 double *dp0=NULL; 00940 double *dp1=NULL; 00941 t_atom a[32]; 00942 00943 if (!node) 00944 return JIT_ERR_GENERIC; 00945 00946 childcount = jit_tree_node_getchildcount(node); 00947 for (i=0;i<childcount;i++) 00948 { 00949 if ((childnode=jit_tree_node_getchild(node,i))&& 00950 (childtoken=(t_jit_expr_token *)childnode->thing)) 00951 { 00952 jit_expr_flattenconstants(x,childnode); 00953 if (childtoken->type!=JIT_EXPR_TOKEN_TYPE_NUMBER) 00954 flat = 0; 00955 } 00956 } 00957 00958 token=(t_jit_expr_token *)node->thing; 00959 if (token&&(token->type==JIT_EXPR_TOKEN_TYPE_OP)&&flat&& 00960 !jit_expr_wordisfunctor(x,jit_atom_getsym(&token->val))&& 00961 !jit_expr_wordisclass(x,jit_atom_getsym(&token->val))) 00962 { 00963 if (childcount==0) 00964 return JIT_ERR_NONE; 00965 00966 // evaluate op on scalar value using 1 cell matrix 00967 jit_matrix_info_default(&info); 00968 info.type = _jit_sym_float64; 00969 info.dimcount = 1; 00970 info.dim[0] = 1; 00971 00972 tmpmatrix0 = jit_object_new(_jit_sym_jit_matrix,&info); 00973 tmpmatrix1 = jit_object_new(_jit_sym_jit_matrix,&info); 00974 00975 jit_object_method(tmpmatrix0,_jit_sym_getdata,&dp0); 00976 jit_object_method(tmpmatrix1,_jit_sym_getdata,&dp1); 00977 00978 *dp0 = 0; 00979 00980 if ((childnode=jit_tree_node_getchild(node,0))&& 00981 (childtoken=(t_jit_expr_token *)childnode->thing)) 00982 { 00983 *dp0 = jit_atom_getfloat(&childtoken->val); 00984 00985 a[0] = token->val; 00986 jit_atom_setobj(a+1,tmpmatrix0); 00987 00988 if (childcount==1) { 00989 jit_object_method(tmpmatrix0,ps_op,ps_op,2,a); 00990 } else { 00991 if ((childnode=jit_tree_node_getchild(node,1))&& 00992 (childtoken=(t_jit_expr_token *)childnode->thing)) 00993 { 00994 *dp1 = jit_atom_getfloat(&childtoken->val); 00995 jit_atom_setobj(a+2,tmpmatrix1); 00996 jit_object_method(tmpmatrix0,ps_op,ps_op,3,a); 00997 } 00998 } 00999 01000 } 01001 token->type = JIT_EXPR_TOKEN_TYPE_NUMBER; 01002 jit_atom_setfloat(&token->val,*dp0); 01003 01004 while (childcount--) 01005 jit_tree_node_deletechild(node,0); 01006 01007 jit_object_free(tmpmatrix0); 01008 jit_object_free(tmpmatrix1); 01009 } 01010 return JIT_ERR_NONE; 01011 } 01012 01013 t_jit_err jit_expr_prepcalc(t_jit_expr *x, t_jit_tree_node *node, t_jit_object *inputlist, t_jit_matrix_info *info, long *pcache) 01014 { 01015 t_jit_tree_node *childnode,*tmpnode; 01016 t_jit_expr_token *childtoken,*token; 01017 long i,j,childcount,cache,tmpcache; 01018 t_jit_err err=JIT_ERR_NONE,tmperr; 01019 t_jit_expr_mxfn *mxfn; 01020 t_symbol *wordsym; 01021 t_jit_matrix_info cinfo; 01022 01023 if (!node) 01024 return JIT_ERR_GENERIC; 01025 01026 cache = 1; 01027 childcount = jit_tree_node_getchildcount(node); 01028 for (i=0;i<childcount;i++) 01029 { 01030 if ((childnode=jit_tree_node_getchild(node,i))&& 01031 (childtoken=(t_jit_expr_token *)childnode->thing)) 01032 { 01033 if (childtoken->type==JIT_EXPR_TOKEN_TYPE_VARIABLE) { 01034 if (jit_expr_wordisattribute(x,jit_atom_getsym(&childtoken->val))) 01035 goto out; 01036 } 01037 if (childtoken->data) { 01038 childtoken->cache = x->cache; 01039 jit_object_method(childtoken->data,_jit_sym_getinfo,&cinfo); 01040 if (info->type!=cinfo.type) 01041 childtoken->cache = cache = 0; 01042 for (j=0;j<info->dimcount;j++) { 01043 if (info->dim[j]!=cinfo.dim[j]) 01044 childtoken->cache = cache = 0; 01045 } 01046 if (!cache) 01047 jit_object_method(childtoken->data,_jit_sym_setinfo,info); 01048 } else { 01049 childtoken->data = jit_object_new(_jit_sym_jit_matrix,info); 01050 childtoken->cache = cache = 0; 01051 } 01052 01053 switch (childtoken->type) { 01054 case JIT_EXPR_TOKEN_TYPE_OP: 01055 tmperr = jit_expr_prepcalc(x,childnode,inputlist,info,&tmpcache); 01056 if (!tmpcache) 01057 childtoken->cache = cache = 0; 01058 if (tmperr) 01059 err = JIT_ERR_GENERIC; 01060 break; 01061 case JIT_EXPR_TOKEN_TYPE_NUMBER: 01062 if (!childtoken->cache) 01063 jit_object_method(childtoken->data,_jit_sym_setall,_jit_sym_setall,1,&childtoken->val); 01064 break; 01065 case JIT_EXPR_TOKEN_TYPE_VARIABLE: 01066 mxfn = NULL; 01067 wordsym = jit_atom_getsym(&childtoken->val); 01068 hashtab_lookup(_jit_expr_mxfns,wordsym,(t_object **)&mxfn); 01069 if (mxfn&&mxfn->nocache) 01070 childtoken->cache = cache = 0; 01071 if (!childtoken->cache&&mxfn&&mxfn->mxfn) { 01072 mxfn->mxfn(x,childnode,inputlist,info,mxfn->a,mxfn->b,mxfn->c); 01073 } else { 01074 if (!mxfn) { 01075 if (jit_expr_mxfn_default(x,childnode,inputlist,info)) { 01076 jit_object_error((t_object *)x,"jit.expr: could not resolve variable %s", wordsym->s_name); 01077 err = JIT_ERR_GENERIC; 01078 } 01079 } 01080 } 01081 break; 01082 default: 01083 wordsym = jit_atom_getsym(&childtoken->val); 01084 jit_object_error((t_object *)x,"jit.expr: could not resolve variable %s", wordsym->s_name); 01085 err = JIT_ERR_GENERIC; 01086 break; 01087 } 01088 } 01089 } 01090 out: 01091 if (pcache) 01092 *pcache = cache; 01093 return err; 01094 } 01095 01096 t_jit_object *jit_expr_treecalc(t_jit_expr *x, t_jit_tree_node *node) 01097 { 01098 t_jit_tree_node *childnode,*tmpnode; 01099 t_jit_expr_token *childtoken,*token=NULL; 01100 long i,j,childcount,ac; 01101 t_atom a[256]; 01102 t_symbol *opsym,*attrsym; 01103 t_jit_op_fn_object *o; 01104 t_jit_object *m; 01105 t_class *c; 01106 t_jit_err err=JIT_ERR_NONE; 01107 01108 if (!node) 01109 return NULL; 01110 01111 if (node->thing) { 01112 token=(t_jit_expr_token *)node->thing; 01113 } else if (node=jit_tree_node_getchild(node,0)) { 01114 token=(t_jit_expr_token *)node->thing; 01115 } 01116 01117 if (!token) 01118 return NULL; 01119 01120 if (token->cache&&token->data) 01121 return token->data; 01122 01123 switch (token->type) { 01124 case JIT_EXPR_TOKEN_TYPE_OP: 01125 a[0] = token->val; //operator name 01126 ac = 1; 01127 01128 opsym = jit_atom_getsym(&token->val); 01129 childcount = jit_tree_node_getchildcount(node); 01130 if (o=jit_op_fn_lookup(opsym)) { 01131 for (i=0;i<o->argcount;i++) 01132 { 01133 if ((childnode=jit_tree_node_getchild(node,i))&& 01134 (childtoken=(t_jit_expr_token *)childnode->thing)) 01135 { 01136 m = jit_expr_treecalc(x,childnode); 01137 if (m) { 01138 jit_atom_setobj(a+i+1,m); 01139 ac++; 01140 } else { 01141 jit_object_error((t_object *)x,"jit.expr: null matrix in jit_expr_treecalc"); 01142 } 01143 } else { 01144 jit_object_error((t_object *)x,"jit.expr: missing arguments to op %s",opsym->s_name); 01145 } 01146 } 01147 if (childcount>o->argcount) 01148 jit_object_post((t_object *)x,"warning: extra arguments to op %s",opsym->s_name); 01149 01150 jit_object_method(token->data,ps_op,ps_op,ac,&a); 01151 return token->data; 01152 } else if (c=jit_functor_lookup(NULL,opsym)) { 01153 t_jit_object *tmpmatrix; 01154 t_jit_object *tmpevaluate; 01155 t_jit_matrix_info info; 01156 t_matrix_conv_info mcinfo; 01157 long attrstart=-1,mchildcount; 01158 01159 for (i=0,mchildcount=0;i<childcount;i++,mchildcount++) { 01160 childnode=jit_tree_node_getchild(node,i); 01161 if (childnode&&(childtoken=(t_jit_expr_token *)childnode->thing)&& 01162 jit_expr_wordisattribute(x,jit_atom_getsym(&childtoken->val))) 01163 { 01164 attrstart = i; 01165 break; 01166 } 01167 } 01168 01169 if (!token->aux2) { 01170 tmpmatrix = jit_object_new(_jit_sym_jit_matrix,NULL); 01171 token->aux2 = tmpmatrix; 01172 } 01173 // else we've cached our tmp matrix and evaluate object 01174 01175 jit_matrix_info_default(&info); 01176 jit_object_method(token->data,_jit_sym_getinfo,&info); 01177 info.type = _jit_sym_float32; 01178 info.planecount = mchildcount; 01179 jit_object_method(token->aux2,_jit_sym_setinfo,&info); 01180 01181 mcinfo.flags = 0; 01182 for (i=0;i<JIT_MATRIX_MAX_PLANECOUNT;i++) 01183 mcinfo.planemap[i] = -1; 01184 01185 for (i=0;i<mchildcount;i++) { 01186 mcinfo.planemap[i] = 0; 01187 if ((childnode=jit_tree_node_getchild(node,i))&& 01188 (childtoken=(t_jit_expr_token *)childnode->thing)) 01189 { 01190 m = jit_expr_treecalc(x,childnode); 01191 if (m) { 01192 jit_object_method(token->aux2,_jit_sym_frommatrix,m,&mcinfo); 01193 } else { 01194 jit_object_error((t_object *)x,"jit.expr: null matrix in jit_expr_treecalc"); 01195 } 01196 } else { 01197 jit_object_error((t_object *)x,"jit.expr: invalid argument for functor %s",opsym->s_name); 01198 } 01199 mcinfo.planemap[i] = -1; 01200 } 01201 01202 if (!token->aux1) { 01203 tmpevaluate = jit_object_new(gensym("jit_functor_evaluate")); 01204 jit_attr_setsym(tmpevaluate,ps_basis,opsym); 01205 if (attrstart>=0) { 01206 for (i=attrstart;i<childcount;) { 01207 if ((childnode=jit_tree_node_getchild(node,i++))&& 01208 (childtoken=(t_jit_expr_token *)childnode->thing)&& 01209 (attrsym=jit_expr_wordisattribute(x,jit_atom_getsym(&childtoken->val)))) 01210 { 01211 j=0; 01212 //set initial attr name (stripping @ symbol) 01213 jit_atom_setsym(a+j,ps_basis); j++; 01214 jit_atom_setsym(a+j,attrsym); j++; 01215 for (;(i<childcount)&&(childnode=jit_tree_node_getchild(node,i))&&(childtoken=(t_jit_expr_token *)childnode->thing);i++) { 01216 if (jit_expr_wordisattribute(x,jit_atom_getsym(&childtoken->val))) 01217 break; 01218 a[j++] = childtoken->val; 01219 } 01220 jit_object_method(tmpevaluate,ps_setattr,ps_setattr,j,a); 01221 } 01222 } 01223 } 01224 token->aux1 = tmpevaluate; 01225 } 01226 01227 jit_object_method(token->aux1,_jit_sym_matrix_calc,token->aux2,token->data); 01228 return token->data; 01229 } else if ((c=jit_expr_wordisclass(x,opsym))&&(o=jit_object_new(c->c_sym))) { 01230 t_jit_object *tmplist; 01231 long attrstart=-1,mchildcount; 01232 01233 tmplist = jit_object_new(_jit_sym_jit_linklist); 01234 for (i=0,mchildcount=0;i<childcount;i++,mchildcount++) { 01235 childnode=jit_tree_node_getchild(node,i); 01236 if (childnode&&(childtoken=(t_jit_expr_token *)childnode->thing)&& 01237 jit_expr_wordisattribute(x,jit_atom_getsym(&childtoken->val))) 01238 { 01239 attrstart = i; 01240 break; 01241 } 01242 } 01243 01244 for (i=0;i<mchildcount;i++) { 01245 if ((childnode=jit_tree_node_getchild(node,i))&& 01246 (childtoken=(t_jit_expr_token *)childnode->thing)) 01247 { 01248 m = jit_expr_treecalc(x,childnode); 01249 if (m) { 01250 jit_object_method(tmplist,_jit_sym_append,m); 01251 } else { 01252 jit_object_error((t_object *)x,"jit.expr: null matrix in jit_expr_treecalc"); 01253 } 01254 } else { 01255 jit_object_error((t_object *)x,"jit.expr: invalid argument for operator %s",opsym->s_name); 01256 } 01257 } 01258 if (attrstart>=0) { 01259 for (i=attrstart;i<childcount;) { 01260 if ((childnode=jit_tree_node_getchild(node,i++))&& 01261 (childtoken=(t_jit_expr_token *)childnode->thing)&& 01262 (attrsym=jit_expr_wordisattribute(x,jit_atom_getsym(&childtoken->val)))) 01263 { 01264 j=0; 01265 //set initial attr name (stripping @ symbol) 01266 for (;(i<childcount)&&(childnode=jit_tree_node_getchild(node,i))&&(childtoken=(t_jit_expr_token *)childnode->thing);i++) { 01267 if (jit_expr_wordisattribute(x,jit_atom_getsym(&childtoken->val))) 01268 break; 01269 a[j++] = childtoken->val; 01270 } 01271 jit_object_method(o,attrsym,j,a); 01272 } 01273 } 01274 } 01275 jit_object_method(o,_jit_sym_matrix_calc,tmplist,token->data); 01276 jit_object_free(o); 01277 jit_object_method(tmplist,_jit_sym_chuck); 01278 return token->data; 01279 } 01280 return NULL; 01281 case JIT_EXPR_TOKEN_TYPE_NUMBER: 01282 case JIT_EXPR_TOKEN_TYPE_VARIABLE: 01283 return token->data; 01284 } 01285 return NULL; 01286 } 01287 01288 long jit_expr_wordisoperator(t_jit_expr *x, t_symbol *s) 01289 { 01290 t_jit_object *o=NULL; 01291 01292 if (jit_op_fn_lookup(s)) 01293 return TRUE; 01294 01295 if (jit_functor_lookup(NULL,s)) 01296 return TRUE; 01297 01298 if (jit_expr_wordisexprop(x,s)) 01299 return TRUE; 01300 01301 if (jit_expr_wordisclass(x,s)) 01302 return TRUE; 01303 01304 return FALSE; 01305 } 01306 01307 t_jit_object *jit_expr_wordisexprop(t_jit_expr *x, t_symbol *s) 01308 { 01309 t_jit_object *o=NULL; 01310 /* 01311 hashtab_lookup(_jit_expr_operators,s,&o); 01312 if (o) 01313 return o; 01314 */ 01315 if (x->operators) { 01316 hashtab_lookup(x->operators,s,&o); 01317 if (o) 01318 return o; 01319 } 01320 return NULL; 01321 } 01322 01323 01324 t_class * jit_expr_wordisclass(t_jit_expr *x, t_symbol *s) 01325 { 01326 char tmp[256]; 01327 long i,len; 01328 t_class *c=NULL; 01329 t_object *p=NULL; 01330 t_symbol *tmpsym; 01331 01332 // if the first four chars are "jit." look up jitter operator 01333 if (s&&s->s_name[0]=='j'&&s->s_name[1]=='i'&&s->s_name[2]=='t'&&s->s_name[3]=='.') 01334 { 01335 strcpy(tmp,s->s_name); 01336 len = strlen(tmp); 01337 for (i=0;i<len;i++) { 01338 //replace periods with underscores 01339 if (tmp[i]=='.') 01340 tmp[i] = '_'; 01341 } 01342 tmpsym = gensym(tmp); 01343 01344 // lookup class 01345 c = class_findbyname(ps_jitter,tmpsym); 01346 if (!c) { 01347 if (p=newinstance(s,0,NULL)) { 01348 c = class_findbyname(ps_jitter,tmpsym); 01349 freeobject(p); 01350 p = NULL; 01351 } 01352 } 01353 } 01354 return c; 01355 } 01356 01357 long jit_expr_wordisfunctor(t_jit_expr *x, t_symbol *s) 01358 { 01359 return (jit_functor_lookup(NULL,s)!=NULL); 01360 } 01361 01362 01363 t_symbol *jit_expr_wordisattribute(t_jit_expr *x, t_symbol *s) 01364 { 01365 if (s&&(s->s_name[0]=='@')) 01366 return gensym(s->s_name+1); 01367 else 01368 return NULL; 01369 } 01370 01371 long jit_expr_wordisconstant(t_jit_expr *x, t_symbol *s, double **val) 01372 { 01373 01374 hashtab_lookup(_jit_expr_constants,s,(t_jit_object **)val); 01375 if (*val) 01376 return TRUE; 01377 01378 if (x->constants) { 01379 hashtab_lookup(x->constants,s,(t_jit_object **)val); 01380 if (*val) 01381 return TRUE; 01382 } 01383 01384 return FALSE; 01385 } 01386 01387 long jit_expr_specialisinfix(t_jit_expr *x, t_symbol *s) 01388 { 01389 if (jit_op_fn_lookup(s)) 01390 return TRUE; 01391 01392 return FALSE; 01393 } 01394 01395 void jit_expr_printtree(t_jit_expr *x, long i) 01396 { 01397 jit_expr_printtree_helper(x,(t_jit_tree_node *)x->exprtrees[i],0); 01398 } 01399 01400 void jit_expr_printtree_helper(t_jit_expr *x, t_jit_tree_node *node, long depth) 01401 { 01402 long i,childcount; 01403 char tmpstr[512]; 01404 t_jit_expr_token *token; 01405 01406 if (!node) 01407 return; 01408 01409 tmpstr[0] = 0; 01410 for (i=0;i<depth;i++) { 01411 strcat(tmpstr," "); 01412 } 01413 01414 if (!node->thing) { 01415 strcat(tmpstr,"ROOT (NULL)"); 01416 } else { 01417 token = (t_jit_expr_token *)node->thing; 01418 if (token->type==JIT_EXPR_TOKEN_TYPE_NUMBER) { 01419 sprintf(tmpstr,"%s %s %f",tmpstr,_jit_expr_token_str[token->type],jit_atom_getfloat(&token->val)); 01420 } else { 01421 sprintf(tmpstr,"%s %s %s",tmpstr,_jit_expr_token_str[token->type],jit_atom_getsym(&token->val)->s_name); 01422 } 01423 } 01424 jit_object_post((t_object *)x,tmpstr); 01425 childcount = jit_tree_node_getchildcount(node); 01426 for (i=0;i<childcount;i++) { 01427 jit_expr_printtree_helper(x,jit_tree_node_getchild(node,i),depth+1); 01428 } 01429 } 01430 01431 t_jit_expr_token *jit_expr_token_new(long type, t_atom *val) 01432 { 01433 t_jit_expr_token *x; 01434 01435 if (x = (t_jit_expr_token *)jit_object_alloc(_jit_expr_token_class)) { 01436 x->type = type; 01437 x->cache = 0; 01438 x->didinfix = 0; 01439 if (val) 01440 x->val = (*val); 01441 else 01442 jit_atom_setlong(&x->val,0); 01443 x->data = NULL; 01444 x->aux1 = NULL; 01445 x->aux2 = NULL; 01446 } 01447 return x; 01448 } 01449 01450 void jit_expr_token_free(t_jit_expr_token *x) 01451 { 01452 if (x->data) 01453 jit_object_free(x->data); 01454 if (x->aux1) 01455 jit_object_free(x->aux1); 01456 if (x->aux2) 01457 jit_object_free(x->aux2); 01458 } 01459 01460 void jit_expr_token_data(t_jit_expr_token *x, t_jit_object *data) 01461 { 01462 x->data = data; 01463 } 01464 01465 t_jit_object *jit_expr_token_getdata(t_jit_expr_token *x) 01466 { 01467 return x->data; 01468 } 01469 01470 t_jit_expr_mxfn *jit_expr_mxfn_new(method mxfn, long a, long b, long c, long nocache) 01471 { 01472 t_jit_expr_mxfn *x; 01473 01474 if (x = (t_jit_expr_mxfn *)jit_object_alloc(_jit_expr_mxfn_class)) { 01475 x->mxfn = mxfn; 01476 x->a = a; 01477 x->b = b; 01478 x->c = c; 01479 x->nocache = nocache; 01480 } 01481 return x; 01482 } 01483 01484 void jit_expr_mxfn_free(t_jit_expr_mxfn *x) 01485 { 01486 // nada 01487 } 01488 01489 t_jit_err jit_expr_mxfn_default(t_jit_expr *x, t_jit_tree_node *node, t_jit_object *inputlist, t_jit_matrix_info *info) 01490 { 01491 // resolve arbitrarily named matrices and planar dereferences 01492 t_jit_expr_token *token; 01493 t_atom at; 01494 t_jit_object *m; 01495 t_matrix_conv_info convinfo; 01496 long i,len,plane=x->execplane; 01497 char *p,tmpstr[256]; 01498 t_symbol *wordsym; 01499 01500 if (node&&(token=(t_jit_expr_token *)node->thing)&&token->data) { 01501 wordsym = jit_atom_getsym(&token->val); 01502 if (!(m=jit_object_findregistered(wordsym))) { 01503 // try parsing for .p[N] syntax 01504 len = strlen(wordsym->s_name); 01505 for (i=0,p=wordsym->s_name;(i<len)&&(p[i]!='.');i++) 01506 tmpstr[i] = p[i]; 01507 if (i<len) { 01508 tmpstr[i]=0; 01509 m = jit_object_findregistered(gensym(tmpstr)); 01510 sscanf(p+i,".p[%d]",&plane); 01511 } 01512 } 01513 if (m) { 01514 convinfo.flags = 0; 01515 for (i=0;i<JIT_MATRIX_MAX_PLANECOUNT;i++) { 01516 convinfo.planemap[i] = -1; 01517 } 01518 convinfo.planemap[0] = plane; 01519 jit_object_method(token->data,_jit_sym_frommatrix,m,&convinfo); 01520 } else { 01521 jit_object_method(token->data,_jit_sym_clear); 01522 } 01523 return JIT_ERR_NONE; 01524 } 01525 return JIT_ERR_GENERIC; 01526 } 01527 01528 t_jit_err jit_expr_mxfn_dim(t_jit_expr *x, t_jit_tree_node *node, t_jit_object *inputlist, t_jit_matrix_info *info, long a, long b, long c) 01529 { 01530 t_jit_expr_token *token; 01531 t_atom at; 01532 01533 if (node&&(token=(t_jit_expr_token *)node->thing)&&token->data) { 01534 jit_atom_setfloat(&at,info->dim[a]); 01535 jit_object_method(token->data,_jit_sym_setall,_jit_sym_setall,1,&at); 01536 return JIT_ERR_NONE; 01537 } 01538 return JIT_ERR_GENERIC; 01539 } 01540 01541 t_jit_err jit_expr_mxfn_norm(t_jit_expr *x, t_jit_tree_node *node, t_jit_object *inputlist, t_jit_matrix_info *info, long a, long b, long c) 01542 { 01543 t_jit_expr_token *token; 01544 t_jit_object *m; 01545 t_jit_matrix_info minfo; 01546 double min,inc,v,*dp=NULL; 01547 long i,dim,jump; 01548 01549 if (node&&(token=(t_jit_expr_token *)node->thing)&&token->data) { 01550 dim = info->dim[a]; 01551 switch (b) { 01552 case JIT_EXPR_SNORM: 01553 min = -1.; 01554 inc = 2./(double)(dim-1); 01555 break; 01556 case JIT_EXPR_CELL: 01557 min = 0.; 01558 inc = 1.; 01559 break; 01560 default: 01561 min = 0.; 01562 inc = 1./(double)(dim-1); 01563 } 01564 01565 jit_matrix_info_default(&minfo); 01566 minfo.planecount = 1; 01567 minfo.dimcount = info->dimcount; 01568 minfo.type = _jit_sym_float64; 01569 for (i=0;i<JIT_MATRIX_MAX_PLANECOUNT;i++) 01570 minfo.dim[i] = (i==a)?dim:1; 01571 01572 m = jit_object_new(_jit_sym_jit_matrix,&minfo); 01573 jit_object_method(m,_jit_sym_getinfo,&minfo); 01574 jit_object_method(m,_jit_sym_getdata,&dp); 01575 if (dp) { 01576 jump = minfo.dimstride[a]/sizeof(double); 01577 for (i=0,v=min;i<dim;i++,v+=inc) { 01578 *dp = v; 01579 dp += jump; // data is typically quad word aligned 01580 } 01581 } 01582 jit_object_method(token->data,_jit_sym_frommatrix,m,NULL); 01583 jit_object_free(m); 01584 return JIT_ERR_NONE; 01585 } 01586 return JIT_ERR_GENERIC; 01587 } 01588 01589 t_jit_err jit_expr_mxfn_input(t_jit_expr *x, t_jit_tree_node *node, t_jit_object *inputlist, t_jit_matrix_info *info, long a, long b, long c) 01590 { 01591 t_jit_expr_token *token; 01592 t_atom at; 01593 t_jit_object *m; 01594 t_matrix_conv_info convinfo; 01595 long i; 01596 01597 if (node&&(token=(t_jit_expr_token *)node->thing)&&token->data) { 01598 if (m=jit_object_method(inputlist,_jit_sym_getindex,a)) { 01599 convinfo.flags = 0; 01600 for (i=0;i<JIT_MATRIX_MAX_PLANECOUNT;i++) { 01601 convinfo.planemap[i] = -1; 01602 } 01603 convinfo.planemap[0] = x->execplane; 01604 jit_object_method(token->data,_jit_sym_frommatrix,m,&convinfo); 01605 } else { 01606 jit_atom_setfloat(&at,0.); 01607 jit_object_method(token->data,_jit_sym_setall,_jit_sym_setall,1,&at); 01608 } 01609 return JIT_ERR_NONE; 01610 } 01611 return JIT_ERR_GENERIC; 01612 } 01613 01614 t_jit_err jit_expr_mxfn_input_plane(t_jit_expr *x, t_jit_tree_node *node, t_jit_object *inputlist, t_jit_matrix_info *info, long a, long b, long c) 01615 { 01616 t_jit_expr_token *token; 01617 t_atom at; 01618 t_jit_object *m; 01619 t_matrix_conv_info convinfo; 01620 long i; 01621 01622 if (node&&(token=(t_jit_expr_token *)node->thing)&&token->data) { 01623 if (m=jit_object_method(inputlist,_jit_sym_getindex,a)) { 01624 convinfo.flags = 0; 01625 for (i=0;i<JIT_MATRIX_MAX_PLANECOUNT;i++) { 01626 convinfo.planemap[i] = -1; 01627 } 01628 convinfo.planemap[0] = b; 01629 jit_object_method(token->data,_jit_sym_frommatrix,m,&convinfo); 01630 } else { 01631 jit_atom_setfloat(&at,0.); 01632 jit_object_method(token->data,_jit_sym_setall,_jit_sym_setall,1,&at); 01633 } 01634 return JIT_ERR_NONE; 01635 } 01636 return JIT_ERR_GENERIC; 01637 } 01638 01639 t_jit_expr_infixop *jit_expr_infixop_new(t_symbol *special, t_symbol *prefix, long precedence) 01640 { 01641 t_jit_expr_infixop *x; 01642 01643 if (x = (t_jit_expr_infixop *)jit_object_alloc(_jit_expr_infixop_class)) { 01644 x->special = special; 01645 x->prefix = prefix; 01646 x->precedence = precedence; 01647 } 01648 return x; 01649 } 01650 01651 void jit_expr_infixop_free(t_jit_expr_infixop *x) 01652 { 01653 // nada 01654 } 01655 01656 void jit_expr_pcre_init(void) 01657 { 01658 const char *errstr; 01659 int erroff; 01660 01661 re_token = pcre_compile(TOKEN_RE, 0, &errstr, &erroff, NULL); 01662 if (errstr) 01663 error("jit.expr: PCRE error compiling re_token (%s)", errstr); 01664 pe_token = pcre_study(re_token, 0, &errstr); 01665 if (errstr) 01666 error("jit.expr: PCRE error studying re_token (%s)", errstr); 01667 01668 re_word = pcre_compile(WORD_RE, 0, &errstr, &erroff, NULL); 01669 if (errstr) 01670 error("jit.expr: PCRE error compiling re_word (%s)", errstr); 01671 pe_word = pcre_study(re_word, 0, &errstr); 01672 if (errstr) 01673 error("jit.expr: PCRE error studying re_word (%s)", errstr); 01674 01675 re_number = pcre_compile(NUMBER_RE, 0, &errstr, &erroff, NULL); 01676 if (errstr) 01677 error("jit.expr: PCRE error compiling re_number (%s)", errstr); 01678 pe_number = pcre_study(re_token, 0, &errstr); 01679 if (errstr) 01680 error("jit.expr: PCRE error studying re_number (%s)", errstr); 01681 01682 re_special = pcre_compile(SPECIAL_RE, 0, &errstr, &erroff, NULL); 01683 if (errstr) 01684 error("jit.expr: PCRE error compiling re_special (%s)", errstr); 01685 pe_special = pcre_study(re_token, 0, &errstr); 01686 if (errstr) 01687 error("jit.expr: PCRE error studying re_special (%s)", errstr); 01688 01689 } 01690 01691 void jit_expr_pcre_dispose(void) 01692 { 01693 pcre_free(re_token); 01694 pcre_free(pe_token); 01695 re_token = NULL; 01696 01697 pcre_free(re_word); 01698 pcre_free(pe_word); 01699 re_word = NULL; 01700 01701 pcre_free(re_number); 01702 pcre_free(pe_number); 01703 re_number = NULL; 01704 01705 pcre_free(re_special); 01706 pcre_free(pe_special); 01707 re_special = NULL; 01708 }
Copyright © 2008, Cycling '74