Тривиль: грамматика — первый заход

Первый набросок: грамматика в формате ANTLR4 (написал с листа и никак не проверял).

Нет лексики, не расписаны выражения, и вообще очень предварительно. На мой взгляд, в целом неплохо, вот только ключевое слово ‘пер’ или ‘перем’ вместо ‘var’ мне не нравится. Может быть стоит сразу найти хорошее слово для ‘mut’ и ‘imm’ — mutable, immutable, так как точно понадобится.

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

модуль Привет

импорт «консоль»

вход {
консоль.печать(«Привет, мир!»)
}

Я сделал приватный проект в gitflic — думаю туда выкладывать какое-то время, а потом запрошу сделать его публичным.

5 комментариев


  1. Надо побольше примерчиков.

    Вместо ПЕР я предпочитаю использовать ДАНО. Чтобы различать переменные и ссылки предпочитаю использовать УКАЗ. Но ссылка — это не указатель, но поскольку в компиляторе Оберона ниже нет сборщика мусора (это принципиально).

    Мой вариант русификации Оберона с ключевыми словами, если интересно:
    https://github.com/prospero78/Oberon07ru

    https://github.com/prospero78/Oberon07ru/blob/master/Source/Compiler/%D0%BC%D0%BE%D0%B4%D0%A1%D0%BA%D0%B0%D0%BD%D0%B5%D1%80.ob07

    Также не рекомендую использовать gitflic.ru

    Есть более адекватный ресурс — tvoygit.ru.
    Не надо ни о чём просить и никого. Публичные и приватные проекты доступны из коробки.

    Ответить

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

      По поводу tvoygit.ru: я не хочу ставить гит на свой сервер или комп. Мне скучно возиться с установкой и поддержкой, жизнь коротка.
      Я бы предпочел платить небольшие деньги, но не думать об этом.

      Ответить

  2. Попробую покритиковать со своей (конечно, плохо исследованной) т.з. радикального перехода к «герметичности».

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

    Кстати, а где у нее будет верх (начало) и низ (конец)? Или будет все как в Java — миллион классов и откуда начинать читать — совсем непонятно.

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

    Впрочем, для решения второй обозначенной проблемы — неуправляемого/произвольного доступа к интерфейсам ввода/вывода, или шире, к интерфейсам через «статические» точки доступа доступные всем отовсюду, — иерархия модулей никак не помогает, тут нужен парадигмальный сдвиг к представлению программы в runtime как иерархии вложенных компонент.

    Этот сдвига подобен переходу от программы-спагетти с массой GOTO откуда угодно куда угодно к структурному программированию Дейкстры. Вот только теперь нам нужны не кубики-процедуры с «одним входом, одним выходом», а кубики-компоненты с набором предоставляемых и потребляемых интерфейсов, потенциально — с внутренним состоянием и внутренней активностью, и запретом на доступ к I/O и прочим ништякам через «публичные статические» точки доступа типа «консоль».печать

    Ответить

    1. Как я понимаю, это уже не про Тривиль.

      Если так, то сейчас не время — сначала Тривиль, потом bootstrap, потом «чуть больше чем Тривиль», потом, может быть «Не тривиль». И вот тогда….
      Сначала площадка для проведения экспериментов, потом эксперименты.

      И вообще, я предпочитаю работать, как в известном анекдоте:
      — Леша, вы верите в любовь с первого взгляда?
      — У меня зрение не очень, мне надо пощупать.

      Ответить

  3. Алексей Н — для меня нет разницы между модулем и классом (в смысле типа, а не в том что объекты с reference семаниткой) в том смысле что для модуля число экземпляторов типа модуль фиксированно, а для классового-типа нет.
    module Math
    sin (x: Real): Real
    end
    … := Math.sin (3.14) /* Мы тут имеем толкьо один обхект тиа Math — ты де помнишь как пару дней наад в КОтлиен смотерли на object Unit {} — это схоже */

    class Circle
    radius: Real
    end
    c is new Сircle() // явное создание объекта

    Т.е. понятие типа для меня первично а сколько объектов бесконечно много, один или фиксированнео количество это другое дело
    unit Type
    foo do … end
    end
    Type.foo () // Это обращение к модулю
    (new Type).foo () // Это вызов той же foo из созданного тут де объекта

    ну а фиксированное количество объектов можно получить если сказать (синтаксис не важен) что на вот эту иерархию типов (units) будет доступен вот такой вот модуль — синглетон определнного типа или на конкретную функцию есть модуль-синглетон. Отсюда получается 3 вида модулей — глобальные (объект только один), на иерархию и на функцию. В моей голове ничего принципиально не поменялось со времен нашей любимой Модулы-2 — модули есть стурктурная замена статиков.
    Другими словами тип = модуль = класс
    Ну и мое любимое
    unit Integer { // В синтаксисе фигурных скокбок :-)
    + (other: Integer): Integer
    + (other: Real): Real
    := (other: Integer) // x: Integer := 5
    := (other: Real) // x: Integer := 3.14
    := (): Real /* Вот для этого
    foo (par: Real) {…}
    foo (5)
    */
    }
    Ну и тогда все главы про narrowing, widening просто идут на … :-) Все в стандартной библиотеке , все в исходном коде — бери и смотри …
    Слово unit «придумал» Зуев :-) Все совпадения с TurboPascal и некоторый другой язык случайны :-)

    Ответить

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *