diff --git a/base/ctx/ctx.go b/base/ctx/ctx.go index 82bbf9cc..208a7c89 100644 --- a/base/ctx/ctx.go +++ b/base/ctx/ctx.go @@ -9,10 +9,6 @@ const CTX = "ctx" var Index = &ice.Context{Name: CTX, Help: "标准模块"} -func init() { - ice.Index.Register(Index, nil, CONTEXT, COMMAND, CONFIG) - ice.Info.Stack[Prefix()] = func(m *ice.Message, key string, arg ...ice.Any) ice.Any { - return nil - } -} +func init() { ice.Index.Register(Index, nil, CONTEXT, COMMAND, CONFIG) } + func Prefix(arg ...string) string { return kit.Keys(CTX, arg) } diff --git a/base/nfs/dir.go b/base/nfs/dir.go index 59c4300e..b26c5a51 100644 --- a/base/nfs/dir.go +++ b/base/nfs/dir.go @@ -201,12 +201,15 @@ func Relative(m *ice.Message, p string) string { return p } func SplitPath(m *ice.Message, p string) []string { + line := kit.Select("1", strings.Split(p, ice.DF), 1) + p = strings.TrimPrefix(p, kit.Path("")+ice.PS) + p = strings.Split(p, ice.DF)[0] if ls := kit.Split(kit.Select(ice.SRC_MAIN_GO, p), ice.PS); len(ls) == 1 { - return []string{PWD, ls[0]} + return []string{PWD, ls[0], line} } else if ls[0] == ice.USR { - return []string{strings.Join(ls[:2], ice.PS) + ice.PS, strings.Join(ls[2:], ice.PS)} + return []string{strings.Join(ls[:2], ice.PS) + ice.PS, strings.Join(ls[2:], ice.PS), line} } else { - return []string{strings.Join(ls[:1], ice.PS) + ice.PS, strings.Join(ls[1:], ice.PS)} + return []string{strings.Join(ls[:1], ice.PS) + ice.PS, strings.Join(ls[1:], ice.PS), line} } } func Dir(m *ice.Message, field string) *ice.Message { diff --git a/base/tcp/host.go b/base/tcp/host.go index 5a3c520f..d8e9445e 100644 --- a/base/tcp/host.go +++ b/base/tcp/host.go @@ -88,21 +88,15 @@ func IsLocalHost(m *ice.Message, ip string) bool { return m.Cmdx(HOST, I func PublishLocalhost(m *ice.Message, url string) string { return m.Cmdx(HOST, PUBLISH, url) } func init() { - ice.Info.Stack[Prefix()] = func(m *ice.Message, key string, arg ...ice.Any) ice.Any { - switch key { - case kit.FuncName(IsLocalHost): - for _, v := range arg { - switch v := v.(type) { - case *ice.Message: - m = v - case string: - return IsLocalHost(m, v) - } + ice.Info.Stack[Prefix(IsLocalHost)] = func(m *ice.Message, key string, arg ...ice.Any) ice.Any { + for _, v := range arg { + switch v := v.(type) { + case *ice.Message: + m = v + case string: + return IsLocalHost(m, v) } - return false - default: - m.ErrorNotImplement(key) - return nil } + return false } } diff --git a/base/tcp/tcp.go b/base/tcp/tcp.go index b29d7e5e..e4a7361d 100644 --- a/base/tcp/tcp.go +++ b/base/tcp/tcp.go @@ -11,4 +11,4 @@ var Index = &ice.Context{Name: TCP, Help: "通信模块"} func init() { ice.Index.Register(Index, nil, HOST, PORT, CLIENT, SERVER) } -func Prefix(arg ...string) string { return kit.Keys(TCP, kit.Keys(arg)) } +func Prefix(arg ...ice.Any) string { return kit.Keys(TCP, kit.Keys(arg...)) } diff --git a/base/yac/expr.go b/base/yac/expr.go index 2d8bfa4a..01cbb06a 100644 --- a/base/yac/expr.go +++ b/base/yac/expr.go @@ -26,16 +26,15 @@ const ( END = "}" ) -var keyword = regexp.MustCompile(`[_a-zA-Z][_a-zA-Z0-9\.]*`) - var level = map[string]int{ "//": 200, "/*": 200, "*/": 200, - "&": 100, // "*": 100, "!": 100, + "!": 100, "&": 100, // "*": 100, "[": 100, "]": 100, "++": 100, "--": 100, "*": 40, "/": 40, "+": 30, "-": 30, "<": 20, ">": 20, ">=": 20, "<=": 20, "!=": 20, "==": 20, "&&": 10, "||": 10, DEFS: 2, DEFINE: 2, ASSIGN: 2, FIELD: 2, OPEN: 1, CLOSE: 1, } +var keyword = regexp.MustCompile(`^[_a-zA-Z.][_a-zA-Z0-9.]*$`) type Expr struct { list ice.List @@ -90,6 +89,15 @@ func (s *Expr) setv(m *ice.Message, p int, op string, v Any) Any { return s.value(m, k, v, op) } } +func (s *Expr) isop(k Any) bool { + switch k := k.(type) { + case int: + return level[s.gets(k)] > 0 + case string: + return level[k] > 0 + } + return false +} func (s *Expr) opv(m *ice.Message, p int, op string, v Any) Any { if !s.runable() { return s.getv(m, p) @@ -103,7 +111,7 @@ func (s *Expr) ops(m *ice.Message) { if !s.runable() || s.getl(-2) < 10 { return } - s.pops(3, s.opv(m, -3, s.gets(-2), s.getv(m, -1))) + s.pops(3, s.opv(m, -3, s.gets(-2), s.get(-1))) } func (s *Expr) end(m *ice.Message) Any { if !s.runable() || len(s.list) == 0 { @@ -122,14 +130,14 @@ func (s *Expr) end(m *ice.Message) Any { } s.list = append(s.list[:0], Value{list}) default: - s.list = append(s.list[:0], s.setv(m, -3, s.gets(-2), s.getv(m, -1))) + s.list = append(s.list[:0], s.setv(m, -3, s.gets(-2), s.get(-1))) } case FIELD: list := kit.List() for i := len(s.list) - 2; i > 0; i -= 2 { if s.gets(i) == DEFINE || s.gets(i) == ASSIGN { for j := 0; j < i; j += 2 { - list = append(list, s.setv(m, j, s.gets(i), s.getv(m, j+i+1))) + list = append(list, s.setv(m, j, s.gets(i), s.get(j+i+1))) } s.list = append(s.list[:0], Value{list}) break @@ -145,49 +153,41 @@ func (s *Expr) end(m *ice.Message) Any { } return s.getv(m, 0) } -func (s *Expr) isop(k Any) bool { - switch k := k.(type) { - case int: - return level[s.gets(k)] > 0 - case string: - return level[k] > 0 - } - return false -} - func (s *Expr) sub(m *ice.Message) *Expr { sub := NewExpr(s.Stack) sub.n = s.n + 1 return sub } -func (s *Expr) ktv(m *ice.Message, ismap bool, t Any, p string) map[string]Any { +func (s *Expr) ktv(m *ice.Message, t Any, p string) map[string]Any { + var kt, vt Any + switch t := t.(type) { + case Map: + kt, vt = s.types(m, t.key, p), s.types(m, t.value, p) + } data := kit.Dict() for s.token() != END { k := "" - kit.If(ismap, func() { + kit.If(t == nil || kt != nil, func() { sub := s.sub(m) - if k = kit.Format(Trans(sub.cals(m, DEFS, END))); k == "" { - k = _parse_const(m, sub.gets(0)) - } + sub.t, sub.p = kt, p + k = kit.Format(Trans(sub.cals(m, DEFS, END))) }, func() { k = s.next(m) kit.If(s.token() != END, func() { s.next(m) }) }) kit.If(s.token() == DEFS, func() { sub := s.sub(m) - if sub.p = p; ismap { - sub.t = t + if sub.p = p; t == nil || kt != nil { + sub.t = vt } else { switch t := t.(type) { case Struct: - if field, ok := t.index[k].(Field); ok { - sub.t = field.kind - } + sub.t = t.index[k].(Field) } } - m.Debug("field %d %#v %#v", sub.n, k, sub.t) + m.Debug("field %d %s %s", sub.n, k, Format(sub.t)) data[k] = sub.cals(m, FIELD, END) - m.Debug("field %d %#v %#v", sub.n, k, data[k]) + m.Debug("field %d %s %s", sub.n, k, Format(data[k])) }) } return data @@ -197,8 +197,9 @@ func (s *Expr) ntv(m *ice.Message, t Any, p string) []Any { for !kit.IsIn(s.token(), SUPS, END) { sub := s.sub(m) sub.t, sub.p = t, p + m.Debug("field %d %d %s", sub.n, len(data), Format(sub.t)) if v := sub.cals(m, FIELD, SUPS, END); v != nil { - m.Debug("field %d %d %#v", sub.n, len(data), v) + m.Debug("field %d %d %s", sub.n, len(data), Format(v)) data = append(data, v) } } @@ -222,7 +223,6 @@ func (s *Expr) cals(m *ice.Message, arg ...string) Any { if kit.IsIn(k, arg...) { return true } - m.Debug("what %v", k) switch k { case SPLIT: return true @@ -231,28 +231,28 @@ func (s *Expr) cals(m *ice.Message, arg ...string) Any { kit.If(strings.Contains(s.gets(-1), ice.PT), func() { p = kit.Split(s.gets(-1), ice.PT)[0] }) switch t := s.getv(m, -1).(type) { case Map: - s.pops(1, Dict{s.ktv(m, true, s.value(m, kit.Keys(p, t.value)), p)}) + s.pops(1, Dict{s.ktv(m, t, p)}) return false case Slice: s.pops(1, List{s.ntv(m, t, p)}) return false case Struct: - s.pops(1, Object{Dict{s.ktv(m, false, t, p)}, t}) + s.pops(1, Object{Dict{s.ktv(m, t, p)}, t}) return false } switch t := s.t.(type) { case Map: - s.pops(0, Dict{s.ktv(m, true, s.value(m, kit.Keys(s.p, t.value)), s.p)}) + s.pops(0, Dict{s.ktv(m, t.value, s.p)}) return false case Slice: s.pops(0, List{s.ntv(m, t, s.p)}) return false case Struct: - s.pops(0, Object{Dict{s.ktv(m, false, t, s.p)}, t}) + s.pops(0, Object{Dict{s.ktv(m, t, s.p)}, t}) return false } if kit.IsIn(s.gets(-1), DEFINE) || len(s.list) == 0 && len(arg) > 0 { - s.pops(0, Dict{s.ktv(m, true, nil, "")}) + s.pops(0, Dict{s.ktv(m, s.t, s.p)}) return false } return true @@ -260,42 +260,23 @@ func (s *Expr) cals(m *ice.Message, arg ...string) Any { s.skip-- return true case MAP: - s.next(m) - key := s.next(m) - s.next(m) - value := s.next(m) - v := Map{key: key, value: value} - name := kit.Format("map[%s]%s", v.key, v.value) - s.value(m, name, v) - s.push(name) + s.push(s.Stack.types(m)) return false case SUBS: - if s.peek(m) == SUPS { - pos := s.Position - if s.next(m); !s.isop(s.peek(m)) { - v := Slice{value: s.next(m)} - name := kit.Format("[]%s", v.value) - s.value(m, name, v) - s.push(name) - return false - } - s.Position = pos + if s.peek(m) == SUPS && !kit.IsIn(kit.Select("", s.rest, s.skip+2), FIELD, SUPS, END, "") { + s.push(s.Stack.types(m)) + return false } if kit.IsIn(s.gets(-1), DEFINE) || len(s.list) == 0 && len(arg) > 0 { - s.push(List{s.ntv(m, nil, "")}) + s.push(List{s.ntv(m, s.t, s.p)}) return false } case STRUCT, INTERFACE: - s.skip-- - name := s.show() - s.rest[s.skip] = name - s.skip-- - m.Cmd(TYPE) - s.push(name) + s.push(s.Stack.types(m)) return false case FUNC: - if s.isop(-1) || len(s.list) == 0 { - s.push(s.value(m, s.funcs(m))) + if s.skip > 0 { + s.push(s.funcs(m, "")) return false } s.skip-- @@ -309,33 +290,51 @@ func (s *Expr) cals(m *ice.Message, arg ...string) Any { } if len(s.list) > 0 && !s.isop(-1) { switch k { + case OPEN: + if strings.HasSuffix(s.gets(-1), ice.PT) { + if s.peek(m) == TYPE { + switch v := s.getv(m, -1).(type) { + case Object: + s.pops(1, v.index) + default: + s.pops(1, kit.Format("%T", v)) + } + } else { + switch t := s.sub(m).cals(m, CLOSE).(type) { + case Struct: + if v, ok := s.get(-1).(Operater); ok { + s.pops(1, Value{list: []Any{v, v.Operate(INSTANCEOF, t)}}) + } + case Interface: + if v, ok := s.get(-1).(Operater); ok { + s.pops(1, Value{list: []Any{v, v.Operate(IMPLEMENTS, t)}}) + } + } + } + return false + } + switch k := s.get(-1).(type) { + case string: + s.pops(1, s.call(m, s.Stack, k)) + default: + s.pops(1, s.call(m, k, "")) + } + return false case SUBS: switch v := s.sub(m).cals(m, SUPS); s.get(-1).(type) { case string: - m.Debug("what %v %v", s.gets(-1), Trans(v)) s.pops(1, kit.Keys(s.gets(-1), kit.Format(Trans(v)))) default: - m.Debug("what %v %v", s.get(-1), v) s.pops(1, s.opv(m, -1, SUBS, v)) } return false - case OPEN: - switch k := s.get(-1).(type) { - case string: - m.Debug("call %v", k) - s.pops(1, s.call(m, s.Stack, k)) - default: - m.Debug("call %v", k) - s.pops(1, s.call(m, k, "")) - } - return false case "++", "--": s.pops(1, s.setv(m, -1, ASSIGN, s.opv(m, -1, k, nil))) return false } if !s.isop(k) { if strings.HasPrefix(k, ice.PT) { - if kit.Select("", s.rest, s.skip+1) == OPEN { + if s.peek(m) == OPEN { s.skip++ s.pops(1, s.call(m, s.getv(m, -1), strings.TrimPrefix(k, ice.PT))) return false @@ -360,7 +359,6 @@ func (s *Expr) cals(m *ice.Message, arg ...string) Any { } return false }) - m.Debug("what %v", s.list) if s.cmds(m, line) { return nil } @@ -379,31 +377,31 @@ func (s *Expr) trans(m *ice.Message, k string) Any { return Number{value: k} } } +func (s *Expr) types(m *ice.Message, t Any, p string) Any { + switch t := t.(type) { + case string: + if p == "" || kit.IsIn(t, STRING, INT) { + return t + } + return s.value(m, kit.Keys(p, t)) + default: + return t + } +} func (s *Expr) cmds(m *ice.Message, line int) (done bool) { if len(s.list) == 1 && s.skip < 2 { m.Search(s.gets(0), func(key string, cmd *ice.Command) { args := kit.List(s.gets(0)) for done = true; s.line == line; { - sub := s.sub(m) - switch sub.cals(m); v := sub.get(0).(type) { - case string: - if _v := s.value(m, v); _v != nil { - args = append(args, kit.Format(Trans(_v))) - } else { - args = append(args, v) - } - default: - args = append(args, kit.Format(Trans(v))) - } + args = append(args, kit.Format(Trans(s.sub(m).cals(m)))) } - m.Cmdy(args...) + kit.If(s.runable(), func() { m.Cmdy(args...) }) }) } return } func (s *Expr) call(m *ice.Message, obj Any, key string) Any { - v := s.sub(m).cals(m, CLOSE) - if arg := _parse_res(m, v); s.runable() { + if arg := _parse_res(m, s.sub(m).cals(m, CLOSE)); s.runable() { return s.calls(m, obj, key, nil, arg...) } else { return nil @@ -417,16 +415,16 @@ func init() { Index.MergeCommands(ice.Commands{ EXPR: {Name: "expr a, b = 1, 2", Hand: func(m *ice.Message, arg ...string) { s := _parse_stack(m) - if arg, v := s.rest, s.cals(m); !s.runable() { + if v := s.cals(m); !s.runable() { return } else if v != nil { - m.Debug("value %#v <- %v", v, arg) + m.Debug("value %s %s <- %v", Format(s), Format(v), arg) switch v := Trans(v).(type) { case Message: case Value: - kit.If(len(v.list) > 0, func() { m.Echo(kit.Format(v.list[0])) }) + kit.If(len(v.list) > 0, func() { m.Echo(kit.Format(Trans(v.list[0]))) }) default: - m.Echo(kit.Format(v)) + m.Echo(kit.Format(Trans(v))) } } else if s.token() == BEGIN { m.Echo(ice.TRUE) diff --git a/base/yac/import.go b/base/yac/import.go index 13618196..52dc97a1 100644 --- a/base/yac/import.go +++ b/base/yac/import.go @@ -28,8 +28,8 @@ func init() { s, f := _parse_frame(m) defer s.popf(m) kit.For(u.Query(), func(k string, v []string) { f.value[k] = v[0] }) - sub := s.parse(m, p, r) - kit.If(pre != "_", func() { kit.For(sub.peekf().value, func(k string, v Any) { s.frame[0].value[kit.Keys(pre, k)] = v }) }) + s.parse(m, p, r) + kit.If(pre != "_", func() { kit.For(f.value, func(k string, v Any) { s.frame[0].value[kit.Keys(pre, k)] = v }) }) } } find := func(pre, url string) { diff --git a/base/yac/stack.go b/base/yac/stack.go index ae8e9d1a..3c4c4cc8 100644 --- a/base/yac/stack.go +++ b/base/yac/stack.go @@ -8,11 +8,15 @@ import ( "strings" ice "shylinux.com/x/icebergs" + "shylinux.com/x/icebergs/base/ctx" "shylinux.com/x/icebergs/base/mdb" "shylinux.com/x/icebergs/base/nfs" kit "shylinux.com/x/toolkits" ) +type Value struct { + list []Any +} type Function struct { obj []Field arg []Field @@ -20,16 +24,19 @@ type Function struct { Position object Object } + type Frame struct { key string + name string value ice.Map defers []func() status int Position } type Stack struct { - last *Frame - frame []*Frame + last *Frame + frame []*Frame + comment []string Position } type Position struct { @@ -45,11 +52,11 @@ type Buffer struct { } func (s *Stack) peekf() *Frame { return s.frame[len(s.frame)-1] } -func (s *Stack) pushf(m *ice.Message, key string) *Frame { - f := &Frame{key: kit.Select(m.CommandKey(), key), value: kit.Dict(), Position: s.Position} +func (s *Stack) pushf(m *ice.Message, arg ...string) *Frame { + f := &Frame{key: kit.Select(m.CommandKey(), arg, 0), name: kit.Select("", arg, 1), value: kit.Dict(), Position: s.Position} kit.If(len(s.frame) > 0, func() { f.status = s.peekf().status }) - m.Debug("stack %d push %s %s", len(s.frame), f.key, s.show()) s.frame = append(s.frame, f) + m.Debug("stack %s push %s", Format(s), kit.Select(s.show(), arg, 2)) return f } func (s *Stack) popf(m *ice.Message) *Frame { @@ -57,7 +64,7 @@ func (s *Stack) popf(m *ice.Message) *Frame { for i := len(f.defers) - 1; i >= 0; i-- { f.defers[i]() } - m.Debug("stack %d pop %s %s", len(s.frame)-1, f.key, s.show()) + m.Debug("stack %s pop %s", Format(s), s.show()) kit.If(len(s.frame) > 0, func() { s.frame = s.frame[:len(s.frame)-1] }) s.last = f return f @@ -70,25 +77,28 @@ func (s *Stack) stack(cb func(*Frame, int) bool) { } } func (s *Stack) value(m *ice.Message, key string, arg ...Any) Any { + keys := strings.Split(key, ice.PT) f, n := s.peekf(), len(s.frame)-1 if len(arg) < 2 || arg[1] != DEFINE { s.stack(func(_f *Frame, i int) bool { - if _f.value[key] != nil { + if _f.value[key] != nil || _f.value[keys[0]] != nil { f, n = _f, i return true } return false }) } - keys := strings.Split(key, ice.PT) - kit.If(strings.Contains(key, ice.PS), func() { keys = []string{key} }) kit.If(len(arg) > 0, func() { + if f.value[key] != nil { + f.value[key] = arg[0] + return + } var v Any = Dict{f.value} for i := 0; i < len(keys); i++ { switch k := keys[i]; _v := v.(type) { case Operater: if i == len(keys)-1 { - m.Debug("value %d:%s set %v %#v", n, f.key, key, arg[0]) + m.Debug("value %d:%s set %s %s", n, f.key, key, Format(arg[0])) _v.Operate(k, arg[0]) } else { if v = _v.Operate(SUBS, k); v == nil { @@ -104,53 +114,30 @@ func (s *Stack) value(m *ice.Message, key string, arg ...Any) Any { } } }) - v, ok := f.value[key] - if ok { + if v, ok := f.value[key]; ok { return v - } else { - if s.stack(func(_f *Frame, i int) bool { - v, ok = _f.value[key] - return ok - }); ok { - return v - } } - v = s + var v Any = Dict{f.value} kit.For(keys, func(k string) { - m.Debug("what %#v %v", v, k) switch _v := v.(type) { case Operater: v = _v.Operate(SUBS, k) - case *Stack: - v = nil - _v.stack(func(_f *Frame, i int) bool { - v, ok = _f.value[k] - return ok - }) default: v = nil } }) if v != nil { return v + } else if v = _parse_const(m, key); v != "" { + return v } - return _parse_const(m, key) + return nil } func (s *Stack) runable() bool { return s.peekf().status > STATUS_DISABLE } func (s *Stack) token() string { return kit.Select("", s.rest, s.skip) } -func (s *Stack) show() string { - if s.Buffer == nil { - return "" - } else if s.skip == -1 { - return kit.Format("%s:%d", s.name, s.line+1) - } else { - return kit.Format("%s:%d:%d", s.name, s.line+1, s.skip) - } -} +func (s *Stack) show() string { return Format(s.Position) } func (s *Stack) read(m *ice.Message) (text string, ok bool) { - isvoid := func(text string) bool { - return strings.TrimSpace(text) == "" || strings.HasPrefix(strings.TrimSpace(text), "#") - } + isvoid := func(text string) bool { return strings.TrimSpace(text) == "" } for s.line++; s.line < len(s.list); s.line++ { if isvoid(s.list[s.line]) { continue @@ -169,9 +156,10 @@ func (s *Stack) read(m *ice.Message) (text string, ok bool) { } func (s *Stack) reads(m *ice.Message, cb func(k string) bool) { block, last := []string{}, 0 + comment := false for { if s.skip++; s.skip < len(s.rest) { - if k := s.rest[s.skip]; k == "`" { + if k, v := s.rest[s.skip], kit.Select("", s.rest, s.skip+1); k == "`" { if len(block) > 0 { kit.If(s.line != last, func() { block, last = append(block, ice.NL), s.line }) block = append(block, k) @@ -180,18 +168,27 @@ func (s *Stack) reads(m *ice.Message, cb func(k string) bool) { } else { block = append(block, k) } - continue } else if len(block) > 0 { kit.If(s.line != last, func() { block, last = append(block, ice.NL), s.line }) block = append(block, k) - continue - } - if s.rest[s.skip] == ice.PS && kit.Select("", s.rest, s.skip+1) == ice.PS { + } else if k == "*" && v == ice.PS { + comment = false + s.skip++ + } else if comment { + + } else if k == ice.PS && v == "*" { + comment = true + s.skip++ + } else if k == ice.PS && v == ice.PS { + s.comment = append(s.comment, s.list[s.line]) s.skip = len(s.rest) - continue - } - if cb(s.rest[s.skip]) { + } else if s.skip == 0 && strings.HasPrefix(k, "#") { + s.comment = append(s.comment, s.list[s.line]) + s.skip = len(s.rest) + } else if cb(s.rest[s.skip]) { break + } else { + s.comment = s.comment[:0] } } else if text, ok := s.read(m); ok { s.rest, s.skip = kit.Split(text, SPACE, BLOCK, QUOTE, TRANS, ice.TRUE), -1 @@ -235,9 +232,9 @@ func (s *Stack) run(m *ice.Message) { m.Cmdy(k, kit.Slice(s.rest, s.skip+1)) } else { if s.skip--; s.skip == -1 { - m.Cmd(EXPR, s.rest, ice.SP, s.show()) + m.Cmd(EXPR, s.rest) } else { - m.Cmd(EXPR, kit.Slice(s.rest, s.skip), ice.SP, s.show()) + m.Cmd(EXPR, kit.Slice(s.rest, s.skip)) } } return false @@ -259,7 +256,6 @@ func (s *Stack) cals0(m *ice.Message, arg ...string) string { func (s *Stack) types(m *ice.Message) Any { for ; s.skip < len(s.rest); s.skip++ { switch s.token() { - case "*": case MAP: s.skip += 2 key := s.types(m) @@ -276,8 +272,10 @@ func (s *Stack) types(m *ice.Message) Any { } types := s.types(m) kit.For(key, func(key string) { - field := Field{key, types} - t.field = append(t.field, field) + field := Field{types, map[string]string{}, key} + if strings.HasSuffix(s.list[s.line], "`") { + kit.For(kit.Split(kit.Select("", kit.Split(s.list[s.line]), -1), ": "), func(k, v string) { field.tags[k] = v }) + } t.index[key] = field }) key, s.skip = key[:0], len(s.rest) @@ -287,90 +285,70 @@ func (s *Stack) types(m *ice.Message) Any { t := Interface{index: map[string]Function{}} for s.next(m); s.next(m) != END; { name := s.token() - field, list := Field{}, [][]Field{} - for s.skip++; s.skip < len(s.rest); s.skip++ { - switch s.token() { - case OPEN: - list = append(list, []Field{}) - case "*": - case FIELD, CLOSE: - list[len(list)-1] = append(list[len(list)-1], field) - field = Field{} - default: - switch t := s.types(m).(type) { - case string: - kit.If(field.name == "", func() { field.name = t }, func() { field.kind = t }) - default: - field.kind = s.types(m) - } - } - } - kit.If(len(list) == 1, func() { list = append(list, []Field{}) }) - t.index[name] = Function{arg: list[0], res: list[1]} - s.skip = len(s.rest) + s.rest[s.skip] = FUNC + t.index[name] = s.types(m).(Function) } return t case FUNC: field, list := Field{}, [][]Field{} - for s.skip++; s.skip < len(s.rest); s.skip++ { + for s.skip++; s.skip < len(s.rest) && s.token() != BEGIN; s.skip++ { switch s.token() { case OPEN: list = append(list, []Field{}) - case "*": case FIELD, CLOSE: list[len(list)-1] = append(list[len(list)-1], field) field = Field{} + case "*": default: switch t := s.types(m).(type) { case string: - kit.If(field.name == "", func() { field.name = t }, func() { field.kind = t }) + kit.If(field.name == "", func() { field.name = t }, func() { field.types = t }) default: - field.kind = s.types(m) + field.types = s.types(m) } } } kit.If(len(list) == 1, func() { list = append(list, []Field{}) }) return Function{arg: list[0], res: list[1]} + case "*": default: - // if t := s.value(m, s.token()); t != nil && t != "" { - // return t - // } return s.token() } } - return "" + return nil } -func (s *Stack) funcs(m *ice.Message) string { - name := s.show() - s.rest[s.skip], s.skip = name, s.skip-1 - m.Cmd(FUNC, name) - f := s.peekf() - status := f.status - defer func() { f.status = status }() - f.status = STATUS_DISABLE - s.run(m) - return name -} -func (s *Stack) calls(m *ice.Message, obj Any, key Any, cb func(*Frame, Function), arg ...Any) Any { - m.Debug("stack %d call %T %s %#v", len(s.frame)-1, obj, key, arg) - if _k, ok := key.(string); ok && _k != "" { - kit.For(kit.Split(_k, ice.PT), func(k string) { - switch v := obj.(type) { - case Operater: - obj = v.Operate(SUBS, k) - case *Stack: - if _v := v.value(m, _k); _v != nil && _v != "" { - obj, key = _v, "" - } else { - obj, key = v.value(m, k), strings.TrimPrefix(_k, k+ice.PT) - } - } - }) +func (s *Stack) funcs(m *ice.Message, name string) Function { + v := s.types(m).(Function) + if f := s.pushf(m, FUNC, name); name == INIT { + f.key = CALL + } else { + f.status = STATUS_DISABLE } + v.Position = s.Position + s.run(m) + return v +} +func (s *Stack) calls(m *ice.Message, obj Any, key string, cb func(*Frame, Function), arg ...Any) Any { + m.Debug("calls %s %T %s(%s)", Format(s), obj, key, Format(arg...)) + switch v := obj.(type) { + case *Stack: + if _v := v.value(m, key); _v != nil { + obj, key = _v, "" + } + } + kit.For(kit.Split(key, ice.PT), func(k string) { + switch v := obj.(type) { + case Operater: + obj, key = v.Operate(SUBS, k), strings.TrimPrefix(strings.TrimPrefix(key, k), ice.PT) + case *Stack: + obj, key = v.value(m, k), strings.TrimPrefix(strings.TrimPrefix(key, k), ice.PT) + } + }) switch obj := obj.(type) { case Function: - m.Debug("stack %d call %T %s %#v", len(s.frame)-1, obj, kit.Select("", obj.obj, -1), arg) - f := s.pushf(m, CALL) + name := kit.Format("%s%s", kit.Select("", kit.Format("%s.", obj.obj[0].types), len(obj.obj) > 1), obj.obj[len(obj.obj)-1].name) + m.Debug("calls %s %s(%s) %s", Format(s), name, Format(arg...), Format(obj.Position)) + f := s.pushf(m, CALL, name, Format(obj.Position)) for _, field := range obj.res { f.value[field.name] = nil } @@ -397,15 +375,15 @@ func (s *Stack) calls(m *ice.Message, obj Any, key Any, cb func(*Frame, Function s.Position = pos }) kit.If(cb != nil, func() { cb(f, obj) }) - s.run(m.Options(ice.YAC_STACK, s)) + s.run(m) return value case Caller: - m.Debug("stack %d call %T %s %#v", len(s.frame)-1, obj, key, arg) kit.For(arg, func(i int, v Any) { arg[i] = Trans(arg[i]) }) + m.Debug("calls %s %s.%s(%s)", Format(s), Format(obj), key, Format(arg...)) return wrap(obj.Call(kit.Format(key), arg...)) case func(*ice.Message, string, ...Any) Any: - m.Debug("stack %d call %s %s %#v", len(s.frame)-1, kit.FileLine(obj, 3), key, arg) kit.For(arg, func(i int, v Any) { arg[i] = Trans(arg[i]) }) + m.Debug("calls %s %s %s %s", Format(s), Format(obj), key, Format(arg...)) return wrap(obj(m, kit.Format(key), arg...)) case func(): obj() @@ -414,18 +392,13 @@ func (s *Stack) calls(m *ice.Message, obj Any, key Any, cb func(*Frame, Function if key == "" { return nil } - m.Debug("stack %d call %T %s %#v", len(s.frame)-1, obj, key, arg) args := kit.List(key) kit.For(arg, func(i int, v Any) { args = append(args, Trans(v)) }) + m.Debug("calls %s %s", Format(s), Format(args...)) return Message{m.Cmd(args...)} } } -func (s *Stack) Handler(obj Any) ice.Handler { - return func(m *ice.Message, arg ...string) { - m.Copy(s.Action(m.Spawn(Index).Spawn(m.Target()), obj, nil, arg...)) - } -} -func (s *Stack) Action(m *ice.Message, obj Any, key Any, arg ...string) *ice.Message { +func (s *Stack) Action(m *ice.Message, obj Any, key string, arg ...string) *ice.Message { s.calls(m, obj, key, func(f *Frame, v Function) { i := 0 for _, field := range v.arg { @@ -443,18 +416,23 @@ func (s *Stack) Action(m *ice.Message, obj Any, key Any, arg ...string) *ice.Mes }) return m } +func (s *Stack) Handler(obj Any) ice.Handler { + return func(m *ice.Message, arg ...string) { + m.Copy(s.Action(m.Options(ice.YAC_STACK, s).Spawn(Index).Spawn(m.Target()), obj, "", arg...)) + } +} func (s *Stack) parse(m *ice.Message, name string, r io.Reader) *Stack { pos := s.Position defer func() { s.Position = pos }() s.Position = Position{Buffer: &Buffer{name: name, input: bufio.NewScanner(r)}} s.peekf().Position = s.Position - m.Debug("stack %d parse %s", len(s.frame)-1, s.show()) + m.Debug("stack %s parse %s", Format(s), s.show()) s.run(m) return s } -func NewStack(m *ice.Message, cb func(*Frame)) *Stack { +func NewStack(m *ice.Message, cb func(*Frame), arg ...string) *Stack { s := &Stack{} - s.pushf(m.Options(ice.YAC_STACK, s), STACK) + s.pushf(m.Options(ice.YAC_STACK, s), kit.Simple(STACK, arg)...) s.load(m, cb) return s } @@ -490,17 +468,17 @@ const STACK = "stack" func init() { Index.MergeCommands(ice.Commands{ - STACK: {Name: "stack path auto parse", Actions: ice.Actions{ + STACK: {Name: "stack path auto parse", Actions: ice.MergeActions(ice.Actions{ "start": {Hand: func(m *ice.Message, arg ...string) {}}, - ice.CMD: {Hand: func(m *ice.Message, arg ...string) {}}, - ice.RUN: {Hand: func(m *ice.Message, arg ...string) {}}, - }, Hand: func(m *ice.Message, arg ...string) { + }, ctx.CmdAction()), Hand: func(m *ice.Message, arg ...string) { if len(arg) == 0 || strings.HasSuffix(arg[0], ice.PS) { m.Options(nfs.DIR_ROOT, nfs.SRC).Cmdy(nfs.CAT, arg) return } nfs.Open(m, path.Join(nfs.SRC, strings.TrimPrefix(path.Join(arg...), nfs.SRC)), func(r io.Reader, p string) { - if NewStack(m, nil).parse(m, p, r); m.Option(ice.DEBUG) == ice.TRUE { + s := NewStack(m, nil, "", p).parse(m, p, r) + if m.StatusTime(mdb.LINK, s.value(m, "_link")); m.Option(ice.DEBUG) == ice.TRUE { + m.Option("__index", kit.Format(s.value(m, "_index"))) m.Cmdy(INFO, arg) } }) @@ -549,11 +527,10 @@ func StackHandler(m *ice.Message, arg ...string) { kit.If(!kit.IsIn(field.name, "m", "msg", ice.ARG), func() { list = append(list, kit.Dict(mdb.NAME, field.name, mdb.TYPE, mdb.TEXT, mdb.VALUE, "")) }) } kit.If(k == mdb.LIST, func() { list = append(list, kit.Dict(mdb.NAME, mdb.LIST, mdb.TYPE, "button", mdb.ACTION, ice.AUTO)) }) - h := func(m *ice.Message, arg ...string) { m.Copy(s.Action(m.Spawn(Index).Spawn(m.Target()), s, k, arg...)) } if k == mdb.LIST { - cmd.Hand, cmd.List = h, list + cmd.Hand, cmd.List = s.Handler(v), list } else { - cmd.Actions[k], cmd.Meta[k] = &ice.Action{Hand: h}, list + cmd.Actions[k], cmd.Meta[k] = &ice.Action{Hand: s.Handler(v)}, list } } }) diff --git a/base/yac/stmt.go b/base/yac/stmt.go index b20a5227..9c170624 100644 --- a/base/yac/stmt.go +++ b/base/yac/stmt.go @@ -21,6 +21,7 @@ const ( DEFAULT = "default" FUNC = "func" INIT = "init" + MAIN = "main" CALL = "call" DEFER = "defer" RETURN = "return" @@ -48,26 +49,23 @@ func init() { } else { f.status, f.defers = STATUS_DISABLE, append(f.defers, func() { f.status = STATUS_NORMAL }) } - s.reads(m, func(k string) bool { - if k == IF { - res := s.expr(m) - kit.If(s.token() == SPLIT, func() { res = s.expr(m) }) - kit.If(res == ice.FALSE, func() { f.status = STATUS_DISABLE }) - } - return true - }) + if s.next(m) == IF { + res := s.expr(m) + kit.If(s.token() == SPLIT, func() { res = s.expr(m) }) + kit.If(res == ice.FALSE, func() { f.status = STATUS_DISABLE }) + } }}, FOR: {Name: "for a = 1; a < 10; a++ {", Hand: func(m *ice.Message, arg ...string) { s, f := _parse_frame(m) if strings.Contains(s.list[s.line], RANGE) { pos, key, list := s.Position, []string{}, []Any{} kit.If(s.last != nil && s.last.line == s.line, func() { list, _ = s.last.value["_range"].([]Any) }) - for { // for k, v := range value { + for { if k := s.cals0(m, FIELD, DEFS, ASSIGN); k == RANGE { if obj, ok := s.cals(m).(Operater); ok { - if _list, ok := obj.Operate(RANGE, list).([]Any); ok { - kit.For(key, func(i int, k string) { f.value[k] = _list[i] }) - f.value["_range"] = _list + if list, ok := obj.Operate(RANGE, list).([]Any); ok { + kit.For(key, func(i int, k string) { f.value[k] = list[i] }) + f.value["_range"] = list break } } @@ -102,8 +100,7 @@ func init() { s.Position, f.defers = list[len(list)-1], append(f.defers, func() { if s.runable() { kit.If(len(list) > 3, func() { s.expr(m, list[2]) }) - s.Position = list[0] - s.Position.skip-- + s.pos(m, list[0], -1) } }) }}, @@ -148,9 +145,12 @@ func init() { f.status = STATUS_NORMAL v := s.cals(m) f.status = STATUS_DISABLE + if f.value["_case"] == "done" { + return + } if res, ok := v.(Operater); ok { if res, ok := res.Operate("==", Trans(s.value(m, "_switch"))).(Boolean); ok && res.value { - f.status, f.value["_case"] = 0, "done" + f.status, f.value["_case"] = STATUS_NORMAL, "done" } } }}, @@ -164,53 +164,32 @@ func init() { }}, FUNC: {Name: "func show(a, b) (c, d)", Hand: func(m *ice.Message, arg ...string) { s := _parse_stack(m) - list, key, kind := [][]Field{[]Field{}}, "", "" - push := func() { - kit.If(key, func() { list[len(list)-1], key, kind = append(list[len(list)-1], Field{name: key, kind: kind}), "", "" }) + field, list := Field{}, []Field{} + if s.next(m) == OPEN { + for s.next(m) != CLOSE { + kit.If(field.name == "", func() { field.name = s.token() }, func() { field.types = s.token() }) + } + s.next(m) + list = append(list, field) } - s.reads(m, func(k string) bool { - switch k { - case OPEN: - defer kit.If(key != "" || len(list) > 1, func() { list = append(list, []Field{}) }) - case FIELD, CLOSE: - case BEGIN: - return true - default: - kit.If(key, func() { kind = k }, func() { key = k }) - return false + name := s.token() + list = append(list, Field{name: name}) + s.rest[s.skip] = FUNC + v := s.funcs(m, name) + if v.obj = list; field.types != nil { + if t, ok := s.value(m, kit.Format(field.types)).(Struct); ok { + m.Debug("value %s set %s.%s %s", Format(s), field.types, name, Format(v)) + t.index[name] = v } - push() - return false - }) - m.Debug("what %#v", list) - kit.If(len(list) < 2, func() { list = append(list, []Field{}) }) - kit.If(len(list) < 3, func() { list = append(list, []Field{}) }) - name, fun := list[0][len(list[0])-1].name, Function{obj: list[0], arg: list[1], res: list[2], Position: s.Position} - if len(list[0]) > 1 { - if st, ok := list[0][0].kind.(Struct); ok { - st.method = append(st.method, fun) - st.index[name] = fun - } - if st, ok := list[0][0].kind.(string); ok { - if st, ok := s.value(m, st).(Struct); ok { - st.method = append(st.method, fun) - st.index[name] = fun - } - } - - } else { - kit.If(name != INIT, func() { s.value(m, name, fun) }) - } - if f := s.pushf(m, ""); name == INIT { - f.key = CALL - } else { - f.status = STATUS_DISABLE + } else if name != INIT { + s.value(m, name, v) } }}, DEFER: {Name: "defer func() {} ()", Hand: func(m *ice.Message, arg ...string) { s := _parse_stack(m) - k := s.next(m) - kit.If(k == FUNC, func() { k = s.funcs(m) }) + obj, k := Any(nil), "" + obj, k = s, s.next(m) + kit.If(k == FUNC, func() { obj, k = s.funcs(m, ""), "" }) s.skip++ args := _parse_res(m, s.cals(m)) if !s.runable() { @@ -218,7 +197,7 @@ func init() { } s.stack(func(f *Frame, i int) bool { if f.key == CALL { - f.defers = append(f.defers, func() { s.calls(m, s, k, nil, args...) }) + f.defers = append(f.defers, func() { s.calls(m, obj, k, nil, args...) }) return true } return false @@ -258,16 +237,44 @@ func init() { m.EchoLine("").EchoLine("stack: %s", arg[0]) _parse_stack(m).stack(func(f *Frame, i int) bool { m.EchoLine("frame: %s %v:%v:%v", f.key, f.name, f.line, f.skip) - kit.For(f.value, func(k string, v Any) { m.EchoLine(" %s: %#v", k, v) }) + show := func(p string) string { + ls := nfs.SplitPath(m, p) + return ice.Render(m, ice.RENDER_ANCHOR, p, m.MergePodCmd("", "web.code.vimer", nfs.PATH, ls[0], nfs.FILE, ls[1], nfs.LINE, ls[2])) + } + kit.For(f.value, func(k string, v Any) { + switch v := v.(type) { + case func(*ice.Message, string, ...Any) Any: + m.EchoLine(" %s: %v", k, show(kit.FileLine(v, 100))) + case Message: + m.EchoLine(" %s: %v", k, show(kit.FileLine(v.Call, 100))) + case Function: + m.EchoLine(" %s: %v", k, show(v.Position.name+":"+kit.Format(v.Position.line+1))) + case Struct: + m.EchoLine(" %s: struct", k) + kit.For(v.index, func(k string, v Any) { + switch v := v.(type) { + case Function: + m.EchoLine(" %s: %v", k, show(v.Position.name+":"+kit.Format(v.Position.line+1))) + case Field: + m.EchoLine(" %s: %v", k, v.Format()) + } + }) + case string: + m.EchoLine(" %s: %v", k, v) + default: + m.EchoLine(" %s: %v", k, Format(v)) + } + }) return false }) m.EchoLine("stmt: %s", arg[0]) - for key, cmd := range m.Target().Commands { - if strings.HasPrefix(key, "_") || strings.HasPrefix(key, "/") { - continue + kit.For(kit.SortedKey(m.Target().Commands), func(key string) { + if strings.HasPrefix(key, "_") || strings.HasPrefix(key, ice.PS) { + return } + cmd := m.Target().Commands[key] m.EchoLine(" %s: %#v", key, cmd.Name) - } + }) }}, PWD: {Name: "pwd", Hand: func(m *ice.Message, arg ...string) { s := _parse_stack(m) diff --git a/base/yac/type.go b/base/yac/type.go index 1cfba13f..d29b4ee4 100644 --- a/base/yac/type.go +++ b/base/yac/type.go @@ -1,42 +1,45 @@ package yac import ( + "strings" + ice "shylinux.com/x/icebergs" kit "shylinux.com/x/toolkits" ) -const ( - CONST = "const" - TYPE = "type" - VAR = "var" - - STRING = "string" - INT = "int" - MAP = "map" - SLICE = "slice" - STRUCT = "struct" - INTERFACE = "interface" -) - type Map struct { - key Any value Any + key Any } type Slice struct { value Any } type Interface struct { index map[string]Function + name string } type Struct struct { - index map[string]Any - method []Function - field []Field + index map[string]Any + name string } type Field struct { - name string - kind Any + types Any + tags map[string]string + name string } + +func (s Field) MarshalJSON() ([]byte, error) { + return []byte(kit.Format("%q", s.Format())), nil +} +func (s Field) Format() string { + if len(s.tags) == 0 { + return kit.Format("%s", s.types) + } + res := []string{} + kit.For(s.tags, func(k, v string) { res = append(res, kit.Format("%s:\"%s\"", k, v)) }) + return kit.Format("%s `%s`", s.types, strings.Join(res, ice.SP)) +} + type Object struct { value Operater index Struct @@ -46,6 +49,33 @@ func (s Object) Operate(op string, v Any) Any { switch op { case "&", "*": return s + case INSTANCEOF: + if t, ok := v.(Struct); ok { + return Value{list: []Any{s, s.index.name == t.name}} + } + return Value{list: []Any{s, false}} + case IMPLEMENTS: + if t, ok := v.(Interface); ok { + for k, v := range t.index { + if _v, ok := s.index.index[k].(Function); ok { + for i, field := range v.arg { + if i < len(_v.arg) && _v.arg[i].types == field.types { + continue + } + return Value{list: []Any{s, false}} + } + for i, field := range v.res { + if i < len(_v.res) && _v.res[i].types == field.types { + continue + } + return Value{list: []Any{s, false}} + } + } else { + return Value{list: []Any{s, false}} + } + } + } + return Value{list: []Any{s, true}} case SUBS: switch v := s.index.index[kit.Format(v)].(type) { case Function: @@ -59,6 +89,22 @@ func (s Object) Operate(op string, v Any) Any { return nil } +const ( + MAP = "map" + SLICE = "slice" + STRUCT = "struct" + INTERFACE = "interface" + STRING = "string" + INT = "int" + + INSTANCEOF = "instanceof" + IMPLEMENTS = "implements" + + CONST = "const" + TYPE = "type" + VAR = "var" +) + func init() { Index.MergeCommands(ice.Commands{ CONST: {Name: "const a = 1", Hand: func(m *ice.Message, arg ...string) { @@ -80,7 +126,16 @@ func init() { s.next(m) fallthrough default: - s.value(m, name, s.types(m)) + switch t := s.types(m).(type) { + case Interface: + t.name = name + s.value(m, name, t) + case Struct: + t.name = name + s.value(m, name, t) + default: + s.value(m, name, t) + } } }}, VAR: {Name: "var a = 1", Hand: func(m *ice.Message, arg ...string) { diff --git a/base/yac/value.go b/base/yac/value.go index 36082d67..fbc07cde 100644 --- a/base/yac/value.go +++ b/base/yac/value.go @@ -7,33 +7,35 @@ import ( "time" ice "shylinux.com/x/icebergs" + "shylinux.com/x/icebergs/base/mdb" "shylinux.com/x/icebergs/base/web" kit "shylinux.com/x/toolkits" ) type Any = ice.Any -type Dict struct{ value map[string]Any } type List struct{ value []Any } -type Value struct{ list []Any } +type Dict struct{ value map[string]Any } type String struct{ value string } type Number struct{ value string } type Boolean struct{ value bool } type Caller interface{ Call(string, ...Any) Any } type Operater interface{ Operate(string, Any) Any } -func (s Dict) MarshalJSON() ([]byte, error) { return json.Marshal(s.value) } func (s List) MarshalJSON() ([]byte, error) { return json.Marshal(s.value) } +func (s Dict) MarshalJSON() ([]byte, error) { return json.Marshal(s.value) } func (s String) MarshalJSON() ([]byte, error) { return json.Marshal(s.value) } func (s Number) MarshalJSON() ([]byte, error) { return json.Marshal(s.value) } func (s Boolean) MarshalJSON() ([]byte, error) { return json.Marshal(s.value) } +func (s Function) MarshalJSON() ([]byte, error) { + return []byte(kit.Format("%q", Format(s.Position))), nil +} -func (s String) String() string { return s.value } func wrap(v Any) Any { switch v := v.(type) { - case map[string]Any: - return Dict{v} case []Any: return List{v} + case map[string]Any: + return Dict{v} case string: return String{v} case int: @@ -46,16 +48,16 @@ func wrap(v Any) Any { } func Trans(v Any) Any { switch v := v.(type) { - case Dict: - return v.value - case List: - return v.value case Value: if len(v.list) > 0 { return Trans(v.list[0]) } else { return nil } + case List: + return v.value + case Dict: + return v.value case String: return v.value case Number: @@ -66,30 +68,6 @@ func Trans(v Any) Any { return v } } -func (s Dict) Operate(op string, v Any) Any { - switch op { - case RANGE: - switch list := v.(type) { - case []Any: - if key := kit.SortedKey(s.value); list != nil && len(list) > 2 { - if i := kit.Int(list[2]) + 1; i < len(key) { - return []Any{key[i], s.value[key[i]], i} - } - } else { - if len(key) > 0 { - return []Any{key[0], s.value[key[0]], 0} - } - } - } - return nil - case SUBS: - return wrap(kit.Value(s.value, kit.Format(v))) - default: - s.value[op] = v - return v - } - return nil -} func (s List) Operate(op string, v Any) Any { switch op { case RANGE: @@ -123,6 +101,30 @@ func (s List) Operate(op string, v Any) Any { } return nil } +func (s Dict) Operate(op string, v Any) Any { + switch op { + case RANGE: + switch list := v.(type) { + case []Any: + if key := kit.SortedKey(s.value); list != nil && len(list) > 2 { + if i := kit.Int(list[2]) + 1; i < len(key) { + return []Any{key[i], s.value[key[i]], i} + } + } else { + if len(key) > 0 { + return []Any{key[0], s.value[key[0]], 0} + } + } + } + return nil + case SUBS: + return wrap(kit.Value(s.value, kit.Format(v))) + default: + s.value[op] = v + return v + } + return nil +} func (s String) Operate(op string, v Any) Any { switch a, b := s.value, kit.Format(v); op { case "+": @@ -191,16 +193,16 @@ func (s *Stack) load(m *ice.Message, cb func(*Frame)) *Stack { f := s.peekf() f.value["kit"] = func(m *ice.Message, key string, arg ...Any) Any { switch key { - case "Dict": - return kit.Dict(arg...) case "List": return kit.List(arg...) + case "Dict": + return kit.Dict(arg...) case "Format": return kit.Format(arg[0], arg[1:]...) case "Formats": return kit.Formats(arg[0]) default: - m.ErrorNotImplement(key) + m.ErrorNotImplement(kit.Keys("kit", key)) return nil } } @@ -209,17 +211,26 @@ func (s *Stack) load(m *ice.Message, cb func(*Frame)) *Stack { command := &ice.Command{Name: "list hash auto", Help: "示例", Actions: ice.Actions{}} obj := arg[1].(Object) for k, v := range obj.index.index { - switch v.(type) { + switch v := v.(type) { case Function: + v.object = obj if k == "List" { command.Hand = stack.Handler(v) } else { - command.Actions[k] = &ice.Action{Hand: stack.Handler(v)} + command.Actions[kit.LowerCapital(k)] = &ice.Action{Hand: stack.Handler(v)} + } + } + } + for k, v := range obj.index.index { + switch v := v.(type) { + case Field: + if k == "list" { + command.Name = v.tags[mdb.NAME] + } else { + command.Actions[k].Name = v.tags[mdb.NAME] } - case Field: } } - command.List = ice.SplitCmd(command.Name, command.Actions) last, list := ice.Index, kit.Split(kit.Format(arg[0]), ice.PT) for i := 1; i < len(list); i++ { has := false @@ -232,7 +243,9 @@ func (s *Stack) load(m *ice.Message, cb func(*Frame)) *Stack { last.Merge(last) }) } - m.Debug("what %#v", command) + link := ice.Render(m, ice.RENDER_ANCHOR, kit.Format(arg[0]), m.MergePodCmd("", kit.Format(arg[0]))) + s.frame[0].value["_index"] = kit.Format(arg[0]) + s.frame[0].value["_link"] = link return nil } f.value["ice.MergeActions"] = func(m *ice.Message, key string, arg ...Any) Any { @@ -247,9 +260,7 @@ func (s *Stack) load(m *ice.Message, cb func(*Frame)) *Stack { return res } for k, v := range ice.Info.Stack { - if strings.HasPrefix(k, "web.code.") { - k = strings.TrimPrefix(k, "web.") - } + kit.If(strings.HasPrefix(k, "web.code."), func() { k = strings.TrimPrefix(k, "web.") }) f.value[k] = v } f.value["m"] = Message{m} @@ -272,6 +283,11 @@ func (m Message) Call(cmd string, arg ...Any) Any { m.Push(str(arg[0]), arg[1], arg[2:]...) case "Echo": m.Echo(str(arg[0]), arg[1:]...) + case "Table": + s := _parse_stack(m.Message) + m.Table(func(val ice.Maps) { s.calls(m.Message, arg[0], "", nil, Dict{kit.Dict(val)}) }) + case "Sleep": + m.Sleep(str(arg[0])) case "Action": m.Action(arg...) case "Display": @@ -293,11 +309,6 @@ func (m Message) Call(cmd string, arg ...Any) Any { return false }) m.Debug(ice.NL + strings.Join(list, ice.NL)) - case "Sleep": - m.Sleep(str(arg[0])) - case "Table": - s := _parse_stack(m.Message) - m.Table(func(val ice.Maps) { s.calls(m.Message, arg[0], nil, nil, Dict{kit.Dict(val)}) }) default: m.ErrorNotImplement(cmd) } @@ -335,10 +346,11 @@ func TransCommands(m *ice.Message, arg ...Any) ice.Commands { case "Actions": s.Actions = TransActions(m, v) case "Hand": - s.Hand = func(m *ice.Message, arg ...string) { - msg := m.Spawn(Index).Spawn(m.Target()) - stack.Action(msg, v, nil, arg...) - m.Copy(msg) + switch v := v.(type) { + case Function: + s.Hand = stack.Handler(v) + case ice.Handler: + s.Hand = v } } }) @@ -361,13 +373,67 @@ func TransActions(m *ice.Message, arg ...Any) ice.Actions { case "Help": s.Help = kit.Format(Trans(v)) case "Hand": - s.Hand = func(m *ice.Message, arg ...string) { - msg := m.Spawn(Index).Spawn(m.Target()) - stack.Action(msg, v, nil, arg...) - m.Copy(msg) + switch v := v.(type) { + case Function: + s.Hand = stack.Handler(v) + case ice.Handler: + s.Hand = v } } actions[k] = s }) return actions } + +func Format(arg ...Any) string { + res := []string{} + for _, v := range arg { + switch v := v.(type) { + case func(*ice.Message, string, ...Any) Any: + res = append(res, kit.FileLine(v, 100)) + case Message: + res = append(res, kit.FileLine(v.Call, 100)) + case Function: + res = append(res, kit.Format("%s %s%s%s", Format(v.obj[:len(v.obj)-1]), v.obj[len(v.obj)-1].name, Format(v.arg), Format(v.res)), Format(v.Position)) + case *Stack: + res = append(res, kit.Format("%d:%s", len(v.frame)-1, kit.Select(v.peekf().key, v.peekf().name))) + case Position: + if v.Buffer == nil { + continue + } else if v.skip == -1 { + res = append(res, kit.Format("%s:%d", v.name, v.line+1)) + } else { + res = append(res, kit.Format("%s:%d:%d", v.name, v.line+1, v.skip)) + } + case Map: + res = append(res, kit.Format("map[%s]%s", v.key, v.value)) + case Slice: + res = append(res, kit.Format("[]%s", v.value)) + case Interface: + res = append(res, kit.Format("interface%s", v.name)) + case Struct: + res = append(res, kit.Format("struct%s", Format(v.index))) + case Object: + res = append(res, kit.Format("%s:%s", v.index.name, Format(v.value))) + case []Field: + for i, field := range v { + res = append(res, kit.Select("", OPEN, i == 0)+field.name, kit.Format(field.types)+kit.Select(FIELD, CLOSE, i == len(v)-1)) + } + case List: + res = append(res, kit.Format(v.value)) + case Dict: + res = append(res, kit.Format(v.value)) + case String: + res = append(res, kit.Format("%q", v.value)) + case Number: + res = append(res, kit.Format("%s", v.value)) + case Boolean: + res = append(res, kit.Format("%t", v.value)) + case string: + res = append(res, kit.Format("%q", v)) + default: + res = append(res, kit.Format(v)) + } + } + return strings.Join(res, " ") +} diff --git a/core/code/shy.go b/core/code/shy.go index f8e78719..c224ca7f 100644 --- a/core/code/shy.go +++ b/core/code/shy.go @@ -30,7 +30,11 @@ func init() { ctx.ProcessCommand(m, yac.STACK, kit.Simple(arg[1])) }}, mdb.ENGINE: {Hand: func(m *ice.Message, arg ...string) { - ctx.ProcessCommand(m, yac.STACK, kit.Simple(arg[1])) + if msg := m.Cmd(yac.STACK, arg[1]); msg.Option("__index") != "" { + ctx.ProcessCommand(m, msg.Option("__index"), kit.Simple()) + } else { + ctx.ProcessCommand(m, yac.STACK, kit.Simple(arg[1])) + } }}, TEMPLATE: {Hand: func(m *ice.Message, arg ...string) { m.Echo(nfs.Template(m, "demo.shy"), path.Base(path.Dir(path.Join(arg[2], arg[1])))) diff --git a/render.go b/render.go index e447684a..a38e464c 100644 --- a/render.go +++ b/render.go @@ -179,6 +179,16 @@ func (m *Message) PushDownload(key string, arg ...string) *Message { return m } +func (m *Message) EchoFields(cmd string) *Message { + return m.Echo(`
+`, cmd) +} func (m *Message) EchoButton(arg ...Any) *Message { return m.Echo(Render(m, RENDER_BUTTON, arg...)) } func (m *Message) EchoAnchor(arg ...string) *Message { return m.Echo(Render(m, RENDER_ANCHOR, arg)) } func (m *Message) EchoQRCode(src string) *Message { return m.Echo(Render(m, RENDER_QRCODE, src)) }