void funcmethods(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]) { int job = getInt(prhs[1]); int nn; double* ptr = 0; // constructor if (job == 0) { int type = getInt(prhs[2]); int n = getInt(prhs[3]); if (type < 20) { ptr = mxGetPr(prhs[4]); size_t msize = mxGetM(prhs[4]); size_t nsize = mxGetN(prhs[4]); size_t lenp = msize*nsize; nn = func_new(type, n, lenp, ptr); } else if (type < 45) { int m = getInt(prhs[4]); nn = func_new(type, n, m, ptr); } else { ptr = mxGetPr(prhs[4]); nn = func_new(type, n, 0, ptr); } plhs[0] = mxCreateNumericMatrix(1,1,mxDOUBLE_CLASS,mxREAL); double* h = mxGetPr(plhs[0]); *h = double(nn); if (nn < 0) { reportError(); } return; } else { int nn = 0; double t; double v = 0.0; int i = getInt(prhs[2]); if (job == 1) { nn = func_del(i); if (nn < 0) { reportError(); } v = double(nn); } else if (job == 2) { t = getDouble(prhs[3]); v = func_value(i, t); if (v == Undef) { reportError(); } } else { mexErrMsgTxt("unknown job parameter"); } plhs[0] = mxCreateNumericMatrix(1,1,mxDOUBLE_CLASS,mxREAL); double* h = mxGetPr(plhs[0]); *h = v; return; } }
func_t *func_cvec(int n) { func_t *f=NULL; f=func_new("cvec"); func_cvec_p_resize(f,n); return f; }
func_t *func_strings_char(const char *str) { func_t *f=NULL; f=func_new(__func_strings); func_strings_set(f,0,str); return f; }
func_t *func_table_bigger(func_t *g) { func_t *f=NULL; f=func_new(__func_table); func_a_resize(f,func_table_bigger_size(g)); return f; }
func_t *func_strings_strings(strings *str) { func_t *f=NULL; f=func_new(__func_strings); func_strings_p_replace(f,strings_new_clone(str)); return f; }
func_t *func_table(void) { func_t *f=NULL; f=func_new(__func_table); func_a_resize(f,__func_table_size[0]); return f; }
func_t *func_add_new(int n) { func_t *f=NULL; f=func_new(__func_add); func_a_resize(f,n); return f; }
func_t *func_strings_str(const char *str[]) { func_t *f=NULL; f=func_new(__func_strings); func_strings_p_replace(f,strings_new_str(str,NULL)); return f; }
func_t *func_strings(int n) { func_t *f=NULL; f=func_new(__func_strings); func_strings_p_replace(f,strings_new(n)); return f; }
func_t *solution(func_t *r, int k) { if (k <= 0) { k = r->n; } func_t *result = func_new(r->n); for (int i = 0; i < r->n; i++) { result->x[i] = r->x[i]; result->f[i] = 0; for (int j = 0; j < r->n; j++) { result->f[i] += G(result->x[i], r->x[j]) * r->f[j]; } } // renormalize double m = 0.; for (int i = 0; i < r->n; i++) { if (fabs(result->f[i]) > m) { m = fabs(result->f[i]); } } double factor = limit / m; printf("%% m = %f, factor = %f\n", m, factor); if (factor < 1) { for (int i = 0; i < result->n; i++) { result->f[i] *= factor; } } return result; }
/** * @since 2016-11-20 */ Object tm_load_module(Object file, Object code, Object name) { Object mod = module_new(file, name, code); Object fnc = func_new(mod, NONE_OBJECT, NULL); GET_FUNCTION(fnc)->code = (unsigned char*) GET_STR(code); GET_FUNCTION(fnc)->name = string_new("#main"); call_function(fnc); return GET_MODULE(mod)->globals; }
/* * Alternate for exec_addfunc() */ struct t_func * exec_addfunc2(struct t_exec *exec, char *name, int (*fn)(struct t_func *func, struct list *args, struct t_value *ret)) { struct t_func *func; func = func_new(name); func->invoke = fn; //exec_addfunc(exec, func); list_push(&exec->functions, func); return func; }
func_t *func_copy(func_t *r) { func_t *result = func_new(r->n); for (int i = 0; i < result->n; i++) { result->x[i] = r->x[i]; result->f[i] = r->f[i]; } result->highlight = r->highlight; return result; }
// def func_t *func_def(const char *name, func_t *g, int amin, int amax) { func_t *f=NULL; f=func_new(__func_def); f->p.def->name=char_new(name," \t\n"); f->p.def->amin=amin; f->p.def->amax=amax; func_aset(f,0,g); return f; }
func_t *rhs(int n) { func_t *result = func_new(n); /* create the support of the function */ double deltax = 1 / (1. + n); /* create the function values */ for (int i = 0; i < result->n; i++) { result->x[i] = (i + 1) * deltax; result->f[i] = a * cos(3 * M_PI * result->x[i]) * deltax; } return result; }
func_t *func_def_script(func_t *f) { int i; strings *a=NULL,*b=NULL; func_t *g=NULL; if(func_is_strings(f) && func_strings_size(f)==1){ if(str_match(func_strings_at(f,0),"^%A%I*$",BLK0,BLK1)){ // f g=func_scope_find(0,func_strings_at(f,0)); if(func_is_def(g) && func_def_name(g)!=NULL){ g=func_new(func_def_name(g)); if(func_find_amin(g)>0){ g=func_del(g); } }else{ g=NULL; } }else if(str_match(func_strings_at(f,0),"^%A%I*(%m+)$",BLK0,BLK1)){ // f(.....) a=strings_split_mask(func_strings_at(f,0),BLK0,BLK1,SPC); if(strings_size(a)==2){ g=func_scope_find(0,strings_at(a,0)); b=strings_split(strings_at(a,1),",",BLK0,BLK1,SPC); if(func_is_def(g) && func_def_name(g)!=NULL){ g=func_new(func_def_name(g)); if(func_find_amin(g)<=strings_size(b) && (strings_size(b)<=func_find_amax(g) || func_find_amax(g)==FUNC_NOLIMIT)){ func_a_resize(g,strings_size(b)); for(i=0; i<strings_size(b); i++){ func_aset(g,i,func_script(strings_at(b,i))); } }else{ g=func_del(g); } }else{ g=NULL; } } } } if(g==NULL){ g=f; }else{ f=func_del(f); } a=strings_del(a); b=strings_del(b); return g; }
func_p func_sparse_to_func(func_sparse_p func_sparse) { func_p result = func_new(1, func_sparse->dimension); return result; }
static void func_new_and (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) { func_new(vo, i, params, 0, 0); }
/** ** evaluate byte code. ** @param f: Frame ** @return evaluated value. */ Object tm_eval(TmFrame* f) { Object* locals = f->locals; Object* top = f->stack; Object cur_fnc = f->fnc; Object globals = get_globals(cur_fnc); // TODO use code cache to replace unsigned char* unsigned char* pc = f->pc; const char* func_name_sz = get_func_name_sz(cur_fnc); Object x, k, v; Object ret = NONE_OBJECT; int i; #if INTERP_DB printf("File \"%s\": enter function %s\n",get_func_file_sz(cur_fnc), get_func_name_sz(cur_fnc)); #endif while (1) { i = (pc[1] << 8) | pc[2]; #if INTERP_DB printf("%30s%2d: %d frame = %d, top = %d\n","", pc[0], i, tm->cur, (int) (top - f->stack)); #endif switch (pc[0]) { case OP_NUMBER: { double d = atof((char*)pc + 3); pc += i; v = tm_number(d); /* obj_append(tm->constants,v);*/ dict_set(tm->constants, v, NONE_OBJECT); break; } case OP_STRING: { v = string_alloc((char*)pc + 3, i); pc += i; /* obj_append(tm->constants,v); */ dict_set(tm->constants, v, NONE_OBJECT); break; } case OP_IMPORT: { // TODO // tm_import(globals) Object import_func = tm_get_global(globals, "_import"); arg_start(); arg_push(globals); Object modname, attr; if (i == 1) { modname = TM_POP(); arg_push(modname); // arg1 } else { attr = TM_POP(); modname = TM_POP(); arg_push(modname); arg_push(attr); } call_function(import_func); break; } case OP_CONSTANT: { TM_PUSH(GET_CONST(i)); break; } case OP_NONE: { TM_PUSH(NONE_OBJECT); break; } case OP_LOAD_LOCAL: { TM_PUSH(locals[i]); break; } case OP_STORE_LOCAL: locals[i] = TM_POP(); break; case OP_LOAD_GLOBAL: { /* tm_printf("load global %o\n", GET_CONST(i)); */ int idx = dict_get_attr(GET_DICT(globals), i); if (idx == -1) { idx = dict_get_attr(GET_DICT(tm->builtins), i); if (idx == -1) { tm_raise("NameError: name %o is not defined", GET_CONST(i)); } else { Object value = GET_DICT(tm->builtins)->nodes[idx].val; // OPTIMIZE // set the builtin to `globals()` obj_set(globals, GET_CONST(i), value); idx = dict_get_attr(GET_DICT(globals), i); pc[0] = OP_FAST_LD_GLO; code16(pc+1, idx); // OPTIMIZE END TM_PUSH(value); } } else { TM_PUSH(GET_DICT(globals)->nodes[idx].val); pc[0] = OP_FAST_LD_GLO; code16(pc+1, idx); } break; } case OP_STORE_GLOBAL: { x = TM_POP(); int idx = dict_set_attr(GET_DICT(globals), i, x); pc[0] = OP_FAST_ST_GLO; code16(pc+1, idx); break; } case OP_FAST_LD_GLO: { TM_PUSH(GET_DICT(globals)->nodes[i].val); break; } case OP_FAST_ST_GLO: { GET_DICT(globals)->nodes[i].val = TM_POP(); break; } case OP_LIST: { TM_PUSH(list_new(2)); FRAME_CHECK_GC(); break; } case OP_APPEND: v = TM_POP(); x = TM_TOP(); tm_assert(IS_LIST(x), "tm_eval: OP_APPEND require list"); list_append(GET_LIST(x), v); break; case OP_DICT_SET: v = TM_POP(); k = TM_POP(); x = TM_TOP(); tm_assert(IS_DICT(x), "tm_eval: OP_DICT_SET require dict"); obj_set(x, k, v); break; case OP_DICT: { TM_PUSH(dict_new()); FRAME_CHECK_GC(); break; } TM_OP(OP_ADD, obj_add) TM_OP(OP_SUB, obj_sub) TM_OP(OP_MUL, obj_mul) TM_OP(OP_DIV, obj_div) TM_OP(OP_MOD, obj_mod) TM_OP(OP_GET, obj_get) case OP_SLICE: { Object second = TM_POP(); Object first = TM_POP(); *top = obj_slice(*top, first, second); break; } case OP_EQEQ: { *(top-1) = tm_number(obj_equals(*(top-1), *top)); top--; break; } case OP_NOTEQ: { *(top-1) = tm_number(!obj_equals(*(top-1), *top)); top--; break; } case OP_LT: { *(top-1) = tm_number(obj_cmp(*(top-1), *top)<0); top--; break; } case OP_LTEQ: { *(top-1) = tm_number(obj_cmp(*(top-1), *top)<=0); top--; break; } case OP_GT: { *(top-1) = tm_number(obj_cmp(*(top-1), *top)>0); top--; break; } case OP_GTEQ: { *(top-1) = tm_number(obj_cmp(*(top-1), *top)>=0); top--; break; } case OP_IN: { *(top-1) = tm_number(obj_in(*(top-1), *top)); top--; break; } case OP_AND: { *(top-1) = tm_number(is_true_obj(*(top-1)) && is_true_obj(*top)); top--; break; } case OP_OR: { *(top-1) = tm_number(is_true_obj(*(top-1)) || is_true_obj(*top)); top--; break; } case OP_NOT:{ *top = tm_number(!is_true_obj(*top)); break; } case OP_SET: k = TM_POP(); x = TM_POP(); v = TM_POP(); #if INTERP_DB tm_printf("Self %o, Key %o, Val %o\n", x, k, v); #endif obj_set(x, k, v); break; case OP_POP: { top--; break; } case OP_NEG: TM_TOP() = obj_neg(TM_TOP()); break; case OP_CALL: { f->top = top; top -= i; arg_set_arguments(top + 1, i); Object func = TM_POP(); TM_PUSH(call_function(func)); // TM_PUSH(call_function(func)); tm->frame = f; FRAME_CHECK_GC(); break; } case OP_APPLY: { f->top = top; Object args = TM_POP(); tm_assert_type(args, TYPE_LIST, "tm_eval: OP_APPLY"); arg_set_arguments(LIST_NODES(args), LIST_LEN(args)); Object func = TM_POP(); x = call_function(func); TM_PUSH(x); tm->frame = f; FRAME_CHECK_GC(); break; } case OP_LOAD_PARAMS: { int parg = pc[1]; int varg = pc[2]; if (tm->arg_cnt < parg || tm->arg_cnt > parg + varg) { tm_raise("ArgError,parg=%d,varg=%d,given=%d", parg, varg, tm->arg_cnt); } for(i = 0; i < tm->arg_cnt; i++){ locals[i] = tm->arguments[i]; } break; } case OP_LOAD_PARG: { int parg = i; for (i = 0; i < parg; i++) { locals[i] = arg_take_obj(func_name_sz); } break; } case OP_LOAD_NARG: { int arg_index = i; Object list = list_new(tm->arg_cnt); while (arg_remains() > 0) { obj_append(list, arg_take_obj(func_name_sz)); } locals[arg_index] = list; break; } case OP_ITER: { *top = iter_new(*top); break; } case OP_NEXT: { Object *next = next_ptr(*top); if (next != NULL) { TM_PUSH(*next); break; } else { pc += i * 3; continue; } break; } case OP_DEF: { Object mod = GET_FUNCTION(cur_fnc)->mod; Object fnc = func_new(mod, NONE_OBJECT, NULL); pc = func_resolve(GET_FUNCTION(fnc), pc); GET_FUNCTION_NAME(fnc) = GET_CONST(i); TM_PUSH(fnc); continue; } case OP_RETURN: { ret = TM_POP(); goto end; } case OP_ROT: { int half = i / 2; int j; for (j = 0; j < half; j++) { Object temp = *(top - j); *(top-j) = *(top - i + j + 1); *(top-i+j+1) = temp; } break; } case OP_UNPACK: { x = TM_POP(); tm_assert_type(x, TYPE_LIST, "tm_eval:UNPACK"); int j; for(j = LIST_LEN(x)-1; j >= 0; j--) { TM_PUSH(LIST_GET(x, j)); } break; } case OP_DEL: { k = TM_POP(); x = TM_POP(); obj_del(x, k); break; } case OP_POP_JUMP_ON_FALSE: { if (!is_true_obj(TM_POP())) { pc += i * 3; continue; } break; } case OP_JUMP_ON_TRUE: { if (is_true_obj(TM_TOP())) { pc += i * 3; continue; } break; } case OP_JUMP_ON_FALSE: { if (!is_true_obj(TM_TOP())) { pc += i * 3; continue; } break; } case OP_UP_JUMP: pc -= i * 3; continue; case OP_JUMP: pc += i * 3; continue; case OP_EOP: case OP_EOF: { ret = NONE_OBJECT; goto end; } case OP_LOAD_EX: { top = f->last_top; TM_PUSH(tm->ex); break; } case OP_SETJUMP: { f->last_top = top; f->jmp = pc + i * 3; break; } case OP_CLR_JUMP: { f->jmp = NULL; break;} case OP_LINE: { f->lineno = i; break;} case OP_DEBUG: { #if 0 Object fdebug = tm_get_global(globals, "__debug__"); f->top = top; tm_call(0, fdebug, 1, tm_number(tm->frame - tm->frames)); break; #endif } case OP_FILE: { // module name here. break; } default: tm_raise("BAD INSTRUCTION, %d\n globals() = \n%o", pc[0], GET_FUNCTION_GLOBALS(f->fnc)); goto end; } pc += 3; } end: /* if (top != f->stack) { tm_raise("tm_eval: operand stack overflow"); }*/ pop_frame(); return ret; }