From cf5b72facc4a5a63814c02554a1899287202070a Mon Sep 17 00:00:00 2001 From: shaoying Date: Sun, 29 Jul 2018 20:06:36 +0800 Subject: [PATCH] mac pro cli --- etc/init.shy | 27 +++++------ src/contexts/cli/cli.go | 104 ++++++++++++++++++++-------------------- src/contexts/ctx.go | 15 ++++-- src/contexts/lex/lex.go | 2 +- src/contexts/nfs/nfs.go | 4 -- src/contexts/yac/yac.go | 47 +++++++++++------- 6 files changed, 105 insertions(+), 94 deletions(-) diff --git a/etc/init.shy b/etc/init.shy index 5bfc4319..be27c8bb 100644 --- a/etc/init.shy +++ b/etc/init.shy @@ -1,24 +1,19 @@ +source etc/local.shy +var a <- +for index $a result hi + echo $hi +end + ~file1 history load etc/history.txt ~shell1 alias import nfs -return -source etc/local.shy -config debug on -return +var b = 1 -return "hello" "world" -source etc/demo.shy -~file1 - history load hi.cmd -scan_file etc/demo.shy -echo "who" -~web - command add get "https://chat.shylinux.com" +label hi -~aaa - login root root +echo $b +let b = $b + 1 +goto hi $b < 4 -~yac - scan_file etc/demo.shy demo_file diff --git a/src/contexts/cli/cli.go b/src/contexts/cli/cli.go index 6ad0a1e1..0e3dfaea 100644 --- a/src/contexts/cli/cli.go +++ b/src/contexts/cli/cli.go @@ -23,8 +23,8 @@ type Frame struct { } type CLI struct { - label map[string]string alias map[string][]string + label map[string]string target *ctx.Context stack []*Frame @@ -33,7 +33,6 @@ type CLI struct { } func (cli *CLI) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server { // {{{ - cli.Message = m c.Caches = map[string]*ctx.Cache{ "level": &ctx.Cache{Name: "level", Value: "0", Help: "嵌套层级"}, "parse": &ctx.Cache{Name: "parse(true/false)", Value: "true", Help: "命令解析"}, @@ -50,7 +49,7 @@ func (cli *CLI) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server // }}} }}, "ps_end": &ctx.Config{Name: "ps_end", Value: "> ", Help: "命令行提示符结尾"}, - "prompt": &ctx.Config{Name: "prompt(ps_target/ps_time)", Value: "ps_count ps_time ps_target ps_end", Help: "命令行提示符, 以空格分隔, 依次显示各种信息", Hand: func(m *ctx.Message, x *ctx.Config, arg ...string) string { + "prompt": &ctx.Config{Name: "prompt(ps_count/ps_time/ps_target/ps_end/...)", Value: "ps_count ps_time ps_target ps_end", Help: "命令行提示符, 以空格分隔, 依次显示缓存或配置信息", Hand: func(m *ctx.Message, x *ctx.Config, arg ...string) string { if len(arg) > 0 { // {{{ return arg[0] } @@ -70,6 +69,7 @@ func (cli *CLI) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server s := new(CLI) s.Context = c + s.Message = m s.target = c s.alias = map[string][]string{ "~": []string{"context"}, @@ -99,44 +99,39 @@ func (cli *CLI) Start(m *ctx.Message, arg ...string) bool { // {{{ yac.Cmd("train", "key", "key", "[A-Za-z_][A-Za-z_0-9]*") yac.Cmd("train", "num", "num", "mul{", "0", "-?[1-9][0-9]*", "0[0-9]+", "0x[0-9]+", "}") yac.Cmd("train", "str", "str", "mul{", "\"[^\"]*\"", "'[^']*'", "}") - yac.Cmd("train", "tran", "tran", "mul{", "@", "$", "}", "opt{", "[a-zA-Z0-9_]+", "}") - yac.Cmd("train", "tran", "tran", "$", "(", "cache", ")") + yac.Cmd("train", "exe", "exe", "mul{", "$", "@", "}", "key") - yac.Cmd("train", "op1", "op1", "mul{", "$", "@", "}") yac.Cmd("train", "op1", "op1", "mul{", "-z", "-n", "}") yac.Cmd("train", "op1", "op1", "mul{", "-e", "-f", "-d", "}") yac.Cmd("train", "op1", "op1", "mul{", "-", "+", "}") - yac.Cmd("train", "op2", "op2", "mul{", "=", "+=", "}") + yac.Cmd("train", "op2", "op2", "mul{", ":=", "=", "+=", "}") yac.Cmd("train", "op2", "op2", "mul{", "+", "-", "*", "/", "%", "}") - yac.Cmd("train", "op2", "op2", "mul{", ">", ">=", "<", "<=", "==", "!=", "}") + yac.Cmd("train", "op2", "op2", "mul{", "<", "<=", ">", ">=", "==", "!=", "}") + yac.Cmd("train", "op2", "op2", "mul{", "~", "!~", "}") - yac.Cmd("train", "val", "val", "opt{", "op1", "}", "mul{", "num", "key", "str", "tran", "}") + yac.Cmd("train", "val", "val", "opt{", "op1", "}", "mul{", "num", "key", "str", "exe", "}") yac.Cmd("train", "exp", "exp", "val", "rep{", "op2", "val", "}") - yac.Cmd("train", "val", "val", "(", "exp", ")") - yac.Cmd("train", "stm", "var", "var", "key") - yac.Cmd("train", "stm", "var", "var", "key", "=", "exp") - yac.Cmd("train", "stm", "var", "var", "key", "<-", "exp") - yac.Cmd("train", "stm", "let", "let", "key", "mul{", "=", "<-", "}", "exp") + yac.Cmd("train", "val", "val", "opt{", "op1", "}", "(", "exp", ")") + + yac.Cmd("train", "stm", "var", "cache", "key", "opt{", "=", "exp", "}") + yac.Cmd("train", "stm", "var", "var", "key", "opt{", "=", "exp", "}") + yac.Cmd("train", "stm", "let", "let", "key", "opt{", "=", "exp", "}") + yac.Cmd("train", "stm", "var", "var", "key", "<-") + yac.Cmd("train", "stm", "var", "var", "key", "<-", "opt{", "exe", "}") + yac.Cmd("train", "stm", "let", "let", "key", "<-", "opt{", "exe", "}") yac.Cmd("train", "stm", "if", "if", "exp") yac.Cmd("train", "stm", "else", "else") yac.Cmd("train", "stm", "end", "end") - - yac.Cmd("train", "word", "word", "mul{", "~", "!", "=", "tran", "str", "[a-zA-Z0-9_/\\-.:]+", "}") - - yac.Cmd("train", "stm", "elif", "elif", "exp") - yac.Cmd("train", "stm", "for", "for", "exp") - yac.Cmd("train", "stm", "for", "for", "exp", ";", "exp") - yac.Cmd("train", "stm", "for", "for", "index", "word", "word", "word") - yac.Cmd("train", "stm", "function", "function", "rep{", "key", "}") + yac.Cmd("train", "stm", "for", "for", "opt{", "exp", ";", "}", "exp") + yac.Cmd("train", "stm", "for", "for", "index", "exp", "exp", "exp") + yac.Cmd("train", "stm", "label", "label", "exp") + yac.Cmd("train", "stm", "goto", "goto", "exp", "opt{", "exp", "}", "exp") yac.Cmd("train", "stm", "return", "return", "rep{", "exp", "}") - yac.Cmd("train", "cmd", "goto", "goto", "word", "exp") - yac.Cmd("train", "cmd", "cmd", "cache", "rep{", "word", "}") - yac.Cmd("train", "cmd", "cmd", "cache", "key", "rep{", "word", "}") - yac.Cmd("train", "cmd", "cmd", "cache", "key", "opt{", "=", "exp", "}") + yac.Cmd("train", "word", "word", "mul{", "~", "!", "=", "exe", "str", "[a-zA-Z0-9_/\\-.:]+", "}") yac.Cmd("train", "cmd", "cmd", "rep{", "word", "}") - yac.Cmd("train", "tran", "tran", "$", "(", "cmd", ")") + yac.Cmd("train", "exe", "exe", "$", "(", "cmd", ")") yac.Cmd("train", "line", "line", "opt{", "mul{", "stm", "cmd", "}", "}", "mul{", ";", "\n", "#[^\n]*\n", "}") } @@ -161,7 +156,7 @@ func (cli *CLI) Start(m *ctx.Message, arg ...string) bool { // {{{ if m.Option("prompt", cmd.Cmd().Conf("prompt")); cmd.Has("return") { m.Result(0, cmd.Meta["return"]) m.Options("scan_end", true) - m.Target().Close(m.Spawn()) + m.Target().Close(m) } m.Optionv("ps_target", cli.target) return nil @@ -222,13 +217,13 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心", if cli.label == nil { cli.label = map[string]string{} } - cli.label[arg[0]] = m.Option("file_pos") + cli.label[arg[1]] = m.Option("file_pos") } // }}} }}, - "goto": &ctx.Command{Name: "goto label [condition]", Help: "向上跳转到指定位置, label: 跳转位置, condition: 跳转条件", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { + "goto": &ctx.Command{Name: "goto label [exp] condition", Help: "向上跳转到指定位置, label: 跳转位置, condition: 跳转条件", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { if cli, ok := m.Target().Server.(*CLI); m.Assert(ok) { // {{{ if pos, ok := cli.label[arg[1]]; ok { - if len(arg) > 2 && !ctx.Right(arg[2]) { + if !ctx.Right(arg[len(arg)-1]) { return } m.Append("file_pos0", pos) @@ -390,36 +385,32 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心", m.Echo("%s", strings.Join(arg, "")) }}, - "tran": &ctx.Command{Name: "tran word", Help: "", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { + "str": &ctx.Command{Name: "str word", Help: "解析字符串", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { + m.Echo(arg[0][1 : len(arg[0])-1]) + }}, + "exe": &ctx.Command{Name: "exe $ ( cmd )", Help: "解析嵌套命令", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { if cli, ok := m.Target().Server.(*CLI); m.Assert(ok) { // {{{ - msg := m.Spawn(cli.target) switch len(arg) { case 1: m.Echo(arg[0]) case 2: + msg := m.Spawn(cli.target) switch arg[0] { case "$": m.Echo(msg.Cap(arg[1])) case "@": m.Echo(msg.Conf(arg[1])) default: - m.Echo(arg[0]) - m.Echo(arg[1]) + m.Echo(arg[0]).Echo(arg[1]) } default: - last := len(arg) - 1 switch arg[0] { - case "$": - m.Result(0, arg[2:last]) - case "@": - m.Result(0, arg[2:last]) + case "$", "@": + m.Result(0, arg[2:len(arg)-1]) } } } //}}} }}, - "str": &ctx.Command{Name: "str word", Help: "", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { - m.Echo(arg[0][1 : len(arg[0])-1]) - }}, "val": &ctx.Command{Name: "val exp", Help: "表达式运算", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { result := "false" // {{{ switch len(arg) { @@ -450,11 +441,22 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心", if info, e := os.Stat(arg[1]); e == nil && info.IsDir() { result = "true" } + case "+": + result = arg[1] + case "-": + result = arg[1] + if i, e := strconv.Atoi(arg[1]); e == nil { + result = fmt.Sprintf("%d", -i) + } } case 3: v1, e1 := strconv.Atoi(arg[0]) v2, e2 := strconv.Atoi(arg[2]) switch arg[1] { + case ":=": + if !m.Target().Has(arg[0]) { + result = m.Cap(arg[0], arg[0], arg[2], "临时变量") + } case "=": result = m.Cap(arg[0], arg[2]) case "+=": @@ -569,7 +571,7 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心", // }}} }}, "var": &ctx.Command{Name: "var a [= exp]", Help: "定义变量, a: 变量名, exp: 表达式", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { - if m.Cap(arg[1], arg[1], "", "临时变量"); len(arg) > 3 { // {{{ + if m.Cap(arg[1], arg[1], "", "临时变量"); len(arg) > 1 { // {{{ switch arg[2] { case "=": m.Cap(arg[1], arg[3]) @@ -607,9 +609,7 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心", m.Caps("parse", false) } else { frame := cli.stack[len(cli.stack)-2] - if frame.run { - m.Caps("parse", false) - } + m.Caps("parse", !frame.run) } } } // }}} @@ -622,8 +622,7 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心", } if cli.stack = cli.stack[:len(cli.stack)-1]; m.Capi("level", -1) > 0 { - frame := cli.stack[len(cli.stack)-1] - m.Caps("parse", frame.run) + m.Caps("parse", cli.stack[len(cli.stack)-1].run) } else { m.Caps("parse", true) } @@ -641,10 +640,8 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心", msg = cli.Message.Tree(code) run = run && msg != nil && msg.Meta != nil && len(msg.Meta[arg[3]]) > 0 } - } else if len(arg) > 3 { - run = run && ctx.Right(arg[3]) } else { - run = run && ctx.Right(arg[1]) + run = run && ctx.Right(arg[len(arg)-1]) } if len(cli.stack) > 0 { @@ -739,6 +736,9 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心", } // }}} }}, + "clear": &ctx.Command{Name: "clear", Help: "", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { + m.Log("fuck", strings.Repeat("\n", 20)) + }}, }, } diff --git a/src/contexts/ctx.go b/src/contexts/ctx.go index 50da02b7..5f7c38cd 100644 --- a/src/contexts/ctx.go +++ b/src/contexts/ctx.go @@ -181,7 +181,7 @@ func (c *Context) Start(m *Message, arg ...string) bool { // {{{ go m.TryCatch(m, true, func(m *Message) { m.Log(m.Cap("status", "start"), "%d server %v %v", m.root.Capi("nserver", 1), m.Meta["detail"], m.Meta["option"]) - c.exit = make(chan bool, 1) + c.exit = make(chan bool, 2) if running <- true; c.Server != nil && c.Server.Start(m, m.Meta["detail"]...) { c.Close(m, m.Meta["detail"]...) } @@ -191,15 +191,20 @@ func (c *Context) Start(m *Message, arg ...string) bool { // {{{ // }}} func (c *Context) Close(m *Message, arg ...string) bool { // {{{ + if len(c.requests) == 0 { + return true + } m.Log("close", "%d:%d %v", len(c.requests), len(c.sessions), arg) if m.target == c { for i := len(c.requests) - 1; i >= 0; i-- { if msg := c.requests[i]; msg.code == m.code { - if msg.source == c || c.Server == nil || c.Server.Close(m, arg...) { - for j := i + 1; j < len(c.requests)-1; j++ { + if c.Server == nil || c.Server.Close(m, arg...) { + for j := i; j < len(c.requests)-1; j++ { + m.Log("close", "requests: %v %s", j, c.requests[j].Format()) c.requests[j] = c.requests[j+1] } + c.requests = c.requests[:len(c.requests)-1] } } } @@ -212,7 +217,7 @@ func (c *Context) Close(m *Message, arg ...string) bool { // {{{ if m.Cap("status") == "start" { m.Log(m.Cap("status", "close"), "%d server %v", m.root.Capi("nserver", -1)+1, arg) for _, msg := range c.sessions { - if msg.target != c { + if msg.Cap("status") == "start" { msg.target.Close(msg, arg...) } } @@ -221,7 +226,7 @@ func (c *Context) Close(m *Message, arg ...string) bool { // {{{ if c.context != nil { m.Log("close", "%d context %v", m.root.Capi("ncontext", -1)+1, arg) delete(c.context.contexts, c.Name) - m.Wait() + c.exit <- true } return true } diff --git a/src/contexts/lex/lex.go b/src/contexts/lex/lex.go index ea4b8389..6d09372c 100644 --- a/src/contexts/lex/lex.go +++ b/src/contexts/lex/lex.go @@ -261,7 +261,7 @@ func (lex *LEX) parse(m *ctx.Message, page int, line []byte) (hash int, rest []b } if pos == len(line) { - hash, pos, word = -1, 0, word[:0] + // hash, pos, word = -1, 0, word[:0] } else if hash == 0 { pos, word = 0, word[:0] } diff --git a/src/contexts/nfs/nfs.go b/src/contexts/nfs/nfs.go index 0d89ba70..5bbb3dcd 100644 --- a/src/contexts/nfs/nfs.go +++ b/src/contexts/nfs/nfs.go @@ -791,10 +791,6 @@ func (nfs *NFS) Close(m *ctx.Message, arg ...string) bool { // {{{ nfs.io = nil } case m.Source(): - m.Source().Close(m.Spawn(m.Source())) - } - if m.Target() == Index { - return false } return true } diff --git a/src/contexts/yac/yac.go b/src/contexts/yac/yac.go index ad87704f..285d8c05 100644 --- a/src/contexts/yac/yac.go +++ b/src/contexts/yac/yac.go @@ -3,6 +3,7 @@ package yac // {{{ import ( // {{{ "contexts" "fmt" + "strconv" ) // }}} @@ -398,24 +399,38 @@ var Index = &ctx.Context{Name: "yac", Help: "语法中心", }}, "info": &ctx.Command{Name: "info", Help: "查看语法矩阵", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { if yac, ok := m.Target().Server.(*YAC); m.Assert(ok) { // {{{ - for i, v := range yac.seed { - m.Echo("seed: %d %v\n", i, v) - } - for i, v := range yac.page { - m.Echo("page: %s %d\n", i, v) - } - for i, v := range yac.hash { - m.Echo("hash: %s %d\n", i, v) - } - for i, v := range yac.state { - m.Echo("node: %v %v\n", i, v) - } - for i, v := range yac.mat { - for k, v := range v { - if v != nil { - m.Echo("node: %s(%d,%d): %v\n", yac.name(i), i, k, v) + if len(arg) == 0 { + for i, v := range yac.seed { + m.Echo("seed: %d %v\n", i, v) + } + for i, v := range yac.page { + m.Echo("page: %s %d\n", i, v) + } + for i, v := range yac.hash { + m.Echo("hash: %s %d\n", i, v) + } + for i, v := range yac.state { + m.Echo("node: %v %v\n", i, v) + } + for i, v := range yac.mat { + for k, v := range v { + if v != nil { + m.Echo("node: %s(%d,%d): %v\n", yac.name(i), i, k, v) + } } } + return + } + + line := yac.mat[yac.page[arg[0]]] + if i, e := strconv.Atoi(arg[0]); e == nil { + line = yac.mat[i] + } + + for i := 0; i < len(line); i++ { + if v, ok := line[byte(i)]; ok && v != nil { + m.Echo("(%s, %d): %v\n", arg[0], i, v) + } } } // }}}