LINUX.ORG.RU

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

 , qod, ,


4

5

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

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

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

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

Ответ на: комментарий от anonymous

Почему «приходится»?

Можно было бы просто сделать в лоб как в lua.

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

Кстати, фишка с select это идея Хохлова, и я сначала удивился… мягко говоря. А потом посмотрел-посмотрел. И понял, что это неплохо.

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

Perl way (timtowtdy) это про кудрявый синтаксис, когда какую-то тривиальную фигню типа if можно записать пятью разными способами, и кодер сидит и думает не про алгоритмы и архитектуру, а как покрасивше цикл изобразить.

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

Так это почти про любой ЯП уровня выше чем ассемблер сказать можно.

Вопрос в том, какое содержание мы вкладываем в вариативность синтаксических форм. Помогают ли они сделать код надёжнее, или нет.

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

Язык программирования всё-таки в той части, за которую отвечает слово «язык» - это про то, как мы читаем и понимаем тексты.

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

Можно было бы просто сделать в лоб как в lua.

Так не надо конечно делать. А кстати, что за фобия такая? Скобочки более декларативные же. begin…end это тяжелое наследие былых времен, когда прикладного программиста считали по дефолту тупым дятлом типа бухгалтерши, которому всё нужно разжевывать: вот начало процедуры, вася, а вот здесь конец, смотри не перепутай. Сейчас зачем это всё? Типа меньше шума? Все равно ведь нашумишь когда будешь структуры и типы описывать.

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

А кстати, что за фобия такая?

Никакой фобии. Пишу на Си-подобных чуть больше чем постоянно.

Скобочки более декларативные же.

Это утверждение лишено содержания. Более декларативной может быть суть, но не форма слов.

begin…end это тяжелое наследие былых времен, когда прикладного программиста считали по дефолту тупым дятлом типа бухгалтерши, которому всё нужно разжевывать: вот начало процедуры, вася, а вот здесь конец, смотри не перепутай.

Проблема begin…end не в том, что они «менее декларативные» (что бы это ни значило), а в том, что бессмысленные. Это тот же блок {}, только на на 6 бессмысленных нажатий на клавиатуре больше.

У меня никаких begin…end не водится.

Сейчас зачем это всё?

      }
    }
  }
}
      end:if
    end:loop_y
  end:loop_x
end:function
wandrien ★★
() автор топика
Последнее исправление: wandrien (всего исправлений: 1)
Ответ на: комментарий от hateWin

Судя по гитхабу, бутстрапинг уже завершен и компилятор переписан на самом языке. Уважуха!

Я срезал путь. Я взял сорцы, которые уже были забустраплены. И потом итеративно правил синтаксис.

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

Проблема begin…end не в том, что они «менее декларативные» (что бы это ни значило)

Это ты уже надрочился воспринимать их как разметку. Но это глаголы вообще-то, и они задуманы как императивные команды.

end:function

Клёвая разметка, но вообще редактор может подсветить скобочки и подсказать, что там в начале блока. Даже xml лаконичнее.

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

Клёвая разметка, но вообще редактор может подсветить скобочки и подсказать, что там в начале блока.

Вот со скобочками и приходится очень часто смотреть, откуда растёт эта скобочка.

В исходниках Qod ориентироваться намного проще даже с самым тупым редактором.

Как человек, который 20 лет пишет и читает код на разных {}-подобиях, вижу разницу.

Даже xml лаконичнее.

Лаконичность ты сам регулируешь. Можно писать просто end.

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

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

anonymous
()
Ответ на: комментарий от lovesan

в SBCL нет такого идиотизма.

den73 пытался прикладывать усилия к SBCL. Не знаю, что ему такого рассказали разработчики, но потом приходил на ЛОР, агитировал делать форк SBCL. Потом пилил его в одиночку.

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

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

Относительно второго, вот это характерная штука: «На самом деле я терпимо отношусь к алгольщине.»

Фишка-то в том, что это как раз не алгольщина. Если брать синтаксические формы, то алгольщина - это Алгол, Паскаль и… внезапно Си и всего его деривативы.

Си воспроизводит структуру форм Алгола почти дословно. С разницей всего в одну лишнюю лексему. (У Си на 1 одну лексему больше).

Алгол:
WHILE   усл DO утвержд
Си:
while ( усл )  утвержд

Алгол:
IF   усл THEN утвержд
Си:
if ( усл )    утвержд

Алгол:
BEGIN утвержд... END
Си:
{     утвержд... }

Как видно, открывающая круглая скобка у Си избыточна и добавлена чисто «для красоты». А в остальном это то же самое.

И если, например, брать Паскаль, то меня всегда раздражало, что при описании алгоритмов это просто «Си, в котором надо печатать больше букв». А зачем печать больше букв, если при прочих равных можно печатать меньше?

В то же время языки Ada, Ruby, Lua или вот Qod используют структуру с имплицитным блоком. Блок утверждений внедрён в составное утверждение по умолчанию, и его не требуется отдельно «начинать» и «завершать». Когда завершается синтаксическая форма, завершается и вложенный блок. Это решает проблему висячего else, делает код более выразительным и «плотным», а также (опционально) позволяет надёжно проверять границы блоков.

Классическое: «Буквы другие, смысл тот же» vs «Буквы те же, смысл другой».

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

ТС вроде делает компилятор для ЯП не особо похожего на лисп. Зачем бы ему прикладывать подорожник SBCL, загадка. Лисперы как всегда на своей волне.

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

Фишка-то в том, что это как раз не алгольщина. Если брать синтаксические формы, то алгольщина - это Алгол, Паскаль и… внезапно Си и всего его деривативы.

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

Как видно, открывающая круглая скобка у Си избыточна и добавлена чисто «для красоты».

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

В то же время языки Ada, Ruby, Lua или вот Qod используют структуру с имплицитным блоком.

Круто звучит, но там всё те же блоки, которые нужно как-то размечать. Иногда без явного begin никак не обойтись.

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

Круто звучит, но там всё те же блоки, которые нужно как-то размечать. Иногда без явного begin никак не обойтись.

Разница именно по смыслу. В if или while блок и соответствующий локальный scope возникает «естественным образом», то есть при чтении текста вполне закономерно, что он должен там быть.

Если же блок нужен явно, то для него нужно и отдельное представление, своя синтаксическая форма.

Если смотреть на синтаксис как на чисто формальный инструмент записи алгоритма, то подход Си, Паскаля и Алгола 60 выглядит более уместным. Но если рассматривать синтаксис как то, что оформляет смысл в виде зримой материи, то вещам, которые предназначены для разного, лучше по-разному и выглядеть.

Практических смыслов отдельного блока я вижу два:

  • Ограничение видимости и времени жизни переменных.
  • Возможность делать exit, перепрыгивая к концу именованного блока.

Выглядеть это может как-то так:

label my_block: do
  ...
  auto x = foo();
  ...
  when x == 0: exit my_block;
  ...
end:my_block

Пока, правда, ни метки, ни именованный exit не реализованы.

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

Прикольно, что по такой логике паскаль и си ничем не отличаются синтаксически, и зачем только люди копья ломали, лол.

Ну так: внутривидовая борьба самая жестокая.

Мало кому в голову придёт холивар «паскаль vs баш». А вот vs Си – очевидно.

Не для красоты, а для балансировки скобок.

Это незначительная деталь, можно было бы сделать так, и суть бы не поменялась:

int x = 0;
while x < 10: {
  if foo(x): printf("%d\n", x);
  x++;
}

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

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

Прикольно, что по такой логике паскаль и си ничем не отличаются синтаксически

Отличаются, но в других частях синтаксиса, а не в этой.

Паскаль: производные типы читаются линейно слева направо.

Си: производные типы читаются справа налево и изнутри наружу.

(Темы записи типов я еще коснусь в черновиках по языку.)

Паскаль: процедуры и функции.

Си: любая подпрограмма есть функция; функция может возвращать «ничего» как допустимый тип данных.

Паскаль: Name без скобок может означать вызов функции без аргументов.

Си: Вызов функции всегда явно маркируется скобками. Name без скобок это указатель на функцию.

Паскаль: присваивание и инкремент - это операторы.

Си: присваивание и инкремент - это операции.

Это из того, что быстро вспомнилось, вероятно заметных различий сильно больше…

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

Ну так: внутривидовая борьба самая жестокая.

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

anonymous
()

Столкнулся с нехваткой скобочек для языка.

Есть мысль использовать {} для записи литералов составных типов:

[]{1, 2, 3} /// массив
Foo{.x = 1, .y = 2} // структура
[]Foo{  // массив структур
  {.x = 1, .y = 2},
  {.x = 2, .y = 4},
}

Но в то же время есть мысль использовать {} для записи параметров шаблона:

auto x = Foo{int}(y);

Очевидно, что эти варианты конфликтуют между собой.

Не знаю, как выкрутиться. Составные скобки использовать не хочу, выглядят всрато.

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

Отдельно символы выглядит неплохо, но они рвут моноширинный текст:

xxxAABAAxxx
xxx「B」xxx

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

auto x = Foo:{int}(y);
auto x = Foo${int}(y);
auto x = Foo`{int}(y);
auto x = Foo#{int}(y);
auto x = Foo|{int}(y);

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

auto d = $[]{1, 2, 3}; /// массив
auto d = $Foo{.x = 1, .y = 2}; // структура
auto d = $[]Foo{  // массив структур
  {.x = 1, .y = 2},
  {.x = 2, .y = 4},
};
wandrien ★★
() автор топика
Последнее исправление: wandrien (всего исправлений: 2)
Ответ на: комментарий от wandrien

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

Не, этот вариант не прокатит. Структура-то может быть шаблонной.

Значит специальный символ должен стоять не перед типом, а после конструктора типа. Как-то так:

template{type T} struct Point2D of
  T x; T y;
end;

auto p = Point2D{int16}${640, 480};
wandrien ★★
() автор топика
Последнее исправление: wandrien (всего исправлений: 1)
Ответ на: комментарий от monk

Он шизофрению творил, и продолжает творить. Натурально то есть, ну, бредовые идеи там и далее по тексту из DSM.

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

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

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

Пункты вида «Recursive descent parser with operator-precedence expression parser» там в списке как бы символизируют.

Хотя общие представления иметь, конечно, стоит. Иначе парсер не написать.

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

Я кстати, выше давал ссылку на то, как у меня устроен парсер выражений с приоритетом операций: Qod. Опубликовал исходники компилятора, над которым работаю (комментарий)

Наверняка он как-то по умному называется в литературе, но я не знаю. Так как его придумал буквально на пальцах, ad-hoc.

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

дык если именнованые блоки то тогда

break и continue + именнованые блоки + when(али какой Short-circuit evaluation если всё в языке выражения) тьюринг полно - но без произволтого гото на метку

интересней(пока доки не смотрел :) ) - как структуры данных определяются

ну и есть какая асинхро|сопро|конку|парале|лениво вот это вот всё в языке?

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

дык сам Фонат Вирта с его однопроходными - компиляция хороша когда интерпретатор может компилировать на ходу без особой потери т.е. очередные live system - но с подержанием когерентности между текущим состоянием исполняемой вещи и выдачей ей эквивалентного сырца по запросу али как

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

но без произволтого гото на метку

Разрешены continue в цикле и exit в блоке/цикле. Таким образом в графе переходов не может быть goto куда попало. Такой граф удобно анализировать на уровне AST, без раскладки в граф базовых блоков промежуточного языка.

пока доки не смотрел

А их пока и нет))

ну и есть какая асинхро|сопро|конку|парале|лениво вот это вот всё в языке?

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

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

си был «урезан» отказом от вложенных исполнимых именованных блоков(в паскале проседура может быть (в симуле стала)-класом чьи подпроцедуры это методы :)

поэтому в С(С++) класс это виртуализация структуры данных struct в отличии от Симулки где класс это обобщение кода процедуры с вложениями :)

код это данные это код очередное

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

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

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

Про классификацию значений:

https://github.com/wandrien/qod/blob/master/drafts/comptime-and-runtime-expr.md

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

у utf8 много парных для скобок

Я пробовал с разными вариантами написать примеры, всё так себе. Они не особо читаются в массиве текста.

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

входной алфавит языка обрыдлый ascii7 ?

Да. Наверное напишу в доках, что расширение входного алфавита – на усмотрение реализации.

Но лично я против всех этих ф = открыть(имяФайла);. Всё из-за того, что в юникоде много разных символов, которые выглядят одинаково. А это идёт в противоречие принципами дизайна данного ЯП.

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