Транслятор¶
Транслятор перетворює дерево синтаксичного розбору на набір мікрооперацій абстракної мови асемблера, але у внутрішньому представленні (список кортежів мови Python). Вона може бути однозначно перетворена у текст програми асемблера, але цей крок робиться для того, щоб можна було зробити оптимізацію.
В даній реалізації транслятор перетворює дерево в код, який специфічний для операційної системи GNU/Linux.
- Системні визови до ядра Linux (номери функції ядра)
- Переривання визову функції ядра int 0x80
- Використання функцій бібліотеки libc
Але модульна архітектура компілятора дозволяє легко реалізувати транслятор для інших систем при необхідності та без впливу на інші модулі програми.
Транслювання відбувається в 2 етапи:
- Збір інформації
- Генерація псевдо-асемблерного коду
Збір інформації¶
Для перетворення коду транслятор в першу чергу робить обхід по дереву та збирає дані про майбутній код, такі як:
- Змінні
- Строкові літерали
- Оголошені функції
- Виклики функцій виводу та вводу
Особливістю є, що транслятор шукає тільки унікальні строки, то ж якщо в коді зустрічаються наприклад виводи на екран тієї самої строки кілька разів, строка буде включена у дані програми тільки один раз.
Якщо в коді не зустрічаються визови вводу/виводу чи інші функції з бібліотеки libc, то бібліотека не буде прилінкована.
-
class
pyCompiler.utils.gen.
TreeStats
¶
-
pyCompiler.utils.gen.
find_vars
(t)¶ Функція збору інформації
Parameters: t – дерево розбору Return type: структура TreeStats з інформацією про код
Генерація псевдо-асемблерного коду¶
Кожен оператор мови високого рівня (myl) транслюється в послідовність команд асемблеру.
-
pyCompiler.utils.gen.
gen_code
(t, stat)¶ Функція, що відповідає за генерацію псевдо-асемблерного коду
Parameters: - t – дерево розбору
- stat – дані про код
Return type: список операторів псевдо-асемблеру
Оголошення функції¶
function mul(x,y)
R = x*y;
return R;
endfunc;
Транслюється в:
jmp Func0End
label Func_mul
mov eax, esp+4
mov vmul_x, eax
mov eax, esp+8
mov vmul_y, eax
; Тіло функції
mov dword eax, [vmul_x]
mov dword ebx, [vmul_y]
imul ebx
; Кінець тіла
ret
label Func0End
Оператор return¶
Повернення результату з функцыї:
return x;
Всередині функції транслюється в:
mov eax, vFUNC_x
ret
Оператор print¶
Для строк:
print "123"
Транслюється в:
push str0
call printf
add esp, 4
push [stdout]
call fflush
add esp, 4
де str0 це:
str0: db "123"
str0len: equ $-str0
Або для змінних:
print x;
транслюється в:
mov eax, [vx]
push eax
push numbs
call printf
add esp, 8
push [stdout]
call fflush
add esp, 4
де numbs це:
numbs: db "%d", 0
Оператор read¶
Читання числа з клавіатури з записом результату в змінну x:
read x;
транслюється в:
push vx
push numbs_in_format
call scanf
add esp, 8
call getchar
де numbs_in_format це:
numbs_in_format: db "%d",0
Інші оператори¶
Транслювання інших операторів дивитись в доданку з вихідним кодом (https://github.com/antigluk/pyCompiler), файл utils/gen.py, функція gen_text_section