refal-5-lambda icon indicating copy to clipboard operation
refal-5-lambda copied to clipboard

Обеспечить поддержку компилятора Digital Mars C++

Open Mazdaywik opened this issue 8 years ago • 20 comments
trafficstars

Есть такой бесплатный компилятор — Digital Mars C++. Необходимо:

  • проверить, компилируется ли Простой Рефал с этим компилятором на высоком уровне предупреждений; если необходимо — внести соответствующие правки;
  • добавить командную строку в c-plus-plus.conf.bat,
  • сравнить с другими компиляторами в плане быстродействия как самого компилятора, так и сгенерированного кода.

Примечание: компилятор найден по ссылке http://codedchaos.blogspot.ru/2011/04/c-ide.html.

Mazdaywik avatar Dec 18 '16 09:12 Mazdaywik

Попробовал обеспечить поддержку компилятора Digital Mars C++. Взял последнюю доступную версию https://github.com/DigitalMars/dmc Тестировалось в wine (wineconsole) В файле bootstrap.bat:

set PATH=%PATH%;Z:\home\user\prog\mk_ref\dmc-master\bin
set CPPLINEE=dmc -A -cpp

(Z:\home\user\prog\mk_ref\dmc-master - то, куда распакован архив последней версии dmc с гитхаба)

Последующий запуск bootstrap.bat ничего не дал, никаких ошибок, ничего не происходит.

Пример работы с компилятором dmc (компиляция простейшей программы hello world)

Z:\home\user\prog\mk_ref>dmc -A -cpp hello.c++
link hello,,,user32+kernel32/noi;


Z:\home\user\prog\mk_ref>hello.exe
Hello, World!
Z:\home\user\prog\mk_ref>

https://www.digitalmars.com/ctg/sc.html#overview - документация на dmc

j123123 avatar Oct 01 '18 13:10 j123123

Строка в %CPPLINEE% должна оканчиваться на опцию, задающую имя исполнимого файла:

set CPPLINEE=cl /EHcs /O2 /W3 /Fe
%CPPLINEE%hello.exe hello.cpp

то же самое, что

cl /EHcs /O2 /W3 /Fehello.exe hello.cpp

Аналогично:

set CPPLINEE=bcc32 -w -e
set CPPLINEE=g++ -Wall -O3 -o

Без опции целевого файла получится фигня.

Mazdaywik avatar Oct 01 '18 13:10 Mazdaywik

Фигня еще в том, что в dmc довольно нестандартно сделано это Вот например таким образом можно получить файл hello.obj

dmc -A -cpp -c -ohello.obj hello.c++

Да, компилятор парсит флаги таким образом, что откусывает кусочек -o и оставшееся - выходной файл

Вот как это описано в документации:

-ofilename Specify output filename
    This specifies the name of the object [.obj]
file if the -c switch is used, otherwise it specifies
the output executable [.exe] file name. The dot extension is optional. 

j123123 avatar Oct 01 '18 14:10 j123123

По-моему, смысл опции -o у GCC точно такой же. С флагом -c это имя объектника, без флага -c — имя исполнимого файла. Т.е. можно смело писать

set CPPLINEE=dmc -A -cpp -o

и всё должно работать. Наверное.

Mazdaywik avatar Oct 01 '18 14:10 Mazdaywik

Нет, ничего так не работает, потому что между -o и именем выходного файла не должно быть пробела

j123123 avatar Oct 01 '18 14:10 j123123

Он вроде не должен добавляться. Попробуй

set CPPLINEE=echo dmc -A -cpp -o

И проверь, что в текстовом редакторе в самом конце строки случайно не впечатан пробел (в vim можно набрать /\s$ и он покажет).

Mazdaywik avatar Oct 01 '18 14:10 Mazdaywik

Попробовал - разницы нет. Может быть проблема не в этом? Вот еще заметил, что этому компилятору не нравятся инклуды вида

#include <iostream>

ему обязательно надо

#include <iostream.h>

Но тогда должны были б появиться ошибки компиляции вида

Fatal error: unable to open input file 'iostream'

при попытке сборки. А тут такого не наблюдается. Или ошибки компиляции там не выводятся никак при бутстрапе?

j123123 avatar Oct 01 '18 14:10 j123123

Вообще, должны выводиться.

Mazdaywik avatar Oct 01 '18 14:10 Mazdaywik

Да, это была проблема wine. На реальной винде такая ошибка выводится.

src

j123123 avatar Oct 01 '18 17:10 j123123

Там надо куда-то прописать, чтобы использовался STL c нужными хедерами

j123123 avatar Oct 01 '18 18:10 j123123

Там надо куда-то прописать, чтобы использовался STL c нужными хедерами

Скорее всего, написать что-то вроде dmc -A -cpp -Iпуть-к-stl …, только этот путь надо выяснять копанием в исходниках.

Если разберёшься, можешь сделать pull request. Только править надо файл scripts/c-plus-plus.conf.bat.template. Потому что файл c-plus-plus.conf.bat в корне не лежит в репозитории, а копируется из .template.

Mazdaywik avatar Oct 01 '18 18:10 Mazdaywik

Я попробовал собрать с stl - есть какие-то ошибки. src Там еще stlport адаптированный для этого компилятора есть, но с ним тоже какие-то ошибки

j123123 avatar Oct 01 '18 18:10 j123123

В таких ситуациях правильнее будет исправлять STL, или исправлять кодогенератор Рефала в C++, чтобы он генерировал код, который бы работал с тем STL, что есть?

j123123 avatar Oct 01 '18 18:10 j123123

В библиотеке Library лежат функции, которые написаны на C++. В функциях на Рефале можно делать вставки кода на C++ между строчками %%%%. Как вставки на ассемблере в самом C++.

Конкретно: вот где ругается:

https://github.com/bmstu-iu9/refal-5-lambda/blob/master/src/srlib/Library.sref#L779-L793

https://github.com/bmstu-iu9/refal-5-lambda/blob/master/src/srlib/Library.sref#L1188-L1220

Правильнее будет понять, на какие места ругается DMC, и их переписать так, чтобы он не ругался.

Судя по тому, что предшествующие файлы оттранслировались успешно, проблем со сгенерированными файлами здесь нет.

После компиляции Library должна начаться компиляция refalrts-*.cpp — там много STL’я (но всё компилируется GCC, Clang, BCC, Visual C++ и даже Open Watcom 1.9 — cf913c441f1cdbafd084e3417503b48a704ba7f1).

Кстати, на данный момент собираются не файлы самого компилятора, а его «полускомпилированного» «дистрибутива» для раскрутки:

https://github.com/bmstu-iu9/simple-refal-distrib

Mazdaywik avatar Oct 01 '18 19:10 Mazdaywik

Код на Рефале компилируется примерно вот во что, никакого STL там нет: https://github.com/bmstu-iu9/simple-refal-distrib/blob/master/compiler/HighLevelRASL-GenSubst-Simple.cpp

Код на Рефале с нативными вставками содержит текст нативных вставок: https://github.com/bmstu-iu9/simple-refal-distrib/blob/master/compiler/Library.cpp (вставки можно легко найти по директиве #line). Именно в них есть проблемный STL.

Mazdaywik avatar Oct 01 '18 19:10 Mazdaywik

Может тогда имеет смысл вообще избавиться от необходимости иметь какую-либо реализацию STL чтобы собрать это?

j123123 avatar Oct 02 '18 07:10 j123123

В смысле, переписать без STL? Можно, но геморно. В рантайме активно используются std::vector, std::list, std::map и std::set. Не говоря о std::string. Придётся тогда написать велосипедные контейнеры для их замены.

Проще, мне кажется, разобраться, что не так с DMC и обойти его проблемы. Как-нибудь позже я сам этим займусь.

Mazdaywik avatar Oct 02 '18 18:10 Mazdaywik

А что если необходимый функционал из STL переписать на самом Рефале? Ну и сделать это как раскрутку компилятора. Вот у нас есть компилятор Рефала Comp_ref который принимает код на рефале Ref_src и выдает код на C++, которому требуется рантайм STL для работы СPP_STL_src т.е.

(Ref_src) -> [Comp_ref] -> (CPP_STL_src)

(тут [Comp_ref] означает что мы вызываем код компилятора Рефала, аргумент слева - вход (код на рефале), справа - выход - исходный код на C++ зависимый от STL) Делаем так - меняем код рефала, чтобы он генерировал код, не зависящий от STL - получаем Ref_Comp_ref_NOSTL Далее, компилируем Ref_Comp_ref_NOSTL компилятором Comp_ref, и получившимся откомпилированным CPP_Comp_ref_TMP компилируем Ref_Comp_ref_NOSTL(самого себя). Всё, зависимости от STL нет. Т.е.

(Ref_Comp_ref_NOSTL) -> [Comp_ref] -> (CPP_Comp_ref_TMP)
(Ref_Comp_ref_NOSTL) -> [CPP_Comp_ref_TMP] -> (СPP_Comp_ref_NOSTL)

CPP_Comp_ref_TMP - Компилятор Рефала, оттранслированный в код C++, который может генерить код на C++, не зависящий от STL, но который сам зависит от STL т.к. собран версией компилятора Рефала, зависящей от STL. СPP_Comp_ref_NOSTL - Компилятор Рефала, оттранслированный в код C++, который уже никак от STL не зависит, и генерирует код на C++, не зависящий от STL.

Сложно ли организовать это?

j123123 avatar Oct 03 '18 06:10 j123123

Рассуждения верны с тем небольшим нюансом, что выход компилятора от STL уже не зависит.

Тот код, который генерируется, использует только функции из refalrts.h, а там STL в принципе нет. Единственный заголовочник, который там подключается — это stddef.h для того, чтобы можно было использовать size_t.

А вот реализация этих функций прямо или косвенно (больше косвенно, чем прямо) уже использует STL. Поэтому никакие шаги раскрутки уже делать не надо, достаточно переписать саму реализацию функций рантайма без использования STL.

А это потребует переписать весь код без использования std::string, std::map, std::vector, std::set и std::list (именно их я использовал). А это значит, что или надо будет велосипедить их аналоги, или писать в сишном стиле: malloc’ать память под массивы и строки и париться над её контролем.


У меня есть очень простой компилятор Рефала (менее 6000 строк кода), который компилирует в C89:

https://github.com/Mazdaywik/Refal-05

Можешь попробовать раскрутить и посмотреть, как он работает и устроен. Исходники (папка src) компилятора написаны на подмножестве Рефала-5 (и одновременно на подмножестве Рефала-05), рантайм (lib/refalrts.{h,c}) — на чистом Си, встроенные функции — на Рефале со вставками кода на чистом Си (lib/Library.ref). Работает на Windows и Linux, для раскрутки требует установленный Рефал-5 (поддержку Рефала-5λ я пока не организовывал, но планирую: Mazdaywik/Refal-05#23).

Актуальная документация в процессе написания (ветка develop, надо смотреть README.md), есть неактуальная документация, которая, однако, не сильно врёт.

Mazdaywik avatar Oct 03 '18 11:10 Mazdaywik

Зачем я показываю Рефал-05? Потому что в Рефале-5λ всё тоже самое, только в 10 раз больше.

Mazdaywik avatar Oct 03 '18 13:10 Mazdaywik