Rev 2053 | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
2053 | jaeger | 1 | Обзор интерпретатора TinyPy и заметки по его адаптации к работе в КолибриОС. |
2 | |||
3 | 1. Что такое TinyPy и чем он хорош в плане портирования |
||
4 | |||
5 | TinyPy - интерпретатор Python-подобного языка, созданный Филом |
||
6 | Хэсси (Phil Hassey), отличающийся очень небольшими размерами: выбором опций |
||
7 | компиляции можно добиться размеров исполняемого модуля в пределах 64 килобайт. |
||
8 | |||
9 | При разработке приложений для Колибри в других операционных системах |
||
10 | доступен довольно широкий выбор кросс-компиляторов. Набор средств разработки в |
||
11 | самой Колибри до недавнего времени был ограничен FASM. Можно предположить, что |
||
12 | возможность создавать программы в самой системе на таком легкоизучаемом и |
||
13 | распространённом языке, как Python, повышает привлекательность системы для |
||
14 | пользователя, далёкого от программирования на ассемблере. |
||
15 | |||
16 | TinyPy оказался лёгок в портировании: значительная часть его написана на самом |
||
17 | Python, а остальная часть - на C, исходные тексты занимают чуть больше 200 Кб. |
||
18 | Для компиляции нужна только стандартная библиотека libc. Из неё используется |
||
19 | всего около полутора десятков функций (vsnprintf/vsprintf, malloc/memcpy/memmove/free, |
||
20 | fopen/fread/fwrite/fclose). |
||
21 | |||
22 | В итоге работа по портированию TinyPy состояла из следующих частей: |
||
23 | 1. Написание Makefile для сборки компилятором GCC с использованием |
||
24 | menuetlibc. |
||
25 | 2. Добавление в menuetlibc недостающих функций vsnprintf/vsprintf. |
||
26 | 3. Подключение библиотеки Колибри для работы с консолью. |
||
27 | 4. И конечно, отлов разнообразных мелких багов (как же без этого!). |
||
28 | |||
29 | 2. Возможности TinyPy. |
||
30 | |||
31 | 2.1. Типы данных. |
||
32 | |||
33 | Каждый объект в среде TinyPy представляется 16-байтовой структурой tp_obj. |
||
34 | Первые 4 байта занимает тип, и назначение последующих 12 байт зависит от него. |
||
35 | Доступны следующие типы: TP_NONE, TP_NUMBER, TP_STRING, TP_DICT, TP_LIST, |
||
36 | TP_FNC, TP_DATA. |
||
37 | |||
38 | TP_NONE - соответствует единственному объекту None. Больше про него сказать |
||
39 | нечего. |
||
40 | |||
41 | TP_NUMBER - число, хранится как float. Если число отличается от ближайшего |
||
42 | целого меньше, чем на 10^(-6), оно считается целым, и при печати выводится |
||
43 | как целое. Также к этому типу относятся логические True и False. |
||
44 | Поддерживаются арифметические операции +,-,*,/,%, битовые << и >>, логические |
||
45 | |, &. |
||
46 | |||
47 | Пример: |
||
48 | print(2+2*2, 7/3, (-7)%3, 1==True, 0==False) |
||
49 | |||
50 | Выводит: |
||
51 | 6 2.333333 -1 1 1 |
||
52 | |||
53 | Заметим сразу, что print является функцией (как в Python 3), то есть параметры |
||
54 | обязательно указывать в скобках. |
||
55 | |||
56 | TP_STRING - строка. Поддерживаются: проверка вхождения ("str1" in "str2"), срезы s[:b], s[a:b], |
||
57 | s[a:], функции len, index, join, split, find, strip, replace. |
||
58 | |||
59 | TP_DICT - словарь, он же ассоциативный массив. Поддерживается добавление |
||
60 | нового элемента и всех элементов другого словаря. Перебор по всем ключам и |
||
61 | удаление элементов пока не поддерживается. Словари также являются удобным способом |
||
62 | представления объектов, в частности, если d словарь, то записи d.key и |
||
63 | d['key'] равнозначны. В этом TinyPy немного напоминает JavaScript. |
||
64 | |||
65 | TP_LIST - список. Поддерживаются: перебор по элементам (for el in list), |
||
66 | функции len, append/appendx, extend, insert/insertx, pop, find, index, sort. |
||
67 | Также поддерживается функция range. reverse() пока не поддерживается. |
||
68 | |||
69 | TP_FNC - функция. Бывает 2 типов - обычная функция и метод, отличаются |
||
70 | порядком вызова. |
||
71 | |||
72 | TP_DATA - внутренние структуры TinyPy. |
||
73 | |||
74 | 2. Возможности TinyPy в сравнении с "большим" Python |
||
75 | |||
76 | "what tinypy won't be: |
||
77 | - a full implementation of Python; |
||
78 | - totally compatible with Python" |
||
79 | "roadmap.txt", tinypy sources |
||
80 | |||
81 | Синтаксис языка TinyPy очень похож на Python, но многие существенные |
||
82 | возможности Python не поддерживаются: |
||
83 | |||
84 | - итераторы и сопрограмм; |
||
85 | - синтаксический "сахар" для объявления списков и словарей, наподобие |
||
86 | odd_squares = [a*a for a in range(100) if a%2]; |
||
2073 | jaeger | 87 | - интерактивная консоль. |
2053 | jaeger | 88 | |
89 | И конечно, не хватает основной силы Python - его стандартной библиотеки. |
||
90 | |||
91 | 3. Расширение TinyPy. |
||
92 | |||
93 | Набор встроенных функций в TinyPy достаточно беден, но зато добавление новых |
||
94 | модулей достаточно просто. Рассмотрим создание модулей на самом TinyPy, на |
||
95 | C и на FASM. |
||
96 | |||
97 | 3.1. Модули на TinyPy. |
||
98 | |||
99 | TinyPy поддерживает модульное программирование, создание модулей |
||
100 | принципиально ничем не отличается от Python. Пусть, у нас есть простая |
||
101 | программа из двух файлов: |
||
102 | |||
103 | Файл math.py: |
||
104 | def square(a): |
||
105 | return a*a |
||
106 | |||
107 | Файл prog.py: |
||
108 | import math |
||
109 | |||
110 | if __name__=="__main__": |
||
111 | math.square(12) |
||
112 | |||
113 | Вначале нужно скомпилировать модуль math.py в байт-код при помощи программы |
||
2073 | jaeger | 114 | py2bc.py, она работает как в Python, так и в TinyPy. Запускаем shell и выполняем команду |
115 | # tinypy py2bc.py math.py math.tpc |
||
116 | |||
117 | После этого можно запустить prog.py из TinyPy. |
||
118 | |||
119 | # tinypy prog.py |
||
120 | 144 |
||
121 | |||
122 | Замечание: синтаксис "from module import function" пока не поддерживается. |
||
2053 | jaeger | 123 | |
124 | 3.2 Модули на C. |
||
125 | |||
126 | Пример создания модулей на C можно посмотреть в каталоге modules/kolibri. Такие |
||
127 | модули статически линкуются с самим интерпретатором и, соответственно, |
||
128 | увеличивают его размер. Для снижения накладных расходов компоненты TinyPy |
||
129 | компилируются в один объектный модуль, а файлы исходных текстов включаются с |
||
130 | помощью директивы #include. Дополнительные модули могут компилироваться как в |
||
131 | отдельные объектные файлы, в этом случае нужно дописать их в Makefile, или |
||
132 | точно так же подключаться директивой include. |
||
133 | |||
134 | В модуле должна присутствовать функция инициализации обычно она называется |
||
135 |
|
||
136 | машины, создаёт словарь экспортируемых объектов и добавляет его в предопределённый словарь modules. |
||
137 | |||
138 | Чтобы определить TinyPy-функцию, нужно создать обычную функцию на C вида |
||
139 | |||
140 | tp_obj myfunc(tp_vm *tp); |
||
141 | |||
142 | 3.3 Модули на FASM. |
||
143 | |||
144 | Модуль на FASM пишется аналогично, но всегда компилируется в отдельный |
||
145 | объектный файл. Пример можно посмотреть в каталоге fasm_modules. Модуль |
||
146 | kolibri_dbg экспортирует одну функцию debug_print, выводящую строку на доску |
||
147 | отладки. |
||
148 | |||
149 | 4. Обзор модуля kolibri. |
||
150 | |||
151 | Продолжение следует.><> |