Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

  1.  
  2. tp_vm *_tp_init(void) {
  3.     int i;
  4.     tp_vm *tp = (tp_vm*)tp_malloc(sizeof(tp_vm));
  5.     tp->cur = 0;
  6.     tp->jmp = 0;
  7.     tp->ex = tp_None;
  8.     tp->root = tp_list(0);
  9.     for (i=0; i<256; i++) { tp->chars[i][0]=i; }
  10.     tp_gc_init(tp);
  11.     tp->_regs = tp_list(tp);
  12.     for (i=0; i<TP_REGS; i++) { tp_set(tp,tp->_regs,tp_None,tp_None); }
  13.     tp->builtins = tp_dict(tp);
  14.     tp->modules = tp_dict(tp);
  15.     tp->_params = tp_list(tp);
  16.     for (i=0; i<TP_FRAMES; i++) { tp_set(tp,tp->_params,tp_None,tp_list(tp)); }
  17.     tp_set(tp,tp->root,tp_None,tp->builtins);
  18.     tp_set(tp,tp->root,tp_None,tp->modules);
  19.     tp_set(tp,tp->root,tp_None,tp->_regs);
  20.     tp_set(tp,tp->root,tp_None,tp->_params);
  21.     tp_set(tp,tp->builtins,tp_string("MODULES"),tp->modules);
  22.     tp_set(tp,tp->modules,tp_string("BUILTINS"),tp->builtins);
  23.     tp_set(tp,tp->builtins,tp_string("BUILTINS"),tp->builtins);
  24.     tp->regs = tp->_regs.list.val->items;
  25.     tp_full(tp);
  26.     return tp;
  27. }
  28.  
  29. void tp_deinit(TP) {
  30.     while (tp->root.list.val->len) {
  31.         _tp_list_pop(tp,tp->root.list.val,0,"tp_deinit");
  32.     }
  33.     tp_full(tp); tp_full(tp);
  34.     tp_delete(tp,tp->root);
  35.     tp_gc_deinit(tp);
  36.     tp_free(tp);
  37. }
  38.  
  39.  
  40. /* tp_frame_*/
  41. void tp_frame(TP,tp_obj globals,tp_code *codes,tp_obj *ret_dest) {
  42.     tp_frame_ f;
  43.     f.globals = globals;
  44.     f.codes = codes;
  45.     f.cur = f.codes;
  46.     f.jmp = 0;
  47. /*     fprintf(stderr,"tp->cur: %d\n",tp->cur);*/
  48.     f.regs = (tp->cur <= 0?tp->regs:tp->frames[tp->cur].regs+tp->frames[tp->cur].cregs);
  49.     f.ret_dest = ret_dest;
  50.     f.lineno = 0;
  51.     f.line = tp_string("");
  52.     f.name = tp_string("?");
  53.     f.fname = tp_string("?");
  54.     f.cregs = 0;
  55. /*     return f;*/
  56.     if (f.regs+256 >= tp->regs+TP_REGS || tp->cur >= TP_FRAMES-1) { tp_raise(,"tp_frame: stack overflow %d",tp->cur); }
  57.     tp->cur += 1;
  58.     tp->frames[tp->cur] = f;
  59. }
  60.  
  61. void _tp_raise(TP,tp_obj e) {
  62.     if (!tp || !tp->jmp) {
  63.         con_printf("\nException:\n%s\n",TP_CSTR(e));
  64.         exit(-1);
  65.         return;
  66.     }
  67.     if (e.type != TP_NONE) { tp->ex = e; }
  68.     tp_grey(tp,e);
  69.     longjmp(tp->buf,1);
  70. }
  71.  
  72. void tp_print_stack(TP) {
  73.     int i;
  74.     con_printf("\n");
  75.     for (i=0; i<=tp->cur; i++) {
  76.         if (!tp->frames[i].lineno) { continue; }
  77.         con_printf("File \"%s\", line %d, in %s\n  %s\n",
  78.             TP_CSTR(tp->frames[i].fname),tp->frames[i].lineno,
  79.             TP_CSTR(tp->frames[i].name),TP_CSTR(tp->frames[i].line));
  80.     }
  81.     con_printf("\nException:\n%s\n",TP_CSTR(tp->ex));
  82. }
  83.  
  84.  
  85.  
  86. void tp_handle(TP) {
  87.     int i;
  88.     for (i=tp->cur; i>=0; i--) {
  89.         if (tp->frames[i].jmp) { break; }
  90.     }
  91.     if (i >= 0) {
  92.         tp->cur = i;
  93.         tp->frames[i].cur = tp->frames[i].jmp;
  94.         tp->frames[i].jmp = 0;
  95.         return;
  96.     }
  97.     tp_print_stack(tp);
  98.     exit(-1);
  99. }
  100.  
  101. void _tp_call(TP,tp_obj *dest, tp_obj fnc, tp_obj params) {
  102.     /*con_printf("_tp_call %s %s\n",TP_CSTR(fnc), TP_CSTR(params));*/
  103.     if (fnc.type == TP_DICT) {
  104.         _tp_call(tp,dest,tp_get(tp,fnc,tp_string("__call__")),params);
  105.         return;
  106.     }
  107.     if (fnc.type == TP_FNC && !(fnc.fnc.ftype&1)) {
  108.         *dest = _tp_tcall(tp,fnc);
  109.         tp_grey(tp,*dest);
  110.         return;
  111.     }
  112.     if (fnc.type == TP_FNC) {
  113.         tp_frame(tp,fnc.fnc.info->globals,(tp_code*)fnc.fnc.val,dest);
  114.         if ((fnc.fnc.ftype&2)) {
  115.             tp->frames[tp->cur].regs[0] = params;
  116.             _tp_list_insert(tp,params.list.val,0,fnc.fnc.info->self);
  117.         } else {
  118.             tp->frames[tp->cur].regs[0] = params;
  119.         }
  120.         return;
  121.     }
  122.     tp_params_v(tp,1,fnc); tp_print(tp);
  123.     tp_raise(,"tp_call: %s is not callable",TP_CSTR(fnc));
  124. }
  125.  
  126.  
  127. void tp_return(TP, tp_obj v) {
  128.     tp_obj *dest = tp->frames[tp->cur].ret_dest;
  129.     if (dest) { *dest = v; tp_grey(tp,v); }
  130. /*     memset(tp->frames[tp->cur].regs,0,TP_REGS_PER_FRAME*sizeof(tp_obj));
  131.        fprintf(stderr,"regs:%d\n",(tp->frames[tp->cur].cregs+1));*/
  132.     memset(tp->frames[tp->cur].regs,0,tp->frames[tp->cur].cregs*sizeof(tp_obj));
  133.     tp->cur -= 1;
  134. }
  135.  
  136. enum {
  137.     TP_IEOF,TP_IADD,TP_ISUB,TP_IMUL,TP_IDIV,TP_IPOW,TP_IAND,TP_IOR,TP_ICMP,TP_IGET,TP_ISET,
  138.     TP_INUMBER,TP_ISTRING,TP_IGGET,TP_IGSET,TP_IMOVE,TP_IDEF,TP_IPASS,TP_IJUMP,TP_ICALL,
  139.     TP_IRETURN,TP_IIF,TP_IDEBUG,TP_IEQ,TP_ILE,TP_ILT,TP_IDICT,TP_ILIST,TP_INONE,TP_ILEN,
  140.     TP_ILINE,TP_IPARAMS,TP_IIGET,TP_IFILE,TP_INAME,TP_INE,TP_IHAS,TP_IRAISE,TP_ISETJMP,
  141.     TP_IMOD,TP_ILSH,TP_IRSH,TP_IITER,TP_IDEL,TP_IREGS,
  142.     TP_ITOTAL
  143. };
  144.  
  145. /* char *tp_strings[TP_ITOTAL] = {
  146.        "EOF","ADD","SUB","MUL","DIV","POW","AND","OR","CMP","GET","SET","NUM",
  147.        "STR","GGET","GSET","MOVE","DEF","PASS","JUMP","CALL","RETURN","IF","DEBUG",
  148.        "EQ","LE","LT","DICT","LIST","NONE","LEN","LINE","PARAMS","IGET","FILE",
  149.        "NAME","NE","HAS","RAISE","SETJMP","MOD","LSH","RSH","ITER","DEL","REGS",
  150.    };*/
  151.  
  152. #define VA ((int)e.regs.a)
  153. #define VB ((int)e.regs.b)
  154. #define VC ((int)e.regs.c)
  155. #define RA regs[e.regs.a]
  156. #define RB regs[e.regs.b]
  157. #define RC regs[e.regs.c]
  158. #define UVBC (unsigned short)(((VB<<8)+VC))
  159. #define SVBC (short)(((VB<<8)+VC))
  160. #define GA tp_grey(tp,RA)
  161. #define SR(v) f->cur = cur; return(v);
  162.  
  163. int tp_step(TP) {
  164.     tp_frame_ *f = &tp->frames[tp->cur];
  165.     tp_obj *regs = f->regs;
  166.     tp_code *cur = f->cur;
  167.     while(1) {
  168.     tp_code e = *cur;
  169. /*     fprintf(stderr,"%2d.%4d: %-6s %3d %3d %3d\n",tp->cur,cur-f->codes,tp_strings[e.i],VA,VB,VC);
  170.        int i; for(i=0;i<16;i++) { fprintf(stderr,"%d: %s\n",i,TP_CSTR(regs[i])); }*/
  171.     switch (e.i) {
  172.         case TP_IEOF: tp_return(tp,tp_None); SR(0); break;
  173.         case TP_IADD: RA = tp_add(tp,RB,RC); break;
  174.         case TP_ISUB: RA = tp_sub(tp,RB,RC); break;
  175.         case TP_IMUL: RA = tp_mul(tp,RB,RC); break;
  176.         case TP_IDIV: RA = tp_div(tp,RB,RC); break;
  177.         case TP_IPOW: RA = tp_pow(tp,RB,RC); break;
  178.         case TP_IAND: RA = tp_and(tp,RB,RC); break;
  179.         case TP_IOR:  RA = tp_or(tp,RB,RC); break;
  180.         case TP_IMOD:  RA = tp_mod(tp,RB,RC); break;
  181.         case TP_ILSH:  RA = tp_lsh(tp,RB,RC); break;
  182.         case TP_IRSH:  RA = tp_rsh(tp,RB,RC); break;
  183.         case TP_ICMP: RA = tp_number(tp_cmp(tp,RB,RC)); break;
  184.         case TP_INE: RA = tp_number(tp_cmp(tp,RB,RC)!=0); break;
  185.         case TP_IEQ: RA = tp_number(tp_cmp(tp,RB,RC)==0); break;
  186.         case TP_ILE: RA = tp_number(tp_cmp(tp,RB,RC)<=0); break;
  187.         case TP_ILT: RA = tp_number(tp_cmp(tp,RB,RC)<0); break;
  188.         case TP_IPASS: break;
  189.         case TP_IIF: if (tp_bool(tp,RA)) { cur += 1; } break;
  190.         case TP_IGET: RA = tp_get(tp,RB,RC); GA; break;
  191.         case TP_IITER:
  192.             if (RC.number.val < tp_len(tp,RB).number.val) {
  193.                 RA = tp_iter(tp,RB,RC); GA;
  194.                 RC.number.val += 1;
  195.                 cur += 1;
  196.             }
  197.             break;
  198.         case TP_IHAS: RA = tp_has(tp,RB,RC); break;
  199.         case TP_IIGET: tp_iget(tp,&RA,RB,RC); break;
  200.         case TP_ISET: tp_set(tp,RA,RB,RC); break;
  201.         case TP_IDEL: tp_del(tp,RA,RB); break;
  202.         case TP_IMOVE: RA = RB; break;
  203.         case TP_INUMBER:
  204.             RA = tp_number(*(tp_num*)(*++cur).string.val);
  205.             cur += sizeof(tp_num)/4;
  206.             continue;
  207.         case TP_ISTRING:
  208.             RA = tp_string_n((*(cur+1)).string.val,UVBC);
  209.             cur += (UVBC/4)+1;
  210.             break;
  211.         case TP_IDICT: RA = tp_dict_n(tp,VC/2,&RB); break;
  212.         case TP_ILIST: RA = tp_list_n(tp,VC,&RB); break;
  213.         case TP_IPARAMS: RA = tp_params_n(tp,VC,&RB); break;
  214.         case TP_ILEN: RA = tp_len(tp,RB); break;
  215.         case TP_IJUMP: cur += SVBC; continue; break;
  216.         case TP_ISETJMP: f->jmp = cur+SVBC; break;
  217.         case TP_ICALL: _tp_call(tp,&RA,RB,RC); cur++; SR(0); break;
  218.         case TP_IGGET:
  219.             if (!tp_iget(tp,&RA,f->globals,RB)) {
  220.                 RA = tp_get(tp,tp->builtins,RB); GA;
  221.             }
  222.             break;
  223.         case TP_IGSET: tp_set(tp,f->globals,RA,RB); break;
  224.         case TP_IDEF:
  225.             RA = tp_def(tp,(*(cur+1)).string.val,f->globals);
  226.             cur += SVBC; continue;
  227.             break;
  228.         case TP_IRETURN: tp_return(tp,RA); SR(0); break;
  229.         case TP_IRAISE: _tp_raise(tp,RA); SR(0); break;
  230.         case TP_IDEBUG:
  231.             tp_params_v(tp,3,tp_string("DEBUG:"),tp_number(VA),RA); tp_print(tp);
  232.             break;
  233.         case TP_INONE: RA = tp_None; break;
  234.         case TP_ILINE:
  235.             f->line = tp_string_n((*(cur+1)).string.val,VA*4-1);
  236. /*             fprintf(stderr,"%7d: %s\n",UVBC,f->line.string.val);*/
  237.             cur += VA; f->lineno = UVBC;
  238.             break;
  239.         case TP_IFILE: f->fname = RA; break;
  240.         case TP_INAME: f->name = RA; break;
  241.         case TP_IREGS: f->cregs = VA; break;
  242.         default: tp_raise(0,"tp_step: invalid instruction %d",e.i); break;
  243.     }
  244.     cur += 1;
  245.     }
  246.     SR(0);
  247. }
  248.  
  249. void tp_run(TP,int cur) {
  250.     if (tp->jmp) {
  251.       tp_raise(,"tp_run(%d) called recusively",cur);
  252.     }
  253.     tp->jmp = 1;
  254.     if (setjmp(tp->buf))
  255.     {
  256.       tp_handle(tp);
  257.     }
  258.     while (tp->cur >= cur && tp_step(tp) != -1);
  259.     tp->cur = cur-1;
  260.     tp->jmp = 0;
  261. }
  262.  
  263.  
  264. tp_obj tp_call(TP, const char *mod, const char *fnc, tp_obj params) {
  265.     tp_obj tmp;
  266.     tp_obj r = tp_None;
  267.     tmp = tp_get(tp,tp->modules,tp_string(mod));
  268.     tmp = tp_get(tp,tmp,tp_string(fnc));
  269.     _tp_call(tp,&r,tmp,params);
  270.     tp_run(tp,tp->cur);
  271.     return r;
  272. }
  273.  
  274. tp_obj tp_import(TP, char const *fname, char const *name, void *codes) {
  275.     tp_obj code = tp_None;
  276.     tp_obj g;
  277.     if (!((fname && strstr(fname,".tpc")) || codes)) {
  278.         return tp_call(tp,"py2bc","import_fname",tp_params_v(tp,2,tp_string(fname),tp_string(name)));
  279.     }
  280.     if (!codes) {
  281.         tp_params_v(tp,1,tp_string(fname));
  282.         code = tp_load(tp);
  283.         /* We cast away the constness. */
  284.         codes = (void *)code.string.val;
  285.     } else {
  286.         code = tp_data(tp,0,codes);
  287.     }
  288.  
  289.     g = tp_dict(tp);
  290.     tp_set(tp,g,tp_string("__name__"),tp_string(name));
  291.     tp_set(tp,g,tp_string("__code__"),code);
  292.     tp_set(tp,g,tp_string("__dict__"),g);
  293.     tp_frame(tp,g,(tp_code*)codes,0);
  294.     tp_set(tp,tp->modules,tp_string(name),g);
  295.     if (!tp->jmp) {
  296.       tp_run(tp,tp->cur);
  297.     }
  298.  
  299.     return g;
  300. }
  301.  
  302.  
  303.  
  304. tp_obj tp_exec_(TP) {
  305.     tp_obj code = TP_OBJ();
  306.     tp_obj globals = TP_OBJ();
  307.     tp_frame(tp,globals,(tp_code*)code.string.val,0);
  308.     return tp_None;
  309. }
  310.  
  311.  
  312. tp_obj tp_import_(TP) {
  313.     tp_obj mod = TP_OBJ();
  314.     char const *s;
  315.     tp_obj r;
  316.  
  317.     if (tp_has(tp,tp->modules,mod).number.val) {
  318.         return tp_get(tp,tp->modules,mod);
  319.     }
  320.  
  321.     s = TP_CSTR(mod);
  322.     r = tp_import(tp,TP_CSTR(tp_add(tp,mod,tp_string(".tpc"))),s,0);
  323.     return r;
  324. }
  325.  
  326. void tp_builtins(TP) {
  327.     struct {const char *s;void *f;} b[] = {
  328.     {"print",tp_print}, {"range",tp_range}, {"min",tp_min},
  329.     {"max",tp_max}, {"bind",tp_bind}, {"copy",tp_copy},
  330.     {"import",tp_import_}, {"len",tp_len_}, {"assert",tp_assert},
  331.     {"str",tp_str2}, {"float",tp_float}, {"system",tp_system},
  332.     {"istype",tp_istype}, {"chr",tp_chr}, {"save",tp_save},
  333.     {"load",tp_load}, {"fpack",tp_fpack}, {"abs",tp_abs},
  334.     {"int",tp_int}, {"exec",tp_exec_}, {"exists",tp_exists},
  335.     {"mtime",tp_mtime}, {"number",tp_float}, {"round",tp_round},
  336.     {"ord",tp_ord}, {"merge",tp_merge}, {"syscall", tp_syscall}, {0,0},
  337.     };
  338.     int i; for(i=0; b[i].s; i++) {
  339.         tp_set(tp,tp->builtins,tp_string(b[i].s),tp_fnc(tp,(tp_obj (*)(tp_vm *))b[i].f));
  340.     }
  341. }
  342.  
  343.  
  344. void tp_args(TP,int argc, char *argv[]) {
  345.     tp_obj self = tp_list(tp);
  346.     int i;
  347.     for (i=1; i<argc; i++) { _tp_list_append(tp,self.list.val,tp_string(argv[i])); }
  348.     tp_set(tp,tp->builtins,tp_string("ARGV"),self);
  349. }
  350.  
  351.  
  352. tp_obj tp_main(TP,char *fname, void *code) {
  353.     return tp_import(tp,fname,"__main__",code);
  354. }
  355. tp_obj tp_compile(TP, tp_obj text, tp_obj fname) {
  356.     return tp_call(tp,"BUILTINS","compile",tp_params_v(tp,2,text,fname));
  357. }
  358.  
  359. tp_obj tp_exec(TP,tp_obj code, tp_obj globals) {
  360.     tp_obj r=tp_None;
  361.     tp_frame(tp,globals,(tp_code*)code.string.val,&r);
  362.     tp_run(tp,tp->cur);
  363.     return r;
  364. }
  365.  
  366. tp_obj tp_eval(TP, char *text, tp_obj globals) {
  367.     tp_obj code = tp_compile(tp,tp_string(text),tp_string("<eval>"));
  368.     return tp_exec(tp,code,globals);
  369. }
  370.  
  371. tp_vm *tp_init(int argc, char *argv[]) {
  372.     tp_vm *tp = _tp_init();
  373.     tp_builtins(tp);
  374.     tp_args(tp,argc,argv);
  375.     tp_compiler(tp);
  376.     return tp;
  377. }
  378.  
  379.  
  380. /**/
  381.