Board.KolibriOS.org

Официальный форум KolibriOS
Текущее время: Вт авг 21, 2018 10:49 pm

Часовой пояс: UTC+03:00




Начать новую тему  Ответить на тему  [ 83 сообщения ]  На страницу Пред. 1 2 3 4 5 6 След.
Автор Сообщение
 Заголовок сообщения: Re: Компилятор Oberon-07
СообщениеДобавлено: Вс апр 15, 2018 8:44 pm 
Не в сети

Зарегистрирован: Вс окт 30, 2011 6:43 pm
Сообщения: 1310
akron1 писал(а):
Не подсвечиваются шестнадцатиричные константы и вложенные комментарии. Конечное END считается ошибкой, если в процедуре нет BEGIN, а такое возможно
Некоторые вещи пофиксил.
Теперь список процедур должен отображаться правильно в выпадающем списке:
Спойлер: Показать
Вложение:
drop_down_list.PNG
drop_down_list.PNG [ 60.1 КБ | 929 просмотров ]
Процелурные типы
Код:
TYPE ProcName = PROCEDURE...
и переменные процедурных типов
Код:
Var ProcName : PROCEDURE...
тоже попадают в этот список.
Если это лишнее — убрать не долго, нужно отредактировать секцию <LABELS>...</LABELS> в файле ob07_spec.xml — убрать ненужные <Label.../>.

Комментарии сейчас могут быть дважды вложенными, то есть, например, так:
Код:
(* 
   (*
    *
    *  (* *** *)
    *
    *)
*)
Я просто не знаю, как это правильно реализовать, сделал, как смог
Спойлер: Показать
comment2 может находится в контейнере comment1, который может находится в контейнере comment:
Код:
<Style id="comment"...
  <Blocks>
    <Block open="//" close="\n"/>
    <Block open="(*" close="*)"/>
  </Blocks>
</Style>
<Style id="comment1"...
  <Containers>
    <Open id="comment"/>
    <Close id="comment"/>
  </Containers>
  <Blocks>
    <Block open="(*" close="*)"/>
  </Blocks>
</Style>
<Style id="comment2"...
  <Containers>
    <Open id="comment1"/>
    <Close id="comment1"/>
  </Containers>
  <Blocks>
    <Block open="(*" close="*)"/>
  </Blocks>
Редактор HippoEDIT позволяет настроить выполнение той или иной программы(команды, bat, и т.п.) в зависимости от расширения открытого файла.
Вполне удобно иметь возможность компилировать и запускать скомпилированный файл прямо из редактора.

Для этого выбираем меню->Tools->Manage Tools
У меня в данный момент уже открыта вкладка с файлом с расширением .ob07, поэтому в меню отображается Manage Tools(Oberon-07)
Спойлер: Показать
Вложение:
menu.PNG
menu.PNG [ 22.62 КБ | 929 просмотров ]
После открытия диалога Manage Tools(см. скриншот под спойлером ниже) выбираем в нём нажатием мыши значок Oberon-07.
Кнопкой Add добавляем новый пункт.
Указываем название(будет отображаться в меню Tools). Я назвал Ob-07 Compiler.
Указываем путь к исполняемому файлу компилятора.
Для сборки консольного приложения под Windows компилятору нужно указать опцию 'con', пишем в аргументах:
Код:
%MainFile% con  
Указываем Initial directory:
Код:
%FileDir%
Можно определить горячую клавишу, по нажатию которой будет запускаться нужная программа(или bat-файл).

Для того, чтобы запускать скомпилированный файл, создадим ещё один пункт.
Я назвал его Run.
В поле Command нужно ввести:
Код:
%MainFileDir%\%FileNameWOExt%.exe
Спойлер: Показать
Вложение:
ob07+run.PNG
ob07+run.PNG [ 65.89 КБ | 929 просмотров ]

Теперь когда активная вкладка будет содержать открытый файл с расширением .ob07, то в меню Tools должны появиться два пункта: Ob-07 Compiler и Run.
Вложение:
Ob07_.7z [2.53 КБ]
28 скачиваний


Вернуться к началу
 Заголовок сообщения: Re: Компилятор Oberon-07
СообщениеДобавлено: Пн апр 16, 2018 8:54 pm 
Не в сети

Зарегистрирован: Вс окт 27, 2013 8:13 pm
Сообщения: 118
0CodErr писал(а):
Процедурные типы и переменные процедурных типов тоже попадают в этот список.
Если это лишнее — убрать не долго
Да, это конечно, лишнее.

0CodErr писал(а):
Комментарии сейчас могут быть дважды вложенными

Нормально, на практике бОльшая глубина не требуется.

При беглом осмотре нашел только один недочет: кроме суффикса "H" (INTEGER), шестнадцатиричные константы могут иметь суффикс "X" (CHAR), последние не подсвечиваются, но должны подсвечиваться как "строки".

В остальном -- отлично!

Сейчас пишу транслятор промежуточного байт-кода в ассемблер FASM, заодно и опробую HyppoEdit.
Байт-код не сложный, но обширный -- около 180 инструкций. Пока обработано только 30. Первые результаты несколько неоднозначные.
Такой код:
Код:
PROCEDURE test (n: INTEGER);
VAR
    a: INTEGER;
BEGIN
    WHILE n > 0 DO
        a := 7FFFFFFFH;
        WHILE a > 0 DO
            a := a - 1
        END;
        n := n - 1
    END
END test;

выполняется в 3 раза быстрее, чем скомпилированный текущим (старым) компилятором, но в 6-7 раз медленнее, чем Delphi7. Но тут понятно, Delphi хорошо оптимизирует: процедура-лист, две переменные -- два регистра. Мои компиляторы честно загружают и сохраняют переменные при каждом обращении. В более сложных случаях разрыв, наверно, будет меньше. Сделать полноценное распределение регистров, конечно, сложно, но можно будет попробовать выявить в программе места, в которых распределить регистры сравнительно просто (вроде этой процедуры), и транслировать такие процедуры по особым правилам.


Вернуться к началу
 Заголовок сообщения: Re: Компилятор Oberon-07
СообщениеДобавлено: Пн апр 16, 2018 10:45 pm 
Не в сети

Зарегистрирован: Вс окт 30, 2011 6:43 pm
Сообщения: 1310
akron1 писал(а):
выполняется в 3 раза быстрее, чем скомпилированный текущим (старым) компилятором, но в 6-7 раз медленнее, чем Delphi7
Ну прогресс ведь уже есть — это главное!
Какое, кстати, внутреннее соглашение вызова(если не указано явно [stdcall] | [winapi]| [cdecl])?
akron1 писал(а):
шестнадцатиричные константы могут иметь суффикс "X" (CHAR), последние не подсвечиваются, но должны подсвечиваться как "строки".
Пробовал такой регуляркой:
Код:
<Regexp text="[0-9][0-9A-F]*X" lead="[^\w]"/>
Вот здесь:
Код:
      <Style id="char" name="Char" text="1" bold="0" italic="0" underline="0" clr="Strings" bkclr="#FFFFFFFF">
        <Blocks>
          <Block open=""" close="""/>
          <Regexp text="[0-9][0-9A-F]*X" lead="[^\w]"/>
        </Blocks>
      </Style>
Проверял её в https://regex101.com/ и она там рабочая.
Но в HippoEDIT она не заработала. Вообще у меня не самая новая версия программы, может просто ещё тег Regexp не поддерживался.
Ни в одной синтаксической схеме, поставляемой с моей версией, не присутствует ни один тег Regexp.
В то же время в файлах отсюда https://www.hippoedit.com/syntax_files.php?lang=ru такой тег присутствует во многих местах, в частности в asm_arm_spec.xml:
Код:
      <Style id="number" extend="true">
        <Blocks>
          <!--  0xFFFF -->
          <Regexp text="0x[0-9A-Fa-f]+\>" lead="[^\w]"/>
          <!-- Binary: 0b1010 -->
          <Regexp text="0b[01]+\>" lead="[^\w]"/>
          <!-- Octal: 01234567 -->
          <Regexp text="0[0-7]\>" lead="[^\w]"/>
          <!-- Decimal  are built-in -->
        </Blocks>
      </Style>

0CodErr писал(а):
Вставка шаблонов кода Code templates по Ctrl+Enter.
Как оказалось, клавишу Ctrl нажимать не всегда обязательно, в большинстве случаев достаточно Enter.
Есть ещё Ctrl+Пробелautocomplete(автоподстановка по первым введённым буквам).

Забыл сказать, что если выбрать опцию 'Capture output', тогда то, что компилятор выводит обычно в консоль, будет выведено прямо в редакторе в панель Output.
Потом его ещё вроде можно регулярками распарсить(Output Pattern).
Спойлер: Показать
Вложение:
capture_output_hippo_edit.PNG
capture_output_hippo_edit.PNG [ 76.13 КБ | 883 просмотра ]


Вернуться к началу
 Заголовок сообщения: Re: Компилятор Oberon-07
СообщениеДобавлено: Пн апр 16, 2018 11:58 pm 
Не в сети

Зарегистрирован: Вс окт 27, 2013 8:13 pm
Сообщения: 118
0CodErr писал(а):
Какое, кстати, внутреннее соглашение вызова(если не указано явно [stdcall] | [winapi]| [cdecl])?

По умолчанию stdcall.
Есть нюансы: массивы и записи всегда передаются по ссылке, но если перед формальным параметром-записью указано VAR, то на самом деле там будет передан не один параметр, а два: тип записи и адрес:
Код:
PROCEDURE (VAR r: REC);
procedure (typeof(r), adr(r)); stdcall

Если формальный параметр -- открытый массив (VAR или нет -- не важно), то кроме адреса передаются длины по всем измерениям:
Код:
PROCEDURE (a: ARRAY OF ... );
procedure (adr(a), len(a, 0), len(a, 1)...); stdcall

В новом компиляторе я изменил порядок передачи адреса и длин:
Код:
PROCEDURE (a: ARRAY OF ... );
procedure (len(a, 0), len(a, 1)..., adr(a)); stdcall

Это оказалось удобнее для индексации массива и передачи в другую процедуру. Не знаю, почему я сразу так не сделал... Наверно, долго не обдумавал и просто взял первое что пришло.


Вернуться к началу
 Заголовок сообщения: Re: Компилятор Oberon-07
СообщениеДобавлено: Вт апр 17, 2018 10:07 am 
В сети

Зарегистрирован: Вт мар 08, 2016 11:00 pm
Сообщения: 311
Может лучше уж опционально транслировать в LLVM ?

В FASM-никакой выгоды, на 1й взгляд.


Вернуться к началу
 Заголовок сообщения: Re: Компилятор Oberon-07
СообщениеДобавлено: Вт апр 17, 2018 1:39 pm 
Не в сети

Зарегистрирован: Вс окт 27, 2013 8:13 pm
Сообщения: 118
Новый компилятор отличается от старого не только "более лучшим" качеством результирующего кода, а также исходного (в последнее время я пишу значительно лучше). Отличается архитектура: есть четкое разделение на фронт-энд (исходный код -> промежуточное представление) и бэк-энд (промежуточное представление -> целевой код). Разделение настолько четкое, что сейчас это физически две отдельные программы. Предполагается, что таких бэк-эндов будет несколько, в принципе, можно будет сделать бэк-энд LLVM. Но пока я транслирую в FASM. Часто говорят, что трансляция ЯВУ в ассемблер не имеет никаких преимуществ. Но я с этим не согласен: это позволяет легко контролировать правильность трансляции, первое время не заниматься опкодами и вычислением меток, а потом можно без проблем заменить ассемблерный код на машинный. Как это и было в первый раз. Может быть, LLVM выдаст более эффективный машинный код, но ассемблер x86 -- это единственный низкоуровневый язык который я кое-как знаю. Всё остальное мне нужно сначала прочитать, осмыслить и только потом приступать к трансляции. В общем, пока цель -- FASM, потом FASM -> машинный код, а потом посмотрим...


Вернуться к началу
 Заголовок сообщения: Re: Компилятор Oberon-07
СообщениеДобавлено: Вт апр 17, 2018 2:59 pm 
Не в сети
Аватара пользователя

Зарегистрирован: Вт июл 04, 2017 5:14 pm
Сообщения: 17
akron1 писал(а):
Байт-код не сложный, но обширный -- около 180 инструкций.


А можно, если это не секрет, узнать, почему так много?


Вернуться к началу
 Заголовок сообщения: Re: Компилятор Oberon-07
СообщениеДобавлено: Вт апр 17, 2018 3:29 pm 
Не в сети

Зарегистрирован: Вс окт 27, 2013 8:13 pm
Сообщения: 118
На самом деле, многие инструкции очень похожи, отличаются знаком операции, порядком и типом операндов.
Например, операции сравнения: их шесть ">", "<", ">=", "<=", "=", "#". Вроде немного...

Но во-первых, они могуть применяться к разным типам операндов: целым, вещественным и строковым. Для каждого типа нужна своя операция сравнения. Таким образом, ужЕ получается 18 операций.

Во-вторых, операнды могут быть константами и переменными (выражениями). Возможны три случая:
1) оба операнда переменные (выражения)
2) левый операнд переменная, правый -- константа
3) правый операнд переменная, левый -- константа
Если оба операнда -- константы, то это вычисляется при компиляции и код не генерируется. Каждый из этих случаев транслируется в машинный код по своим правилам.

18*3 = 54

То же самое можно сказать про арифметические операции: "+", "-" и т. д. А еще есть встроенные в язык процедуры: INC, ODD, LSL ... Вот так и получается ~180.

Конечно, некоторые инструкции полностью совпадают:

a > 5: больше(выраж, конст)
5 < a: меньше(конст, выраж)

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


Вернуться к началу
 Заголовок сообщения: Re: Компилятор Oberon-07
СообщениеДобавлено: Вт апр 17, 2018 5:50 pm 
Не в сети
Аватара пользователя

Зарегистрирован: Вт июл 04, 2017 5:14 pm
Сообщения: 17
akron1 писал(а):
...

Ага, теперь всё понял. Благодарю за развёрнутый ответ.


Вернуться к началу
 Заголовок сообщения: Re: Компилятор Oberon-07
СообщениеДобавлено: Вт апр 17, 2018 7:21 pm 
В сети

Зарегистрирован: Вт мар 08, 2016 11:00 pm
Сообщения: 311
akron1 писал(а):
Новый компилятор отличается от старого не только "более лучшим" качеством результирующего кода, а также исходного (в последнее время я пишу значительно лучше). Отличается архитектура: есть четкое разделение на фронт-энд (исходный код -> промежуточное представление) и бэк-энд (промежуточное представление -> целевой код). Разделение настолько четкое, что сейчас это физически две отдельные программы. Предполагается, что таких бэк-эндов будет несколько, в принципе, можно будет сделать бэк-энд LLVM. Но пока я транслирую в FASM. Часто говорят, что трансляция ЯВУ в ассемблер не имеет никаких преимуществ. Но я с этим не согласен: это позволяет легко контролировать правильность трансляции, первое время не заниматься опкодами и вычислением меток, а потом можно без проблем заменить ассемблерный код на машинный. Как это и было в первый раз. Может быть, LLVM выдаст более эффективный машинный код, но ассемблер x86 -- это единственный низкоуровневый язык который я кое-как знаю. Всё остальное мне нужно сначала прочитать, осмыслить и только потом приступать к трансляции. В общем, пока цель -- FASM, потом FASM -> машинный код, а потом посмотрим...

Возможно, если почитать и осмыслить чужой байт код - не только LLVM, есть же JVM, .net bc, hhvm итп, то найдутся удачные решения и для своего ?


Вернуться к началу
 Заголовок сообщения: Re: Компилятор Oberon-07
СообщениеДобавлено: Вт апр 17, 2018 10:35 pm 
Не в сети

Зарегистрирован: Вс окт 27, 2013 8:13 pm
Сообщения: 118
Siemargl писал(а):
Возможно, если почитать и осмыслить чужой байт код - не только LLVM, есть же JVM, .net bc, hhvm итп, то найдутся удачные решения и для своего ?

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


Вернуться к началу
 Заголовок сообщения: Re: Компилятор Oberon-07
СообщениеДобавлено: Вт апр 17, 2018 11:12 pm 
Не в сети

Зарегистрирован: Вс окт 30, 2011 6:43 pm
Сообщения: 1310
akron1 писал(а):
0CodErr писал(а):
Процедурные типы и переменные процедурных типов тоже попадают в этот список.
Если это лишнее — убрать не долго
Да, это конечно, лишнее.
Убрал процедурные типы и переменные процедурного типа из выпадающего списка.
akron1 писал(а):
При беглом осмотре нашел только один недочет: кроме суффикса "H" (INTEGER), шестнадцатиричные константы могут иметь суффикс "X" (CHAR), последние не подсвечиваются, но должны подсвечиваться как "строки".
Добавил для строковых шестнадцатеричных констант
Код:
<Regexp text="[0-9][0-9A-F]*X" lead="[^\w]"/> 
может в новой версии это заработает(у меня не самая новая).
Сейчас вместо stdcall|winapi|cdecl также допустимо писать какой-нибудь my_call, то есть, так:
Код:
    PROCEDURE [my_call] MyProcedure(Param1: INTEGER);
Вложение:
Ob07_.7z [2.23 КБ]
30 скачиваний


Вернуться к началу
 Заголовок сообщения: Re: Компилятор Oberon-07
СообщениеДобавлено: Вт май 01, 2018 3:57 am 
Не в сети

Зарегистрирован: Вс окт 27, 2013 8:13 pm
Сообщения: 118
Осталась необработана только одна инструкция промежуточного кода. Она довольно сложная, и сходу я не придумал, как её эффективно транслировать в ассемблер. Это новая операция, в старой версии языка её нет и в уже написанных программах естесственно тоже, поэтому пока я отложил её реализацию, но на днях, конечно сделаю. Компилятор успешно транслирует свой собственный код, а также после небольших модификаций удалось скомпилировать и Editor.
Антивирусы не ругаются на GUI-приложения и я выяснил одну из причин, почему есть такая проблема со старым компилятором. Остается еще много мелких недоработок: не доделан рантайм, нет поддержки KolibriOS, не очень информативные сообщения об ошибках компиляции, нет удаления неиспользуемых процедур, ненадежная работа с плавающей точкой, возможно, что-то еще.
Новый компилятор создает чуть более компактный код, но код при этом более разнообразный и поэтому хуже сжимается. Похоже, что размер сжатого кода будет всё же чуть больше, чем у старого компилятора. Но зато по скорости большое преимущество.

Провел ряд тестов на скорость между новым, старым компилятором и tcc.
1. задача размытия изображения (blur)
2. рекурсивное вычисление чисел Фибоначчи (fib)
3. задача о ферзях (queens)
4. сортировка "пузырьком" целочисленного массива (фиксированной длины и нефиксированной (открытый массив)) (bubble, bubbleOA)

Результат сравнения со старым компилятором (во сколько раз новый быстрее)

queens 1.85
fib 2.52
blur 5.01 (!)
bubble 2.20
bubbleOA 9.20 (!)

Очень слабым местом старого компилятора была индексация массивов (особенно открытых), что хорошо видно по результатам blur и bubbleOA.

Результат сравнения с tcc

queens 1.28
fib 1.02
blur 1.01

Как видно, качество кодогенерации в целом не уступает tcc.
При этом, в задаче blur идет интенсивная работа с массивами, а Оберон традиционно проверяет индексы при выполнении.
В задаче fib некоторый оверхед вносит синтаксис Оберона: из-за невозможности возврата из середины процедуры, выполняются лишние действия.
В задаче queens нет возвратов из середины и работа с массивами менее интенсивная, поэтому здесь tcc остался позади.

Сортировку на tcc не тестировал, потому что язык C позволяет выполнить ручную оптимизацию: заменить индексацию массива на инкремент указателя, что должно быть гораздо эффективнее.

Превзойти tcc, это, конечно не великое достижение, но в сравнении с тем, что было, весьма неплохо.


Вернуться к началу
 Заголовок сообщения: Re: Компилятор Oberon-07
СообщениеДобавлено: Вт май 01, 2018 9:59 am 
Не в сети

Зарегистрирован: Вс окт 30, 2011 6:43 pm
Сообщения: 1310
Ну, прогресс уже есть — это здорово!
Было бы ещё интересно сравнить результаты с другими реализациями Oberon(или Modula).
akron1 писал(а):
Превзойти tcc, это, конечно не великое достижение, но в сравнении с тем, что было, весьма неплохо.
Конечно, неплохо! Может можно ещё добиться скорости за счёт оптимизированных стандартных модулей? Тогда меньше пришлось бы париться из-за качества кодогенерации.


Вернуться к началу
 Заголовок сообщения: Re: Компилятор Oberon-07
СообщениеДобавлено: Вт май 01, 2018 1:33 pm 
Не в сети

Зарегистрирован: Вс окт 27, 2013 8:13 pm
Сообщения: 118
Компилятор XDS хоть и устаревший, но оптимизирующий, с ним сравнивать неинтересно и он еще имеет настройки оптимизации, вроде отключения проверок.
Можно будет сравнить с Black Box, он похоже один из лучших среди неоптимизирующих.

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

Впрочем, не все возможности исчерпаны: можно сделать табличный CASE, счетчики FOR хранить в регистрах. Вообще, компилятор использует только регистры eax, ecx и edx для хранения промежуточных значений выражений. Регистры ebx, esi, edi не используются и можно попробовать задействовать их для хранения часто используемых переменных, но для этого надо делать второй проход и серьезно изменить промежуточное представление.

Еще можно проанализировать промежуточный код, определить какие последовательности инструкций встречаются наиболее часто и транслировать такие последовательности как единое целое. Можно оптимизировать переходы: сейчас компилятор далеко не всегда делает переход по флагу после сравнения -- часто делается установка байта setCC, test и только потом переход. Но это всё в неопределенном будущем...

Оптимизация библиотек мало что даст, но из рантайма надо будет выжать как можно больше.


Вернуться к началу
Показать сообщения за:  Поле сортировки  
Начать новую тему  Ответить на тему  [ 83 сообщения ]  На страницу Пред. 1 2 3 4 5 6 След.

Часовой пояс: UTC+03:00


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

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 1 гость


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  
Создано на основе phpBB® Forum Software © phpBB Limited
Русская поддержка phpBB