[Из песочницы] Почему бы не сделать свой Lisp для веба?
Вот есть JavaScript — прекрасная вещь. И прекрасная она по большей части потому, что дебаггер и отладочные инструменты встроены в каждый Браузер. Без дебаггера и инспектора DOM-дерева было гораздо тяжелее что-либо разрабатывать на JavaScript.
Вот я и решил запилить свой Lisp, но с хорошим дебаггером. Взял маленький, простенький littlelisp и отрефакторил его на 99%. Заточил под пошаговое выполнение и создал свою IDE, простую но работающую.
В итоге получилось следующее.
Сам язык получился смесью Lisp и JavaScript-a потому, что Lisp я знал плохо, а JavaScript хорошо:)
Далее примеры кода.
(alert document.location.href)
(setq x "ok!")
(alert (x.substring 0 2))
;; пример с if
(setq x (prompt "Value of X:"))
(if (x == null)
(setq x "(none)")
(alert (+ "x = " x))
:else
(alert (+ "x = " x))
)
;; кстати тела while/if не обязательно оборачивать в свой список
(setq i 0)
(while (i < 10)
(console.log i)
(++ i)
)
;; синтаксический сахар для арифметических и логических операторов
(x < 2) ;; -> (< x 2)
((x < 2) && (x > -1)) ;; -> (&& (< x 2) (> x -1))
((x < 2) || (x > -1)) ;; -> (|| (< x 2) (> x -1))
(x + 1 2 3) ;; -> (+ x 1 2 3) => x+1+2+3
(x ++) ;; -> (++ x)
(++ x y z) ;; -> увеличит на 1 переменные x, y, z последовательно
;; создание и заполнение JS-объекта
(setq obj1 (new Object))
(setq obj1.a 123 obj1.b "abc") ;; можно за один вызов
(setq name "c")
(setq obj1.@name ()) ;; @ - разыменовывает
(setq obj1.@name.0 111)
(setq obj1.@name.1 222)
(setq obj1.@name.2 333)
(alert (obj1.c.join " ")) ;; покажет "111 222 333"
;; классы пока-что сделаны по простому
(defclass Трамвай
:extends Object
:instvars "из_чего номер"
:classvars "всего"
:constructor init
)
(setq Трамвай.всего 0)
(defmeth Трамвай.init (номер основа) (
(setq this.номер номер)
(setq this.из_чего основа)
(Трамвай.всего ++)
))
(defmeth Трамвай.поехали () (
(window.alert (+ " Трамвай №" this.номер " из " this.из_чего " за вами выехал!"))
))
(setq Трамвай1 (new Трамвай 9 "буханки хлеба"))
(Трамвай1.поехали)
(alert (+ "Трамваев всего: " Трамвай.всего))
;; лямбды и функции тоже есть
((lambda (x y) (alert (x + y)) "a" "b")
(defun f1 (x) (alert (x + " - ok!")))
(f1 "f1")
;; выполнение произвольного кода пока-что через создание и вызов JS-функции
((new Function "msg" "alert(msg);") document.title)
;; эксепшены тоже можно отлавливать
(catch (a.b)) ;; вернёт Exception object (Error: "a" is undefined!)
Собственно, сам проект на гитхабе здесь: https://github.com/SaemonZixel/littlelisp.js
Напоследок скажу, что код пока-что в бете (на 17 мая 2020г). Ошибок пока что много и я их потихоньку нахожу и правлю :(
Но зато дебаггер почти как в Smalltalk-средах разработки получилось сделать! :)
Можно доводить код прям в деббагере. Выделить любой фрагмент кода и просмотреть результат или запустить вложенный деббагер.