LINUX.ORG.RU

Qod. Опубликовал исходники компилятора, над которым работаю

 , qod, ,


4

4

Финально определился с названием языка, подчистил разные хвосты и написал README. Теперь наконец-то можно посмотреть на нечто большее, чем просто фрагменты кода в постах на форуме: https://github.com/wandrien/qod/

Драфты по дизайну языка пока еще не готовы. Если перед НГ завала работы не будет, то может выложу их в течение пары недель. Черновики пишу на русском, осилить всё чётко сформулировать на английском в разумные сроки я точно не смогу. На русском-то не всегда получается.

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

А пока можно посмотреть на сам код вживую.

Вчера частично избавился от лишнего mov после операции получения остатка от деления:

         mov     EAX,  dword [EBP-16]
         xor     EDX,  EDX
         div     dword [EBP-20]
-        mov     EAX,  EDX
-        push    EAX
+        push    EDX
         push    dword [EBP+8]
         call    @10865
         mov     EAX,  dword [EBP+8]
         xor     EDX,  EDX
         div     dword [EBP+12]
-        mov     EAX,  EDX
-        test    EAX,  EAX
+        test    EDX,  EDX
         je      @13250

А также случайно обнаружил, что присваивание числового литерала булевой переменной (bool b = 0;) роняет компилятор вместо диагностики тайпчека. Пофиксил.

wandrien ★★
() автор топика
Ответ на: комментарий от wandrien

код притом, что switch делается как выборка адреса ветки исполнения из таблицы переходов, а if - как последовательная проверка условий пока не найдется то, что дает true.

это у тебя с хохловым это одно и то же небось

alysnix ★★★
()
Ответ на: комментарий от alysnix

Это деталь реализации. Выбираться он может хоть обращением к Всезнающему Оракулу, для описания языка это иррелевантно.

Познакомься с тем, как работает современный оптимизирующий компилятор:

enum X {
    X1, X2, X3, X4, X5
};

extern int foo1(int);
extern int foo2(int);
extern int foo3(int);
extern int foo4(int);
extern int foo5(int);

int bar(X x, int y)
{
    if (x == X1) return foo1(y);
    if (x == X2) return foo2(y);
    if (x == X3) return foo3(y);
    if (x == X4) return foo4(y);
    if (x == X5) return foo5(y);
    return 0;
}
bar(X, int):
        mov     eax, edi
        mov     edi, esi
        cmp     eax, 4
        ja      .L4
        jmp     [QWORD PTR .L6[0+rax*8]]
.L6:
        .quad   .L10
        .quad   .L9
        .quad   .L8
        .quad   .L7
        .quad   .L5
.L7:
        jmp     foo4(int)
.L5:
        jmp     foo5(int)
.L10:
        jmp     foo1(int)
.L9:
        jmp     foo2(int)
.L8:
        jmp     foo3(int)
.L4:
        xor     eax, eax
        ret

Что ты не понимаешь про семантику, это уже ясно.

wandrien ★★
() автор топика
Ответ на: комментарий от wandrien

не кидай мне выхлоп чужих компиляторов. тут твой обсуждают.

а дай-ка код на асме для выражения(это псевдокод)

int lval = 10;
int lcnt = 0;

switch (lval) 
case 1: lcnt = lcnt+10
case 5: lcnt = lcnt+20
case 10:lcnt = lcnt+30
default:  lcnt = 100
}

короче интересно, как у тебя табличка генерится. у тебя похоже и нет ее.

alysnix ★★★
()
Последнее исправление: alysnix (всего исправлений: 2)
Ответ на: комментарий от wandrien

Это деталь реализации.

неа. это какой-компилятор подменил if, в силу того, что он просто есть извращенный switch, на нечто вроде него.

что как раз и говорит, что switch - это вполне себе базовый оператор, в который иногда вон и if переделывают.

то есть switch это не «деталь реализации», это и есть реализация. и без этой «детальки» твоя телега далеко не уедет.

alysnix ★★★
()
Последнее исправление: alysnix (всего исправлений: 1)
Ответ на: комментарий от alysnix

А если крестовый код в лямбда-исчисление компилировать, то там какие «базовые операторы»?

Эксперт, у которого «этих языков как мух» (или как там было), продолжает генерировать лулзы.

wandrien ★★
() автор топика
Ответ на: комментарий от wandrien

А если крестовый код в лямбда-исчисление компилировать, то там какие «базовые операторы»?

покажи выхлоп для твоего оператора switch, и зубы крестами не заговаривай, умнег блин

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

alysnix ★★★
()
Последнее исправление: alysnix (всего исправлений: 2)

Ускорил парсинг немножко в процессе чистки технического долга: https://github.com/wandrien/qod/commit/e499dea752dc5886920aa142601c5b6f6b751823

До:

=> Running valgrind --tool=callgrind (--optimize speed)
==214907== I   refs:      554,126,370
=> Running valgrind --tool=callgrind (--optimize size)
==214946== I   refs:      597,024,432
=> Running valgrind --tool=callgrind (--optimize none)
==214958== I   refs:      347,194,152

После:

=> Running valgrind --tool=callgrind (--optimize speed)
==252758== I   refs:      488,619,082
=> Running valgrind --tool=callgrind (--optimize size)
==252789== I   refs:      531,807,452
=> Running valgrind --tool=callgrind (--optimize none)
==252796== I   refs:      280,350,460
wandrien ★★
() автор топика
when pARGS >= nDICT:
		StopInternal(__FILE__, __LINE__);

такого рода лабуда есть классический assert (bool, …) и есть это в любом и компиляторе и не компиляторе…почему хохлов этому тебя не надоумил, непонятно.

и писать надо нечто вроде этого

assert(pARGS < nDICT, __FILE__, __LINE__);

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

alysnix ★★★
()
Ответ на: комментарий от wandrien

Ускорил парсинг немножко

ааа… чтобы ускорить парсинг, тебе нужно делать нормальный лексер(тебе это говорилось), а не фигней в потемках заниматься.

тогда ты в гордостью отринул предложение…а теперь ловишь блох в карманах.

лексер пиши, с этого и надо было начинать

alysnix ★★★
()
Последнее исправление: alysnix (всего исправлений: 2)
Ответ на: комментарий от alysnix

классический assert (bool, …) и есть это в любом и компиляторе и не компиляторе…

Ты теперь решил и свои навыки чтения манов продемонстрировать?

Похвально, но оценка неудовлетворительная.

$  COLUMNS=1000 man --nj assert | grep NDEBUG
       If the macro NDEBUG is defined at the moment <assert.h> was last included, the macro assert() generates no code, and hence does nothing at all.  It is not recommended to define NDEBUG if using assert() to detect error conditions since the software may behave non-deterministically.
       assert() is implemented as a macro; if the expression tested has side-effects, program behavior will be different depending on whether NDEBUG is defined.  This may create Heisenbugs which go away when debugging is turned on.
wandrien ★★
() автор топика
Ответ на: комментарий от wandrien

каких еще манов???

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

alysnix ★★★
()
Ответ на: комментарий от alysnix

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

А что именно нечто сделать? Что именно сделать, га?

wandrien ★★
() автор топика
Ответ на: комментарий от wandrien

Как скажешь

ты дурной вообще? assert это такая устоявшаяся конструкция для проверки предиката. я не утверждал, что она есть в любом языке в виде оператора. я утверждал то, что проверки предикатов надо писать не мусорным кодом с ифами, а некими assert’ами причем лучше своими, а не встроенными в язык или его системные либы, если оно так.

напиши свой ассерт и не мучай читателя уже.

alysnix ★★★
()
Последнее исправление: alysnix (всего исправлений: 1)
Ответ на: комментарий от wandrien

Ясно.

что ясно. «assert на любом языке» - это повествование тебе о том факте, что это может быть реализовано хоть макрой(если макры есть), хоть функцией, хоть с закосом в полиморфизьм, шаблоном. и реализовано пользователем!

в язык это лучше вообще не вставлять, поскольку не всех может устраивать предопределенная форма assert, и они все равно будут писать свои.

alysnix ★★★
()
Последнее исправление: alysnix (всего исправлений: 1)
Ответ на: комментарий от wandrien

ты вообще народу говнеца подкинул.

твои тексты, в силу бутстреппинга, ни гитхаб подсветить или распутать на символы не может, ни ide какая-нить. и грамматику ты отложил на потом.

приходится их распутывать как письмена индейцев майя. я вот кажется вижу багу, но мне надо найти место, где вызывается твоя функция…

функция поиска в репозитории ругается, что репозиторий еще не индексирован.

способ - скачать все к себе и искать штатными средствами буду воспринимать как хамство.

alysnix ★★★
()
Последнее исправление: alysnix (всего исправлений: 2)
Ответ на: комментарий от alysnix

способ - скачать все к себе и искать штатными средствами буду воспринимать как хамство.

Это вообще какая-то странная предъява. По такой логике делать любой новый самодостаточный язык – это хамство.

X512 ★★★★★
()
Ответ на: комментарий от X512

Это вообще какая-то странная предъява.

не странная - бутстреппингом занимаются с уже сформулированным языком, а не во время с ним «экспериментов».

ради «экспериментов» пиши язык свой на си или плюсах. как только язык устоялся - если тебе особо приспичило - делай бутстреппинг. в принципе, многие языки так и живут на сях… пока кого-нить не торкнет переписать компилятор на сам язык.

а пользователю вообще все равно, на чем он.

alysnix ★★★
()
Последнее исправление: alysnix (всего исправлений: 1)
Ответ на: комментарий от wandrien

Пространство имён qod.optional содержит имена,

где определение «пространства имен»-то?

когда пишешь такие доки, ставь ссылки на доки, в которых даны определения используемых терминов.

описываешь типы - рассказывай с кем они совместимы и как.

тип noreturn - странный. смысл его неясен, как применять, и зачем - непонятно.

Тип type

у тебя и правило декларации типа начинается с «type», и есть такой тип «type»… никто не запутается там? такие вот неоднозначности до добра не доводят… верней не дают ничего кроме проблем.

alysnix ★★★
()
Последнее исправление: alysnix (всего исправлений: 2)
Ответ на: комментарий от vM

Стало интересно измерить скорость компиляции в «строках в секунду». (Очень зыбкая величина.)

#!/bin/bash

O="/tmp/qodc.tmp.asm"

repetitions=30

run_test() {
	for a in {1..30} ; do
		../build/compiler/qodc_c --optimize none --output "$O" ctx4lnx.qd
	done
}

LANG=C

sleep 2
T="`(time run_test) 2>&1 | grep real | grep -P -o '(?<=0m)[0-9.]+'`"

lines=`cloc --json --read-lang-def=../extra/qod.cloc-lang-def --exclude-dir=tests,samples . | jq .Qod.code`

total_lines=$(($lines * $repetitions))

lines_per_second="`echo "$total_lines / $T"| bc`"

echo "total_lines      = $total_lines"
echo "time             = $T"
echo "lines per second = $lines_per_second"

На Core i5-2450M получилось так:

total_lines      = 296430
time             = 2.530
lines per second = 117166
wandrien ★★
() автор топика
Последнее исправление: wandrien (всего исправлений: 1)
Ответ на: комментарий от gaylord

while (! ... stop читается прям по логике языка: «пока не останов».

А чтобы читать until, мысленно не переводя в голове на нормальную логику, я недостаточно американец)

wandrien ★★
() автор топика
Ответ на: комментарий от gaylord

там не только условие противоположное, в while и repeat. там одно условие проверяется ДО, а второе ПОСЛЕ

короче одно описывается грамматической формой bnf

while ->  {action}
repeat ->  action {action}

вот в зависимости от формы и надо ставить то или это.

alysnix ★★★
()
Последнее исправление: alysnix (всего исправлений: 1)
Ответ на: комментарий от gaylord

У меня есть

while прямое условие do
  ...
end

и

repeat
  ...
until обратное условие;

Второе весьма логично синтаксически. Но если смотреть через призму семантики, то как человек, который 20 лет пишет на языках, имеющих цикл do {} while (), я ломаю себе мозг каждый раз.

wandrien ★★
() автор топика
Ответ на: комментарий от gaylord

Но нет repeat ... while?

Нету.

Потому что это будет противоречить принципу лёгкости распознавания синтаксических форм глазами. Видя while, вы не будете сразу понимать, это конец прежнего цикла или начало вложенного.

wandrien ★★
() автор топика
Ответ на: комментарий от wandrien

Значение типа не материализуемо в компилируемую форму. Не существует каких-либо бит, которые можно было бы поместить в исполняемый файл в качестве «типа». Тип это абстракция, которой компилятор оперирует исключительно при сборке программы.

если ты сможешь в классы и наследования, ты поймешь, как ты горько ошибался… но это уже совсем другая история.

alysnix ★★★
()
Ответ на: комментарий от alysnix

у тебя и правило декларации типа начинается с «type», и есть такой тип «type»… никто не запутается там?

Запись type t = [10]char; это ровно такая же запись как int x = 2 + 3;. В объявлении переменных не путаешься?

wandrien ★★
() автор топика