From 6f5e22631cdd1dd4bae5702f76ffe17718237219 Mon Sep 17 00:00:00 2001 From: shylinux Date: Mon, 3 Apr 2023 01:05:16 +0800 Subject: [PATCH] opt some --- base/yac/expr.go | 89 ++++++++++++++++++++++----------------- base/yac/stack.go | 103 +++++++++++++++++++++++----------------------- base/yac/stmt.go | 28 ++++--------- base/yac/value.go | 39 ++++++++++-------- 4 files changed, 132 insertions(+), 127 deletions(-) diff --git a/base/yac/expr.go b/base/yac/expr.go index ebadddc1..3f06298e 100644 --- a/base/yac/expr.go +++ b/base/yac/expr.go @@ -39,7 +39,6 @@ var level = map[string]int{ type Expr struct { list ice.List s *Stack - n int } func (s *Expr) push(v Any) *Expr { @@ -74,7 +73,11 @@ func (s *Expr) setv(m *ice.Message, p int, op string, v Any) Any { case string: return s.s.value(m, k, s.s.value(m, v), op) case Value: - return s.s.value(m, k, v.list[0], op) + if len(v.list) > 0 { + return s.s.value(m, k, v.list[0], op) + } else { + return s.s.value(m, k) + } default: return s.s.value(m, k, v, op) } @@ -92,9 +95,6 @@ func (s *Expr) ops(m *ice.Message) { if !s.s.runable() || s.getl(-2) < 10 { return } - if s.n++; s.n > 100 { - panic(s.n) - } s.pops(3, s.opv(m, -3, s.gets(-2), s.getv(m, -1))) } func (s *Expr) end(m *ice.Message) Any { @@ -104,36 +104,36 @@ func (s *Expr) end(m *ice.Message) Any { return s.getv(m, 0) } m.Debug("expr ops %v", s.list) - for len(s.list) > 1 { + for i := 0; i < 100 && len(s.list) > 1; i++ { switch s.ops(m); s.gets(-2) { + case DEFINE, ASSIGN: + switch v := s.getv(m, -1).(type) { + case Value: + list := kit.List() + for i := 0; i < len(s.list)-1; i += 2 { + kit.If(i/2 < len(v.list), func() { list = append(list, s.setv(m, i, s.gets(-2), v.list[i/2])) }) + } + 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))) + } case FIELD: list := kit.List() for i := len(s.list) - 2; i > 0; i -= 2 { - if s.gets(i) == ASSIGN || s.gets(i) == DEFINE { + 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))) } - s.list = kit.List(Value{list: list}) + s.list = append(s.list[:0], Value{list}) break } else if i == 1 { for i := 0; i < len(s.list); i += 2 { list = append(list, s.getv(m, i)) } - s.list = kit.List(Value{list: list}) + s.list = append(s.list[:0], Value{list}) break } } - case ASSIGN, DEFINE: - list := kit.List() - switch v := s.getv(m, -1).(type) { - case Value: - for i := 0; i < len(s.list)-1; i += 2 { - kit.If(i/2 < len(v.list), func() { list = append(list, s.setv(m, i, s.gets(-2), v.list[i/2])) }) - } - default: - s.setv(m, -3, s.gets(-2), s.getv(m, -1)) - } - s.list = kit.List(Value{list}) } } m.Debug("expr ops %v", s.list) @@ -177,7 +177,12 @@ func (s *Expr) cals(m *ice.Message) Any { s.s.skip-- s.pops(1, s.s.value(m, s.s.funcs(m))) } else { - s.pops(1, s.call(m, s.s, s.gets(-1))) + switch k := s.get(-1).(type) { + case string: + s.pops(1, s.call(m, s.s, k)) + default: + s.pops(1, s.call(m, k, "")) + } } return false } @@ -193,28 +198,36 @@ func (s *Expr) cals(m *ice.Message) Any { } } if level[k] > 0 { - for level[k] >= 9 && level[k] <= s.getl(-2) && level[k] < 100 { + for 9 <= level[k] && level[k] <= s.getl(-2) && level[k] < 100 { s.ops(m) } s.push(k) } else { - if strings.HasPrefix(k, "\"") { - s.push(String{value: k[1 : len(k)-1]}) - } else if k == ice.TRUE { - s.push(Boolean{value: true}) - } else if k == ice.FALSE { - s.push(Boolean{value: false}) - } else if keyword.MatchString(k) { - s.push(k) - } else { - s.push(Number{value: k}) - } - if s.gets(-2) == "!" { + if s.push(s.trans(m, k)); s.gets(-2) == "!" { s.pops(2, s.opv(m, -1, "!", nil)) } } return false }) + if s.cmds(m, line) { + return nil + } + return s.end(m) +} +func (s *Expr) trans(m *ice.Message, k string) Any { + if strings.HasPrefix(k, "\"") { + return String{value: k[1 : len(k)-1]} + } else if k == ice.TRUE { + return Boolean{value: true} + } else if k == ice.FALSE { + return Boolean{value: false} + } else if keyword.MatchString(k) { + return k + } else { + return Number{value: k} + } +} +func (s *Expr) cmds(m *ice.Message, line int) bool { if cmds := false; len(s.list) == 1 && s.s.skip < 2 { m.Search(s.gets(0), func(key string, cmd *ice.Command) { if cmds = true; s.s.line == line { @@ -237,10 +250,10 @@ func (s *Expr) cals(m *ice.Message) Any { } }) if cmds { - return nil + return true } } - return s.end(m) + return false } func (s *Expr) call(m *ice.Message, obj Any, key string) Any { list := kit.List() @@ -255,13 +268,13 @@ func (s *Expr) call(m *ice.Message, obj Any, key string) Any { } return s.s.call(m, obj, key, nil, list...) } -func NewExpr(s *Stack) *Expr { return &Expr{kit.List(), s, 0} } +func NewExpr(s *Stack) *Expr { return &Expr{kit.List(), s} } const EXPR = "expr" func init() { Index.MergeCommands(ice.Commands{ - EXPR: {Name: "expr a = 1", Hand: func(m *ice.Message, arg ...string) { + EXPR: {Name: "expr a, b = 1, 2", Hand: func(m *ice.Message, arg ...string) { s := _parse_stack(m) arg = s.rest if v := s.cals(m); !s.runable() { diff --git a/base/yac/stack.go b/base/yac/stack.go index a92ffee7..00695b67 100644 --- a/base/yac/stack.go +++ b/base/yac/stack.go @@ -21,9 +21,9 @@ type Function struct { type Frame struct { key string value ice.Map + defers []func() status int Position - pop func() } type Stack struct { last *Frame @@ -53,12 +53,9 @@ func (s *Stack) pushf(m *ice.Message, key string) *Frame { } func (s *Stack) popf(m *ice.Message) *Frame { f := s.peekf() - list := kit.List(f.value["_defer"]) - delete(f.value, "_defer") - for i := len(list) - 1; i >= 0; i-- { - list[i].(func())() + for i := len(f.defers) - 1; i >= 0; i-- { + f.defers[i]() } - kit.If(f.pop != nil, func() { f.pop() }) m.Debug("stack pop %d %v %s:%d", len(s.frame)-1, f.key, f.name, f.line) kit.If(len(s.frame) > 0, func() { s.frame = s.frame[:len(s.frame)-1] }) s.last = f @@ -184,12 +181,12 @@ func (s *Stack) call(m *ice.Message, obj Any, key Any, cb func(*Frame, Function) value.list = arg } } - f.pop, s.Position = func() { + f.defers, s.Position = append(f.defers, func() { if len(obj.res) > 0 && len(value.list) == 0 { kit.For(obj.res, func(i int, k string) { value.list = append(value.list, f.value[k]) }) } s.Position = pos - }, obj.Position + }), obj.Position kit.If(cb != nil, func() { cb(f, obj) }) s.run(m.Options(STACK, s)) return value @@ -223,8 +220,7 @@ func (s *Stack) expr(m *ice.Message, pos ...Position) string { } func (s *Stack) funcs(m *ice.Message) string { name := kit.Format("%s:%d:%d", s.name, s.line, s.skip) - s.rest[s.skip] = name - s.skip-- + s.rest[s.skip], s.skip = name, s.skip-1 m.Cmd(FUNC, name) f := s.peekf() status := f.status @@ -235,9 +231,7 @@ func (s *Stack) funcs(m *ice.Message) string { } func (s *Stack) parse(m *ice.Message, name string, r io.Reader, cb func(*Frame)) *Stack { s.Buffer = &Buffer{name: name, input: bufio.NewScanner(r)} - s.load(m) - kit.If(cb != nil, func() { cb(s.peekf()) }) - s.run(m) + s.load(m, cb).run(m) return s } func NewStack() *Stack { return &Stack{} } @@ -246,6 +240,25 @@ func _parse_stack(m *ice.Message) *Stack { return m.Optionv(STACK).(*Stack) } func _parse_frame(m *ice.Message) (*Stack, *Frame) { return _parse_stack(m), _parse_stack(m).pushf(m, "") } +func _parse_cache(m *ice.Message, name string) *Stack { + key := kit.Keys(m.PrefixKey(), name) + s := mdb.Cache(m, key, func() (v Any) { + nfs.Open(m, existsFile(m, name), func(r io.Reader, p string) { + v = NewStack().parse(m.Spawn(), p, r, nil) + }) + return + }).(*Stack) + kit.If(m.Option(ice.DEBUG) == ice.TRUE, func() { mdb.Cache(m, key, nil) }) + return s +} +func _parse_res(m *ice.Message, v Any) []Any { + switch v := v.(type) { + case Value: + return v.list + default: + return []Any{v} + } +} const ( STATUS_NORMAL = 0 @@ -257,47 +270,36 @@ func init() { Index.MergeCommands(ice.Commands{ STACK: {Name: "stack path auto parse", Actions: ice.Actions{ ice.CMD: {Hand: func(m *ice.Message, arg ...string) { - nfs.Open(m, existsFile(m, arg[0]), func(r io.Reader, p string) { - meta := kit.Dict() - kit.For(NewStack().parse(m.Spawn(), p, r, nil).peekf().value, func(k string, v Any) { - switch v := v.(type) { - case Function: - list := kit.List() - kit.For(v.arg, func(k string) { - switch k { - case "m", ice.ARG: - default: - list = append(list, kit.Dict(mdb.NAME, k, 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)) }) - meta[k] = list - } - }) - m.Push(ice.INDEX, arg[0]) - m.Push(mdb.NAME, arg[0]) - m.Push(mdb.HELP, arg[0]) - m.Push(mdb.LIST, kit.Format(meta[mdb.LIST])) - m.Push(mdb.META, kit.Format(meta)) + s := _parse_cache(m, arg[0]) + meta := kit.Dict() + kit.For(s.peekf().value, func(k string, v Any) { + switch v := v.(type) { + case Function: + list := kit.List() + kit.For(v.arg, func(k string) { + if !kit.IsIn(k, "m", ice.ARG) { + list = append(list, kit.Dict(mdb.NAME, k, 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)) }) + meta[k] = list + } }) + m.Push(ice.INDEX, arg[0]) + m.Push(mdb.NAME, arg[0]) + m.Push(mdb.HELP, arg[0]) + m.Push(mdb.LIST, kit.Format(meta[mdb.LIST])) + m.Push(mdb.META, kit.Format(meta)) }}, ice.RUN: {Hand: func(m *ice.Message, arg ...string) { - s := mdb.Cache(m, arg[0], func() (stack Any) { - nfs.Open(m, existsFile(m, arg[0]), func(r io.Reader, p string) { - stack = NewStack().parse(m.Spawn(), p, r, nil) - }) - return - }).(*Stack) - kit.If(m.Option("debug") == ice.TRUE, func() { mdb.Cache(m, arg[0], nil) }) - m.StatusTime() - action := mdb.LIST + s := _parse_cache(m, arg[0]) + action, i := mdb.LIST, 0 if len(arg) > 2 && arg[1] == ice.ACTION && s.value(m, arg[2]) != nil { action, arg = arg[2], arg[3:] } else { arg = arg[1:] } - i := 0 - s.call(m, s, action, func(f *Frame, v Function) { + s.call(m.StatusTime(), s, action, func(f *Frame, v Function) { kit.For(v.arg, func(k string) { switch k { case "m": @@ -307,8 +309,7 @@ func init() { kit.For(arg, func(v string) { list = append(list, String{v}) }) f.value[k] = Value{list} default: - f.value[k] = String{m.Option(k, kit.Select(m.Option(k), arg, i))} - i++ + f.value[k], i = String{m.Option(k, kit.Select(m.Option(k), arg, i))}, i+1 } }) }) @@ -318,11 +319,9 @@ func init() { return } nfs.Open(m, path.Join(nfs.SRC, path.Join(arg...)), func(r io.Reader, p string) { - if NewStack().parse(m, p, r, nil); m.Option(ice.DEBUG) != ice.TRUE { - return + if NewStack().parse(m, p, r, nil); m.Option(ice.DEBUG) == ice.TRUE { + m.EchoLine("").EchoLine("stack: %s", arg[0]).Cmdy(INFO) } - m.EchoLine("").EchoLine("stack: %s", arg[0]).Cmdy(INFO) - }) }}, }) diff --git a/base/yac/stmt.go b/base/yac/stmt.go index 94c27bcb..4a35b1f1 100644 --- a/base/yac/stmt.go +++ b/base/yac/stmt.go @@ -44,7 +44,7 @@ func init() { if s.last.status == STATUS_DISABLE { f.status = 0 } else { - f.status, f.pop = STATUS_DISABLE, func() { f.status = 0 } + f.status, f.defers = STATUS_DISABLE, append(f.defers, func() { f.status = 0 }) } s.reads(m, func(k string) bool { if k == IF { @@ -76,13 +76,13 @@ func init() { res = s.expr(m, list[1]) } kit.If(res == ice.FALSE, func() { f.status = STATUS_DISABLE }) - s.Position, f.pop = list[len(list)-1], func() { + 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-- } - } + }) }}, BREAK: {Name: "break", Hand: func(m *ice.Message, arg ...string) { s := _parse_stack(m) @@ -179,17 +179,14 @@ func init() { v = []Any{v} } s.stack(func(f *Frame, i int) bool { - if kit.IsIn(f.key, CALL, SOURCE, STACK) { - f.value["_defer"] = append(kit.List(f.value["_defer"]), func() { - s.call(m, s, k, nil, v.([]Any)...) - }) + if f.key == CALL { + f.defers = append(f.defers, func() { s.call(m, s, k, nil, v.([]Any)...) }) return true } return false }) return true }) - }}, RETURN: {Name: "return show", Hand: func(m *ice.Message, arg ...string) { s := _parse_stack(m) @@ -202,12 +199,7 @@ func init() { case CALL: switch cb := f.value["_return"].(type) { case func(...Any): - switch v := v.(type) { - case Value: - cb(v.list...) - default: - cb(v) - } + cb(_parse_res(m, v)...) } case SOURCE: s.input = nil @@ -230,10 +222,8 @@ func init() { }}, INFO: {Name: "info", Hand: func(m *ice.Message, arg ...string) { _parse_stack(m).stack(func(f *Frame, i int) bool { - m.EchoLine("frame: %s %v:%v:%v", f.key, f.Position.name, f.Position.line, f.Position.skip) - kit.For(f.value, func(k string, v Any) { - m.EchoLine(" %s: %#v", k, v) - }) + 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) }) return false }) }}, @@ -242,7 +232,7 @@ func init() { res := []string{kit.Format("%d:%d", s.line, s.skip)} s.stack(func(f *Frame, i int) bool { kit.If(i > 0, func() { - res = append(res, kit.Format("%s:%d:%d %s %v", f.name, f.line, f.skip, f.key, kit.Select(ice.FALSE, ice.TRUE, f.status > STATUS_DISABLE))) + res = append(res, kit.Format("%s %s %s:%d:%d", f.key, kit.Select(ice.FALSE, ice.TRUE, f.status > STATUS_DISABLE), f.name, f.line, f.skip)) }) return false }) diff --git a/base/yac/value.go b/base/yac/value.go index 376c7d9b..f72a766e 100644 --- a/base/yac/value.go +++ b/base/yac/value.go @@ -27,10 +27,16 @@ func (s Boolean) MarshalJSON() ([]byte, error) { return json.Marshal(s.value) } func wrap(v Any) Any { switch v := v.(type) { - case bool: - return Boolean{v} + case map[string]Any: + return Dict{v} + case []Any: + return List{v} case string: return String{v} + case int: + return Number{kit.Format(v)} + case bool: + return Boolean{v} default: return v } @@ -147,11 +153,9 @@ func (s Boolean) Operate(op string, v Any) Any { type Message struct{ *ice.Message } func (m Message) Call(cmd string, arg ...Any) Any { - str := func(v Any) string { return kit.Format(trans(v)) } args := []Any{} - for _, v := range arg { - args = append(args, trans(v)) - } + kit.For(arg, func(i int, v Any) { args = append(args, trans(v)) }) + str := func(v Any) string { return kit.Format(trans(v)) } switch cmd { case "Option": return String{m.Option(str(args[0]), args[1:]...)} @@ -165,26 +169,20 @@ func (m Message) Call(cmd string, arg ...Any) Any { m.Push(str(args[0]), args[1], args[2:]...) case "Echo": m.Echo(str(args[0]), args[1:]...) - case "Table": - s := _parse_stack(m.Message) - var value Any - m.Table(func(val ice.Maps) { value = s.call(m.Message, arg[0], nil, nil, Dict{kit.Dict(val)}) }) - return value - case "Sleep": - m.Sleep(str(args[0])) case "Action": m.Action(args...) + case "Sleep": + m.Sleep(str(args[0])) + case "Table": + s := _parse_stack(m.Message) + m.Table(func(val ice.Maps) { s.call(m.Message, arg[0], nil, nil, Dict{kit.Dict(val)}) }) default: m.ErrorNotImplement(cmd) } return m } -func (s *Stack) load(m *ice.Message) *Stack { +func (s *Stack) load(m *ice.Message, cb func(*Frame)) *Stack { f := s.pushf(m.Options(STACK, s), "") - f.value["m"] = Message{m} - for k, v := range ice.Info.Stack { - f.value[k] = v - } f.value["kit"] = func(m *ice.Message, key string, arg ...Any) Any { kit.For(arg, func(i int, v Any) { arg[i] = trans(v) }) switch key { @@ -197,5 +195,10 @@ func (s *Stack) load(m *ice.Message) *Stack { return nil } } + for k, v := range ice.Info.Stack { + f.value[k] = v + } + f.value["m"] = Message{m} + kit.If(cb != nil, func() { cb(s.peekf()) }) return s }