- Rebuilt TinyPy

- Non-working trash is cleaned.
- Updated from latest git version. 
- Fixed modules pygame math and others. 
- Removed old modules added new ones.
- All samples work except "net"

git-svn-id: svn://kolibrios.org@8535 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
superturbocat2001 2021-01-12 23:18:45 +00:00
parent 44a5c1b211
commit b29cc6670d
59 changed files with 11516 additions and 6128 deletions

View File

@ -1,35 +0,0 @@
== 1.1 =========================================================================
* applied patch by Dean Hall to fix several range() bugs
* applied patch by Krzysztof Kowalczyk to add VS 2005, 2008 compatibility.
* reorganized the source so that contributed modules can go into contrib
* reorganized the reorganization so that modules go into modules
since that seems less confusing somehow
* added a crude pygame module - to see it in action:
$ python setup.py linux pygame
$ ./build/tinypy examples/julia.py
* added support for
from x import *
from x import y
* trimmed off 1064 bytes by changing all the tokens from dicts to
a Token class in tokenize, parse, encode modules
* applied patch by Seth Lemons to support /* */ comment stripping in
setup.py and get tinypy up to -std=c89 spec
* cleaned up encode.py so that registers are no longer leaked
added assert after each frame to check that this is the case
* applied patch by KK to improve tinypy/tests.py feedback
* applied patch by allefant to finish namespacing tinypy
* applied patch by allefant to keep blob->tinypy.h from having warnings
* added math module from Rockins Chen
* fixed precedent of **
* removed unused tp_data meta methods
* made tp_data API "safer" by requiring the magic type
* improved setup.py to handle the clean argument
* renamed some internal fnc names for no good reason
* added boot option to setup.py so that full boostrapping
isn't always required
* applied const correctness patch from allefant
* fixed memory leak in list & dict copy functions
* improved kwargs support
* got it compiling with -Wc++-compat
* applied ord patch from allefant
* fixed mingw build

View File

@ -0,0 +1,119 @@
"""
a simple diversing asteroids simulation
"""
import sys
import math
import random
import pygame
if "tinypy" not in sys.version: # not tinypy
import pygame.locals
SCR_WIDTH = 600
SCR_HEIGHT = 600
NASTEROIDS = 320 # number of asteroids
INIT_NASTEROIDS = 80 # initial number of asteroids
OFFSET = 20 # max initial offset
DIV_FACTOR = 1.1 # diverse factor
class Center(object):
x = SCR_WIDTH / 2
y = SCR_HEIGHT / 2
class Graphics(object):
x = 0
y = 0
w = SCR_WIDTH
h = SCR_HEIGHT
center = Center()
BACKGROUND = (0, 0, 0) # black background
def __init__(self):
pygame.init()
self.screen = pygame.display.set_mode((SCR_WIDTH, SCR_HEIGHT))
self.clearScreen()
def drawRect(self, sx, sy, w, h, color):
sx = int(sx)
sy = int(sy)
dx = int(sx + w)
dy = int(sy + h)
for x in range(sx, dx):
for y in range(sy, dy):
self.screen.set_at((x, y), color)
def clearScreen(self):
for x in range(SCR_WIDTH):
for y in range(SCR_HEIGHT):
self.screen.set_at((x, y), self.BACKGROUND)
def flipDisplay(self):
pygame.display.flip()
class Asteroid(object):
graphics = Graphics()
def __init__(self):
self.x = 0 # x and y, set to invalid position
self.y = 0
self.size = 1
self.color = [0, 0, 0]
def show(self):
self.graphics.drawRect(self.x, self.y, self.size, self.size, self.color)
def hide(self):
self.graphics.drawRect(self.x, self.y, self.size, self.size, self.graphics.BACKGROUND)
def update(self):
# update asteroids[i]'s position
if (self.x <= self.graphics.x or self.x >= self.graphics.w or
self.y <= self.graphics.y or self.y >= self.graphics.h):
self.x = self.graphics.center.x - OFFSET + OFFSET * 2 * random.random()
self.y = self.graphics.center.y - OFFSET + OFFSET * 2 * random.random()
self.color[0] = random.randint(20, 255)
self.color[1] = random.randint(20, 255)
self.color[2] = random.randint(20, 255)
else:
gx = self.graphics.center.x + (self.x - self.graphics.center.x) * DIV_FACTOR
if (math.fabs(self.x - self.graphics.center.x) < 1e-6):
gy = self.graphics.center.y + (self.y - self.graphics.center.y) * DIV_FACTOR
else:
k = (gx - self.graphics.center.x) / (self.x - self.graphics.center.x)
gy = self.graphics.center.y + (self.y - self.graphics.center.y) * k
self.x = gx
self.y = gy
# update self's size
self.size = int(5 * ((math.fabs(self.x - self.graphics.center.x) * 2) / self.graphics.w))
if self.size <= 1:
self.size = 1
def main():
asteroids = []
for i in range(INIT_NASTEROIDS):
asteroid = Asteroid()
asteroid.update()
asteroids.append(asteroid)
_quit = False
while not _quit:
for e in pygame.event.get():
if e.type in (pygame.locals.QUIT, pygame.locals.KEYDOWN):
_quit = True
if (len(asteroids) < NASTEROIDS):
asteroid = Asteroid()
asteroid.update()
asteroids.append(asteroid)
for i in range(len(asteroids)):
# hide asteroids[i]
asteroids[i].hide()
# update asteroids[i]
asteroids[i].update()
# show asteroids[i]
asteroids[i].show()
# swap display content actually
Asteroid.graphics.flipDisplay()
if __name__ == '__main__':
main()
print("#OK")

View File

@ -1,6 +1,6 @@
# center: 10043 # center: 10043
import pygame import pygame, sys
if '.' in str(1.0): if not "tinypy" in sys.version:
import pygame.locals import pygame.locals
SW,SH = 120,120 SW,SH = 120,120

View File

@ -0,0 +1 @@
While sockets are disabled these examples don't work!

View File

@ -0,0 +1,13 @@
# Read/Write file example
# Copyright (C) 2019-2021 Logaev Maxim (turbocat2001), GPLv3
import ksys # KolibriOS syscalls
fw=ksys.open('my.txt','w') # Open file for writing
fw.write("I love KolibriOS") # Write symbols to my.txt file
fw.close() # Close file
fr=ksys.open('my.txt', 'r') # Open file for reading
str=fr.read() # Read symbols from file
print(str) # Print to console
fr.close() # Close file

View File

@ -0,0 +1,170 @@
#!/bin/env python
#
# vines borrowed from xscreensaver
#
"""
/*-
* Copyright (c) 1997 by Tracy Camp campt@hurrah.com
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose and without fee is hereby granted,
* provided that the above copyright notice appear in all copies and that
* both that copyright notice and this permission notice appear in
* supporting documentation.
*
* This file is provided AS IS with no warranties of any kind. The author
* shall have no liability with respect to the infringement of copyrights,
* trade secrets or any patents by this file or any part thereof. In no
* event will the author be liable for any lost revenue or profits or
* other special, indirect and consequential damages.
*
* If you make a modification I would of course appreciate a copy.
*
* Revision History:
* 01-Nov-2000: Allocation checks
* 11-Jul-1997: David Hansen <dhansen@metapath.com>
* Changed names to vines and modified draw loop
* to honor batchcount so vines can be grown or plotted.
* 10-May-1997: Compatible with xscreensaver
* 21-Mar-1997: David Hansen <dhansen@metapath.com>
* Updated mode to draw complete patterns on every
* iteration instead of growing the vine. Also made
* adjustments to randomization and changed variable
* names to make logic easier to follow.
*/
/*-
* This was modifed from a 'screen saver' that a friend and I
* wrote on our TI-8x calculators in high school physics one day
* Basically another geometric pattern generator, this ones claim
* to fame is a pseudo-fractal looking vine like pattern that creates
* nifty whorls and loops.
*/
"""
import sys
import math
import random
import pygame
if "tinypy" not in sys.version: # not tinypy
import pygame.locals
SCR_WIDTH = 800
SCR_HEIGHT = 600
class VineStruct(object):
a = 0
x1 = 0
y1 = 0
x2 = 0
y2 = 0
i = 0
length = 0
iterations = 0
constant = 0
ang = 0
centerx = 0
centery = 0
class Vines(object):
def __init__(self):
self.fp = VineStruct()
self.fp.i = 0
self.fp.length = 0
self.fp.iterations = 30 + random.randint(0, 100)
pygame.init()
self.screen = pygame.display.set_mode((SCR_WIDTH, SCR_HEIGHT))
def __drawLine__(self, x1, y1, x2, y2, color):
# validate the bounds
if x1 < 0: x1 = 0
if x1 > SCR_WIDTH: x1 = SCR_WIDTH
if x2 < 0: x2 = 0
if x2 > SCR_WIDTH: x2 = SCR_WIDTH
if y1 < 0: y1 = 0
if y1 > SCR_HEIGHT: y1 = SCR_HEIGHT
if y2 < 0: y2 = 0
if y2 > SCR_HEIGHT: y2 = SCR_HEIGHT
if x1 <= x2:
sx, sy = x1, y1
dx, dy = x2, y2
else:
sx, sy = x2, y2
dx, dy = x1, y1
if (abs(x1 - x2) < 1e-4):
x = sx
if sy > dy:
sy, dy = dy, sy
y = sy
while (y < dy):
self.screen.set_at((x, y), color)
y += 1
else:
k = (dy - sy) / (dx - sx)
x = sx
while (x < dx):
y = sy + k * (x - sx)
self.screen.set_at((x, y), color)
x += 1
pygame.display.flip()
def draw(self):
red = random.randint(0, 255)
green = random.randint(0, 255)
blue = random.randint(0, 255)
if (self.fp.i >= self.fp.length):
self.fp.iterations -= 1
if (self.fp.iterations == 0):
self.__init__(self)
self.fp.centerx = random.randint(0, SCR_WIDTH);
self.fp.centery = random.randint(0, SCR_HEIGHT);
self.fp.ang = 60 + random.randint(0, 720);
self.fp.length = 100 + random.randint(0, 3000);
self.fp.constant= self.fp.length * (10 + random.randint(0, 10))
self.fp.i = 0;
self.fp.a = 0;
self.fp.x1 = 0;
self.fp.y1 = 0;
self.fp.x2 = 1;
self.fp.y2 = 0;
count = self.fp.i + random.randint(10, 100)
if (count > self.fp.length):
count = self.fp.length
while (self.fp.i < count):
x1 = self.fp.centerx + (self.fp.x1 / self.fp.constant)
y1 = self.fp.centery - (self.fp.y1 / self.fp.constant)
x2 = self.fp.centerx + (self.fp.x2 / self.fp.constant)
y2 = self.fp.centery - (self.fp.y2 / self.fp.constant)
color = (red, green, blue)
self.__drawLine__(x1, y1, x2, y2, color)
self.fp.a += (self.fp.ang * self.fp.i)
self.fp.x1 = self.fp.x2
self.fp.y1 = self.fp.y2
self.fp.x2 += int((self.fp.i * (math.cos(self.fp.a) * 360.0)) / (2.0 * math.pi))
self.fp.y2 += int((self.fp.i * (math.sin(self.fp.a) * 360.0)) / (2.0 * math.pi))
self.fp.i += 1
def main():
myVine = Vines()
_quit = False
while not _quit:
for e in pygame.event.get():
if e.type in (pygame.locals.QUIT,pygame.locals.KEYDOWN):
_quit = True
myVine.draw()
if __name__ == '__main__':
main()
print("#OK")

View File

@ -0,0 +1,35 @@
# C-style window example
# Copyright (C) 2019-2021 Logaev Maxim (turbocat2001), GPLv3
import ksys # KolibriOS syscalls
import bitwise # Bitwise operations for large numbers
my_button = 2 # My button
exit_button = 1 # System exit button
number = 0 # Clicks count
colors = ksys.get_sys_colors() # Get system colors table
def Redraw():
ksys.start_draw()
ksys.create_window(10, 40, 400, 200, "My window", colors.work_area, 0x14)
ksys.draw_text("KolibriOS TinyPy example", 15, 34, 0, bitwise.add(0x90000000, colors.work_text))
ksys.create_button(150, 100 , 50, 100, my_button, colors.work_button)
ksys.draw_text("Click!", 155, 115, 0, bitwise.add(0x91000000, colors.work_button_text))
ksys.draw_text(str(number), 15,100, 0, bitwise.add(0x92000000, colors.work_text))
ksys.end_draw()
if __name__=="__main__":
ksys.debug_print("Start!\n") # Print "Start!" in debug board
while True:
event = ksys.get_event()
if event == 1: # Redraw event
Redraw()
if event == 3: # Buttons event
button = ksys.get_button() # Get clicked button number
if button == exit_button:
break;
if button == my_button:
number=number+1
Redraw()
print("Done!") # Print "Done!" in console

View File

@ -1,19 +0,0 @@
#include "tp.h"
void debug_write_byte(const char ch){
__asm__ __volatile__(
"int $0x40"
::"a"(63), "b"(1), "c"(ch)
);
}
tp_obj kolibri_debug_print(TP)
{
tp_obj str = TP_TYPE(TP_STRING);
for(int i=0; i < str.string.len; i++)
{
debug_write_byte(str.string.val[i]);
}
return tp_None;
}

View File

@ -1,163 +0,0 @@
#include "tp.h"
#include <kos32sys.h>
typedef unsigned short int uint16_t;
typedef unsigned int uint32_t;
extern void _tp_raise(TP,tp_obj);
extern tp_obj tp_dict(TP);
extern tp_obj tp_method(TP,tp_obj self,tp_obj v(TP));
extern tp_obj tp_number(tp_num v);
extern tp_obj tp_list(TP);
extern void _tp_list_append(TP,_tp_list *self, tp_obj v);
extern tp_obj tp_call(TP, const char *mod, const char *fnc, tp_obj params);
extern void _tp_call(TP,tp_obj *dest, tp_obj fnc, tp_obj params);
extern int tp_bool(TP,tp_obj v);
extern tp_obj tp_has(TP,tp_obj self, tp_obj k);
// #define _cdecl __attribute__((cdecl))
extern int (* _cdecl con_printf)(const char* format,...);
static tp_obj kolibri_show(TP)
{
tp_obj self = TP_TYPE(TP_DICT);
uint16_t xpos = (uint16_t)(tp_get(tp, self, tp_string("x")).number.val);
uint16_t ypos = (uint16_t)tp_get(tp, self, tp_string("y")).number.val;
uint16_t height = (uint16_t)tp_get(tp, self, tp_string("height")).number.val;
uint16_t width = (uint16_t)tp_get(tp, self, tp_string("width")).number.val;
uint16_t fixedsize = (uint16_t)tp_get(tp, self, tp_string("fixedsize")).number.val;
uint32_t bgcolor = (uint32_t)tp_get(tp, self, tp_string("bgcolor")).number.val;
uint32_t status;
uint32_t style;
uint32_t x = xpos * 0x10000 + width;
uint32_t y = ypos * 0x10000 + height;
if (fixedsize)
style = 0;
else
style = 0x33000000 + (bgcolor & 0xFFFFFF);
asm volatile ("int $0x40"::"a"(12), "b"(1));
asm volatile ("int $0x40"::
"a"(0), "b"(x), "c"(y), "d"(style),
"S"(0), "D"(0));
asm volatile ("int $0x40"::"a"(12), "b"(2));
/* If window has additional handler, run it. */
if (tp_bool(tp, tp_has(tp, self, tp_string("on_show"))))
{
tp_obj result;
tp_obj fnc = tp_get(tp, self, tp_string("on_show"));
tp_obj param_list = tp_list(tp); /* Prepare parameters. */
_tp_list_append(tp, param_list.list.val, self);
_tp_call(tp, &result, fnc, param_list);
}
return tp_None;
}
static void window_function(void)
{
uint32_t ev;
/* Wait for event. */
do {
asm volatile("int $0x40":"=a"(ev):"a"(10));
} while(ev != 3);
asm volatile("int $040"::"a"(-1));
}
static tp_obj kolibri_default_handler(TP)
{
return tp_None;
}
/* Run window_function() in separated thread. */
static tp_obj kolibri_run(TP)
{
tp_obj self = TP_TYPE(TP_DICT);
tp_obj redraw = tp_get(tp, self, tp_string("show"));
tp_obj result;
tp_obj key_handler = tp_None;
tp_obj button_handler = tp_None;
int button_id;
uint32_t ev;
int leave=0;
tp_obj param_list;
/* Obtain handlers. */
if (tp_bool(tp, tp_has(tp, self, tp_string("on_key"))))
key_handler = tp_get(tp, self, tp_string("on_key"));
if (tp_bool(tp, tp_has(tp, self, tp_string("on_button"))))
button_handler = tp_get(tp, self, tp_string("on_button"));
while(!leave){
asm volatile("int $0x40":"=a"(ev):"a"(10));
switch (ev)
{
case 1:
_tp_call(tp, &result, redraw, tp_None);
break;
case 2:
if (key_handler.type == TP_FNC)
{
param_list = tp_list(tp); /* Prepare parameters. */
_tp_list_append(tp, param_list.list.val, self);
oskey_t key;
key = get_key();
_tp_list_append(tp, param_list.list.val, tp_number(key.code));
_tp_call(tp, &result, key_handler, param_list);
}
break;
case 3:
button_id = get_os_button();
if (button_id == 1)
leave = 1;
else if (button_handler.type == TP_FNC)
{
param_list = tp_list(tp); /* Prepare parameters. */
_tp_list_append(tp, param_list.list.val, self);
_tp_list_append(tp, param_list.list.val, tp_number(button_id));
_tp_call(tp, &result, button_handler, param_list);
}
break;
default:
con_printf("Got unknown event %d\n", ev);
break;
}
};
return tp_None;
}
static tp_obj kolibri_print_text(TP)
{
tp_obj self = TP_TYPE(TP_DICT);
uint32_t textcolor = (uint32_t)tp_get(tp, self, tp_string("textcolor")).number.val;
uint16_t x = (uint16_t)tp_get(tp, self, tp_string("curx")).number.val;
uint16_t y = (uint16_t)tp_get(tp, self, tp_string("cury")).number.val;
uint32_t ofs;
uint32_t width = (uint32_t)tp_get(tp, self, tp_string("width")).number.val;
tp_obj text = TP_TYPE(TP_STRING);
draw_text_sys((char *)text.string.val, x, y, text.string.len, textcolor);
/* Update cursor position. */
ofs = 6 * text.string.len;
tp_set(tp, self, tp_string("cury"), tp_number(y + 9 * ((x + ofs) / width)));
tp_set(tp, self, tp_string("curx"), tp_number((x + ofs)%width));
return tp_None;
}
tp_obj kolibri_mainwindow(TP)
{
tp_obj obj = tp_dict(tp);
obj = tp_dict(tp);
tp_set(tp, obj, tp_string("x"), TP_TYPE(TP_NUMBER));
tp_set(tp, obj, tp_string("y"), TP_TYPE(TP_NUMBER));
tp_set(tp, obj, tp_string("height"), TP_TYPE(TP_NUMBER));
tp_set(tp, obj, tp_string("width"), TP_TYPE(TP_NUMBER));
tp_set(tp, obj, tp_string("curx"), tp_number(0));
tp_set(tp, obj, tp_string("cury"), tp_number(0));
tp_set(tp, obj, tp_string("fixedsize"), TP_TYPE(TP_NUMBER));
tp_set(tp, obj, tp_string("textcolor"), tp_number(0x202020));
tp_set(tp, obj, tp_string("bgcolor"), tp_number(0xFFFFFF));
tp_set(tp, obj, tp_string("show"), tp_method(tp, obj, kolibri_show));
tp_set(tp, obj, tp_string("run"), tp_method(tp, obj, kolibri_run));
/*tp_set(tp, obj, tp_string("keyhandler"), tp_method(tp, obj, kolibri_default_handler));
tp_set(tp, obj, tp_string("buttonhandler"), tp_method(tp, obj, kolibri_default_handler));*/
tp_set(tp, obj, tp_string("print_text"), tp_method(tp, obj, kolibri_print_text));
return obj;
}

View File

@ -1,29 +0,0 @@
#include "tp.h"
extern tp_obj kolibri_open(TP);
extern tp_obj kolibri_mainwindow(TP);
extern tp_obj kolibri_debug_print(TP);
extern tp_obj kolibri_socket_module(TP);
extern tp_obj tp_dict(TP);
extern tp_obj tp_fnc(TP,tp_obj v(TP));
void kolibri_init(TP)
{
tp_obj kolibri_mod = tp_dict(tp);
tp_obj socket_mod = kolibri_socket_module(tp);
tp_set(tp, kolibri_mod, tp_string("open"), tp_fnc(tp, kolibri_open));
tp_set(tp, kolibri_mod, tp_string("window"), tp_fnc(tp, kolibri_mainwindow));
/* debug */
tp_set(tp, kolibri_mod, tp_string("debug_print"), tp_fnc(tp, kolibri_debug_print));
/* socket is a separated module. */
tp_set(tp, kolibri_mod, tp_string("socket"), socket_mod);
/* Bind module attributes. */
tp_set(tp, kolibri_mod, tp_string("__doc__"),
tp_string("KolibriOS system specific functions."));
tp_set(tp, kolibri_mod, tp_string("__name__"), tp_string("kolibri"));
tp_set(tp, kolibri_mod, tp_string("__file__"), tp_string(__FILE__));
/* Bind to tiny modules[] */
tp_set(tp, tp->modules, tp_string("kolibri"), kolibri_mod);
}

View File

@ -1,383 +0,0 @@
import os
import sys
VARS = {}
TOPDIR = os.path.abspath(os.path.dirname(__file__))
TEST = False
CLEAN = False
BOOT = False
CORE = ['tokenize','parse','encode','py2bc']
MODULES = []
def main():
chksize()
if len(sys.argv) < 2:
print HELP
return
global TEST,CLEAN,BOOT
TEST = 'test' in sys.argv
CLEAN = 'clean' in sys.argv
BOOT = 'boot' in sys.argv
CLEAN = CLEAN or BOOT
TEST = TEST or BOOT
get_libs()
build_mymain()
cmd = sys.argv[1]
if cmd == 'linux':
vars_linux()
build_gcc()
elif cmd == 'mingw':
vars_windows()
build_gcc()
elif cmd == 'vs':
build_vs()
elif cmd == '64k':
build_64k()
elif cmd == 'blob':
build_blob()
else:
print 'invalid command'
HELP = """
python setup.py command [options] [modules]
Commands:
linux - build tinypy for linux
mingw - build tinypy for mingw under windows
vs - build tinypy using Visual Studio 2005 / 2008
64k - build a 64k version of the tinypy source
blob - build a single tinypy.c and tinypy.h
build - build CPython module ***
install - install CPython module ***
Options:
test - run tests during build
clean - rebuild all .tpc during build
boot - fully bootstrap and test tinypy
Modules:
math - build math module
random - build random module *
pygame - build pygame module **
marshal - build marshal module ***
jit - build jit module ***
re - build re module ***
* coming soon!!
** proof-of-concept included
*** vaporware
"""
def vars_linux():
VARS['$RM'] = 'rm -f'
VARS['$VM'] = './vm'
VARS['$TINYPY'] = './tinypy'
VARS['$SYS'] = '-linux'
VARS['$FLAGS'] = ''
VARS['$WFLAGS'] = '-std=c89 -Wall -Wc++-compat'
#-Wwrite-strings - i think this is included in -Wc++-compat
if 'pygame' in MODULES:
VARS['$FLAGS'] += ' `sdl-config --cflags --libs` '
def vars_windows():
VARS['$RM'] = 'del'
VARS['$VM'] = 'vm'
VARS['$TINYPY'] = 'tinypy'
VARS['$FLAGS'] = '-lmingw32'
VARS['$WFLAGS'] = '-Wwrite-strings -Wall'
VARS['$SYS'] = '-mingw32'
if 'pygame' in MODULES:
VARS['$FLAGS'] += ' -Ic:\\mingw\\include\\SDL -lSDLmain -lSDL '
def do_cmd(cmd):
for k,v in VARS.items():
cmd = cmd.replace(k,v)
if '$' in cmd:
print 'vars_error',cmd
sys.exit(-1)
print cmd
r = os.system(cmd)
if r:
print 'exit_status',r
sys.exit(r)
def do_chdir(dest):
print 'cd',dest
os.chdir(dest)
def build_bc(opt=False):
out = []
for mod in CORE:
out.append("""unsigned char tp_%s[] = {"""%mod)
fname = mod+".tpc"
data = open(fname,'rb').read()
cols = 16
for n in xrange(0,len(data),cols):
out.append(",".join([str(ord(v)) for v in data[n:n+cols]])+',')
out.append("""};""")
out.append("")
f = open('bc.c','wb')
f.write('\n'.join(out))
f.close()
def open_tinypy(fname,*args):
return open(os.path.join(TOPDIR,'tinypy',fname),*args)
def build_blob():
mods = CORE[:]
do_chdir(os.path.join(TOPDIR,'tinypy'))
for mod in mods: do_cmd('python py2bc.py %s.py %s.tpc'%(mod,mod))
do_chdir(os.path.join(TOPDIR))
out = []
out.append("/*")
out.extend([v.rstrip() for v in open(os.path.join(TOPDIR,'LICENSE.txt'),'r')])
out.append("*/")
out.append("")
out.append("#ifndef TINYPY_H")
out.append("#define TINYPY_H")
out.extend([v.rstrip() for v in open_tinypy('tp.h','r')])
for fname in ['list.c','dict.c','misc.c','string.c','builtins.c',
'gc.c','ops.c','vm.c','tp.c']:
for line in open_tinypy(fname,'r'):
line = line.rstrip()
if not len(line): continue
if line[0] == '/': continue
if line[0] == ' ': continue
if line[0] == '\t': continue
if line[-1] != '{': continue
if 'enum' in line: continue
if '=' in line: continue
if '#' in line: continue
line = line.replace('{',';')
# Do not include prototypes already defined earlier, or gcc will
# warn about doubled prototypes in user code.
if '(' in line:
line2 = line[:line.find('(') + 1]
got_already = False
for already in out:
if already.startswith(line2):
got_already = True
break
if got_already: continue
out.append(line)
out.append("#endif")
out.append('')
dest = os.path.join(TOPDIR,'build','tinypy.h')
print 'writing %s'%dest
f = open(dest,'w')
f.write('\n'.join(out))
f.close()
# we leave all the tinypy.h stuff at the top so that
# if someone wants to include tinypy.c they don't have to have
# tinypy.h cluttering up their folder
for mod in CORE:
out.append("""extern unsigned char tp_%s[];"""%mod)
for fname in ['list.c','dict.c','misc.c','string.c','builtins.c',
'gc.c','ops.c','vm.c','tp.c','bc.c']:
for line in open_tinypy(fname,'r'):
line = line.rstrip()
if line.find('#include "') != -1: continue
out.append(line)
out.append('')
dest = os.path.join(TOPDIR,'build','tinypy.c')
print 'writing %s'%dest
f = open(dest,'w')
f.write('\n'.join(out))
f.close()
def py2bc(cmd,mod):
src = '%s.py'%mod
dest = '%s.tpc'%mod
if CLEAN or not os.path.exists(dest) or os.stat(src).st_mtime > os.stat(dest).st_mtime:
cmd = cmd.replace('$SRC',src)
cmd = cmd.replace('$DEST',dest)
do_cmd(cmd)
else:
print '#',dest,'is up to date'
def build_gcc():
mods = CORE[:]
do_chdir(os.path.join(TOPDIR,'tinypy'))
if TEST:
mods.append('tests')
do_cmd("gcc $WFLAGS -g vmmain.c $FLAGS -lm -o vm")
do_cmd('python tests.py $SYS')
for mod in mods:
py2bc('python py2bc.py $SRC $DEST',mod)
else:
for mod in mods:
py2bc('python py2bc.py $SRC $DEST -nopos',mod)
if BOOT:
do_cmd('$VM tests.tpc $SYS')
for mod in mods: py2bc('$VM py2bc.tpc $SRC $DEST',mod)
build_bc()
do_cmd("gcc $WFLAGS -g tpmain.c $FLAGS -lm -o tinypy")
#second pass - builts optimized binaries and stuff
if BOOT:
do_cmd('$TINYPY tests.py $SYS')
for mod in mods: py2bc('$TINYPY py2bc.py $SRC $DEST -nopos',mod)
build_bc(True)
if BOOT:
do_cmd("gcc $WFLAGS -O2 tpmain.c $FLAGS -lm -o tinypy")
do_cmd('$TINYPY tests.py $SYS')
print("# OK - we'll try -O3 for extra speed ...")
do_cmd("gcc $WFLAGS -O3 tpmain.c $FLAGS -lm -o tinypy")
do_cmd('$TINYPY tests.py $SYS')
do_cmd("gcc $WFLAGS -O3 mymain.c $FLAGS -lm -o ../build/tinypy")
do_chdir('..')
if TEST:
test_mods(os.path.join('.','build','tinypy')+' $TESTS')
print("# OK")
def get_libs():
modules = os.listdir('modules')
for m in modules[:]:
if m not in sys.argv: modules.remove(m)
global MODULES
MODULES = modules
def build_mymain():
src = os.path.join(TOPDIR,'tinypy','tpmain.c')
out = open(src,'r').read()
dest = os.path.join(TOPDIR,'tinypy','mymain.c')
vs = []
for m in MODULES:
vs.append('#include "../modules/%s/init.c"'%m)
out = out.replace('/* INCLUDE */','\n'.join(vs))
vs = []
for m in MODULES:
vs.append('%s_init(tp);'%m)
out = out.replace('/* INIT */','\n'.join(vs))
f = open(dest,'w')
f.write(out)
f.close()
return True
def test_mods(cmd):
for m in MODULES:
tests = os.path.join('modules',m,'tests.py')
if not os.path.exists(tests): continue
cmd = cmd.replace('$TESTS',tests)
do_cmd(cmd)
def build_vs():
# How to compile on windows with Visual Studio:
# Call the batch script that sets environement variables for Visual Studio and
# then run this script.
# For VS 2005 the script is:
# "C:\Program Files\Microsoft Visual Studio 8\Common7\Tools\vsvars32.bat"
# For VS 2008: "C:\Program Files\Microsoft Visual Studio 9.0\Common7\Tools\vsvars32.bat"
# Doesn't compile with vc6 (no variadic macros)
# Note: /MD option causes to dynamically link with msvcrt80.dll. This dramatically
# reduces size (for vm.exe 159k => 49k). Downside is that msvcrt80.dll must be
# present on the system (and not all windows machine have it). You can either re-distribute
# msvcrt80.dll or statically link with C runtime by changing /MD to /MT.
mods = CORE[:]; mods.append('tests')
os.chdir(os.path.join(TOPDIR,'tinypy'))
do_cmd('cl vmmain.c /D "inline=" /Od /Zi /MD /Fdvm.pdb /Fmvm.map /Fevm.exe')
do_cmd('python tests.py -win')
for mod in mods: do_cmd('python py2bc.py %s.py %s.tpc'%(mod,mod))
do_cmd('vm.exe tests.tpc -win')
for mod in mods: do_cmd('vm.exe py2bc.tpc %s.py %s.tpc'%(mod,mod))
build_bc()
do_cmd('cl /Od tpmain.c /D "inline=" /Zi /MD /Fdtinypy.pdb /Fmtinypy.map /Fetinypy.exe')
#second pass - builts optimized binaries and stuff
do_cmd('tinypy.exe tests.py -win')
for mod in mods: do_cmd('tinypy.exe py2bc.py %s.py %s.tpc -nopos'%(mod,mod))
build_bc(True)
do_cmd('cl /Os vmmain.c /D "inline=__inline" /D "NDEBUG" /Gy /GL /Zi /MD /Fdvm.pdb /Fmvm.map /Fevm.exe /link /opt:ref /opt:icf')
do_cmd('cl /Os tpmain.c /D "inline=__inline" /D "NDEBUG" /Gy /GL /Zi /MD /Fdtinypy.pdb /Fmtinypy.map /Fetinypy.exe /link /opt:ref,icf /OPT:NOWIN98')
do_cmd("tinypy.exe tests.py -win")
do_cmd("dir *.exe")
def shrink(fname):
f = open(fname,'r'); lines = f.readlines(); f.close()
out = []
fixes = [
'vm','gc','params','STR',
'int','float','return','free','delete','init',
'abs','round','system','pow','div','raise','hash','index','printf','main']
passing = False
for line in lines:
#quit if we've already converted
if '\t' in line: return ''.join(lines)
#change " " into "\t" and remove blank lines
if len(line.strip()) == 0: continue
line = line.rstrip()
l1,l2 = len(line),len(line.lstrip())
line = "\t"*((l1-l2)/4)+line.lstrip()
#remove comments
if '.c' in fname or '.h' in fname:
#start block comment
if line.strip()[:2] == '/*':
passing = True;
#end block comment
if line.strip()[-2:] == '*/':
passing = False;
continue
#skip lines inside block comments
if passing:
continue
if '.py' in fname:
if line.strip()[:1] == '#': continue
#remove the "namespace penalty" from tinypy ...
for name in fixes:
line = line.replace('TP_'+name,'t'+name)
line = line.replace('tp_'+name,'t'+name)
line = line.replace('TP_','')
line = line.replace('tp_','')
out.append(line)
return '\n'.join(out)+'\n'
def chksize():
t1,t2 = 0,0
for fname in [
'tokenize.py','parse.py','encode.py','py2bc.py',
'tp.h','list.c','dict.c','misc.c','string.c','builtins.c',
'gc.c','ops.c','vm.c','tp.c','tpmain.c',
]:
fname = os.path.join(TOPDIR,'tinypy',fname)
f = open(fname,'r'); t1 += len(f.read()); f.close()
txt = shrink(fname)
t2 += len(txt)
print "#",t1,t2,t2-65536
return t2
def build_64k():
for fname in [
'tokenize.py','parse.py','encode.py','py2bc.py',
'tp.h','list.c','dict.c','misc.c','string.c','builtins.c',
'gc.c','ops.c','vm.c','tp.c','tpmain.c',
]:
src = os.path.join(TOPDIR,'tinypy',fname)
dest = os.path.join(TOPDIR,'build',fname)
txt = shrink(src)
f = open(dest,'w')
f.write(txt)
f.close()
print '%s saved to %s'%(src,dest)
if __name__ == '__main__':
main()

View File

@ -0,0 +1,13 @@
/* Copyright (C) 2019-2021 Logaev Maxim (turbocat2001), GPLv3 */
#include "tinypy.h"
#define GET_NUM_ARG() TP_TYPE(TP_NUMBER).number.val
#define GET_STR_ARG() TP_TYPE(TP_STRING).string.val
static tp_obj _add(TP){
unsigned num1 = (unsigned)GET_NUM_ARG();
unsigned num2 = (unsigned)GET_NUM_ARG();
return tp_number(num1 | num2);
}

View File

@ -0,0 +1,17 @@
#include "tinypy.h"
#include "bitwise.c"
#define EXPORT(MOD_NAME, F_NAME, F_POINT) tp_set(tp, MOD_NAME , tp_string(F_NAME), tp_fnc(tp, F_POINT))
void bitwise_init(TP)
{
tp_obj bit_mod = tp_dict(tp);
EXPORT(bit_mod, "add" , _add);
tp_set(tp, bit_mod, tp_string("__doc__"), tp_string("Bitwise operations for large numbers"));
tp_set(tp, bit_mod, tp_string("__name__"), tp_string("bitwise"));
tp_set(tp, bit_mod, tp_string("__file__"), tp_string(__FILE__));
tp_set(tp, tp->modules, tp_string("bitwise"), bit_mod);
}

View File

@ -1,21 +1,15 @@
#include <string.h> #include <string.h>
#include "tp.h" #include "tinypy.h"
extern tp_obj tp_fnc(TP,tp_obj v(TP)); #define call70(par, st) __asm__ __volatile__("int $0x40":"=a"(st):"a"(70), "b"(par))
extern tp_obj tp_method(TP,tp_obj self,tp_obj v(TP)); #define call70_rw(par, st, cnt) __asm__ __volatile__ ("int $0x40":"=a"(st), "=b"(cnt):"a"(70), "b"(par))
extern tp_obj tp_number(tp_num v);
extern tp_obj tp_string(char const *v); #define GET_STR_ARG() TP_TYPE(TP_STRING).string.val
extern tp_obj tp_list(TP);
extern tp_obj tp_dict(TP);
extern void _tp_raise(TP,tp_obj);
// #define _cdecl __attribute__((cdecl))
extern int (* _cdecl con_printf)(const char* format,...);
#define call70(par, st) asm volatile ("int $0x40":"=a"(st):"a"(70), "b"(par))
#define call70_rw(par, st, cnt) asm volatile ("int $0x40":"=a"(st), "=b"(cnt):"a"(70), "b"(par))
typedef unsigned int uint32_t; typedef unsigned int uint32_t;
typedef unsigned char uint8_t; typedef unsigned char uint8_t;
#pragma pack(push, 1)
typedef struct { typedef struct {
uint32_t subfnc; uint32_t subfnc;
uint32_t res1; uint32_t res1;
@ -24,8 +18,10 @@ typedef struct {
uint8_t *data; uint8_t *data;
uint8_t res4; uint8_t res4;
char *fn; char *fn;
}__attribute__((__packed__)) info_params_t; }info_params_t;
#pragma pack(pop)
#pragma pack(push,1)
typedef struct { typedef struct {
uint32_t subfnc; uint32_t subfnc;
uint32_t pos; uint32_t pos;
@ -34,7 +30,8 @@ typedef struct {
char* data; char* data;
uint8_t res2; uint8_t res2;
char* fn; char* fn;
} __attribute__((__packed__)) rw_params_t; }rw_params_t;
#pragma pack(pop)
static tp_obj kolibri_close(TP) static tp_obj kolibri_close(TP)
{ {
@ -58,7 +55,7 @@ static tp_obj kolibri_read(TP)
char *mode = (char *)tp_get(tp, self, tp_string("mode")).string.val; char *mode = (char *)tp_get(tp, self, tp_string("mode")).string.val;
if (*mode != 'r') if (*mode != 'r')
tp_raise(tp_None, "IOError: file not open for reading", tp_None); tp_raise_f(tp_None, "IOError: file not open for reading", tp_None);
if (!buf) if (!buf)
return tp_None; return tp_None;
@ -100,7 +97,7 @@ static tp_obj kolibri_write(TP)
if (*mode != 'w' && *mode != 'a') if (*mode != 'w' && *mode != 'a')
{ {
tp_raise(tp_None, "IOError: file not open for writing", tp_None); tp_raise_f(tp_None, "IOError: file not open for writing", tp_None);
} }
else else
{ {
@ -112,7 +109,7 @@ static tp_obj kolibri_write(TP)
call70_rw((&params), status, cnt); call70_rw((&params), status, cnt);
if (status) if (status)
{ {
tp_raise(tp_None, "IOError: writing failed with status %d", status); tp_raise_f(tp_None, "IOError: writing failed with status %d", status);
} }
pos += cnt; pos += cnt;
tp_set(tp, self, tp_string("pos"), tp_number(pos)); tp_set(tp, self, tp_string("pos"), tp_number(pos));
@ -142,7 +139,7 @@ static tp_obj kolibri_writelines(TP)
if (*mode != 'w' && *mode != 'a') if (*mode != 'w' && *mode != 'a')
{ {
tp_raise(tp_None, "IOError: file not open for writing", tp_None); tp_raise_f(tp_None, "IOError: file not open for writing", tp_None);
} }
else else
{ {
@ -162,7 +159,7 @@ static tp_obj kolibri_writelines(TP)
call70_rw((&params), status, cnt); call70_rw((&params), status, cnt);
if (status) if (status)
tp_raise(tp_None, "IOError: writing failed with status %d", status); tp_raise_f(tp_None, "IOError: writing failed with status %d", status);
pos += cnt; pos += cnt;
} }
tp_set(tp, self, tp_string("pos"), tp_number(pos)); tp_set(tp, self, tp_string("pos"), tp_number(pos));
@ -214,13 +211,13 @@ tp_obj kolibri_open(TP) {
if (mode_obj.type == TP_NONE) if (mode_obj.type == TP_NONE)
mode_obj = tp_string("r"); mode_obj = tp_string("r");
else if (mode_obj.type != TP_STRING) else if (mode_obj.type != TP_STRING)
tp_raise(tp_None, "ValueError: bad file access mode %s", TP_CSTR(mode_obj)); tp_raise_f(tp_None, "ValueError: bad file access mode %s", TP_CSTR(mode_obj));
switch(mode_obj.string.val[0]) switch(mode_obj.string.val[0])
{ {
case 'w': case 'w':
call70((&params), status); call70((&params), status);
if (status) if (status)
tp_raise(tp_None, "IOError: cannot open file for writing", tp_None); tp_raise_f(tp_None, "IOError: cannot open file for writing", tp_None);
size = 0; size = 0;
break; break;
case 'a': case 'a':
@ -229,10 +226,10 @@ tp_obj kolibri_open(TP) {
case 'r': case 'r':
break; break;
default: default:
tp_raise(tp_None, "ValueError: mode string must begin with 'r', 'w', or 'a'", tp_None); tp_raise_f(tp_None, "ValueError: mode string must begin with 'r', 'w', or 'a'", tp_None);
} }
if ((size = kolibri_filesize(fn)) < 0) if ((size = kolibri_filesize(fn)) < 0)
tp_raise(tp_None, "IOError: filesize returned %d", tp_number(size)); tp_raise_f(tp_None, "IOError: filesize returned %d", tp_number(size));
obj = tp_dict(tp); obj = tp_dict(tp);
tp_set(tp, obj, tp_string("name"), tp_string(fn)); tp_set(tp, obj, tp_string("name"), tp_string(fn));
tp_set(tp, obj, tp_string("size"), tp_number(size)); tp_set(tp, obj, tp_string("size"), tp_number(size));

View File

@ -0,0 +1,32 @@
#include "tinypy.h"
#include "syscalls.c"
#include "fs.c"
#define EXPORT(MOD_NAME, F_NAME, F_POINT) tp_set(tp, MOD_NAME , tp_string(F_NAME), tp_fnc(tp, F_POINT))
extern tp_obj tp_dict(TP);
extern tp_obj tp_fnc(TP,tp_obj v(TP));
void ksys_init(TP)
{
tp_obj ksys_mod = tp_dict(tp);
// syscalls
EXPORT(ksys_mod, "debug_print" , _debug_print);
EXPORT(ksys_mod, "start_draw" , _start_draw);
EXPORT(ksys_mod, "end_draw" , _end_draw);
EXPORT(ksys_mod, "create_window", _create_window);
EXPORT(ksys_mod, "create_button", _create_button);
EXPORT(ksys_mod, "draw_text" , _draw_text);
EXPORT(ksys_mod, "get_event" , _get_event);
EXPORT(ksys_mod, "get_button" ,_get_button);
EXPORT(ksys_mod, "get_sys_colors",_get_sys_colors);
// filesystem
EXPORT(ksys_mod, "open", kolibri_open);
tp_set(tp, ksys_mod, tp_string("__doc__"), tp_string("KolibriOS system specific functions."));
tp_set(tp, ksys_mod, tp_string("__name__"), tp_string("kolibri"));
tp_set(tp, ksys_mod, tp_string("__file__"), tp_string(__FILE__));
tp_set(tp, tp->modules, tp_string("ksys"), ksys_mod);
}

View File

@ -0,0 +1,92 @@
/* Copyright (C) 2019-2021 Logaev Maxim (turbocat2001), GPLv3 */
#include "tinypy.h"
#include <kos32sys.h>
#define GET_NUM_ARG() TP_TYPE(TP_NUMBER).number.val
#define GET_STR_ARG() TP_TYPE(TP_STRING).string.val
void debug_write_byte(const char ch){
__asm__ __volatile__(
"int $0x40"
::"a"(63), "b"(1), "c"(ch)
);
}
static tp_obj _debug_print(TP){
tp_obj str = TP_TYPE(TP_STRING);
for(int i=0; i < str.string.len; i++)
{
debug_write_byte(str.string.val[i]);
}
return tp_None;
}
static tp_obj _start_draw(TP){
begin_draw();
return tp_None;
}
static tp_obj _end_draw(TP){
end_draw();
return tp_None;
}
static tp_obj _create_window(TP){
int x = GET_NUM_ARG();
int y = GET_NUM_ARG();
int w = GET_NUM_ARG();
int h = GET_NUM_ARG();
const char *title= GET_STR_ARG();
unsigned int color = GET_NUM_ARG();
unsigned int style = GET_NUM_ARG();
sys_create_window(x,y,w,h, title, color,style);
return tp_None;
}
static tp_obj _create_button(TP){
unsigned int x = GET_NUM_ARG();
unsigned int y = GET_NUM_ARG();
unsigned int h = GET_NUM_ARG();
unsigned int w = GET_NUM_ARG();
unsigned int id = GET_NUM_ARG();
unsigned int color = GET_NUM_ARG();
define_button((x << 16) + w, (y << 16) + h, id, color);
return tp_None;
}
static tp_obj _draw_text(TP){
const char *str= GET_STR_ARG();
int x = GET_NUM_ARG();
int y = GET_NUM_ARG();
int len = GET_NUM_ARG();
unsigned color = (unsigned)GET_NUM_ARG();
draw_text_sys(str, x, y, len, color);
return tp_None;
}
static tp_obj _get_event(TP){
return tp_number(get_os_event());
}
static tp_obj _get_button(TP){
return tp_number(get_os_button());
}
static tp_obj _get_sys_colors(TP){
tp_obj color_obj = tp_dict(tp);
struct kolibri_system_colors colors;
get_system_colors(&colors);
tp_set(tp, color_obj, tp_string("frame_area"), tp_number(colors.frame_area));
tp_set(tp, color_obj, tp_string("grab_bar"), tp_number(colors.grab_bar));
tp_set(tp, color_obj, tp_string("grab_bar_button)"), tp_number(colors.grab_bar_button));
tp_set(tp, color_obj, tp_string( "grab_button_text)"), tp_number(colors.grab_button_text));
tp_set(tp, color_obj, tp_string("grab_text"), tp_number(colors.grab_text));
tp_set(tp, color_obj, tp_string("work_area"), tp_number(colors.work_area));
tp_set(tp, color_obj, tp_string("work_button"), tp_number(colors.work_button));
tp_set(tp, color_obj, tp_string("work_button_text"), tp_number(colors.work_button_text));
tp_set(tp, color_obj, tp_string("work_graph"), tp_number(colors.work_graph));
tp_set(tp, color_obj, tp_string("work_text"), tp_number(colors.work_text));
return color_obj;
}

View File

@ -1,5 +1,4 @@
#include "math.c" #include "math.c"
#include "../../tinypy/tp.h"
/* /*
* init math module, namely, set its dictionary * init math module, namely, set its dictionary

View File

@ -1,4 +1,6 @@
#include <math.h> #include <math.h>
#include "tinypy.h"
#ifndef M_E #ifndef M_E
#define M_E 2.7182818284590452354 #define M_E 2.7182818284590452354
#endif #endif
@ -23,8 +25,8 @@
errno = 0; \ errno = 0; \
r = cfunc(x); \ r = cfunc(x); \
if (errno == EDOM || errno == ERANGE) { \ if (errno == EDOM || errno == ERANGE) { \
tp_raise(tp_None, "%s(x): x=%f, " \ tp_raise(tp_None, tp_printf(tp, "%s(x): x=%f " \
"out of range", __func__, x); \ "out of range", __func__, x)); \
} \ } \
\ \
return (tp_number(r)); \ return (tp_number(r)); \
@ -46,8 +48,8 @@
errno = 0; \ errno = 0; \
r = cfunc(x, y); \ r = cfunc(x, y); \
if (errno == EDOM || errno == ERANGE) { \ if (errno == EDOM || errno == ERANGE) { \
tp_raise(tp_None, "%s(x, y): x=%f,y=%f " \ tp_raise(tp_None, tp_printf(tp, "%s(x, y): x=%f,y=%f " \
"out of range", __func__, x, y);\ "out of range", __func__, x, y)); \
} \ } \
\ \
return (tp_number(r)); \ return (tp_number(r)); \
@ -185,8 +187,8 @@ static tp_obj math_frexp(TP) {
errno = 0; errno = 0;
r = frexp(x, &y); r = frexp(x, &y);
if (errno == EDOM || errno == ERANGE) { if (errno == EDOM || errno == ERANGE) {
tp_raise(tp_None, "%s(x): x=%f, " tp_raise(tp_None, tp_printf(tp, "%s(x): x=%f, "
"out of range", __func__, x); "out of range", __func__, x));
} }
_tp_list_append(tp, rList.list.val, tp_number(r)); _tp_list_append(tp, rList.list.val, tp_number(r));
@ -234,7 +236,7 @@ static tp_obj math_log(TP) {
else if (b.type == TP_NUMBER) else if (b.type == TP_NUMBER)
y = (double)b.number.val; y = (double)b.number.val;
else else
tp_raise(tp_None, "%s(x, [base]): base invalid", __func__); tp_raise(tp_None, tp_printf(tp, "%s(x, [base]): base invalid", __func__));
errno = 0; errno = 0;
num = log10(x); num = log10(x);
@ -251,8 +253,8 @@ static tp_obj math_log(TP) {
return (tp_number(r)); return (tp_number(r));
excep: excep:
tp_raise(tp_None, "%s(x, y): x=%f,y=%f " tp_raise(tp_None, tp_printf(tp, "%s(x, y): x=%f,y=%f "
"out of range", __func__, x, y); "out of range", __func__, x, y));
} }
/* /*
@ -278,8 +280,8 @@ static tp_obj math_modf(TP) {
errno = 0; errno = 0;
r = modf(x, &y); r = modf(x, &y);
if (errno == EDOM || errno == ERANGE) { if (errno == EDOM || errno == ERANGE) {
tp_raise(tp_None, "%s(x): x=%f, " tp_raise(tp_None, tp_printf(tp, "%s(x): x=%f, "
"out of range", __func__, x); "out of range", __func__, x));
} }
_tp_list_append(tp, rList.list.val, tp_number(r)); _tp_list_append(tp, rList.list.val, tp_number(r));
@ -303,8 +305,8 @@ static tp_obj math_pow(TP) {
errno = 0; errno = 0;
r = pow(x, y); r = pow(x, y);
if (errno == EDOM || errno == ERANGE) { if (errno == EDOM || errno == ERANGE) {
tp_raise(tp_None, "%s(x, y): x=%f,y=%f " tp_raise(tp_None, tp_printf(tp, "%s(x, y): x=%f,y=%f "
"out of range", __func__, x, y); "out of range", __func__, x, y));
} }
return (tp_number(r)); return (tp_number(r));
@ -362,4 +364,3 @@ TP_MATH_FUNC1(tan)
* mathematically, tanh(x) = sinh(x) / cosh(x). * mathematically, tanh(x) = sinh(x) / cosh(x).
*/ */
TP_MATH_FUNC1(tanh) TP_MATH_FUNC1(tanh)

View File

@ -0,0 +1,15 @@
#include "math/init.c"
#include "random/init.c"
#include "re/init.c"
#include "ksys/init.c"
#include "pygame/init.c"
#include "bitwise/init.c"
void init_std_modules(TP){
math_init(tp);
random_init(tp);
re_init(tp);
ksys_init(tp);
pygame_init(tp);
bitwise_init(tp);
}

View File

@ -14,13 +14,13 @@ Uint32 pygame_list_to_color(TP,tp_obj clr,SDL_Surface *s) {
#define PYGAME_TYPE_SURF 0x1001 #define PYGAME_TYPE_SURF 0x1001
void pygame_surf_free(TP,tp_obj d) { void pygame_surf_free(TP,tp_obj d) {
if (d.data.magic != PYGAME_TYPE_SURF) { tp_raise(,"%s","not a surface"); } if (d.data.magic != PYGAME_TYPE_SURF) { tp_raise(,tp_printf(tp, "%s","not a surface")); }
SDL_FreeSurface((SDL_Surface*)d.data.val); SDL_FreeSurface((SDL_Surface*)d.data.val);
} }
SDL_Surface *pygame_obj_to_surf(TP,tp_obj self) { SDL_Surface *pygame_obj_to_surf(TP,tp_obj self) {
tp_obj d = tp_get(tp,self,tp_string("__surf")); tp_obj d = tp_get(tp,self,tp_string("__surf"));
if (d.data.magic != PYGAME_TYPE_SURF) { tp_raise(0,"%s","not a surface"); } if (d.data.magic != PYGAME_TYPE_SURF) { tp_raise(0,tp_printf(tp, "%s","not a surface")); }
return (SDL_Surface*)d.data.val; return (SDL_Surface*)d.data.val;
} }

View File

@ -1,6 +1,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <time.h> #include <time.h>
#include <errno.h> #include <errno.h>
#include "tinypy.h"
#include <math.h> #include <math.h>
#ifndef M_E #ifndef M_E

View File

@ -36,6 +36,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include "regexpr.h" #include "regexpr.h"
#include "tinypy.h"
/* The original code blithely assumed that sizeof(short) == 2. Not /* The original code blithely assumed that sizeof(short) == 2. Not
* always true. Original instances of "(short)x" were replaced by * always true. Original instances of "(short)x" were replaced by

View File

@ -1,36 +1,32 @@
NAME = tinypy NAME=tinypy
CC = kos32-gcc CC = kos32-gcc
LD = kos32-ld LD = kos32-ld
SDK_DIR:= $(abspath ../../../../contrib/sdk)
LDFLAGS = -static -nostdlib -T $(SDK_DIR)/sources/newlib/app.lds \ LDFLAGS = -static -nostdlib -T $(SDK_DIR)/sources/newlib/app.lds \
--image-base 0 -lgcc -lc.dll --image-base 0 -lgcc -lSDLn -lc.dll -lsound
CFLAGS = -U_Win32 -U_WIN32 -U__MINGW32__ -mpreferred-stack-boundary=2 \ SDL_DIR = $(SDK_DIR)/sources/SDL-1.2.2_newlib
-mincoming-stack-boundary=2 -fno-builtin -fno-common
CFLAGS = -DCONIO -U_Win32 -U_WIN32 -U__MINGW32__ -mpreferred-stack-boundary=2 \
-mincoming-stack-boundary=2 -fno-builtin -fno-common -O3
INCLUDES= -I. -I$(SDK_DIR)/sources/newlib/libc/include INCLUDES= -I. -I$(SDK_DIR)/sources/newlib/libc/include -I$(SDL_DIR)/include
LIBPATH:= -L $(SDK_DIR)/lib -L /home/autobuild/tools/win32/mingw32/lib LIBPATH:= -L $(SDK_DIR)/lib -L /home/autobuild/tools/win32/mingw32/lib -L.
MODULES_DIR = $(abspath ../modules) STD_MODULES= ../std_modules/modules.o
OBJECTS = tpmain.o $(STD_MODULES)
MODULES_OBJ = $(MODULES_DIR)/kolibri/init.o \ all:$(NAME)
$(MODULES_DIR)/kolibri/fs.o \
$(MODULES_DIR)/kolibri/net.o \
$(MODULES_DIR)/kolibri/gui.o \
$(MODULES_DIR)/kolibri/debug.o
OBJECTS = tpmain.o $(MODULES_OBJ)
all: $(NAME)
$(NAME): $(OBJECTS) $(NAME): $(OBJECTS)
$(LD) $(LIBPATH) --subsystem native -o $@ $(OBJECTS) $(LDFLAGS) -n # -Map $(NAME).map $(LD) $(LIBPATH) --subsystem native -o $@ $(OBJECTS) $(LDFLAGS) -n -Map $(NAME).map
objcopy $@ -O binary strip -S $(NAME)
kos32-objcopy $@ -O binary
kpack $@
%.o : %.c Makefile %.o : %.c Makefile
$(CC) -c $(INCLUDES) $(CFLAGS) -o $@ $< $(CC) -c $(INCLUDES) $(CFLAGS) -o $@ $<
clean: clean:
rm -f *.o $(NAME).map $(MODULES_OBJ) rm -f $(NAME).map $(OBJECTS) *.o core/*.tpc core/*.pyc

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,34 @@
#!/bin/python2
# Copyright (C) 2019-2021 Logaev Maxim (turbocat2001), GPLv3
import os
CORE = ['tokenize','parse','encode','py2bc']
def py2bc(cmd,mod):
src = 'core/%s.py'%mod
dest = 'core/%s.tpc'%mod
cmd = cmd.replace('$SRC',src)
cmd = cmd.replace('$DEST',dest)
os.system(cmd)
def build_bc(opt=False):
out = []
for mod in CORE:
out.append("""unsigned char tp_%s[] = {"""%mod)
fname ="core/"+mod+".tpc"
data = open(fname,'rb').read()
cols = 16
for n in xrange(0,len(data),cols):
out.append(",".join([str(ord(v)) for v in data[n:n+cols]])+',')
out.append("""};""")
out.append("")
f = open('bc.c','wb')
f.write('\n'.join(out))
f.close()
for src in CORE:
py2bc('python2 core/py2bc.py $SRC $DEST',src)
build_bc(True)

View File

@ -1,209 +0,0 @@
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;
}
#define BUF_SIZE 2048
tp_obj tp_raw_input(TP) {
tp_obj prompt;
char *buf = malloc(BUF_SIZE);
if (tp->params.list.val->len)
{
prompt = TP_OBJ();
con_printf("%s", TP_CSTR(prompt));
}
con_gets(buf, BUF_SIZE);
return tp_string(buf);
}
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

@ -1,35 +1,23 @@
#include "kolibri.h" // Copyright (C) 2019-2021 Logaev Maxim (turbocat2001), GPLv3
/*
#define __stdcall __attribute__((stdcall)) #include <string.h>
#define _cdecl __attribute__((cdecl))
#define _stdcall __attribute__((stdcall)) char con_enabled=0;
*/ const char title[]="KTinyPy";
#pragma pack(push,1)
typedef struct{
char *name;
void *data;
} kol_struct_import;
#pragma pack(pop)
void (* _stdcall con_init)(unsigned w_w, unsigned w_h, unsigned s_w, unsigned s_h, const char* t); 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,...); int (* _cdecl con_printf)(const char* format,...);
void (* _stdcall con_exit)(char bCloseWindow); void (* _stdcall con_exit)(char bCloseWindow);
void (* __stdcall con_gets)(char* str, int n); void (* __stdcall con_gets)(char* str, int n);
void (* _stdcall con_set_title)(const char* title); void (* _stdcall con_set_title)(const char* title);
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")) ||
!(con_set_title = ( _stdcall void (*)(const char*))
kol_cofflib_procload (imp, "con_set_title")))
{
kol_exit();
}
con_init(-1, -1, -1, -1, title);
}
kol_struct_import* kol_cofflib_load(char *name) kol_struct_import* kol_cofflib_load(char *name)
{ {
kol_struct_import* result; kol_struct_import* result;
@ -51,18 +39,32 @@ void* kol_cofflib_procload (kol_struct_import *imp, char *name)
return NULL; 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() void kol_exit()
{ {
asm ("int $0x40"::"a"(-1)); asm ("int $0x40"::"a"(-1));
} }
void console_load()
{
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")) ||
!(con_set_title = ( _stdcall void (*)(const char*))
kol_cofflib_procload (imp, "con_set_title")))
{
kol_exit();
}
}
void console_init(){
con_init(-1, -1, -1, -1, title);
con_enabled=1;
}

View File

@ -0,0 +1,78 @@
def get_ops():
""" Builds an opcode name <-> value dictionary """
li = ["EOF","ADD","SUB","MUL","DIV","POW","BITAND","BITOR","CMP","GET", \
"SET","NUMBER","STRING","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","BITXOR", "IFN", "NOT", "BITNOT"]
dic = {}
for i in li:
dic[i] = li.index(i)
return dic
def prepare(x):
""" Prepares the line for processing by breaking it into tokens,
removing empty tokens and stripping whitespace """
try:
ind = x.index('"')
except:
ind = -1
if ind != -1:
d = x[ind:]
x = x[:ind]
x = x.split(' ')
tmp = []
final = []
for i in x:
if i:
if i[0] != ':':
tmp.append(i)
for i in tmp[:4]:
final.append(i)
if not d:
d = "".join(tmp[4:])
final.append(d.strip())
return final
def dequote(x):
""" Removes outermost quotes from a string, if they exist """
if x[0] == '"' and x[len(x)-1] == '"':
return x[1:len(x)-1]
return x
def assemble(asmc):
asmc = asmc.strip()
asmc = asmc.split('\n')
bc = []
ops = get_ops()
for line in asmc:
current = prepare(line)
i,a,b,c,d = current
a = int(a)
b = int(b)
c = int(c)
bc.append(chr(ops[i]))
bc.append(chr(a))
bc.append(chr(b))
bc.append(chr(c))
if i == "LINE":
n = a * 4
d = dequote(d)
text = d
text += chr(0) * (n - len(d))
bc.append(text)
if i == "STRING":
d = dequote(d)
text = d + "\0"*(4-len(d)%4)
bc.append(text)
elif i == "NUMBER":
d = int(d)
bc.append(fpack(d))
bc = "".join(bc)
return bc
if __name__ == '__main__':
asmc = load(ARGV[1])
bc = assemble(asmc)
save(ARGV[2], bc)

View File

@ -1,6 +1,6 @@
def _boot_init(): def _boot_init():
global FTYPE global FTYPE
f = open('tp.h','r').read() f = open('tinypy.h','r').read()
FTYPE = 'f' FTYPE = 'f'
if 'double tp_num' in f: FTYPE = 'd' if 'double tp_num' in f: FTYPE = 'd'
import sys import sys

View File

@ -0,0 +1,175 @@
import os
import sys
import struct
ARGV = sys.argv
RM = 'rm -f '
VM = './vm '
TINYPY = './tinypy '
if '-mingw32' in ARGV:
RM = 'del '
VM = 'vm '
TINYPY = 'tinypy '
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 boot_init():
global FTYPE
f = open('tp.h','r').read()
FTYPE = 'f'
if 'double tp_num' in f: FTYPE = 'd'
boot_init()
def fpack(v):
return struct.pack(FTYPE,v)
def system(cmd):
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()
def do_cmd(cmd):
FLAGS = ''
SDL = '`sdl-config --cflags --libs`'
SYS = '-linux'
if '-mingw32' in sys.argv:
#-mwindows -mno-cygwin
FLAGS = '-mwindows -lmingw32'
#SDL = '-lSDLmain -Ic:/packages/sdl-devel/include -Lc:/packages/sdl-devel/lib -lSDL -Lc:/packages/sdl-devel/lib -lSDL'
SDL = '-Ic:/packages/sdl-devel/include -Lc:/packages/sdl-devel/lib '+\
'-lSDLmain -lSDL'
SYS = '-mingw32'
cmd = cmd.replace('$FLAGS',FLAGS)
cmd = cmd.replace('$SYS',SYS)
cmd = cmd.replace('$SDL',SDL)
print cmd
r = os.system(cmd)
if r:
print 'exit',r
sys.exit(r)
def chksize():
import mk64k
t1,t2 = 0,0
for fname in [
'tokenize.py','parse.py','encode.py','py2bc.py',
'tp.h','list.c','dict.c','misc.c','string.c','builtins.c',
'gc.c','ops.c','vm.c','tp.c','tpmain.c',
]:
f = open(fname,'r'); t1 += len(f.read()); f.close()
txt = mk64k.shrink(fname)
t2 += len(txt)
print "#",t1,t2,t2-65536
return t2
MODS = ['tokenize','parse','encode','py2bc']
def build_bc(opt=False):
out = []
for mod in MODS:
out.append("""unsigned char tp_%s[] = {"""%mod)
fname = mod+".tpc"
data = open(fname,'rb').read()
cols = 16
for n in xrange(0,len(data),cols):
out.append(",".join([str(ord(v)) for v in data[n:n+cols]])+',')
out.append("""};""")
out.append("")
f = open('bc.c','wb')
f.write('\n'.join(out))
f.close()
def build_tp():
out = []
out.append("/*")
out.extend([v.rstrip() for v in open('LICENSE.txt','r')])
out.append("*/")
out.append("")
out.append("#ifndef TINYPY_H")
out.append("#define TINYPY_H")
out.extend([v.rstrip() for v in open('tp.h','r')])
for fname in ['list.c','dict.c','misc.c','string.c','builtins.c',
'gc.c','ops.c','vm.c','tp.c']:
for line in open(fname,'r'):
line = line.rstrip()
if not len(line): continue
if line[0] == ' ': continue
if line[0] == '\t': continue
if line[-1] != '{': continue
if 'enum' in line: continue
if '=' in line: continue
if '#' in line: continue
line = line.replace('{',';')
out.append(line)
out.append("#endif")
out.append('')
f = open('tinypy.h','w')
f.write('\n'.join(out))
f.close()
# we leave all the tinypy.h stuff at the top so that
# if someone wants to include tinypy.c they don't have to have
# tinypy.h cluttering up their folder
for mod in MODS:
out.append("""extern unsigned char tp_%s[];"""%mod)
for fname in ['list.c','dict.c','misc.c','string.c','builtins.c',
'gc.c','ops.c','vm.c','tp.c','bc.c']:
for line in open(fname,'r'):
line = line.rstrip()
if line.find('#include "') != -1: continue
out.append(line)
out.append('')
f = open('tinypy.c','w')
f.write('\n'.join(out))
f.close()
def bootstrap():
mods = MODS[:]; mods.append('tests')
do_cmd("gcc -Wall -g vmmain.c $FLAGS -lm -o vm")
do_cmd('python tests.py $SYS')
for mod in mods: do_cmd('python py2bc.py %s.py %s.tpc'%(mod,mod))
do_cmd(VM+'tests.tpc $SYS')
for mod in mods: do_cmd(VM+'py2bc.tpc %s.py %s.tpc'%(mod,mod))
build_bc()
do_cmd("gcc -Wall -g tpmain.c $FLAGS -lm -o tinypy")
#second pass - builts optimized binaries and stuff
do_cmd(TINYPY+'tests.py $SYS')
for mod in mods: do_cmd(TINYPY+'py2bc.py %s.py %s.tpc -nopos'%(mod,mod))
build_bc(True)
do_cmd("gcc -Wall -O2 tpmain.c $FLAGS -lm -o tinypy")
do_cmd(TINYPY+'tests.py $SYS')
print("# OK - we'll try -O3 for extra speed ...")
do_cmd("gcc -Wall -O3 tpmain.c $FLAGS -lm -o tinypy")
do_cmd(TINYPY+'tests.py $SYS')
print("# OK")
build_tp()
do_cmd("gcc -Wall -O3 tinypy-sdl.c tinypy.c $FLAGS $SDL -lm -o tinypy-sdl")
if __name__ == '__main__':
bootstrap()

View File

@ -0,0 +1,99 @@
import sys
__tinypy__ = "tinypy" in sys.version
if not __tinypy__:
from boot import *
__tinypy__ = False
else:
__tinypy__ = True
def get_ops():
""" Builds an value <-> opcode name dictionary """
li = ["EOF","ADD","SUB","MUL","DIV","POW","BITAND","BITOR","CMP","GET", \
"SET","NUMBER","STRING","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","BITXOR", "IFN", "NOT", "BITNOT"]
dic = {}
for i in li:
dic[li.index(i)] = i
return dic
def isupper(x):
return ord(x) >= ord("A") and ord(x) <= ord("Z")
def pad(s, n):
p = ""
if n < 0:
m = -n - len(s)
if m > 0: p = " " * m
return p + s
m = n - len(s)
if m > 0: p = " " * m
return s + p
def funpack(bytes):
if not __tinypy__:
import struct
return struct.unpack("d", bytes)[0]
def eat(x, bit):
y = int(x / 2 ** bit)
x -= y * 2 ** bit
return x, y
x = 0
for i in range(8):
x += ord(bytes[i]) * 2 ** (i * 8)
x, sign = eat(x, 63)
x, exponent = eat(x, 52)
x, mantissa1 = eat(x, 31)
x, mantissa2 = eat(x, 0)
mantissa = mantissa1 * 2 ** 31 + mantissa2
sign = sign * -2 + 1
x = sign * 2 ** (exponent - 1023) * (1 + mantissa / 2 ** 52)
return x
def text(x, ip, bc):
return "".join([chr(c) for c in bc[ip:ip+x]])
def trim(x):
txt = []
for c in x:
if ord(c):
txt.append(c)
return "".join(txt)
def disassemble(bc):
bc = [ord(x) for x in bc]
asmc = []
ip = 0
names = get_ops()
while ip < len(bc):
i, a, b, c = bc[ip:ip + 4]
line = ""
line += pad(names[i], 10) + ":"
line += " " + pad(str(a), -3)
line += " " + pad(str(b), -3)
line += " " + pad(str(c), -3)
ip += 4
if names[i] == "LINE":
n = a * 4
line += " \"" + text(n,ip,bc) + "\""
line = trim(line)
ip += n
elif names[i] == "STRING":
n = b * 256 + c
line += " \"" + text(n,ip,bc) + "\""
line = trim(line)
ip += (int(n / 4) + 1) * 4
elif names[i] == "NUMBER":
f = funpack(text(8,ip,bc))
line += " " + str(f)
ip += 8
asmc.append(line)
asmc = "\n".join(asmc)
return asmc
if __name__ == "__main__":
bc = load(ARGV[1])
asmc = disassemble(bc)
print(asmc)

View File

@ -1,9 +1,9 @@
import tokenize import tokenize, sys
from tokenize import Token from tokenize import Token
if '.' in str(1.0): if not "tinypy" in sys.version:
from boot import * 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 EOF,ADD,SUB,MUL,DIV,POW,BITAND,BITOR,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,BITXOR,IFN,NOT,BITNOT = 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,45,46,47,48
class DState: class DState:
def __init__(self,code,fname): def __init__(self,code,fname):
@ -13,9 +13,9 @@ class DState:
self.stack,self.out,self._scopei,self.tstack,self._tagi,self.data = [],[('tag','EOF')],0,[],0,{} self.stack,self.out,self._scopei,self.tstack,self._tagi,self.data = [],[('tag','EOF')],0,[],0,{}
self.error = False self.error = False
def begin(self,gbl=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)) 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.rglobals,self.cregs,self.tmpc))
else: self.stack.append(None) 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.vars,self.r2n,self.n2r,self._tmpi,self.mreg,self.snum,self._globals,self.lineno,self.globals,self.rglobals,self.cregs,self.tmpc = [],{},{},0,0,str(self._scopei),gbl,-1,[],[],['regs'],0
self._scopei += 1 self._scopei += 1
insert(self.cregs) insert(self.cregs)
def end(self): def end(self):
@ -25,10 +25,12 @@ class DState:
# This next line forces the encoder to # This next line forces the encoder to
# throw an exception if any tmp regs # throw an exception if any tmp regs
# were leaked within the frame # were leaked within the frame
assert(self.tmpc == 0) #REG # assert(self.tmpc == 0) #REG
if self.tmpc != 0:
print("Warning:\nencode.py contains a register leak\n")
if len(self.stack) > 1: 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() self.vars,self.r2n,self.n2r,self._tmpi,self.mreg,self.snum,self._globals,self.lineno,self.globals,self.rglobals,self.cregs,self.tmpc = self.stack.pop()
else: self.stack.pop() else: self.stack.pop()
@ -185,6 +187,12 @@ def imanage(orig,fnc):
t = Token(orig.pos,'symbol','=',[items[0],orig]) t = Token(orig.pos,'symbol','=',[items[0],orig])
return fnc(t) return fnc(t)
def unary(i,tb,r=None):
r = get_tmp(r)
b = do(tb)
code(i,r,b)
if r != b: free_tmp(b)
return r
def infix(i,tb,tc,r=None): def infix(i,tb,tc,r=None):
r = get_tmp(r) r = get_tmp(r)
b,c = do(tb,r),do(tc) b,c = do(tb,r),do(tc)
@ -192,21 +200,17 @@ def infix(i,tb,tc,r=None):
if r != b: free_tmp(b) if r != b: free_tmp(b)
free_tmp(c) free_tmp(c)
return r return r
def ss_infix(ss,i,tb,tc,r=None): def logic_infix(op, tb, tc, _r=None):
r = get_tmp(r) t = get_tag()
r2 = get_tmp() r = do(tb, _r)
ss = _do_number(ss) if _r != r: free_tmp(_r) #REG
t = get_tag() if op == 'and': code(IF, r)
r = do(tb,r) elif op == 'or': code(IFN, r)
code(EQ,r2,r,ss) jump(t, 'end')
code(IF,r2) _r = r
jump(t,'else') r = do(tc, _r)
jump(t,'end') if _r != r: free_tmp(_r) #REG
tag(t,'else') tag(t, 'end')
r = do(tc,r)
tag(t,'end')
free_tmp(r2) #REG
free_tmp(ss) #REG
return r return r
def _do_none(r=None): def _do_none(r=None):
@ -216,13 +220,13 @@ def _do_none(r=None):
def do_symbol(t,r=None): def do_symbol(t,r=None):
sets = ['='] sets = ['=']
isets = ['+=','-=','*=','/='] isets = ['+=','-=','*=','/=', '|=', '&=', '^=']
cmps = ['<','>','<=','>=','==','!='] cmps = ['<','>','<=','>=','==','!=']
metas = { metas = {
'+':ADD,'*':MUL,'/':DIV,'**':POW, '+':ADD,'*':MUL,'/':DIV,'**':POW,
'-':SUB,'and':AND,'or':OR, '-':SUB,
'%':MOD,'>>':RSH,'<<':LSH, '%':MOD,'>>':RSH,'<<':LSH,
'&':AND,'|':OR, '&':BITAND,'|':BITOR,'^':BITXOR,
} }
if t.val == 'None': return _do_none(r) if t.val == 'None': return _do_none(r)
if t.val == 'True': if t.val == 'True':
@ -232,8 +236,7 @@ def do_symbol(t,r=None):
items = t.items items = t.items
if t.val in ['and','or']: if t.val in ['and','or']:
ss = int(t.val == 'or') return logic_infix(t.val, items[0], items[1], r)
return ss_infix(ss,metas[t.val],items[0],items[1],r)
if t.val in isets: if t.val in isets:
return imanage(t,do_symbol) return imanage(t,do_symbol)
if t.val == 'is': if t.val == 'is':
@ -241,7 +244,7 @@ def do_symbol(t,r=None):
if t.val == 'isnot': if t.val == 'isnot':
return infix(CMP,items[0],items[1],r) return infix(CMP,items[0],items[1],r)
if t.val == 'not': if t.val == 'not':
return infix(EQ,Token(t.pos,'number',0),items[0],r) return unary(NOT, items[0], r)
if t.val == 'in': if t.val == 'in':
return infix(HAS,items[1],items[0],r) return infix(HAS,items[1],items[0],r)
if t.val == 'notin': if t.val == 'notin':
@ -406,6 +409,8 @@ def do_call(t,r=None):
def do_name(t,r=None): def do_name(t,r=None):
if t.val in D.vars: if t.val in D.vars:
return do_local(t,r) return do_local(t,r)
if t.val not in D.rglobals:
D.rglobals.append(t.val)
r = get_tmp(r) r = get_tmp(r)
c = do_string(t) c = do_string(t)
code(GGET,r,c) code(GGET,r,c)
@ -413,6 +418,9 @@ def do_name(t,r=None):
return r return r
def do_local(t,r=None): def do_local(t,r=None):
if t.val in D.rglobals:
D.error = True
tokenize.u_error('UnboundLocalError',D.code,t.pos)
if t.val not in D.vars: if t.val not in D.vars:
D.vars.append(t.val) D.vars.append(t.val)
return get_reg(t.val) return get_reg(t.val)
@ -471,82 +479,36 @@ def do_class(t):
parent = None parent = None
if items[0].type == 'name': if items[0].type == 'name':
name = items[0].val name = items[0].val
parent = Token(tok.pos,'name','object')
else: else:
name = items[0].items[0].val name = items[0].items[0].val
parent = items[0].items[1].val parent = items[0].items[1]
kls = do(Token(t.pos,'dict',0,[])) kls = do(Token(t.pos,'dict',0,[]))
un_tmp(kls)
ts = _do_string(name) ts = _do_string(name)
code(GSET,ts,kls) code(GSET,ts,kls)
free_tmp(ts) #REG 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,[ free_tmp(do(Token(tok.pos,'call',None,[
Token(tok.pos,'get',None,[ Token(tok.pos,'name','setmeta'),
Token(tok.pos,'name',name), Token(tok.pos,'reg',kls),
Token(tok.pos,'string','__new__')]), parent])))
Token(tok.pos,'name','self')]))) #REG
for member in items[1].items:
if init: if member.type == 'def': do_def(member,kls)
tmp = get_tmp() elif member.type == 'symbol' and member.val == '=': do_classvar(member,kls)
t3 = _do_string('__init__') else: continue
code(GET,tmp,slf,t3)
t4 = get_tmp() free_reg(kls) #REG
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_classvar(t,r):
var = do_string(t.items[0])
val = do(t.items[1])
code(SET,r,var,val)
free_reg(var)
free_reg(val)
def do_while(t): def do_while(t):
items = t.items items = t.items
t = stack_tag() t = stack_tag()
@ -613,6 +575,7 @@ def do_try(t):
t = get_tag() t = get_tag()
setjmp(t,'except') setjmp(t,'except')
free_tmp(do(items[0])) #REG free_tmp(do(items[0])) #REG
code(SETJMP,0)
jump(t,'end') jump(t,'end')
tag(t,'except') tag(t,'except')
free_tmp(do(items[1].items[1])) #REG free_tmp(do(items[1].items[1])) #REG
@ -679,6 +642,7 @@ def do(t,r=None):
try: try:
if t.type in rmap: if t.type in rmap:
return rmap[t.type](t,r) return rmap[t.type](t,r)
#if r != None: free_reg(r) #REG
return fmap[t.type](t) return fmap[t.type](t)
except: except:
if D.error: raise if D.error: raise

View File

@ -1,6 +1,6 @@
import tokenize import tokenize, sys
from tokenize import Token from tokenize import Token
if '.' in str(1.0): if not "tinypy" in sys.version:
from boot import * from boot import *
def check(t,*vs): def check(t,*vs):
@ -29,6 +29,7 @@ class PData:
self.pos = 0 self.pos = 0
self.token = None self.token = None
self.stack = [] self.stack = []
self._terminal = 0
def init(self): def init(self):
global omap,dmap global omap,dmap
omap = cpy(base_dmap) omap = cpy(base_dmap)
@ -43,26 +44,34 @@ class PData:
else: else:
t = Token((0,0),'eof','eof') t = Token((0,0),'eof','eof')
self.token = do(t) self.token = do(t)
self._terminal += 1
if check(self.token,'nl','eof',';','dedent'):
self._terminal = 0
return t return t
def terminal(self):
if self._terminal > 1:
error('invalid statement',self.token)
def error(ctx,t): def error(ctx,t):
print t
tokenize.u_error(ctx,P.s,t.pos) tokenize.u_error(ctx,P.s,t.pos)
def nud(t): def nud(t):
#if 'nud' not in t: #if 'nud' not in t:
# error('no nud',t) #error('no nud',t)
return t.nud(t) return t.nud(t)
def led(t,left): def led(t,left):
#if 'led' not in t: #if 'led' not in t:
# error('no led',t) #error('no led',t)
return t.led(t,left) return t.led(t,left)
def get_lbp(t): def get_lbp(t):
#if 'lbp' not in t: #if 'lbp' not in t:
# error('no lbp',t) #error('no lbp',t)
return t.lbp return t.lbp
def get_items(t): def get_items(t):
#if 'items' not in t: #if 'items' not in t:
# error('no items',t) #error('no items',t)
return t.items return t.items
def expression(rbp): def expression(rbp):
@ -184,22 +193,29 @@ def dict_nud(t):
def advance(t=None): def advance(t=None):
return P.advance(t) return P.advance(t)
def iblock(items):
while check(P.token,'nl',';'): advance()
while True:
items.append(expression(0))
P.terminal()
while check(P.token,'nl',';'): advance()
if check(P.token,'dedent','eof'): break
def block(): def block():
items = [] items = []
tok = P.token tok = P.token
while check(P.token,'nl'): advance() if check(P.token,'nl'):
if check(P.token,'indent'): while check(P.token,'nl'): advance()
advance('indent') advance('indent')
while not check(P.token,'dedent'): iblock(items)
items.append(expression(0))
while check(P.token,';','nl'): advance()
advance('dedent') advance('dedent')
else: else:
items.append(expression(0)) items.append(expression(0))
while check(P.token,';'): while check(P.token,';'):
advance(';') advance(';')
items.append(expression(0)) items.append(expression(0))
P.terminal()
while check(P.token,'nl'): advance() while check(P.token,'nl'): advance()
if len(items) > 1: if len(items) > 1:
@ -286,12 +302,13 @@ def try_nud(t):
advance(':') advance(':')
b = block() b = block()
items.append(Token(tok.pos,'except','except',[a,b])) items.append(Token(tok.pos,'except','except',[a,b]))
if check(P.token,'else'): #commenting this out, i don't think this next bit is valid syntax??
tok = P.token #if check(P.token,'else'):
advance('else') #tok = P.token
advance(':') #advance('else')
b = block() #advance(':')
items.append(Token(tok.pos,'else','else',[b])) #b = block()
#items.append(Token(tok.pos,'else','else',[b]))
return t return t
def prefix_nud(t): def prefix_nud(t):
#bp = 70 #bp = 70
@ -370,8 +387,9 @@ def i_infix(bp,led,*vs):
for v in vs: base_dmap[v] = {'lbp':bp,'bp':bp,'led':led} for v in vs: base_dmap[v] = {'lbp':bp,'bp':bp,'led':led}
i_infix(40,infix_led,'<','>','<=','>=','!=','==') i_infix(40,infix_led,'<','>','<=','>=','!=','==')
i_infix(40,infix_is,'is','in') i_infix(40,infix_is,'is','in')
i_infix(10,infix_led,'+=','-=','*=','/=') i_infix(10,infix_led,'+=','-=','*=','/=', '&=', '|=', '^=')
i_infix(31,infix_led,'and','&') i_infix(32,infix_led,'and','&')
i_infix(31,infix_led,'^')
i_infix(30,infix_led,'or','|') i_infix(30,infix_led,'or','|')
i_infix(36,infix_led,'<<','>>') i_infix(36,infix_led,'<<','>>')
def i_terms(*vs): def i_terms(*vs):
@ -392,8 +410,8 @@ def do(t):
def do_module(): def do_module():
tok = P.token tok = P.token
items = [] items = []
while not check(P.token,'eof'): iblock(items)
items.append(block()) advance('eof')
if len(items) > 1: if len(items) > 1:
return Token(tok.pos,'statements',';',items) return Token(tok.pos,'statements',';',items)
return items.pop() return items.pop()

View File

@ -1,5 +1,5 @@
print("Starting py2bc") import sys
if not (str(1.0) == "1"): if not "tinypy" in sys.version:
from boot import * from boot import *
import tokenize,parse,encode import tokenize,parse,encode
@ -27,6 +27,8 @@ def _import(name):
MODULES[name] = g MODULES[name] = g
exec(code,g) exec(code,g)
return g return g
def _init(): def _init():
BUILTINS['compile'] = _compile BUILTINS['compile'] = _compile
BUILTINS['import'] = _import BUILTINS['import'] = _import
@ -51,3 +53,10 @@ def main(src,dest):
if __name__ == '__main__': if __name__ == '__main__':
main(ARGV[1],ARGV[2]) main(ARGV[1],ARGV[2])
main(ARGV[1],ARGV[2])
main(ARGV[1],ARGV[2])
main(ARGV[1],ARGV[2])
main(ARGV[1],ARGV[2])
main(ARGV[1],ARGV[2])
main(ARGV[1],ARGV[2])
main(ARGV[1],ARGV[2])

View File

@ -1,7 +1,9 @@
# figure out if we're in python or tinypy (tinypy displays "1.0" as "1") import sys
is_tinypy = (str(1.0) == "1") is_tinypy = "tinypy" in sys.version
if not is_tinypy: if not is_tinypy:
from boot import * from boot import *
import asm
import disasm
################################################################################ ################################################################################
RM = 'rm -f ' RM = 'rm -f '
@ -11,9 +13,10 @@ TMP = 'tmp.txt'
if '-mingw32' in ARGV or "-win" in ARGV: if '-mingw32' in ARGV or "-win" in ARGV:
RM = 'del ' RM = 'del '
VM = 'vm ' VM = 'vm '
TINYPY = 'tinypy ' TINYPY = '..\\tinypy '
TMP = 'tmp.txt' TMP = 'tmp.txt'
#TMP = 'stdout.txt' #TMP = 'stdout.txt'
SANDBOX = '-sandbox' in ARGV
def system_rm(fname): def system_rm(fname):
system(RM+fname) system(RM+fname)
@ -84,6 +87,17 @@ def t_parse(s,ex=''):
#print(s); print(ex); print(r) #print(s); print(ex); print(r)
assert(r==ex) assert(r==ex)
def t_unparse(s):
import tokenize, parse
ok = False
try:
tokens = tokenize.tokenize(s)
tree = parse.parse(s,tokens)
except:
ok = True
assert(ok == True)
if __name__ == '__main__': if __name__ == '__main__':
t_parse('2+4*3', '(+ 2 (* 4 3))') t_parse('2+4*3', '(+ 2 (* 4 3))')
t_parse('4*(2+3)', '(* 4 (+ 2 3))') t_parse('4*(2+3)', '(* 4 (+ 2 3))')
@ -166,6 +180,36 @@ if __name__ == '__main__':
t_parse('return\nx','(; return x)') t_parse('return\nx','(; return x)')
t_parse('"""test"""','test') t_parse('"""test"""','test')
t_parse('return a,b','(return (, a b))') t_parse('return a,b','(return (, a b))')
# this should throw an error - bug #26
t_unparse("""
while 1:
pass
""")
# test cases for python 2.x print statements - bug #17
# since this is python 2.x syntax it should output an syntax Exception
# mini-block style
t_unparse("""
def x(): print "OK"
""")
# block level
t_unparse("""
def x():
print "OK"
""")
# module level
t_unparse("""
print "OK"
""")
################################################################################ ################################################################################
@ -192,6 +236,7 @@ def t_render(ss,ex,exact=True):
cmd = VM + fname + " > tmp.txt" cmd = VM + fname + " > tmp.txt"
system(cmd) system(cmd)
res = load(TMP).strip() res = load(TMP).strip()
#print(ss,ex,res) #print(ss,ex,res)
if exact: if exact:
if res != ex: showerror(cmd, ss, ex, res) if res != ex: showerror(cmd, ss, ex, res)
@ -199,6 +244,18 @@ def t_render(ss,ex,exact=True):
else: else:
if ex not in res: showerror(cmd, ss, ex, res) if ex not in res: showerror(cmd, ss, ex, res)
assert(ex in res) assert(ex in res)
def t_unrender(s):
import tokenize, parse, encode
ok = False
try:
tokens = tokenize.tokenize(s)
t = parse.parse(s,tokens)
r = encode.encode('tmp.tpc',s,t)
except:
ok = True
assert(ok == True)
def test_range(): def test_range():
t_render("""print(str(range(4))[:5])""","<list") t_render("""print(str(range(4))[:5])""","<list")
@ -249,6 +306,14 @@ if __name__ == '__main__':
t_render('print(234)',"234") t_render('print(234)',"234")
t_render('a=3\nprint(a)',"3") t_render('a=3\nprint(a)',"3")
t_render('print(2+3)',"5") t_render('print(2+3)',"5")
t_render('print(4|1)',"5")
t_render('print(5&7)',"5")
t_render('print(2^7)',"5")
t_render('print(7^2&2)',"5")
t_render('print(7^2|4)',"5")
t_render('x=4\nx|=1\nprint(x)',"5")
t_render('x=5\nx&=7\nprint(x)',"5")
t_render('x=2\nx^=7\nprint(x)',"5")
t_render(""" t_render("""
x = 2 x = 2
x += 3 x += 3
@ -442,13 +507,6 @@ fnc()
""" """
,"OK") ,"OK")
t_render("""
class C:
def __init__(self,data): self.data = data
def print(self): print(self.data)
C("OK").print()
"""
,"OK")
t_render(""" t_render("""
x = [v*v for v in range(0,5)] x = [v*v for v in range(0,5)]
@ -493,12 +551,12 @@ print(x.a+y.a)
x = {} x = {}
y = x['x'] y = x['x']
""" """
,'KeyError',0) ,'KeyError', False)
t_render(""" t_render("""
x = [] x = []
y = x[1] y = x[1]
""" """
,'KeyError',0) ,'KeyError', False)
t_render("""print("O"+"K")""","OK") t_render("""print("O"+"K")""","OK")
t_render("""print("-".join(["O","K"]))""","O-K") t_render("""print("-".join(["O","K"]))""","O-K")
t_render("""print("OK-OK".split("-")[1])""","OK") t_render("""print("OK-OK".split("-")[1])""","OK")
@ -535,7 +593,8 @@ test('O')
t_render("""a,b,d = [0],0,'OK'; print(d)""","OK") t_render("""a,b,d = [0],0,'OK'; print(d)""","OK")
t_render(""" t_render("""
def test(): raise def test():
raise
try: try:
test() test()
except: except:
@ -548,7 +607,7 @@ except:
t_render(""" t_render("""
def test(a,b): def test(a,b):
print a+b[2] print (a+b[2])
test(1,3) test(1,3)
""","Exception",False) ""","Exception",False)
@ -581,22 +640,6 @@ test()
print(x) print(x)
""","OK") ""","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("print(len([1,2,3]))","3")
t_render('if not "?" in "xyz": print("OK")',"OK") t_render('if not "?" in "xyz": print("OK")',"OK")
@ -634,30 +677,8 @@ def test(x,y): print(x); return y
test('a',1) or test('b',1) and test('c',0) test('a',1) or test('b',1) and test('c',0)
""","a") ""","a")
t_render("def test(): print('OK')\n{'__call__':test}()","OK") #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(""" t_render("""
def test(): def test():
@ -678,7 +699,7 @@ test()
t_render("""x=(1,3);print({x:'OK'}[x])""","OK") 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("""x=(1,3);y=(1,3);print({x:'OK'}[y])""","OK")
t_render("""print({(1,3):'OK'}[(1,3)])""","OK") t_render("""print({(1,3):'OK'}[(1,3)])""","OK")
t_render("def test(): test()\ntest()","Exception",0) t_render("def test(): test()\ntest()","Exception", False)
t_render("x = []; x.append(x); print(x<x)","0"); t_render("x = []; x.append(x); print(x<x)","0");
t_render("x = []; x.append(x); print({x:'OK'}[x])","OK") t_render("x = []; x.append(x); print({x:'OK'}[x])","OK")
#t_render("print(float(str(4294967296))==float('4294967296'))","1") #t_render("print(float(str(4294967296))==float('4294967296'))","1")
@ -718,6 +739,397 @@ print(test()['x'])
""" """
,"OK") ,"OK")
t_render("""
def get(self,k):
return k+"K"
v = object()
v.__get__ = bind(get,v)
print(v.O)
""",
"OK")
t_render("""
def set(self,k,v):
self = getraw(self)
self[k] = v + "K"
v = object()
v.__set__ = bind(set,v)
v.x = "O"
print(v.x)
""",
"OK")
t_render("""
def call(self,x):
print(x)
v = object()
v.__call__ = bind(call,v)
v("OK")
"""
,"OK")
#a REG related test
t_render("""
def test():
init = True
if init and True:
pass
print("OK")
""","OK")
meta_objs_init = """
def my_new(klass,*p):
self = object()
setmeta(self,klass)
self.__init__(*p)
return self
def A_init(self,v):
if v: print("A_init")
def A_test1(self):
print("A_test1")
def A_test2(self):
print("A_test2")
A = {'__new__':my_new,'__init__':A_init,'test1':A_test1,'test2':A_test2}
def B_init(self,v):
if v: print("B_init")
def B_test2(self):
print("B_test2")
B = {'__init__':B_init,'test2':B_test2}
setmeta(B,A)
"""
t_render(meta_objs_init+"""A(True)""","A_init")
t_render(meta_objs_init+"""A(False).test1()""","A_test1")
t_render(meta_objs_init+"""A(False).test2()""","A_test2")
t_render(meta_objs_init+"""B(True)""","B_init")
t_render(meta_objs_init+"""B(False).test1()""","A_test1")
t_render(meta_objs_init+"""B(False).test2()""","B_test2")
#various class construct use tests
t_render("""
class C:
def __init__(self,data): self.data = data
def print(self): print(self.data)
C("OK").print()
"""
,"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("""
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")
#test that you can make a callable object
t_render("""
class Test:
def __init__(self,v):
self.value = v
def __call__(self):
print(self.value)
x = Test('OK')
x()
""","OK")
#test that you can use a __get__
t_render("""
class Test:
def __get__(self,k):
return k+"K"
x = Test()
print(x.O)
""","OK")
#test that you can use __set__
t_render("""
class Test:
def __set__(self,k,v):
getraw(self)[k] = "O"+v
x = Test()
x.v = "K"
print(x.v)
""","OK")
#test that exceptions are cleared after they are caught
#and not repeated
t_render("""
def test():
try:
pass
except:
pass
print("OK")
raise
try:
test()
except:
pass
""","OK")
#check that missing attributes throw an error
t_render("""
class A: pass
try:
A().x
except:
print('OK')
""","OK")
#check that a changed attribute gets changed
t_render("""
class A:
def x(self): pass
a = A()
a.x = "OK"
print(a.x)
""","OK")
#test that you can use a __get__ gets inherited
t_render("""
class A:
def __get__(self,k):
return k+"K"
class B(A):
pass
x = B()
print(x.O)
""","OK")
#test that meta methods aren't called on non-objects
t_render("""
def get(): pass
x = {"__get__":get}
try:
z = x.y
except:
print("OK")
""","OK")
#test that meta stuff is inheritited in dicts
t_render("""
x = {1:"O"}
y = {2:"K"}
setmeta(y,x)
print(y[1]+y[2])
""","OK")
#test that meta stuff doesn't change into methods in dicts
t_render("""
def get(k): return k
x = {"get":get}
print(x.get("OK"))
""","OK")
#tests issue 14: string.index() should give an exception if substring not found
t_render("""
try:
"test-".index("=")
except:
print("OK")
""","OK")
#issue 19: test that multiplying a string with a negative value returns an empty string
t_render("""
foo = "abc" * -1
print(foo)
""", "")
#issue 18: tests that strings containing NUL chars are printed correctly
t_render("""
foo = "abc" + chr(0) + "d"
print(foo)
""", "abc" + chr(0) + "d")
#issue 18 (related): tests that "".strip() treats strings containing NUL chars correctly
t_render("""
foo = "abc" + chr(0) + "d\n"
print(foo.strip())
""", "abc" + chr(0) + "d")
#test that class variables work as expected
t_render("""
class A:
foo = 42
s = str(A.foo)
A.foo += 1
s += str(A.foo)
print(s)
""", "4243")
#check that class variables are not leaked to the global scope
t_render("""
class A:
foo = 42
print(foo)
""", "KeyError", False)
#test that class variables can correctly be accessed by a subclass
t_render("""
class A:
foo = "OK"
class B(A):
pass
print(B.foo)
""", "OK")
#test that class variables can be accessed from instances
t_render("""
class A:
foo = "OK"
o = A()
print(o.foo)
""", "OK")
#test case for possible register allocation bug #22
t_render("""
x = [1, 2, 3]
for i in x:
if i != 0 and i:
y = "OK"
print(y)
""","OK")
#test that sandbox() raises an exception when the time limit is passed
if SANDBOX:
t_render("""
sandbox(1, False)
while True:
pass
""", "SandboxError", False)
#test that calling sandbox() removes the sandbox builtin
if SANDBOX:
t_render("""
sandbox(500, False)
try:
sandbox(200)
except:
print("OK")
""", "OK")
#test that sandbox() raises an exception when the memory limit is passed
if SANDBOX:
t_render("""
sandbox(False, 1)
a = 42
""", "SandboxError", False)
#test that circular inheritance doesn't cause an infinite lookup chain
t_render("""
class A:
pass
class B:
pass
setmeta(A, B)
setmeta(B, A)
foo = A()
print("OK")
""", "tp_lookup",False)
#tests issue #20: test that string multiplication is commutative
t_render("""
foo = "O"
bar = "K"
print(3 * foo, bar * 3)
""", "OOO KKK")
#test issue #27: that the __main__ module doesn't get GC'd
t_render("""
MODULES["__main__"] = None
for n in range(0,50000):
x = [n]
print("OK")
""","OK")
#test case for UnboundLocalError - bug #16
t_unrender("""
def foo():
print(v)
v = "ERROR"
""")
#test for segfault on large split
t_render("""
x = " ".join([str(n) for n in range(0,50000)])
y = x.split("1")
print("OK")
""","OK")
#test for Issue 42: 'not' operator only works for numbers,
#not dicts, lists, or strings
#Reported by kiwidrew, Apr 08, 2009
#see also: http://code.google.com/p/tinypy/issues/detail?id=42
t_render("""
if not None:
print('OK')
""", "OK")
t_render("""
n = 0
if not n:
print('OK')
""","OK")
t_render("""
d = {}
if not d:
print('OK')
""","OK")
t_render("""
l = []
if not l:
print('OK')
""","OK")
t_render("""
s = ''
if not s:
print('OK')
""","OK")
################################################################################ ################################################################################
def t_boot(ss,ex,exact=True): def t_boot(ss,ex,exact=True):
@ -730,9 +1142,10 @@ def t_boot(ss,ex,exact=True):
save(fname,s) save(fname,s)
n += 1 n += 1
system_rm('tmp.txt') system_rm('tmp.txt')
system(TINYPY+fname+' > tmp.txt') #system(TINYPY+fname+' > tmp.txt')
system("../build/tinypy "+fname+' > tmp.txt')
res = load(TMP).strip() res = load(TMP).strip()
#print(ss,ex,res) print(ss,ex,res)
if exact: assert(res == ex) if exact: assert(res == ex)
else: assert(ex in res) else: assert(ex in res)
@ -744,7 +1157,300 @@ try:
except: except:
pass pass
def t_api(ss_py,ss,ex):
if not '-linux' in ARGV:
return
#first verify that the python code produces the result
t_render(ss_py,ex)
#then verify that the C code does ...
fname = "tmp.c"
system_rm("tmp.c")
system_rm("tmp")
system_rm(TMP)
save(fname,ss)
system("gcc tmp.c -Wall -g -lm -o tmp")
cmd = "./tmp > "+TMP
system(cmd)
res = load(TMP).strip()
if res != ex: showerror(cmd, ss, ex, res)
assert(res == ex)
if is_boot == True and __name__ == '__main__': if is_boot == True and __name__ == '__main__':
print("# t_boot") print("# t_boot")
t_boot(["def test(): print('OK')","import tmp1; tmp1.test()"],"OK") t_boot(["def test(): print('OK')","import tmp1; tmp1.test()"],"OK")
print("# t_api")
# all t_api examples include a python equivalent
# also include a brief explanation of the point
# of the example
# just a "hello world" style example
t_api("""
print ("OK")
""","""
#include "tp.c"
int main(int argc, char *argv[]) {
tp_vm *tp = tp_init(argc,argv);
tp_params_v(tp,1,tp_string("OK"));
tp_print(tp);
tp_deinit(tp);
return(0);
}
""",
"OK")
# how to create a c function and call it
t_api("""
def test(v):
print(v)
test("OK")
""","""
#include "tp.c"
tp_obj test(TP) {
tp_obj v = TP_OBJ();
tp_params_v(tp,1,v);
tp_print(tp);
return tp_None;
}
int main(int argc, char *argv[]) {
tp_vm *tp = tp_init(argc,argv);
tp_obj fnc = tp_fnc(tp,test);
tp_call(tp,fnc,tp_params_v(tp,1,tp_string("OK")));
tp_deinit(tp);
return(0);
}
""",
"OK")
# how to create a simple class
t_api("""
class A:
def __init__(self,value):
self.value = value
def test(self):
print(self.value)
A("OK").test()
""","""
#include "tp.c"
tp_obj A_init(TP) {
tp_obj self = TP_TYPE(TP_DICT);
tp_obj v = TP_OBJ();
tp_set(tp,self,tp_string("value"),v);
return tp_None;
}
tp_obj A_test(TP) {
tp_obj self = TP_TYPE(TP_DICT);
tp_obj v = tp_get(tp,self,tp_string("value"));
tp_params_v(tp,1,v);
tp_print(tp);
return tp_None;
}
int main(int argc, char *argv[]) {
tp_vm *tp = tp_init(argc,argv);
/* create our class */
tp_obj tmp;
tp_obj A = tp_class(tp);
tp_set(tp,A,tp_string("__init__"),tp_fnc(tp,A_init));
tp_set(tp,A,tp_string("test"),tp_fnc(tp,A_test));
/* instantiate it and call test */
tmp = tp_call(tp,A,tp_params_v(tp,1,tp_string("OK")));
tp_call(tp,tp_get(tp,tmp,tp_string("test")),tp_params_v(tp,0));
tp_deinit(tp);
return(0);
}
""",
"OK")
################################################################################
def unformat(x):
x = x.split(' ')
r = []
for i in x:
if i != ':':
if i:
r.append(i)
return " ".join(r)
def t_asm(ass, ex, exact=True,check_dis=True):
ass = ass.strip()
bc = asm.assemble(ass)
dis = disasm.disassemble(bc)
dis = unformat(dis)
if check_dis and dis != ass:
print (ass)
print (dis)
assert(dis == ass)
fname = "tmp.tpc"
system_rm(fname)
system_rm(TMP)
save(fname,bc)
cmd = VM + fname + " > " + TMP
system(cmd)
res = load("tmp.txt").strip()
if exact:
if ex != res:
print (ass)
print (ex)
print (res)
assert(ex == res)
else:
if ex not in res:
print (ass)
print (ex)
print (res)
assert(ex in res)
if is_boot == True and __name__ == '__main__':
print("# t_asm")
t_asm("""
NUMBER 0 0 0 42
DEBUG 0 0 0
EOF 0 0 0
""", "DEBUG: 0 42")
t_asm("""
STRING 0 0 1 "a"
NUMBER 1 0 0 41
GSET 0 1 0
STRING 2 0 1 "a"
GGET 1 2 0
NUMBER 2 0 0 1
ADD 1 1 2
GSET 0 1 0
STRING 2 0 5 "print"
GGET 1 2 0
STRING 3 0 1 "a"
GGET 2 3 0
PARAMS 0 2 1
CALL 0 1 0
EOF 0 0 0
""", "42")
t_asm("""
STRING 0 0 4 "str1"
STRING 1 0 3 "foo"
GSET 0 1 0
STRING 0 0 4 "str2"
STRING 1 0 3 "bar"
GSET 0 1 0
STRING 2 0 5 "print"
GGET 1 2 0
STRING 3 0 4 "str1"
GGET 2 3 0
STRING 4 0 4 "str2"
GGET 3 4 0
ADD 2 2 3
PARAMS 0 2 1
CALL 0 1 0
EOF 0 0 0
""", "foobar")
t_asm("""
STRING 0 0 3 "foo"
STRING 1 0 3 "bar"
NUMBER 2 0 0 1
IF 2 0 0
ADD 0 0 1
STRING 1 0 5 "print"
GGET 3 1 0
PARAMS 2 0 1
CALL 0 3 2
EOF 0 0 0
""", "foo");
t_asm("""
NUMBER 0 0 0 1
NUMBER 1 0 0 2
JUMP 0 0 2
ADD 0 0 1
DEBUG 0 0 0
EOF 0 0 0
""", "DEBUG: 0 1");
t_asm("""
STRING 0 0 3 "foo"
NUMBER 1 0 0 3
MUL 0 0 1
DEBUG 0 0 0
EOF 0 0 0
""", "DEBUG: 0 foofoofoo");
t_asm("""
NUMBER 0 0 0 1
NUMBER 0 0 0 42
LIST 0 0 2
GET 0 0 1
DEBUG 0 0 0
EOF 0 0 0
""", "DEBUG: 0 42");
t_asm("""
NUMBER 0 0 0 1
NUMBER 1 0 0 1
NUMBER 2 0 0 1
LIST 0 0 3
LEN 0 0 0
DEBUG 0 0 0
EOF 0 0 0
""", "DEBUG: 0 3");
t_asm("""
DEF 0 0 13
STRING 1 0 3 "foo"
NAME 1 0 0
STRING 3 0 5 "print"
GGET 2 3 0
STRING 3 0 3 "foo"
PARAMS 1 3 1
CALL 1 2 1
EOF 0 0 0
PARAMS 1 0 0
CALL 1 0 1
EOF 0 0 0
""", "foo");
#test that function definitions longer than the bytecode are properly sanitized
if SANDBOX:
t_asm("""
DEF 0 0 100
REGS 2 0 0
STRING 1 0 3 "foo"
NAME 1 0 0
PASS 0 0 0
EOF 0 0 0
""", "SandboxError", False)
#test that negative out of bounds jumps are sanitized
if SANDBOX:
t_asm("""
JUMP 0 127 255
EOF 0 0 0
""", "SandboxError", False)
#test that positive out of bounds jumps are sanitized
if SANDBOX:
t_asm("""
JUMP 0 128 0
EOF 0 0 0
""", "SandboxError", False)
#test that strings with boundaries beyond the end of the bytecode are properly sanitized
if SANDBOX:
t_asm("""
STRING 1 0 100 "foobar"
EOF 0 0 0
""", "SandboxError", False,False)

View File

@ -12,14 +12,14 @@ def u_error(ctx,s,i):
r += " "+" "*x+"^" +'\n' r += " "+" "*x+"^" +'\n'
raise 'error: '+ctx+'\n'+r raise 'error: '+ctx+'\n'+r
ISYMBOLS = '`-=[];,./~!@$%^&*()+{}:<>?' ISYMBOLS = '`-=[];,./~!@$%^&*()+{}:<>?|'
SYMBOLS = [ SYMBOLS = [
'def','class','yield','return','pass','and','or','not','in','import', 'def','class','yield','return','pass','and','or','not','in','import',
'is','while','break','for','continue','if','else','elif','try', 'is','while','break','for','continue','if','else','elif','try',
'except','raise','True','False','None','global','del','from', 'except','raise','True','False','None','global','del','from',
'-','+','*','**','/','%','<<','>>', '-','+','*','**','/','%','<<','>>',
'-=','+=','*=','/=','=','==','!=','<','>', '-=','+=','*=','/=','=','==','!=','<','>', '|=', '&=', '^=',
'<=','>=','[',']','{','}','(',')','.',':',',',';','&','|','!', '<=','>=','[',']','{','}','(',')','.',':',',',';','&','|','!', '^'
] ]
B_BEGIN,B_END = ['[','(','{'],[']',')','}'] B_BEGIN,B_END = ['[','(','{'],[']',')','}']
@ -35,13 +35,14 @@ def clean(s):
return s return s
def tokenize(s): def tokenize(s):
global T
s = clean(s) s = clean(s)
try: return do_tokenize(s) T,i,l = TData(),0,len(s)
try: return do_tokenize(s,i,l)
except: u_error('tokenize',s,T.f) except: u_error('tokenize',s,T.f)
def do_tokenize(s): def do_tokenize(s,i,l):
global T global T
T,i,l = TData(),0,len(s)
T.f = (T.y,i-T.yi+1) T.f = (T.y,i-T.yi+1)
while i < l: while i < l:
c = s[i]; T.f = (T.y,i-T.yi+1) c = s[i]; T.f = (T.y,i-T.yi+1)
@ -59,6 +60,8 @@ def do_tokenize(s):
else: u_error('tokenize',s,T.f) else: u_error('tokenize',s,T.f)
indent(0) indent(0)
r = T.res; T = None r = T.res; T = None
#for t in r:
#print (t.pos,t.type,t.val)
return r return r
def do_nl(s,i,l): def do_nl(s,i,l):
@ -88,7 +91,6 @@ def indent(v):
v = T.indent.pop() v = T.indent.pop()
T.add('dedent',v) T.add('dedent',v)
def do_symbol(s,i,l): def do_symbol(s,i,l):
symbols = [] symbols = []
v,f,i = s[i],i,i+1 v,f,i = s[i],i,i+1

View File

@ -1,169 +0,0 @@
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

@ -1,152 +0,0 @@
/* 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

@ -1,98 +0,0 @@
#ifndef NULL
#define NULL ((void*)0)
#endif
#pragma pack(push,1)
typedef struct
{
unsigned p00;
unsigned p04;
char *p08;
unsigned p12;
unsigned p16;
char p20;
char *p21;
} kol_struct70;
#pragma pack(pop)
#pragma pack(push,1)
typedef struct
{
unsigned p00;
char p04;
char p05[3];
unsigned p08;
unsigned p12;
unsigned p16;
unsigned p20;
unsigned p24;
unsigned p28;
unsigned long long p32;
unsigned p40;
} kol_struct_BDVK;
#pragma pack(pop)
#pragma pack(push,1)
typedef struct
{
char *name;
void *data;
} kol_struct_import;
#pragma pack(pop)
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

@ -1,133 +0,0 @@
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

@ -1,68 +0,0 @@
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

@ -1,274 +0,0 @@
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;
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);
}
}
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;
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

@ -1,165 +0,0 @@
#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

@ -1,21 +0,0 @@
import kolibri
def onshow():
print("Show window")
def onkey():
print("Key pressed")
def onbtn():
print("Button pressed")
kolibri.debug_print("Debug test line\n")
w = kolibri.window(10,10,400, 400, False)
w.on_show = onshow
w.on_key = onkey
w.on_button = onbtn
w.show()
print("running")
w.run()
print("Exit")

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,612 @@
/*
================================================================================
tinypy contains tinypy code licensed in a MIT format license. It also
contains some goodies grabbed from Python, so that license is included
as well.
================================================================================
The tinypy License
Copyright (c) 2008 Phil Hassey
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
================================================================================
PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2
--------------------------------------------
1. This LICENSE AGREEMENT is between the Python Software Foundation
("PSF"), and the Individual or Organization ("Licensee") accessing and
otherwise using this software ("Python") in source or binary form and
its associated documentation.
2. Subject to the terms and conditions of this License Agreement, PSF
hereby grants Licensee a nonexclusive, royalty-free, world-wide
license to reproduce, analyze, test, perform and/or display publicly,
prepare derivative works, distribute, and otherwise use Python
alone or in any derivative version, provided, however, that PSF's
License Agreement and PSF's notice of copyright, i.e., "Copyright (c)
2001, 2002, 2003, 2004, 2005, 2006, 2007 Python Software Foundation;
All Rights Reserved" are retained in Python alone or in any derivative
version prepared by Licensee.
3. In the event Licensee prepares a derivative work that is based on
or incorporates Python or any part thereof, and wants to make
the derivative work available to others as provided herein, then
Licensee hereby agrees to include in any such work a brief summary of
the changes made to Python.
4. PSF is making Python available to Licensee on an "AS IS"
basis. PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND
DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON WILL NOT
INFRINGE ANY THIRD PARTY RIGHTS.
5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON
FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS
A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON,
OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
6. This License Agreement will automatically terminate upon a material
breach of its terms and conditions.
7. Nothing in this License Agreement shall be deemed to create any
relationship of agency, partnership, or joint venture between PSF and
Licensee. This License Agreement does not grant permission to use PSF
trademarks or trade name in a trademark sense to endorse or promote
products or services of Licensee, or any third party.
8. By copying, installing or otherwise using Python, Licensee
agrees to be bound by the terms and conditions of this License
Agreement.
================================================================================
*/
#ifndef TINYPY_H
#define TINYPY_H
/* File: General
* Things defined in tp.h.
*/
#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>
#include <time.h>
#ifdef __GNUC__
#define tp_inline __inline__
#endif
#ifdef _MSC_VER
#ifdef NDEBUG
#define tp_inline __inline
#else
/* don't inline in debug builds (for easier debugging) */
#define tp_inline
#endif
#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;
int dtype;
} tp_dict_;
typedef struct tp_fnc_ {
int type;
struct _tp_fnc *info;
int ftype;
void *cfnc;
} tp_fnc_;
typedef struct tp_data_ {
int type;
struct _tp_data *info;
void *val;
int magic;
} tp_data_;
/* Type: tp_obj
* Tinypy's object representation.
*
* Every object in tinypy is of this type in the C API.
*
* Fields:
* type - This determines what kind of objects it is. It is either TP_NONE, in
* which case this is the none type and no other fields can be accessed.
* Or it has one of the values listed below, and the corresponding
* fields can be accessed.
* number - TP_NUMBER
* number.val - A double value with the numeric value.
* string - TP_STRING
* string.val - A pointer to the string data.
* string.len - Length in bytes of the string data.
* dict - TP_DICT
* list - TP_LIST
* fnc - TP_FNC
* data - TP_DATA
* data.val - The user-provided data pointer.
* data.magic - The user-provided magic number for identifying the data type.
*/
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;
int len;
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_obj meta;
} _tp_dict;
typedef struct _tp_fnc {
int gci;
tp_obj self;
tp_obj globals;
tp_obj code;
} _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_obj code;
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_EXTRA 2
/* #define TP_REGS_PER_FRAME 256*/
#define TP_REGS 16384
/* Type: tp_vm
* Representation of a tinypy virtual machine instance.
*
* A new tp_vm struct is created with <tp_init>, and will be passed to most
* tinypy functions as first parameter. It contains all the data associated
* with an instance of a tinypy virtual machine - so it is easy to have
* multiple instances running at the same time. When you want to free up all
* memory used by an instance, call <tp_deinit>.
*
* Fields:
* These fields are currently documented:
*
* builtins - A dictionary containing all builtin objects.
* modules - A dictionary with all loaded modules.
* params - A list of parameters for the current function call.
* frames - A list of all call frames.
* cur - The index of the currently executing call frame.
* frames[n].globals - A dictionary of global sybmols in callframe n.
*/
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;
#ifdef CPYTHON_MOD
jmp_buf nextexpr;
#endif
int jmp;
tp_obj ex;
char chars[256][2];
int cur;
/* gc */
_tp_list *white;
_tp_list *grey;
_tp_list *black;
int steps;
/* sandbox */
clock_t clocks;
double time_elapsed;
double time_limit;
unsigned long mem_limit;
unsigned long mem_used;
int mem_exceeded;
} tp_vm;
#define TP tp_vm *tp
typedef struct _tp_data {
int gci;
void (*free)(TP,tp_obj);
} _tp_data;
#define tp_True tp_number(1)
#define tp_False tp_number(0)
extern tp_obj tp_None;
#ifdef TP_SANDBOX
void *tp_malloc(TP, unsigned long);
void *tp_realloc(TP, void *, unsigned long);
void tp_free(TP, void *);
#else
#define tp_malloc(TP,x) calloc((x),1)
#define tp_realloc(TP,x,y) realloc(x,y)
#define tp_free(TP,x) free(x)
#endif
void tp_sandbox(TP, double, unsigned long);
void tp_time_update(TP);
void tp_mem_update(TP);
void tp_run(TP,int cur);
void tp_set(TP,tp_obj,tp_obj,tp_obj);
tp_obj tp_get(TP,tp_obj,tp_obj);
tp_obj tp_has(TP,tp_obj self, tp_obj k);
tp_obj tp_len(TP,tp_obj);
void tp_del(TP,tp_obj,tp_obj);
tp_obj tp_str(TP,tp_obj);
int tp_bool(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);
tp_obj tp_call(TP, tp_obj fnc, tp_obj params);
tp_obj tp_add(TP,tp_obj a, tp_obj b) ;
/* __func__ __VA_ARGS__ __FILE__ __LINE__ */
/* Function: tp_raise
* Macro to raise an exception.
*
* This macro will return from the current function returning "r". The
* remaining parameters are used to format the exception message.
*/
#define tp_raise_f(r,fmt,...) { \
_tp_raise(tp,tp_printf(tp,fmt,__VA_ARGS__)); \
return r; \
}
#define tp_raise(r,v) { \
_tp_raise(tp,v); \
return r; \
}
/* Function: tp_string
* Creates a new string object from a C string.
*
* Given a pointer to a C string, creates a tinypy object representing the
* same string.
*
* *Note* Only a reference to the string will be kept by tinypy, so make sure
* it does not go out of scope, and don't de-allocate it. Also be aware that
* tinypy will not delete the string for you. In many cases, it is best to
* use <tp_string_t> or <tp_string_slice> to create a string where tinypy
* manages storage for you.
*/
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;
}
#define TP_CSTR_LEN 256
#define TP_CSTR(v) ((tp_str(tp,(v))).string.val)
tp_inline static void tp_cstr(TP,tp_obj v, char *s, int l) {
if (v.type != TP_STRING) {
tp_raise(,tp_string("(tp_cstr) TypeError: value not a string"));
}
if (v.string.len >= l) {
tp_raise(,tp_string("(tp_cstr) TypeError: value too long"));
}
memset(s,0,l);
memcpy(s,v.string.val,v.string.len);
}
#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_string("(tp_type) TypeError: unexpected type")); }
return v;
}
#define TP_NO_LIMIT 0
#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_STR() (TP_TYPE(TP_STRING))
#define TP_DEFAULT(d) (tp->params.list.val->len?tp_get(tp,tp->params,tp_None):(d))
/* Macro: TP_LOOP
* Macro to iterate over all remaining arguments.
*
* If you have a function which takes a variable number of arguments, you can
* iterate through all remaining arguments for example like this:
*
* > tp_obj *my_func(tp_vm *tp)
* > {
* > // We retrieve the first argument like normal.
* > tp_obj first = TP_OBJ();
* > // Then we iterate over the remaining arguments.
* > tp_obj arg;
* > TP_LOOP(arg)
* > // do something with arg
* > TP_END
* > }
*/
#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)); }
/* Function: tp_number
* Creates a new numeric object.
*/
tp_inline static tp_obj tp_number(tp_num v) {
tp_obj val = {TP_NUMBER};
val.number.val = v;
return val;
}
tp_inline static void tp_echo(TP,tp_obj e) {
e = tp_str(tp,e);
fwrite(e.string.val,1,e.string.len,stdout);
}
/* Function: tp_string_n
* Creates a new string object from a partial C string.
*
* Like <tp_string>, but you specify how many bytes of the given C string to
* use for the string object. The *note* also applies for this function, as the
* string reference and length are kept, but no actual substring is stored.
*/
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
void _tp_list_realloc(TP, _tp_list *self,int len) ;
void _tp_list_set(TP,_tp_list *self,int k, tp_obj v, const char *error) ;
void _tp_list_free(TP, _tp_list *self) ;
tp_obj _tp_list_get(TP,_tp_list *self,int k,const char *error) ;
void _tp_list_insertx(TP,_tp_list *self, int n, tp_obj v) ;
void _tp_list_appendx(TP,_tp_list *self, tp_obj v) ;
void _tp_list_insert(TP,_tp_list *self, int n, tp_obj v) ;
void _tp_list_append(TP,_tp_list *self, tp_obj v) ;
tp_obj _tp_list_pop(TP,_tp_list *self, int n, const char *error) ;
int _tp_list_find(TP,_tp_list *self, tp_obj v) ;
tp_obj tp_index(TP) ;
_tp_list *_tp_list_new(TP) ;
tp_obj _tp_list_copy(TP, tp_obj rr) ;
tp_obj tp_append(TP) ;
tp_obj tp_pop(TP) ;
tp_obj tp_insert(TP) ;
tp_obj tp_extend(TP) ;
tp_obj tp_list_nt(TP) ;
tp_obj tp_list(TP) ;
tp_obj tp_list_n(TP,int n,tp_obj *argv) ;
int _tp_sort_cmp(tp_obj *a,tp_obj *b) ;
tp_obj tp_sort(TP) ;
int tp_lua_hash(void const *v,int l) ;
void _tp_dict_free(TP, _tp_dict *self) ;
int tp_hash(TP,tp_obj v) ;
void _tp_dict_hash_set(TP,_tp_dict *self, int hash, tp_obj k, tp_obj v) ;
void _tp_dict_tp_realloc(TP,_tp_dict *self,int len) ;
int _tp_dict_hash_find(TP,_tp_dict *self, int hash, tp_obj k) ;
int _tp_dict_find(TP,_tp_dict *self,tp_obj k) ;
void _tp_dict_setx(TP,_tp_dict *self,tp_obj k, tp_obj v) ;
void _tp_dict_set(TP,_tp_dict *self,tp_obj k, tp_obj v) ;
tp_obj _tp_dict_get(TP,_tp_dict *self,tp_obj k, const char *error) ;
void _tp_dict_del(TP,_tp_dict *self,tp_obj k, const char *error) ;
_tp_dict *_tp_dict_new(TP) ;
tp_obj _tp_dict_copy(TP,tp_obj rr) ;
int _tp_dict_next(TP,_tp_dict *self) ;
tp_obj tp_merge(TP) ;
tp_obj tp_dict(TP) ;
tp_obj tp_dict_n(TP,int n, tp_obj* argv) ;
tp_obj _tp_dcall(TP,tp_obj fnc(TP)) ;
tp_obj _tp_tcall(TP,tp_obj fnc) ;
tp_obj tp_fnc_new(TP,int t, void *v, tp_obj c,tp_obj s, tp_obj g) ;
tp_obj tp_def(TP,tp_obj code, tp_obj g) ;
tp_obj tp_fnc(TP,tp_obj v(TP)) ;
tp_obj tp_method(TP,tp_obj self,tp_obj v(TP)) ;
tp_obj tp_data(TP,int magic,void *v) ;
tp_obj tp_params(TP) ;
tp_obj tp_params_n(TP,int n, tp_obj argv[]) ;
tp_obj tp_params_v(TP,int n,...) ;
tp_obj tp_string_t(TP, int n) ;
tp_obj tp_string_copy(TP, const char *s, int n) ;
tp_obj tp_string_sub(TP, tp_obj s, int a, int b) ;
int _tp_str_index(tp_obj s, tp_obj k) ;
tp_obj tp_join(TP) ;
tp_obj tp_split(TP) ;
tp_obj tp_find(TP) ;
tp_obj tp_str_index(TP) ;
tp_obj tp_str2(TP) ;
tp_obj tp_chr(TP) ;
tp_obj tp_ord(TP) ;
tp_obj tp_strip(TP) ;
tp_obj tp_replace(TP) ;
tp_obj tp_print(TP) ;
tp_obj tp_bind(TP) ;
tp_obj tp_min(TP) ;
tp_obj tp_max(TP) ;
tp_obj tp_copy(TP) ;
tp_obj tp_len_(TP) ;
tp_obj tp_assert(TP) ;
tp_obj tp_range(TP) ;
tp_obj tp_system(TP) ;
tp_obj tp_istype(TP) ;
tp_obj tp_float(TP) ;
tp_obj tp_save(TP) ;
tp_obj tp_load(TP) ;
tp_obj tp_fpack(TP) ;
tp_obj tp_abs(TP) ;
tp_obj tp_int(TP) ;
tp_num _roundf(tp_num v) ;
tp_obj tp_round(TP) ;
tp_obj tp_exists(TP) ;
tp_obj tp_mtime(TP) ;
int _tp_lookup_(TP,tp_obj self, tp_obj k, tp_obj *meta, int depth) ;
int _tp_lookup(TP,tp_obj self, tp_obj k, tp_obj *meta) ;
tp_obj tp_setmeta(TP) ;
tp_obj tp_getmeta(TP) ;
tp_obj tp_object(TP) ;
tp_obj tp_object_new(TP) ;
tp_obj tp_object_call(TP) ;
tp_obj tp_getraw(TP) ;
tp_obj tp_class(TP) ;
tp_obj tp_builtins_bool(TP) ;
void tp_follow(TP,tp_obj v) ;
void tp_reset(TP) ;
void tp_gc_init(TP) ;
void tp_gc_deinit(TP) ;
void tp_delete(TP,tp_obj v) ;
void tp_collect(TP) ;
void _tp_gcinc(TP) ;
void tp_full(TP) ;
void tp_gcinc(TP) ;
tp_obj tp_iter(TP,tp_obj self, tp_obj k) ;
int tp_iget(TP,tp_obj *r, tp_obj self, tp_obj k) ;
tp_obj tp_mul(TP,tp_obj a, tp_obj b) ;
tp_obj tp_bitwise_not(TP, tp_obj a) ;
tp_vm *_tp_init(void) ;
void tp_deinit(TP) ;
void tp_frame(TP,tp_obj globals,tp_obj code,tp_obj *ret_dest) ;
void tp_print_stack(TP) ;
void tp_handle(TP) ;
void tp_return(TP, tp_obj v) ;
int tp_step(TP) ;
void _tp_run(TP,int cur) ;
tp_obj tp_ez_call(TP, const char *mod, const char *fnc, tp_obj params) ;
tp_obj _tp_import(TP, tp_obj fname, tp_obj name, tp_obj code) ;
tp_obj tp_import(TP, const char * fname, const char * name, void *codes, int len) ;
tp_obj tp_exec_(TP) ;
tp_obj tp_import_(TP) ;
void tp_builtins(TP) ;
void tp_args(TP,int argc, char *argv[]) ;
tp_obj tp_main(TP,char *fname, void *code, int len) ;
tp_obj tp_compile(TP, tp_obj text, tp_obj fname) ;
tp_obj tp_exec(TP, tp_obj code, tp_obj globals) ;
tp_obj tp_eval(TP, const char *text, tp_obj globals) ;
tp_vm *tp_init(int argc, char *argv[]) ;
void tp_compiler(TP) ;
tp_obj tp_sandbox_(TP) ;
void tp_bounds(TP, tp_code *cur, int n) ;
#endif

View File

@ -1,32 +0,0 @@
#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

@ -1,233 +0,0 @@
#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

@ -1,22 +1,24 @@
/* INCLUDE */ #include "tinypy.c"
#include "tp.c"
const char header[] = "TinyPy for KolibriOS"; extern void init_std_modules(TP);
int main(int argc, const char *argv[]) { int main(int argc, char *argv[]) {
/* INIT */ tp_vm *tp = tp_init(argc,argv);
tp_vm *tp = tp_init(argc, argv);
kolibri_init(tp); #ifdef CONIO
CONSOLE_INIT(header); console_load();
tp_call(tp,"py2bc","tinypy",tp_None); #endif
// con_printf("Done");
init_std_modules(tp);
tp_ez_call(tp,"py2bc","tinypy",tp_None);
tp_deinit(tp); tp_deinit(tp);
// Exit console #ifdef CONIO
con_exit(0); if(con_enabled==1){
con_exit(0);
}
#endif
// Exit program return(0);
return 0;
} }
/**/

View File

@ -1,380 +0,0 @@
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}, {"raw_input", tp_raw_input},
{"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

@ -1,9 +0,0 @@
#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);
}