Re[7]: Хочется странного
От: elmal  
Дата: 28.12.24 18:55
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>а) мнемоники команд. Банальная штука типа "положи в стек целую константу" требует енкодинга команды и енкодинга константы. Делать это каждый раз руками? Код становится невозможно даже прочитать, не то что поддерживать. Интуитивно хочется иметь готовую функцию типа EmitLoadConstant(x byteCodeStream, int value) или byteCodeStream.EmitLoadConstant(value).

А что, сейчас такую вещь как словари, студенты не знают? Причем не знают в джаваскрипте, где это основная структура данных? Я вот считаю, что прежде чем рассказывать студентам как компилятор работает, нужно их с базовыми структурами данных познакомить и приучить их использовать. А так да, я в курсе что сейчас и выпускают специалистов без этого знания.

Относительно готовых функция и того, как ты считаешь они должны выглядеть. То, что ты привел — это нарушение Single Responsibility Principle в чистом виде. Я бы делал проще, функция encode, на вход енам команды и опциональные параметры (если язык понавороченнее, то можно и поинтереснее фичи использовать вроде Sealed Class и тому подобному), на выходе массив байт. Внутри логика преобразования, причем весьма тривиальная. И отдельно уже идет запись в стрим или еще куда, уже стандартными средствами. Базовый принцип — нельзя смешивать логику и ввод вывод, это всегда должно быть отделено. В идеале сначала ввод без логики, затем операции, затем вывод без логики, тривиальный — если так делать, то код прекрасно становится читаемый и поддерживаемый.

Кстати рекомендую прочитать:
https://habr.com/ru/companies/jugru/articles/858418/
Принцип блин в 1977 сформулирован!

S>б) goto. Не хочется вручную вычислять байтовые смещения с риском промахнуться. Удобнее иметь функции вида MarkLabel() c возможностью использовать результат этой функции в эмите jump-инструкций

Тоже самое, эту функцию написать самому тривиально, там кода 3 строчки. Если студент не в состоянии это написать сам — рано ему компиляторами заниматься.

S>г) предсказание будущего. Каждый метод указывает в заголовке размер байт-кода, количество переменных, а также максимальную глубину стека. При кодогенерации это довольно-таки тяжело оценить заранее — так что либо делать два прохода по внутреннему представлению, либо, всё-таки, инкапсулировать это всё в некий класс, отвечающий за порождение байтиков, который всё это рассчитает самостоятельно с гарантиями корректности и без замусоривания пользовательского кода.

Да, нужно инкапсулировать. И там не будет ничего сложного и громоздкого. Можно через ленивые вычисления и все такое, совершенно не обязательно в несколько проходов. А на деле — а хоть бы и в несколько проходов, что тут такого? Ну медленнее, но зато код будет вообще шикарный и простой, прекрасно тестируемый. Хоть 10 проходов, лишь бы почище сам код был.

Вот студенты и должны научиться это делать. Написать компилятор учебный — это именно требуется разобраться как подобные вещи делаются с нуля. Без библиотек кодогенерации, только через стандартные структуры данных, средства языка и все такое. Для начала следует сделать интерпретатор, крайне б желательно было осилить книжку SICP, чтоб мозги на место поставить, и там собственно пример как делается интерпретатор вполне есть. Изменений как из интерпретатора сделать компилятор, кстати, будет вообще минимум! Тупо бежишь по AST, но не непосредственно выполняешь, а делаешь кодогенерарацию.

Если же пользоваться готовыми библиотеками — ни хрена студенты не поймут! И придется еще тратить время на то, чтоб с библиотекой разобраться. И далеко не факт что API библиотеки будет сделано достаточно хорошо. В результате что был курс, что его не было — в памяти не останется вообще ни черта! Особенно если упор делать не на реализацию и программу, а на отчет и его защиту с презентациями, как у нас тут некоторые делают, да еще и ЕСПД привлекают начиная с первого курса для даже лабораторных.

На деле — прекрасная учебная задача, на которой студенты могут набить руку и попробовать не городить спагетти говнокод, а написать прекрасный компактный и поддерживаемый код, пусть и не идеально шустрый, однопроходный и все такое. Однопроходный тоже кстати можно написать достаточно компактно и поддерживаемо, но напрягаться умственно придется сложнее, все эти ленивости и все такое, контекст держать — если нет цели сделать максимально шустро, лучше сделать просто максимально понятно. Нужно именно приучить студентов не говнокодить копипастить, а бороться со сложностью и запутанностью, походя самим писать вспомогательные функции для удобства на скорость, причем чтоб тратить на это меньше времени, чем если говнокодить все в лоб! А то ведь большинство такому не научится даже на работе реальной, тупо никто не покажет как можно, так и будут блин ждать пока добрый буржуй напишет удобную функцию, а если функции нет, так и будут копипастить блин один и тот же код и даже мысли блин не возникнет написать так, как удобно. Собственно большинство библиотек тоже ни фига не удобны в использовании.

А вообще, я блин в шоке насколько мало программистов с профильным блин образованием в курсе как работают интерпретаторы, компиляторы и т.д. Не на детальном уровне, а на базовом и общем!!!! Мне в обычной работе, если что, неоднократно приходилось это писать. Чаще всего интерпретаторы, именно компилятор не было смысла, но кодогенератор тоже приходилось писать далеко не один раз, и напишу еще не раз. Вроде не совсем ненужный навык.

PS Хотел еще ссылку на охрененный курс по компиляторам на ютубе привести, но блин не могу найти. Даже университет не помню какой, толь MIT, толь Беркли. Там несколько, более ранний был довольно стандартный, профессора звали что то вроде Кубианович, начинается точно на Куби, а вот более поздний там преподавали поинтереснее и был фокус на написании DSL и еще там в названии было Hack Your Language. Очень мне б блин самому не помешало пересмотреть, а то как понадобилось однопроходный парсер с приоритетами операций писать — я блин нормально хрен написал, тупо забыл как это все элегантно делается.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.