TugBoat -- новый транслятор с Клиппера на С

Что такое TugBoat ?

 

TugBoat - дополнительный интеллектуальный компилятор с языка Клиппер на язык C.

TugBoat_55.zip (360K)
Скачать это ?

FAQ (начало, engl)

А теперь об этом поподробнее и пореалистичнее…

Дополнительный компилятор

С самого начала для меня задача заключалась в ускорении выполнения существующих Клиппер-программ. Повторюсь, “существующих”. То есть если разработчик использовал библиотеку QWERTY_for_Clipper очень левого разработчика со всеми исходными текстами — он может ускорить свое приложение, в том числе и ускорить функции их этой библиотеки. Если же он использует библиотеку ASDFG_for_Clipper очень правого разработчика и исходников этой библиотеки нету в пределах досягаемости — ну что ж, можно ускорить работу только своего кода, а чужой код приходится использовать как есть.

Как это работает ? Ну, я просто генерю С-код, а на С написано 85 % Клиппера. Естественно, это может работать вместе, если все сделано правильно. Список моих недоработок смотри в “Bugs”. Подробнее же механизм работы читайте дальше.

Увеличение скорости

Вначале была идея. “Если интерпретатор Клиппера написан большей частью на C и выполняет в основном декодирование байт-кода в вызовы соответствующих C функций — почему бы не попробовать странслировать исходники на Клиппере в C – программу, с непосредственными вызовами этих функций ?”

Первый вариант TugBoat примерно это и делал. Порождался С-код, состоящий сплошь из вызовов других функций. Скорость увеличилась, но ненамного - на десятки процентов. Львиную доли времени съедал динамический контроль типов.

Следующим шагом было обнаружение и выделение статического типа переменных. Особенно типа “целый” , “длинный целый”, “логический”, “дата”, операции над которыми могут выполняться без привлечения Клиппер-машины. Тут и появилась “интеллектуальность” в компиляторе (см. ниже)

Но все равно получающийся С-код выглядел непристойно. Причина — дурная практика N-уровневой адресации в клипперовских массивах. Но писал кто-то, а отвечать мне! В Клипперовской программе

f[1][2][3] += a[4][5][6]

выглядит почти приемлемо. В С-программе это выглядит просто ужасно. И пришлось добавлять классический глобальный оптимизатор — с вынесением общих подвыражений и чисткой циклов вверх. Как правило, после прохода оптимизации сишный код становится на 30% короче (и на сколько-то быстрее). Теперь выходной код выглядит получше:

 

Код без оптимизатора

Код с оптимизатором

CLC_putaa0any (f, (1), (2));

_putln (CLC_puta1long (3));

CLC_putaa0any (a, (4), (5));

_putln (CLC_puta1long (6));

_tos--;

LONGCAST(_tos) += LONGCAST (_tos-1);

CLC_putaa0any (f, (1), (2));

CLC_popa2 ((3));

{

ITEM _loc1 = CLC_putaa0 (a, (1), (2), -1);

CLC_putaa0any (f, (4), (5));

CLC_popa0long (_loc1, (3),

(CLC_puta0long (_loc1, (3)) +

CLC_puta1long (6)));

}

_pull (1);

 

Поподробнее о механизме работы смотри в “Теории” и “Истории”

“Интеллектуальность” или обнаружение семантических ошибок

Задача вычисления статических типов для языка с динамической типизацией хоть и сложна, но относится к категории “уже пройденных”. Похожие методы использовались при трансляции ЛИСПа в машинный код (помните японский проект ЭВМ пятого поколения ? Вот тогда).

Я это сделал. Например Вы увидите что-то вроде:

Warning FILE.prg 123: Local variable I type SHORTINT in function …

Тут и появилась “интеллектуальность” в компиляторе — просто внутри него происходит ошибка вычисления статического типа в том месте, где в программе произошла бы ошибка динамической типизации (например 1 + “1”, или 2 > nil — все это выражения с ошибками типизации). Например:

>> local i := 0

>> i := str (i) + i

>>----------- сообщение ------------

>>Error a.PRG 4: Type clash, SHORTINT to STRING

Подробно расписывать здесь как вычисляются статические типы я не могу (это три прохода компилятора, то есть словами это будет очень долго и потому скучно). Бог даст, подвернется коммерчески приемлемый вариант перевода TugBoat на “Open Source”, тогда и посмотрите. Ну а если такого варианта не будет — ну что ж, придется более-менее подробно расписывать. Но позже. То есть не знаю когда.

Новые возможности

Можно описывать типы параметров функции, например:

external function qwerty(__integer,__integer|__real,__array)__nil

Синтаксис описания EXTERNAL функций:

external имя_функции function (arg1, arg2,...) returned

где "arg" или "returned" есть

[тип] | [тип] |...

То есть можно написать, например:

external function val (__string) __INTEGER | __REAL

Синтаксис описания STATIC функций:

__static имя_функции function (arg1, arg2,...) returned

где "arg" or "returned" то же самое

Предупреждение: все описания функций должны быть в начале файла

Можно описывать явно типы переменных, например

function qwerty (a,b,c)

local __shortint i

if a == int(b)

for i = 1 to len ( с )

c[i] := str ( i )

next

endif

return nil

Синтаксис переменных с типами:

STATIC [type] имя := выражение, имя := выражение, ...

LOCAL [type] имя := выражение, имя := выражение, ...

 

где [type] есть один из:

__shortint то есть "short int" в "C"

__integer то есть "long int" в "C"

__logical то есть "int" в "C"

__real то есть "ITEM" в "C"

__string то есть "ITEM" в "C"

__array то есть "ITEM" в "C"

__nil то есть "ITEM" в "C"

__date то есть "long" в "C"

 

Теория

Конечно, Вы это знаете, но тем не менее повторю начальные данные

эти процедуры (вызываемые интерпретатором) написаны на C возникает законный вопрос

может быть, если вызывать эти процедуры непосредственно из C-программы, скорость увеличится ?

и отсюда начинается история TugBoat…

В Клиппер-машине все локальные переменные и временные результаты храняться в моделируемом стеке в виде структур данных по 14 байтов, причем по первому байту определяется, что это - целое число, строка или массив и т.д. . То есть прибавить единицу к переменной в Клиппере — значит:

 

Buglist

Строки в квадратных скобках недоступны

If “abcd” == [abcd]

Переменные с именами, совпадающими с ключевыми словами недоступны

If := 1

Protected mode из под Блинкера крайне нестабильно

Выражение вида

If a > 2.or. a < -2

Дает синтаксическую ошибку перед .or. должен быть пробел

 

  

Best regards,

http://www.geocities.com/cl2cru/

Ai mailto:ai@bogorod.tula.net (Bulatov Vladislav)