Кодогенерация из байт-кода в бинарный модуль

Программирование на Visual Basic, главный форум. Обсуждение тем программирования на VB 1—6.
Даже если вы плохо разбираетесь в VB и программировании вообще — тут вам помогут. В разумных пределах, конечно.
Правила форума
Темы, в которых будет сначала написано «что нужно сделать», а затем просьба «помогите», будут закрыты.
Читайте требования к создаваемым темам.
jangle
Википедик
Википедик
Аватара пользователя
 
Сообщения: 3013
Зарегистрирован: 03.06.2005 (Пт) 12:02
Откуда: Нидерланды

Кодогенерация из байт-кода в бинарный модуль

Сообщение jangle » 10.08.2006 (Чт) 14:49

У меня есть самописный язык программирования, пока реализованный в виде интерпретатора. Он довольно мощный, похож на Basic и легко позволяет быстро писать довольно сложные программки. Например вот некоторые функции:

'копирование всех файлов с дискеты в каталог C:\WINDOWS

Drive("C").Folder($win).CopyFile Drive("A").ReadFileName("*.*")

'Распечатка всех файлов с расширением *.doc на принтере

Printer.Name("hp LaserJet 3015 PCL 6").PrintFile (Drive("C").Folder($MyDocuments).File("*.doc"))

'Удаление файлов с расширением *.tmp из всех папок на диске С

Drive("C").DeleteFile("*.tmp")

'Отображение структуры каталогов диска С в консольном окне

Console.Write(Drive("C").GetFolderName))

Сначала код выполнялся построчно и довольно медленно, поэтому я написал транслятор в байт код.
Например конструкция x=x+1 будет откомпилирована в такой bytecode:


0000: AddStack x
0001: AddStack 1
0002: SUM
0003: ReadStack x
0004: ClearStack



А например MsgBox ("Hello","World",1) в такой:

0000: Str_1 "Hello"
0001: Str_2 "World"
0002: Str_3 "user32.dll"
0003: Str_4 "MessageBoxA"
0004: AddStack @ Str_3
0005: AddStack @ Str_4
0006: AddStack 0
0007: AddStack @ Str_1
0008: AddStack @ Str_2
0009: AddStack 1
0010: Call_Invoke
0011: Stop


Теперь следующий шаг, написать транслятор из текстового байт-кода в бинарник состоящий из четырех-адресных инструкций такого вида:

;Тетрада - 1
0000: 00F1 <--- ID команды байт-кода
0001: 01A1 <--- Операнд1
0002: 1123 <--- Операнд2
0003: 1123 <--- Операнд3

;Тетрада - 2
0004: 00A0 <--- ID команды байт-кода
0005: 0000
0006: 0000
0007: 0001

;Тетрада - 3
0008: 1000 <--- ID команды байт-кода
0009: 0000
0010: 0000
0011: FF1A

;Тетрада - 4
0012: АА00 <--- ID команды байт-кода
0013: 0010
0014: 0100
0015: 0000



Похоже на пулеметную ленту с патронами, виртуальная машина по очереди "заглатывает" каждую тетраду, выполняя для каждой Call Dword (ID), т.е. ID является константным указателем на функцию-обработчик команды. Каждая команда сама "знает" сколько параметров ей надо снять со стека, а также следит за его сбалансированностью.

Проблема - куда девать текстовые литералы и константы?
Отображать например каждый байт литерала в виде тетрады, это слишком жирно будет, хочется сделать компактный бинарник.

Или к примеру, может сделать отдельную секцию для литералов? И отдельную для констант?
Но это очень сильно усложнит процесс трансляции, т.к. необходимо увязывать ссылки на таблицу литералов с адресами их вызова и в процессе трансляции пересчитывать смещения всех переходов по коду, надо будет сначала собрать таблицу литералов, вычислить ее размер. Потом оттранслировать блок тетрад, оставляя в точках переходов "пустышки", слить все таблицы и тетрады в единый бинарник, и в финале пробежаться по коду пропатчивая "пустышки" правильными ссылками на литералы и константы...
Вот такой гемморой, вырисовывается. Практически во всех книжках по компиляции, афторы стыдливо пропускают момент кодогенерации, отделываясь туманными общими фразами, что это очень просто и элементарно...
Может это и так, но что-то ничего лучше придумать не смог, просто уперся рогами в землю.

Если кто-нибудь делал такие вещи, поделитесь идеями, как проще всего реализовать трансляцию из пост/префиксной формы в тетрады, с учетом литералов, адресации, условных переходов и т.д.

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 10.08.2006 (Чт) 14:57

Погляди в моём блоге, я в июне что-то на эту тему выдумывал. Потом бросил.
Литералы, действительно, принято складывать в отдельное место. Ещё при этом сливают совпадающие строки.
Изображение

jangle
Википедик
Википедик
Аватара пользователя
 
Сообщения: 3013
Зарегистрирован: 03.06.2005 (Пт) 12:02
Откуда: Нидерланды

Сообщение jangle » 10.08.2006 (Чт) 15:13

tyomitch - cпасибо! Сейчас буду смотреть. Кстати, идея сливать совпадающие строки меня не посещала, это же настоящая оптимизация! :)


Вернуться в Visual Basic 1–6

Кто сейчас на конференции

Сейчас этот форум просматривают: AhrefsBot, Google-бот, Mail.ru [бот] и гости: 32

    TopList  
cron