From 1545b142fdf4542c68f317dc58c0ca3bff587bc7 Mon Sep 17 00:00:00 2001 From: shylinux Date: Fri, 7 Apr 2023 00:25:24 +0800 Subject: [PATCH] opt type --- base/gdb/gdb.go | 2 +- base/web/web.go | 10 +++- base/web/web.shy | 2 + base/yac/expr.go | 46 ++++++++++----- base/yac/stack.go | 37 +++++++----- base/yac/stmt.go | 17 ++++-- base/yac/value.go | 134 ++++++++++++++++++++++++++++++++++++------- conf.go | 1 + core/code/code.go | 10 ++-- core/code/install.go | 3 + type.go | 1 + 11 files changed, 204 insertions(+), 59 deletions(-) create mode 100644 base/web/web.shy diff --git a/base/gdb/gdb.go b/base/gdb/gdb.go index da7d7ddd..a65aee1f 100644 --- a/base/gdb/gdb.go +++ b/base/gdb/gdb.go @@ -28,7 +28,7 @@ func (f *Frame) Start(m *ice.Message, arg ...string) { for { select { case <-time.Tick(t): - m.Option(ice.LOG_DISABLE, ice.TRUE) + // m.Option(ice.LOG_DISABLE, ice.TRUE) m.Cmd(TIMER, HAPPEN) case s, ok := <-f.s: if !ok { diff --git a/base/web/web.go b/base/web/web.go index 2f71c827..db377455 100644 --- a/base/web/web.go +++ b/base/web/web.go @@ -74,7 +74,15 @@ var Index = &ice.Context{Name: WEB, Help: "网络模块"} func init() { ice.Index.Register(Index, &Frame{}, BROAD, SERVE, SPACE, DREAM, CACHE, SPIDE, SHARE) } func ApiAction(arg ...string) ice.Actions { return ice.Actions{kit.Select(ice.PS, arg, 0): {}} } -func Prefix(arg ...string) string { return kit.Keys(WEB, arg) } +func Prefix(arg ...string) string { + for i, k := range arg { + switch k { + case "Register": + arg[i] = "Index.Register" + } + } + return kit.Keys(WEB, arg) +} func P(arg ...string) string { return path.Join(ice.PS, path.Join(arg...)) } func PP(arg ...string) string { return P(arg...) + ice.PS } diff --git a/base/web/web.shy b/base/web/web.shy new file mode 100644 index 00000000..8afaae74 --- /dev/null +++ b/base/web/web.shy @@ -0,0 +1,2 @@ +type Frame struct{} + diff --git a/base/yac/expr.go b/base/yac/expr.go index 5348523f..2d8bfa4a 100644 --- a/base/yac/expr.go +++ b/base/yac/expr.go @@ -95,7 +95,7 @@ func (s *Expr) opv(m *ice.Message, p int, op string, v Any) Any { return s.getv(m, p) } if obj, ok := s.getv(m, p).(Operater); ok { - return obj.Operate(op, trans(v)) + return obj.Operate(op, Trans(v)) } return s.getv(m, p) } @@ -166,10 +166,13 @@ func (s *Expr) ktv(m *ice.Message, ismap bool, t Any, p string) map[string]Any { k := "" kit.If(ismap, func() { sub := s.sub(m) - if k = kit.Format(trans(sub.cals(m, DEFS, END))); k == "" { + if k = kit.Format(Trans(sub.cals(m, DEFS, END))); k == "" { k = _parse_const(m, sub.gets(0)) } - }, func() { k, _ = s.next(m), s.next(m) }) + }, 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 { @@ -182,8 +185,9 @@ func (s *Expr) ktv(m *ice.Message, ismap bool, t Any, p string) map[string]Any { } } } - m.Debug("field %d %#v %#v", sub.n, k, data[k]) + m.Debug("field %d %#v %#v", sub.n, k, sub.t) data[k] = sub.cals(m, FIELD, END) + m.Debug("field %d %#v %#v", sub.n, k, data[k]) }) } return data @@ -218,6 +222,7 @@ 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 @@ -289,30 +294,41 @@ func (s *Expr) cals(m *ice.Message, arg ...string) Any { s.push(name) return false case FUNC: - s.push(s.value(m, s.funcs(m))) - return false + if s.isop(-1) || len(s.list) == 0 { + s.push(s.value(m, s.funcs(m))) + return false + } + s.skip-- + return true + case CLOSE: + if s.gets(-2) == OPEN { + s.pops(2, s.get(-1)) + return false + } + return true } if len(s.list) > 0 && !s.isop(-1) { switch k { case SUBS: switch v := s.sub(m).cals(m, SUPS); s.get(-1).(type) { case string: - s.pops(1, kit.Keys(s.gets(-1), kit.Format(trans(v)))) + 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 CLOSE: - kit.If(s.gets(-2) == OPEN, func() { s.pops(2, s.get(-1)) }) - return false case "++", "--": s.pops(1, s.setv(m, -1, ASSIGN, s.opv(m, -1, k, nil))) return false @@ -344,6 +360,7 @@ 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 } @@ -371,12 +388,12 @@ func (s *Expr) cmds(m *ice.Message, line int) (done bool) { 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))) + 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(v))) } } m.Cmdy(args...) @@ -385,7 +402,8 @@ func (s *Expr) cmds(m *ice.Message, line int) (done bool) { return } func (s *Expr) call(m *ice.Message, obj Any, key string) Any { - if arg := _parse_res(m, s.sub(m).cals(m, CLOSE)); s.runable() { + v := s.sub(m).cals(m, CLOSE) + if arg := _parse_res(m, v); s.runable() { return s.calls(m, obj, key, nil, arg...) } else { return nil @@ -403,7 +421,7 @@ func init() { return } else if v != nil { m.Debug("value %#v <- %v", v, arg) - switch v := trans(v).(type) { + switch v := Trans(v).(type) { case Message: case Value: kit.If(len(v.list) > 0, func() { m.Echo(kit.Format(v.list[0])) }) diff --git a/base/yac/stack.go b/base/yac/stack.go index 15445920..ae8e9d1a 100644 --- a/base/yac/stack.go +++ b/base/yac/stack.go @@ -117,6 +117,7 @@ func (s *Stack) value(m *ice.Message, key string, arg ...Any) Any { } v = s kit.For(keys, func(k string) { + m.Debug("what %#v %v", v, k) switch _v := v.(type) { case Operater: v = _v.Operate(SUBS, k) @@ -351,13 +352,14 @@ func (s *Stack) funcs(m *ice.Message) string { 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 { + 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) @@ -395,26 +397,35 @@ 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(STACK, s)) + s.run(m.Options(ice.YAC_STACK, s)) 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]) }) + kit.For(arg, func(i int, v Any) { arg[i] = Trans(arg[i]) }) return wrap(obj.Call(kit.Format(key), arg...)) case func(*ice.Message, string, ...Any) Any: - 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("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]) }) return wrap(obj(m, kit.Format(key), arg...)) case func(): obj() return nil default: + 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)) }) + kit.For(arg, func(i int, v Any) { args = append(args, Trans(v)) }) return Message{m.Cmd(args...)} } } -func (s *Stack) action(m *ice.Message, obj Any, key Any, arg ...string) *ice.Message { +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 { s.calls(m, obj, key, func(f *Frame, v Function) { i := 0 for _, field := range v.arg { @@ -443,20 +454,20 @@ func (s *Stack) parse(m *ice.Message, name string, r io.Reader) *Stack { } func NewStack(m *ice.Message, cb func(*Frame)) *Stack { s := &Stack{} - s.pushf(m.Options(STACK, s), STACK) + s.pushf(m.Options(ice.YAC_STACK, s), STACK) s.load(m, cb) return s } -func _parse_stack(m *ice.Message) *Stack { return m.Optionv(STACK).(*Stack) } +func _parse_stack(m *ice.Message) *Stack { return m.Optionv(ice.YAC_STACK).(*Stack) } func _parse_frame(m *ice.Message) (*Stack, *Frame) { return _parse_stack(m), _parse_stack(m).pushf(m, "") } func _parse_const(m *ice.Message, key string) string { if k := kit.Select(key, strings.Split(key, ice.PT), -1); kit.IsUpper(k) { - if c, ok := ice.Info.Index[strings.ToLower(k)].(*ice.Context); ok && (key == k || key == c.Prefix(k)) { - return strings.ToLower(k) - } + // if c, ok := ice.Info.Index[strings.ToLower(k)].(*ice.Context); ok && (key == k || key == c.Prefix(k)) { + return strings.ToLower(k) + // } } return "" } @@ -538,7 +549,7 @@ 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...)) } + 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 } else { diff --git a/base/yac/stmt.go b/base/yac/stmt.go index fa17a0b0..b20a5227 100644 --- a/base/yac/stmt.go +++ b/base/yac/stmt.go @@ -149,7 +149,7 @@ func init() { v := s.cals(m) f.status = STATUS_DISABLE if res, ok := v.(Operater); ok { - if res, ok := res.Operate("==", trans(s.value(m, "_switch"))).(Boolean); ok && res.value { + if res, ok := res.Operate("==", Trans(s.value(m, "_switch"))).(Boolean); ok && res.value { f.status, f.value["_case"] = 0, "done" } } @@ -182,13 +182,22 @@ func init() { 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 { - st := list[0][0].kind.(Struct) - st.method = append(st.method, fun) - st.index[name] = fun + 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) }) } diff --git a/base/yac/value.go b/base/yac/value.go index 40b20f64..36082d67 100644 --- a/base/yac/value.go +++ b/base/yac/value.go @@ -7,6 +7,7 @@ import ( "time" ice "shylinux.com/x/icebergs" + "shylinux.com/x/icebergs/base/web" kit "shylinux.com/x/toolkits" ) @@ -26,6 +27,7 @@ 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 String) String() string { return s.value } func wrap(v Any) Any { switch v := v.(type) { case map[string]Any: @@ -42,7 +44,7 @@ func wrap(v Any) Any { return v } } -func trans(v Any) Any { +func Trans(v Any) Any { switch v := v.(type) { case Dict: return v.value @@ -50,7 +52,7 @@ func trans(v Any) Any { return v.value case Value: if len(v.list) > 0 { - return trans(v.list[0]) + return Trans(v.list[0]) } else { return nil } @@ -202,30 +204,52 @@ func (s *Stack) load(m *ice.Message, cb func(*Frame)) *Stack { return nil } } + f.value["ice.Cmd"] = func(m *ice.Message, key string, arg ...Any) Any { + stack := m.Optionv(ice.YAC_STACK).(*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) { + case Function: + if k == "List" { + command.Hand = stack.Handler(v) + } else { + command.Actions[k] = &ice.Action{Hand: stack.Handler(v)} + } + 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 + if ice.Pulse.Search(strings.Join(list[:i], ice.PT)+ice.PT, func(p *ice.Context, s *ice.Context) { has, last = true, s }); !has { + context := &ice.Context{Name: list[i-1], Caches: ice.Caches{ice.CTX_FOLLOW: &ice.Cache{Value: strings.Join(list[:i], ice.PT)}}} + last = last.Register(context, &web.Frame{}) + } + kit.If(i == len(list)-1, func() { + last.Merge(&ice.Context{Commands: ice.Commands{list[i]: command}}) + last.Merge(last) + }) + } + m.Debug("what %#v", command) + return nil + } f.value["ice.MergeActions"] = func(m *ice.Message, key string, arg ...Any) Any { - s := _parse_stack(m) _actions := ice.Actions{} for _, v := range arg { - actions := ice.Actions{} - kit.For(v, func(k string, v Any) { - action := &ice.Action{} - kit.For(v, func(k string, v Any) { - switch k { - case "Name": - action.Name = kit.Format(trans(v)) - case "Help": - action.Help = kit.Format(trans(v)) - case "Hand": - action.Hand = func(m *ice.Message, arg ...string) { s.action(m, v, nil, arg...) } - } - }) - actions[k] = action - }) - ice.MergeActions(_actions, actions) + ice.MergeActions(_actions, TransActions(m, v)) } - return _actions + res := Dict{value: kit.Dict()} + for k, v := range _actions { + res.value[k] = Object{value: Dict{kit.Dict("Name", v.Name, "Help", v.Help, "Hand", v.Hand)}} + } + return res } for k, v := range ice.Info.Stack { + if strings.HasPrefix(k, "web.code.") { + k = strings.TrimPrefix(k, "web.") + } f.value[k] = v } f.value["m"] = Message{m} @@ -234,7 +258,7 @@ func (s *Stack) load(m *ice.Message, cb func(*Frame)) *Stack { } func (m Message) Call(cmd string, arg ...Any) Any { - str := func(v Any) string { return kit.Format(trans(v)) } + str := func(v Any) string { return kit.Format(Trans(v)) } switch cmd { case "Option": return m.Option(str(arg[0]), arg[1:]...) @@ -254,7 +278,7 @@ func (m Message) Call(cmd string, arg ...Any) Any { if len(arg) > 0 { m.ProcessDisplay(arg...) } else { - m.ProcessDisplay(kit.Format("%s?_t=%d", trans(_parse_stack(m.Message).value(m.Message, "_script")), time.Now().Unix())) + m.ProcessDisplay(kit.Format("%s?_t=%d", Trans(_parse_stack(m.Message).value(m.Message, "_script")), time.Now().Unix())) } case "StatusTime": m.StatusTime(arg...) @@ -281,3 +305,69 @@ func (m Message) Call(cmd string, arg ...Any) Any { } type Message struct{ *ice.Message } + +func TransContext(m *ice.Message, key string, arg ...Any) *ice.Context { + s := &ice.Context{Caches: ice.Caches{ice.CTX_FOLLOW: &ice.Cache{}}} + kit.For(arg[0], func(k string, v ice.Any) { + switch k { + case "Name": + s.Name = kit.Format(Trans(v)) + case "Help": + s.Help = kit.Format(Trans(v)) + case "Commands": + s.Commands = TransCommands(m, v) + } + }) + s.Merge(s).Cap(ice.CTX_FOLLOW, kit.Keys(key, s.Name)) + return s +} +func TransCommands(m *ice.Message, arg ...Any) ice.Commands { + commands := ice.Commands{} + stack := m.Optionv(ice.YAC_STACK).(*Stack) + kit.For(arg[0], func(k string, v ice.Any) { + s := &ice.Command{} + kit.For(v, func(k string, v ice.Any) { + switch k { + case "Name": + s.Name = kit.Format(Trans(v)) + case "Help": + s.Help = kit.Format(Trans(v)) + 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) + } + } + }) + commands[k] = s + }) + return commands +} +func TransActions(m *ice.Message, arg ...Any) ice.Actions { + switch v := arg[0].(type) { + case ice.Actions: + return v + } + actions := ice.Actions{} + stack := m.Optionv(ice.YAC_STACK).(*Stack) + kit.For(arg[0], func(k string, v ice.Any) { + s := &ice.Action{} + switch k { + case "Name": + s.Name = kit.Format(Trans(v)) + 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) + } + } + actions[k] = s + }) + return actions +} diff --git a/conf.go b/conf.go index d437eda9..a9d69d43 100644 --- a/conf.go +++ b/conf.go @@ -210,6 +210,7 @@ const ( // MSG MSG_HEIGHT = "sess.height" MSG_DAEMON = "sess.daemon" MSG_FILES = "file.system" + YAC_STACK = "stack" LOG_DISABLE = "log.disable" ) const ( // RENDER diff --git a/core/code/code.go b/core/code/code.go index 0fa6a72d..faeaf18f 100644 --- a/core/code/code.go +++ b/core/code/code.go @@ -3,6 +3,7 @@ package code import ( ice "shylinux.com/x/icebergs" "shylinux.com/x/icebergs/base/web" + "shylinux.com/x/icebergs/base/yac" kit "shylinux.com/x/toolkits" ) @@ -16,9 +17,10 @@ func init() { VIMER, INNER, XTERM, PPROF, BENCH, C, SH, SHY, PY, GO, JS, CSS, HTML, ) - ice.Info.Stack[CODE] = func(m *ice.Message, key string, arg ...ice.Any) ice.Any { - return nil +} +func init() { + ice.Info.Stack[Prefix(Index.Register)] = func(m *ice.Message, key string, arg ...ice.Any) ice.Any { + return Index.Register(yac.TransContext(m, Prefix(), arg...), &web.Frame{}) } } - -func Prefix(arg ...string) string { return web.Prefix(CODE, kit.Keys(arg)) } +func Prefix(arg ...ice.Any) string { return web.Prefix(CODE, kit.Keys(arg...)) } diff --git a/core/code/install.go b/core/code/install.go index ee774951..f4bd6145 100644 --- a/core/code/install.go +++ b/core/code/install.go @@ -206,3 +206,6 @@ func InstallAction(args ...ice.Any) ice.Actions { nfs.TRASH: {Hand: func(m *ice.Message, arg ...string) { nfs.Trash(m, m.Option(nfs.PATH)) }}, } } +func init() { + ice.Info.Stack[Prefix(InstallAction)] = func(m *ice.Message, key string, arg ...ice.Any) ice.Any { return InstallAction(arg...) } +} diff --git a/type.go b/type.go index 9c53bf94..0003e9d6 100644 --- a/type.go +++ b/type.go @@ -178,6 +178,7 @@ func (c *Context) Merge(s *Context) *Context { for k, v := range s.Configs { c.Configs[k] = v } + kit.If(c.Caches == nil, func() { c.Caches = Caches{} }) return c } func (c *Context) Begin(m *Message, arg ...string) *Context {