-
Notifications
You must be signed in to change notification settings - Fork 1
/
take2.mdtlbl
97 lines (86 loc) · 3.09 KB
/
take2.mdtlbl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
#* 此篇使用的是v0.5.0的语法
在这个版本为take语法进行了扩展
这是一个让代码复用更加方便的版本
首先, 允许`take F;`这种写法了, 这将等价于以前的`take __ = F;`
我们不再需要填写一个用不上的常量来符合语法了
然后是一个重要的语法, `take[Value*]`, 你可以在左边take的右侧插入一个方括号
当你没有在里面写值时, 这等同于你不加这个方括号
如果你在里面写了1至若干个值,
那么take将不会被构建为一个Take, 而是一个Expand.
你可以将它理解成一个块, 常量的作用域就是来源于Expand
然后它会将你写在方括号内的`Value`按顺序在这个块内
`const _0 = V1;`
`const _1 = V2;`
`const _2 = V3;`
这种, 将你传入的顺序分配给`_0` `_1` `_2`名字的常量
注意, 这不会进行label收集, 它仅在语法层面的`const`被编写时有效
所以, 如果你想要在内部使用被跳转标签, 请老实的构建一个`const`再传入
然后是take的本身`Take`
接着, 如果你的take返回用常量没有缺省的话,
还会再加一行`ConstLeak`, 将这个你给出的返回常量泄露到外部一层块
因为这种形式的take建立了一个块, 不将其泄露到上一层块我们将无法再获取它
这个`ConstLeak`目前无法被手动编写, 防止滥用、作用域逃逸等不规范使用
*#
const DO = (
# 这是一个用来执行传入的第一个参数的const
print "enter";
take _0;
print "exit";
);
take[(
print "hello";
)] DO;
#* 以上代码会被编译为
print "enter"
print "hello"
print "exit"
*#
# 可以看到, 我们使用take计算了这个`DO`, 然后它被展开
# 但是根据上述介绍, 我们知道, 是先将_0被const到了我们传入的DExp中
# 然后再进行take的
# 所以take展开的内容中间才会正常获取_0得到我们的DExp
const ADD = (
# 这是一个将传入值计算并加1再与之前的自身相乘的DExp
take N = _0; # 这里首先将传入的值计算出来, 避免如果是一个DExp反复计算
op $ N + 1;
op $ $ * N;
);
take[(op $ 3 + 4;)] RES = ADD;
print RES;
#* 以上代码会被编译为
op add __1 3 4
op add __0 __1 1
op mul __0 __0 __1
print __0
*#
# 首先ADD头部的take会先将传入的DExp计算出来
# 然后再使用
# 接着我们的RES被映射到了返回句柄__0, 接下来使用并将其打印了出来
# 我们可以看看如果不使用`take N = _0`并且N换成_0直接使用会怎样
# 以下为代码
const ADD = (
# 这是一个将传入值计算并加1再与之前的自身相乘的DExp
op $ _0 + 1;
op $ $ * _0;
);
take[(op $ 3 + 4;)] RES = ADD;
print RES;
#* 以上代码会被编译为
op add __1 3 4
op add __0 __1 1
op add __2 3 4
op mul __0 __0 __2
print __0
*#
# 我们可以看到, 3 + 4被重复计算了
# 这就是先使用take计算出来的意义
# 多个值的示例
const PRINT2 = (
print _0 _1;
);
take[123 456] PRINT2;
#* 以上代码会被编译为
print 123
print 456
*#
# 多个值传入也是可以的