Предложение по Учебному Проекту № 3
Предлагаю создать Учебный Проект по созданию языка программирования (ЯП). Тут можно будет рассмотреть разные инструменты типа bison, можно будет обсуждать всякие парадигмы ЯП, виртуальных машин и т.д.
Какие тут плюсы? Первый: такая практика (создание ЯП) интересна мне самому. Второе: теоретически, у проекта могут быть кураторы, раз тема интересна. Третье: возможно, на форуме есть другие люди, которым такая практика может пригодится.
Потенциальные минусы. У меня уже есть некоторое представление о том, какой ЯП буду создавать. Это не будет ещё один клон Хаскеля или Лиспа. Скорее, что-то похожее на классические компилируемые языки, типа C++ или Паскаля, но с некоторыми принципиальными отличиями. Соответственно, и ТЗ напишу я.
Кроме того, если не будет веских аргументов против, то буду использовать именно bison или какие-то другие клоны yacc, ибо классика.
Есть у кого-нибудь идеи, предложения, пожелания?
а первые два чем закончились?
[/off]
Первый закончился так:
http://code.google.com/p/neat-address-book/
Тут была освоена работа в паре, были изучены некоторые особенности работы с данными, с ООП в C++. Кроме того, я начал осваивать Юнит-тесты, хотя и варварским велосипедным способом.
Второй был менее удачным. Его тема тут:
http://forum.codenet.ru/showthread.php?t=56775
Тут я также изучал ООП, а так же Python (правда, игнорируя некоторые рекомендации, например, PEP-8). Закончилось созданием альфы игры "Робот", которым (роботом) может управлять человек или скрипт.
Какие тут плюсы? Первый: такая практика (создание ЯП) интересна мне самому.
offtop: первый плюс офигенен=))
Надо было подписаться как Капитан Очевидность...
Ну так прямо сейчас приступать никто и не будет. Надо провести некоторую подготовительную работу. Как раз до Нового Года и продлится, наверное.
Пока накидаю основные моменты ТЗ, чтобы желающие вдохновились или остыли :)
Возможно тоже приму участие, если сроки будут примерно такие(у меня в ближайший месяц времени просто 100% не будет). Всё равно на автомат по методам трансляции надо будет написать LARL анализатор, как раз раскачаюсь после его написания))
Краткое описание: процедурно-агрегирующий, компилируемый язык программирования со статической типизацией. Язык должен быть прост и лаконичен, пусть для этого потребуется пожертвовать некоторой гибкостью.
Основные особенности.
1. Управление памятью. Нет ни явного ручного управления памятью, ни сборщика мусора. Грубо говоря, не создаём "мусор". Обычно такой подход снижает гибкость языка, но повышает предсказуемость. Памятью управляем косвенно, в основном за счёт динамических массивов и словарей. Но лазейка для "простреливания ноги" остаётся. Об ней ниже.
2. ООП.
2.1. Полностью отсутствует наследование, но расширены возможности композиции классов. Например, есть инструкция "поднятия" функции агрегируемого объекта.
2.2. Добавлены "классы-утки", являющиеся абстрактными классами наоборот. Таким образом, для обеспечения полиморфизма не требуется наследоваться нескольким классам от одного абстрактного, но создавать класс-утку на основе нескольких существующих с одноимёнными функциями. Этот способ позволяет использовать полиморфизм в тот момент, когда он нужен, а не прогнозировать, что он потребуется.
3. Шаблоны. Любая функция или класс может быть шаблонным. Это достигается путём переопределения какого-либо типа, используемого в функции или классе. С другой стороны, остаётся и явное указание имени изменяемого типа в самих функциях.
4. Модули аналогичны тем, которые используются в Python. Никаких хедеров, никаких пространств имён.
5. Кроме того, из Python будут переняты отступы.
6. Из Ruby будут переняты разнообразные виды циклов и некоторые сокращения.
7. Функции не возвращают значений явно. Они используют константные ссылки как входные значения и неконстантные ссылки как выходные. Всё что явно создано в функции в ней же и уничтожается.
8. Программы компилируются в код на C++. Кроме того, код на C++ может быть включён в текст программ. Это добавит гибкости для простреливания ноги.
Пока опущены некоторые моменты, типа исключений, многопоточности и препроцессора.
1. Написать подробное ТЗ. Буду выкладывать тут черновики, чтобы желающие могли указать на ошибки.
2. Ознакомиться с теорией. Пока я начал с практической части - разбираюсь с калькулятором hoc от Кернигана и Пайка. Возможно, потребуется изучить более солидные теоретические материалы. Пока не знаю.
3. Создать идеологию проекта: сроки, итерации, взаимодействие участников и т.д.
4. Выбрать инструменты и технологии.
Всё делаю сам. Но любым советам и предложениям буду рад.
интересует какой резон компилировать в c++ кроме стремления прострелить себе ногу?
имхо компилировать в исходник на другом языке да еще на C++ -- одна из худших идей. кроме того непонятно какова роль виртуальных машин во всем этом.
1. Кросплатформенность же и простота реализации. Можно конечно и в чистый си компилировать, но, думаю, что это намного увеличит трудоёмкость.
2. Так мы можем получить простой способ использовать существующий код на C++ (и совместимый с ним C).
3. Учебная цель. Люди, программирующие на C++ получат дополнительную практику. Конечно, первый среди них - сам я.
Пока никакой. Они упоминались только в цитате. Разрабатывать свою виртуальную машину я не собирался. Хотя интересны варианты компилирования в байт-код какого-нибудь Parrot или LLVM. Но пока я не углублялся в этом направлении.
А руководитель проекта:D:D:D чует разницу между разработкой Языка Программирования и разработкой Компилятора\Интерпретатора и Виртуальной Машины? Пока я заметил в мыслях автора некоторую кашу из этих процессов.
хм... появляется вопрос: предполагается реализовывать всё на C++ ?
В первую очередь - попрактиковаться в написании компиляторов. Естественно, не с нуля, а используя существующие инструменты.
Для этого можно было бы изобретать велосипед в чистом виде - например, компилятор Паскаля в Си (я действительно не вижу принципиальной разницы между компилятором в какой-либо ЯП и машинный код). Но мне видится, что это будет скучное занятие. Намного интереснее изобретать своё.
Но если есть другие соображения - могу рассмотреть и их.
У меня маленький опыт и я опишу его, чтобы вы знали с кем связываетесь. Я изобретал простейшие интерпретаторы ассемблероподобных языков. В одном были чистые инструкции (то есть совсем примитивно), в другом уже добавлялся препроцессор, который раскладывал на инструкции выражения типа if((a > b) and (c < d)...).
Когда мне не хватило скорости интерпретирования текстовых команд, то я сделал транслятор строк в байт-код (тупо сделал соответствие инструкций и констант типа int) и, соответственно, интерпретатор этого байт-кода. Избавление от разбора строк намного увеличило скорость выполнения. Чем вам не простейшая модель виртуальной машины?
Ну, ещё когда-то делал вручную перевод ассемблерных команд в машинный код какого-то древнего процессора (вроде бы, 8080), ибо приходилось работать со стендом, который понимал только машинный код. Но интересного в этом было мало.
Предполагается использовать bison (аналог yacc), который тесно связан с C++. Если всё равно будет использоваться C++, то почему бы не сделать компиляцию в него?
Большого числа и не надо. Я рассчитываю на два-три участника.
На это и отведён подготовительный период.
Я же упоминал калькулятор hoc из книги "THE UNIX PROGRAMMING ENVIRONMENT" от Кернигана и Пайка. До ООП не доходит, но функции есть, что уже неплохо.
В версии, которую я откопал используется какая-то древняя версия си, всё заточено под yacc. Приходится бороться с ерорами и варнингами, но тем интереснее :)
Далее. Реализовать ООП и всякие исключения можно, например, на основе COS. Штука интересная для отдельного изучения сама по себе. Хотя, может и заблуждаюсь.
Не умер. Могу привести небольшой отчёт о моих исследованиях.
Я скомпилировал и отладил 6 версий языка hoc на современном си и bison. При том, делал я их как проекты Code::Blocks, чтобы было проще работать, запускать.
Возможно, надо выложить эти проекты, а возможно будет полезнее, если каждый сам их сделает.
У hoc, как у учебного инструмента для конкретного проекта есть некоторые недостатки.
1. Он является интерпретатором, а не компилятором.
2. Он написан на си. Предполагаю, что это не самый лучший выбор для учебного проекта - много неустойчивых конструкций.
3. Довольно сложно что-то сделать только на его основе. Всё-таки надо читать дополнительную теорию.
В качестве альтернативы bison я начал рассматривать PLY. Приятной особенностью было то, что анализаторы задаются в нем не выходя за рамки языка Python.
Но тут опять я упёрся в то, что трудно уйти за рамки простых примеров. Пытался переводить инструкцию. Но и тут возникли некоторые сложности. Например, не очевидно, что "syntax directed translation" должно переводиться как "синтаксически управляемая трансляция". То есть опять таки надо знать теорию.
Предполагаю, что придётся всё-таки прочитать "Книгу дракона", составить какой-то конспект, заточенный под этот конкретный проект. Современный выпуск этой книги меня озадачил тем, что примеры в нем даются на Java. Кроме того, как-то засомневался я покупать очередной кирпич. Пока читаю старое издание с красным драконом на обложке.
Сколько уйдёт на это времени - не знаю. И пока не вижу способа подключить других. Но так как всё равно было решено отложить на январь, то пока не говорил о своих исследованиях.
Я скомпилировал и отладил 6 версий языка hoc на современном си и bison. При том, делал я их как проекты Code::Blocks, чтобы было проще работать, запускать.
мне было бы удобно, если бы эти проекты можно было бы скачать с репоpитория в сети (codeplex - mercurial, github\gitorius - git) + набор ссылок для раскуривания кода.
python, лично мне не интересен, но если я найду время, то попробую раскурить fslex + fsyacc (аналоги ocamllex, ocamlyacc для F# на котором я сейчас достаточно часто пишу).
Предполагаю, что придётся всё-таки прочитать "Книгу дракона", составить какой-то конспект, заточенный под этот конкретный проект. Современный выпуск этой книги меня озадачил тем, что примеры в нем даются на Java. Кроме того, как-то засомневался я покупать очередной кирпич. Пока читаю старое издание с красным драконом на обложке.
Сколько уйдёт на это времени - не знаю. И пока не вижу способа подключить других. Но так как всё равно было решено отложить на январь, то пока не говорил о своих исследованиях.
Было бы оч. не плохо иметь примерный список того, что нужно будет знать. Тогда лично я мог бы потихоньку начать устранять свои пробелы в теории уже.
Книгу дракона листал, когда писал LARL-анализатор, тоже старое издание. Мутновато там всё написано к сожалению (либо переводчики постарались так). Пришлось собрать много костылей пока написал.
Я скомпилировал и отладил 6 версий языка hoc на современном си и bison. При том, делал я их как проекты Code::Blocks, чтобы было проще работать, запускать.
Слушай, возьми уже нормальный инструмент, и нормальный язык а? На Си и Бизоне быстро ничего сделать не получится.
Сколько уйдёт на это времени - не знаю. И пока не вижу способа подключить других. Но так как всё равно было решено отложить на январь, то пока не говорил о своих исследованиях.
Если хочется написать свой компилятор, то после НГ начнем проект Nemerle 2.0. Присоединяйся ;)
Сейчас нету времени смотреть Nemerle. Да и не особо удобен он для меня на данный момент, т.к. дома юзаю VS2010 (а для Немерля плагина под неё нету), а в походных условиях emacs + F# плагин (писать на Nemerle в emacs\vim не могу, слишком много "лишнего" там нужно писать, без интеллисенсе не удобно банально, да и fsi удобнее как то).
Вот как появиться плагин для VS2010, поюзаю Nemerle скорее всего.
Не уверен, что буду регистрироваться на codeplex. Но это не главное. Каждая версия является иллюстрацией к определённой главе книги THE UNIX PROGRAMMING ENVIRONMENT" от Кернигана и Пайка. Последняя версия основана на исходниках, которые доступны тут:
http://netlib.bell-labs.com/~bwk/hoc.sh
В любом случае, полезнее каждому проделать такой же путь. Хотя, возможно, будет полезнее переводить эти проекты на другой язык.
Мне не интересен F#. Но ocaml - другое дело. Возможно, стоит его использовать.
Было бы интересно провести анализ bison+flex vs PLY vs ocamlyacc+ocamllex. Но не уверен что осилю в ближайшее время. Поэтому взялся за то, что мне ближе.
Пока ничего не могу сказать конкретно. Возможно, надо сделать подготовительные проекты. Например, тот же hoc, выполненный с помощью разных инструментов. Заодно прояснится, что требуется знать по теории.
emacs + F# - посмеялся от души. :D
"Лишнего" в Немерле писать надо еще меньше чем в F#, но это так, к слову (F# и рядом не стоял с возможностями Nemerle). Плагина к VS2010 в ближайшее время не планируется (хотя он в каком-то виде есть в репозитории), если (когда) руки дойдут, будет аддон к SharpDevelop 4.0.
А чем не устраивает VS Shell + Nemerle?
Я понимаю, что Си и Бизон - не самый подходящий для моих целей инструмент. Но не вижу чем предлагаемое лучше связки PLY+Python. Второе хоть ближе к классике по духу.
Так это будет не мой компилятор.
Если раскрывать мотивы, то мне интересно разработать язык, который будет позволять писать программы для встроенных устройств, программы с предсказуемым поведением (этого я не могу сказать про языки, использующие сборщик мусора). Nemerle тут не подходит.
более вменяемых вариантов для нетбука имхо нету. т.к. F# можно юзать без дебаггера вполне - fsi более чем позволяет. в Nemerle такого нету насколько мне известно.
можно линк на то, как это заюзать. но опять же, всё упирается в вожможность удобного заюза на нетбуке.
п.с. под лишним я подразумевал обёртку классов, using'ги и т.п. про возможности макросов знаю, смотрел немного.
upd. линк нашёл, раньше почему то не натыкался на такой вариант ide для Nemerle, спасибо. Попробую поюзать.
Я не знаю что там в PLY сделали, но у нас бонусы следующие:
1) не нужны внешние инструменты и интеграция их в билдпроцесс
2) парсер компилируется в достаточно эффективный код: на моей машине парсер C# по скорости приближается к 4МБ/с.
3) вариантные типы и паттерн матчинг - я не представляю как можно писать компиляторы на языках без сопоставления с образцом
З.Ы. из особенностей - нет лексера, язык описывается единой грамматикой
Есть у кого-нибудь идеи, предложения, пожелания?
Советую ознакомиться с вот этим опытом.
В PLY аналогично, если я правильно понимаю.
Думаю, это не актуально, если правильно работать с модулями.
На это мне пока нечего ответить - не разбираюсь.
Насколько я понимаю, тут рекомендуется не идти в первый класс, а сразу в десятый. При том, что учитель в десятом - велосипедостроитель.
Но в любом случае, спасибо за ссылку. Дорасту - попытаюсь осмыслить.
Ну так отличный повод разобраться. :) Компиляция - это процесс преобразования одних деревьев - в другие. А более удобных средств работы с древесными данными нежели сопоставление с образцом человечество еще не придумало.
Тут рекомендуется вдумчиво почитать и осмыслить использованные техники и инструменты. Вся его кухня (с виртуальной машиной) заняла не более 3к строк кода.
Интересное определение, но сравнительно вольное. И подозреваю, что в некоторых случаях неверное.
Дело же не в 3к кода, а в контексте. Стихотворение на китайском может занимать 10 строчек, но для понимания потребует хорошего знания китайской культуры.
Например, выражения "рекурсивный спуск с откатами", "описание грамматики", "парсер-комбинатор" и т.д. в статье употребляются между делом, как понятное всем. А понятен он тем, что знаком с классикой (ну или отчасти тем, кто нахватался этих терминов в аналогичных статьях и как-то интуитивно понял).
Пока не будут продемонстрированы контрпримеры я останусь при совем мнении (про деревья).
Ну так эти вопросы легко гуглятся, тем более что нетривиальным вопрос тут только в парсер-комбинаторах.
Самый очевидный и унылый пример - перевод ассемблера в машинный код. Но понятно, что тут речь о другом.
Более весомый аргумент может быть в том, что перевод одного дерева в другое - это только часть работы нормального компилятора, не самая объёмная. Если я правильно понимаю, то работа с деревьями имеется в основном на стадии синтаксического анализа. При лексическом анализе, при оптимизации и т.п. её может не быть. А это тоже части нормального компилятора.
Но опять же, я пока "плаваю" в этом вопросе. Лучше отложить это обсуждение :)
Так я же не про то, что не гуглятся. Я про то, что гуглить много и материал будет не самого лучшего качество, ибо выбираться он будет случайным образом. Лучше уж взять книгу, где всё упорядочено.
И потом, мне не достаточно определений, теории. Я не понимаю, если не ознакомлюсь с кучей примеров, не порешаю задачки. И тут с гуглом опять будет проблема. С книгой проще.
Список есть частный случай дерева. ;)
Ты понимаешь неправильно. Текст после этапа синтаксического разбора превращается в AST (abstract syntax tree) - дерево, содражщее все объявления, конструкции, выражения. Далее нужно это дерево типизировать. Иными словами сопоставить все текстовые идентификаторы с теми сущностями на которые они ссылаются, т.е. определить их семантику. Тут мы подходим ко второй форме - типизированному дереву. Количество преобразований этого типизированного дерева зависит от сложности языка. В Nemerle к примеру происходит 4 трансформации: собственно вывод типов с раскрытием макросов (это сам по себе итерационный процесс) и еще три этапа постпроцессинга. На каждом этапе постпроцессинга выполняются некоторые преобразования - инлайнинг локальных функций, оптимизация хвостовой рекурсии, ликвидация замыканий и т.п. После всех преобразований дерево программы приводится к такому виду, в котором его уже совсем просто записать в виде машинного кода - т.е. свести к списку инструкций (который на самом деле никакой не список, а граф).
Ты лучше осиль серию статей Dmon-а - они лучше любой книги, в которых зачастую слишком много не особенно нужной математики. Жаль, что поляки, от которых нам достался Nemerle не обладали таковым опытом - глядишь давно бы уже релизнулись...
З.Ы. Кстати, при оптимизации происходит поиск в коде неких паттернов. Для таких задача в правильных ЯП есть инструмент - pattern matching (сопоставление с образцом). Что лучше: взять язык с уже встроенным механизом, или язык в котором такую штуку нужно эмулировать чем придется?
...строка - частный случай списка, символ - частный случай строки...
В результате может получиться, что все операции - преобразования деревьев. Но тогда теряется смысл определения, хотя остается правдивость.
Очень может быть.
То есть ты утверждаешь, что его статьи для новичков? У меня сложилось другое впечатление.
горячишься, на счет "правильных".
Если языки почти полностью одинаковы, и отличаются только этой фичей, то лучше взять тот, где есть сопоставление с образцом. Но языки отличаются не только этим.
В результате может получиться, что все операции - преобразования деревьев. Но тогда теряется смысл определения, хотя остается правдивость.
Смысл определения не теряется. Пол Грэм именно так когда-то рассуждал назвав число - списком. ;) Это вопрос точки зрения на структуры данных.
А когда это вопросы компиляции были для новичков? ;)
Если языки почти полностью одинаковы, и отличаются только этой фичей, то лучше взять тот, где есть сопоставление с образцом. Но языки отличаются не только этим.
Вот ты сейчас подтверждаешь парадокс Блаба. ;)
да, да. Я - унылый "блаб-программист".