Files
jaeger c27ead6711 tinypy: can now run from shell and use command line parameters.
git-svn-id: svn://kolibrios.org@2073 a494cfbc-eb01-0410-851d-a64ba20cac60
2011-08-18 21:08:16 +00:00

152 lines
5.7 KiB
Plaintext

Обзор интерпретатора TinyPy и заметки по его адаптации к работе в КолибриОС.
1. Что такое TinyPy и чем он хорош в плане портирования
TinyPy - интерпретатор Python-подобного языка, созданный Филом
Хэсси (Phil Hassey), отличающийся очень небольшими размерами: выбором опций
компиляции можно добиться размеров исполняемого модуля в пределах 64 килобайт.
При разработке приложений для Колибри в других операционных системах
доступен довольно широкий выбор кросс-компиляторов. Набор средств разработки в
самой Колибри до недавнего времени был ограничен FASM. Можно предположить, что
возможность создавать программы в самой системе на таком легкоизучаемом и
распространённом языке, как Python, повышает привлекательность системы для
пользователя, далёкого от программирования на ассемблере.
TinyPy оказался лёгок в портировании: значительная часть его написана на самом
Python, а остальная часть - на C, исходные тексты занимают чуть больше 200 Кб.
Для компиляции нужна только стандартная библиотека libc. Из неё используется
всего около полутора десятков функций (vsnprintf/vsprintf, malloc/memcpy/memmove/free,
fopen/fread/fwrite/fclose).
В итоге работа по портированию TinyPy состояла из следующих частей:
1. Написание Makefile для сборки компилятором GCC с использованием
menuetlibc.
2. Добавление в menuetlibc недостающих функций vsnprintf/vsprintf.
3. Подключение библиотеки Колибри для работы с консолью.
4. И конечно, отлов разнообразных мелких багов (как же без этого!).
2. Возможности TinyPy.
2.1. Типы данных.
Каждый объект в среде TinyPy представляется 16-байтовой структурой tp_obj.
Первые 4 байта занимает тип, и назначение последующих 12 байт зависит от него.
Доступны следующие типы: TP_NONE, TP_NUMBER, TP_STRING, TP_DICT, TP_LIST,
TP_FNC, TP_DATA.
TP_NONE - соответствует единственному объекту None. Больше про него сказать
нечего.
TP_NUMBER - число, хранится как float. Если число отличается от ближайшего
целого меньше, чем на 10^(-6), оно считается целым, и при печати выводится
как целое. Также к этому типу относятся логические True и False.
Поддерживаются арифметические операции +,-,*,/,%, битовые << и >>, логические
|, &.
Пример:
print(2+2*2, 7/3, (-7)%3, 1==True, 0==False)
Выводит:
6 2.333333 -1 1 1
Заметим сразу, что print является функцией (как в Python 3), то есть параметры
обязательно указывать в скобках.
TP_STRING - строка. Поддерживаются: проверка вхождения ("str1" in "str2"), срезы s[:b], s[a:b],
s[a:], функции len, index, join, split, find, strip, replace.
TP_DICT - словарь, он же ассоциативный массив. Поддерживается добавление
нового элемента и всех элементов другого словаря. Перебор по всем ключам и
удаление элементов пока не поддерживается. Словари также являются удобным способом
представления объектов, в частности, если d словарь, то записи d.key и
d['key'] равнозначны. В этом TinyPy немного напоминает JavaScript.
TP_LIST - список. Поддерживаются: перебор по элементам (for el in list),
функции len, append/appendx, extend, insert/insertx, pop, find, index, sort.
Также поддерживается функция range. reverse() пока не поддерживается.
TP_FNC - функция. Бывает 2 типов - обычная функция и метод, отличаются
порядком вызова.
TP_DATA - внутренние структуры TinyPy.
2. Возможности TinyPy в сравнении с "большим" Python
"what tinypy won't be:
- a full implementation of Python;
- totally compatible with Python"
"roadmap.txt", tinypy sources
Синтаксис языка TinyPy очень похож на Python, но многие существенные
возможности Python не поддерживаются:
- итераторы и сопрограмм;
- синтаксический "сахар" для объявления списков и словарей, наподобие
odd_squares = [a*a for a in range(100) if a%2];
- интерактивная консоль.
И конечно, не хватает основной силы Python - его стандартной библиотеки.
3. Расширение TinyPy.
Набор встроенных функций в TinyPy достаточно беден, но зато добавление новых
модулей достаточно просто. Рассмотрим создание модулей на самом TinyPy, на
C и на FASM.
3.1. Модули на TinyPy.
TinyPy поддерживает модульное программирование, создание модулей
принципиально ничем не отличается от Python. Пусть, у нас есть простая
программа из двух файлов:
Файл math.py:
def square(a):
return a*a
Файл prog.py:
import math
if __name__=="__main__":
math.square(12)
Вначале нужно скомпилировать модуль math.py в байт-код при помощи программы
py2bc.py, она работает как в Python, так и в TinyPy. Запускаем shell и выполняем команду
# tinypy py2bc.py math.py math.tpc
После этого можно запустить prog.py из TinyPy.
# tinypy prog.py
144
Замечание: синтаксис "from module import function" пока не поддерживается.
3.2 Модули на C.
Пример создания модулей на C можно посмотреть в каталоге modules/kolibri. Такие
модули статически линкуются с самим интерпретатором и, соответственно,
увеличивают его размер. Для снижения накладных расходов компоненты TinyPy
компилируются в один объектный модуль, а файлы исходных текстов включаются с
помощью директивы #include. Дополнительные модули могут компилироваться как в
отдельные объектные файлы, в этом случае нужно дописать их в Makefile, или
точно так же подключаться директивой include.
В модуле должна присутствовать функция инициализации обычно она называется
<modname>_init. Она вызывается в tpmain сразу после инициализации виртуальной
машины, создаёт словарь экспортируемых объектов и добавляет его в предопределённый словарь modules.
Чтобы определить TinyPy-функцию, нужно создать обычную функцию на C вида
tp_obj myfunc(tp_vm *tp);
3.3 Модули на FASM.
Модуль на FASM пишется аналогично, но всегда компилируется в отдельный
объектный файл. Пример можно посмотреть в каталоге fasm_modules. Модуль
kolibri_dbg экспортирует одну функцию debug_print, выводящую строку на доску
отладки.
4. Обзор модуля kolibri.
Продолжение следует.