Язык программирования Mash


    http://mash-project.org
    https://github.com/RoPi0n/mash-lang

    Mash?


    Это императивный язык программирования с динамической типизацией, сборкой мусора, ООП и поддержкой многопоточности.



    Интересно? Тогда под кат!

    Насколько завершен проект?




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

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

    По функционалу Mash схож с Python.

    Язык спроектирован максимально простым и полнофункциональным.

    Полностью поддерживает ООП, интроспекцию, рефлексию, функции высшего порядка, многопоточность, синхронизацию, распараллеливание и синхронизацию кода внутри тела методов.

    В качестве среды выполнения языка используется стековая виртуальная машина (ВМ), поддерживающая многопоточность, сборку мусора (Reference Counting).

    Реализован транслятор языка (с построением AST, все как по книжкам) в абстрактный код для ВМ и в перспективе в другие языки (но из-за сложности языка — это пока только планы на будущее).

    Для удобства в ознакомлении с языком и работе с ним реализована небольшая IDE (FPC + SynEdit).

    Встраиваемость


    ВМ языка имеет API, функционал языка можно расширять путем написания библиотек для ВМ на любом нативном языке (FPC, Delphi, C/C++, Rust и т.д.), также язык можно встроить в любой ваш проект, при этом получить в свое распоряжение весь функционал Mash'a и его нативных библиотек.

    Debug?


    У ВМ предусмотрена возможность работы в связке с отладчиком (который пока что очень сырой).

    Язык поддерживает трассировку исключений.



    Поддержка платформ


    Язык полностью написан на Free Pascal, который в свою очередь поддерживает огромный список платформ, под которые может быть собран Mash.

    Зависимости от каких-либо библиотек отсутствуют.

    Проект уже собирался ранее и тестировался на Windows, Linux и Android.

    На что Mash способен уже сейчас?


    На данный момент я работаю над реализацией стандартного набора библиотек для работы с файлами, математикой, I/O, многопоточностью, GUI, сетью, базами данных, криптографией и т.д.





    В репозитории проекта (и в Pre-Release сборке) можно найти небольшие демо-приложения.
    На Mash написана змейка, асинхронный веб сервер/фреймворк (по типу Flask'a), отрисовка графиков в декартовой и полярных системах координат, Аттрактор Лоренца, вращение простых 3D моделек по типу кубика, а так же версия транслятора Mash'a, написанная на Mash'e.

    Что дальше?


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

    В разработке, помимо библиотек для ВМ, находится JIT компилятор по типу HotSpot.

    Дочитали до конца?


    Спасибо за внимание.

    Средняя зарплата в IT

    113 000 ₽/мес.
    Средняя зарплата по всем IT-специализациям на основании 5 253 анкет, за 2-ое пол. 2020 года Узнать свою зарплату
    AdBlock похитил этот баннер, но баннеры не зубы — отрастут

    Подробнее
    Реклама

    Комментарии 67

      +15

      Не хватает описания того, зачем собственно он вообще нужен ещё один такой.

        +2

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

          +2
          Какие у него преимущества перед альтернативами?
            +2
            Пока ещё рано говорить о преимуществах не завершенного проекта, перед альтернативами, над которыми трудились тысячи людей, на протяжении десятилетий :)

            Пока что можно сказать, что это отечественный аналог Python'а, который можно встроить в какой-нибудь софт.
              –2
              Если отечественный, значит должен быть на русском как 1С!
                0

                Надо сначала на ассемблере написать компилятор С, потом на этом С написать ВМ для Mash-а, вот тогда это будет полное ипортозамещение. Кстати, я не шучу, такое в области каких-нибудь госзаказов вполне прокатить сможет.

                +1
                Ну, а есть вообще какие-то предположения, зачем миру нужен еще один питон? Просто сейчас рано говорить, а потом будет уже поздно
                +5
                Предполлагаю, что у всех альтернатив есть фатальный недостаток )))
                +1
                В академической работе вы должны указать практическую или научную новизну.
                  –5

                  Юные натуралисты в живом уголке скрестили хомячка с хомячком. Без академических целей, просто позырить.

                +1

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


                Это сложные вещи, важные навыки и опыт, которыми может похвастать далеко не каждый "я уже 15 лет в разработках".


                Так что пускай автор дерзает, вреда от этого никому точно не будет.

                  +1

                  Где они нужны прямо вот запредельно? Где-то нехватка разработчиков компиляторов?

                    0

                    Ну так-то почти во всех языковых платформах нехватка разработчиков. А во всех остальных областях нехватка разработчиков, способных понять, о чём думали разработчики платформы.


                    Нехватка разработчиков в платформах (языках, стандартных библиотеках, среде исполнения), на мой взгляд, в основном из-за того, что среды разработки быстро обрастают грузом наследия и каждая следующая фича пилится сложнее предыдущих. С этой точки зрения, "академические" или "бесполезные" языки как раз и являются единственным местом, где можно проверить подходы, которые лет через Nдцать дойдут до мейнстрима.

                +9
                Меня если честно очень удивляет отсутствие строгой типизации во всех подобных скриптовых языках. Какого типа и размера переменная i? Что будет, если я ее сдвину на 8 или 16 вправо? Или отниму из нее 255. Как мне работать с отдельными битами в этом языке, если я понятния не имею, какой размер у переменных. В Паскале с этим было все строго.
                  0

                  Для работы с битовыми операциями или же с байтами по-отдельности предусмотрены языковые операторы и ряд классов по типу stream, в будущем этот функционал языка будет расширен.


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


                  Ну а так, в Mash будет все это поддерживаться на уровне "работает медленно, но корректно".
                  :)

                    0

                    Так а размер-то какой в итоге? Да и вообще семантика всего этого дела

                      0
                      Типы данных под капотом ВМ:
                      null
                      unsigned int — 4 байта (для счетчиков)
                      int — 8 байт
                      double — 8 байт (5.0E-324… 1.7E308, значащих цифр: 15-16)
                      string — динамическая длина, 1 символ = 1 байт
                      array — массив указателей, длина фиксированная, размер зависит от разрядности ос, но её можно изменять через SetLen()
                        +1
                        string — динамическая длина, 1 символ = 1 байт

                        Ээээ… А юникод? Тут уже XXI век на дворе.

                  +3
                  Хабы: Высокая производительность

                  Так производительность какая? Высокая? А где замеры?
                    +1
                    Спасибо за статью. Желаю Вашему языка взлететь. От себя хочу добавить, задумайтесь над опциональной строгой типизацией, в это сторону сейчас двигаются многие динамически типизированные языки. Т.е. возможности явно указать тип. Для прототипирования строгая типизация не нужна, а вот для более крупных проектов очень. И лучше заложить эту возможность с самого начала. IMHO
                      0
                      Точнее, это type hint, как в том же Python сделано.
                        +4
                        Тайпхинты в Python для интерпретатора означают примерно ничего. :(
                          0

                          Тайпхинты в Python нужны чтоб код был более выразительным. Если нужно больше производительности, то на помощь придут декораторы @njit :)

                      +1
                      читаю статью, смотрю примеры, вот прям не выходит из головы Delphi, потом дошел до места где написано что на Free Pascal написан ) и стало понятно почему. В любом случае интересный проект и много опыта можно получить делая это, удачи проекту и Вам! Желаю собрать большое комьюнити по это дело.
                        0

                        Динамический паскаль

                          –2
                          Использовать двоеточие ":" для начала блока — на мой взгляд плохая идея. Было бы логичнее использовать ключевое слово, например «do».
                            0
                            «then begin» — тоже неплохо)
                            +10
                            А почему логотип Mash лично мне чем-то до боли напоминает логотип Rust? Я просто интересуюсь.
                              +1

                              То же впечатление — однозначные ассоциации с растом.

                                +1
                                Зашел из-за логотипа)
                                +1

                                Что за бинари в репозитории и почему они не в releases собственных репозиториев?
                                Где тесты или хотя бы примеры? Хотя бы код той же змейки. Есть подозрение, что те же явные указатели скрывают некоторые проблемы с памятью.
                                Что с перегрузкой операторов?
                                Что с деструкторами?
                                Что с обработкой ошибок?
                                Есть API для запуска нативного кода, но снова где примеры (нашел только в pdf пример на паскале, что называется "без пруфов" что работает)?
                                Есть код, но где инструкция по сборке?
                                Зовется высокопроизводительным, но где бенчмарки?
                                Проекты обычно принято разбивать на несколько файлов — как организовано взаимодействие таких code units? Или пока только все в один файл?
                                за whilst палец вверх

                                  0
                                  Уши Delphi и Free Pascal всё же видны.
                                  за whilst палец вверх

                                  Безусловно цикл с whilst пишется короче на целую строчку чем repeat...until, но зато repeat...until гораздо нагляднее показывает что делается на самом деле и с похмелья через часов 8 подряд упорного программирования его не спутаешь на автомате с циклом while. IMHO.
                                    0
                                    Если к паскалю добавить немного python… ;)
                                    Но всё равно end без begin выглядит странно. Конец блока end, начало :?
                                    ?= — это присваивание (чем плохо паскалевское :=? ), или что-то непривычное? Оба варианта плохие, набираются в 3 нажатия. Почему не питоновское =?
                                    Язык как язык, выучить можно.
                                      0
                                      Синтаксис в этом плане похож на Ruby немного :)
                                      ?= — присваивание указателя на объект.
                                      = — присваивание значения.
                                      @= — присваивание значения по виртуальному указателю (на сайте есть небольшая документация).
                                        0

                                        для меня это больше перловый синтаксис напоминает. ждем таких же нечитаемых однострочников с core dumped внутри.

                                          0

                                          В языке отсутствует оператор;
                                          Т.е. нельзя написать кучу кода в одну строку.

                                      0

                                      может я плохо доку читал, но я думал while и whilst синонимы

                                        +1
                                        В доке написано:
                                        Циклы while & whilst

                                        Это самые обычные циклы while, только у whilst — проверка условия осуществляется после итерации цикла.

                                        То есть насколько я понял whilst делает то же самое, что и repeat...until во Free Pascal и Delphi. Ну а while аналогичен while из Free Pascal и Delphi.
                                      0
                                      1. В репозитории лежит сборка языка, для тех у кого нет желания собирать проект самостоятельно, думаю таких людей много, ещё и на FPC все написано…
                                      2. В репозитории полно примеров кода, bin/win64/test, примеры также включены в архив с пре-релизной сборкой.
                                      3. Перегрузка операторов ещё не отлажена, будет добавлена в язык позже. Это второстепенная задача пока что.
                                      4. Деструкторы в языке отсутствуют, т.к. есть сборщик мусора. Освободить память от того же экземпляра класса можно присвоив переменной с указателем на него — null.
                                      5. Язык поддерживает конструкции try/catch/finally/raise, выравнивание стека при исключении, обратную трассировку исключений и в целом исключения довольно хорошо проработаны в Mash.
                                      6. Ну опять же по API. Откройте любой пример, вы можете увидеть там println(). ВМ по умолчанию не поддерживает ни одной лишней функции, даже такой простой как вывод чего-либо в консоль. Весь функционал, расширяющий ВМ лежит в виде модулей в папке lib рядом с ней, либо должен лежать рядом с проектом (если требуется распространять потом mash приложение + свою библиотеку).
                                      Исходники библиотек можно глянуть в ветке /runtime/libs/
                                      7. Инструкция по сборке? Проект написан без зависимостей, .lpi файлы идут вместе с исходниками. Можно скачать Lazarus и собрать все за 5 минут. Ну а вообще для FPC процесс сборки выглядит очень даже просто, достаточно пары команд в консоль послать :)
                                      8. Я не упоминал вроде, что язык высокопроизводительный. Без JIT'a он все ещё остается интерпретируемым, хоть и через стековую ВМ. Производительность языка пока что на уровне старых версий Python'а.
                                      9. В языке можно разбивать проекты на кучу файлов, есть оператор uses. В этом плане все супер :)

                                      Спасибо за вопросы :)
                                        +1
                                        7. Инструкция по сборке? Проект написан без зависимостей, .lpi файлы идут вместе с исходниками. Можно скачать Lazarus и собрать все за 5 минут. Ну а вообще для FPC процесс сборки выглядит очень даже просто, достаточно пары команд в консоль послать :)

                                        Это IMHO из той же серии, что «Проект написан без зависимостей, сначала покупаете себе компьютер, после устанавливаете на него Windows, Linux или любую свою любимую OS, под которую есть Free Pascal. А дальше .lpi файлы идут вместе с исходниками, собираешь и всё работает! Что? Как конкретно собирать, какие директивы давать fpc, что куда класть и прочее? Позвольте, это язык Mash, а как собирать при помощи fpc и его оболочки Lazarus читайте на соответствующих сайтах! Или смотри рисунок номер 1
                                          –3

                                          Если вам сложно собрать проект без зависимостей, путем нажатия 2-3 кнопок в ide, то в таком случае придется подождать до релиза :)

                                            +1
                                            Мне? Мне как раз несложно. Только неинтересно :-) А кому-нибудь может быть именно интересно на этот Mash посмотреть, потыкать в него палочкой, но собрать ему сложно. Для таких и желательна инструкция по сборке. Иначе теряется как минимум аудитория таких вот заинтересованных, а как максимум и дальнейший интерес этой аудитории.
                                              0
                                              Некоторые, не увидев привычного Makefile|configure|cmakelists.txt|*.pro|..etc.., огорчаются.
                                                +2
                                                Причём огорчаются довольно сильно и иногда до того сильно, что больше никогда не заходят смотреть что стало с этим проектом.
                                                  0
                                                  Я такой огорченный и есть) скачал, инструкций по сборке нет, что делать с пачкой pas файлов — непонятно)
                                                    +1
                                                    Там же есть исполняемые файлы :-) Правда только под Windows. Поэтому я тоже не смог посмотреть Mash в действии. Нет, безусловно я смог бы напрячься и без «привычного Makefile|configure|cmakelists.txt|*.pro|..etc.» собрать Mash под Linux, что делать с пачкой файлов .pas я в курсе. Но оно мне надо, напрягаться лишний раз и вручную делать то, что на раз-два-три сделал бы при помощи «привычного Makefile|configure|cmakelists.txt|*.pro|..etc.» абсолютно без всякого напряжения и лишних раздумий? Не надо. Поэтому просто стёр всё что я скачал. Уверен что я не один оказался в такой ситуации.
                                                      0
                                                      pfemidi:
                                                      Там же есть исполняемые файлы :-) Правда только под Windows. Поэтому я тоже не смог посмотреть Mash в действии.

                                                      Под wine Mash IDE не пошло, позволило создать простейший hello.mash:

                                                      uses <crt>

                                                      proc main():
                                                          println(“Hello world!”)
                                                      end


                                                      но при попытке его откомпилировать выдало штук 10 абсолютно пустых окон «Error» без какого-либо содержимого в них и зависло. Выручил pkill на процесс wine.

                                                      Вызов:

                                                      ./mashc.exe hello.mash hello.out

                                                      создал мне hello.out с набором команд какого-то судя по всему внутреннего ассемблера:

                                                      [...]
                                                      word vtable__methodname 41
                                                      word vtable__methodaddr 42
                                                      @global.arg_counter
                                                      @global.this
                                                      @global.temp
                                                      word global.zero 0
                                                      word global.one  1
                                                      str global.raised "ERaisedException"
                                                      pushc global.zero
                                                      peek  global.arg_counter
                                                      pop
                                                      [...]


                                                      Попробовал напустить на него:

                                                      ./asm.exe console hello.out hello

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

                                                      ./svmc.exe
                                                      MASH!
                                                      Stack-based virtual machine.
                                                      Version: 0.2
                                                      Using: svmc.exe <svmexe file> [args]


                                                      а будучи запущен с параметром, с этим самым hello:

                                                      ./svmc.exe hello

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

                                                  image

                                                0
                                                1. Деструкторы в языке отсутствуют, т.к. есть сборщик мусора. Освободить память от того же экземпляра класса можно присвоив переменной с указателем на него — null.

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


                                                1. Я не упоминал вроде, что язык высокопроизводительный.

                                                Hubs: High perfomance


                                                1. В языке можно разбивать проекты на кучу файлов, есть оператор uses. В этом плане все супер :)

                                                как-то у вас этот момент и в статье и в доке упущен.


                                                ну и финалочка — когда планируете язык self-hosting сделать?

                                                  0

                                                  Для закрытия стримов/сокетов и т.п. объявлены методы close(), т.е. после вызова поток закрыт, но все ещё находится в памяти ВМ, ждет своего часа, когда GC освободит память :)


                                                  Ну, хаб о высокой производительности, просто потому что можно выбрать 5 хабов :)


                                                  self-hosting уже делал, есть версия транслятора для Mash, написанная на Mash'e.
                                                  Но у неё есть один недостаток — время компиляции через неё кода на Mash. Одинаковый код компилятор на FPC и на Mash'е могут собирать 0,0001 сек. и 6-7 сек. соответственно.

                                              +1
                                              Автор, желаю вам удачи :) Было бы интересно почитать про подводные камни при разработке языка, к чему стоит быть готовым начиная такой неординарный проект. Можете рассказать про стадии в разработке и сколько времени потребовала каждая стадия?
                                                0
                                                Подводных камней очень много, начиная от того, что нужно изучить всю доступную теорию перед началом разработки (иначе выйдет полная фигня), заканчивая тем что нужно продумать ряд сложных моментов в архитектуре языка и ВМ, например как реализовать параллельную сборку мусора, передачу объектов по указателям из одного потока в другой, чтоб сборщик мусора случайно не освободил память, чтоб не было утечек памяти и т.п.

                                                Пока занимался разработкой, понял почему эта сфера деятельности у разработчиков не очень популярна :)

                                                Проект начал своё развитие в 2018-м и сейчас до сих пор он все ещё не завершенный :)
                                                Возможно как доучусь до 4-го курса, то получится оформить все как конечную готовую работу.
                                                  0
                                                  >> например как реализовать параллельную сборку мусора

                                                  А как она у вас организована?
                                                  Переносимые ссылки или указатели? Stop the World есть?
                                                    0

                                                    Reference Counting + Interlocked операции, STW нету.

                                                +1
                                                Когда-то, в середине 2000х, в нашей провинции на защите дипломных работ, абсолютное большинство группы ПОВТ и АС представило проекты интернет-магазинов. Естественно, у комиссии был вопрос — «А что, собственно, уникального в вашем магазине?» Над ответами того потока в том ВУЗе до сих пор хихикают. Я это к чему — уровень студентов шагнул далеко вперед, а вечный вопрос «А на кой это нужно?» — тут как тут. А вообще автор молодец.
                                                PS Когда вижу uses crt; жду, что вот-вот появится clrscr; )
                                                  0

                                                  Каждый уважающий себя программист обязан написать свой язык программирования :).
                                                  Можно посмотреть мой проект 32-битного компилятора Delavar: http://dc32.ml. Этот проект не так амбициозен и так и не был доведен до конца. Есть англо- и русскоязычный синтаксис. Есть поддержка ООП. Есть версия для Windows и Linux. Есть простенькая IDE, написанная на Делаваре (с подсветкой синтаксиса).

                                                    0
                                                    Вы молодец. Хотел плюсануть в карму, зашёл в профиль и оказалось, что уже сделал это когда-то. Успехов!
                                                      0

                                                      А можно как-нибудь посмотреть на AST? Вот буквально, как оно выглядит. Дамп какой-нибудь, или типа того?

                                                        0
                                                        Визуализацию AST не делал. /lang/u_ast* — код.
                                                          0

                                                          Код я видел, мне бы на дамп поглядеть, хотя бы для самых простых случаев. Ну вот хотя бы как proc main из самого первого примера выглядит в AST?


                                                          Это не совсем праздный интерес, если есть такая возможность — хоть сюда комментарием можете выплеснуть?

                                                            0

                                                            В компиляторе каждая нода AST представляет собой класс (под каждый языковой блок — отдельный) + интерфейс базовой ноды.


                                                            Ноды, содержащие блоки кода, т.е. ноды class, enum, method, for, while и т.д. содержат массив, в который в процессе разбора кода закидываются по порядку ноды, входящие в блок кода.


                                                            Полное AST даже простого кода, который приведен в начале статьи выглядело бы очень громоздким, чтобы его тут постить, т.к. для того чтобы собрать этот код нужно также включить в сборку ряд файлов с базовыми классами & методами, благодаря которым все работает (например поддержка некоторых операторов языковых, инициализация выполнения кода, частичное управление памятью, обработка и traceback исключений, реализованы полностью на Mash'е, см. /bin/win64/inc/sys/*)

                                                              0
                                                              содержат массив

                                                              Ох. А править-то его как? Тут поля слишком узкие, чтобы полностью аргументировать мою точку зрения (вот тут можно про нее почитать по-английски), но AST обязан иметь языконезависимое представление, если вы рассчитываете на взлет языка. Я мог бы попробрвать запустить его, скажем, в виртуальной машине эрланга, если бы AST выражался по-человечески, а не паскалевскими классами.


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

                                                                0

                                                                Править AST можно как и любое дерево.
                                                                Речь шла про массив указателей на другие ноды.


                                                                Поддержку макросов можно внедрить хоть сейчас, только вот необходимость её наличия в таком языке конечно сомнительна :)

                                                        0

                                                        Смутил скриншот со стектрейсом – почему исключение «floating point division by zero»? С одной стороны, деление float на 0 определено и даёт infinity, а с другой, все числа в коде целые.

                                                          0
                                                          1. По поводу infinity — не во всех языках деление на ноль определено.
                                                          2. Деление — вещественная операция, т.е. при делении числа из типа int превращаются в тип float. Для целочисленного деления в языке есть отдельный оператор, как и во многих других языках.

                                                        Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                                                        Самое читаемое