Mystical:一种基于环状结构的编程语言可视化
Mystical
我一直想创造一种类似于魔法阵的编程语言。这个项目更像是一种用魔法圆环的方式来编写 PostScript 代码,但在本文档中,我将称它为 Mystical。
环 (Rings)
Mystical 的结构基于环。这些环是由文本和符印 (sigils) 组成的圆形带状区域,具有内外边界。程序主环的内容从最右侧(3点钟方向)的点开始,并逆时针方向 (widdershins,counter-clockwise) 流动,这样既尊重了 PostScript 的角度,也反映了从外部编写这些环的假设。辅助环从它们连接到调用者的点开始。
Mystical 中有三种类型的环:
- 可执行数组,在 PostScript 中用
{
}
表示,在 Mystical 中用内外都有简单圆环边界,内部有一个星形的结构表示。起始/结束点用炼金术中的“工作完成”符号标记。 - 不可执行数组,在 PostScript 中用
[
]
表示,与可执行数组类似,但没有星形。起始/结束点用一个简单的三角形标记。 - 字典,在 PostScript 中用
<<
>>
表示,在 Mystical 中用具有双重外边界和单一内边界的多边形表示。起始/结束点的标记方式与数组相同。
xarray | array | dict
---|---|---
|
|
{ 0 0 currentlinewidth 1.5 mul 0 360 arc fill }
| [ 0 1 2 1.5 40 360 (Hooray World) ]
| << /longname (Mystical) /w 45 /h 8 /x 23 >>
(请注意,字典图像中的条目顺序与 PostScript 文本不同,因为 PostScript 中不保留字典插入顺序。)
当这些结构之一出现在另一个结构内部时,包含点上的一个小圆圈或点会连接到一条线,该线通向辅助环的起始/结束符印。
[
0 1 2 1.5 40 360 <<
/longname (Mystical) /w 45 /h 8 /x 23
>>
]
理论上,可以在 PostScript 中以 Mystical 无法处理的方式使用 [ ]
和 << >>
:
[ 1 2 3 split { ] /first exch def [ } if 4 5 6 ] /final exch def
所以请不要这样做。
诸如 gsave/grestore
和 begin/end
之类的其他命令更有可能以非平衡或循环交叉的方式使用,因此它们被视为下面的普通符印。
文本和符印 (Text and Sigils)
环的边缘包含文本或符印。符印是代表运算符、变量或其他关键字的符号。任何名称,在 PostScript 中写为 /name
,在 Mystical 中则用围绕或叠加名称文本或其符印的三角形来代替。任何字符串,在 PostScript 中用 ()
表示,在 Mystical 中都包含在类似纹章的形状中,其中包含字符串文本。
array | /array | (array) | foo | /foo | /foobar
---|---|---|---|---|---
|
|
|
|
|
标准符印 (Standard Sigils)
许多内置运算符都有自己的符印。如果运算符作为名称或运算符出现(但如果它作为字符串出现则不然),则使用这些符印代替运算符的文本。我通常根据命令的首字母和概念的插图来制作这些符印,尽管在某些情况下,我采取了更具说明性的路线或创建了一些标准的视觉语言。以下是一些示例 - 有关完整列表,请参见 Standard Sigils。
符印示例 (Sample sigils)
|
|
|
|
|
|
|
---|---|---|---|---|---|---|---
dup | copy | add | mul | neg | for | forall | repeat
|
|
|
|
|
|
|
if | ifelse | eq | ne | ge | gt | le | lt
|
|
|
|
|
|
|
moveto | lineto | arc | arcn | curveto | closepath | stroke | fill
|
|
|
|
|
|
gsave | grestore | translate | scale | rotate | setmatrix | currentmatrix
|
|
|
|
|
|
|
setrgbcolor | currentrgbcolor | setcmykcolor | currentcmykcolor | sethsbcolor | currenthsbcolor | setgray | currentgray
|
|
|
|
|
|
dict | begin | end | def | get | put | length
用户符印 (User Sigils)
可以在运行时将新函数或名称的符印添加到 sigil_bank
。它们应该适合以原点为中心的 1 单位正方形,因此任何坐标都不应超过 0.5(当然,您可以转换坐标系以方便)。如果您使用 nstroke
而不是 stroke
,您将获得与标准符印相同的书法效果。
可以使用任何符印系统设计用户变量的符印。我的示例主要使用字母碰撞,灵感来自 Spare 的 Chaos Magick 系统,但任何将单词变成符号的东西都可以使用 - kameas、wheels、Square Word Calligraphy、Circular Gallifreyan、sitelen sitelen、illustration、puns 等。基于官方运算符的新名称可以合并这些运算符的标准符印。
|
|
|
---|---|---|---
arg | dot | softscale | nstroke
/name { ring } def
的连字 (Ligature)
有一个 def
的符印,但是一个非常常见的模式是压入一个名称,压入一个函数,并将名称定义为函数。为了节省空间并强调此定义,此情况有一种特殊的语法,包括通常的名称三角形,其连接线的末端直接位于其下方,并且完全省略了 def 符印。为了简单起见,这扩展到其他两种环类型。def
的任何其他用法都将像往常一样使用 def 符印。
{ ... /even { 2 mod 0 eq } def ... }
这仅适用于可执行数组内部。我考虑过在字典中对 /name { ring }
使用类似的连字,但是出错的可能性太大了。
算法示例 (Sample Algorithms)
快速排序是此页面顶部的插图。
欧几里德的 GCD 算法(使用我 dmmlib 中的 /arg {exch def} def
函数):
用于生成 Mystical 图像的函数 (Functions to generate Mystical images)
所有这些都在 "mystical.ps" 中定义。
mystical
:接受一个 array,xarray 或者 dict 并在 Mystical 中渲染它,必要时下降到子结构中。整个图像将被缩放以适合单位圆。
mystical_evoke
:与 mystical
相同,但它接受在当前字典中查找的名称。
mystical_evoke_label
:类似于 mystical_evoke
,但添加了一个 name-def 连字,名称位于顶部,并将图像定向为名称符印朝上。
所有这些都有附加了 _unscaled
的版本,它们会跳过缩放步骤。环的厚度将为 1 个单位,因此图像将非常大。
布局问题 (layout issues)
目前,该代码计算出子圆的布局,以便没有任何东西发生冲突,但是它过于安全了,因此大多数程序会分布得很开。对于此页面上的示例,我运行了解析/布局函数(mystical_get_spell
和 mystical_make_evocation_ligature
),然后在调用绘图函数 draw_sigil
和 draw_link
之前调整了结果。我打算改进默认布局。
这是一种编程语言吗? (Is this a programming language?)
目前,这是一种绘制 PostScript 程序的方法 - 没有解释器可以提取 Mystical 图像并执行相应的计算。它可以由人运行和解释,或者(更可能)由人阅读并将其转换为 PostScript 程序并运行它。我现在将进一步的哲学论点留给其他人。
这可以用于其他语言吗? (Could this work for other languages?)
这种方法似乎适用于只有运算符的其他语言,例如 Forth。具有更复杂语句的语言可能会更加困难,我不知道每个大括号或缩进都有一个新的环是否会过于繁琐。
此页面由 Denis 于 2025-05-16 生成。