FSML In His Grace
FSML is a postfix concatenative homoiconic programming language designed to give me and everyone for those who wish a familiar, comfortable postfix programming environment and be competitive in modern realities, effective in every way.
The development is in its infancy, so most of the document will be devoted to language concepts and its development plans, not what has already been done. Although for the seed, I will first show a few small examples of what has already been done. Then I will describe the concept. And at the end I will give you the technical details. I hope that the reader is generally familiar with postfix programming languages, such as Forth, Factor or 8th.
First of all, note that objects duplicated using typical Forth words like dup, over, etc are available by reference, not by value. In particular, this means the following.
1 dup
[2] 1 -> 1
25 +
[2] 1 + 25 -> 1 + 25
Oops! This is not what you would expect from a Forth or a Factor. In these languages, the result would be:
1 dup
\ 1 -> 1
25 +
\ 26 -> 1
This is explained by the fact that in FSML, by duplicating a stack element using DUP, we actually duplicated a reference to an object, since an abstract stack can actually contain only references. Thus, both resulting stack elements are references to the same object. And by adding 25 to it, we made this object an expression of 25 + 1. Therefore, the top two elements of the stack refer to this expression.
Need "ind" after "dup" to detach. "ind" means independent or individual, at your choice. It creates a new object and rearranges the reference to it. This new object still references the same subexpression as before. But all subsequent operations on it will create a different semantic graph. From now on, they will have a different history of operations on them, imprinted in the nodes of abstract semantic graphs (asg). But what was done before "ind" will remain a common part of the history of operations on the element.
1 dup ind
[2] 1 -> 1
25 +
[2] 1 + 25 -> 1
There is also a "dc" operation, which means deep copy. dc performs a deep copy of the asg corresponding to the stack element. From this moment on, a completely new graph appears, which has no vertices in common with the original one. The new graph is not an exact copy of the original one. For example, the vertices of a graph may contain uids, which by definition cannot be the same as in the prototype.
.js
:
12 34 + 56 78 -
[2] 56 - 78 -> 12 + 34
.js
\ var subex_2 = 12 + 34;
\ var subex_3 = 56 - 78;
.eval
:
as df + 56 78 -
[2] 56 - 78 -> "as" + "df"
.eval
\ evaluated stack: [ -22, asdf ]
123 some_name !
some_name @ 456 +
.eval dp
[ 579 ]
ol
:
+ * ol
[1] (var_2, var_3, var_4) => var_4 * (var_3 + var_2);
mul
with !
:
* ol mul ! .js
\ var mul = (var_0, var_1) => var_1 * var_0;
if
, 1range
and 1fold
:
12 dup [ 1 1range mul @ 1fold ] [ 0 ] if .eval
* ol mul !
[479001600]
if
and while
:
12 dup [ 1 [ over * over 1 - ] while swap dp ] [ 0 ] if .eval
[479001600]
'We put a string with spaces on the stack and immediately drop it using dp' dp
'dp is a short alias for the classic drop' dp
'Without indentation between the left quotation mark and the beginning of the line, this is
not necessary here' dp
"Or with double quotes" dp
Or_without_quotes_at_all_if_the_string_does_not_contain_whitespace_characters dp
'\ Full-fledged comments have not yet been implemented, so for now it is also for comments,
although the string start can be from the backslash of the Forth comment, so that it is
clear, but still it is only a string' dp
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);