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
4 changes: 0 additions & 4 deletions parser/inst.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,10 +115,6 @@ func (p *parser) desugarMemberWrite(inst *ast.Instruction) {
if len(inst.Writes) != 1 || !strings.Contains(inst.Writes[0], keytree.MemberSep) {
return
}
// 绝对路径 key(如 /lib/math.Pi)里的 . 是 key 的一部分,不是成员分隔符
if inst.Writes[0][0] == '/' {
return
}
s := inst.Writes[0]
dt := strings.Index(s, keytree.MemberSep)
base := s[:dt]
Expand Down
32 changes: 16 additions & 16 deletions rwir/builtin/array.go
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ func (atOp) Call(f *rwir.Frame) error {
fp := keytree.FrameRoot(f.PC)
if base := separatedBase(f.KV, fp, f.Inst.Reads[0].Name); base != "" {
idx := int(asInt64(inputs[1]))
return writeResult(f, kvspace.GetOne(f.KV, fmt.Sprintf("%s<%d>", base, idx)))
return writeResult(f, kvspace.GetOne(f.KV, fmt.Sprintf("%s[%d]", base, idx)))
}
}
if kvspace.IsNone(inputs[0]) {
Expand Down Expand Up @@ -295,7 +295,7 @@ func (arraySetOp) Call(f *rwir.Frame) error {
fp := keytree.FrameRoot(f.PC)
if base := separatedBase(f.KV, fp, f.Inst.Reads[0].Name); base != "" {
idx := int(asInt64(inputs[1]))
f.KV.Set([]kvspace.KVPair{{Key: fmt.Sprintf("%s<%d>", base, idx), Val: inputs[2]}})
f.KV.Set([]kvspace.KVPair{{Key: fmt.Sprintf("%s[%d]", base, idx), Val: inputs[2]}})
vthread.Set(bg, f.KV, f.Vtid, rwir.NextPC(f.PC), "running")
return nil
}
Expand Down Expand Up @@ -361,7 +361,7 @@ func (hasOp) Call(f *rwir.Frame) error {
return writeResult(f, kvspace.NewBool(!kvspace.IsNone(v)))
}

// scatterOp: array.scatter(src) -> dst。解压 compact 数组为散 key(dst<0>..dst<N-1>),不动 src。
// scatterOp: array.scatter(src) -> dst。解压 compact 数组为散 key(dst[0]..dst[N-1]),不动 src。
type scatterOp struct{}
func (scatterOp) Call(f *rwir.Frame) error {
if len(f.Inst.Writes) == 0 {
Expand All @@ -385,7 +385,7 @@ func (scatterOp) Call(f *rwir.Frame) error {
n := int(arr.ArrayLen())
pairs := make([]kvspace.KVPair, 0, n)
for i := 0; i < n; i++ {
pairs = append(pairs, kvspace.KVPair{Key: fmt.Sprintf("%s<%d>", dst, i), Val: typedIndex(arr, i)})
pairs = append(pairs, kvspace.KVPair{Key: fmt.Sprintf("%s[%d]", dst, i), Val: typedIndex(arr, i)})
}
if len(pairs) > 0 {
f.KV.Set(pairs)
Expand All @@ -394,7 +394,7 @@ func (scatterOp) Call(f *rwir.Frame) error {
return nil
}

// compactOp: array.compact(src) -> dst。压缩散 key(src<0>..src<N-1>)为 compact 数组,不动 src。
// compactOp: array.compact(src) -> dst。压缩散 key(src[0]..src[N-1])为 compact 数组,不动 src。
type compactOp struct{}
func (compactOp) Call(f *rwir.Frame) error {
if len(f.Inst.Reads) == 0 {
Expand All @@ -411,7 +411,7 @@ func (compactOp) Call(f *rwir.Frame) error {
src := resolveWriteSlot(f.KV, fp, f.Inst.Reads[0].Name)
var elems []kvspace.XValue
for i := 0; ; i++ {
v := kvspace.GetOne(f.KV, fmt.Sprintf("%s<%d>", src, i))
v := kvspace.GetOne(f.KV, fmt.Sprintf("%s[%d]", src, i))
if kvspace.IsNone(v) {
break
}
Expand All @@ -428,7 +428,7 @@ func (compactOp) Call(f *rwir.Frame) error {
return nil
}

// ensureScattered 若 base 是 compact 数组,就地 scatter 为散 key(写 base<0>..base<N-1>,删 base)。
// ensureScattered 若 base 是 compact 数组,就地 scatter 为散 key(写 base[0]..base[N-1],删 base)。
func ensureScattered(f *rwir.Frame, base string) {
arr := kvspace.GetOne(f.KV, base)
if kvspace.IsNone(arr) || kvspace.ElemSize(arr.Kind()) <= 0 {
Expand All @@ -437,7 +437,7 @@ func ensureScattered(f *rwir.Frame, base string) {
n := int(arr.ArrayLen())
pairs := make([]kvspace.KVPair, 0, n)
for i := 0; i < n; i++ {
pairs = append(pairs, kvspace.KVPair{Key: fmt.Sprintf("%s<%d>", base, i), Val: typedIndex(arr, i)})
pairs = append(pairs, kvspace.KVPair{Key: fmt.Sprintf("%s[%d]", base, i), Val: typedIndex(arr, i)})
}
f.KV.Set(pairs)
f.KV.Del(base)
Expand All @@ -455,7 +455,7 @@ func (appendOp) Call(f *rwir.Frame) error {
base := resolveWriteSlot(f.KV, fp, f.Inst.Reads[0].Name)
ensureScattered(f, base)
n := separatedLen(f.KV, base)
f.KV.Set([]kvspace.KVPair{{Key: fmt.Sprintf("%s<%d>", base, n), Val: readInputs(f)[1]}})
f.KV.Set([]kvspace.KVPair{{Key: fmt.Sprintf("%s[%d]", base, n), Val: readInputs(f)[1]}})
nextPC(f)
return nil
}
Expand All @@ -482,31 +482,31 @@ func (sliceOp) Call(f *rwir.Frame) error {
elems := make([]kvspace.KVPair, 0, hi-lo)
for i := lo; i < hi; i++ {
elems = append(elems, kvspace.KVPair{
Key: fmt.Sprintf("%s<%d>", base, i-lo),
Val: kvspace.GetOne(f.KV, fmt.Sprintf("%s<%d>", base, i)),
Key: fmt.Sprintf("%s[%d]", base, i-lo),
Val: kvspace.GetOne(f.KV, fmt.Sprintf("%s[%d]", base, i)),
})
}
f.KV.Set(elems)
for i := hi - lo; i < n; i++ {
f.KV.Del(fmt.Sprintf("%s<%d>", base, i))
f.KV.Del(fmt.Sprintf("%s[%d]", base, i))
}
nextPC(f)
return nil
}

// separatedBase 返回分离数组的 base key 路径(base<0> 存在);非分离返回 ""。
// separatedBase 返回分离数组的 base key 路径(base[0] 存在);非分离返回 ""。
func separatedBase(kv kvspace.KVSpace, fp, name string) string {
base := resolveWriteSlot(kv, fp, name)
if kvspace.IsNone(kvspace.GetOne(kv, base+"<0>")) {
if kvspace.IsNone(kvspace.GetOne(kv, base+"[0]")) {
return ""
}
return base
}

// separatedLen 返回分离数组的元素数(base<0>..base<N-1>)。
// separatedLen 返回分离数组的元素数(base[0]..base[N-1])。
func separatedLen(kv kvspace.KVSpace, base string) int {
for i := 0; ; i++ {
if kvspace.IsNone(kvspace.GetOne(kv, fmt.Sprintf("%s<%d>", base, i))) {
if kvspace.IsNone(kvspace.GetOne(kv, fmt.Sprintf("%s[%d]", base, i))) {
return i
}
}
Expand Down
10 changes: 5 additions & 5 deletions rwirext/json/json.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ func rootKey(kv kvspace.KVSpace, framePath string, r rwir.Param) string {
}

// buildMap 递归把 root 下的子树读成 map[string]any。
// 目录→嵌套 map;散 key 数组(name<0>..name<N-1>)→ JSON 数组;叶子→Go 值。
// 目录→嵌套 map;散 key 数组(name[0]..name[N-1])→ JSON 数组;叶子→Go 值。
func buildMap(kv kvspace.KVSpace, root string) map[string]any {
m := map[string]any{}
scat := map[string][]int{}
Expand All @@ -95,7 +95,7 @@ func buildMap(kv kvspace.KVSpace, root string) map[string]any {
sort.Ints(idxs)
arr := make([]interface{}, len(idxs))
for i, idx := range idxs {
arr[i] = toJSONValue(kvspace.GetOne(kv, root+"/"+base+"<"+strconv.Itoa(idx)+">"))
arr[i] = toJSONValue(kvspace.GetOne(kv, root+"/"+base+"["+strconv.Itoa(idx)+"]"))
}
m[base] = arr
}
Expand All @@ -119,10 +119,10 @@ func writeMap(kv kvspace.KVSpace, root string, m map[string]any) {
}
}

// splitArrayName 解析散 key 数组元素名 name<i> → (name, i, ok)。
// splitArrayName 解析散 key 数组元素名 name[i] → (name, i, ok)。
func splitArrayName(name string) (base string, idx int, ok bool) {
lt := strings.LastIndex(name, "<")
if lt <= 0 || !strings.HasSuffix(name, ">") {
lt := strings.LastIndex(name, "[")
if lt <= 0 || !strings.HasSuffix(name, "]") {
return "", 0, false
}
i, err := strconv.Atoi(name[lt+1 : len(name)-1])
Expand Down
4 changes: 2 additions & 2 deletions tutorial/04-array/separated.kv
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# separated: 散 key 数组(元素分散在 b<0>..b<N-1> 各自 key,按 key 寻址)
# separated: 散 key 数组(元素分散在 b[0]..b[N-1] 各自 key,按 key 寻址)
# 语义: 字面量初始化默认 compact;array.scatter 把 compact 转散 key,array.compact 反向
# 散 key 元素访问与 compact 一致,统一用 [i]
# 期望输出:
Expand All @@ -9,7 +9,7 @@
# c[0] = 10
rwfunc main() -> () {
a:[]int64 = [10, 20, 30] # 字面量初始化 → compact
b <- array.scatter(a) # 显式 scatter:compact a → 散 key b(b<0>..b<2>
b <- array.scatter(a) # 显式 scatter:compact a → 散 key b(b[0]..b[2]
len(b) -> n1
println("len(b) =", n1)
println("b[0] =", b[0]) # 散 key 元素访问 [i]
Expand Down
2 changes: 1 addition & 1 deletion tutorial/10-rwirext/json.kv
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
# 3) ./kvlang tutorial/10-rwirext/json.kv
# 语义: json.to(rootkey) 把 rootkey 整棵子树读成 map[string]any 再 json.Marshal;
# json.from(json) 反序列化 JSON 写回子树。目录→嵌套对象;compact 数组([]T)与
# 散 key 数组(name<0>..name<N-1>)统一序列化为 JSON 数组。
# 散 key 数组(name[0]..name[N-1])统一序列化为 JSON 数组。
# 期望输出:
# j = {"active":true,"age":42,"cont":[10,20,30],"grp":{"c":1,"d":2},"name":"alice","scat":[10,20,30],"score":3.14}
# name = alice
Expand Down
Loading