Создание своего языка - Lisp

Узнай цену своей работы

Формулировка задачи:

Однажды появилась идея, и вот теперь пишу о ней. Не знаю правильную ли ветку форума я выбрал, потому что вряд ли какая-то подойдет, но так как лисп первый функциональный язык, я думаю тут мне помогут. Появилась идея написать язык программирования. Хотел бы спросить у форумчан о возможных проблемах, неточностях и тем с чем мне предстоит встретиться. Сам язык, по идее, должен получится функциональным, императивным, объектно-ориентированным, динамически типизированным с возможностью прямого указания типов (возможно многое противоречит друг-другу ))). В данный момент я придумываю синтаксис и больше всего интересуют возможные связанные с ним проблемы. Основная идея в том что вызовы функций и методов всегда s-expressions, что функции что методы возвращают значение последней вычисленной формы. Как в лиспе тут будут пакеты которые называются Namespace и классы, которые соответственно Class. Основные идеи пространства имен: 1. В пакетах всё публично, поэтому в случае подключения пакетов пространства имен просто конектится к стандартному пакету, который подключен всегда по умолчанию. В случае повторения имен различных подключенных пакетов, функции с этими именами не могут быть вызваны как обычно и требуют прямого указания пакета в месте вызова(так как в классах). 2. В классах же все наоборот приватно, но для классов автоматически определенны функции publiс, private, protected, setter, getter, get-set которые определяют видимость и доступ. 3. Пакеты могут быть преобразованы в классы и наоборот Основные синтаксические плюшки: = оператор присвоения имени значения $ подсмотрел в хаскелле(замена скобок) {} анонимное пространство имен (автоматически подключается к вышестоящему пространству) (Function arg1 arg2 ...) вызов функции c аргументами '() или [] список (-> (арг1 арг2 ...) (применение арг1 арг2)) лямбда-функция (ns.function arg1 arg2) вызов функции из пространства нс на аргументах арг1 арг2 (class.method arg1 arg2) вызов метода класса сласс с аргументами арг1 арг2
ns = {                                                  //присвоение имени нс указателя на новое пространство имен
    a, b, c                                             //обьявление имен a,b,c в данном пакете
    x = 1                                               //присвоение имени х значения 1
    int::y = 2                                          //присвоение имени у , которое имеет тип инт значения 2 
 
    funс = $ -> (arg1 arg2) (+ arg1 arg2)                //имени func соотвествует лямбда функция сумирующая два принимающих аргумента
 
    b = (func x y)                                      //присвоение имени б значения вызова функции func с аргументами х у то бишь b = 3
 
    c = $ -> () {let1 = 1, let2 = 2} (funс let1 let2)   //с это функция которая создает две переменные внутри себя и вызывает func на этих аргументах
 
    l = (- 5 3 2)                               //l = 0
    b = $ + 1 2 3 4                             //b = 10
    Class::test = {                             //объявление класса тест грубо говоря произойдет что-то вроде (cast {...} 'class)

        (constructor arg)                       //объявления конструктора принимающего один аргумент, будет зависеть от set
 
        test = "test"                           //объявления приватной переменной строки тест в классе тест
        getTest = $ -> () this.test             //объявление приватного метода который возвращает значение переменной тест
        setTest = $ -> (arg) {this.test = arg}  //функция присвоения переменной тест значения, но тут я думаю изменить но не знаю как. Не хочу вводить функцию set(((
        //HELLO коментарий
    }
 
    z = (test.new)                              //создание экземпляра класса тест и присвоение его значения имени z
    е = (z.getTest)                             //думаю дальше понятно
    (z.setTest "already")
}
Все идеи мнения и т.д.)
Как вариант можно ввести специальную функцию для создания конструктора, может вот так
$ constructor (arg) { this.test = arg }

Решение задачи: «Создание своего языка»

textual
Листинг программы
(defmethod foo ((s string))
  (concatenate 'string s s))
 
 
(defmethod foo ((i number))
  (* i i))
 
 
(defmethod foo ((lst list))
  (loop for arg in lst collect (foo arg)))
 
 
CL-USER 1 > (mapcar #'foo '("aa" 2 3 4))
("aaaa" 4 9 16)
 
CL-USER 2 >

Объяснение кода листинга программы

В данном коде определён метод foo, который может принимать три типа аргументов: строку, число и список. В каждом из соответствующих методов происходит следующее:

  1. Для строки — происходит рекурсивный вызов метода с аргументом, который является результатом конкатенации строки и самого аргумента.
  2. Для числа — происходит рекурсивный вызов метода с аргументом, который является результатом умножения числа на само себя.
  3. Для списка — происходит итерация по элементам списка, на которых применяется метод foo, после чего результат собирается в новый список. Также в коде происходит вызов метода foo с аргументом aa, результатом чего является строка aaaa. Затем происходит вызов метода foo с аргументом [2 3 4], результатом чего является список [aaaa 4 9 16].

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

7   голосов , оценка 3.429 из 5
Похожие ответы