Комментарии 91
Вот зря вы их всех в одну кучу. Разница между этими двумя, и условным ANTLR — огромная. Примерно такая же, как между вашим способом написать рекурсивный спуск вручную, и самим yacc.
Но в общем ANTLR позволяет сосредоточиться именн на сути своего языка, а не размениваться на мелочи.
Модель памяти примерно соответствовала «малой» (если кто-то ещё помнит эту терминологию 16-битной эпохи): для кода, глобальных данных и стека выделялось по одному сегменту размером 64 кб.Позанудствую: это tiny-model. «Малая» модель это 64 кб для кода отдельно, и для данных 64 кб отдельно.
Однако во внутренней процедуре нет адреса стекового кадра внешней процедуры — внутренняя процедура не знает, от чего отсчитывать адрес искомой переменной. Этот адрес приходится всякий раз передавать во внутреннюю процедуру через дополнительный скрытый параметр.
А как же неиспользуемая из-за её тормознутости (но однако тем не менее существующая) инструкция ENTER? Для этого в принципе и была создана.
push bp
mov bp,sp,
sub sp,local_size
или с сохранением ещё адресов предыдущих фреймов в зависимости от уровня вложенности. Вот в Turbo C 2.0 (или даже ещё в Turbo C 1.5, за давностью лет не помню) если в установках компилятора выставить процессор выше чем чем x86 использовалась. В Borland C++ 3.1 AFAIR эта инструкция уже не применялась, leave остался, а вот enter уже не использовался. А leave используют до сих пор. В принципе инструкции хорошие, годные, вот если бы они такое бешеное количество тактов не занимали по сравнению с последовательностью обычных команд, получилось бы вполне православно. Но как говорил Черномырдин: «Хотели как лучше, а вышло как всегда» :-)
пусть взгляды Вирта уже устарели и утратили всякую связь с реалиями ИТ, а компиляторы делают совсем не так, как учил Вирт.Серьёзнааа???? Да вроде ничего не изменилось. А взгляды Вирта вполне себе живут и здравствуют. Хотя, возможно, мы о разном. Так что там за взгляды, в чём они устарели, и почему они «утратили связь с реалиями ИТ»?
Как гошник поддерживаю вопрос тоже!
Подход Go (да и оберона, наверное) – это простота, которая хуже воровства. Наличие только простых конструкций вынуждает для решения мало-мальски нетривиальных вещей писать огромные простыни кода, в которых каждая строчка, конечно, проста и понятна, а вот что они делают вместе...
Как бы оценки тут не давались, просто сказал, что эти подходы живы.
Или "вы хотите поговорить об этом"?
На ассемблере пишут и операционные системы, и прикладные решения.
Начиная с Modula ( т.е. ещё до Modula-2 на котором была написана AS/400, первоначально ) был взят курс на создание модуля SYSTEM с функциями ADDRESS(), SIZE() и т.п.
Как итог, на Алголах стало возможно программировать и ОС, и прикладное ПО.
Да всякие, позволяющие повысить уровень абстракции, потому что задачи из некоторой предметной области я хочу решать по возможности декларативно, оперируя терминами из этой области, а не байтиками, указателями и циклами. Повысить, стараясь не дать этим абстракциям протекать, сохраняя надёжность и гарантии корректности, потому что мне, как человеку, свойственно ошибаться и быть невнимательным.
Если конкретнее, то это, например, развитые системы типов (желательно с параметрическим полиморфизмом, алгебраическими типами, классами типов или трейтами – для type-driven development и correctness by construction), вывод типов (чтобы не загромождать код очевидными аннотациями), произвольные операторы или хотя бы их перегрузка (для удобных eDSL), ненавязчивая (но корректная) обработка ошибок, вменяемое метапрограммирование (не препроцессор и кодогенерация, а хоть какие-то приличные макросы)...
А то, что «а вот на языке X делают задачу Y», не особо свидетельствует о удобстве и пригодности X для Y. Можно и молотком шурупы забивать, можно и топором бороду брить, можно и в экселе 3D-движок написать.
Но это, конечно, если совсем привередничать. А так – даже банальный foreach вместо for/while, и жить уже становится лучше и веселей.
В общем мы тут подумали и решили ответить статьёй, тем более про Оберон давно статей не было.
По поводу восстановления после ошибок. Цитирую Compiler Construction Вирта, раздел «7.3. Coping with syntactic errors».
1. As many errors as possible must be detected in a single scan through the text.
2. As few additional assumptions as possible about the language are to be made.
3. Error handling features should not slow down the parser appreciably.
4. The parser program should not grow in size significantly
Что касается конкретного компилятора — то это простой однопроходной компилятор, написанный собственными «руками и мозгами». Он сознательно сделан таким — чтобы студенты могли понять и воспроизвести нечто подобное за отведенное время. В данном случае, смысла в использовании различных генераторов нет — там нечему учиться, «нажми на кнопку и получишь результат...». Описанное тобой относится именно к генераторам, вручную написанный парсер не имеет таких проблем.
В целом ведь дело не в самодовлеющей простоте и минималистичности. Помните виртовский метод пошагового уточнения/улучшения программы? Это применимо и к языкам. Представьте себе язык программирования, стандарт на который с каждой версией становится все тоньше, все яснее. На каждой итерации выделяются более мощные, общие языковые механизмы, а все не нужное отсекается. В этом смысле Оберон хорош даже не как конкретный ЯП, а как идея подхода к разработке ЯП.
Виртовский учебник лично Вас научил технологии создания простых компиляторов. И не только Вас — эту небольшую книгу можно рекомендовать в качестве начального введения в предмет. Ничего более краткого и доходчивого, по большому счету, до сих пор не написали.
Такой же точно подход применили разработчики языка Go. Та же самая простота. И не удивительно, одним и разработчиков был ученик, прошедший школу Вирта.
Оберон так и остался… академическим проектом.На нём разрабатывают промышленное ПО. Вы, скорее всего, ещё не успели прочитать статьи от Kemet?
Если не нравятся спорные моменты, как то, отсутствие беззнаковых целых, то давайте посмотрим на современные Modula-2 ( их разработчики, кстати, называют их Modula-2(Oberon-2), так как синтаксис объекто-ориентированного программирования в стиле Н.Вирта).
Давайте возьмём Modula-3 ( проект, кстати, «скорее жив чем мёртв», сегодня было многообещающее, в практическом плане, сообщение в списке рассылки).
Оберон-технологии используются в различных промышленных системах, scada, медицинских приборах, дронах, управляющем по и тд.
В октябре 2018 в Орле прошел День Оберона. В теме есть ссылки на видео докладов, в том числе доклад Юрга Гуткнехта из ETHZ.
Так же полезно почитать Igor Schagaev · Thomas Kaegi-Trachsel. Software Design for Resilient Computer Systems, ISBN-978-3-319-29463-6
Если, как и цикл FOR, вернули в современные Oberon-ы, то я только «за»
основной заслугой (Н.Вирта) так и останется то, что в далёкие 70-е он придал верный импульс Алголу-60, создав Паскаль.Я бы поставил на первое место Modula-2:
решение проблемы блоков BEGIN END в IF ( ELSIF), циклах;
приход Алголов в системное программирование и т.д.
Уточню, что я имел в виду: Вирт всегда был и остаётся сторонником экстремальной простоты. Сравните два пути развития Паскаля. Первый — по Вирту: Паскаль — Модула-2 — Оберон. Второй — по Borland: Паскаль — Турбо-Паскаль — Дельфи. Первый путь — путь упрощения, второй — путь усложнения. Индустрия однозначно предпочла второй путьВо-первых сложно подсчитать объективно: «допинг» применяли обе стороны — Н.Вирт «выкидывал» цикл FOR и беззнаковые целые, его ученики-коммерсанты придумывали вместо RECORD с указателями на процедуры новые ключевое слово OBJECT
Во-вторых владельцы Delphi не смогли ( скорее, решили съэкономить) и просто лицензировали(?) разработки комады FPC для x64.
Т.е. путь усложнения имеет и отрицательные стороны.
Ну и финальный аккорд:
Во времена холодной войны ( с этапами оттепелей а-яля «Союз-Апполон») обе стороны
очень внимательно отслеживали состояние дел «по ту сторону окена».
Не только аэродинамику советских мини-челноков 60-70x, но и системы управления.
В частности, Э.Дейкстра ( если читать оригнал) говорил не о запрете BASIC в средних школах. Речь шла о Сибирском отделении Академии Наук СССР.
Теперь внимание: Н.Вирт был зван и тепло принят в Новосибирске.
Его ученик бизнесмен-саксофонист «срубивший бабла» и ушедший на пенсион раньше своего технологичекского гуру — я как-то сомневаюсь
Не став развивать Borland Modula-2 ( был для CP/M) и предоставив бороться не компиляторам, а благим пожеланиям от MISRA, с «парными фигурными скобочками»
выше упомянутый бизнесмен de-facto соучастник Тойота скандала с анти-тормозами в легковых автомобилях.
уже почти 20ть лет прошло, а я до сих пор часто использую именование result :)
В тот день, когда я перешёл с 32-битной Windows XP на 64-битную Windows 7 без виртуальной машины DOS, я мысленно похоронил свой проект.
Реинкарнируйте в DosBOX
Однако настоящая трудность, специфичная для Паскаля, подстерегала совсем в другом месте — в работе с вложенными процедурами. Может возникнуть совершенно невинная надобность обратиться к локальной переменной внешней процедуры из внутренней. Однако во внутренней процедуре нет адреса стекового кадра внешней процедуры — внутренняя процедура не знает, от чего отсчитывать адрес искомой переменной. Этот адрес приходится всякий раз передавать во внутреннюю процедуру через дополнительный скрытый параметр. Подозреваю, что именно это осложнение заставило разработчиков C вовсе отказаться от вложения функций. Однако в Паскале они есть, и с этим приходится считаться.
Вот что получается: Н.Вирт ( и Вы) смогли осилить, а те кто якобы не «утратили всякую связь с реалиями ИТ» — как в анекдоте N13 «не смогли, или не захотели»
А потом «почему-то» новейшие автомобили при нажатии на педаль тормоза...
P.S. см. Глава 5. Компиляторы
в книге
Л. Бек Введение в системное программирование
An introduction to systems programming
Leland L. Beck
San Diego State University
Addison-Wesley Publishing Company Reading, Massachusetts Menlo Park, California Don Mills, Ontario Wokingham, England Amsterdam Sydney Singapore Tokyo Mexico City Bogota Santiago San Juan
Л. Бек
Введение в системное программирование
Перевод с английского Н.А. Богомолова, В.М. Вязовского и С.Е. Морковина под редакцией Л.Н. Королева
Москва «Мир» 1988
ББК 32.973
Б42
УДК 681.142
Бек Л. Введение в системное программирование: Перевод с английского. — М.: Мир, 1988. — 448 с., ил.
ISBN 5-03-000011-9
Монография учебного характера, написанная американским специалистом. В ней изложены все основные компоненты системного программного обеспечения. Особое внимание уделено их взаимосвязи с архитектурой вычислительных комплексов. Конкретные реализации компонентов обсуждаются на примере трех современных вычислительных систем: IBM/370, VAX, CYBER.
Для системных программистов, аспирантов, студентов вузов.
ББК 32.973
КРАТКОЕ ОГЛАВЛЕНИЕ:
От редактора перевода (5).
Предисловие (7).
Глава 1. Основные понятия (11).
Глава 2. Ассемблеры (38).
Глава 3. Загрузчики и программы связывания (122).
Глава 4. Макропроцессоры (178).
Глава 5. Компиляторы (222).
Глава 6. Операционные системы (312).
Глава 7. Другие компоненты системного программного обеспечения (399).
Приложения (430).
Литература (437).
Предметный указатель (440).
Редакция литературы по математическим наукам
Учебное издание
Леланд Л. Бек
ВВЕДЕНИЕ В СИСТЕМНОЕ ПРОГРАММИРОВАНИЕ
P.P.S. А лучше — полностью прочтите
P.P.P.S.
Я не профессиональный программистЯ понимаю, что не все учились по специальности 22.04, но и я книгу нашел в библиотеке Заводского района
( И критика автора языка Modula-2 — в статье про его ранний язык ...)
forum.sources.ru/index.php?showtopic=8810
P.S. Больше всего выглядит как Паскаль, но внутреннее построение оригинальное.
Реинкарнируйте в DosBOX
Именно это я и сделал ради скриншотов для поста. Однако запуск в DOSBox всегда оставляет ощущение искусственности происходящего.
Вот что получается: Н.Вирт ( и Вы) смогли осилить, а те кто якобы не «утратили всякую связь с реалиями ИТ» — как в анекдоте N13 «не смогли, или не захотели»
Насколько я знаю, для вложения процедур у Вирта была и вполне прагматическая причина — сведение косвенной рекурсии к прямой. Опережающих описаний в оригинальном Паскале не было. Если они в языке есть, то вложенные процедуры не слишком нужны. Да и, откровенно говоря, они не самый лучший способ структурирования кода.
для вложения процедур у Вирта была и вполне прагматическая причина — сведение косвенной рекурсии к прямойОхотно допускаю ( хотя и верится с трудом — уже на 1989 опережающие описания процедур были «всегда» т.е. в «древних» 70-х «уже были») что ради рекурсии.
Рекурсия — фирменная «фишка» Алголов и предмет законной гордости европейской школы.
В американских компиляторах той поры просто не было стека ( вообще).
Не было простой реентерабельности, т.к. было принято менять код программы прямо на ходу. Причём не для чего либо экзотического типа ИИ, а в совершенно тривиальных конструкциях.
( Перечитываю переводную классику издательства «Мир» )
вложенные процедуры не слишком нужны. Да и, откровенно говоря, они не самый лучший способ структурирования кода.Есть и другая точка зрения: как ни странно, именно вложенные процедуры считают способом построения иерархической структуры программы. И наоборот, модули обеспечивают только плоскую структуру. Самое удивительное, что это преподносилось, как один из немногих плюсов наследников Pascal. Ещё более удивительно, что автор этого построения занимается «не Паскалем».
вложенные процедуры не слишком нужны.
Как известно, практика критерий истины.
Буквально на днях видел вложенные процедуры в исходном коде, если не самого компилятора Modula-3, то в коде стандартной библиотеки.
Выглядело органично даже в 20-тистрочной подпрограмме.
Настолько же естественным путём вложенные процедуры потребуются при доказательном программировании ( см. ADA SPARK, Frama-C) из практических соображений, так как выход из середины циклов становится недопустим.
Однако настоящая трудность, специфичная для Паскаля, подстерегала совсем в другом месте — в работе с вложенными процедурами.Кстати, в Clarion изящно обошли Вашу проблему с необходимостью стека фреймов(?), работы с ним с помощью регистра BX(?) и т.п. Просто вложенные процедуры сделаны без параметров и без собственных локальных переменных.
А уж во чтобы превратилась структура программы без этих routines я просто боюсь представить: их штук 20-40 в темплайте для генерации исходного кода для процедур отображения на экране файла базы данных в виде таблицы и в другом template для построения reports их не меньше.
Дело в мультипликации: файлов БД при реляционной схеме даже для относительно простого ПО требуется несколько десятков, для каждого файла нужны минимум по одной процедуре указанных выше темплейтов ( а обычно не одной, а несколько) и ещё по одной процедуре основанной на темплайте Forms.
Сперва родился простейший компилятор PL/0, а из него постепенно вырос почти полнофункциональный компилятор Паскаля для MS-DOS.У Вирта в «Algorithms + Data Structures = Programs» (по Вашей ссылке на Вики) приведен листинг интерпретатора PL/0. Вашу фразу понимать, что на основе этого листинга Вы сделали компилятор PL/0? И потом Вы сделали из него компилятор Паскаля? Если так, то ИМХО это не лучший путь. У Вирта есть публикации его трансляторов Паскаля. Нпр, PascalS (о котором недавно упоминал). А еще лучше ИМХО взять полноценный, нпр., Pascal P5 — я так сделал для специализированного скриптового языка игрового бота (написал к интерпретатору IDE). ИМХО не надо изобретать велосипеды, а свою энергию употребить на доработку, расширение, генерацию и оптимизацию кода. Такая работа позволит полностью прочувствовать транслятор изнутри, но не по собственному переделанному коду, а по сделанному хорошими спецами. И стоило использовать ассемблер:
Машинный код генерировался напрямую, без помощи внешнего ассемблера или компоновщика.— Время на отладке сохранить и exe вместо com получить на выходе.
Все выше сказано не для умаления работы, а для читателя, который может захотеть сделать что-то подобное — пусть знает, что м.б. и другой путь. Спасибо за статью. Успехов!
PS yacc подходит для создания модели при испытании нового ЯП, его демонстрации, а хороший код на нем сделать проблематично.
А в Борланд он не предлагал?Дело было уже в 2000-е, Borland не занимался Турбо-Паскалем.
Чем клон был лучше прототипа?Видимо, как раз наличием удобочитаемых исходников. Настоящий Турбо-Паскаль был на ассемблере (не уверен насчёт 7-й версии, но 3-я точно).
Дело было уже в 2000-еА какую версию клонировал? Неужели 3-ю?
не уверен насчёт 7-й версии
Т.о. м.б. она уже была на Паскале (м.б. на С или С++ :) Но в любом случае — Внушает! Автору бы сейчас выложить свой исх.код на sourceforge.net, нпр. Денег никто не даст, но PR возможен.
PS И на Хабре статью про этот клон было бы интересно почитать :)
После загрузил в IDA turbo.exe. Тут уже не чистый ассемблер:
Правда если дальше углубиться/посмотреть то становиться ясно что тут больше не ассемблерные вставки в HLL на Паскале, а паскальные вставки в программу на ассемблере. IDA даже честно нашла стандартные функции из RTL всё того же Turbo Pascal. Как я и предполагал сам компиляторный движок такой же как в tpc.exe, отладчик на ассемблере, а на Паскале написан только UI. Вот что говорит по этому поводу википедия:
Начиная с 6-й версии в поставку TP/BP включалась объектная библиотека Turbo Vision, представляющая собой полноценную инфраструктуру (англ. framework) для создания оконных приложений, работающих в текстовом режиме. В частности, интерфейс самой среды разработки TP/BP был реализован средствами этой библиотеки.
Похоже что сначала был написан на ассемблере строчный компилятор tpc.exe, а после был написан уже turbo.exe, который был скомпилирован уже при помощи имеющегося tpc.exe ну tasm.exe само собой :-)
Скомпилировал пару демо программ для Win32 входящих в его примеры, одна из них с OpenGL (всё бодренько и FPS ~174 в примере)
P.S. Взял Virtual Pascal здесь old-dos.ru/index.php?page=files&mode=files&do=show&id=1436
Вашу фразу понимать, что на основе этого листинга Вы сделали компилятор PL/0? И потом Вы сделали из него компилятор Паскаля? Если так, то ИМХО это не лучший путь. У Вирта есть публикации его трансляторов Паскаля. Нпр, PascalS (о котором недавно упоминал).
Листинга я тогда не видел, а видел только грамматику в Википедии. На её основе и писал компилятор с чистого листа. На полноценный Паскаль не замахивался, поскольку в глубине души считал серьёзный компилятор неподъёмной для себя задачей. Когда удался PL/0 — возросли и мои аппетиты: добавил указатели, затем массивы, затем функции, затем действительные числа с фиксированной точкой, которую заменил на плавающую, и т.д. Так и вырос Паскаль. Эталонной грамматикой на этом этапе служила именно грамматика Pascal-S.
Листинга я тогда не видел, а видел только грамматику в ВикипедииИнтересно: почему? Разве эта книга Вирта редкая? (Там не только листинг, но целая глава про него). М.б. посмотреть в книгу казалось не спортивным? Всё самому сделать? ;)
Немного странно, что в комментариях не вспомнили fpc — самый, вероятно, на сегодня актуальный компилятор паскаля, к тому же с открытыми исходниками. Да, он как раз из другого направления, из тех, что развивались больше «в сторону усложнения», с оглядкой на Delphi и др.
Автор, Вы не делали попыток посмотреть, что и как сделано в fpc и сравнить со своим проектом?
Мой компилятор Паскаля и польское современное искусство