Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions layout/src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1239,6 +1239,12 @@ impl Parser {
if symbol::lookup(&t.value).word == "add" {
return self.parse_pratt(UNARY_PREC);
}
// 一元前缀 & = 取址:&x ≡ kv·abs(x)(中缀 & 仍为按位与,走 pratt 中缀路径)。
if symbol::lookup(&t.value).word == "bitand" {
let arg = self.parse_pratt(UNARY_PREC)?;
let op = format!("kv{}abs", keytree::MEMBER_SEP);
return Some(ast::call(&op, vec![arg]));
}
let arg = self.parse_pratt(UNARY_PREC)?;
return Some(ast::call(&t.value, vec![arg]));
}
Expand Down
2 changes: 1 addition & 1 deletion layout/src/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,7 @@ static ENTRIES: &[Entry] = &[
precedence: 80,
arith: true,
cmp: false,
unary: false,
unary: true,
},
Entry {
word: "bitor",
Expand Down
3 changes: 2 additions & 1 deletion stdlib/kvlang/spec/01-词法/08-运算符基础.kv
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@ x = 42 // 左写、右读
- `/`(U+002F)**不是**除号。它只用于绝对路径字面量与注释(`//`、`/*`);出现在其他位置的裸 `/` 不承
载算术除法语义。

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

## 比较运算符

Expand Down
20 changes: 19 additions & 1 deletion stdlib/kvlang/spec/01-词法/09-逻辑位运算与优先级.kv
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,27 @@ lib kvlang/spec/词法/逻辑位运算与优先级 {

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

`&` 一符二用,靠位置区分(同 C):操作数之后为中缀**按位与**;表达式起始或运算符之后为一元前缀
**取址**(见下 [[取址运算符 `&`]])。

## 取址运算符 `&`

一元前缀 `&loc` 求值为 `loc` 所在节点的绝对 KV 路径字符串,等价 `kv·abs(loc)`。操作数须为位置
(location):帧内裸名、容器/成员链(`x`、`list·1`、`base·field`)。

产物是普通路径串,与指针惯例同型(可 `-> p` 存指针、`+ "·n"` 拼子节点、赋给 `next` 字段);与
`*T` ref 标注互补——`&` 造路径,`*` 标注该路径所指目标的形态(见 [[ptr]])。

```
list·1 -> x
&x -> p // p = x 的绝对路径串,等价 kv·abs(x)
p + "·next" -> q
```

## 优先级

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

| 运算符 | 优先级 |
|--------|--------|
Expand Down
3 changes: 3 additions & 0 deletions stdlib/kvlang/spec/03-类型系统/16-ptr.kv
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,8 @@ lib kvlang/spec/类型系统/ptr {
"/n1" -> p // 引号 = 路径串(指针)
p·val -> v // 按值解引用:读 /n1·val
```

局部变量/容器成员取指针用一元前缀 `&`(`&x ≡ kv·abs(x)`,返回绝对路径串),与 `*` ref 标注互补——
`&` 造路径、`*` 标注目标形态(见 [[逻辑位运算与优先级]] 取址运算符)。
"#### -> /lib/kvlang/spec/类型系统/ptr
}
2 changes: 1 addition & 1 deletion stdlib/kvlang/spec/附录/05-表达式.kv
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ primary = literal | ident | path
| struct_literal
| map_literal

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

infix_primary = binary_op expr

Expand Down
1 change: 1 addition & 0 deletions stdlib/kvlang/spec/附录/07-内建函数.kv
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ builtin_call = ( "abs" | "neg" | "sign" | "pow" | "sqrt" | "exp" | "log"
(* ÷ : 两侧 int → 整除(C 风格);任一侧 float → 浮除 *)
(* s[i] 读返单字符字符串,越界返 "";s[i]="X" 单字符替换写回新串 *)
(* + 作用在 string∧string → 拼接 *)
(* &x 是 kv·abs(x) 的语法糖(一元前缀取址,返回 x 的绝对路径串);与中缀按位与 a & b 靠位置区分 *)
```
"## -> /lib/kvlang/spec/附录/内建函数
}
24 changes: 8 additions & 16 deletions tutorial/08-leetcode/002_add_two_numbers.kv
Original file line number Diff line number Diff line change
Expand Up @@ -47,23 +47,15 @@ rwfunc add(a:[]char/utf32, b:[]char/utf32) -> () {
}

rwfunc test() -> () {
l1:[int64]·Node = {}
kv·abs(l1) -> b1
b1 + "·2" -> a2
b1 + "·3" -> a3
l1·1:Node = {val=2 next=a2}
l1·2:Node = {val=4 next=a3}
l1·3:Node = {val=3 next=""}
b1 + "·1" -> h1
a3:Node = {val=3}
a2:Node = {val=4 next=&a3}
a1:Node = {val=2 next=&a2}
&a1 -> h1

l2:[int64]·Node = {}
kv·abs(l2) -> b2
b2 + "·2" -> c2
b2 + "·3" -> c3
l2·1:Node = {val=5 next=c2}
l2·2:Node = {val=6 next=c3}
l2·3:Node = {val=4 next=""}
b2 + "·1" -> h2
b3:Node = {val=4}
b2:Node = {val=6 next=&b3}
b1:Node = {val=5 next=&b2}
&b1 -> h2

lc·add(h1, h2)
}
24 changes: 8 additions & 16 deletions tutorial/08-leetcode/021_merge_two_lists.kv
Original file line number Diff line number Diff line change
Expand Up @@ -44,23 +44,15 @@ rwfunc merge(a:[]char/utf32, b:[]char/utf32) -> () {
}

rwfunc test() -> () {
a:[int64]·Node = {}
kv·abs(a) -> ab
ab + "·2" -> a2
ab + "·3" -> a3
a·1:Node = {val=1 next=a2}
a·2:Node = {val=2 next=a3}
a·3:Node = {val=4 next=""}
ab + "·1" -> ha
a3:Node = {val=4}
a2:Node = {val=2 next=&a3}
a1:Node = {val=1 next=&a2}
&a1 -> ha

b:[int64]·Node = {}
kv·abs(b) -> bb
bb + "·2" -> b2
bb + "·3" -> b3
b·1:Node = {val=1 next=b2}
b·2:Node = {val=3 next=b3}
b·3:Node = {val=4 next=""}
bb + "·1" -> hb
b3:Node = {val=4}
b2:Node = {val=3 next=&b3}
b1:Node = {val=1 next=&b2}
&b1 -> hb

merge(ha, hb)
}
38 changes: 14 additions & 24 deletions tutorial/08-leetcode/083_remove_dup_list.kv
Original file line number Diff line number Diff line change
Expand Up @@ -43,29 +43,19 @@ rwfunc show(head:[]char/utf32) -> () {
}

rwfunc test() -> () {
e:[int64]·Node = {}
kv·abs(e) -> eb
eb + "·2" -> e2
eb + "·3" -> e3
e·1:Node = {val=1 next=e2}
e·2:Node = {val=1 next=e3}
e·3:Node = {val=2 next=""}
eb + "·1" -> e1
dedup(e1)
show(e1)
e3:Node = {val=2}
e2:Node = {val=1 next=&e3}
e1:Node = {val=1 next=&e2}
&e1 -> eh
dedup(eh)
show(eh)

f:[int64]·Node = {}
kv·abs(f) -> fb
fb + "·2" -> f2
fb + "·3" -> f3
fb + "·4" -> f4
fb + "·5" -> f5
f·1:Node = {val=1 next=f2}
f·2:Node = {val=1 next=f3}
f·3:Node = {val=2 next=f4}
f·4:Node = {val=3 next=f5}
f·5:Node = {val=3 next=""}
fb + "·1" -> f1
dedup(f1)
show(f1)
f5:Node = {val=3}
f4:Node = {val=3 next=&f5}
f3:Node = {val=2 next=&f4}
f2:Node = {val=1 next=&f3}
f1:Node = {val=1 next=&f2}
&f1 -> fh
dedup(fh)
show(fh)
}
28 changes: 12 additions & 16 deletions tutorial/08-leetcode/141_linked_list_cycle.kv
Original file line number Diff line number Diff line change
Expand Up @@ -32,23 +32,19 @@ struct Node {
}

rwfunc test() -> () {
c:[int64]·Node = {}
kv·abs(c) -> cb
cb + "·1" -> c1
cb + "·2" -> c2
cb + "·3" -> c3
c·1:Node = {val=3 next=c2}
c·2:Node = {val=2 next=c3}
c·3:Node = {val=0 next=c1}
r1 = has_cycle(c1)
c1:Node = {val=3}
c2:Node = {val=2}
c3:Node = {val=0}
c1·next = &c2
c2·next = &c3
c3·next = &c1
&c1 -> h1
r1 = has_cycle(h1)
println(r1)

n:[int64]·Node = {}
kv·abs(n) -> nb
nb + "·1" -> n1
nb + "·2" -> n2
n·1:Node = {val=1 next=n2}
n·2:Node = {val=2 next=""}
has_cycle(n1) -> r2
d2:Node = {val=2}
d1:Node = {val=1 next=&d2}
&d1 -> h2
has_cycle(h2) -> r2
println(r2)
}
32 changes: 10 additions & 22 deletions tutorial/08-leetcode/160_intersection_list.kv
Original file line number Diff line number Diff line change
Expand Up @@ -45,32 +45,20 @@ rwfunc get_intersection(ha:[]char/utf32, hb:[]char/utf32) -> () {

rwfunc test() -> () {
// common tail: 8→4→5
t:[int64]·Node = {}
kv·abs(t) -> tb
tb + "·1" -> t8
tb + "·2" -> t4
tb + "·3" -> t5
t·1:Node = {val=8 next=t4}
t·2:Node = {val=4 next=t5}
t·3:Node = {val=5 next=""}
t5:Node = {val=5}
t4:Node = {val=4 next=&t5}
t8:Node = {val=8 next=&t4}

// list A: 4→1→t8
a:[int64]·Node = {}
kv·abs(a) -> ab
ab + "·2" -> a2
a·1:Node = {val=4 next=a2}
a·2:Node = {val=1 next=t8}
ab + "·1" -> ha
a2:Node = {val=1 next=&t8}
a1:Node = {val=4 next=&a2}
&a1 -> ha

// list B: 5→6→1→t8
b:[int64]·Node = {}
kv·abs(b) -> bb
bb + "·2" -> b2
bb + "·3" -> b3
b·1:Node = {val=5 next=b2}
b·2:Node = {val=6 next=b3}
b·3:Node = {val=1 next=t8}
bb + "·1" -> hb
b3:Node = {val=1 next=&t8}
b2:Node = {val=6 next=&b3}
b1:Node = {val=5 next=&b2}
&b1 -> hb

get_intersection(ha, hb)
}
24 changes: 8 additions & 16 deletions tutorial/08-leetcode/203_remove_linked_elements.kv
Original file line number Diff line number Diff line change
Expand Up @@ -27,21 +27,13 @@ rwfunc remove(head:[]char/utf32, val:int64) -> () {
}

rwfunc test() -> () {
n:[int64]·Node = {}
kv·abs(n) -> nb
nb + "·2" -> n2
nb + "·3" -> n3
nb + "·4" -> n4
nb + "·5" -> n5
nb + "·6" -> n6
nb + "·7" -> n7
n·1:Node = {val=1 next=n2}
n·2:Node = {val=2 next=n3}
n·3:Node = {val=6 next=n4}
n·4:Node = {val=3 next=n5}
n·5:Node = {val=4 next=n6}
n·6:Node = {val=5 next=n7}
n·7:Node = {val=6 next=""}
nb + "·1" -> h
n7:Node = {val=6}
n6:Node = {val=5 next=&n7}
n5:Node = {val=4 next=&n6}
n4:Node = {val=3 next=&n5}
n3:Node = {val=6 next=&n4}
n2:Node = {val=2 next=&n3}
n1:Node = {val=1 next=&n2}
&n1 -> h
remove(h, 6)
}
18 changes: 6 additions & 12 deletions tutorial/08-leetcode/206_reverse_linked_list.kv
Original file line number Diff line number Diff line change
Expand Up @@ -29,17 +29,11 @@ rwfunc reverse(head:[]char/utf32) -> () {
}

rwfunc test() -> () {
n:[int64]·Node = {}
kv·abs(n) -> nb
nb + "·2" -> p2
nb + "·3" -> p3
nb + "·4" -> p4
nb + "·5" -> p5
n·1:Node = {val=1 next=p2}
n·2:Node = {val=2 next=p3}
n·3:Node = {val=3 next=p4}
n·4:Node = {val=4 next=p5}
n·5:Node = {val=5 next=""}
nb + "·1" -> h
n5:Node = {val=5}
n4:Node = {val=4 next=&n5}
n3:Node = {val=3 next=&n4}
n2:Node = {val=2 next=&n3}
n1:Node = {val=1 next=&n2}
&n1 -> h
reverse(h)
}
24 changes: 8 additions & 16 deletions tutorial/08-leetcode/234_palindrome_list.kv
Original file line number Diff line number Diff line change
Expand Up @@ -40,23 +40,15 @@ rwfunc is_pal(head:[]char/utf32) -> () {
}

rwfunc test() -> () {
p:[int64]·Node = {}
kv·abs(p) -> pb
pb + "·2" -> p2
pb + "·3" -> p3
pb + "·4" -> p4
p·1:Node = {val=1 next=p2}
p·2:Node = {val=2 next=p3}
p·3:Node = {val=2 next=p4}
p·4:Node = {val=1 next=""}
pb + "·1" -> hp
p4:Node = {val=1}
p3:Node = {val=2 next=&p4}
p2:Node = {val=2 next=&p3}
p1:Node = {val=1 next=&p2}
&p1 -> hp
is_pal(hp)

q:[int64]·Node = {}
kv·abs(q) -> qb
qb + "·2" -> q2
q·1:Node = {val=1 next=q2}
q·2:Node = {val=2 next=""}
qb + "·1" -> hq
q2:Node = {val=2}
q1:Node = {val=1 next=&q2}
&q1 -> hq
is_pal(hq)
}
15 changes: 7 additions & 8 deletions tutorial/12-struct/03-linked-list.kv
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// linked-list: struct 节点存进 map(int 键、struct 值),指针用绝对路径
// 语义: /list 是 [int64]·Node 的 map;节点存在自增整数键 ·1 ·2 ·3
// next 字段存下一节点的绝对路径串(""=尾);"路径"·field 解引用
// linked-list: 局部 struct 节点变量 + & 取址串成链表
// 语义: 每个节点是帧内 struct 局部变量;next 存下一节点地址(&node ≡ kv·abs(node))
// ""=尾;cur·field 按 next 路径解引用遍历。尾节点先建,&node 恒指向已存在节点
// 期望输出:
// 10
// 20
Expand All @@ -11,11 +11,10 @@ struct Node {
}

rwfunc test() -> () {
/list:[int64]·Node = {}
/list·1:Node = {val=10 next="/list·2"}
/list·2:Node = {val=20 next="/list·3"}
/list·3:Node = {val=30}
cur = "/list·1"
n3:Node = {val=30}
n2:Node = {val=20 next=&n3}
n1:Node = {val=10 next=&n2}
cur = &n1
while (cur != "") {
cur·val -> v
println(v)
Expand Down
Loading
Loading