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