Создание своего языка - 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, который может принимать три типа аргументов: строку, число и список. В каждом из соответствующих методов происходит следующее:
- Для строки — происходит рекурсивный вызов метода с аргументом, который является результатом конкатенации строки и самого аргумента.
- Для числа — происходит рекурсивный вызов метода с аргументом, который является результатом умножения числа на само себя.
- Для списка — происходит итерация по элементам списка, на которых применяется метод foo, после чего результат собирается в новый список.
Также в коде происходит вызов метода foo с аргументом
aa
, результатом чего является строкаaaaa
. Затем происходит вызов метода foo с аргументом [2 3 4], результатом чего является список [aaaa
4 9 16].
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д