FSML In His Grace

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

Разработка находится в зачаточном состоянии, поэтому большая часть документа будет посвящена концепции языка и планам его развития, а не тому, что уже сделано. Хотя для затравки я сначала покажу несколько небольших примеров того, что уже сделано. Затем опишу концепцию. И в конце приведу технические подробности. Надеюсь, что читатель в общих чертах знаком с постфиксными языками прогаммирования, как Форт, Фактор или 8th.

В первую очередь заметьте, что объекты, дублируемые с помощью классических Форт-слов как dup, over, и т.д. доступны по ссылке, а не по значению. В частности это означает следующее.

1 dup

[2] 1 -> 1

25 +

[2] 1 + 25 -> 1 + 25

Упс! Это не то, чего бы вы ожидали от Форта или Фактора. В этих языках результат был бы таким:

1 dup

stack: 1 -> 1

25 +

stack: 26 -> 1

Это объясняется тем, что в FSML продублировав элемент стека используя DUP мы на самом деле продублировали ссылку на объект, так как абстрактный стек в действительности может содержать только ссылки. Таким образом оба получившихся элемента стека - это ссылки на один объект. И прибавив к нему 25, мы сделали этот объект выражением 25 + 1. Поэтому два верхних элемента стека ссылаются на это выражение.

Нужен "ind" после "dup", чтобы разделить их. "ind" означает независимый или индивидуальный, на ваш выбор. Он создаёт новый объект и переставляет ссылку на него. Этот новый объект всё ещё ссылается на то же подвыражение, что и раньше. Но все последующие операции над ним будут создавать другой семантический граф. С этого момента они будут иметь разную историю операций над ними, запечатлённую в вершинах абстрактных семантических графов (asg). Но то, что было сделано до "ind" останется общей частью истории операций над элементом.

1 dup ind

[2] 1 -> 1

25 +

[2] 1 + 25 -> 1

Существует также операция "dc", что означает deep copy. dc производит глубокое копирование asg, соответствующего элементу стека. С этого момента появляется полностью новый граф, который не имеет общих вершин с исходным. Новый граф не является точной копией исходного. Например вершины графа могут содержать uid, которые по определению не могут быть такими же, как в прототипе.

1. Вычисляем факториал числа 12 с if и while :

12 dup [ 1 [ over * over 1 - ] while swap dp ] [ 0 ] if .eval

\ [479001600]

2. Считываем и записываем переменную в старом добром трогательном Форт-стиле с @ и ! :

123 some_name !
some_name @ 456 +
.eval dp

\ [ 579 ]

3. Строки :

'Кладём на стек строку с пробелами и сразу же её сбрасываем при помощи dp' dp


'dp - это короткий псевдоним для классического drop' dp

'Без отступа между левой кавычкой и началом строки, здесь это не нужно' dp
"Или с двойными кавычками" dp

Или_вообще_без_кавычек_если_строка_не_содержит_пробелов dp

'\ Полноценные комментарии ещё не реализованы, поэтому пока это и для комментариев, хотя начать строку можно с обратного слэша Форт-комментария, чтобы было понятно, но всё же это только строка' dp

4. Склеиваем сторки в цикле :

"" comma !
2 "" [ comma @ + ' somename_' + over + '_alias = somename_'
+ over + ', ' comma ! over 1 - ] while swap dp
'let ' swap + ';' +
.eval dp

\ [let somename_2_alias = somename_2, somename_1_alias = somename_1;]

5. Создаём пустой массив и кладём пару элементов :

list 12 push 34 push
.js

\ var subex_2 = [];
\ var subex_1 = (subex_2 .push (12), subex_2);
\ var subex_0 = (subex_1 .push (34), subex_1);

© 2022, 2023 Александр (Шýрко) Стадничéнко