Uploaded tinypy sources.

git-svn-id: svn://kolibrios.org@1913 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
jaeger
2011-03-31 09:59:54 +00:00
parent 00ac1c33b5
commit 9fd32b8cdf
34 changed files with 9410 additions and 0 deletions

View File

@@ -0,0 +1,7 @@
export MENUETDEV=/home/john/Kolibri/kolibrios.org/libc
OUTFILE = tpmain
OBJS = tpmain.o
include $(MENUETDEV)/makefiles/Makefile_for_program
#testmod.o: fasm_modules/testmod.s
# fasm fasm_modules/testmod.s
# cp fasm_modules/testmod.o .

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,46 @@
def _boot_init():
global FTYPE
f = open('tp.h','r').read()
FTYPE = 'f'
if 'double tp_num' in f: FTYPE = 'd'
import sys
global ARGV
ARGV = sys.argv
_boot_init()
def merge(a,b):
if isinstance(a,dict):
for k in b: a[k] = b[k]
else:
for k in b: setattr(a,k,b[k])
def number(v):
if type(v) is str and v[0:2] == '0x':
v = int(v[2:],16)
return float(v)
def istype(v,t):
if t == 'string': return isinstance(v,str)
elif t == 'list': return (isinstance(v,list) or isinstance(v,tuple))
elif t == 'dict': return isinstance(v,dict)
elif t == 'number': return (isinstance(v,float) or isinstance(v,int))
raise '?'
def fpack(v):
import struct
return struct.pack(FTYPE,v)
def system(cmd):
import os
return os.system(cmd)
def load(fname):
f = open(fname,'rb')
r = f.read()
f.close()
return r
def save(fname,v):
f = open(fname,'wb')
f.write(v)
f.close()

View File

@@ -0,0 +1,196 @@
tp_obj tp_print(TP) {
int n = 0;
tp_obj e;
TP_LOOP(e)
if (n) { con_printf(" "); }
con_printf("%s",TP_CSTR(e));
n += 1;
TP_END;
con_printf("\n");
return tp_None;
}
tp_obj tp_bind(TP) {
tp_obj r = TP_OBJ();
tp_obj self = TP_OBJ();
return tp_fnc_new(tp,r.fnc.ftype|2,r.fnc.val,self,r.fnc.info->globals);
}
tp_obj tp_min(TP) {
tp_obj r = TP_OBJ();
tp_obj e;
TP_LOOP(e)
if (tp_cmp(tp,r,e) > 0) { r = e; }
TP_END;
return r;
}
tp_obj tp_syscall(TP) {
tp_obj r = TP_OBJ();
int result;
asm("int $0x40":"=a"(result):
"a"((int)tp_get(tp, r, tp_string_n("eax", 3)).number.val),
"b"((int)tp_get(tp, r, tp_string_n("ebx", 3)).number.val),
"c"((int)tp_get(tp, r, tp_string_n("ecx", 3)).number.val),
"d"((int)tp_get(tp, r, tp_string_n("edx", 3)).number.val));
return tp_number(result);
}
tp_obj tp_max(TP) {
tp_obj r = TP_OBJ();
tp_obj e;
TP_LOOP(e)
if (tp_cmp(tp,r,e) < 0) { r = e; }
TP_END;
return r;
}
tp_obj tp_copy(TP) {
tp_obj r = TP_OBJ();
int type = r.type;
if (type == TP_LIST) {
return _tp_list_copy(tp,r);
} else if (type == TP_DICT) {
return _tp_dict_copy(tp,r);
}
tp_raise(tp_None,"tp_copy(%s)",TP_CSTR(r));
}
tp_obj tp_len_(TP) {
tp_obj e = TP_OBJ();
return tp_len(tp,e);
}
tp_obj tp_assert(TP) {
int a = TP_NUM();
if (a) { return tp_None; }
tp_raise(tp_None,"%s","assert failed");
}
tp_obj tp_range(TP) {
int a,b,c,i;
tp_obj r = tp_list(tp);
switch (tp->params.list.val->len) {
case 1: a = 0; b = TP_NUM(); c = 1; break;
case 2:
case 3: a = TP_NUM(); b = TP_NUM(); c = TP_DEFAULT(tp_number(1)).number.val; break;
default: return r;
}
if (c != 0) {
for (i=a; (c>0) ? i<b : i>b; i+=c) {
_tp_list_append(tp,r.list.val,tp_number(i));
}
}
return r;
}
tp_obj tp_system(TP) {
char const *s = TP_STR();
int r = system(s);
return tp_number(r);
}
tp_obj tp_istype(TP) {
tp_obj v = TP_OBJ();
char const *t = TP_STR();
if (strcmp("string",t) == 0) { return tp_number(v.type == TP_STRING); }
if (strcmp("list",t) == 0) { return tp_number(v.type == TP_LIST); }
if (strcmp("dict",t) == 0) { return tp_number(v.type == TP_DICT); }
if (strcmp("number",t) == 0) { return tp_number(v.type == TP_NUMBER); }
tp_raise(tp_None,"is_type(%s,%s)",TP_CSTR(v),t);
}
tp_obj tp_float(TP) {
tp_obj v = TP_OBJ();
int ord = TP_DEFAULT(tp_number(0)).number.val;
int type = v.type;
if (type == TP_NUMBER) { return v; }
if (type == TP_STRING) {
if (strchr(TP_CSTR(v),'.')) { return tp_number(atof(TP_CSTR(v))); }
return(tp_number(strtol(TP_CSTR(v),0,ord)));
}
tp_raise(tp_None,"tp_float(%s)",TP_CSTR(v));
}
tp_obj tp_save(TP) {
char const *fname = TP_STR();
tp_obj v = TP_OBJ();
FILE *f;
f = fopen(fname,"wb");
if (!f) { tp_raise(tp_None,"tp_save(%s,...)",fname); }
fwrite(v.string.val,v.string.len,1,f);
fclose(f);
return tp_None;
}
#define READ_BLK 1024
tp_obj tp_load(TP) {
FILE *f;
long l = 0;
tp_obj r;
char *s;
char const *fname = TP_STR();
long rd = 0;
long allocated = 32 * READ_BLK;
if (!(f = fopen(fname, "rb"))) {
tp_raise(tp_None,"tp_load(%s)",fname);
}
if (!(s = malloc(allocated)))
tp_raise(tp_None, "tp_load(%s): out of memory", fname);
rd = 0;
do {
if (l + READ_BLK < allocated) {
allocated += READ_BLK;
if (!(s = realloc(s, allocated))) {
tp_raise(tp_None, "tp_load(%s): out of memory", fname);
}
}
rd = fread(s + l, 1, READ_BLK, f);
l += rd;
} while (rd == READ_BLK);
r = tp_string_n(s, l);
fclose(f);
return tp_track(tp,r);
}
tp_obj tp_fpack(TP) {
tp_num v = TP_NUM();
tp_obj r = tp_string_t(tp,sizeof(tp_num));
*(tp_num*)r.string.val = v;
return tp_track(tp,r);
}
tp_obj tp_abs(TP) {
return tp_number(fabs(tp_float(tp).number.val));
}
tp_obj tp_int(TP) {
return tp_number((long)tp_float(tp).number.val);
}
tp_num _roundf(tp_num v) {
tp_num av = fabs(v); tp_num iv = (long)av;
av = (av-iv < 0.5?iv:iv+1);
return (v<0?-av:av);
}
tp_obj tp_round(TP) {
return tp_number(_roundf(tp_float(tp).number.val));
}
tp_obj tp_exists(TP) {
char const *s = TP_STR();
struct stat stbuf;
return tp_number(!stat(s,&stbuf));
}
tp_obj tp_mtime(TP) {
char const *s = TP_STR();
struct stat stbuf;
if (!stat(s,&stbuf)) { return tp_number(stbuf.st_mtime); }
tp_raise(tp_None,"tp_mtime(%s)",s);
}

View File

@@ -0,0 +1,169 @@
int tp_lua_hash(void const *v,int l) {
int i,step = (l>>5)+1;
int h = l + (l >= 4?*(int*)v:0);
for (i=l; i>=step; i-=step) {
h = h^((h<<5)+(h>>2)+((unsigned char *)v)[i-1]);
}
return h;
}
void _tp_dict_free(_tp_dict *self) {
tp_free(self->items);
tp_free(self);
}
/* void _tp_dict_reset(_tp_dict *self) {
memset(self->items,0,self->alloc*sizeof(tp_item));
self->len = 0;
self->used = 0;
self->cur = 0;
}*/
int tp_hash(TP,tp_obj v) {
switch (v.type) {
case TP_NONE: return 0;
case TP_NUMBER: return tp_lua_hash(&v.number.val,sizeof(tp_num));
case TP_STRING: return tp_lua_hash(v.string.val,v.string.len);
case TP_DICT: return tp_lua_hash(&v.dict.val,sizeof(void*));
case TP_LIST: {
int r = v.list.val->len; int n; for(n=0; n<v.list.val->len; n++) {
tp_obj vv = v.list.val->items[n]; r += vv.type != TP_LIST?tp_hash(tp,v.list.val->items[n]):tp_lua_hash(&vv.list.val,sizeof(void*)); } return r;
}
case TP_FNC: return tp_lua_hash(&v.fnc.info,sizeof(void*));
case TP_DATA: return tp_lua_hash(&v.data.val,sizeof(void*));
}
tp_raise(0,"tp_hash(%s)",TP_CSTR(v));
}
void _tp_dict_hash_set(TP,_tp_dict *self, int hash, tp_obj k, tp_obj v) {
tp_item item;
int i,idx = hash&self->mask;
for (i=idx; i<idx+self->alloc; i++) {
int n = i&self->mask;
if (self->items[n].used > 0) { continue; }
if (self->items[n].used == 0) { self->used += 1; }
item.used = 1;
item.hash = hash;
item.key = k;
item.val = v;
self->items[n] = item;
self->len += 1;
return;
}
tp_raise(,"_tp_dict_hash_set(%d,%d,%s,%s)",self,hash,TP_CSTR(k),TP_CSTR(v));
}
void _tp_dict_tp_realloc(TP,_tp_dict *self,int len) {
tp_item *items = self->items;
int i,alloc = self->alloc;
len = _tp_max(8,len);
self->items = (tp_item*)tp_malloc(len*sizeof(tp_item));
self->alloc = len; self->mask = len-1;
self->len = 0; self->used = 0;
for (i=0; i<alloc; i++) {
if (items[i].used != 1) { continue; }
_tp_dict_hash_set(tp,self,items[i].hash,items[i].key,items[i].val);
}
tp_free(items);
}
int _tp_dict_hash_find(TP,_tp_dict *self, int hash, tp_obj k) {
int i,idx = hash&self->mask;
for (i=idx; i<idx+self->alloc; i++) {
int n = i&self->mask;
if (self->items[n].used == 0) { break; }
if (self->items[n].used < 0) { continue; }
if (self->items[n].hash != hash) { continue; }
if (tp_cmp(tp,self->items[n].key,k) != 0) { continue; }
return n;
}
return -1;
}
int _tp_dict_find(TP,_tp_dict *self,tp_obj k) {
return _tp_dict_hash_find(tp,self,tp_hash(tp,k),k);
}
void _tp_dict_setx(TP,_tp_dict *self,tp_obj k, tp_obj v) {
int hash = tp_hash(tp,k); int n = _tp_dict_hash_find(tp,self,hash,k);
if (n == -1) {
if (self->len >= (self->alloc/2)) {
_tp_dict_tp_realloc(tp,self,self->alloc*2);
} else if (self->used >= (self->alloc*3/4)) {
_tp_dict_tp_realloc(tp,self,self->alloc);
}
_tp_dict_hash_set(tp,self,hash,k,v);
} else {
self->items[n].val = v;
}
}
void _tp_dict_set(TP,_tp_dict *self,tp_obj k, tp_obj v) {
_tp_dict_setx(tp,self,k,v);
tp_grey(tp,k); tp_grey(tp,v);
}
tp_obj _tp_dict_get(TP,_tp_dict *self,tp_obj k, const char *error) {
int n = _tp_dict_find(tp,self,k);
if (n < 0) {
tp_raise(tp_None,"%s: KeyError: %s\n",error,TP_CSTR(k));
}
return self->items[n].val;
}
void _tp_dict_del(TP,_tp_dict *self,tp_obj k, const char *error) {
int n = _tp_dict_find(tp,self,k);
if (n < 0) { tp_raise(,"%s: KeyError: %s\n",error,TP_CSTR(k)); }
self->items[n].used = -1;
self->len -= 1;
}
_tp_dict *_tp_dict_new(void) {
_tp_dict *self = (_tp_dict*)tp_malloc(sizeof(_tp_dict));
return self;
}
tp_obj _tp_dict_copy(TP,tp_obj rr) {
tp_obj obj = {TP_DICT};
_tp_dict *o = rr.dict.val;
_tp_dict *r = _tp_dict_new();
*r = *o; r->gci = 0;
r->items = (tp_item*)tp_malloc(sizeof(tp_item)*o->alloc);
memcpy(r->items,o->items,sizeof(tp_item)*o->alloc);
obj.dict.val = r;
return tp_track(tp,obj);
}
int _tp_dict_next(TP,_tp_dict *self) {
if (!self->len) { tp_raise(0,"_tp_dict_next(...)",0); }
while (1) {
self->cur = ((self->cur + 1) & self->mask);
if (self->items[self->cur].used > 0) {
return self->cur;
}
}
}
tp_obj tp_merge(TP) {
tp_obj self = TP_OBJ();
tp_obj v = TP_OBJ();
int i; for (i=0; i<v.dict.val->len; i++) {
int n = _tp_dict_next(tp,v.dict.val);
_tp_dict_set(tp,self.dict.val,
v.dict.val->items[n].key,v.dict.val->items[n].val);
}
return tp_None;
}
volatile tp_obj tp_dict(TP) {
tp_obj r = {TP_DICT};
r.dict.val = _tp_dict_new();
return tp ? tp_track(tp,r) : r;
}
tp_obj tp_dict_n(TP,int n, tp_obj* argv) {
tp_obj r = tp_dict(tp);
int i; for (i=0; i<n; i++) { tp_set(tp,r,argv[i*2],argv[i*2+1]); }
return r;
}

View File

@@ -0,0 +1,699 @@
import tokenize
from tokenize import Token
if '.' in str(1.0):
from boot import *
EOF,ADD,SUB,MUL,DIV,POW,AND,OR,CMP,GET,SET,NUMBER,STRING,GGET,GSET,MOVE,DEF,PASS,JUMP,CALL,RETURN,IF,DEBUG,EQ,LE,LT,DICT,LIST,NONE,LEN,POS,PARAMS,IGET,FILE,NAME,NE,HAS,RAISE,SETJMP,MOD,LSH,RSH,ITER,DEL,REGS = 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44
class DState:
def __init__(self,code,fname):
self.code, self.fname = code,fname
self.lines = self.code.split('\n')
self.stack,self.out,self._scopei,self.tstack,self._tagi,self.data = [],[('tag','EOF')],0,[],0,{}
self.error = False
def begin(self,gbl=False):
if len(self.stack): self.stack.append((self.vars,self.r2n,self.n2r,self._tmpi,self.mreg,self.snum,self._globals,self.lineno,self.globals,self.cregs,self.tmpc))
else: self.stack.append(None)
self.vars,self.r2n,self.n2r,self._tmpi,self.mreg,self.snum,self._globals,self.lineno,self.globals,self.cregs,self.tmpc = [],{},{},0,0,str(self._scopei),gbl,-1,[],['regs'],0
self._scopei += 1
insert(self.cregs)
def end(self):
self.cregs.append(self.mreg)
code(EOF)
# This next line forces the encoder to
# throw an exception if any tmp regs
# were leaked within the frame
assert(self.tmpc == 0) #REG
if len(self.stack) > 1:
self.vars,self.r2n,self.n2r,self._tmpi,self.mreg,self.snum,self._globals,self.lineno,self.globals,self.cregs,self.tmpc = self.stack.pop()
else: self.stack.pop()
def insert(v): D.out.append(v)
def write(v):
if istype(v,'list'):
insert(v)
return
for n in range(0,len(v),4):
insert(('data',v[n:n+4]))
def setpos(v):
if '-nopos' in ARGV: return
line,x = v
if line == D.lineno: return
text = D.lines[line-1]
D.lineno = line
val = text + "\0"*(4-len(text)%4)
code_16(POS,len(val)/4,line)
write(val)
def code(i,a=0,b=0,c=0):
if not istype(i,'number'): raise
if not istype(a,'number'): raise
if not istype(b,'number'): raise
if not istype(c,'number'): raise
write(('code',i,a,b,c))
def code_16(i,a,b):
if b < 0: b += 0x8000
code(i,a,(b&0xff00)>>8,(b&0xff)>>0)
def get_code16(i,a,b):
return ('code',i,a,(b&0xff00)>>8,(b&0xff)>>0)
def _do_string(v,r=None):
r = get_tmp(r)
val = v + "\0"*(4-len(v)%4)
code_16(STRING,r,len(v))
write(val)
return r
def do_string(t,r=None):
return _do_string(t.val,r)
def _do_number(v,r=None):
r = get_tmp(r)
code(NUMBER,r,0,0)
write(fpack(number(v)))
return r
def do_number(t,r=None):
return _do_number(t.val,r)
def get_tag():
k = str(D._tagi)
D._tagi += 1
return k
def stack_tag():
k = get_tag()
D.tstack.append(k)
return k
def pop_tag():
D.tstack.pop()
def tag(*t):
t = D.snum+':'+':'.join([str(v) for v in t])
insert(('tag',t))
def jump(*t):
t = D.snum+':'+':'.join([str(v) for v in t])
insert(('jump',t))
def setjmp(*t):
t = D.snum+':'+':'.join([str(v) for v in t])
insert(('setjmp',t))
def fnc(*t):
t = D.snum+':'+':'.join([str(v) for v in t])
r = get_reg(t)
insert(('fnc',r,t))
return r
def map_tags():
tags = {}
out = []
n = 0
for item in D.out:
if item[0] == 'tag':
tags[item[1]] = n
continue
if item[0] == 'regs':
out.append(get_code16(REGS,item[1],0))
n += 1
continue
out.append(item)
n += 1
for n in range(0,len(out)):
item = out[n]
if item[0] == 'jump':
out[n] = get_code16(JUMP,0,tags[item[1]]-n)
elif item[0] == 'setjmp':
out[n] = get_code16(SETJMP,0,tags[item[1]]-n)
elif item[0] == 'fnc':
out[n] = get_code16(DEF,item[1],tags[item[2]]-n)
for n in range(0,len(out)):
item = out[n]
if item[0] == 'data':
out[n] = item[1]
elif item[0] == 'code':
i,a,b,c = item[1:]
out[n] = chr(i)+chr(a)+chr(b)+chr(c)
else:
raise str(('huh?',item))
if len(out[n]) != 4:
raise ('code '+str(n)+' is wrong length '+str(len(out[n])))
D.out = out
def get_tmp(r=None):
if r != None: return r
return get_tmps(1)[0]
def get_tmps(t):
rs = alloc(t)
regs = range(rs,rs+t)
for r in regs:
set_reg(r,"$"+str(D._tmpi))
D._tmpi += 1
D.tmpc += t #REG
return regs
def alloc(t):
s = ''.join(["01"[r in D.r2n] for r in range(0,min(256,D.mreg+t))])
return s.index('0'*t)
def is_tmp(r):
if r is None: return False
return (D.r2n[r][0] == '$')
def un_tmp(r):
n = D.r2n[r]
free_reg(r)
set_reg(r,'*'+n)
def free_tmp(r):
if is_tmp(r): free_reg(r)
return r
def free_tmps(r):
for k in r: free_tmp(k)
def get_reg(n):
if n not in D.n2r:
set_reg(alloc(1),n)
return D.n2r[n]
#def get_clean_reg(n):
#if n in D.n2r: raise
#set_reg(D.mreg,n)
#return D.n2r[n]
def set_reg(r,n):
D.n2r[n] = r; D.r2n[r] = n
D.mreg = max(D.mreg,r+1)
def free_reg(r):
if is_tmp(r): D.tmpc -= 1
n = D.r2n[r]; del D.r2n[r]; del D.n2r[n]
def imanage(orig,fnc):
items = orig.items
orig.val = orig.val[:-1]
t = Token(orig.pos,'symbol','=',[items[0],orig])
return fnc(t)
def infix(i,tb,tc,r=None):
r = get_tmp(r)
b,c = do(tb,r),do(tc)
code(i,r,b,c)
if r != b: free_tmp(b)
free_tmp(c)
return r
def ss_infix(ss,i,tb,tc,r=None):
r = get_tmp(r)
r2 = get_tmp()
ss = _do_number(ss)
t = get_tag()
r = do(tb,r)
code(EQ,r2,r,ss)
code(IF,r2)
jump(t,'else')
jump(t,'end')
tag(t,'else')
r = do(tc,r)
tag(t,'end')
free_tmp(r2) #REG
free_tmp(ss) #REG
return r
def _do_none(r=None):
r = get_tmp(r)
code(NONE,r)
return r
def do_symbol(t,r=None):
sets = ['=']
isets = ['+=','-=','*=','/=']
cmps = ['<','>','<=','>=','==','!=']
metas = {
'+':ADD,'*':MUL,'/':DIV,'**':POW,
'-':SUB,'and':AND,'or':OR,
'%':MOD,'>>':RSH,'<<':LSH,
'&':AND,'|':OR,
}
if t.val == 'None': return _do_none(r)
if t.val == 'True':
return _do_number('1',r)
if t.val == 'False':
return _do_number('0',r)
items = t.items
if t.val in ['and','or']:
ss = int(t.val == 'or')
return ss_infix(ss,metas[t.val],items[0],items[1],r)
if t.val in isets:
return imanage(t,do_symbol)
if t.val == 'is':
return infix(EQ,items[0],items[1],r)
if t.val == 'isnot':
return infix(CMP,items[0],items[1],r)
if t.val == 'not':
return infix(EQ,Token(t.pos,'number',0),items[0],r)
if t.val == 'in':
return infix(HAS,items[1],items[0],r)
if t.val == 'notin':
r = infix(HAS,items[1],items[0],r)
zero = _do_number('0')
code(EQ,r,r,free_tmp(zero))
return r
if t.val in sets:
return do_set_ctx(items[0],items[1]);
elif t.val in cmps:
b,c = items[0],items[1]
v = t.val
if v[0] in ('>','>='):
b,c,v = c,b,'<'+v[1:]
cd = EQ
if v == '<': cd = LT
if v == '<=': cd = LE
if v == '!=': cd = NE
return infix(cd,b,c,r)
else:
return infix(metas[t.val],items[0],items[1],r)
def do_set_ctx(k,v):
if k.type == 'name':
if (D._globals and k.val not in D.vars) or (k.val in D.globals):
c = do_string(k)
b = do(v)
code(GSET,c,b)
free_tmp(c)
free_tmp(b)
return
a = do_local(k)
b = do(v)
code(MOVE,a,b)
free_tmp(b)
return a
elif k.type in ('tuple','list'):
if v.type in ('tuple','list'):
n,tmps = 0,[]
for kk in k.items:
vv = v.items[n]
tmp = get_tmp(); tmps.append(tmp)
r = do(vv)
code(MOVE,tmp,r)
free_tmp(r) #REG
n+=1
n = 0
for kk in k.items:
vv = v.items[n]
tmp = tmps[n]
free_tmp(do_set_ctx(kk,Token(vv.pos,'reg',tmp))) #REG
n += 1
return
r = do(v); un_tmp(r)
n, tmp = 0, Token(v.pos,'reg',r)
for tt in k.items:
free_tmp(do_set_ctx(tt,Token(tmp.pos,'get',None,[tmp,Token(tmp.pos,'number',str(n))]))) #REG
n += 1
free_reg(r)
return
r = do(k.items[0])
rr = do(v)
tmp = do(k.items[1])
code(SET,r,tmp,rr)
free_tmp(r) #REG
free_tmp(tmp) #REG
return rr
def manage_seq(i,a,items,sav=0):
l = max(sav,len(items))
n,tmps = 0,get_tmps(l)
for tt in items:
r = tmps[n]
b = do(tt,r)
if r != b:
code(MOVE,r,b)
free_tmp(b)
n +=1
if not len(tmps):
code(i,a,0,0)
return 0
code(i,a,tmps[0],len(items))
free_tmps(tmps[sav:])
return tmps[0]
def p_filter(items):
a,b,c,d = [],[],None,None
for t in items:
if t.type == 'symbol' and t.val == '=': b.append(t)
elif t.type == 'args': c = t
elif t.type == 'nargs': d = t
else: a.append(t)
return a,b,c,d
def do_import(t):
for mod in t.items:
mod.type = 'string'
v = do_call(Token(t.pos,'call',None,[
Token(t.pos,'name','import'),
mod]))
mod.type = 'name'
do_set_ctx(mod,Token(t.pos,'reg',v))
def do_from(t):
mod = t.items[0]
mod.type = 'string'
v = do(Token(t.pos,'call',None,[
Token(t.pos,'name','import'),
mod]))
item = t.items[1]
if item.val == '*':
free_tmp(do(Token(t.pos,'call',None,[
Token(t.pos,'name','merge'),
Token(t.pos,'name','__dict__'),
Token(t.pos,'reg',v)]))) #REG
else:
item.type = 'string'
free_tmp(do_set_ctx(
Token(t.pos,'get',None,[ Token(t.pos,'name','__dict__'),item]),
Token(t.pos,'get',None,[ Token(t.pos,'reg',v),item])
)) #REG
def do_globals(t):
for t in t.items:
if t.val not in D.globals:
D.globals.append(t.val)
def do_del(tt):
for t in tt.items:
r = do(t.items[0])
r2 = do(t.items[1])
code(DEL,r,r2)
free_tmp(r); free_tmp(r2) #REG
def do_call(t,r=None):
r = get_tmp(r)
items = t.items
fnc = do(items[0])
a,b,c,d = p_filter(t.items[1:])
e = None
if len(b) != 0 or d != None:
e = do(Token(t.pos,'dict',None,[])); un_tmp(e);
for p in b:
p.items[0].type = 'string'
t1,t2 = do(p.items[0]),do(p.items[1])
code(SET,e,t1,t2)
free_tmp(t1); free_tmp(t2) #REG
if d: free_tmp(do(Token(t.pos,'call',None,[Token(t.pos,'name','merge'),Token(t.pos,'reg',e),d.items[0]]))) #REG
manage_seq(PARAMS,r,a)
if c != None:
t1,t2 = _do_string('*'),do(c.items[0])
code(SET,r,t1,t2)
free_tmp(t1); free_tmp(t2) #REG
if e != None:
t1 = _do_none()
code(SET,r,t1,e)
free_tmp(t1) #REG
code(CALL,r,fnc,r)
free_tmp(fnc) #REG
return r
def do_name(t,r=None):
if t.val in D.vars:
return do_local(t,r)
r = get_tmp(r)
c = do_string(t)
code(GGET,r,c)
free_tmp(c)
return r
def do_local(t,r=None):
if t.val not in D.vars:
D.vars.append(t.val)
return get_reg(t.val)
def do_def(tok,kls=None):
items = tok.items
t = get_tag()
rf = fnc(t,'end')
D.begin()
setpos(tok.pos)
r = do_local(Token(tok.pos,'name','__params'))
do_info(items[0].val)
a,b,c,d = p_filter(items[1].items)
for p in a:
v = do_local(p)
tmp = _do_none()
code(GET,v,r,tmp)
free_tmp(tmp) #REG
for p in b:
v = do_local(p.items[0])
do(p.items[1],v)
tmp = _do_none()
code(IGET,v,r,tmp)
free_tmp(tmp) #REG
if c != None:
v = do_local(c.items[0])
tmp = _do_string('*')
code(GET,v,r,tmp)
free_tmp(tmp) #REG
if d != None:
e = do_local(d.items[0])
code(DICT,e,0,0)
tmp = _do_none()
code(IGET,e,r,tmp)
free_tmp(tmp) #REG
free_tmp(do(items[2])) #REG
D.end()
tag(t,'end')
if kls == None:
if D._globals: do_globals(Token(tok.pos,0,0,[items[0]]))
r = do_set_ctx(items[0],Token(tok.pos,'reg',rf))
else:
rn = do_string(items[0])
code(SET,kls,rn,rf)
free_tmp(rn)
free_tmp(rf)
def do_class(t):
tok = t
items = t.items
parent = None
if items[0].type == 'name':
name = items[0].val
else:
name = items[0].items[0].val
parent = items[0].items[1].val
kls = do(Token(t.pos,'dict',0,[]))
ts = _do_string(name)
code(GSET,ts,kls)
free_tmp(ts) #REG
init,_new = False,[]
if parent:
_new.append(Token(t.pos,'call',None,[
Token(t.pos,'get',None,[
Token(t.pos,'name',parent),
Token(t.pos,'string','__new__'),
]),
Token(t.pos,'name','self'),
]))
for fc in items[1].items:
if fc.type != 'def': continue
fn = fc.items[0].val
if fn == '__init__': init = True
do_def(fc,kls)
_new.append(Token(fc.pos,'symbol','=',[
Token(fc.pos,'get',None,[
Token(fc.pos,'name','self'),
Token(fc.pos,'string',fn)]),
Token(fc.pos,'call',None,[
Token(fc.pos,'name','bind'),
Token(fc.pos,'get',None,[
Token(fc.pos,'name',name),
Token(fc.pos,'string',fn)]),
Token(fc.pos,'name','self')])
]))
do_def(Token(t.pos,'def',None,[
Token(t.pos,'name','__new__'),
Token(t.pos,'list',None,[Token(t.pos,'name','self')]),
Token(t.pos,'statements',None,_new)]),kls)
t = get_tag()
rf = fnc(t,'end')
D.begin()
params = do_local(Token(tok.pos,'name','__params'))
slf = do_local(Token(tok.pos,'name','self'))
code(DICT,slf,0,0)
free_tmp(do(Token(tok.pos,'call',None,[
Token(tok.pos,'get',None,[
Token(tok.pos,'name',name),
Token(tok.pos,'string','__new__')]),
Token(tok.pos,'name','self')]))) #REG
if init:
tmp = get_tmp()
t3 = _do_string('__init__')
code(GET,tmp,slf,t3)
t4 = get_tmp()
code(CALL,t4,tmp,params)
free_tmp(tmp) #REG
free_tmp(t3) #REG
free_tmp(t4) #REG
code(RETURN,slf)
D.end()
tag(t,'end')
ts = _do_string('__call__')
code(SET,kls,ts,rf)
free_tmp(kls) #REG
free_tmp(ts) #REG
def do_while(t):
items = t.items
t = stack_tag()
tag(t,'begin')
tag(t,'continue')
r = do(items[0])
code(IF,r)
free_tmp(r) #REG
jump(t,'end')
free_tmp(do(items[1])) #REG
jump(t,'begin')
tag(t,'break')
tag(t,'end')
pop_tag()
def do_for(tok):
items = tok.items
reg = do_local(items[0])
itr = do(items[1])
i = _do_number('0')
t = stack_tag(); tag(t,'loop'); tag(t,'continue')
code(ITER,reg,itr,i); jump(t,'end')
free_tmp(do(items[2])) #REG
jump(t,'loop')
tag(t,'break'); tag(t,'end'); pop_tag()
free_tmp(itr) #REG
free_tmp(i)
def do_comp(t,r=None):
name = 'comp:'+get_tag()
r = do_local(Token(t.pos,'name',name))
code(LIST,r,0,0)
key = Token(t.pos,'get',None,[
Token(t.pos,'reg',r),
Token(t.pos,'symbol','None')])
ap = Token(t.pos,'symbol','=',[key,t.items[0]])
do(Token(t.pos,'for',None,[t.items[1],t.items[2],ap]))
return r
def do_if(t):
items = t.items
t = get_tag()
n = 0
for tt in items:
tag(t,n)
if tt.type == 'elif':
a = do(tt.items[0]); code(IF,a); free_tmp(a);
jump(t,n+1)
free_tmp(do(tt.items[1])) #REG
elif tt.type == 'else':
free_tmp(do(tt.items[0])) #REG
else:
raise
jump(t,'end')
n += 1
tag(t,n)
tag(t,'end')
def do_try(t):
items = t.items
t = get_tag()
setjmp(t,'except')
free_tmp(do(items[0])) #REG
jump(t,'end')
tag(t,'except')
free_tmp(do(items[1].items[1])) #REG
tag(t,'end')
def do_return(t):
if t.items: r = do(t.items[0])
else: r = _do_none()
code(RETURN,r)
free_tmp(r)
return
def do_raise(t):
if t.items: r = do(t.items[0])
else: r = _do_none()
code(RAISE,r)
free_tmp(r)
return
def do_statements(t):
for tt in t.items: free_tmp(do(tt))
def do_list(t,r=None):
r = get_tmp(r)
manage_seq(LIST,r,t.items)
return r
def do_dict(t,r=None):
r = get_tmp(r)
manage_seq(DICT,r,t.items)
return r
def do_get(t,r=None):
items = t.items
return infix(GET,items[0],items[1],r)
def do_break(t): jump(D.tstack[-1],'break')
def do_continue(t): jump(D.tstack[-1],'continue')
def do_pass(t): code(PASS)
def do_info(name='?'):
if '-nopos' in ARGV: return
code(FILE,free_tmp(_do_string(D.fname)))
code(NAME,free_tmp(_do_string(name)))
def do_module(t):
do_info()
free_tmp(do(t.items[0])) #REG
def do_reg(t,r=None): return t.val
fmap = {
'module':do_module,'statements':do_statements,'def':do_def,
'return':do_return,'while':do_while,'if':do_if,
'break':do_break,'pass':do_pass,'continue':do_continue,'for':do_for,
'class':do_class,'raise':do_raise,'try':do_try,'import':do_import,
'globals':do_globals,'del':do_del,'from':do_from,
}
rmap = {
'list':do_list, 'tuple':do_list, 'dict':do_dict, 'slice':do_list,
'comp':do_comp, 'name':do_name,'symbol':do_symbol,'number':do_number,
'string':do_string,'get':do_get, 'call':do_call, 'reg':do_reg,
}
def do(t,r=None):
if t.pos: setpos(t.pos)
try:
if t.type in rmap:
return rmap[t.type](t,r)
return fmap[t.type](t)
except:
if D.error: raise
D.error = True
tokenize.u_error('encode',D.code,t.pos)
def encode(fname,s,t):
t = Token((1,1),'module','module',[t])
global D
s = tokenize.clean(s)
D = DState(s,fname)
D.begin(True)
do(t)
D.end()
map_tags()
out = D.out; D = None
return ''.join(out)

View File

@@ -0,0 +1,152 @@
/* tp_obj tp_track(TP,tp_obj v) { return v; }
void tp_grey(TP,tp_obj v) { }
void tp_full(TP) { }
void tp_gc_init(TP) { }
void tp_gc_deinit(TP) { }
void tp_delete(TP,tp_obj v) { }*/
void tp_grey(TP,tp_obj v) {
if (v.type < TP_STRING || (!v.gci.data) || *v.gci.data) { return; }
*v.gci.data = 1;
if (v.type == TP_STRING || v.type == TP_DATA) {
_tp_list_appendx(tp,tp->black,v);
return;
}
_tp_list_appendx(tp,tp->grey,v);
}
void tp_follow(TP,tp_obj v) {
int type = v.type;
if (type == TP_LIST) {
int n;
for (n=0; n<v.list.val->len; n++) {
tp_grey(tp,v.list.val->items[n]);
}
}
if (type == TP_DICT) {
int i;
for (i=0; i<v.dict.val->len; i++) {
int n = _tp_dict_next(tp,v.dict.val);
tp_grey(tp,v.dict.val->items[n].key);
tp_grey(tp,v.dict.val->items[n].val);
}
}
if (type == TP_FNC) {
tp_grey(tp,v.fnc.info->self);
tp_grey(tp,v.fnc.info->globals);
}
}
void tp_reset(TP) {
int n;
_tp_list *tmp;
for (n=0; n<tp->black->len; n++) {
*tp->black->items[n].gci.data = 0;
}
tmp = tp->white;
tp->white = tp->black;
tp->black = tmp;
}
void tp_gc_init(TP) {
tp->white = _tp_list_new();
tp->strings = _tp_dict_new();
tp->grey = _tp_list_new();
tp->black = _tp_list_new();
tp->steps = 0;
}
void tp_gc_deinit(TP) {
_tp_list_free(tp->white);
_tp_dict_free(tp->strings);
_tp_list_free(tp->grey);
_tp_list_free(tp->black);
}
void tp_delete(TP,tp_obj v) {
int type = v.type;
if (type == TP_LIST) {
_tp_list_free(v.list.val);
return;
} else if (type == TP_DICT) {
_tp_dict_free(v.dict.val);
return;
} else if (type == TP_STRING) {
tp_free(v.string.info);
return;
} else if (type == TP_DATA) {
if (v.data.info->free) {
v.data.info->free(tp,v);
}
tp_free(v.data.info);
return;
} else if (type == TP_FNC) {
tp_free(v.fnc.info);
return;
}
tp_raise(,"tp_delete(%s)",TP_CSTR(v));
}
void tp_collect(TP) {
int n;
for (n=0; n<tp->white->len; n++) {
tp_obj r = tp->white->items[n];
if (*r.gci.data) { continue; }
if (r.type == TP_STRING) {
/*this can't be moved into tp_delete, because tp_delete is
also used by tp_track_s to delete redundant strings*/
_tp_dict_del(tp,tp->strings,r,"tp_collect");
}
tp_delete(tp,r);
}
tp->white->len = 0;
tp_reset(tp);
}
void _tp_gcinc(TP) {
tp_obj v;
if (!tp->grey->len) {
return;
}
v = _tp_list_pop(tp,tp->grey,tp->grey->len-1,"_tp_gcinc");
tp_follow(tp,v);
_tp_list_appendx(tp,tp->black,v);
}
void tp_full(TP) {
while (tp->grey->len) {
_tp_gcinc(tp);
}
tp_collect(tp);
tp_follow(tp,tp->root);
}
void tp_gcinc(TP) {
tp->steps += 1;
if (tp->steps < TP_GCMAX || tp->grey->len > 0) {
_tp_gcinc(tp); _tp_gcinc(tp);
}
if (tp->steps < TP_GCMAX || tp->grey->len > 0) { return; }
tp->steps = 0;
tp_full(tp);
return;
}
tp_obj tp_track(TP,tp_obj v) {
if (v.type == TP_STRING) {
int i = _tp_dict_find(tp,tp->strings,v);
if (i != -1) {
tp_delete(tp,v);
v = tp->strings->items[i].key;
tp_grey(tp,v);
return v;
}
_tp_dict_setx(tp,tp->strings,v,tp_True);
}
tp_gcinc(tp);
tp_grey(tp,v);
return v;
}
/**/

View File

@@ -0,0 +1,65 @@
#include "kolibri.h"
#define __stdcall __attribute__((stdcall))
#define _cdecl __attribute__((cdecl))
#define _stdcall __attribute__((stdcall))
void (* _stdcall con_init)(unsigned w_w, unsigned w_h, unsigned s_w, unsigned s_h, const char* t);
int (* _cdecl con_printf)(const char* format,...);
void (* _stdcall con_exit)(char bCloseWindow);
void (* __stdcall con_gets)(char* str, int n);
void CONSOLE_INIT(const char title[])
{
kol_struct_import *imp;
if (!(imp = kol_cofflib_load("/sys/lib/console.obj")) ||
!(con_init = ( _stdcall void (*)(unsigned, unsigned, unsigned, unsigned, const char*))
kol_cofflib_procload (imp, "con_init")) ||
!(con_printf = ( _cdecl int (*)(const char*,...))
kol_cofflib_procload (imp, "con_printf"))||
!(con_gets = ( __stdcall void (*)(char*, int))
kol_cofflib_procload (imp, "con_gets"))||
!(con_exit = ( _stdcall void (*)(char))
kol_cofflib_procload (imp, "con_exit")))
{
kol_exit();
}
con_init(-1, -1, -1, -1, title);
}
kol_struct_import* kol_cofflib_load(char *name)
{
kol_struct_import* result;
asm ("int $0x40":"=a"(result):"a"(68), "b"(19), "c"(name));
return result;
}
void* kol_cofflib_procload (kol_struct_import *imp, char *name)
{
int i;
for (i=0;;i++)
{
if ( NULL == ((imp+i) -> name))
break;
else
if ( 0 == strcmp(name, (imp+i)->name) )
return (imp+i)->data;
}
return NULL;
}
void kol_board_puts(char *s)
{
unsigned i;
i = 0;
while (*(s+i))
{
asm ("int $0x40"::"a"(63), "b"(1), "c"(*(s+i)));
i++;
}
}
void kol_exit()
{
asm ("int $0x40"::"a"(-1));
}

View File

@@ -0,0 +1,92 @@
#define NULL ((void*)0)
typedef struct
{
unsigned p00 __attribute__((packed));
unsigned p04 __attribute__((packed));
unsigned p08 __attribute__((packed));
unsigned p12 __attribute__((packed));
unsigned p16 __attribute__((packed));
char p20 __attribute__((packed));
char *p21 __attribute__((packed));
} kol_struct70 __attribute__((packed));
typedef struct
{
unsigned p00 __attribute__((packed));
char p04 __attribute__((packed));
char p05[3] __attribute__((packed));
unsigned p08 __attribute__((packed));
unsigned p12 __attribute__((packed));
unsigned p16 __attribute__((packed));
unsigned p20 __attribute__((packed));
unsigned p24 __attribute__((packed));
unsigned p28 __attribute__((packed));
unsigned p32[2] __attribute__((packed));
unsigned p40 __attribute__((packed));
} kol_struct_BDVK __attribute__((packed));
typedef struct
{
char *name __attribute__((packed));
void *data __attribute__((packed));
} kol_struct_import __attribute__((packed));
void kol_exit();
void kol_sleep(unsigned d);
void kol_wnd_define(unsigned x, unsigned y, unsigned w, unsigned h, unsigned c);
void kol_wnd_move(unsigned x, unsigned y);
void kol_wnd_caption(char *s);
void kol_event_mask(unsigned e);
unsigned kol_event_wait();
unsigned kol_event_wait_time(unsigned time);
unsigned kol_event_check();
void kol_paint_start();
void kol_paint_end();
void kol_paint_pixel(unsigned x, unsigned y, unsigned c);
void kol_paint_bar(unsigned x, unsigned y, unsigned w, unsigned h, unsigned c);
void kol_paint_line(unsigned x1, unsigned y1, unsigned x2, unsigned y2, unsigned c);
void kol_paint_string(unsigned x, unsigned y, char *s, unsigned c);
void kol_paint_image(unsigned x, unsigned y, unsigned w, unsigned h, char *d);
void kol_paint_image_pal(unsigned x, unsigned y, unsigned w, unsigned h, char *d, unsigned *palette);
unsigned kol_key_get();
unsigned kol_key_control();
void kol_key_lang_set(unsigned lang);
unsigned kol_key_lang_get();
void kol_key_mode_set(unsigned mode);
unsigned kol_key_mode_get();
void kol_btn_define(unsigned x, unsigned y, unsigned w, unsigned h, unsigned d, unsigned c);
unsigned kol_btn_get();
void kol_btn_type(unsigned t);
unsigned kol_mouse_pos();
unsigned kol_mouse_posw();
unsigned kol_mouse_btn();
void kol_board_putc(char c);
void kol_board_puts(char *s);
void kol_board_puti(int n);
int kol_file_70(kol_struct70 *k);
kol_struct_import* kol_cofflib_load(char *name);
void* kol_cofflib_procload (kol_struct_import *imp, char *name);
unsigned kol_cofflib_procnum (kol_struct_import *imp);
void kol_cofflib_procname (kol_struct_import *imp, char *name, unsigned n);
unsigned kol_system_end(unsigned param);
unsigned kol_system_cpufreq();
unsigned kol_system_mem();
unsigned kol_system_memfree();
unsigned kol_system_time_get();
unsigned kol_system_date_get();
void kol_path_file2dir(char *dir, char *fname);
void kol_path_full(char *full, char *fname);
void kol_screen_wait_rr();
void kol_screen_get_size(unsigned *w, unsigned *h);
unsigned kol_skin_height();
unsigned kol_thread_start(unsigned start, unsigned stack);
unsigned kol_time_tick();
unsigned kol_sound_speaker(char data[]);
unsigned kol_process_info(unsigned slot, char buf1k[]);
int kol_process_kill_pid(unsigned process);
void kol_get_kernel_ver(char buff16b[]);
int kol_kill_process(unsigned process);

View File

@@ -0,0 +1,133 @@
void _tp_list_realloc(_tp_list *self,int len) {
if (!len) { len=1; }
self->items = (tp_obj*)tp_realloc(self->items,len*sizeof(tp_obj));
self->alloc = len;
}
void _tp_list_set(TP,_tp_list *self,int k, tp_obj v, const char *error) {
if (k >= self->len) { tp_raise(,"%s: KeyError: %d\n",error,k); }
self->items[k] = v;
tp_grey(tp,v);
}
void _tp_list_free(_tp_list *self) {
tp_free(self->items);
tp_free(self);
}
tp_obj _tp_list_get(TP,_tp_list *self,int k,const char *error) {
if (k >= self->len) { tp_raise(tp_None,"%s: KeyError: %d\n",error,k); }
return self->items[k];
}
void _tp_list_insertx(TP,_tp_list *self, int n, tp_obj v) {
if (self->len >= self->alloc) {
_tp_list_realloc(self,self->alloc*2);
}
if (n < self->len) { memmove(&self->items[n+1],&self->items[n],sizeof(tp_obj)*(self->len-n)); }
self->items[n] = v;
self->len += 1;
}
void _tp_list_appendx(TP,_tp_list *self, tp_obj v) {
_tp_list_insertx(tp,self,self->len,v);
}
void _tp_list_insert(TP,_tp_list *self, int n, tp_obj v) {
_tp_list_insertx(tp,self,n,v);
tp_grey(tp,v);
}
void _tp_list_append(TP,_tp_list *self, tp_obj v) {
_tp_list_insert(tp,self,self->len,v);
}
tp_obj _tp_list_pop(TP,_tp_list *self, int n, const char *error) {
tp_obj r = _tp_list_get(tp,self,n,error);
if (n != self->len-1) { memmove(&self->items[n],&self->items[n+1],sizeof(tp_obj)*(self->len-(n+1))); }
self->len -= 1;
return r;
}
int _tp_list_find(TP,_tp_list *self, tp_obj v) {
int n;
for (n=0; n<self->len; n++) {
if (tp_cmp(tp,v,self->items[n]) == 0) {
return n;
}
}
return -1;
}
tp_obj tp_index(TP) {
tp_obj self = TP_OBJ();
tp_obj v = TP_OBJ();
int i = _tp_list_find(tp,self.list.val,v);
if (i < 0) { tp_raise(tp_None,"tp_index(%s,%s) - item not found",TP_CSTR(self),TP_CSTR(v)); }
return tp_number(i);
}
_tp_list *_tp_list_new(void) {
return (_tp_list*)tp_malloc(sizeof(_tp_list));
}
tp_obj _tp_list_copy(TP, tp_obj rr) {
tp_obj val = {TP_LIST};
_tp_list *o = rr.list.val;
_tp_list *r = _tp_list_new();
*r = *o; r->gci = 0;
r->items = (tp_obj*)tp_malloc(sizeof(tp_obj)*o->alloc);
memcpy(r->items,o->items,sizeof(tp_obj)*o->alloc);
val.list.val = r;
return tp_track(tp,val);
}
tp_obj tp_append(TP) {
tp_obj self = TP_OBJ();
tp_obj v = TP_OBJ();
_tp_list_append(tp,self.list.val,v);
return tp_None;
}
tp_obj tp_pop(TP) {
tp_obj self = TP_OBJ();
return _tp_list_pop(tp,self.list.val,self.list.val->len-1,"pop");
}
tp_obj tp_insert(TP) {
tp_obj self = TP_OBJ();
int n = TP_NUM();
tp_obj v = TP_OBJ();
_tp_list_insert(tp,self.list.val,n,v);
return tp_None;
}
tp_obj tp_extend(TP) {
tp_obj self = TP_OBJ();
tp_obj v = TP_OBJ();
int i;
for (i=0; i<v.list.val->len; i++) {
_tp_list_append(tp,self.list.val,v.list.val->items[i]);
}
return tp_None;
}
tp_obj tp_list(TP) {
tp_obj r = {TP_LIST};
r.list.val = _tp_list_new();
return tp ? tp_track(tp,r) : r;
}
tp_obj tp_list_n(TP,int n,tp_obj *argv) {
int i;
tp_obj r = tp_list(tp); _tp_list_realloc(r.list.val,n);
for (i=0; i<n; i++) {
_tp_list_append(tp,r.list.val,argv[i]);
}
return r;
}
int _tp_sort_cmp(tp_obj *a,tp_obj *b) {
return tp_cmp(0,*a,*b);
}
tp_obj tp_sort(TP) {
tp_obj self = TP_OBJ();
qsort(self.list.val->items, self.list.val->len, sizeof(tp_obj), (int(*)(const void*,const void*))_tp_sort_cmp);
return tp_None;
}

View File

@@ -0,0 +1,68 @@
tp_obj *tp_ptr(tp_obj o) {
tp_obj *ptr = (tp_obj*)tp_malloc(sizeof(tp_obj)); *ptr = o;
return ptr;
}
tp_obj _tp_dcall(TP,tp_obj fnc(TP)) {
return fnc(tp);
}
tp_obj _tp_tcall(TP,tp_obj fnc) {
if (fnc.fnc.ftype&2) {
_tp_list_insert(tp,tp->params.list.val,0,fnc.fnc.info->self);
}
return _tp_dcall(tp,(tp_obj (*)(tp_vm *))fnc.fnc.val);
}
tp_obj tp_fnc_new(TP,int t, void *v, tp_obj s, tp_obj g) {
tp_obj r = {TP_FNC};
_tp_fnc *info = (_tp_fnc*)tp_malloc(sizeof(_tp_fnc));
info->self = s;
info->globals = g;
r.fnc.ftype = t;
r.fnc.info = info;
r.fnc.val = v;
return tp_track(tp,r);
}
tp_obj tp_def(TP,void *v, tp_obj g) {
return tp_fnc_new(tp,1,v,tp_None,g);
}
tp_obj tp_fnc(TP,tp_obj v(TP)) {
return tp_fnc_new(tp,0,v,tp_None,tp_None);
}
tp_obj tp_method(TP,tp_obj self,tp_obj v(TP)) {
return tp_fnc_new(tp,2,v,self,tp_None);
}
tp_obj tp_data(TP,int magic,void *v) {
tp_obj r = {TP_DATA};
r.data.info = (_tp_data*)tp_malloc(sizeof(_tp_data));
r.data.val = v;
r.data.magic = magic;
return tp_track(tp,r);
}
tp_obj tp_params(TP) {
tp_obj r;
tp->params = tp->_params.list.val->items[tp->cur];
r = tp->_params.list.val->items[tp->cur];
r.list.val->len = 0;
return r;
}
tp_obj tp_params_n(TP,int n, tp_obj argv[]) {
tp_obj r = tp_params(tp);
int i; for (i=0; i<n; i++) { _tp_list_append(tp,r.list.val,argv[i]); }
return r;
}
tp_obj tp_params_v(TP,int n,...) {
int i;
tp_obj r = tp_params(tp);
va_list a; va_start(a,n);
for (i=0; i<n; i++) {
_tp_list_append(tp,r.list.val,va_arg(a,tp_obj));
}
va_end(a);
return r;
}

View File

@@ -0,0 +1,24 @@
#include "tp.c"
const char header[]="TinyPy for kolibriOS";
const int argc = 2;
void main(void) {
char *argv[2]={"tpmain", ""};
CONSOLE_INIT(header);
con_printf("TinyPy console, version 1.1.\n");
con_printf("Enter program file:");
if (!(argv[1] = malloc(256)))
con_printf("Memory error\n");
con_gets(argv[1], 256);
argv[1][strlen(argv[1]) - 1] = '\0';
con_printf("Running file %s\n", argv[1]);
tp_vm *tp = tp_init(argc, argv);
tp_call(tp,"py2bc","tinypy",tp_None);
tp_deinit(tp);
return;
}
/**/

View File

@@ -0,0 +1,276 @@
tp_obj tp_str(TP,tp_obj self) {
int type = self.type;
if (type == TP_STRING) {
return self;
}
if (type == TP_NUMBER) {
tp_num v = self.number.val;
if ((fabs(v)-fabs((long)v)) < 0.000001) { return tp_printf(tp,"%ld",(long)v); }
return tp_printf(tp,"%f",v);
} else if(type == TP_DICT) {
return tp_printf(tp,"<dict 0x%x>",self.dict.val);
} else if(type == TP_LIST) {
return tp_printf(tp,"<list 0x%x>",self.list.val);
} else if (type == TP_NONE) {
return tp_string("None");
} else if (type == TP_DATA) {
return tp_printf(tp,"<data 0x%x>",self.data.val);
} else if (type == TP_FNC) {
return tp_printf(tp,"<fnc 0x%x>",self.fnc.info);
}
return tp_string("<?>");
}
int tp_bool(TP,tp_obj v) {
switch(v.type) {
case TP_NUMBER: return v.number.val != 0;
case TP_NONE: return 0;
case TP_STRING: return v.string.len != 0;
case TP_LIST: return v.list.val->len != 0;
case TP_DICT: return v.dict.val->len != 0;
}
return 1;
}
tp_obj tp_has(TP,tp_obj self, tp_obj k) {
int type = self.type;
if (type == TP_DICT) {
if (_tp_dict_find(tp,self.dict.val,k) != -1) { return tp_True; }
return tp_False;
} else if (type == TP_STRING && k.type == TP_STRING) {
char *p = strstr(TP_CSTR(self),TP_CSTR(k));
return tp_number(p != 0);
} else if (type == TP_LIST) {
return tp_number(_tp_list_find(tp,self.list.val,k)!=-1);
}
tp_raise(tp_None,"tp_has(%s,%s)",TP_CSTR(self),TP_CSTR(k));
}
void tp_del(TP,tp_obj self, tp_obj k) {
int type = self.type;
if (type == TP_DICT) {
_tp_dict_del(tp,self.dict.val,k,"tp_del");
return;
}
tp_raise(,"tp_del(%s,%s)",TP_CSTR(self),TP_CSTR(k));
}
tp_obj tp_iter(TP,tp_obj self, tp_obj k) {
int type = self.type;
if (type == TP_LIST || type == TP_STRING) { return tp_get(tp,self,k); }
if (type == TP_DICT && k.type == TP_NUMBER) {
return self.dict.val->items[_tp_dict_next(tp,self.dict.val)].key;
}
tp_raise(tp_None,"tp_iter(%s,%s)",TP_CSTR(self),TP_CSTR(k));
}
tp_obj tp_get(TP,tp_obj self, tp_obj k) {
int type = self.type;
tp_obj r;
/*con_printf("tp_get %s %s\n", TP_CSTR(self), TP_CSTR(k));*/
if (type == TP_DICT) {
return _tp_dict_get(tp,self.dict.val,k,"tp_get");
} else if (type == TP_LIST) {
if (k.type == TP_NUMBER) {
int l = tp_len(tp,self).number.val;
int n = k.number.val;
n = (n<0?l+n:n);
return _tp_list_get(tp,self.list.val,n,"tp_get");
} else if (k.type == TP_STRING) {
if (strcmp("append",TP_CSTR(k)) == 0) {
return tp_method(tp,self,tp_append);
} else if (strcmp("pop",TP_CSTR(k)) == 0) {
return tp_method(tp,self,tp_pop);
} else if (strcmp("index",TP_CSTR(k)) == 0) {
return tp_method(tp,self,tp_index);
} else if (strcmp("sort",TP_CSTR(k)) == 0) {
return tp_method(tp,self,tp_sort);
} else if (strcmp("extend",TP_CSTR(k)) == 0) {
return tp_method(tp,self,tp_extend);
} else if (strcmp("*",TP_CSTR(k)) == 0) {
tp_params_v(tp,1,self);
r = tp_copy(tp);
self.list.val->len=0;
return r;
}
} else if (k.type == TP_NONE) {
return _tp_list_pop(tp,self.list.val,0,"tp_get");
}
} else if (type == TP_STRING) {
if (k.type == TP_NUMBER) {
int l = self.string.len;
int n = k.number.val;
n = (n<0?l+n:n);
if (n >= 0 && n < l) { return tp_string_n(tp->chars[(unsigned char)self.string.val[n]],1); }
} else if (k.type == TP_STRING) {
if (strcmp("join",TP_CSTR(k)) == 0) {
return tp_method(tp,self,tp_join);
} else if (strcmp("split",TP_CSTR(k)) == 0) {
return tp_method(tp,self,tp_split);
} else if (strcmp("index",TP_CSTR(k)) == 0) {
return tp_method(tp,self,tp_str_index);
} else if (strcmp("strip",TP_CSTR(k)) == 0) {
return tp_method(tp,self,tp_strip);
} else if (strcmp("replace",TP_CSTR(k)) == 0) {
return tp_method(tp,self,tp_replace);
}
}
}
if (k.type == TP_LIST) {
int a,b,l;
tp_obj tmp;
l = tp_len(tp,self).number.val;
tmp = tp_get(tp,k,tp_number(0));
if (tmp.type == TP_NUMBER) { a = tmp.number.val; }
else if(tmp.type == TP_NONE) { a = 0; }
else { tp_raise(tp_None,"%s is not a number",TP_CSTR(tmp)); }
tmp = tp_get(tp,k,tp_number(1));
if (tmp.type == TP_NUMBER) { b = tmp.number.val; }
else if(tmp.type == TP_NONE) { b = l; }
else { tp_raise(tp_None,"%s is not a number",TP_CSTR(tmp)); }
a = _tp_max(0,(a<0?l+a:a)); b = _tp_min(l,(b<0?l+b:b));
if (type == TP_LIST) {
return tp_list_n(tp,b-a,&self.list.val->items[a]);
} else if (type == TP_STRING) {
tp_obj r = tp_string_t(tp,b-a);
char *ptr = r.string.info->s;
memcpy(ptr,self.string.val+a,b-a); ptr[b-a]=0;
return tp_track(tp,r);
}
}
con_printf("Raising exception\n");
tp_raise(tp_None,"tp_get(%s,%s)",TP_CSTR(self),TP_CSTR(k));
}
int tp_iget(TP,tp_obj *r, tp_obj self, tp_obj k) {
if (self.type == TP_DICT) {
int n = _tp_dict_find(tp,self.dict.val,k);
if (n == -1) { return 0; }
*r = self.dict.val->items[n].val;
tp_grey(tp,*r);
return 1;
}
if (self.type == TP_LIST && !self.list.val->len) { return 0; }
*r = tp_get(tp,self,k); tp_grey(tp,*r);
return 1;
}
void tp_set(TP,tp_obj self, tp_obj k, tp_obj v) {
int type;
con_printf("vm is %x self is %x k is %x v is %x", tp, self, k, v);
type = self.type;
if (type == TP_DICT) {
_tp_dict_set(tp,self.dict.val,k,v);
return;
} else if (type == TP_LIST) {
if (k.type == TP_NUMBER) {
_tp_list_set(tp,self.list.val,k.number.val,v,"tp_set");
return;
} else if (k.type == TP_NONE) {
_tp_list_append(tp,self.list.val,v);
return;
} else if (k.type == TP_STRING) {
if (strcmp("*",TP_CSTR(k)) == 0) {
tp_params_v(tp,2,self,v); tp_extend(tp);
return;
}
}
}
tp_raise(,"tp_set(%s,%s,%s)",TP_CSTR(self),TP_CSTR(k),TP_CSTR(v));
}
tp_obj tp_add(TP,tp_obj a, tp_obj b) {
if (a.type == TP_NUMBER && a.type == b.type) {
return tp_number(a.number.val+b.number.val);
} else if (a.type == TP_STRING && a.type == b.type) {
int al = a.string.len, bl = b.string.len;
tp_obj r = tp_string_t(tp,al+bl);
char *s = r.string.info->s;
memcpy(s,a.string.val,al); memcpy(s+al,b.string.val,bl);
return tp_track(tp,r);
} else if (a.type == TP_LIST && a.type == b.type) {
tp_obj r;
tp_params_v(tp,1,a);
r = tp_copy(tp);
tp_params_v(tp,2,r,b);
tp_extend(tp);
return r;
}
tp_raise(tp_None,"tp_add(%s,%s)",TP_CSTR(a),TP_CSTR(b));
}
tp_obj tp_mul(TP,tp_obj a, tp_obj b) {
if (a.type == TP_NUMBER && a.type == b.type) {
return tp_number(a.number.val*b.number.val);
} else if (a.type == TP_STRING && b.type == TP_NUMBER) {
int al = a.string.len; int n = b.number.val;
tp_obj r = tp_string_t(tp,al*n);
char *s = r.string.info->s;
int i; for (i=0; i<n; i++) { memcpy(s+al*i,a.string.val,al); }
return tp_track(tp,r);
}
tp_raise(tp_None,"tp_mul(%s,%s)",TP_CSTR(a),TP_CSTR(b));
}
tp_obj tp_len(TP,tp_obj self) {
int type = self.type;
if (type == TP_STRING) {
return tp_number(self.string.len);
} else if (type == TP_DICT) {
return tp_number(self.dict.val->len);
} else if (type == TP_LIST) {
return tp_number(self.list.val->len);
}
tp_raise(tp_None,"tp_len(%s)",TP_CSTR(self));
}
int tp_cmp(TP,tp_obj a, tp_obj b) {
if (a.type != b.type) { return a.type-b.type; }
switch(a.type) {
case TP_NONE: return 0;
case TP_NUMBER: return _tp_sign(a.number.val-b.number.val);
case TP_STRING: {
int v = memcmp(a.string.val,b.string.val,_tp_min(a.string.len,b.string.len));
if (v == 0) { v = a.string.len-b.string.len; }
return v;
}
case TP_LIST: {
int n,v; for(n=0;n<_tp_min(a.list.val->len,b.list.val->len);n++) {
tp_obj aa = a.list.val->items[n]; tp_obj bb = b.list.val->items[n];
if (aa.type == TP_LIST && bb.type == TP_LIST) { v = aa.list.val-bb.list.val; } else { v = tp_cmp(tp,aa,bb); }
if (v) { return v; } }
return a.list.val->len-b.list.val->len;
}
case TP_DICT: return a.dict.val - b.dict.val;
case TP_FNC: return a.fnc.info - b.fnc.info;
case TP_DATA: return (char*)a.data.val - (char*)b.data.val;
}
tp_raise(0,"tp_cmp(%s,%s)",TP_CSTR(a),TP_CSTR(b));
}
#define TP_OP(name,expr) \
tp_obj name(TP,tp_obj _a,tp_obj _b) { \
if (_a.type == TP_NUMBER && _a.type == _b.type) { \
tp_num a = _a.number.val; tp_num b = _b.number.val; \
return tp_number(expr); \
} \
tp_raise(tp_None,"%s(%s,%s)",#name,TP_CSTR(_a),TP_CSTR(_b)); \
}
TP_OP(tp_and,((long)a)&((long)b));
TP_OP(tp_or,((long)a)|((long)b));
TP_OP(tp_mod,((long)a)%((long)b));
TP_OP(tp_lsh,((long)a)<<((long)b));
TP_OP(tp_rsh,((long)a)>>((long)b));
TP_OP(tp_sub,a-b);
TP_OP(tp_div,a/b);
TP_OP(tp_pow,pow(a,b));
/**/

View File

@@ -0,0 +1,408 @@
import tokenize
from tokenize import Token
if '.' in str(1.0):
from boot import *
def check(t,*vs):
if vs[0] == None: return True
if t.type in vs: return True
if t.type == 'symbol' and t.val in vs: return True
return False
def tweak(k,v):
P.stack.append((k,dmap[k]))
if v: dmap[k] = omap[k]
else: dmap[k] = {'lbp':0,'nud':itself}
def restore():
k,v = P.stack.pop()
dmap[k] = v
def cpy(d):
r = {}
for k in d: r[k] = d[k]
return r
class PData:
def __init__(self,s,tokens):
self.s = s
self.tokens = tokens
self.pos = 0
self.token = None
self.stack = []
def init(self):
global omap,dmap
omap = cpy(base_dmap)
dmap = cpy(base_dmap)
self.advance()
def advance(self,val=None):
if not check(self.token,val):
error('expected '+val,self.token)
if self.pos < len(self.tokens):
t = self.tokens[self.pos]
self.pos += 1
else:
t = Token((0,0),'eof','eof')
self.token = do(t)
return t
def error(ctx,t):
print t
tokenize.u_error(ctx,P.s,t.pos)
def nud(t):
#if 'nud' not in t:
# error('no nud',t)
return t.nud(t)
def led(t,left):
#if 'led' not in t:
# error('no led',t)
return t.led(t,left)
def get_lbp(t):
#if 'lbp' not in t:
# error('no lbp',t)
return t.lbp
def get_items(t):
#if 'items' not in t:
# error('no items',t)
return t.items
def expression(rbp):
t = P.token
advance()
left = nud(t)
while rbp < get_lbp(P.token):
t = P.token
advance()
left = led(t,left)
return left
def infix_led(t,left):
t.items = [left,expression(t.bp)]
return t
def infix_is(t,left):
if check(P.token,'not'):
t.val = 'isnot'
advance('not')
t.items = [left,expression(t.bp)]
return t
def infix_not(t,left):
advance('in')
t.val = 'notin'
t.items = [left,expression(t.bp)]
return t
def infix_tuple(t,left):
r = expression(t.bp)
if left.val == ',':
left.items.append(r)
return left
t.items = [left,r]
t.type = 'tuple'
return t
def lst(t):
if t == None: return []
if check(t,',','tuple','statements'):
return get_items(t)
return [t]
def ilst(typ,t):
return Token(t.pos,typ,typ,lst(t))
def call_led(t,left):
r = Token(t.pos,'call','$',[left])
while not check(P.token,')'):
tweak(',',0)
r.items.append(expression(0))
if P.token.val == ',': advance(',')
restore()
advance(")")
return r
def get_led(t,left):
r = Token(t.pos,'get','.',[left])
items = [left]
more = False
while not check(P.token,']'):
more = False
if check(P.token,':'):
items.append(Token(P.token.pos,'symbol','None'))
else:
items.append(expression(0))
if check(P.token,':'):
advance(':')
more = True
if more:
items.append(Token(P.token.pos,'symbol','None'))
if len(items) > 2:
items = [left,Token(t.pos,'slice',':',items[1:])]
r.items = items
advance("]")
return r
def dot_led(t,left):
r = expression(t.bp)
r.type = 'string'
t.items = [left,r]
return t
def itself(t):
return t
def paren_nud(t):
tweak(',',1)
r = expression(0)
restore()
advance(')')
return r
def list_nud(t):
t.type = 'list'
t.val = '[]'
t.items = []
next = P.token
tweak(',',0)
while not check(P.token,'for',']'):
r = expression(0)
t.items.append(r)
if P.token.val == ',': advance(',')
if check(P.token,'for'):
t.type = 'comp'
advance('for')
tweak('in',0)
t.items.append(expression(0))
advance('in')
t.items.append(expression(0))
restore()
restore()
advance(']')
return t
def dict_nud(t):
t.type='dict'
t.val = '{}'
t.items = []
tweak(',',0)
while not check(P.token,'}'):
t.items.append(expression(0))
if check(P.token,':',','): advance()
restore()
advance('}')
return t
def advance(t=None):
return P.advance(t)
def block():
items = []
tok = P.token
while check(P.token,'nl'): advance()
if check(P.token,'indent'):
advance('indent')
while not check(P.token,'dedent'):
items.append(expression(0))
while check(P.token,';','nl'): advance()
advance('dedent')
else:
items.append(expression(0))
while check(P.token,';'):
advance(';')
items.append(expression(0))
while check(P.token,'nl'): advance()
if len(items) > 1:
return Token(tok.pos,'statements',';',items)
return items.pop()
def def_nud(t):
items = t.items = []
items.append(P.token); advance()
advance('(')
r = Token(t.pos,'symbol','():',[])
items.append(r)
while not check(P.token,')'):
tweak(',',0)
r.items.append(expression(0))
if check(P.token,','): advance(',')
restore()
advance(')')
advance(':')
items.append(block())
return t
def while_nud(t):
items = t.items = []
items.append(expression(0))
advance(':')
items.append(block())
return t
def class_nud(t):
items = t.items = []
items.append(expression(0))
advance(':')
items.append(ilst('methods',block()))
return t
def from_nud(t):
items = t.items = []
items.append(expression(0))
advance('import')
items.append(expression(0))
return t
def for_nud(t):
items = t.items = []
tweak('in',0)
items.append(expression(0))
advance('in')
items.append(expression(0))
restore()
advance(':')
items.append(block())
return t
def if_nud(t):
items = t.items = []
a = expression(0)
advance(':')
b = block()
items.append(Token(t.pos,'elif','elif',[a,b]))
while check(P.token,'elif'):
tok = P.token
advance('elif')
a = expression(0)
advance(':')
b = block()
items.append(Token(tok.pos,'elif','elif',[a,b]))
if check(P.token,'else'):
tok = P.token
advance('else')
advance(':')
b = block()
items.append(Token(tok.pos,'else','else',[b]))
return t
def try_nud(t):
items = t.items = []
advance(':')
b = block()
items.append(b)
while check(P.token,'except'):
tok = P.token
advance('except')
if not check(P.token,':'): a = expression(0)
else: a = Token(tok.pos,'symbol','None')
advance(':')
b = block()
items.append(Token(tok.pos,'except','except',[a,b]))
if check(P.token,'else'):
tok = P.token
advance('else')
advance(':')
b = block()
items.append(Token(tok.pos,'else','else',[b]))
return t
def prefix_nud(t):
#bp = 70
#if 'bp' in t: bp = t['bp']
bp = t.bp
t.items = [expression(bp)]
return t
def prefix_nud0(t):
if check(P.token,'nl',';','eof','dedent'): return t
return prefix_nud(t)
def prefix_nuds(t):
r = expression(0)
return ilst(t.type,r)
def prefix_neg(t):
r = expression(50)
if r.type == 'number':
r.val = str(-float(r.val))
return r
t.items = [Token(t.pos,'number','0'),r]
return t
def vargs_nud(t):
r = prefix_nud(t)
t.type = 'args'
t.val = '*'
return t
def nargs_nud(t):
r = prefix_nud(t)
t.type = 'nargs'
t.val = '**'
return t
base_dmap = {
',':{'lbp':20,'bp':20,'led':infix_tuple},
'+':{'lbp':50,'bp':50,'led':infix_led},
'-':{'lbp':50,'nud':prefix_neg,
'bp':50,'led':infix_led},
'not':{'lbp':35,'nud':prefix_nud,'bp':35,
'bp':35,'led':infix_not },
'%':{'lbp':60,'bp':60,'led':infix_led},
'*':{'lbp':60,'nud':vargs_nud,
'bp':60,'led':infix_led,},
'**': {'lbp':65,'nud':nargs_nud,
'bp':65,'led':infix_led,},
'/':{'lbp':60,'bp':60,'led':infix_led},
'(':{'lbp':70,'nud':paren_nud,
'bp':80,'led':call_led,},
'[':{'lbp':70,'nud':list_nud,
'bp':80,'led':get_led,},
'{':{'lbp':0,'nud':dict_nud,},
'.':{'lbp':80,'bp':80,'led':dot_led,'type':'get',},
'break':{'lbp':0,'nud':itself,'type':'break'},
'pass':{'lbp':0,'nud':itself,'type':'pass'},
'continue':{'lbp':0,'nud':itself,'type':'continue'},
'eof':{'lbp':0,'type':'eof','val':'eof'},
'def':{'lbp':0,'nud':def_nud,'type':'def',},
'while':{'lbp':0,'nud':while_nud,'type':'while',},
'for':{'lbp':0,'nud':for_nud,'type':'for',},
'try':{'lbp':0,'nud':try_nud,'type':'try',},
'if':{'lbp':0,'nud':if_nud,'type':'if',},
'class':{'lbp':0,'nud':class_nud,'type':'class',},
'raise':{'lbp':0,'nud':prefix_nud0,'type':'raise','bp':20,},
'return':{'lbp':0,'nud':prefix_nud0,'type':'return','bp':10,},
'import':{'lbp':0,'nud':prefix_nuds,'type':'import','bp':20,},
'from':{'lbp':0,'nud':from_nud,'type':'from','bp':20,},
'del':{'lbp':0,'nud':prefix_nuds,'type':'del','bp':10,},
'global':{'lbp':0,'nud':prefix_nuds,'type':'globals','bp':20,},
'=':{
'lbp':10,'bp':9,'led':infix_led,
},
}
def i_infix(bp,led,*vs):
for v in vs: base_dmap[v] = {'lbp':bp,'bp':bp,'led':led}
i_infix(40,infix_led,'<','>','<=','>=','!=','==')
i_infix(40,infix_is,'is','in')
i_infix(10,infix_led,'+=','-=','*=','/=')
i_infix(31,infix_led,'and','&')
i_infix(30,infix_led,'or','|')
i_infix(36,infix_led,'<<','>>')
def i_terms(*vs):
for v in vs: base_dmap[v] = {'lbp':0,'nud':itself}
i_terms(')','}',']',';',':','nl','elif','else','True','False','None','name','string','number','indent','dedent','except')
base_dmap['nl']['val'] = 'nl'
def gmap(t,v):
if v not in dmap:
error('unknown "%s"'%v,t)
return dmap[v]
def do(t):
if t.type == 'symbol': r = gmap(t,t.val)
else: r = gmap(t,t.type)
merge(t,r)
return t
def do_module():
tok = P.token
items = []
while not check(P.token,'eof'):
items.append(block())
if len(items) > 1:
return Token(tok.pos,'statements',';',items)
return items.pop()
def parse(s,tokens,wrap=0):
global P
s = tokenize.clean(s)
P=PData(s,tokens); P.init()
r = do_module()
P = None
return r

View File

@@ -0,0 +1,56 @@
print("Starting py2bc")
if not (str(1.0) == "1"):
from boot import *
import tokenize,parse,encode
def _compile(s,fname):
tokens = tokenize.tokenize(s)
t = parse.parse(s,tokens)
r = encode.encode(fname,s,t)
return r
def _import(name):
if name in MODULES:
return MODULES[name]
py = name+".py"
tpc = name+".tpc"
print("CP")
if exists(py):
if not exists(tpc) or mtime(py) > mtime(tpc):
s = load(py)
code = _compile(s,py)
save(tpc,code)
if not exists(tpc): raise
code = load(tpc)
g = {'__name__':name,'__code__':code}
g['__dict__'] = g
MODULES[name] = g
exec(code,g)
return g
def _init():
BUILTINS['compile'] = _compile
BUILTINS['import'] = _import
def import_fname(fname,name):
g = {}
g['__name__'] = name
MODULES[name] = g
s = load(fname)
code = _compile(s,fname)
g['__code__'] = code
exec(code,g)
return g
def tinypy():
print("tinypy called")
return import_fname(ARGV[0],'__main__')
def main(src,dest):
s = load(src)
r = _compile(s,src)
save(dest,r)
if __name__ == '__main__':
print("Running main")
main(ARGV[1],ARGV[2])

View File

@@ -0,0 +1,165 @@
#include <stdarg.h>
tp_obj tp_string_t(TP, int n) {
tp_obj r = tp_string_n(0,n);
r.string.info = (_tp_string*)tp_malloc(sizeof(_tp_string)+n);
r.string.val = r.string.info->s;
return r;
}
tp_obj tp_printf(TP, char const *fmt,...) {
int l;
tp_obj r;
char tmp[2000];
char *s;
va_list arg;
va_start(arg, fmt);
l = vsnprintf(tmp, sizeof(tmp), fmt,arg);
r = tp_string_t(tp,l);
s = r.string.info->s;
va_end(arg);
va_start(arg, fmt);
vsprintf(s,fmt,arg);
va_end(arg);
return tp_track(tp,r);
}
int _tp_str_index(tp_obj s, tp_obj k) {
int i=0;
while ((s.string.len - i) >= k.string.len) {
if (memcmp(s.string.val+i,k.string.val,k.string.len) == 0) {
return i;
}
i += 1;
}
return -1;
}
tp_obj tp_join(TP) {
tp_obj delim = TP_OBJ();
tp_obj val = TP_OBJ();
int l=0,i;
tp_obj r;
char *s;
for (i=0; i<val.list.val->len; i++) {
if (i!=0) { l += delim.string.len; }
l += tp_str(tp,val.list.val->items[i]).string.len;
}
r = tp_string_t(tp,l);
s = r.string.info->s;
l = 0;
for (i=0; i<val.list.val->len; i++) {
tp_obj e;
if (i!=0) {
memcpy(s+l,delim.string.val,delim.string.len); l += delim.string.len;
}
e = tp_str(tp,val.list.val->items[i]);
memcpy(s+l,e.string.val,e.string.len); l += e.string.len;
}
return tp_track(tp,r);
}
tp_obj tp_string_slice(TP,tp_obj s, int a, int b) {
tp_obj r = tp_string_t(tp,b-a);
char *m = r.string.info->s;
memcpy(m,s.string.val+a,b-a);
return tp_track(tp,r);
}
tp_obj tp_split(TP) {
tp_obj v = TP_OBJ();
tp_obj d = TP_OBJ();
tp_obj r = tp_list(tp);
int i;
while ((i=_tp_str_index(v,d))!=-1) {
_tp_list_append(tp,r.list.val,tp_string_slice(tp,v,0,i));
v.string.val += i + d.string.len; v.string.len -= i + d.string.len;
/* tp_grey(tp,r); // should stop gc or something instead*/
}
_tp_list_append(tp,r.list.val,tp_string_slice(tp,v,0,v.string.len));
/* tp_grey(tp,r); // should stop gc or something instead*/
return r;
}
tp_obj tp_find(TP) {
tp_obj s = TP_OBJ();
tp_obj v = TP_OBJ();
return tp_number(_tp_str_index(s,v));
}
tp_obj tp_str_index(TP) {
tp_obj s = TP_OBJ();
tp_obj v = TP_OBJ();
int n = _tp_str_index(s,v);
if (n >= 0) { return tp_number(n); }
tp_raise(tp_None,"tp_str_index(%s,%s)",s,v);
}
tp_obj tp_str2(TP) {
tp_obj v = TP_OBJ();
return tp_str(tp,v);
}
tp_obj tp_chr(TP) {
int v = TP_NUM();
return tp_string_n(tp->chars[(unsigned char)v],1);
}
tp_obj tp_ord(TP) {
char const *s = TP_STR();
return tp_number((unsigned char)s[0]);
}
tp_obj tp_strip(TP) {
char const *v = TP_STR();
int i, l = strlen(v); int a = l, b = 0;
tp_obj r;
char *s;
for (i=0; i<l; i++) {
if (v[i] != ' ' && v[i] != '\n' && v[i] != '\t' && v[i] != '\r') {
a = _tp_min(a,i); b = _tp_max(b,i+1);
}
}
if ((b-a) < 0) { return tp_string(""); }
r = tp_string_t(tp,b-a);
s = r.string.info->s;
memcpy(s,v+a,b-a);
return tp_track(tp,r);
}
tp_obj tp_replace(TP) {
tp_obj s = TP_OBJ();
tp_obj k = TP_OBJ();
tp_obj v = TP_OBJ();
tp_obj p = s;
int i,n = 0;
int c;
int l;
tp_obj rr;
char *r;
char *d;
tp_obj z;
while ((i = _tp_str_index(p,k)) != -1) {
n += 1;
p.string.val += i + k.string.len; p.string.len -= i + k.string.len;
}
/* fprintf(stderr,"ns: %d\n",n); */
l = s.string.len + n * (v.string.len-k.string.len);
rr = tp_string_t(tp,l);
r = rr.string.info->s;
d = r;
z = p = s;
while ((i = _tp_str_index(p,k)) != -1) {
p.string.val += i; p.string.len -= i;
memcpy(d,z.string.val,c=(p.string.val-z.string.val)); d += c;
p.string.val += k.string.len; p.string.len -= k.string.len;
memcpy(d,v.string.val,v.string.len); d += v.string.len;
z = p;
}
memcpy(d,z.string.val,(s.string.val + s.string.len) - z.string.val);
return tp_track(tp,rr);
}

View File

@@ -0,0 +1,2 @@
if __name__=="__main__":
print("ok!")

View File

@@ -0,0 +1,750 @@
# figure out if we're in python or tinypy (tinypy displays "1.0" as "1")
is_tinypy = (str(1.0) == "1")
if not is_tinypy:
from boot import *
################################################################################
RM = 'rm -f '
VM = './vm '
TINYPY = './tinypy '
TMP = 'tmp.txt'
if '-mingw32' in ARGV or "-win" in ARGV:
RM = 'del '
VM = 'vm '
TINYPY = 'tinypy '
TMP = 'tmp.txt'
#TMP = 'stdout.txt'
def system_rm(fname):
system(RM+fname)
################################################################################
#if not is_tinypy:
#v = chksize()
#assert (v < 65536)
################################################################################
def t_show(t):
if t.type == 'string': return '"'+t.val+'"'
if t.type == 'number': return t.val
if t.type == 'symbol': return t.val
if t.type == 'name': return '$'+t.val
return t.type
def t_tokenize(s,exp=''):
import tokenize
result = tokenize.tokenize(s)
res = ' '.join([t_show(t) for t in result])
#print(s); print(exp); print(res)
assert(res == exp)
if __name__ == '__main__':
t_tokenize("234",'234')
t_tokenize("234.234",'234.234')
t_tokenize("phil",'$phil')
t_tokenize("_phil234",'$_phil234')
t_tokenize("'phil'",'"phil"')
t_tokenize('"phil"','"phil"')
t_tokenize("'phil' x",'"phil" $x')
t_tokenize("#comment","")
t_tokenize("and","and")
t_tokenize("=","=")
t_tokenize("()","( )")
t_tokenize("(==)","( == )")
t_tokenize("phil=234","$phil = 234")
t_tokenize("a b","$a $b")
t_tokenize("a\nb","$a nl $b")
t_tokenize("a\n b","$a nl indent $b dedent")
t_tokenize("a\n b\n c", "$a nl indent $b nl indent $c dedent dedent")
t_tokenize("a\n b\n c", "$a nl indent $b nl $c dedent")
t_tokenize("a\n b\n \n c", "$a nl indent $b nl nl indent $c dedent dedent")
t_tokenize("a\n b\nc", "$a nl indent $b nl dedent $c")
t_tokenize("a\n b\n c\nd", "$a nl indent $b nl indent $c nl dedent dedent $d")
t_tokenize("(\n )","( )")
t_tokenize(" x","indent $x dedent")
t_tokenize(" #","")
t_tokenize("None","None")
################################################################################
def t_lisp(t):
if t.type == 'block':
return """{%s}"""%' '.join([t_lisp(tt) for tt in t.items])
if t.type == 'statement':
return """%s;"""%' '.join([t_lisp(tt) for tt in t.items])
if t.items == None: return t.val
args = ''.join([" "+t_lisp(tt) for tt in t.items])
return "("+t.val+args+")"
def t_parse(s,ex=''):
import tokenize, parse
r = ''
tokens = tokenize.tokenize(s)
tree = parse.parse(s,tokens)
r = t_lisp(tree)
#print(s); print(ex); print(r)
assert(r==ex)
if __name__ == '__main__':
t_parse('2+4*3', '(+ 2 (* 4 3))')
t_parse('4*(2+3)', '(* 4 (+ 2 3))')
t_parse('(2+3)*4', '(* (+ 2 3) 4)')
t_parse('1<2', '(< 1 2)')
t_parse('x=3', '(= x 3)')
t_parse('x = 2*3', '(= x (* 2 3))')
t_parse('x = y', '(= x y)')
t_parse('2,3', '(, 2 3)')
t_parse('2,3,4', '(, 2 3 4)')
t_parse('[]', '([])')
t_parse('[1]', '([] 1)')
t_parse('[2,3,4]', '([] 2 3 4)')
t_parse('print(3)', '($ print 3)')
t_parse('print()', '($ print)')
t_parse('print(2,3)', '($ print 2 3)')
t_parse('def fnc():pass', '(def fnc (():) pass)')
t_parse('def fnc(x):pass', '(def fnc ((): x) pass)')
t_parse('def fnc(x,y):pass', '(def fnc ((): x y) pass)')
t_parse('x\ny\nz', '(; x y z)')
t_parse('return x', '(return x)')
t_parse('print(test(2,3))', '($ print ($ test 2 3))')
t_parse('x.y', '(. x y)')
t_parse('get(2).x', '(. ($ get 2) x)')
t_parse('{}', '({})')
t_parse('True', 'True')
t_parse('False', 'False')
t_parse('None', 'None')
t_parse('while 1:pass', '(while 1 pass)')
t_parse('for x in y:pass', '(for x y pass)')
t_parse('print("x")', '($ print x)')
t_parse('if 1: pass', '(if (elif 1 pass))')
t_parse('x = []', '(= x ([]))')
t_parse('x[1]', '(. x 1)')
t_parse('import sdl', '(import sdl)')
t_parse('2 is 3', '(is 2 3)')
t_parse('2 is not 3', '(isnot 2 3)')
t_parse('x is None', '(is x None)')
t_parse('2 is 3 or 4 is 5', '(or (is 2 3) (is 4 5))')
t_parse('e.x == 3 or e.x == 4', '(or (== (. e x) 3) (== (. e x) 4))')
t_parse('if 1==2: 3\nelif 4:5\nelse:6', '(if (elif (== 1 2) 3) (elif 4 5) (else 6))')
t_parse('x = y(2)*3 + y(4)*5', '(= x (+ (* ($ y 2) 3) (* ($ y 4) 5)))')
t_parse('x(1,2)+y(3,4)', '(+ ($ x 1 2) ($ y 3 4))')
t_parse('x(a,b,c[d])', '($ x a b (. c d))')
t_parse('x(1,2)*j+y(3,4)*k+z(5,6)*l', '(+ (+ (* ($ x 1 2) j) (* ($ y 3 4) k)) (* ($ z 5 6) l))')
t_parse('a = b.x/c * 2 - 1', '(= a (- (* (/ (. b x) c) 2) 1))')
t_parse('for x in y: z', '(for x y z)')
t_parse('min(255,n*2)','($ min 255 (* n 2))')
t_parse('c = pal[i*8]','(= c (. pal (* i 8)))')
t_parse('{x:y,a:b}','({} x y a b)')
t_parse('x[1:2:3]','(. x (: 1 2 3))')
if is_tinypy: t_parse('x - -234','(- x -234)')
else: t_parse('x - -234','(- x -234.0)')
t_parse('x - -y','(- x (- 0 y))')
t_parse('x = ((y*4)-2)','(= x (- (* y 4) 2))')
if is_tinypy: t_parse('print([1,2,"OK",4][-3:3][1])','($ print (. (. ([] 1 2 OK 4) (: -3 3)) 1))')
else: t_parse('print([1,2,"OK",4][-3:3][1])','($ print (. (. ([] 1 2 OK 4) (: -3.0 3)) 1))')
t_parse('a,b = 1,2','(= (, a b) (, 1 2))')
t_parse('class C: pass','(class C (methods pass))')
t_parse('def test(*v): pass','(def test ((): (* v)) pass)')
t_parse('def test(**v): pass','(def test ((): (** v)) pass)')
t_parse('test(*v)','($ test (* v))')
t_parse('test(**v)','($ test (** v))')
t_parse('def test(x=y): pass','(def test ((): (= x y)) pass)')
t_parse('test(x=y)','($ test (= x y))')
t_parse('def test(y="K",x="Z"): pass','(def test ((): (= y K) (= x Z)) pass)')
t_parse('return x+y','(return (+ x y))')
t_parse('if "a" is not "b": pass','(if (elif (isnot a b) pass))')
t_parse('z = 0\nfor x in y: pass','(; (= z 0) (for x y pass))')
t_parse('for k in {"OK":0}: pass','(for k ({} OK 0) pass)')
t_parse('print(test(10,3,z=50000,*[200],**{"x":4000}))','($ print ($ test 10 3 (= z 50000) (* ([] 200)) (** ({} x 4000))))')
t_parse('x="OK";print(x)','(; (= x OK) ($ print x))')
t_parse('[(1,3)]','([] (, 1 3))')
t_parse('x[:]','(. x (: None None))')
t_parse('x[:1]','(. x (: None 1))')
t_parse('x[1:]','(. x (: 1 None))')
t_parse('return\nx','(; return x)')
t_parse('"""test"""','test')
t_parse('return a,b','(return (, a b))')
################################################################################
def showerror(cmd, ss, ex, res):
print(cmd)
print("ss : '" + str(ss) + "'")
print("ex : '" + str(ex) + "'")
print("res: '" + str(res) + "'")
def t_render(ss,ex,exact=True):
import tokenize, parse, encode
if not istype(ss,'list'): ss =[ss]
n = 1
for s in ss:
fname = 'tmp'+str(n)+'.tpc'
system_rm(fname)
tokens = tokenize.tokenize(s)
t = parse.parse(s,tokens)
r = encode.encode(fname,s,t)
f = save(fname,r)
n += 1
system_rm('tmp.txt')
cmd = VM + fname + " > tmp.txt"
system(cmd)
res = load(TMP).strip()
#print(ss,ex,res)
if exact:
if res != ex: showerror(cmd, ss, ex, res)
assert(res == ex)
else:
if ex not in res: showerror(cmd, ss, ex, res)
assert(ex in res)
def test_range():
t_render("""print(str(range(4))[:5])""","<list")
t_render("""print(len(range(4)))""","4")
t_render("""print(range(4)[0])""","0")
t_render("""print(range(4)[1])""","1")
t_render("""print(range(4)[-1])""","3")
t_render("""print(str(range(-4))[:5])""","<list")
t_render("""print(len(range(-4)))""","0")
t_render("""print(str(range(0,5,3))[:5])""","<list")
t_render("""print(len(range(0,5,3)))""","2")
t_render("""print(range(0,5,3)[0])""","0")
t_render("""print(range(0,5,3)[1])""","3")
t_render("""print(range(0,5,3)[-1])""","3")
t_render("""print(str(range(5,0,-3))[:5])""","<list")
t_render("""print(len(range(5,0,-3)))""","2")
t_render("""print(range(5,0,-3)[0])""","5")
t_render("""print(range(5,0,-3)[1])""","2")
t_render("""print(range(5,0,-3)[-1])""","2")
t_render("""print(str(range(-8,-4))[:5])""","<list")
t_render("""print(len(range(-8,-4)))""","4")
t_render("""print(range(-8,-4)[0])""","-8")
t_render("""print(range(-8,-4)[1])""","-7")
t_render("""print(range(-8,-4)[-1])""","-5")
t_render("""print(str(range(-4,-8,-1))[:5])""","<list")
t_render("""print(len(range(-4,-8,-1)))""","4")
t_render("""print(range(-4,-8,-1)[0])""","-4")
t_render("""print(range(-4,-8,-1)[1])""","-5")
t_render("""print(range(-4,-8,-1)[-1])""","-7")
t_render("""print(str(range(-4,-8))[:5])""","<list")
t_render("""print(len(range(-4,-8)))""","0")
t_render("""print(str(range(-8,-4,-1))[:5])""","<list")
t_render("""print(len(range(-8,-4,-1)))""","0")
t_render("""print(str(range(0,4,0))[:5])""","<list")
t_render("""print(len(range(0,4,0)))""","0")
if __name__ == '__main__':
t_render('print("hello world")',"hello world")
t_render('print(234)',"234")
t_render('a=3\nprint(a)',"3")
t_render('print(2+3)',"5")
t_render("""
x = 2
x += 3
print(x)
"""
,"5")
t_render("""
x = "OK"
print(x)
"""
,"OK")
t_render("""
a,b = 1,2
print(a+b)
"""
,"3")
t_render("""
x = 1
if x == 1:
print("yes")
""","yes")
t_render("""
if 0 == 1:
print("X")
else:
print("OK")
"""
,"OK")
t_render("""
if 0 == 1:
print("X")
elif 1 == 2:
print("Y")
else:
print("OK")
"""
,"OK")
t_render("""
def test(x,y):
return x+y
r = test(3,5)
print(r)
""","8")
t_render("""
x = 1
t = 0
while x<=5:
t = t+x
x = x+1
print(t)
""","15")
t_render("""
x = {}
x.y = "test"
print(x.y)
""","test")
t_render("""
if "a" is "a":
print("OK")
"""
,"OK")
t_render("""
if "a" is not "b":
print("OK")
"""
,"OK")
t_render("""
if None is None:
print("OK")
"""
,"OK")
t_render("""
if "x" is "x" or "y" is "y":
print("OK")
"""
,"OK")
t_render("""
x = 1
while x < 3:
break
x = x + 1
print(x)
"""
,"1")
t_render("""
x = 1
n = 0
while x < 10:
x = x + 1
if n == 2:
continue
n = n + 1
print(n)
"""
,"2")
t_render("""
def test(x): return x
y = test(1)*2 + test(3)*4 + test(5)*6
print(y)
"""
,"44")
t_render("""
def test(a,b): return a+b
print(test(1,1)+test(1,1))
"""
,"4")
t_render("""
def test(): print("OK")
x = test
x()
"""
,"OK")
t_render("""
x = [2,4,6]
print(x[1])
"""
,"4")
t_render("""
def test(): print("OK")
x = [1,test,2]
x[1]()
"""
,"OK")
t_render("""
z = 0
for x in [1,2,3]:
z += x
print(z)
"""
,"6")
t_render("""
z = 0
for x in range(1,4):
z += x
print(z)
"""
,"6")
t_render("""
x = {'a':'OK'}
print(x.a)
"""
,"OK")
t_render("""print("1234"[1:3])""","23")
t_render("""print("1234"[-3:3])""","23")
t_render("""print([1,2,"OK",4][-3:3][1])""","OK")
t_render("""
n = 0
for x in range(0,10,2):
n += 1
print(n)
"""
,"5")
t_render("""print(max(3,8,2,6))""","8")
t_render("""print(min(3,4,2,6))""","2")
t_render("""for k in {'OK':0}: print(k)""","OK")
t_render("""
X = "OK"
def test(): print(X)
test()
"""
,"OK")
t_render("""
a = 4
def test(z):
for i in range(0,a):
z += i
return z
print(test(1))
"""
,"7")
t_render("""
def test(self): print(self)
fnc = bind(test,"OK")
fnc()
"""
,"OK")
t_render("""
class C:
def __init__(self,data): self.data = data
def print(self): print(self.data)
C("OK").print()
"""
,"OK")
t_render("""
x = [v*v for v in range(0,5)]
print(x[3])
"""
,"9")
t_render("""
t = [[y*10+x for x in range(0,10)] for y in range(0,10)]
print(t[2][3])
"""
,"23")
t_render("""
x = [1]
x.extend([2,3])
print(x[1])
"""
,"2")
#t_render("""
#x = {'a':3}
#merge(x,{'b':4})
#print(x.b)
#"""
#,"4")
t_render("""
x = [1,2,3]
y = copy(x)
y[0] *= 10
print(x[0]+y[0])
"""
,"11")
t_render("""
x = {'a':3}
y = copy(x)
y.a *= 10
print(x.a+y.a)
"""
,"33")
t_render("""
x = {}
y = x['x']
"""
,'KeyError',0)
t_render("""
x = []
y = x[1]
"""
,'KeyError',0)
t_render("""print("O"+"K")""","OK")
t_render("""print("-".join(["O","K"]))""","O-K")
t_render("""print("OK-OK".split("-")[1])""","OK")
t_render("""
def test(*v): return max(v[2])
print(test(*[1,2,"OK"]))
"""
,"OK")
t_render("""
def test(**v): return v['x']
print(test(**{'x':'OK'}))
"""
,"OK")
#t_render("""
#def test(y='K',x='Z'): print(x+y)
#test(x='O')
#"""
#,"OK")
t_render("""
def test(y='K',x='Z'): print(x+y)
test('O')
"""
,"ZO")
#t_render("""
#def test(a,b=2,*c,**d): return a+b+c[0]+d['x']+d['z']
#print(test(10,3,z=50000,*[200],**{'x':4000}))
#"""
#,"54213")
t_render("""print("".join(["O"]+["K"]))""","OK")
t_render("""x="OK";print(x)""","OK")
t_render("""x = [1,2,] ; print(x[1])""","2")
t_render("""a,b,d = [0],0,'OK'; print(d)""","OK")
t_render("""
def test(): raise
try:
test()
except:
print("OK")
""","OK")
t_render("""print("OKx"[:-1])""","OK")
t_render("""print("xOK"[1:])""","OK")
t_render("""a,b = "OK"; print(a+b)""","OK")
t_render("""
def test(a,b):
print a+b[2]
test(1,3)
""","Exception",False)
t_render("""
def test(): raise
test()
""","Exception",False)
t_render(['OK="OK"',"import tmp1\nprint(tmp1.OK)"],"OK")
t_render(['O="O"','K="K"',"import tmp1, tmp2\nprint(tmp1.O+tmp2.K)"],"OK")
t_render("""
def test(): return
x = 1
print(test())
""","None")
t_render("""
def test(): pass
x = 1
print(test())
""","None")
t_render("""
def test():
global x
x = "OK"
test()
print(x)
""","OK")
t_render("""
class X:
pass
y = X()
print("OK")
""","OK")
t_render("""
class X: pass
def test(): y = X()
test()
print("OK")
""","OK")
t_render(["class X: pass\ndef test(): y = X()","import tmp1\ntmp1.test();print('OK')"],"OK")
t_render("print(len([1,2,3]))","3")
t_render('if not "?" in "xyz": print("OK")',"OK")
t_render('print({1:"OK"}[1])',"OK")
t_render('print(len("\0"))',"1")
t_render('print(1 in {1:2})',"1")
t_render('x = {1:2}; del x[1]; print(len(x))','0')
t_render("""
def test(t):
t = "O"+t
print(t)
test("K")
""","OK")
t_render("""print([1,2,3].index(3))""","2")
t_render("""print("1,2,3".split(",").index("3"))""","2")
t_render("""v = [3,2,1]; v.sort(); print(v[0])""","1")
t_render("""print(abs(-5))""","5")
t_render("""print(int(1.234))""","1")
t_render("print(int(round(1.5)))","2")
t_render("print(ord('X'))","88")
t_render("print(ord(chr(128)))","128")
#t_render("print(fsize('LICENSE.txt'))","181")
t_render("print(int('ff',16))","255")
t_render("""
def test(x,y): print(x); return y
test('a',1) or test('b',1) and test('c',0)
""","a")
t_render("def test(): print('OK')\n{'__call__':test}()","OK")
t_render("""
class A:
def __init__(self):
self.a = 'O'
self.b = 'x'
def test(self):
print("KO")
class B(A):
def __init__(self):
A.__init__(self)
self.b = 'K'
def test(self):
print(self.a+self.b)
B().test()
""","OK")
t_render("""
class A:
def test(self):
print(self)
A.test("OK")
""","OK")
t_render("""
def test():
def fnc():
print("OK")
fnc()
test()
""","OK")
t_render("""print("aa..bbb...ccc".replace("..","X"))""","aaXbbbX.ccc")
t_render("""print("..bbb..".replace("..","X"))""","XbbbX")
t_render("""print("234".replace("\r\n","\n"))""","234")
t_render("""print("a\0b".replace("\0","X"))""","aXb")
t_render("""x = "a\0b"; x = x.replace("\0","c"); print(x)""","acb")
t_render("""print(0xff)""","255")
t_render("""x=(1,3);print({x:'OK'}[x])""","OK")
t_render("""x=(1,3);y=(1,3);print({x:'OK'}[y])""","OK")
t_render("""print({(1,3):'OK'}[(1,3)])""","OK")
t_render("def test(): test()\ntest()","Exception",0)
t_render("x = []; x.append(x); print(x<x)","0");
t_render("x = []; x.append(x); print({x:'OK'}[x])","OK")
#t_render("print(float(str(4294967296))==float('4294967296'))","1")
t_render("print(2**3)","8")
#t_render("x = 'OK',\nprint(x[0])","OK")
test_range()
t_render(['v="OK"',"from tmp1 import *\nprint(v)"],"OK")
t_render(['v="OK"',"from tmp1 import v\nprint(v)"],"OK")
t_render(['x="X";y="K"',"x = 'O'\nfrom tmp1 import y\nprint(x+y)"],"OK")
t_render("""
def test(**e):
print(e['x'])
test(x='OK')
""","OK")
# test register allocator
s = "def f():pass\n"+("f()\n"*256)+"print('OK')"
t_render(s,"OK")
t_render("print(2**3)","8")
t_render("print(2*3**2)", "18", False)
t_render("""
def test(**v): return 'OK'
print(test())
"""
,"OK")
t_render("""
def test(**v):
v['x'] = 'OK'
return v
print(test()['x'])
"""
,"OK")
################################################################################
def t_boot(ss,ex,exact=True):
if not istype(ss,'list'): ss =[ss]
n = 1
for s in ss:
fname = 'tmp'+str(n)+'.tpc'
system_rm(fname)
fname = 'tmp'+str(n)+'.py'
save(fname,s)
n += 1
system_rm('tmp.txt')
system(TINYPY+fname+' > tmp.txt')
res = load(TMP).strip()
#print(ss,ex,res)
if exact: assert(res == ex)
else: assert(ex in res)
is_boot = False
try:
assert(is_tinypy == True)
x = compile('x=3','')
is_boot = True
except:
pass
if is_boot == True and __name__ == '__main__':
print("# t_boot")
t_boot(["def test(): print('OK')","import tmp1; tmp1.test()"],"OK")

View File

@@ -0,0 +1,171 @@
class Token:
def __init__(self,pos=(0,0),type='symbol',val=None,items=None):
self.pos,self.type,self.val,self.items=pos,type,val,items
def u_error(ctx,s,i):
y,x = i
line = s.split('\n')[y-1]
p = ''
if y < 10: p += ' '
if y < 100: p += ' '
r = p + str(y) + ": " + line + "\n"
r += " "+" "*x+"^" +'\n'
raise 'error: '+ctx+'\n'+r
ISYMBOLS = '`-=[];,./~!@$%^&*()+{}:<>?'
SYMBOLS = [
'def','class','yield','return','pass','and','or','not','in','import',
'is','while','break','for','continue','if','else','elif','try',
'except','raise','True','False','None','global','del','from',
'-','+','*','**','/','%','<<','>>',
'-=','+=','*=','/=','=','==','!=','<','>',
'<=','>=','[',']','{','}','(',')','.',':',',',';','&','|','!',
]
B_BEGIN,B_END = ['[','(','{'],[']',')','}']
class TData:
def __init__(self):
self.y,self.yi,self.nl = 1,0,True
self.res,self.indent,self.braces = [],[0],0
def add(self,t,v): self.res.append(Token(self.f,t,v))
def clean(s):
s = s.replace('\r\n','\n')
s = s.replace('\r','\n')
return s
def tokenize(s):
s = clean(s)
try: return do_tokenize(s)
except: u_error('tokenize',s,T.f)
def do_tokenize(s):
global T
T,i,l = TData(),0,len(s)
T.f = (T.y,i-T.yi+1)
while i < l:
c = s[i]; T.f = (T.y,i-T.yi+1)
if T.nl: T.nl = False; i = do_indent(s,i,l)
elif c == '\n': i = do_nl(s,i,l)
elif c in ISYMBOLS: i = do_symbol(s,i,l)
elif c >= '0' and c <= '9': i = do_number(s,i,l)
elif (c >= 'a' and c <= 'z') or \
(c >= 'A' and c <= 'Z') or c == '_': i = do_name(s,i,l)
elif c=='"' or c=="'": i = do_string(s,i,l)
elif c=='#': i = do_comment(s,i,l)
elif c == '\\' and s[i+1] == '\n':
i += 2; T.y,T.yi = T.y+1,i
elif c == ' ' or c == '\t': i += 1
else: u_error('tokenize',s,T.f)
indent(0)
r = T.res; T = None
return r
def do_nl(s,i,l):
if not T.braces:
T.add('nl',None)
i,T.nl = i+1,True
T.y,T.yi = T.y+1,i
return i
def do_indent(s,i,l):
v = 0
while i<l:
c = s[i]
if c != ' ' and c != '\t': break
i,v = i+1,v+1
if c != '\n' and c != '#' and not T.braces: indent(v)
return i
def indent(v):
if v == T.indent[-1]: pass
elif v > T.indent[-1]:
T.indent.append(v)
T.add('indent',v)
elif v < T.indent[-1]:
n = T.indent.index(v)
while len(T.indent) > n+1:
v = T.indent.pop()
T.add('dedent',v)
def do_symbol(s,i,l):
symbols = []
v,f,i = s[i],i,i+1
if v in SYMBOLS: symbols.append(v)
while i<l:
c = s[i]
if not c in ISYMBOLS: break
v,i = v+c,i+1
if v in SYMBOLS: symbols.append(v)
v = symbols.pop(); n = len(v); i = f+n
T.add('symbol',v)
if v in B_BEGIN: T.braces += 1
if v in B_END: T.braces -= 1
return i
def do_number(s,i,l):
v,i,c =s[i],i+1,s[i]
while i<l:
c = s[i]
if (c < '0' or c > '9') and (c < 'a' or c > 'f') and c != 'x': break
v,i = v+c,i+1
if c == '.':
v,i = v+c,i+1
while i<l:
c = s[i]
if c < '0' or c > '9': break
v,i = v+c,i+1
T.add('number',v)
return i
def do_name(s,i,l):
v,i =s[i],i+1
while i<l:
c = s[i]
if (c < 'a' or c > 'z') and (c < 'A' or c > 'Z') and (c < '0' or c > '9') and c != '_': break
v,i = v+c,i+1
if v in SYMBOLS: T.add('symbol',v)
else: T.add('name',v)
return i
def do_string(s,i,l):
v,q,i = '',s[i],i+1
if (l-i) >= 5 and s[i] == q and s[i+1] == q: # """
i += 2
while i<l-2:
c = s[i]
if c == q and s[i+1] == q and s[i+2] == q:
i += 3
T.add('string',v)
break
else:
v,i = v+c,i+1
if c == '\n': T.y,T.yi = T.y+1,i
else:
while i<l:
c = s[i]
if c == "\\":
i = i+1; c = s[i]
if c == "n": c = '\n'
if c == "r": c = chr(13)
if c == "t": c = "\t"
if c == "0": c = "\0"
v,i = v+c,i+1
elif c == q:
i += 1
T.add('string',v)
break
else:
v,i = v+c,i+1
return i
def do_comment(s,i,l):
i += 1
while i<l:
c = s[i]
if c == '\n': break
i += 1
return i

View File

@@ -0,0 +1,32 @@
#ifndef TP_COMPILER
#define TP_COMPILER 1
#endif
#include "tp.h"
#include "list.c"
#include "koconsole.c"
#include "dict.c"
#include "misc.c"
#include "string.c"
#include "builtins.c"
#include "gc.c"
#include "ops.c"
void tp_compiler(TP);
#include "vm.c"
tp_obj tp_None = {TP_NONE};
#if TP_COMPILER
#include "bc.c"
void tp_compiler(TP) {
tp_import(tp,0,"tokenize",tp_tokenize);
tp_import(tp,0,"parse",tp_parse);
tp_import(tp,0,"encode",tp_encode);
tp_import(tp,0,"py2bc",tp_py2bc);
tp_call(tp,"py2bc","_init",tp_None);
}
#else
void tp_compiler(TP) { }
#endif
/**/

View File

@@ -0,0 +1,233 @@
#ifndef TP_H
#define TP_H
#include <setjmp.h>
#include <sys/stat.h>
#ifndef __USE_ISOC99
#define __USE_ISOC99
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <math.h>
#ifdef __GNUC__
#define tp_inline __inline__
#endif
#ifdef _MSC_VER
#define tp_inline __inline
#endif
#ifndef tp_inline
#error "Unsuported compiler"
#endif
#define tp_malloc(x) calloc((x),1)
#define tp_realloc(x,y) realloc(x,y)
#define tp_free(x) free(x)
/* #include <gc/gc.h>
#define tp_malloc(x) GC_MALLOC(x)
#define tp_realloc(x,y) GC_REALLOC(x,y)
#define tp_free(x)*/
enum {
TP_NONE,TP_NUMBER,TP_STRING,TP_DICT,
TP_LIST,TP_FNC,TP_DATA,
};
typedef double tp_num;
typedef struct tp_number_ {
int type;
tp_num val;
} tp_number_;
typedef struct tp_string_ {
int type;
struct _tp_string *info;
char const *val;
int len;
} tp_string_;
typedef struct tp_list_ {
int type;
struct _tp_list *val;
} tp_list_;
typedef struct tp_dict_ {
int type;
struct _tp_dict *val;
} tp_dict_;
typedef struct tp_fnc_ {
int type;
struct _tp_fnc *info;
int ftype;
void *val;
} tp_fnc_;
typedef struct tp_data_ {
int type;
struct _tp_data *info;
void *val;
int magic;
} tp_data_;
typedef union tp_obj {
int type;
tp_number_ number;
struct { int type; int *data; } gci;
tp_string_ string;
tp_dict_ dict;
tp_list_ list;
tp_fnc_ fnc;
tp_data_ data;
} tp_obj;
typedef struct _tp_string {
int gci;
char s[1];
} _tp_string;
typedef struct _tp_list {
int gci;
tp_obj *items;
int len;
int alloc;
} _tp_list;
typedef struct tp_item {
int used;
int hash;
tp_obj key;
tp_obj val;
} tp_item;
typedef struct _tp_dict {
int gci;
tp_item *items;
int len;
int alloc;
int cur;
int mask;
int used;
} _tp_dict;
typedef struct _tp_fnc {
int gci;
tp_obj self;
tp_obj globals;
} _tp_fnc;
typedef union tp_code {
unsigned char i;
struct { unsigned char i,a,b,c; } regs;
struct { char val[4]; } string;
struct { float val; } number;
} tp_code;
typedef struct tp_frame_ {
tp_code *codes;
tp_code *cur;
tp_code *jmp;
tp_obj *regs;
tp_obj *ret_dest;
tp_obj fname;
tp_obj name;
tp_obj line;
tp_obj globals;
int lineno;
int cregs;
} tp_frame_;
#define TP_GCMAX 4096
#define TP_FRAMES 256
/* #define TP_REGS_PER_FRAME 256*/
#define TP_REGS 16384
typedef struct tp_vm {
tp_obj builtins;
tp_obj modules;
tp_frame_ frames[TP_FRAMES];
tp_obj _params;
tp_obj params;
tp_obj _regs;
tp_obj *regs;
tp_obj root;
jmp_buf buf;
int jmp;
tp_obj ex;
char chars[256][2];
int cur;
/* gc*/
_tp_list *white;
_tp_list *grey;
_tp_list *black;
_tp_dict *strings;
int steps;
} tp_vm;
#define TP tp_vm *tp
typedef struct _tp_data {
int gci;
void (*free)(TP,tp_obj);
} _tp_data;
/* NOTE: these are the few out of namespace items for convenience*/
#define tp_True tp_number(1)
#define tp_False tp_number(0)
#define TP_CSTR(v) ((tp_str(tp,(v))).string.val)
extern tp_obj tp_None;
void tp_set(TP,tp_obj,tp_obj,tp_obj);
tp_obj tp_get(TP,tp_obj,tp_obj);
tp_obj tp_len(TP,tp_obj);
tp_obj tp_str(TP,tp_obj);
int tp_cmp(TP,tp_obj,tp_obj);
void _tp_raise(TP,tp_obj);
tp_obj tp_printf(TP,char const *fmt,...);
tp_obj tp_track(TP,tp_obj);
void tp_grey(TP,tp_obj);
/* __func__ __VA_ARGS__ __FILE__ __LINE__ */
#define tp_raise(r,fmt,...) { \
_tp_raise(tp,tp_printf(tp,fmt,__VA_ARGS__)); \
return r; \
}
#define TP_OBJ() (tp_get(tp,tp->params,tp_None))
tp_inline static tp_obj tp_type(TP,int t,tp_obj v) {
if (v.type != t) { tp_raise(tp_None,"_tp_type(%d,%s)",t,TP_CSTR(v)); }
return v;
}
#define TP_TYPE(t) tp_type(tp,t,TP_OBJ())
#define TP_NUM() (TP_TYPE(TP_NUMBER).number.val)
#define TP_STR() (TP_CSTR(TP_TYPE(TP_STRING)))
#define TP_DEFAULT(d) (tp->params.list.val->len?tp_get(tp,tp->params,tp_None):(d))
#define TP_LOOP(e) \
int __l = tp->params.list.val->len; \
int __i; for (__i=0; __i<__l; __i++) { \
(e) = _tp_list_get(tp,tp->params.list.val,__i,"TP_LOOP");
#define TP_END \
}
tp_inline static int _tp_min(int a, int b) { return (a<b?a:b); }
tp_inline static int _tp_max(int a, int b) { return (a>b?a:b); }
tp_inline static int _tp_sign(tp_num v) { return (v<0?-1:(v>0?1:0)); }
tp_inline static tp_obj tp_number(tp_num v) {
tp_obj val = {TP_NUMBER};
val.number.val = v;
return val;
}
tp_inline static tp_obj tp_string(char const *v) {
tp_obj val;
tp_string_ s = {TP_STRING, 0, v, 0};
s.len = strlen(v);
val.string = s;
return val;
}
tp_inline static tp_obj tp_string_n(char const *v,int n) {
tp_obj val;
tp_string_ s = {TP_STRING, 0,v,n};
val.string = s;
return val;
}
#endif

View File

@@ -0,0 +1,24 @@
#include "tp.c"
/* INCLUDE */
const char header[]="TinyPy for kolibriOS";
const int argc = 2;
extern _stdcall void testmod_init(tp_vm *tp);
void main(void) {
char *argv[2]={"tpmain", "test.py"};
CONSOLE_INIT(header);
con_printf("TinyPy console, version 1.1.\n");
con_printf("Enter program file:");
if (!(argv[1] = malloc(256)))
con_printf("Memory error\n");
con_gets(argv[1], 256);
argv[1][strlen(argv[1]) - 1] = '\0';
con_printf("Running file %s\n", argv[1]);
tp_vm *tp = tp_init(argc, argv);
/* INIT */
tp_call(tp,"py2bc","tinypy",tp_None);
tp_deinit(tp);
return;
}
/**/

View File

@@ -0,0 +1,380 @@
tp_vm *_tp_init(void) {
int i;
tp_vm *tp = (tp_vm*)tp_malloc(sizeof(tp_vm));
tp->cur = 0;
tp->jmp = 0;
tp->ex = tp_None;
tp->root = tp_list(0);
for (i=0; i<256; i++) { tp->chars[i][0]=i; }
tp_gc_init(tp);
tp->_regs = tp_list(tp);
for (i=0; i<TP_REGS; i++) { tp_set(tp,tp->_regs,tp_None,tp_None); }
tp->builtins = tp_dict(tp);
tp->modules = tp_dict(tp);
tp->_params = tp_list(tp);
for (i=0; i<TP_FRAMES; i++) { tp_set(tp,tp->_params,tp_None,tp_list(tp)); }
tp_set(tp,tp->root,tp_None,tp->builtins);
tp_set(tp,tp->root,tp_None,tp->modules);
tp_set(tp,tp->root,tp_None,tp->_regs);
tp_set(tp,tp->root,tp_None,tp->_params);
tp_set(tp,tp->builtins,tp_string("MODULES"),tp->modules);
tp_set(tp,tp->modules,tp_string("BUILTINS"),tp->builtins);
tp_set(tp,tp->builtins,tp_string("BUILTINS"),tp->builtins);
tp->regs = tp->_regs.list.val->items;
tp_full(tp);
return tp;
}
void tp_deinit(TP) {
while (tp->root.list.val->len) {
_tp_list_pop(tp,tp->root.list.val,0,"tp_deinit");
}
tp_full(tp); tp_full(tp);
tp_delete(tp,tp->root);
tp_gc_deinit(tp);
tp_free(tp);
}
/* tp_frame_*/
void tp_frame(TP,tp_obj globals,tp_code *codes,tp_obj *ret_dest) {
tp_frame_ f;
f.globals = globals;
f.codes = codes;
f.cur = f.codes;
f.jmp = 0;
/* fprintf(stderr,"tp->cur: %d\n",tp->cur);*/
f.regs = (tp->cur <= 0?tp->regs:tp->frames[tp->cur].regs+tp->frames[tp->cur].cregs);
f.ret_dest = ret_dest;
f.lineno = 0;
f.line = tp_string("");
f.name = tp_string("?");
f.fname = tp_string("?");
f.cregs = 0;
/* return f;*/
if (f.regs+256 >= tp->regs+TP_REGS || tp->cur >= TP_FRAMES-1) { tp_raise(,"tp_frame: stack overflow %d",tp->cur); }
tp->cur += 1;
tp->frames[tp->cur] = f;
}
void _tp_raise(TP,tp_obj e) {
if (!tp || !tp->jmp) {
con_printf("\nException:\n%s\n",TP_CSTR(e));
exit(-1);
return;
}
if (e.type != TP_NONE) { tp->ex = e; }
tp_grey(tp,e);
longjmp(tp->buf,1);
}
void tp_print_stack(TP) {
int i;
con_printf("\n");
for (i=0; i<=tp->cur; i++) {
if (!tp->frames[i].lineno) { continue; }
con_printf("File \"%s\", line %d, in %s\n %s\n",
TP_CSTR(tp->frames[i].fname),tp->frames[i].lineno,
TP_CSTR(tp->frames[i].name),TP_CSTR(tp->frames[i].line));
}
con_printf("\nException:\n%s\n",TP_CSTR(tp->ex));
}
void tp_handle(TP) {
int i;
for (i=tp->cur; i>=0; i--) {
if (tp->frames[i].jmp) { break; }
}
if (i >= 0) {
tp->cur = i;
tp->frames[i].cur = tp->frames[i].jmp;
tp->frames[i].jmp = 0;
return;
}
tp_print_stack(tp);
exit(-1);
}
void _tp_call(TP,tp_obj *dest, tp_obj fnc, tp_obj params) {
/*con_printf("_tp_call %s %s\n",TP_CSTR(fnc), TP_CSTR(params));*/
if (fnc.type == TP_DICT) {
_tp_call(tp,dest,tp_get(tp,fnc,tp_string("__call__")),params);
return;
}
if (fnc.type == TP_FNC && !(fnc.fnc.ftype&1)) {
*dest = _tp_tcall(tp,fnc);
tp_grey(tp,*dest);
return;
}
if (fnc.type == TP_FNC) {
tp_frame(tp,fnc.fnc.info->globals,(tp_code*)fnc.fnc.val,dest);
if ((fnc.fnc.ftype&2)) {
tp->frames[tp->cur].regs[0] = params;
_tp_list_insert(tp,params.list.val,0,fnc.fnc.info->self);
} else {
tp->frames[tp->cur].regs[0] = params;
}
return;
}
tp_params_v(tp,1,fnc); tp_print(tp);
tp_raise(,"tp_call: %s is not callable",TP_CSTR(fnc));
}
void tp_return(TP, tp_obj v) {
tp_obj *dest = tp->frames[tp->cur].ret_dest;
if (dest) { *dest = v; tp_grey(tp,v); }
/* memset(tp->frames[tp->cur].regs,0,TP_REGS_PER_FRAME*sizeof(tp_obj));
fprintf(stderr,"regs:%d\n",(tp->frames[tp->cur].cregs+1));*/
memset(tp->frames[tp->cur].regs,0,tp->frames[tp->cur].cregs*sizeof(tp_obj));
tp->cur -= 1;
}
enum {
TP_IEOF,TP_IADD,TP_ISUB,TP_IMUL,TP_IDIV,TP_IPOW,TP_IAND,TP_IOR,TP_ICMP,TP_IGET,TP_ISET,
TP_INUMBER,TP_ISTRING,TP_IGGET,TP_IGSET,TP_IMOVE,TP_IDEF,TP_IPASS,TP_IJUMP,TP_ICALL,
TP_IRETURN,TP_IIF,TP_IDEBUG,TP_IEQ,TP_ILE,TP_ILT,TP_IDICT,TP_ILIST,TP_INONE,TP_ILEN,
TP_ILINE,TP_IPARAMS,TP_IIGET,TP_IFILE,TP_INAME,TP_INE,TP_IHAS,TP_IRAISE,TP_ISETJMP,
TP_IMOD,TP_ILSH,TP_IRSH,TP_IITER,TP_IDEL,TP_IREGS,
TP_ITOTAL
};
/* char *tp_strings[TP_ITOTAL] = {
"EOF","ADD","SUB","MUL","DIV","POW","AND","OR","CMP","GET","SET","NUM",
"STR","GGET","GSET","MOVE","DEF","PASS","JUMP","CALL","RETURN","IF","DEBUG",
"EQ","LE","LT","DICT","LIST","NONE","LEN","LINE","PARAMS","IGET","FILE",
"NAME","NE","HAS","RAISE","SETJMP","MOD","LSH","RSH","ITER","DEL","REGS",
};*/
#define VA ((int)e.regs.a)
#define VB ((int)e.regs.b)
#define VC ((int)e.regs.c)
#define RA regs[e.regs.a]
#define RB regs[e.regs.b]
#define RC regs[e.regs.c]
#define UVBC (unsigned short)(((VB<<8)+VC))
#define SVBC (short)(((VB<<8)+VC))
#define GA tp_grey(tp,RA)
#define SR(v) f->cur = cur; return(v);
int tp_step(TP) {
tp_frame_ *f = &tp->frames[tp->cur];
tp_obj *regs = f->regs;
tp_code *cur = f->cur;
while(1) {
tp_code e = *cur;
/* fprintf(stderr,"%2d.%4d: %-6s %3d %3d %3d\n",tp->cur,cur-f->codes,tp_strings[e.i],VA,VB,VC);
int i; for(i=0;i<16;i++) { fprintf(stderr,"%d: %s\n",i,TP_CSTR(regs[i])); }*/
switch (e.i) {
case TP_IEOF: tp_return(tp,tp_None); SR(0); break;
case TP_IADD: RA = tp_add(tp,RB,RC); break;
case TP_ISUB: RA = tp_sub(tp,RB,RC); break;
case TP_IMUL: RA = tp_mul(tp,RB,RC); break;
case TP_IDIV: RA = tp_div(tp,RB,RC); break;
case TP_IPOW: RA = tp_pow(tp,RB,RC); break;
case TP_IAND: RA = tp_and(tp,RB,RC); break;
case TP_IOR: RA = tp_or(tp,RB,RC); break;
case TP_IMOD: RA = tp_mod(tp,RB,RC); break;
case TP_ILSH: RA = tp_lsh(tp,RB,RC); break;
case TP_IRSH: RA = tp_rsh(tp,RB,RC); break;
case TP_ICMP: RA = tp_number(tp_cmp(tp,RB,RC)); break;
case TP_INE: RA = tp_number(tp_cmp(tp,RB,RC)!=0); break;
case TP_IEQ: RA = tp_number(tp_cmp(tp,RB,RC)==0); break;
case TP_ILE: RA = tp_number(tp_cmp(tp,RB,RC)<=0); break;
case TP_ILT: RA = tp_number(tp_cmp(tp,RB,RC)<0); break;
case TP_IPASS: break;
case TP_IIF: if (tp_bool(tp,RA)) { cur += 1; } break;
case TP_IGET: RA = tp_get(tp,RB,RC); GA; break;
case TP_IITER:
if (RC.number.val < tp_len(tp,RB).number.val) {
RA = tp_iter(tp,RB,RC); GA;
RC.number.val += 1;
cur += 1;
}
break;
case TP_IHAS: RA = tp_has(tp,RB,RC); break;
case TP_IIGET: tp_iget(tp,&RA,RB,RC); break;
case TP_ISET: tp_set(tp,RA,RB,RC); break;
case TP_IDEL: tp_del(tp,RA,RB); break;
case TP_IMOVE: RA = RB; break;
case TP_INUMBER:
RA = tp_number(*(tp_num*)(*++cur).string.val);
cur += sizeof(tp_num)/4;
continue;
case TP_ISTRING:
RA = tp_string_n((*(cur+1)).string.val,UVBC);
cur += (UVBC/4)+1;
break;
case TP_IDICT: RA = tp_dict_n(tp,VC/2,&RB); break;
case TP_ILIST: RA = tp_list_n(tp,VC,&RB); break;
case TP_IPARAMS: RA = tp_params_n(tp,VC,&RB); break;
case TP_ILEN: RA = tp_len(tp,RB); break;
case TP_IJUMP: cur += SVBC; continue; break;
case TP_ISETJMP: f->jmp = cur+SVBC; break;
case TP_ICALL: _tp_call(tp,&RA,RB,RC); cur++; SR(0); break;
case TP_IGGET:
if (!tp_iget(tp,&RA,f->globals,RB)) {
RA = tp_get(tp,tp->builtins,RB); GA;
}
break;
case TP_IGSET: tp_set(tp,f->globals,RA,RB); break;
case TP_IDEF:
RA = tp_def(tp,(*(cur+1)).string.val,f->globals);
cur += SVBC; continue;
break;
case TP_IRETURN: tp_return(tp,RA); SR(0); break;
case TP_IRAISE: _tp_raise(tp,RA); SR(0); break;
case TP_IDEBUG:
tp_params_v(tp,3,tp_string("DEBUG:"),tp_number(VA),RA); tp_print(tp);
break;
case TP_INONE: RA = tp_None; break;
case TP_ILINE:
f->line = tp_string_n((*(cur+1)).string.val,VA*4-1);
/* fprintf(stderr,"%7d: %s\n",UVBC,f->line.string.val);*/
cur += VA; f->lineno = UVBC;
break;
case TP_IFILE: f->fname = RA; break;
case TP_INAME: f->name = RA; break;
case TP_IREGS: f->cregs = VA; break;
default: tp_raise(0,"tp_step: invalid instruction %d",e.i); break;
}
cur += 1;
}
SR(0);
}
void tp_run(TP,int cur) {
if (tp->jmp) {
tp_raise(,"tp_run(%d) called recusively",cur);
}
tp->jmp = 1;
if (setjmp(tp->buf))
{
tp_handle(tp);
}
while (tp->cur >= cur && tp_step(tp) != -1);
tp->cur = cur-1;
tp->jmp = 0;
}
tp_obj tp_call(TP, const char *mod, const char *fnc, tp_obj params) {
tp_obj tmp;
tp_obj r = tp_None;
tmp = tp_get(tp,tp->modules,tp_string(mod));
tmp = tp_get(tp,tmp,tp_string(fnc));
_tp_call(tp,&r,tmp,params);
tp_run(tp,tp->cur);
return r;
}
tp_obj tp_import(TP, char const *fname, char const *name, void *codes) {
tp_obj code = tp_None;
tp_obj g;
if (!((fname && strstr(fname,".tpc")) || codes)) {
return tp_call(tp,"py2bc","import_fname",tp_params_v(tp,2,tp_string(fname),tp_string(name)));
}
if (!codes) {
tp_params_v(tp,1,tp_string(fname));
code = tp_load(tp);
/* We cast away the constness. */
codes = (void *)code.string.val;
} else {
code = tp_data(tp,0,codes);
}
g = tp_dict(tp);
tp_set(tp,g,tp_string("__name__"),tp_string(name));
tp_set(tp,g,tp_string("__code__"),code);
tp_set(tp,g,tp_string("__dict__"),g);
tp_frame(tp,g,(tp_code*)codes,0);
tp_set(tp,tp->modules,tp_string(name),g);
if (!tp->jmp) {
tp_run(tp,tp->cur);
}
return g;
}
tp_obj tp_exec_(TP) {
tp_obj code = TP_OBJ();
tp_obj globals = TP_OBJ();
tp_frame(tp,globals,(tp_code*)code.string.val,0);
return tp_None;
}
tp_obj tp_import_(TP) {
tp_obj mod = TP_OBJ();
char const *s;
tp_obj r;
if (tp_has(tp,tp->modules,mod).number.val) {
return tp_get(tp,tp->modules,mod);
}
s = TP_CSTR(mod);
r = tp_import(tp,TP_CSTR(tp_add(tp,mod,tp_string(".tpc"))),s,0);
return r;
}
void tp_builtins(TP) {
struct {const char *s;void *f;} b[] = {
{"print",tp_print}, {"range",tp_range}, {"min",tp_min},
{"max",tp_max}, {"bind",tp_bind}, {"copy",tp_copy},
{"import",tp_import_}, {"len",tp_len_}, {"assert",tp_assert},
{"str",tp_str2}, {"float",tp_float}, {"system",tp_system},
{"istype",tp_istype}, {"chr",tp_chr}, {"save",tp_save},
{"load",tp_load}, {"fpack",tp_fpack}, {"abs",tp_abs},
{"int",tp_int}, {"exec",tp_exec_}, {"exists",tp_exists},
{"mtime",tp_mtime}, {"number",tp_float}, {"round",tp_round},
{"ord",tp_ord}, {"merge",tp_merge}, {"syscall", tp_syscall}, {0,0},
};
int i; for(i=0; b[i].s; i++) {
tp_set(tp,tp->builtins,tp_string(b[i].s),tp_fnc(tp,(tp_obj (*)(tp_vm *))b[i].f));
}
}
void tp_args(TP,int argc, char *argv[]) {
tp_obj self = tp_list(tp);
int i;
for (i=1; i<argc; i++) { _tp_list_append(tp,self.list.val,tp_string(argv[i])); }
tp_set(tp,tp->builtins,tp_string("ARGV"),self);
}
tp_obj tp_main(TP,char *fname, void *code) {
return tp_import(tp,fname,"__main__",code);
}
tp_obj tp_compile(TP, tp_obj text, tp_obj fname) {
return tp_call(tp,"BUILTINS","compile",tp_params_v(tp,2,text,fname));
}
tp_obj tp_exec(TP,tp_obj code, tp_obj globals) {
tp_obj r=tp_None;
tp_frame(tp,globals,(tp_code*)code.string.val,&r);
tp_run(tp,tp->cur);
return r;
}
tp_obj tp_eval(TP, char *text, tp_obj globals) {
tp_obj code = tp_compile(tp,tp_string(text),tp_string("<eval>"));
return tp_exec(tp,code,globals);
}
tp_vm *tp_init(int argc, char *argv[]) {
tp_vm *tp = _tp_init();
tp_builtins(tp);
tp_args(tp,argc,argv);
tp_compiler(tp);
return tp;
}
/**/

View File

@@ -0,0 +1,9 @@
#define TP_COMPILER 0
#include "tp.c"
int main(int argc, char *argv[]) {
tp_vm *tp = tp_init(argc,argv);
tp_import(tp,argv[1],"__main__",0);
tp_deinit(tp);
return(0);
}