void traditional_save (char * text, unsigned length) { if (n_arg == -1) inc_n_arg (); if (! args[n_arg]) args[n_arg] = arg_start (0 /* no debug */); arg_add (args[n_arg], text, yylineno); }
Object obj_mod(Object a, Object b) { if (a.type == b.type && a.type == TYPE_NUM) { return tm_number((long) GET_NUM(a) % (long) GET_NUM(b)); } else if (a.type == TYPE_STR) { Object *__mod__ = get_builtin("__mod__"); if (__mod__ == NULL) { tm_raise("__mod__ is not defined"); } else { arg_start(); arg_push(a); arg_push(b); return call_function(*__mod__); } } tm_raise("obj_mod: can not module %o and %o", a, b); return NONE_OBJECT; }
void loop_xboard(void) { position_t* pos = position_new(); color_t engineColor = C_BLACK; IF.info_depth = info_depth; IF.info_pv = info_pv; IF.info_curmove = info_curmove; IF.search_done = search_done; log_set_mode(MODE_GUI); log_line("xboard mode"); threads_init(pos); while (1) { char* line = get_line(); char* token = arg_start(line); if (!strcmp(token, "new")) { position_reset(pos); TT_clear(); engineColor = C_BLACK; InGame = 1; } else if (!strcmp(token, "quit")) { InGame = 0; threads_search_stop(); break; } else if (!strcmp(token, "protover")) { char* v = arg_next(); if (v && atoi(v) == 2) { send_line("feature myname=\"Walce\""); send_line("feature setboard=1 usermove=1 sigint=0 sigterm=0"); send_line("feature playother=1 ping=1 time=1 colors=0 name=1"); send_line("feature ics=1 analyze=1"); send_line("feature option=\"Search Depth -spin %d 0 20\"", 0); send_line("feature option=\"Thinking Time -spin %d 0 600000\"", 0); send_line("feature done=1"); } } else if (!strcmp(token, "random") || !strcmp(token, "bk") || !strcmp(token, "ics") || !strcmp(token, "name") || !strcmp(token, "accepted") || !strcmp(token, "computer") ) { ; // IGNORE } else if (!strcmp(token, "variant") || !strcmp(token, "rejected") || !strcmp(token, "draw") || !strcmp(token, "hint") || !strcmp(token, "hard") || !strcmp(token, "easy") || !strcmp(token, "rating") || !strcmp(token, "pause") || !strcmp(token, "resume") || !strcmp(token, "memory") || !strcmp(token, "cores") || !strcmp(token, "egtpath") ) { send_line("Error (not implemented yet): %s", token); } else if (!strcmp(token, "?")) { threads_search_stop(); } else if (!strcmp(token, "st")) { token = arg_next(); if (token) TC.l_time = atoi(token) * 1000; } else if (!strcmp(token, "level")) { char* moves = arg_next(); char* min = arg_next(); char* inc = arg_next(); char* sec = min ? strchr(min, ':') : NULL; if (sec) *sec++ = 0; if (inc) { int t = atoi(min) * 60 + (sec ? atoi(sec) : 0); TC.togo = atoi(moves); TC.ctime[0] = TC.otime[0] = t * 1000; TC.ctime[1] = TC.otime[1] = atoi(inc) * 1000; } } else if (!strcmp(token, "time")) { token = arg_next(); if (token) TC.ctime[0] = atoi(token) * 10; } else if (!strcmp(token, "otim")) { token = arg_next(); if (token) TC.otime[0] = atoi(token) * 10; } else if (!strcmp(token, "analyze")) { ModeAnalyze = 1; TC.infinite = 1; engineColor = pos->to_move; threads_search(); } else if (ModeAnalyze && !strcmp(token, "exit")) { threads_search_stop(); ModeAnalyze = 0; TC.infinite = 0; } else if (ModeAnalyze && !strcmp(token, ".")) { //send_line("Error (not implemented yet): %s", token); } else if (!strncmp(line, "result", 6)) { InGame = 0; threads_search_stop(); } else if (!strncmp(line, "force", 5)) { engineColor = C_NONE; } else if (!strcmp(token, "go")) { engineColor = pos->to_move; threads_search(); } else if (!strcmp(token, "playother")) { engineColor = 1 ^ pos->to_move; } else if (!strcmp(token, "white")) { pos->to_move = C_WHITE; engineColor = C_BLACK; } else if (!strcmp(token, "black")) { pos->to_move = C_BLACK; engineColor = C_WHITE; } else if (!strcmp(token, "sd")) { char* d = arg_next(); if (d) TC.l_depth = atoi(d); } else if (!strcmp(token, "ping")) { char* a = arg_rest(); if (a) send_line("pong %s", a); else send_line("pong"); } else if (!strcmp(token, "edit")) { send_line("Error (command not implemented): %s", token); } else if (!strcmp(token, "undo")) { if (!position_unmove(pos)) send_line("Error (command not legal now): %s", token); } else if (!strcmp(token, "remove")) { if (!position_unmove(pos) || !position_unmove(pos)) send_line("Error (command not legal now): %s", token); } else if (!strcmp(token, "setboard")) { char* b = arg_rest(); if (!b) send_line("Error (missing argument): %s", token); else position_set(pos, b); } else if (!strcmp(token, "post")) { ModePost = 1; } else if (!strcmp(token, "nopost")) { ModePost = 1; } else if (!strcmp(token, "option")) { char* o = arg_next_sep('='); char* v = arg_next(); if (!o) log_line("missing option"); else if (!strcmp(o, "Thinking Time")) { if (v) TC.l_time = atoi(v); } else if (!strcmp(o, "Search Depth")) { if (v) TC.l_depth = atoi(v); } else log_line("unknown option: %s", o); } else { if (!strcmp(token, "usermove")) token = arg_next(); threads_search_stop(); move_t move = parse_move(pos, token); if (!move) { send_line("Illegal move: %s", token); } else { position_move(pos, move); position_print(pos, C_WHITE); if (ModeAnalyze || engineColor == pos->to_move) threads_search(); } } } threads_exit(); position_destroy(pos); }
/** ** 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; }
int Printf (char* messageVoulu, ...){ int i = 0, j = 0, k; int variable, nbArg; char *value; char buffer[MAX_LENGTH]; int alloue = 0; arg_list alist; alist = arg_start (); nbArg = 0; // tant que l'on est pas a la fin du message while (messageVoulu[i] != '\0') { // si on a un %, il faut recuperer la variable // la transformer en chaine et la rajouter au resultat if (messageVoulu[i] == '%') { nbArg++; if (nbArg < 4) { i++; variable = arg_arg (alist); switch (messageVoulu[i]) { case 'd': // un entier value = Itoa (variable); alloue = 1; break; case 'i': value = Itoa (variable); alloue = 1; break; case 'c': value = malloc(2*sizeof(char)); if(value == 0) return -1; value[0] = (char) variable; value[1] = '\0'; alloue = 1; break; case 's': // un string value = (char*) variable; break; default: PutString("argument %"); PutChar(messageVoulu[i]); PutString(" invalide\n"); return -1; break; } k = 0; while (value[k] != '\0') { buffer[j] = value[k]; j++; k++; } } else // si on veut lire un 4eme argument { if(alloue) free(value); arg_end(alist); return -1; } } else { buffer[j] = messageVoulu[i]; j++; } i++; } PutString(buffer); // on vide le buffer (sinon, il y a des affichages en trop for (i = 0; i < MAX_LENGTH; i++) { buffer[i] = '\0'; } if(alloue) free(value); arg_end(alist); return 0; }
int Scanf (char* typeVariable, ...) { void* variable; int i, nbArg; char c; arg_list alist; i = 0; alist = arg_start (); nbArg = 0; // tant qu'on est pas a la fin de la liste de variables a lire while (typeVariable[i] != '\0') { //si on lit un %, on va regarder la lettre apres pour savoir //le type de variable a lire if (typeVariable[i] == '%') { nbArg++; if (nbArg < 4) { variable = (void*) arg_arg (alist); i++; switch (typeVariable[i]) { case 'i': case 'd': //cas de récupération d'un int c = GetChar(); *((int*) variable) = 0; while (c != '\n' && c != ' ' && c != '\t') { *((int*) variable) *= 10; *((int*) variable) += (c - '0'); c = GetChar(); } break; case 'c': //cas de récupération d'un char //GetString(tmp, MAX_LENGH); *((char*)variable) = (char)GetChar(); GetChar(); /*((char*) variable)[0] = tmp[0]; ((char*) variable)[1] = '\0';*/ break; case 's': //cas de récupération d'un string GetString ((char*) variable, MAX_LENGTH); break; default: PutString("argument %"); PutChar(typeVariable[i]); PutString(" invalide\n"); arg_end(alist); return -1; break; } } else {// si on a plus de 3 arguments a lire, on a une erreur arg_end(alist); return -1; } } i++; } arg_end(alist); return 0; }