Skip to content

Commit c0078f3

Browse files
authored
Merge pull request #284 from array2d/wip/struct-list-spec
struct/链表 tutorial + spec 运算符/内建 + parser/symbol
2 parents 8c8ffbe + d271d4b commit c0078f3

18 files changed

Lines changed: 129 additions & 171 deletions

layout/src/parser.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1239,6 +1239,12 @@ impl Parser {
12391239
if symbol::lookup(&t.value).word == "add" {
12401240
return self.parse_pratt(UNARY_PREC);
12411241
}
1242+
// 一元前缀 & = 取址:&x ≡ kv·abs(x)(中缀 & 仍为按位与,走 pratt 中缀路径)。
1243+
if symbol::lookup(&t.value).word == "bitand" {
1244+
let arg = self.parse_pratt(UNARY_PREC)?;
1245+
let op = format!("kv{}abs", keytree::MEMBER_SEP);
1246+
return Some(ast::call(&op, vec![arg]));
1247+
}
12421248
let arg = self.parse_pratt(UNARY_PREC)?;
12431249
return Some(ast::call(&t.value, vec![arg]));
12441250
}

layout/src/symbol.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,7 @@ static ENTRIES: &[Entry] = &[
260260
precedence: 80,
261261
arith: true,
262262
cmp: false,
263-
unary: false,
263+
unary: true,
264264
},
265265
Entry {
266266
word: "bitor",

stdlib/kvlang/spec/01-词法/08-运算符基础.kv

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,8 @@ x = 42 // 左写、右读
4444
- `/`(U+002F**不是**除号。它只用于绝对路径字面量与注释(`//``/*`);出现在其他位置的裸 `/` 不承
4545
载算术除法语义。
4646

47-
一元 `+``-` 作前缀;`√`(U+221A,平方根)亦为一元前缀运算符。
47+
一元 `+``-` 作前缀;`√`(U+221A,平方根)亦为一元前缀运算符。`&` 亦兼一元前缀(取址,
48+
`&x ≡ kv·abs(x)`);其中缀身份(按位与)与前缀身份靠位置区分,同 C,详见 [[逻辑位运算与优先级]]。
4849

4950
## 比较运算符
5051

stdlib/kvlang/spec/01-词法/09-逻辑位运算与优先级.kv

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,27 @@ lib kvlang/spec/词法/逻辑位运算与优先级 {
1818

1919
分别为按位与、按位或、按位异或、左移、右移。
2020

21+
`&` 一符二用,靠位置区分(同 C):操作数之后为中缀**按位与**;表达式起始或运算符之后为一元前缀
22+
**取址**(见下 [[取址运算符 `&`]])。
23+
24+
## 取址运算符 `&`
25+
26+
一元前缀 `&loc` 求值为 `loc` 所在节点的绝对 KV 路径字符串,等价 `kv·abs(loc)`。操作数须为位置
27+
(location):帧内裸名、容器/成员链(`x``list·1``base·field`)。
28+
29+
产物是普通路径串,与指针惯例同型(可 `-> p` 存指针、`+ "·n"` 拼子节点、赋给 `next` 字段);与
30+
`*T` ref 标注互补——`&` 造路径,`*` 标注该路径所指目标的形态(见 [[ptr]])。
31+
32+
```
33+
list·1 -> x
34+
&x -> p // p = x 的绝对路径串,等价 kv·abs(x)
35+
p + "·next" -> q
36+
```
37+
2138
## 优先级
2239

23-
中缀运算符的优先级如下(数值越大结合越紧);一元前缀运算符(`+ - ! √`)优先级高于全部中缀。
40+
中缀运算符的优先级如下(数值越大结合越紧);一元前缀运算符(`+ - ! √ &`)优先级高于全部中缀。
41+
`&a·b ≡ &(a·b)`(成员链先结合,同 C 的 `&a.b`)。
2442

2543
| 运算符 | 优先级 |
2644
|--------|--------|

stdlib/kvlang/spec/03-类型系统/16-ptr.kv

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,8 @@ lib kvlang/spec/类型系统/ptr {
1616
"/n1" -> p // 引号 = 路径串(指针)
1717
p·val -> v // 按值解引用:读 /n1·val
1818
```
19+
20+
局部变量/容器成员取指针用一元前缀 `&``&x ≡ kv·abs(x)`,返回绝对路径串),与 `*` ref 标注互补——
21+
`&` 造路径、`*` 标注目标形态(见 [[逻辑位运算与优先级]] 取址运算符)。
1922
"#### -> /lib/kvlang/spec/类型系统/ptr
2023
}

stdlib/kvlang/spec/附录/05-表达式.kv

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ primary = literal | ident | path
1818
| struct_literal
1919
| map_literal
2020

21-
prefix_unary = "-" | "!" | "" (* √ = sqrt(U+221A,一元 *)
21+
prefix_unary = "-" | "!" | "" | "&" (* √ = sqrt(U+221A&x ≡ kv·abs(x) 取址 *)
2222

2323
infix_primary = binary_op expr
2424

stdlib/kvlang/spec/附录/07-内建函数.kv

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ builtin_call = ( "abs" | "neg" | "sign" | "pow" | "sqrt" | "exp" | "log"
3232
(* ÷ : 两侧 int → 整除(C 风格);任一侧 float → 浮除 *)
3333
(* s[i] 读返单字符字符串,越界返 "";s[i]="X" 单字符替换写回新串 *)
3434
(* + 作用在 string∧string → 拼接 *)
35+
(* &x 是 kv·abs(x) 的语法糖(一元前缀取址,返回 x 的绝对路径串);与中缀按位与 a & b 靠位置区分 *)
3536
```
3637
"## -> /lib/kvlang/spec/附录/内建函数
3738
}

tutorial/08-leetcode/002_add_two_numbers.kv

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -47,23 +47,15 @@ rwfunc add(a:[]char/utf32, b:[]char/utf32) -> () {
4747
}
4848

4949
rwfunc test() -> () {
50-
l1:[int64]·Node = {}
51-
kv·abs(l1) -> b1
52-
b1 + "·2" -> a2
53-
b1 + "·3" -> a3
54-
l1·1:Node = {val=2 next=a2}
55-
l1·2:Node = {val=4 next=a3}
56-
l1·3:Node = {val=3 next=""}
57-
b1 + "·1" -> h1
50+
a3:Node = {val=3}
51+
a2:Node = {val=4 next=&a3}
52+
a1:Node = {val=2 next=&a2}
53+
&a1 -> h1
5854

59-
l2:[int64]·Node = {}
60-
kv·abs(l2) -> b2
61-
b2 + "·2" -> c2
62-
b2 + "·3" -> c3
63-
l2·1:Node = {val=5 next=c2}
64-
l2·2:Node = {val=6 next=c3}
65-
l2·3:Node = {val=4 next=""}
66-
b2 + "·1" -> h2
55+
b3:Node = {val=4}
56+
b2:Node = {val=6 next=&b3}
57+
b1:Node = {val=5 next=&b2}
58+
&b1 -> h2
6759

6860
lc·add(h1, h2)
6961
}

tutorial/08-leetcode/021_merge_two_lists.kv

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -44,23 +44,15 @@ rwfunc merge(a:[]char/utf32, b:[]char/utf32) -> () {
4444
}
4545

4646
rwfunc test() -> () {
47-
a:[int64]·Node = {}
48-
kv·abs(a) -> ab
49-
ab + "·2" -> a2
50-
ab + "·3" -> a3
51-
1:Node = {val=1 next=a2}
52-
2:Node = {val=2 next=a3}
53-
3:Node = {val=4 next=""}
54-
ab + "·1" -> ha
47+
a3:Node = {val=4}
48+
a2:Node = {val=2 next=&a3}
49+
a1:Node = {val=1 next=&a2}
50+
&a1 -> ha
5551

56-
b:[int64]·Node = {}
57-
kv·abs(b) -> bb
58-
bb + "·2" -> b2
59-
bb + "·3" -> b3
60-
1:Node = {val=1 next=b2}
61-
2:Node = {val=3 next=b3}
62-
3:Node = {val=4 next=""}
63-
bb + "·1" -> hb
52+
b3:Node = {val=4}
53+
b2:Node = {val=3 next=&b3}
54+
b1:Node = {val=1 next=&b2}
55+
&b1 -> hb
6456

6557
merge(ha, hb)
6658
}

tutorial/08-leetcode/083_remove_dup_list.kv

Lines changed: 14 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -43,29 +43,19 @@ rwfunc show(head:[]char/utf32) -> () {
4343
}
4444

4545
rwfunc test() -> () {
46-
e:[int64]·Node = {}
47-
kv·abs(e) -> eb
48-
eb + "·2" -> e2
49-
eb + "·3" -> e3
50-
1:Node = {val=1 next=e2}
51-
2:Node = {val=1 next=e3}
52-
3:Node = {val=2 next=""}
53-
eb + "·1" -> e1
54-
dedup(e1)
55-
show(e1)
46+
e3:Node = {val=2}
47+
e2:Node = {val=1 next=&e3}
48+
e1:Node = {val=1 next=&e2}
49+
&e1 -> eh
50+
dedup(eh)
51+
show(eh)
5652

57-
f:[int64]·Node = {}
58-
kv·abs(f) -> fb
59-
fb + "·2" -> f2
60-
fb + "·3" -> f3
61-
fb + "·4" -> f4
62-
fb + "·5" -> f5
63-
1:Node = {val=1 next=f2}
64-
2:Node = {val=1 next=f3}
65-
3:Node = {val=2 next=f4}
66-
4:Node = {val=3 next=f5}
67-
5:Node = {val=3 next=""}
68-
fb + "·1" -> f1
69-
dedup(f1)
70-
show(f1)
53+
f5:Node = {val=3}
54+
f4:Node = {val=3 next=&f5}
55+
f3:Node = {val=2 next=&f4}
56+
f2:Node = {val=1 next=&f3}
57+
f1:Node = {val=1 next=&f2}
58+
&f1 -> fh
59+
dedup(fh)
60+
show(fh)
7161
}

0 commit comments

Comments
 (0)