mirror of
https://github.com/KolibriOS/kolibrios.git
synced 2024-12-25 16:16:50 +03:00
- 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:
parent
44a5c1b211
commit
b29cc6670d
@ -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
|
119
programs/develop/tinypy/examples/asteroid.py
Normal file
119
programs/develop/tinypy/examples/asteroid.py
Normal 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")
|
||||
|
@ -1,6 +1,6 @@
|
||||
# center: 10043
|
||||
import pygame
|
||||
if '.' in str(1.0):
|
||||
import pygame, sys
|
||||
if not "tinypy" in sys.version:
|
||||
import pygame.locals
|
||||
|
||||
SW,SH = 120,120
|
||||
|
1
programs/develop/tinypy/examples/net/ATTENTION.txt
Normal file
1
programs/develop/tinypy/examples/net/ATTENTION.txt
Normal file
@ -0,0 +1 @@
|
||||
While sockets are disabled these examples don't work!
|
13
programs/develop/tinypy/examples/rw_file.py
Normal file
13
programs/develop/tinypy/examples/rw_file.py
Normal 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
|
170
programs/develop/tinypy/examples/vines.py
Normal file
170
programs/develop/tinypy/examples/vines.py
Normal 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")
|
35
programs/develop/tinypy/examples/сlicker.py
Normal file
35
programs/develop/tinypy/examples/сlicker.py
Normal 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
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
@ -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);
|
||||
}
|
@ -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()
|
13
programs/develop/tinypy/std_modules/bitwise/bitwise.c
Normal file
13
programs/develop/tinypy/std_modules/bitwise/bitwise.c
Normal 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);
|
||||
}
|
||||
|
17
programs/develop/tinypy/std_modules/bitwise/init.c
Executable file
17
programs/develop/tinypy/std_modules/bitwise/init.c
Executable 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);
|
||||
}
|
@ -1,21 +1,15 @@
|
||||
#include <string.h>
|
||||
#include "tp.h"
|
||||
#include "tinypy.h"
|
||||
|
||||
extern tp_obj tp_fnc(TP,tp_obj v(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_string(char const *v);
|
||||
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))
|
||||
|
||||
#define GET_STR_ARG() TP_TYPE(TP_STRING).string.val
|
||||
|
||||
#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 char uint8_t;
|
||||
|
||||
#pragma pack(push, 1)
|
||||
typedef struct {
|
||||
uint32_t subfnc;
|
||||
uint32_t res1;
|
||||
@ -24,8 +18,10 @@ typedef struct {
|
||||
uint8_t *data;
|
||||
uint8_t res4;
|
||||
char *fn;
|
||||
}__attribute__((__packed__)) info_params_t;
|
||||
}info_params_t;
|
||||
#pragma pack(pop)
|
||||
|
||||
#pragma pack(push,1)
|
||||
typedef struct {
|
||||
uint32_t subfnc;
|
||||
uint32_t pos;
|
||||
@ -34,7 +30,8 @@ typedef struct {
|
||||
char* data;
|
||||
uint8_t res2;
|
||||
char* fn;
|
||||
} __attribute__((__packed__)) rw_params_t;
|
||||
}rw_params_t;
|
||||
#pragma pack(pop)
|
||||
|
||||
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;
|
||||
|
||||
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)
|
||||
return tp_None;
|
||||
@ -100,7 +97,7 @@ static tp_obj kolibri_write(TP)
|
||||
|
||||
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
|
||||
{
|
||||
@ -112,7 +109,7 @@ static tp_obj kolibri_write(TP)
|
||||
call70_rw((¶ms), status, cnt);
|
||||
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;
|
||||
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')
|
||||
{
|
||||
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
|
||||
{
|
||||
@ -162,7 +159,7 @@ static tp_obj kolibri_writelines(TP)
|
||||
|
||||
call70_rw((¶ms), status, cnt);
|
||||
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;
|
||||
}
|
||||
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)
|
||||
mode_obj = tp_string("r");
|
||||
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])
|
||||
{
|
||||
case 'w':
|
||||
call70((¶ms), 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;
|
||||
break;
|
||||
case 'a':
|
||||
@ -229,10 +226,10 @@ tp_obj kolibri_open(TP) {
|
||||
case 'r':
|
||||
break;
|
||||
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)
|
||||
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);
|
||||
tp_set(tp, obj, tp_string("name"), tp_string(fn));
|
||||
tp_set(tp, obj, tp_string("size"), tp_number(size));
|
32
programs/develop/tinypy/std_modules/ksys/init.c
Executable file
32
programs/develop/tinypy/std_modules/ksys/init.c
Executable 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);
|
||||
}
|
92
programs/develop/tinypy/std_modules/ksys/syscalls.c
Normal file
92
programs/develop/tinypy/std_modules/ksys/syscalls.c
Normal 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;
|
||||
}
|
@ -1,5 +1,4 @@
|
||||
#include "math.c"
|
||||
#include "../../tinypy/tp.h"
|
||||
|
||||
/*
|
||||
* init math module, namely, set its dictionary
|
@ -1,4 +1,6 @@
|
||||
#include <math.h>
|
||||
#include "tinypy.h"
|
||||
|
||||
#ifndef M_E
|
||||
#define M_E 2.7182818284590452354
|
||||
#endif
|
||||
@ -23,8 +25,8 @@
|
||||
errno = 0; \
|
||||
r = cfunc(x); \
|
||||
if (errno == EDOM || errno == ERANGE) { \
|
||||
tp_raise(tp_None, "%s(x): x=%f, " \
|
||||
"out of range", __func__, x); \
|
||||
tp_raise(tp_None, tp_printf(tp, "%s(x): x=%f " \
|
||||
"out of range", __func__, x)); \
|
||||
} \
|
||||
\
|
||||
return (tp_number(r)); \
|
||||
@ -46,8 +48,8 @@
|
||||
errno = 0; \
|
||||
r = cfunc(x, y); \
|
||||
if (errno == EDOM || errno == ERANGE) { \
|
||||
tp_raise(tp_None, "%s(x, y): x=%f,y=%f " \
|
||||
"out of range", __func__, x, y);\
|
||||
tp_raise(tp_None, tp_printf(tp, "%s(x, y): x=%f,y=%f " \
|
||||
"out of range", __func__, x, y)); \
|
||||
} \
|
||||
\
|
||||
return (tp_number(r)); \
|
||||
@ -185,8 +187,8 @@ static tp_obj math_frexp(TP) {
|
||||
errno = 0;
|
||||
r = frexp(x, &y);
|
||||
if (errno == EDOM || errno == ERANGE) {
|
||||
tp_raise(tp_None, "%s(x): x=%f, "
|
||||
"out of range", __func__, x);
|
||||
tp_raise(tp_None, tp_printf(tp, "%s(x): x=%f, "
|
||||
"out of range", __func__, x));
|
||||
}
|
||||
|
||||
_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)
|
||||
y = (double)b.number.val;
|
||||
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;
|
||||
num = log10(x);
|
||||
@ -251,8 +253,8 @@ static tp_obj math_log(TP) {
|
||||
return (tp_number(r));
|
||||
|
||||
excep:
|
||||
tp_raise(tp_None, "%s(x, y): x=%f,y=%f "
|
||||
"out of range", __func__, x, y);
|
||||
tp_raise(tp_None, tp_printf(tp, "%s(x, y): x=%f,y=%f "
|
||||
"out of range", __func__, x, y));
|
||||
}
|
||||
|
||||
/*
|
||||
@ -278,8 +280,8 @@ static tp_obj math_modf(TP) {
|
||||
errno = 0;
|
||||
r = modf(x, &y);
|
||||
if (errno == EDOM || errno == ERANGE) {
|
||||
tp_raise(tp_None, "%s(x): x=%f, "
|
||||
"out of range", __func__, x);
|
||||
tp_raise(tp_None, tp_printf(tp, "%s(x): x=%f, "
|
||||
"out of range", __func__, x));
|
||||
}
|
||||
|
||||
_tp_list_append(tp, rList.list.val, tp_number(r));
|
||||
@ -303,8 +305,8 @@ static tp_obj math_pow(TP) {
|
||||
errno = 0;
|
||||
r = pow(x, y);
|
||||
if (errno == EDOM || errno == ERANGE) {
|
||||
tp_raise(tp_None, "%s(x, y): x=%f,y=%f "
|
||||
"out of range", __func__, x, y);
|
||||
tp_raise(tp_None, tp_printf(tp, "%s(x, y): x=%f,y=%f "
|
||||
"out of range", __func__, x, y));
|
||||
}
|
||||
|
||||
return (tp_number(r));
|
||||
@ -362,4 +364,3 @@ TP_MATH_FUNC1(tan)
|
||||
* mathematically, tanh(x) = sinh(x) / cosh(x).
|
||||
*/
|
||||
TP_MATH_FUNC1(tanh)
|
||||
|
15
programs/develop/tinypy/std_modules/modules.c
Normal file
15
programs/develop/tinypy/std_modules/modules.c
Normal 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);
|
||||
}
|
@ -14,13 +14,13 @@ Uint32 pygame_list_to_color(TP,tp_obj clr,SDL_Surface *s) {
|
||||
#define PYGAME_TYPE_SURF 0x1001
|
||||
|
||||
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_Surface *pygame_obj_to_surf(TP,tp_obj self) {
|
||||
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;
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <errno.h>
|
||||
#include "tinypy.h"
|
||||
|
||||
#include <math.h>
|
||||
#ifndef M_E
|
@ -36,6 +36,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "regexpr.h"
|
||||
#include "tinypy.h"
|
||||
|
||||
/* The original code blithely assumed that sizeof(short) == 2. Not
|
||||
* always true. Original instances of "(short)x" were replaced by
|
@ -1,36 +1,32 @@
|
||||
NAME = tinypy
|
||||
NAME=tinypy
|
||||
CC = kos32-gcc
|
||||
LD = kos32-ld
|
||||
|
||||
SDK_DIR:= $(abspath ../../../../contrib/sdk)
|
||||
|
||||
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 \
|
||||
-mincoming-stack-boundary=2 -fno-builtin -fno-common
|
||||
SDL_DIR = $(SDK_DIR)/sources/SDL-1.2.2_newlib
|
||||
|
||||
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
|
||||
LIBPATH:= -L $(SDK_DIR)/lib -L /home/autobuild/tools/win32/mingw32/lib
|
||||
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 -L.
|
||||
|
||||
MODULES_DIR = $(abspath ../modules)
|
||||
STD_MODULES= ../std_modules/modules.o
|
||||
|
||||
OBJECTS = tpmain.o $(STD_MODULES)
|
||||
|
||||
MODULES_OBJ = $(MODULES_DIR)/kolibri/init.o \
|
||||
$(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)
|
||||
all:$(NAME)
|
||||
|
||||
$(NAME): $(OBJECTS)
|
||||
$(LD) $(LIBPATH) --subsystem native -o $@ $(OBJECTS) $(LDFLAGS) -n # -Map $(NAME).map
|
||||
objcopy $@ -O binary
|
||||
$(LD) $(LIBPATH) --subsystem native -o $@ $(OBJECTS) $(LDFLAGS) -n -Map $(NAME).map
|
||||
strip -S $(NAME)
|
||||
kos32-objcopy $@ -O binary
|
||||
kpack $@
|
||||
|
||||
%.o : %.c Makefile
|
||||
$(CC) -c $(INCLUDES) $(CFLAGS) -o $@ $<
|
||||
|
||||
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
34
programs/develop/tinypy/tinypy/bcgen.py
Normal file
34
programs/develop/tinypy/tinypy/bcgen.py
Normal 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)
|
@ -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);
|
||||
}
|
@ -1,35 +1,23 @@
|
||||
#include "kolibri.h"
|
||||
/*
|
||||
#define __stdcall __attribute__((stdcall))
|
||||
#define _cdecl __attribute__((cdecl))
|
||||
#define _stdcall __attribute__((stdcall))
|
||||
*/
|
||||
// Copyright (C) 2019-2021 Logaev Maxim (turbocat2001), GPLv3
|
||||
|
||||
#include <string.h>
|
||||
|
||||
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);
|
||||
int (* _cdecl con_printf)(const char* format,...);
|
||||
void (* _stdcall con_exit)(char bCloseWindow);
|
||||
void (* __stdcall con_gets)(char* str, int n);
|
||||
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* result;
|
||||
@ -51,18 +39,32 @@ void* kol_cofflib_procload (kol_struct_import *imp, char *name)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void kol_board_puts(char *s)
|
||||
{
|
||||
unsigned i;
|
||||
i = 0;
|
||||
while (*(s+i))
|
||||
{
|
||||
asm ("int $0x40"::"a"(63), "b"(1), "c"(*(s+i)));
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
void kol_exit()
|
||||
{
|
||||
asm ("int $0x40"::"a"(-1));
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
78
programs/develop/tinypy/tinypy/core/asm.py
Normal file
78
programs/develop/tinypy/tinypy/core/asm.py
Normal 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)
|
@ -1,6 +1,6 @@
|
||||
def _boot_init():
|
||||
global FTYPE
|
||||
f = open('tp.h','r').read()
|
||||
f = open('tinypy.h','r').read()
|
||||
FTYPE = 'f'
|
||||
if 'double tp_num' in f: FTYPE = 'd'
|
||||
import sys
|
175
programs/develop/tinypy/tinypy/core/build.py
Normal file
175
programs/develop/tinypy/tinypy/core/build.py
Normal 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()
|
99
programs/develop/tinypy/tinypy/core/disasm.py
Normal file
99
programs/develop/tinypy/tinypy/core/disasm.py
Normal 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)
|
@ -1,9 +1,9 @@
|
||||
import tokenize
|
||||
import tokenize, sys
|
||||
from tokenize import Token
|
||||
if '.' in str(1.0):
|
||||
if not "tinypy" in sys.version:
|
||||
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:
|
||||
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.error = False
|
||||
def begin(self,gbl=False):
|
||||
if len(self.stack): self.stack.append((self.vars,self.r2n,self.n2r,self._tmpi,self.mreg,self.snum,self._globals,self.lineno,self.globals,self.cregs,self.tmpc))
|
||||
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)
|
||||
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
|
||||
insert(self.cregs)
|
||||
def end(self):
|
||||
@ -25,10 +25,12 @@ class DState:
|
||||
# This next line forces the encoder to
|
||||
# throw an exception if any tmp regs
|
||||
# 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:
|
||||
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()
|
||||
|
||||
|
||||
@ -185,6 +187,12 @@ def imanage(orig,fnc):
|
||||
t = Token(orig.pos,'symbol','=',[items[0],orig])
|
||||
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):
|
||||
r = get_tmp(r)
|
||||
b,c = do(tb,r),do(tc)
|
||||
@ -192,21 +200,17 @@ def infix(i,tb,tc,r=None):
|
||||
if r != b: free_tmp(b)
|
||||
free_tmp(c)
|
||||
return r
|
||||
def ss_infix(ss,i,tb,tc,r=None):
|
||||
r = get_tmp(r)
|
||||
r2 = get_tmp()
|
||||
ss = _do_number(ss)
|
||||
t = get_tag()
|
||||
r = do(tb,r)
|
||||
code(EQ,r2,r,ss)
|
||||
code(IF,r2)
|
||||
jump(t,'else')
|
||||
jump(t,'end')
|
||||
tag(t,'else')
|
||||
r = do(tc,r)
|
||||
tag(t,'end')
|
||||
free_tmp(r2) #REG
|
||||
free_tmp(ss) #REG
|
||||
def logic_infix(op, tb, tc, _r=None):
|
||||
t = get_tag()
|
||||
r = do(tb, _r)
|
||||
if _r != r: free_tmp(_r) #REG
|
||||
if op == 'and': code(IF, r)
|
||||
elif op == 'or': code(IFN, r)
|
||||
jump(t, 'end')
|
||||
_r = r
|
||||
r = do(tc, _r)
|
||||
if _r != r: free_tmp(_r) #REG
|
||||
tag(t, 'end')
|
||||
return r
|
||||
|
||||
def _do_none(r=None):
|
||||
@ -216,13 +220,13 @@ def _do_none(r=None):
|
||||
|
||||
def do_symbol(t,r=None):
|
||||
sets = ['=']
|
||||
isets = ['+=','-=','*=','/=']
|
||||
isets = ['+=','-=','*=','/=', '|=', '&=', '^=']
|
||||
cmps = ['<','>','<=','>=','==','!=']
|
||||
metas = {
|
||||
'+':ADD,'*':MUL,'/':DIV,'**':POW,
|
||||
'-':SUB,'and':AND,'or':OR,
|
||||
'-':SUB,
|
||||
'%':MOD,'>>':RSH,'<<':LSH,
|
||||
'&':AND,'|':OR,
|
||||
'&':BITAND,'|':BITOR,'^':BITXOR,
|
||||
}
|
||||
if t.val == 'None': return _do_none(r)
|
||||
if t.val == 'True':
|
||||
@ -232,8 +236,7 @@ def do_symbol(t,r=None):
|
||||
items = t.items
|
||||
|
||||
if t.val in ['and','or']:
|
||||
ss = int(t.val == 'or')
|
||||
return ss_infix(ss,metas[t.val],items[0],items[1],r)
|
||||
return logic_infix(t.val, items[0], items[1], r)
|
||||
if t.val in isets:
|
||||
return imanage(t,do_symbol)
|
||||
if t.val == 'is':
|
||||
@ -241,7 +244,7 @@ def do_symbol(t,r=None):
|
||||
if t.val == 'isnot':
|
||||
return infix(CMP,items[0],items[1],r)
|
||||
if t.val == 'not':
|
||||
return infix(EQ,Token(t.pos,'number',0),items[0],r)
|
||||
return unary(NOT, items[0], r)
|
||||
if t.val == 'in':
|
||||
return infix(HAS,items[1],items[0],r)
|
||||
if t.val == 'notin':
|
||||
@ -406,6 +409,8 @@ def do_call(t,r=None):
|
||||
def do_name(t,r=None):
|
||||
if t.val in D.vars:
|
||||
return do_local(t,r)
|
||||
if t.val not in D.rglobals:
|
||||
D.rglobals.append(t.val)
|
||||
r = get_tmp(r)
|
||||
c = do_string(t)
|
||||
code(GGET,r,c)
|
||||
@ -413,6 +418,9 @@ def do_name(t,r=None):
|
||||
return r
|
||||
|
||||
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:
|
||||
D.vars.append(t.val)
|
||||
return get_reg(t.val)
|
||||
@ -471,82 +479,36 @@ def do_class(t):
|
||||
parent = None
|
||||
if items[0].type == 'name':
|
||||
name = items[0].val
|
||||
parent = Token(tok.pos,'name','object')
|
||||
else:
|
||||
name = items[0].items[0].val
|
||||
parent = items[0].items[1].val
|
||||
parent = items[0].items[1]
|
||||
|
||||
kls = do(Token(t.pos,'dict',0,[]))
|
||||
un_tmp(kls)
|
||||
ts = _do_string(name)
|
||||
code(GSET,ts,kls)
|
||||
free_tmp(ts) #REG
|
||||
|
||||
init,_new = False,[]
|
||||
if parent:
|
||||
_new.append(Token(t.pos,'call',None,[
|
||||
Token(t.pos,'get',None,[
|
||||
Token(t.pos,'name',parent),
|
||||
Token(t.pos,'string','__new__'),
|
||||
]),
|
||||
Token(t.pos,'name','self'),
|
||||
]))
|
||||
|
||||
for fc in items[1].items:
|
||||
if fc.type != 'def': continue
|
||||
fn = fc.items[0].val
|
||||
if fn == '__init__': init = True
|
||||
do_def(fc,kls)
|
||||
_new.append(Token(fc.pos,'symbol','=',[
|
||||
Token(fc.pos,'get',None,[
|
||||
Token(fc.pos,'name','self'),
|
||||
Token(fc.pos,'string',fn)]),
|
||||
Token(fc.pos,'call',None,[
|
||||
Token(fc.pos,'name','bind'),
|
||||
Token(fc.pos,'get',None,[
|
||||
Token(fc.pos,'name',name),
|
||||
Token(fc.pos,'string',fn)]),
|
||||
Token(fc.pos,'name','self')])
|
||||
]))
|
||||
|
||||
do_def(Token(t.pos,'def',None,[
|
||||
Token(t.pos,'name','__new__'),
|
||||
Token(t.pos,'list',None,[Token(t.pos,'name','self')]),
|
||||
Token(t.pos,'statements',None,_new)]),kls)
|
||||
|
||||
t = get_tag()
|
||||
rf = fnc(t,'end')
|
||||
D.begin()
|
||||
params = do_local(Token(tok.pos,'name','__params'))
|
||||
|
||||
slf = do_local(Token(tok.pos,'name','self'))
|
||||
code(DICT,slf,0,0)
|
||||
|
||||
|
||||
free_tmp(do(Token(tok.pos,'call',None,[
|
||||
Token(tok.pos,'get',None,[
|
||||
Token(tok.pos,'name',name),
|
||||
Token(tok.pos,'string','__new__')]),
|
||||
Token(tok.pos,'name','self')]))) #REG
|
||||
|
||||
if init:
|
||||
tmp = get_tmp()
|
||||
t3 = _do_string('__init__')
|
||||
code(GET,tmp,slf,t3)
|
||||
t4 = get_tmp()
|
||||
code(CALL,t4,tmp,params)
|
||||
free_tmp(tmp) #REG
|
||||
free_tmp(t3) #REG
|
||||
free_tmp(t4) #REG
|
||||
code(RETURN,slf)
|
||||
|
||||
D.end()
|
||||
tag(t,'end')
|
||||
ts = _do_string('__call__')
|
||||
code(SET,kls,ts,rf)
|
||||
free_tmp(kls) #REG
|
||||
free_tmp(ts) #REG
|
||||
|
||||
|
||||
|
||||
Token(tok.pos,'name','setmeta'),
|
||||
Token(tok.pos,'reg',kls),
|
||||
parent])))
|
||||
|
||||
for member in items[1].items:
|
||||
if member.type == 'def': do_def(member,kls)
|
||||
elif member.type == 'symbol' and member.val == '=': do_classvar(member,kls)
|
||||
else: continue
|
||||
|
||||
free_reg(kls) #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):
|
||||
items = t.items
|
||||
t = stack_tag()
|
||||
@ -613,6 +575,7 @@ def do_try(t):
|
||||
t = get_tag()
|
||||
setjmp(t,'except')
|
||||
free_tmp(do(items[0])) #REG
|
||||
code(SETJMP,0)
|
||||
jump(t,'end')
|
||||
tag(t,'except')
|
||||
free_tmp(do(items[1].items[1])) #REG
|
||||
@ -679,6 +642,7 @@ def do(t,r=None):
|
||||
try:
|
||||
if t.type in rmap:
|
||||
return rmap[t.type](t,r)
|
||||
#if r != None: free_reg(r) #REG
|
||||
return fmap[t.type](t)
|
||||
except:
|
||||
if D.error: raise
|
@ -1,6 +1,6 @@
|
||||
import tokenize
|
||||
import tokenize, sys
|
||||
from tokenize import Token
|
||||
if '.' in str(1.0):
|
||||
if not "tinypy" in sys.version:
|
||||
from boot import *
|
||||
|
||||
def check(t,*vs):
|
||||
@ -29,6 +29,7 @@ class PData:
|
||||
self.pos = 0
|
||||
self.token = None
|
||||
self.stack = []
|
||||
self._terminal = 0
|
||||
def init(self):
|
||||
global omap,dmap
|
||||
omap = cpy(base_dmap)
|
||||
@ -43,26 +44,34 @@ class PData:
|
||||
else:
|
||||
t = Token((0,0),'eof','eof')
|
||||
self.token = do(t)
|
||||
|
||||
self._terminal += 1
|
||||
if check(self.token,'nl','eof',';','dedent'):
|
||||
self._terminal = 0
|
||||
return t
|
||||
|
||||
def terminal(self):
|
||||
if self._terminal > 1:
|
||||
error('invalid statement',self.token)
|
||||
|
||||
def error(ctx,t):
|
||||
print t
|
||||
tokenize.u_error(ctx,P.s,t.pos)
|
||||
|
||||
def nud(t):
|
||||
#if 'nud' not in t:
|
||||
# error('no nud',t)
|
||||
#error('no nud',t)
|
||||
return t.nud(t)
|
||||
def led(t,left):
|
||||
#if 'led' not in t:
|
||||
# error('no led',t)
|
||||
#error('no led',t)
|
||||
return t.led(t,left)
|
||||
def get_lbp(t):
|
||||
#if 'lbp' not in t:
|
||||
# error('no lbp',t)
|
||||
#error('no lbp',t)
|
||||
return t.lbp
|
||||
def get_items(t):
|
||||
#if 'items' not in t:
|
||||
# error('no items',t)
|
||||
#error('no items',t)
|
||||
return t.items
|
||||
|
||||
def expression(rbp):
|
||||
@ -184,22 +193,29 @@ def dict_nud(t):
|
||||
def advance(t=None):
|
||||
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():
|
||||
items = []
|
||||
tok = P.token
|
||||
|
||||
while check(P.token,'nl'): advance()
|
||||
if check(P.token,'indent'):
|
||||
|
||||
if check(P.token,'nl'):
|
||||
while check(P.token,'nl'): advance()
|
||||
advance('indent')
|
||||
while not check(P.token,'dedent'):
|
||||
items.append(expression(0))
|
||||
while check(P.token,';','nl'): advance()
|
||||
iblock(items)
|
||||
advance('dedent')
|
||||
else:
|
||||
items.append(expression(0))
|
||||
while check(P.token,';'):
|
||||
advance(';')
|
||||
items.append(expression(0))
|
||||
P.terminal()
|
||||
while check(P.token,'nl'): advance()
|
||||
|
||||
if len(items) > 1:
|
||||
@ -286,12 +302,13 @@ def try_nud(t):
|
||||
advance(':')
|
||||
b = block()
|
||||
items.append(Token(tok.pos,'except','except',[a,b]))
|
||||
if check(P.token,'else'):
|
||||
tok = P.token
|
||||
advance('else')
|
||||
advance(':')
|
||||
b = block()
|
||||
items.append(Token(tok.pos,'else','else',[b]))
|
||||
#commenting this out, i don't think this next bit is valid syntax??
|
||||
#if check(P.token,'else'):
|
||||
#tok = P.token
|
||||
#advance('else')
|
||||
#advance(':')
|
||||
#b = block()
|
||||
#items.append(Token(tok.pos,'else','else',[b]))
|
||||
return t
|
||||
def prefix_nud(t):
|
||||
#bp = 70
|
||||
@ -370,8 +387,9 @@ def i_infix(bp,led,*vs):
|
||||
for v in vs: base_dmap[v] = {'lbp':bp,'bp':bp,'led':led}
|
||||
i_infix(40,infix_led,'<','>','<=','>=','!=','==')
|
||||
i_infix(40,infix_is,'is','in')
|
||||
i_infix(10,infix_led,'+=','-=','*=','/=')
|
||||
i_infix(31,infix_led,'and','&')
|
||||
i_infix(10,infix_led,'+=','-=','*=','/=', '&=', '|=', '^=')
|
||||
i_infix(32,infix_led,'and','&')
|
||||
i_infix(31,infix_led,'^')
|
||||
i_infix(30,infix_led,'or','|')
|
||||
i_infix(36,infix_led,'<<','>>')
|
||||
def i_terms(*vs):
|
||||
@ -392,8 +410,8 @@ def do(t):
|
||||
def do_module():
|
||||
tok = P.token
|
||||
items = []
|
||||
while not check(P.token,'eof'):
|
||||
items.append(block())
|
||||
iblock(items)
|
||||
advance('eof')
|
||||
if len(items) > 1:
|
||||
return Token(tok.pos,'statements',';',items)
|
||||
return items.pop()
|
@ -1,5 +1,5 @@
|
||||
print("Starting py2bc")
|
||||
if not (str(1.0) == "1"):
|
||||
import sys
|
||||
if not "tinypy" in sys.version:
|
||||
from boot import *
|
||||
|
||||
import tokenize,parse,encode
|
||||
@ -27,6 +27,8 @@ def _import(name):
|
||||
MODULES[name] = g
|
||||
exec(code,g)
|
||||
return g
|
||||
|
||||
|
||||
def _init():
|
||||
BUILTINS['compile'] = _compile
|
||||
BUILTINS['import'] = _import
|
||||
@ -51,3 +53,10 @@ def main(src,dest):
|
||||
|
||||
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])
|
@ -1,7 +1,9 @@
|
||||
# figure out if we're in python or tinypy (tinypy displays "1.0" as "1")
|
||||
is_tinypy = (str(1.0) == "1")
|
||||
import sys
|
||||
is_tinypy = "tinypy" in sys.version
|
||||
if not is_tinypy:
|
||||
from boot import *
|
||||
import asm
|
||||
import disasm
|
||||
|
||||
################################################################################
|
||||
RM = 'rm -f '
|
||||
@ -11,9 +13,10 @@ TMP = 'tmp.txt'
|
||||
if '-mingw32' in ARGV or "-win" in ARGV:
|
||||
RM = 'del '
|
||||
VM = 'vm '
|
||||
TINYPY = 'tinypy '
|
||||
TINYPY = '..\\tinypy '
|
||||
TMP = 'tmp.txt'
|
||||
#TMP = 'stdout.txt'
|
||||
SANDBOX = '-sandbox' in ARGV
|
||||
def system_rm(fname):
|
||||
system(RM+fname)
|
||||
|
||||
@ -84,6 +87,17 @@ def t_parse(s,ex=''):
|
||||
#print(s); print(ex); print(r)
|
||||
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__':
|
||||
t_parse('2+4*3', '(+ 2 (* 4 3))')
|
||||
t_parse('4*(2+3)', '(* 4 (+ 2 3))')
|
||||
@ -166,6 +180,36 @@ if __name__ == '__main__':
|
||||
t_parse('return\nx','(; return x)')
|
||||
t_parse('"""test"""','test')
|
||||
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"
|
||||
system(cmd)
|
||||
res = load(TMP).strip()
|
||||
|
||||
#print(ss,ex,res)
|
||||
if exact:
|
||||
if res != ex: showerror(cmd, ss, ex, res)
|
||||
@ -199,6 +244,18 @@ def t_render(ss,ex,exact=True):
|
||||
else:
|
||||
if ex not in res: showerror(cmd, ss, ex, 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():
|
||||
t_render("""print(str(range(4))[:5])""","<list")
|
||||
@ -249,6 +306,14 @@ if __name__ == '__main__':
|
||||
t_render('print(234)',"234")
|
||||
t_render('a=3\nprint(a)',"3")
|
||||
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("""
|
||||
x = 2
|
||||
x += 3
|
||||
@ -442,13 +507,6 @@ fnc()
|
||||
"""
|
||||
,"OK")
|
||||
|
||||
t_render("""
|
||||
class C:
|
||||
def __init__(self,data): self.data = data
|
||||
def print(self): print(self.data)
|
||||
C("OK").print()
|
||||
"""
|
||||
,"OK")
|
||||
|
||||
t_render("""
|
||||
x = [v*v for v in range(0,5)]
|
||||
@ -493,12 +551,12 @@ print(x.a+y.a)
|
||||
x = {}
|
||||
y = x['x']
|
||||
"""
|
||||
,'KeyError',0)
|
||||
,'KeyError', False)
|
||||
t_render("""
|
||||
x = []
|
||||
y = x[1]
|
||||
"""
|
||||
,'KeyError',0)
|
||||
,'KeyError', False)
|
||||
t_render("""print("O"+"K")""","OK")
|
||||
t_render("""print("-".join(["O","K"]))""","O-K")
|
||||
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("""
|
||||
def test(): raise
|
||||
def test():
|
||||
raise
|
||||
try:
|
||||
test()
|
||||
except:
|
||||
@ -548,7 +607,7 @@ except:
|
||||
|
||||
t_render("""
|
||||
def test(a,b):
|
||||
print a+b[2]
|
||||
print (a+b[2])
|
||||
test(1,3)
|
||||
""","Exception",False)
|
||||
|
||||
@ -581,22 +640,6 @@ test()
|
||||
print(x)
|
||||
""","OK")
|
||||
|
||||
t_render("""
|
||||
class X:
|
||||
pass
|
||||
y = X()
|
||||
print("OK")
|
||||
""","OK")
|
||||
|
||||
t_render("""
|
||||
class X: pass
|
||||
def test(): y = X()
|
||||
test()
|
||||
print("OK")
|
||||
""","OK")
|
||||
|
||||
t_render(["class X: pass\ndef test(): y = X()","import tmp1\ntmp1.test();print('OK')"],"OK")
|
||||
|
||||
t_render("print(len([1,2,3]))","3")
|
||||
|
||||
t_render('if not "?" in "xyz": print("OK")',"OK")
|
||||
@ -634,30 +677,8 @@ def test(x,y): print(x); return y
|
||||
test('a',1) or test('b',1) and test('c',0)
|
||||
""","a")
|
||||
|
||||
t_render("def test(): print('OK')\n{'__call__':test}()","OK")
|
||||
#t_render("def test(): print('OK')\n{'__call__':test}()","OK")
|
||||
|
||||
t_render("""
|
||||
class A:
|
||||
def __init__(self):
|
||||
self.a = 'O'
|
||||
self.b = 'x'
|
||||
def test(self):
|
||||
print("KO")
|
||||
class B(A):
|
||||
def __init__(self):
|
||||
A.__init__(self)
|
||||
self.b = 'K'
|
||||
def test(self):
|
||||
print(self.a+self.b)
|
||||
B().test()
|
||||
""","OK")
|
||||
|
||||
t_render("""
|
||||
class A:
|
||||
def test(self):
|
||||
print(self)
|
||||
A.test("OK")
|
||||
""","OK")
|
||||
|
||||
t_render("""
|
||||
def test():
|
||||
@ -678,7 +699,7 @@ test()
|
||||
t_render("""x=(1,3);print({x:'OK'}[x])""","OK")
|
||||
t_render("""x=(1,3);y=(1,3);print({x:'OK'}[y])""","OK")
|
||||
t_render("""print({(1,3):'OK'}[(1,3)])""","OK")
|
||||
t_render("def test(): test()\ntest()","Exception",0)
|
||||
t_render("def test(): test()\ntest()","Exception", False)
|
||||
t_render("x = []; x.append(x); print(x<x)","0");
|
||||
t_render("x = []; x.append(x); print({x:'OK'}[x])","OK")
|
||||
#t_render("print(float(str(4294967296))==float('4294967296'))","1")
|
||||
@ -718,6 +739,397 @@ print(test()['x'])
|
||||
"""
|
||||
,"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):
|
||||
@ -730,9 +1142,10 @@ def t_boot(ss,ex,exact=True):
|
||||
save(fname,s)
|
||||
n += 1
|
||||
system_rm('tmp.txt')
|
||||
system(TINYPY+fname+' > tmp.txt')
|
||||
#system(TINYPY+fname+' > tmp.txt')
|
||||
system("../build/tinypy "+fname+' > tmp.txt')
|
||||
res = load(TMP).strip()
|
||||
#print(ss,ex,res)
|
||||
print(ss,ex,res)
|
||||
if exact: assert(res == ex)
|
||||
else: assert(ex in res)
|
||||
|
||||
@ -744,7 +1157,300 @@ try:
|
||||
except:
|
||||
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__':
|
||||
print("# t_boot")
|
||||
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)
|
||||
|
@ -12,14 +12,14 @@ def u_error(ctx,s,i):
|
||||
r += " "+" "*x+"^" +'\n'
|
||||
raise 'error: '+ctx+'\n'+r
|
||||
|
||||
ISYMBOLS = '`-=[];,./~!@$%^&*()+{}:<>?'
|
||||
ISYMBOLS = '`-=[];,./~!@$%^&*()+{}:<>?|'
|
||||
SYMBOLS = [
|
||||
'def','class','yield','return','pass','and','or','not','in','import',
|
||||
'is','while','break','for','continue','if','else','elif','try',
|
||||
'except','raise','True','False','None','global','del','from',
|
||||
'-','+','*','**','/','%','<<','>>',
|
||||
'-=','+=','*=','/=','=','==','!=','<','>',
|
||||
'<=','>=','[',']','{','}','(',')','.',':',',',';','&','|','!',
|
||||
'-=','+=','*=','/=','=','==','!=','<','>', '|=', '&=', '^=',
|
||||
'<=','>=','[',']','{','}','(',')','.',':',',',';','&','|','!', '^'
|
||||
]
|
||||
B_BEGIN,B_END = ['[','(','{'],[']',')','}']
|
||||
|
||||
@ -35,13 +35,14 @@ def clean(s):
|
||||
return s
|
||||
|
||||
def tokenize(s):
|
||||
global T
|
||||
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)
|
||||
|
||||
def do_tokenize(s):
|
||||
def do_tokenize(s,i,l):
|
||||
global T
|
||||
T,i,l = TData(),0,len(s)
|
||||
T.f = (T.y,i-T.yi+1)
|
||||
while i < l:
|
||||
c = s[i]; T.f = (T.y,i-T.yi+1)
|
||||
@ -59,6 +60,8 @@ def do_tokenize(s):
|
||||
else: u_error('tokenize',s,T.f)
|
||||
indent(0)
|
||||
r = T.res; T = None
|
||||
#for t in r:
|
||||
#print (t.pos,t.type,t.val)
|
||||
return r
|
||||
|
||||
def do_nl(s,i,l):
|
||||
@ -88,7 +91,6 @@ def indent(v):
|
||||
v = T.indent.pop()
|
||||
T.add('dedent',v)
|
||||
|
||||
|
||||
def do_symbol(s,i,l):
|
||||
symbols = []
|
||||
v,f,i = s[i],i,i+1
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
/**/
|
||||
|
@ -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);
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
@ -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));
|
||||
|
||||
|
||||
/**/
|
@ -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);
|
||||
}
|
||||
|
@ -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")
|
2793
programs/develop/tinypy/tinypy/tinypy.c
Normal file
2793
programs/develop/tinypy/tinypy/tinypy.c
Normal file
File diff suppressed because it is too large
Load Diff
612
programs/develop/tinypy/tinypy/tinypy.h
Normal file
612
programs/develop/tinypy/tinypy/tinypy.h
Normal 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
|
@ -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
|
||||
|
||||
/**/
|
@ -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
|
@ -1,22 +1,24 @@
|
||||
/* INCLUDE */
|
||||
#include "tp.c"
|
||||
#include "tinypy.c"
|
||||
|
||||
const char header[] = "TinyPy for KolibriOS";
|
||||
extern void init_std_modules(TP);
|
||||
|
||||
int main(int argc, const char *argv[]) {
|
||||
/* INIT */
|
||||
tp_vm *tp = tp_init(argc, argv);
|
||||
kolibri_init(tp);
|
||||
CONSOLE_INIT(header);
|
||||
tp_call(tp,"py2bc","tinypy",tp_None);
|
||||
// con_printf("Done");
|
||||
int main(int argc, char *argv[]) {
|
||||
tp_vm *tp = tp_init(argc,argv);
|
||||
|
||||
#ifdef CONIO
|
||||
console_load();
|
||||
#endif
|
||||
|
||||
init_std_modules(tp);
|
||||
tp_ez_call(tp,"py2bc","tinypy",tp_None);
|
||||
tp_deinit(tp);
|
||||
|
||||
// Exit console
|
||||
con_exit(0);
|
||||
#ifdef CONIO
|
||||
if(con_enabled==1){
|
||||
con_exit(0);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Exit program
|
||||
return 0;
|
||||
return(0);
|
||||
}
|
||||
|
||||
/**/
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
/**/
|
@ -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);
|
||||
}
|
Loading…
Reference in New Issue
Block a user