diff --git a/etc/dotsfile/shy.vim b/etc/dotsfile/shy.vim index 6cc3013b..0ac47671 100644 --- a/etc/dotsfile/shy.vim +++ b/etc/dotsfile/shy.vim @@ -38,8 +38,9 @@ syn match shyCommand "\(^\|\t\| \|$(\)[a-zA-Z0-9_\.]\+\>" call Keys("Operator", ["new"]) call Keys("Statment", ["config", "cache"]) call Keys("Statment", ["return", "source"]) -call Keys("Statment", ["if", "else", "else if", "for", "fun", "end"]) call Keys("Statment", ["let", "var"]) +call Keys("Statment", ["if", "else", "else if", "for", "fun", "end"]) +call Keys("Statment", ["label", "goto"]) " context nfs call Keys("SubCommand", ["import", "export", "load", "save"]) diff --git a/src/contexts/cli/version.go b/src/contexts/cli/version.go index 741ce07d..0e87c559 100644 --- a/src/contexts/cli/version.go +++ b/src/contexts/cli/version.go @@ -4,5 +4,5 @@ var version = struct { host string self int }{ - "2019-07-24 17:59:29", "ZYB-20190522USI", 242, + "2019-07-26 01:59:19", "ZYB-20190522USI", 257, } diff --git a/src/contexts/ctx/core.go b/src/contexts/ctx/core.go index 54f24044..050b4133 100644 --- a/src/contexts/ctx/core.go +++ b/src/contexts/ctx/core.go @@ -405,7 +405,7 @@ func (m *Message) Free(cbs ...func(msg *Message) (done bool)) *Message { return m } -func (m *Message) Goshy(input []string, index int, stack *kit.Stack) *kit.Stack { +func (m *Message) Goshy(input []string, index int, stack *kit.Stack, cb func(*Message)) bool { if stack == nil { stack = &kit.Stack{} stack.Push("source", true, 0) @@ -419,6 +419,14 @@ func (m *Message) Goshy(input []string, index int, stack *kit.Stack) *kit.Stack // 执行语句 msg := m.Cmd("yac.parse", line+"\n") + if cb != nil { + cb(msg) + } + + // 切换模块 + if v := msg.Optionv("bio.ctx"); v != nil { + m.Optionv("bio.ctx", v) + } // 跳转语句 if msg.Appends("bio.pos0") { @@ -430,8 +438,8 @@ func (m *Message) Goshy(input []string, index int, stack *kit.Stack) *kit.Stack if msg.Appends("bio.end") { m.Copy(msg, "append").Copy(msg, "result") msg.Appends("bio.end", "") - break + return true } } - return stack + return false } diff --git a/src/contexts/ctx/ctx.go b/src/contexts/ctx/ctx.go index 813ef1ca..575a449a 100644 --- a/src/contexts/ctx/ctx.go +++ b/src/contexts/ctx/ctx.go @@ -675,6 +675,7 @@ var Index = &Context{Name: "ctx", Help: "模块中心", Server: &CTX{}, cs = append(cs, msg.target) return false }) + msg = m.Spawn() for _, v := range cs { if msg.target = v; v == nil { diff --git a/src/contexts/nfs/nfs.go b/src/contexts/nfs/nfs.go index d55e0049..926306b5 100644 --- a/src/contexts/nfs/nfs.go +++ b/src/contexts/nfs/nfs.go @@ -326,7 +326,8 @@ func (nfs *NFS) Start(m *ctx.Message, arg ...string) bool { stack := &kit.Stack{} stack.Push(m.Option("stack.key", "source"), m.Options("stack.run", true), m.Optioni("stack.pos", 0)) m.Optionv("bio.ctx", m.Target()) - m.Optionv("bio.stack", stack) + + input := make([]string, 0, 128) line, bio := "", bufio.NewScanner(nfs) for nfs.prompt(); ; nfs.prompt() { @@ -348,35 +349,13 @@ func (nfs *NFS) Start(m *ctx.Message, arg ...string) bool { m.Log("debug", "%s %d %d [%s]", "input", m.Capi("ninput", 1), len(line), line) m.Confv("input", -2, map[string]interface{}{"time": time.Now().Unix(), "line": line}) - // 解析数据 - for i := m.Capi("ninput") - 1; i < m.Capi("ninput"); i++ { - line = m.Conf("input", []interface{}{i, "line"}) - m.Optionv("input", m.Confv("input")) - m.Optioni("stack.pos", i) - - // 执行语句 - msg := m.Cmd("yac.parse", line+"\n") - nfs.print(m.Conf("prompt"), line) + if input = append(input, line); m.Goshy(input, len(input)-1, stack, func(msg *ctx.Message) { + if m.Confs("term", "use") { + nfs.print(m.Conf("prompt"), line) + } nfs.print(msg.Meta["result"]...) - - // 切换模块 - if v := msg.Optionv("bio.ctx"); v != nil { - m.Optionv("bio.ctx", v) - } - - // 跳转语句 - if msg.Appends("bio.pos0") { - i = int(msg.Appendi("bio.pos0")) - 1 - msg.Append("bio.pos0", "") - } - - // 结束脚本 - if msg.Appends("bio.end") { - m.Copy(msg, "append") - m.Copy(msg, "result") - msg.Appends("bio.end", "") - return true - } + }) { + break } line = "" } diff --git a/src/contexts/yac/yac.go b/src/contexts/yac/yac.go index e5df296e..084ca352 100644 --- a/src/contexts/yac/yac.go +++ b/src/contexts/yac/yac.go @@ -334,6 +334,9 @@ var Index = &ctx.Context{Name: "yac", Help: "语法中心", map[string]interface{}{"page": "stm", "hash": "fun", "word": []interface{}{"fun", "key", "rep{", "key", "}"}}, map[string]interface{}{"page": "stm", "hash": "else", "word": []interface{}{"else", "opt{", "if", "exp", "}"}}, map[string]interface{}{"page": "stm", "hash": "end", "word": []interface{}{"end"}}, + + map[string]interface{}{"page": "stm", "hash": "label", "word": []interface{}{"label", "key"}}, + map[string]interface{}{"page": "stm", "hash": "goto", "word": []interface{}{"goto", "key"}}, /* map[string]interface{}{"page": "op1", "hash": "op1", "word": []interface{}{"mul{", "-z", "-n", "}"}}, @@ -350,8 +353,6 @@ var Index = &ctx.Context{Name: "yac", Help: "语法中心", map[string]interface{}{"page": "stm", "hash": "for", "word": []interface{}{"for", "opt{", "exp", ";", "}", "exp"}}, map[string]interface{}{"page": "stm", "hash": "for", "word": []interface{}{"for", "index", "exp", "opt{", "exp", "}", "exp"}}, - map[string]interface{}{"page": "stm", "hash": "label", "word": []interface{}{"label", "exp"}}, - map[string]interface{}{"page": "stm", "hash": "goto", "word": []interface{}{"goto", "exp", "opt{", "exp", "}", "exp"}}, */ @@ -543,6 +544,12 @@ var Index = &ctx.Context{Name: "yac", Help: "语法中心", msg := m.Spawn(m.Optionv("bio.ctx")) switch arg[0] { case "$": + if stack, ok := m.Optionv("bio.stack").(*kit.Stack); ok { + if v, ok := stack.Hash(arg[1]); ok { + m.Echo("%v", v) + break + } + } m.Echo(msg.Cap(arg[1])) case "@": value := msg.Option(arg[1]) @@ -933,33 +940,25 @@ var Index = &ctx.Context{Name: "yac", Help: "语法中心", }}, "var": &ctx.Command{Name: "var a [= exp]", Help: "定义变量, a: 变量名, exp: 表达式", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { - if m.Cap(arg[1], arg[1], "", "临时变量"); len(arg) > 1 { - switch arg[2] { - case "=": - m.Cap(arg[1], arg[3]) - case "<-": - m.Cap(arg[1], m.Cap("last_msg")) - } + if stack, ok := m.Optionv("bio.stack").(*kit.Stack); ok { + m.Log("stack", "%v = %v", arg[1], arg[3]) + stack.Peek().Hash[arg[1]] = arg[3] } - m.Echo(m.Cap(arg[1])) return }}, "let": &ctx.Command{Name: "let a = exp", Help: "设置变量, a: 变量名, exp: 表达式", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { - switch arg[2] { - case "=": - m.Cap(arg[1], arg[3]) - m.Log("stack", "let %v = %v", arg[1], arg[3]) - case "<-": - m.Cap(arg[1], m.Cap("last_msg")) + if stack, ok := m.Optionv("bio.stack").(*kit.Stack); ok { + m.Log("stack", "%v = %v", arg[1], arg[3]) + stack.Hash(arg[1], arg[3]) } - m.Echo(m.Cap(arg[1])) return }}, "if": &ctx.Command{Name: "if exp", Help: "条件语句, exp: 表达式", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { stack := m.Optionv("bio.stack").(*kit.Stack) - p := stack.Push(arg[0], stack.Peek().Run && kit.Right(arg[1]), m.Optioni("stack.pos")) + o := stack.Peek() + p := stack.Push(arg[0], o.Run && kit.Right(arg[1]), m.Optioni("stack.pos")) m.Log("stack", "push %v", p.String("\\")) - if p.Run { + if !o.Run || p.Run { p.Done = true } return @@ -1034,8 +1033,7 @@ var Index = &ctx.Context{Name: "yac", Help: "语法中心", self := &ctx.Command{Name: strings.Join(arg[1:], " "), Help: []string{"pwd", "ls"}} self.Hand = func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { - - m.Goshy(self.Help.([]string), 0, nil) + m.Goshy(self.Help.([]string), 0, nil, nil) return } m.Target().Commands[arg[1]] = self @@ -1045,7 +1043,7 @@ var Index = &ctx.Context{Name: "yac", Help: "语法中心", "else": &ctx.Command{Name: "else", Help: "条件语句", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { p := m.Optionv("bio.stack").(*kit.Stack).Peek() p.Run = !p.Done && !p.Run && (len(arg) == 1 || kit.Right(arg[2])) - m.Log("stack", "set: run = %v", p.Run) + m.Log("stack", "set: %v", p.String("|")) if p.Run { p.Done = true } @@ -1063,10 +1061,9 @@ var Index = &ctx.Context{Name: "yac", Help: "语法中心", end := m.Optioni("stack.pos") self := p.Data.(*ctx.Command) help := []string{} - for i, v := range m.Optionv("input").([]interface{}) { + for i, v := range m.Optionv("bio.input").([]string) { if p.Pos < i && i < end { - val := v.(map[string]interface{}) - help = append(help, val["line"].(string)) + help = append(help, v) } } self.Help = help @@ -1076,22 +1073,19 @@ var Index = &ctx.Context{Name: "yac", Help: "语法中心", }}, "label": &ctx.Command{Name: "label name", Help: "记录当前脚本的位置, name: 位置名", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { - if cli, ok := m.Target().Server.(*YAC); m.Assert(ok) { - if cli.label == nil { - cli.label = map[string]string{} - } - cli.label[arg[1]] = m.Option("file_pos") + p := m.Optionv("bio.stack").(*kit.Stack).Peek() + if p.Label == nil { + p.Label = map[string]int{} } + m.Log("stack", "%v <= %v", arg[1], m.Optioni("stack.pos")+1) + p.Label[arg[1]] = m.Optioni("stack.pos") + 1 return }}, "goto": &ctx.Command{Name: "goto label [exp] condition", Help: "向上跳转到指定位置, label: 跳转位置, condition: 跳转条件", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { - if cli, ok := m.Target().Server.(*YAC); m.Assert(ok) { - if pos, ok := cli.label[arg[1]]; ok { - if !kit.Right(arg[len(arg)-1]) { - return - } - m.Append("file_pos0", pos) - } + stack := m.Optionv("bio.stack").(*kit.Stack) + if i, ok := stack.Label(arg[1]); ok { + m.Log("stack", "%v => %v", arg[1], i) + m.Append("bio.pos0", i) } return }}, diff --git a/src/toolkit/shy.go b/src/toolkit/shy.go index 3b577776..98a524cd 100644 --- a/src/toolkit/shy.go +++ b/src/toolkit/shy.go @@ -6,13 +6,15 @@ import ( ) type Frame struct { - Key string - Run bool - Pos int - deep int - // list []string - Done bool - Data interface{} + Key string + Run bool + Pos int + + deep int + Done bool + Data interface{} + Hash map[string]interface{} + Label map[string]int } func (f *Frame) String(meta string) string { @@ -27,7 +29,7 @@ type Stack struct { } func (s *Stack) Push(key string, run bool, pos int) *Frame { - s.fs = append(s.fs, &Frame{Key: key, Run: run, Pos: pos, deep: len(s.fs)}) + s.fs = append(s.fs, &Frame{Key: key, Run: run, Pos: pos, deep: len(s.fs), Hash: map[string]interface{}{}}) return s.fs[len(s.fs)-1] } func (s *Stack) Peek() *Frame { @@ -44,3 +46,28 @@ func (s *Stack) Pop() *Frame { s.fs = s.fs[:len(s.fs)-1] return f } +func (s *Stack) Hash(key string, val ...interface{}) (interface{}, bool) { + for i := len(s.fs) - 1; i >= 0; i-- { + if v, ok := s.fs[i].Hash[key]; ok { + if len(val) > 0 { + s.fs[i].Hash[key] = val[0] + } + return v, ok + } + } + + if len(val) > 0 { + s.fs[len(s.fs)-1].Hash[key] = val[0] + return val[0], true + } + return nil, false +} +func (s *Stack) Label(key string) (int, bool) { + for i := len(s.fs) - 1; i >= 0; i-- { + if v, ok := s.fs[i].Label[key]; ok { + s.fs = s.fs[:i+1] + return v, ok + } + } + return -1, false +}