Subversion Repositories Kolibri OS

Rev

Rev 1913 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

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