EXTERN int val_compare( value a, value b ) { char tmp_buf[32]; switch( C(val_type(a),val_type(b)) ) { case C(VAL_INT,VAL_INT): return icmp(val_int(a),val_int(b)); case C(VAL_INT32,VAL_INT): return icmp(val_int32(a),val_int(b)); case C(VAL_INT,VAL_INT32): return icmp(val_int(a),val_int32(b)); case C(VAL_INT32,VAL_INT32): return icmp(val_int32(a),val_int32(b)); case C(VAL_INT,VAL_FLOAT): return fcmp(val_int(a),val_float(b)); case C(VAL_INT32,VAL_FLOAT): return fcmp(val_int32(a),val_float(b)); case C(VAL_INT,VAL_STRING): return scmp(tmp_buf,sprintf(tmp_buf,"%d",val_int(a)),val_string(b),val_strlen(b)); case C(VAL_INT32,VAL_STRING): return scmp(tmp_buf,sprintf(tmp_buf,"%d",val_int32(a)),val_string(b),val_strlen(b)); case C(VAL_FLOAT,VAL_INT): return fcmp(val_float(a),val_int(b)); case C(VAL_FLOAT,VAL_INT32): return fcmp(val_float(a),val_int32(b)); case C(VAL_FLOAT,VAL_FLOAT): return fcmp(val_float(a),val_float(b)); case C(VAL_FLOAT,VAL_STRING): return scmp(tmp_buf,sprintf(tmp_buf,FLOAT_FMT,val_float(a)),val_string(b),val_strlen(b)); case C(VAL_STRING,VAL_INT): return scmp(val_string(a),val_strlen(a),tmp_buf,sprintf(tmp_buf,"%d",val_int(b))); case C(VAL_STRING,VAL_INT32): return scmp(val_string(a),val_strlen(a),tmp_buf,sprintf(tmp_buf,"%d",val_int32(b))); case C(VAL_STRING,VAL_FLOAT): return scmp(val_string(a),val_strlen(a),tmp_buf,sprintf(tmp_buf,FLOAT_FMT,val_float(b))); case C(VAL_STRING,VAL_BOOL): return scmp(val_string(a),val_strlen(a),val_bool(b)?"true":"false",val_bool(b)?4:5); case C(VAL_BOOL,VAL_STRING): return scmp(val_bool(a)?"true":"false",val_bool(a)?4:5,val_string(b),val_strlen(b)); case C(VAL_STRING,VAL_STRING): return scmp(val_string(a),val_strlen(a),val_string(b),val_strlen(b)); case C(VAL_BOOL,VAL_BOOL): return (a == b) ? 0 : (val_bool(a) ? 1 : -1); case C(VAL_OBJECT,VAL_OBJECT): if( a == b ) return 0; { value tmp = val_field(a,id_compare); if( tmp == val_null ) return invalid_comparison; a = val_callEx(a,tmp,&b,1,NULL); } if( val_is_int(a) ) return val_int(a); return invalid_comparison; default: if( a == b ) return 0; return invalid_comparison; } }
void WZMaterial::setDefaults() { vals[WZM_MAT_EMISSIVE] = val_type(0.f); vals[WZM_MAT_AMBIENT] = val_type(1.f); vals[WZM_MAT_DIFFUSE] = val_type(1.f); vals[WZM_MAT_SPECULAR] = val_type(1.f); shininess = 10.f; }
bool WZMaterial::isDefault() const { if (shininess == 10.f && (m_skipemissive || vals[WZM_MAT_EMISSIVE] == val_type(0.f)) && vals[WZM_MAT_AMBIENT] == val_type(1.f) && vals[WZM_MAT_DIFFUSE] == val_type(1.f) && vals[WZM_MAT_SPECULAR] == val_type(1.f)) return true; return false; }
/** $typeof : any -> int <doc> Return the type of a value. The following builtins are defined : <ul> <li>[$tnull] = 0</li> <li>[$tint] = 1</li> <li>[$tfloat] = 2</li> <li>[$tbool] = 3</li> <li>[$tstring] = 4</li> <li>[$tobject] = 5</li> <li>[$tarray] = 6</li> <li>[$tfunction] = 7</li> <li>[$tabstract] = 8</li> </ul> </doc> **/ static value builtin_typeof( value v ) { switch( val_type(v) ) { case VAL_INT: case VAL_INT32: return alloc_int(1); case VAL_NULL: return alloc_int(0); case VAL_FLOAT: return alloc_int(2); case VAL_BOOL: return alloc_int(3); case VAL_STRING: return alloc_int(4); case VAL_OBJECT: return alloc_int(5); case VAL_ARRAY: return alloc_int(6); case VAL_FUNCTION: return alloc_int(7); case VAL_ABSTRACT: return alloc_int(8); default: neko_error(); } }
/** math_ceil : number -> int <doc>Return rounded-up integer</doc> **/ static value math_ceil( value n ) { switch( val_type(n) ) { case VAL_INT: return n; case VAL_FLOAT: return alloc_int( (int)ceil(val_float(n)) ); default: neko_error(); } }
/** math_abs : number -> number <doc>Return absolute value of a number</doc> **/ static value math_abs( value n ) { switch( val_type(n) ) { case VAL_INT: return alloc_int( abs(val_int(n)) ); case VAL_FLOAT: return alloc_float( fabs(val_float(n)) ); default: neko_error(); } }
/** math_fround : number -> number <doc>Return rounded float without integer overflow</doc> **/ static value math_fround( value n ) { switch( val_type(n) ) { case VAL_INT: return n; case VAL_FLOAT: return alloc_float( floor(val_float(n) + 0.5) ); default: neko_error(); } }
/** math_round : number -> int <doc>Return nearest integer</doc> **/ static value math_round( value n ) { switch( val_type(n) ) { case VAL_INT: case VAL_INT32: return n; case VAL_FLOAT: return alloc_best_int( (int)floor(val_float(n) + 0.5) ); default: neko_error(); } }
/** math_int : number -> int <doc>Return integer rounded down towards 0</doc> **/ static value math_int( value n ) { switch( val_type(n) ) { case VAL_INT: return n; case VAL_FLOAT: { tfloat v = val_float(n); return alloc_int( (int)((n < 0) ? ceil(v) : floor(v)) ); } default: neko_error(); } }
static void profile_functions( const char *name, neko_module *m, int *tot ) { unsigned int i; value *dbg = val_is_null(m->debuginf)?NULL:val_array_ptr(m->debuginf); for(i=0;i<m->nglobals;i++) { value v = m->globals[i]; if( val_is_function(v) && val_type(v) == VAL_FUNCTION && ((vfunction*)v)->module == m ) { int pos = (int)(((int_val)((vfunction*)v)->addr - (int_val)m->code) / sizeof(int_val)); if( m->code[PROF_SIZE+pos] > 0 ) { printf("%-8d %-4d %-20s %X ",m->code[PROF_SIZE+pos],i,name,pos); if( dbg ) val_print(dbg[pos]); printf("\n"); } } } }
/** $int : any -> int? <doc>Convert the value to the corresponding integer or return [null]</doc> **/ static value builtin_int( value f ) { switch( val_type(f) ) { case VAL_FLOAT: #ifdef NEKO_WINDOWS return alloc_best_int((int)val_float(f)); #else // in case of overflow, the result is unspecified by ISO // so we have to make a module 2^32 before casting to int return alloc_int((unsigned int)fmod(val_float(f),4294967296.0)); #endif case VAL_STRING: { char *c = val_string(f), *end; int h; if( val_strlen(f) >= 2 && c[0] == '0' && (c[1] == 'x' || c[1] == 'X') ) { h = 0; c += 2; while( *c ) { char k = *c++; if( k >= '0' && k <= '9' ) h = (h << 4) | (k - '0'); else if( k >= 'A' && k <= 'F' ) h = (h << 4) | ((k - 'A') + 10); else if( k >= 'a' && k <= 'f' ) h = (h << 4) | ((k - 'a') + 10); else return val_null; } return alloc_best_int(h); } h = strtol(c,&end,10); return ( c == end ) ? val_null : alloc_best_int(h); } case VAL_INT: case VAL_INT32: return f; } return val_null; }
// Determine value type int api_val_type(value arg1) { int t=val_type(arg1); if (t==VAL_OBJECT) { value __a = val_field(arg1,__a_id); if (val_is_array(__a)) return valtArray; value __s = val_field(arg1,__s_id); if (val_is_string(__s)) return valtString; } if (t<7) return (ValueType)t; if (t==VAL_ABSTRACT) return valtAbstractBase; if (t==VAL_PRIMITIVE || t==VAL_JITFUN) return valtFunction; if (t==VAL_32_BITS || t==VAL_INT) return valtInt; return valtNull; }
ExpOp, std::exp(expr.val()), std::exp(expr.val(j)), std::exp(expr.val(j))*expr.dx(i,j), std::exp(expr.val(j))*expr.fastAccessDx(i,j)) FAD_UNARYOP_MACRO(log, LogOp, std::log(expr.val()), std::log(expr.val(j)), expr.dx(i,j)/expr.val(j), expr.fastAccessDx(i,j)/expr.val(j)) FAD_UNARYOP_MACRO(log10, Log10Op, std::log10(expr.val()), std::log10(expr.val(j)), expr.dx(i,j)/( std::log(val_type(10))*expr.val(j)), expr.fastAccessDx(i,j) / ( std::log(val_type(10))*expr.val(j))) FAD_UNARYOP_MACRO(sqrt, SqrtOp, std::sqrt(expr.val()), std::sqrt(expr.val(j)), expr.dx(i,j)/(val_type(2)* std::sqrt(expr.val(j))), expr.fastAccessDx(i,j)/(val_type(2)* std::sqrt(expr.val(j)))) FAD_UNARYOP_MACRO(cos, CosOp, std::cos(expr.val()), std::cos(expr.val(j)), -expr.dx(i,j)* std::sin(expr.val(j)), -expr.fastAccessDx(i,j)* std::sin(expr.val(j))) FAD_UNARYOP_MACRO(sin, SinOp,
static void val_buffer_rec( buffer b, value v, vlist *stack ) { char buf[32]; int i, l; vlist *vtmp = stack; while( vtmp != NULL ) { if( vtmp->v == v ) { buffer_append_sub(b,"...",3); return; } vtmp = vtmp->next; } switch( val_type(v) ) { case VAL_INT: buffer_append_sub(b,buf,sprintf(buf,"%d",val_int(v))); break; case VAL_STRING: buffer_append_sub(b,val_string(v),val_strlen(v)); break; case VAL_FLOAT: buffer_append_sub(b,buf,sprintf(buf,FLOAT_FMT,val_float(v))); break; case VAL_NULL: buffer_append_sub(b,"null",4); break; case VAL_BOOL: if( val_bool(v) ) buffer_append_sub(b,"true",4); else buffer_append_sub(b,"false",5); break; case VAL_FUNCTION: buffer_append_sub(b,buf,sprintf(buf,"#function:%d",val_fun_nargs(v))); break; case VAL_OBJECT: { value s = val_field(v,id_string); if( s != val_null ) s = val_callEx(v,s,NULL,0,NULL); if( val_is_string(s) ) buffer_append_sub(b,val_string(s),val_strlen(s)); else { vlist2 vtmp; vtmp.v = v; vtmp.next = stack; vtmp.b = b; vtmp.prev = 0; buffer_append_sub(b,"{",1); val_iter_fields(v,val_buffer_fields,&vtmp); if( vtmp.prev ) buffer_append_sub(b," }",2); else buffer_append_sub(b,"}",1); } break; } case VAL_ARRAY: buffer_append_sub(b,"[",1); l = val_array_size(v); { vlist vtmp; vtmp.v = v; vtmp.next = stack; for(i=0;i<l;i++) { value vi = val_array_ptr(v)[i]; val_buffer_rec(b,vi,&vtmp); if( i != l - 1 ) buffer_append_sub(b,",",1); } } buffer_append_sub(b,"]",1); break; case VAL_INT32: buffer_append_sub(b,buf,sprintf(buf,"%d",val_int32(v))); break; case VAL_ABSTRACT: buffer_append_sub(b,"#abstract",9); break; default: buffer_append_sub(b,"#unknown",8); break; } }
static void hash_rec( value v, int *h, vlist *l ) { val_type t = val_type(v); switch( t ) { case VAL_INT: HBIG(val_int(v)); break; case VAL_INT32: HBIG(val_int32(v)); break; case VAL_NULL: HSMALL(0); break; case VAL_FLOAT: { int k = sizeof(tfloat); while( k ) HSMALL(val_string(v)[--k]); } break; case VAL_BOOL: HSMALL(val_bool(v)); break; case VAL_STRING: { int k = val_strlen(v); while( k ) HSMALL(val_string(v)[--k]); } break; case VAL_OBJECT: case VAL_ARRAY: { vlist *tmp = l; int k = 0; while( tmp != NULL ) { if( tmp->v == v ) { HSMALL(k); return; } k = k + 1; tmp = tmp->next; } } if( t == VAL_OBJECT ) { vparam p; p.h = h; p.l.v = v; p.l.next = l; val_iter_fields(v,hash_obj_rec,&p); v = (value)((vobject*)v)->proto; if( v != NULL ) hash_rec(v,h,&p.l); } else { vlist cur; int k = val_array_size(v); cur.v = v; cur.next = l; while( k ) hash_rec(val_array_ptr(v)[--k],h,&cur); } break; default: // ignore since we want hashes to be stable wrt memory break; } }
void serialize_rec( sbuffer *b, value o ) { b->nrec++; if( b->nrec > 350 ) failure("Serialization stack overflow"); switch( val_type(o) ) { case VAL_NULL: write_char(b,'N'); break; case VAL_BOOL: if( val_bool(o) ) write_char(b,'T'); else write_char(b,'F'); break; case VAL_INT: write_char(b,'i'); write_int(b,val_int(o)); break; case VAL_FLOAT: write_char(b,'f'); write_str(b,sizeof(tfloat),&val_float(o)); break; case VAL_STRING: if( !write_ref(b,o,NULL) ) { write_char(b,'s'); write_int(b,val_strlen(o)); write_str(b,val_strlen(o),val_string(o)); } break; case VAL_OBJECT: { value s; if( !write_ref(b,o,&s) ) { if( s != NULL ) { // reference was not written if( !val_is_function(s) || (val_fun_nargs(s) != 0 && val_fun_nargs(s) != VAR_ARGS) ) failure("Invalid __serialize method"); write_char(b,'x'); serialize_rec(b,((neko_module*)((vfunction*)s)->module)->name); serialize_rec(b,val_ocall0(o,id_serialize)); // put reference back write_ref(b,o,NULL); break; } write_char(b,'o'); val_iter_fields(o,serialize_fields_rec,b); write_int(b,0); o = (value)((vobject*)o)->proto; if( o == NULL ) write_char(b,'z'); else { write_char(b,'p'); serialize_rec(b,o); } } } break; case VAL_ARRAY: if( !write_ref(b,o,NULL) ) { int i; int n = val_array_size(o); write_char(b,'a'); write_int(b,n); for(i=0;i<n;i++) serialize_rec(b,val_array_ptr(o)[i]); } break; case VAL_FUNCTION: if( !write_ref(b,o,NULL) ) { neko_module *m; if( val_tag(o) == VAL_PRIMITIVE ) { // assume that alloc_array(0) return a constant array ptr // we don't want to access custom memory (maybe not a ptr) if( ((vfunction*)o)->env != alloc_array(0) ) failure("Cannot Serialize Primitive with environment"); write_char(b,'p'); write_int(b,((vfunction*)o)->nargs); serialize_rec(b,((vfunction*)o)->module); break; } if( val_tag(o) == VAL_JITFUN ) failure("Cannot Serialize JIT method"); write_char(b,'L'); m = (neko_module*)((vfunction*)o)->module; serialize_rec(b,m->name); write_int(b,(int)((int_val*)((vfunction*)o)->addr - m->code)); write_int(b,((vfunction*)o)->nargs); serialize_rec(b,((vfunction*)o)->env); } break; case VAL_INT32: write_char(b,'I'); write_int(b,val_int32(o)); break; case VAL_ABSTRACT: if( val_is_kind(o,k_hash) ) { int i; vhash *h = val_hdata(o); write_char(b,'h'); write_int(b,h->ncells); write_int(b,h->nitems); for(i=0;i<h->ncells;i++) { hcell *c = h->cells[i]; while( c != NULL ) { write_int(b,c->hkey); serialize_rec(b,c->key); serialize_rec(b,c->val); c = c->next; } } break; } default: failure("Cannot Serialize Abstract"); break; } b->nrec--; }