yac

package
v2.1.0+incompatible Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 29, 2019 License: MIT Imports: 8 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var Index = &ctx.Context{Name: "yac", Help: "语法中心",
	Caches: map[string]*ctx.Cache{
		"nshy": &ctx.Cache{Name: "nshy", Value: "0", Help: "引擎数量"},
	},
	Configs: map[string]*ctx.Config{
		"nline": &ctx.Config{Name: "nline", Value: "line", Help: "默认页"},
		"nvoid": &ctx.Config{Name: "nvoid", Value: "void", Help: "默认值"},
		"meta": &ctx.Config{Name: "meta", Value: map[string]interface{}{
			"ncell": 128, "nlang": 64, "compact": true,
			"name": "shy%d", "help": "engine",
		}, Help: "初始参数"},
		"seed": &ctx.Config{Name: "seed", Value: []interface{}{
			map[string]interface{}{"page": "void", "hash": "void", "word": []interface{}{"[\t ]+"}},

			map[string]interface{}{"page": "num", "hash": "num", "word": []interface{}{"mul{", "0", "-?[1-9][0-9]*", "0[0-9]+", "0x[0-9]+", "}"}},
			map[string]interface{}{"page": "key", "hash": "key", "word": []interface{}{"[A-Za-z_][A-Za-z_0-9]*"}},
			map[string]interface{}{"page": "str", "hash": "str", "word": []interface{}{"mul{", "\"[^\"]*\"", "'[^']*'", "}"}},
			map[string]interface{}{"page": "exe", "hash": "exe", "word": []interface{}{"mul{", "$", "@", "}", "opt{", "key", "}"}},
			map[string]interface{}{"page": "exe", "hash": "exe", "word": []interface{}{"mul{", "$", "@", "}", "opt{", "num", "}"}},

			map[string]interface{}{"page": "op1", "hash": "op1", "word": []interface{}{"mul{", "-", "+", "}"}},
			map[string]interface{}{"page": "op2", "hash": "op2", "word": []interface{}{"mul{", "~", "!~", "}"}},
			map[string]interface{}{"page": "op2", "hash": "op2", "word": []interface{}{"mul{", "+", "-", "*", "/", "%", "}"}},
			map[string]interface{}{"page": "op2", "hash": "op2", "word": []interface{}{"mul{", "<", "<=", ">", ">=", "==", "!=", "}"}},
			map[string]interface{}{"page": "val", "hash": "val", "word": []interface{}{"opt{", "op1", "}", "mul{", "num", "key", "str", "exe", "}"}},
			map[string]interface{}{"page": "exp", "hash": "exp", "word": []interface{}{"val", "rep{", "op2", "val", "}"}},
			map[string]interface{}{"page": "stm", "hash": "return", "word": []interface{}{"return", "rep{", "exp", "}"}},

			map[string]interface{}{"page": "word", "hash": "word", "word": []interface{}{"mul{", "~", "!", "\\?", "\\?\\?", "exe", "str", "[\\-a-zA-Z0-9_:/.%*]+", "=", "<", ">$", ">@", ">", "\\|", "}"}},
			map[string]interface{}{"page": "cmd", "hash": "cmd", "word": []interface{}{"rep{", "word", "}"}},
			map[string]interface{}{"page": "com", "hash": "cmd", "word": []interface{}{"rep{", ";", "cmd", "}"}},
			map[string]interface{}{"page": "com", "hash": "com", "word": []interface{}{"mul{", "#[^\n]*\n?", "\n", "}"}},
			map[string]interface{}{"page": "line", "hash": "line", "word": []interface{}{"opt{", "mul{", "stm", "cmd", "}", "}", "com"}},

			map[string]interface{}{"page": "op1", "hash": "op1", "word": []interface{}{"mul{", "!", "}"}},
			map[string]interface{}{"page": "op2", "hash": "op2", "word": []interface{}{"mul{", "&&", "||", "}"}},
			map[string]interface{}{"page": "exe", "hash": "exe", "word": []interface{}{"(", "exp", ")"}},
			map[string]interface{}{"page": "exe", "hash": "exe", "word": []interface{}{"$", "(", "cmd", ")"}},
			map[string]interface{}{"page": "stm", "hash": "var", "word": []interface{}{"var", "key", "opt{", "=", "exp", "}"}},
			map[string]interface{}{"page": "stm", "hash": "let", "word": []interface{}{"let", "key", "opt{", "=", "exp", "}"}},
			map[string]interface{}{"page": "stm", "hash": "let", "word": []interface{}{"let", "key", "=", "\\[", "rep{", "exp", "}", "\\]"}},
			map[string]interface{}{"page": "stm", "hash": "let", "word": []interface{}{"let", "key", "=", "\\{", "rep{", "exp", "}", "\\}"}},
			map[string]interface{}{"page": "stm", "hash": "if", "word": []interface{}{"if", "exp"}},
			map[string]interface{}{"page": "stm", "hash": "for", "word": []interface{}{"for", "rep{", "key", "}"}},
			map[string]interface{}{"page": "stm", "hash": "for", "word": []interface{}{"for", "rep{", "exp", "}"}},
			map[string]interface{}{"page": "stm", "hash": "fun", "word": []interface{}{"fun", "key", "rep{", "exp", "}"}},
			map[string]interface{}{"page": "stm", "hash": "kit", "word": []interface{}{"kit", "rep{", "exp", "}"}},
			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"}},
		}, Help: "语法集合的最大数量"},
		"input": &ctx.Config{Name: "input", Value: map[string]interface{}{
			"text":     true,
			"select":   true,
			"button":   true,
			"upfile":   true,
			"textarea": true,
			"exports":  true,
			"feature":  true,
		}, Help: "控件类型"},
		"exec": &ctx.Config{Name: "info", Value: map[string]interface{}{
			"disable": map[string]interface{}{
				"void": true,
				"num":  true,
				"key":  true,
				"op1":  true,
				"op2":  true,
				"word": true,
				"line": true,
			},
			"always": map[string]interface{}{
				"if":   true,
				"else": true,
				"end":  true,
				"for":  true,
			},
		}, Help: "嵌套层级日志的标记"},

		"alias": &ctx.Config{Name: "alias", Value: map[string]interface{}{
			"~":  []string{"context"},
			"!":  []string{"message"},
			":":  []string{"command"},
			"::": []string{"command", "list"},

			"note":     []string{"mdb.note"},
			"pwd":      []string{"nfs.pwd"},
			"path":     []string{"nfs.path"},
			"dir":      []string{"nfs.dir"},
			"git":      []string{"nfs.git"},
			"brow":     []string{"web.brow"},
			"ifconfig": []string{"tcp.ifconfig"},
		}, Help: "启动脚本"},
	},
	Commands: map[string]*ctx.Command{
		"_init": &ctx.Command{Name: "_init", Help: "添加语法规则, page: 语法集合, hash: 语句类型, word: 语法模板", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
			if yac, ok := m.Target().Server.(*YAC); m.Assert(ok) {
				yac.lex = m.Cmd("lex.spawn")
				m.Confm("seed", func(line int, seed map[string]interface{}) {
					m.Spawn().Cmd("train", seed["page"], seed["hash"], seed["word"])
				})
			}
			return
		}},
		"train": &ctx.Command{Name: "train page hash word...", Help: "添加语法规则, page: 语法集合, hash: 语句类型, word: 语法模板", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
			if yac, ok := m.Target().Server.(*YAC); m.Assert(ok) {
				page := yac.index(m, "npage", arg[0])
				hash := yac.index(m, "nhash", arg[1])
				if yac.mat[page] == nil {
					yac.mat[page] = map[byte]*State{}
					for i := 0; i < m.Confi("meta", "nlang"); i++ {
						yac.mat[page][byte(i)] = nil
					}
				}
				yac.train(m, page, hash, arg[2:], 1)

				yac.seed = append(yac.seed, &Seed{page, hash, arg[2:]})
				m.Cap("stream", fmt.Sprintf("%d,%s,%s", m.Cap("nseed", len(yac.seed)),
					m.Cap("npage"), m.Cap("nhash", len(yac.hash)-1)))
			}
			return
		}},
		"parse": &ctx.Command{Name: "parse line", Help: "解析语句", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
			if yac, ok := m.Target().Server.(*YAC); m.Assert(ok) {
				stack, _ := m.Optionv("bio.stack").(*kit.Stack)
				m.Optioni("yac.page", yac.page[m.Conf("nline")])
				m.Optioni("yac.void", yac.page[m.Conf("nvoid")])

				_, word, _ := yac.parse(m, m, stack, m.Optioni("yac.page"), m.Optioni("yac.void"), []byte(arg[0]), 1)
				m.Result(word)
			}
			return
		}},
		"show": &ctx.Command{Name: "show seed|page|hash|mat", Help: "查看信息", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
			if yac, ok := m.Target().Server.(*YAC); m.Assert(ok) {
				if len(arg) == 0 {
					m.Push("seed", len(yac.seed))
					m.Push("page", len(yac.page))
					m.Push("hash", len(yac.hash))
					m.Push("nmat", len(yac.mat))
					m.Push("node", len(yac.state))
					m.Table()
					return
				}

				switch arg[0] {
				case "seed":
					for _, v := range yac.seed {
						m.Push("page", yac.hand[v.page])
						m.Push("word", strings.Replace(strings.Replace(fmt.Sprint(v.word), "\n", "\\n", -1), "\t", "\\t", -1))
						m.Push("hash", yac.word[v.hash])
					}
					m.Sort("page", "int").Table()

				case "page":
					for k, v := range yac.page {
						m.Add("append", "page", k)
						m.Add("append", "code", v)
					}
					m.Sort("code", "int").Table()

				case "hash":
					for k, v := range yac.hash {
						m.Add("append", "hash", k)
						m.Add("append", "code", v)
						m.Add("append", "hand", yac.hand[v])
					}
					m.Sort("code", "int").Table()

				case "node":
					for _, v := range yac.state {
						m.Push("star", v.star)
						m.Push("next", v.next)
						m.Push("hash", v.hash)
					}
					m.Table()

				case "mat":
					for i, v := range yac.mat {
						if i <= m.Capi("npage") {
							m.Push("index", yac.hand[i])
						} else if i < m.Confi("meta", "nlang") {
							continue
						} else {
							m.Push("index", i)
						}

						for j := byte(0); j < byte(m.Confi("meta", "ncell")); j++ {
							c := fmt.Sprintf("%d", j)
							if s := v[j]; s == nil {
								m.Push(c, "")
							} else {
								m.Push(c, fmt.Sprintf("%d,%d,%d", s.star, s.next, s.hash))
							}
						}
					}

					ncol := len(m.Meta["append"])
					nrow := len(m.Meta[m.Meta["append"][0]])
					for i := 0; i < ncol-1; i++ {
						for j := i + 1; j < ncol; j++ {
							same := true
							void := true
							for n := 0; n < nrow; n++ {
								if m.Meta[m.Meta["append"][i]][n] != "" {
									void = false
								}

								if m.Meta[m.Meta["append"][i]][n] != m.Meta[m.Meta["append"][j]][n] {
									same = false
									break
								}
							}

							if same {
								if !void {
									key = m.Meta["append"][i] + "," + m.Meta["append"][j]
									m.Meta[key] = m.Meta[m.Meta["append"][i]]
									m.Meta["append"][i] = key
								}

								for k := j; k < ncol-1; k++ {
									m.Meta["append"][k] = m.Meta["append"][k+1]
								}
								ncol--
								j--
							}
						}
					}
					m.Meta["append"] = m.Meta["append"][:ncol]
					m.Table()
				}
			}
			return
		}},

		"str": &ctx.Command{Name: "str word", Help: "解析字符串", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
			m.Echo(arg[0][1 : len(arg[0])-1])
			return
		}},
		"exe": &ctx.Command{Name: "exe $ ( cmd )", Help: "解析嵌套命令", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
			switch len(arg) {
			case 1:
				m.Echo(arg[0])
			case 2:
				bio := m.Optionv("bio.msg").(*ctx.Message)
				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
						}
					}

					if i, e := strconv.Atoi(arg[1]); e == nil {
						m.Echo(bio.Detail(i))
						break
					}

					m.Echo(kit.Select(msg.Cap(arg[1]), bio.Option(arg[1])))

				case "@":

					if stack, ok := m.Optionv("bio.stack").(*kit.Stack); ok {
						if v, ok := stack.Hash(arg[1]); ok {
							m.Echo("%v", v)
							break
						}
					}

					if i, e := strconv.Atoi(arg[1]); e == nil {
						m.Echo(bio.Detail(i))
						break
					}

					m.Echo(kit.Select(msg.Conf(arg[1]), bio.Option(arg[1])))

				default:
					m.Echo(arg[0]).Echo(arg[1])
				}
			default:
				switch arg[0] {
				case "$", "@":
					m.Result(0, arg[2:len(arg)-1])
				case "(":
					m.Echo(arg[1])
				}
			}
			return
		}},
		"val": &ctx.Command{Name: "val exp", Help: "表达式运算", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
			result := "false"
			switch len(arg) {
			case 0:
				result = ""
			case 1:
				result = arg[0]
			case 2:
				switch arg[0] {
				case "-z":
					if arg[1] == "" {
						result = "true"
					}
				case "-n":
					if arg[1] != "" {
						result = "true"
					}

				case "-e":
					if _, e := os.Stat(arg[1]); e == nil {
						result = "true"
					}
				case "-f":
					if info, e := os.Stat(arg[1]); e == nil && !info.IsDir() {
						result = "true"
					}
				case "-d":
					if info, e := os.Stat(arg[1]); e == nil && info.IsDir() {
						result = "true"
					}
				case "!":
					result = kit.Format(!kit.Right(arg[1]))
				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 "=":
					result = m.Cap(arg[0], arg[2])
				case "+=":
					if i, e := strconv.Atoi(m.Cap(arg[0])); e == nil && e2 == nil {
						result = m.Cap(arg[0], fmt.Sprintf("%d", v2+i))
					} else {
						result = m.Cap(arg[0], m.Cap(arg[0])+arg[2])
					}
				case "+":
					if e1 == nil && e2 == nil {
						result = fmt.Sprintf("%d", v1+v2)
					} else {
						result = arg[0] + arg[2]
					}
				case "-":
					if e1 == nil && e2 == nil {
						result = fmt.Sprintf("%d", v1-v2)
					} else {
						result = strings.Replace(arg[0], arg[2], "", -1)
					}
				case "*":
					result = arg[0]
					if e1 == nil && e2 == nil {
						result = fmt.Sprintf("%d", v1*v2)
					}
				case "/":
					result = arg[0]
					if e1 == nil && e2 == nil {
						result = fmt.Sprintf("%d", v1/v2)
					}
				case "%":
					result = arg[0]
					if e1 == nil && e2 == nil {
						result = fmt.Sprintf("%d", v1%v2)
					}

				case "<":
					if e1 == nil && e2 == nil {
						result = fmt.Sprintf("%t", v1 < v2)
					} else {
						result = fmt.Sprintf("%t", arg[0] < arg[2])
					}
				case "<=":
					if e1 == nil && e2 == nil {
						result = fmt.Sprintf("%t", v1 <= v2)
					} else {
						result = fmt.Sprintf("%t", arg[0] <= arg[2])
					}
				case ">":
					if e1 == nil && e2 == nil {
						result = fmt.Sprintf("%t", v1 > v2)
					} else {
						result = fmt.Sprintf("%t", arg[0] > arg[2])
					}
				case ">=":
					if e1 == nil && e2 == nil {
						result = fmt.Sprintf("%t", v1 >= v2)
					} else {
						result = fmt.Sprintf("%t", arg[0] >= arg[2])
					}
				case "==":
					if e1 == nil && e2 == nil {
						result = fmt.Sprintf("%t", v1 == v2)
					} else {
						result = fmt.Sprintf("%t", arg[0] == arg[2])
					}
				case "!=":
					if e1 == nil && e2 == nil {
						result = fmt.Sprintf("%t", v1 != v2)
					} else {
						result = fmt.Sprintf("%t", arg[0] != arg[2])
					}
				case "&&":
					if kit.Right(arg[0]) {
						result = arg[2]
					} else {
						result = arg[0]
					}
				case "||":
					if kit.Right(arg[0]) {
						result = arg[0]
					} else {
						result = arg[2]
					}

				case "~":
					if m, e := regexp.MatchString(arg[2], arg[0]); m && e == nil {
						result = "true"
					}
				case "!~":
					if m, e := regexp.MatchString(arg[2], arg[0]); !m || e != nil {
						result = "true"
					}
				}
			}
			m.Echo(result)

			return
		}},
		"exp": &ctx.Command{Name: "exp word", Help: "表达式运算", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
			if len(arg) > 0 && arg[0] == "{" {
				msg := m.Spawn()
				for i := 1; i < len(arg); i++ {
					key := arg[i]
					for i += 3; i < len(arg); i++ {
						if arg[i] == "]" {
							break
						}
						msg.Add("append", key, arg[i])
					}
				}
				m.Echo("%d", msg.Code())
				return
			}

			pre := map[string]int{
				"=":  -1,
				"||": 0,
				"==": 1, "~": 1,
				"+": 2, "-": 2,
				"*": 3, "/": 3, "%": 3,
			}
			num, op := []string{arg[0]}, []string{}

			for i := 1; i < len(arg); i += 2 {
				if len(op) > 0 && pre[op[len(op)-1]] >= pre[arg[i]] {
					num[len(op)-1] = m.Cmdx("yac.val", num[len(op)-1], op[len(op)-1], num[len(op)])
					num, op = num[:len(num)-1], op[:len(op)-1]
				}
				num, op = append(num, arg[i+1]), append(op, arg[i])
			}

			for i := len(op) - 1; i >= 0; i-- {
				num[i] = m.Cmdx("yac.val", num[i], op[i], num[i+1])
			}

			m.Echo("%s", num[0])
			return
		}},
		"return": &ctx.Command{Name: "return result...", Help: "结束脚本, result: 返回值", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
			m.Appends("bio.end", true)
			m.Result(arg[1:])
			return
		}},
		"com": &ctx.Command{Name: "com", Help: "解析注释", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
			return
		}},
		"cmd": &ctx.Command{Name: "cmd word", Help: "解析命令", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {

			detail := []string{}
			if alias, ok := m.Confv("alias", arg[0]).([]string); ok {
				detail, arg = append(detail, alias...), arg[1:]
			}
			detail = append(detail, arg...)

			target := m.Optionv("bio.ctx")
			if detail[0] != "context" {
				defer func() { m.Optionv("bio.ctx", target) }()
			}

			msg := m
			for k, v := range m.Confv("system", "script").(map[string]interface{}) {
				if strings.HasSuffix(detail[0], "."+k) {
					msg = m.Spawn(m.Optionv("bio.ctx"))
					detail[0] = m.Cmdx("nfs.path", detail[0])
					detail = append([]string{v.(string)}, detail...)
					break
				}
			}

			if msg == m {
				if routes := strings.Split(detail[0], "."); len(routes) > 1 && !strings.Contains(detail[0], ":") {
					route := strings.Join(routes[:len(routes)-1], ".")
					if msg = m.Find(route, false); msg == nil {
						msg = m.Find(route, true)
					}

					if msg == nil {
						m.Echo("%s not exist", route)
						return
					}
					detail[0] = routes[len(routes)-1]
				} else {
					msg = m.Spawn(m.Optionv("bio.ctx"))
				}
			}
			msg.Copy(m, "option").Copy(m, "append")

			args, rest := []string{}, []string{}
			exports := []map[string]string{}
			exec, execexec := true, false
			for i := 0; i < len(detail); i++ {
				switch detail[i] {
				case "?":
					if !kit.Right(detail[i+1]) {
						return
					}
					i++
				case "??":
					exec = false
					execexec = execexec || kit.Right(detail[i+1])
					i++
				case "<":
					m.Cmdy("nfs.import", detail[i+1])
					i++
				case ">":
					exports = append(exports, map[string]string{"file": detail[i+1]})
					i++
				case ">$":
					if i == len(detail)-2 {
						exports = append(exports, map[string]string{"cache": detail[i+1], "index": "result"})
						i += 1
						break
					}
					exports = append(exports, map[string]string{"cache": detail[i+1], "index": detail[i+2]})
					i += 2
				case ">@":
					if i == len(detail)-2 {
						exports = append(exports, map[string]string{"config": detail[i+1], "index": "result"})
						i += 1
						break
					}
					exports = append(exports, map[string]string{"config": detail[i+1], "index": detail[i+2]})
					i += 2
				case "|":
					detail, rest = detail[:i], detail[i+1:]
				case "%":
					rest = append(rest, "select")
					detail, rest = detail[:i], append(rest, detail[i+1:]...)
				default:
					args = append(args, detail[i])
				}
			}
			if !exec && !execexec {
				return
			}

			if msg.Set("detail", args).Cmd(); !msg.Hand {
				msg.Cmd("system", args)
			}
			if msg.Appends("bio.ctx1") {
				target = msg.Target()
			}

			if len(rest) > 0 {
				pipe := msg.Spawn()
				pipe.Copy(msg, "append").Copy(msg, "result").Cmd("cmd", rest)
				msg.Set("append").Copy(pipe, "append")
				msg.Set("result").Copy(pipe, "result")
			}

			for _, v := range exports {
				if v["file"] != "" {
					m.Sess("nfs").Copy(msg, "option").Copy(msg, "append").Copy(msg, "result").Cmd("export", v["file"])
					msg.Set("result")
				}
				if v["cache"] != "" {
					if v["index"] == "result" {
						m.Cap(v["cache"], strings.Join(msg.Meta["result"], ""))
					} else {
						m.Cap(v["cache"], msg.Append(v["index"]))
					}
				}
				if v["config"] != "" {
					if v["index"] == "result" {
						m.Conf(v["config"], strings.Join(msg.Meta["result"], ""))
					} else {
						m.Conf(v["config"], msg.Append(v["index"]))
					}
				}
			}

			m.Optionv("bio.ctx", msg.Target())
			m.Set("append").Copy(msg, "append")
			m.Set("result").Copy(msg, "result")
			return
		}},
		"alias": &ctx.Command{Name: "alias [short [long...]]|[delete short]|[import module [command [alias]]]",
			Help: "查看、定义或删除命令别名, short: 命令别名, long: 命令原名, delete: 删除别名, import导入模块所有命令",
			Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
				switch len(arg) {
				case 0:
					m.Cmdy("ctx.config", "alias")
				case 1:
					m.Cmdy("ctx.config", "alias", arg[0])
				default:
					switch arg[0] {
					case "delete":
						alias := m.Confm("alias")
						m.Echo("delete: %s %v\n", arg[1], alias[arg[1]])
						delete(alias, arg[1])
					case "import":
						msg := m.Find(arg[1], false)
						if msg == nil {
							msg = m.Find(arg[1], true)
						}
						if msg == nil {
							m.Echo("%s not exist", arg[1])
							return
						}

						module := msg.Cap("module")
						for k, _ := range msg.Target().Commands {
							if len(k) > 0 && k[0] == '/' {
								continue
							}

							if len(arg) == 2 {
								m.Confv("alias", k, []string{module + "." + k})
								m.Log("info", "import %s.%s", module, k)
								continue
							}

							if key := k; k == arg[2] {
								if len(arg) > 3 {
									key = arg[3]
								}
								m.Confv("alias", key, []string{module + "." + k})
								m.Log("info", "import %s.%s as %s", module, k, key)
								break
							}
						}
					default:
						m.Confv("alias", arg[0], arg[1:])
						m.Log("info", "%s: %v", arg[0], arg[1:])
					}
				}
				return
			}},

		"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 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]
			}
			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) {
			if stack, ok := m.Optionv("bio.stack").(*kit.Stack); ok {
				switch arg[3] {
				case "[":
					list := []interface{}{}
					for i := 4; i < len(arg)-1; i++ {
						list = append(list, arg[i])
					}
					m.Log("stack", "%v = %v", arg[1], list)
					stack.Hash(arg[1], list)

				case "{":
					list := map[string]interface{}{}
					for i := 4; i < len(arg)-2; i += 2 {
						list[arg[i]] = arg[i+1]
					}
					m.Log("stack", "%v = %v", arg[1], list)
					stack.Hash(arg[1], list)

				default:
					m.Log("stack", "%v = %v", arg[1], arg[3])
					stack.Hash(arg[1], arg[3])
				}
			}
			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)
			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 !o.Run || p.Run {
				p.Done = true
			}
			return
		}},
		"for": &ctx.Command{Name: "for exp | for index val... in list", Help: "循环语句",
			Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
				stack := m.Optionv("bio.stack").(*kit.Stack)
				m.Log("stack", "push %v", stack.Push(arg[0], stack.Peek().Run && kit.Right(arg[1]), m.Optioni("stack.pos")).String("\\"))

				val, _ := stack.Hash(arg[len(arg)-1])
				index := kit.Int(stack.FS[len(stack.FS)-2].Hash["_index"])
				switch val := val.(type) {
				case map[string]interface{}:
					list := make([]string, 0, len(val))
					for k, _ := range val {
						list = append(list, k)
					}
					sort.Strings(list)

					if index < len(list) {
						stack.Hash(arg[1], list[index])
					}
					stack.Peek().Run = false
					for i, j := 2, index; i < len(arg)-2 && j < len(list); i, j = i+1, j+1 {
						stack.Peek().Run = true
						stack.Hash(arg[i], val[list[j]])
						stack.FS[len(stack.FS)-2].Hash["_index"] = j + 1
					}

				case []interface{}:
					stack.Hash(arg[1], index)
					stack.Peek().Run = false
					for i, j := 2, index; i < len(arg)-2 && j < len(val); i, j = i+1, j+1 {
						stack.Peek().Run = true
						stack.Hash(arg[i], val[j])
						stack.FS[len(stack.FS)-2].Hash["_index"] = j + 1
					}
				default:
				}
				if !stack.Peek().Run {
					stack.FS[len(stack.FS)-2].Hash["_index"] = 0
				}
				return
			}},
		"fun": &ctx.Command{Name: "fun name help", Help: "小函数", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
			p := m.Optionv("bio.stack").(*kit.Stack).Push(arg[0], false, m.Optioni("stack.pos"))
			m.Log("stack", "push %v", p.String("\\"))

			if len(arg) > 2 {
				m.Cmd("kit", "kit", arg[1:])
			}
			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, nil)
				m.Log("time", "parse: %v", m.Format("cost"))
				return
			}
			m.Target().Commands[arg[1]] = self
			m.Log("info", "fun: %v %v", arg[1], arg)
			p.Data = self
			return
		}},
		"kit": &ctx.Command{Name: "kit name help [init [view]] [public|protected|private] cmd arg... [input value [key val]...]...", Help: "小功能", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
			m.Log("info", "_index: %v", arg)

			args := []interface{}{}
			inputs := []interface{}{}
			exports := []interface{}{}
			feature := map[string]interface{}{}

			init, view, right, cmd := "", "", "", ""
			begin := 3

			switch arg[3] {
			case "private", "protected", "public":
				begin, right, cmd = 5, arg[3], arg[4]
			default:
				switch arg[4] {
				case "private", "protected", "public":
					begin, init, right, cmd = 6, arg[3], arg[4], arg[5]
				default:
					begin, init, view, right, cmd = 7, arg[3], arg[4], arg[5], arg[6]
				}
			}

			if m.Confs("input", cmd) {
				cmd, begin = arg[1], begin-1
			}

			for i := begin; i < len(arg); i++ {
				if !m.Confs("input", arg[i]) {
					args = append(args, arg[i])
					continue
				}
				for j := i; j < len(arg); j++ {
					if j < len(arg)-1 && !m.Confs("input", arg[j+1]) {
						continue
					}
					args := arg[i : j+1]
					if arg[i] == "feature" {
						feature[arg[i+1]] = arg[i+2]

					} else if arg[i] == "exports" {
						for k := 1; k < len(args); k += 1 {
							exports = append(exports, args[k])
						}
					} else {
						input := map[string]interface{}{
							"type":  kit.Select("", args, 0),
							"value": kit.Select("", args, 1),
						}
						for k := 2; k < len(args)-1; k += 2 {
							switch val := input[args[k]].(type) {
							case nil:
								input[args[k]] = args[k+1]
							case string:
								input[args[k]] = []interface{}{input[args[k]], args[k+1]}
							case []interface{}:
								input[args[k]] = append(val, args[k+1])
							}
						}
						inputs = append(inputs, input)
					}
					i = j
					break
				}
			}

			if len(inputs) == 0 {
				inputs = []interface{}{
					map[string]interface{}{"type": "text", "name": "arg"},
					map[string]interface{}{"type": "button", "value": "执行"},
				}
			}

			m.Confv("_index", []interface{}{-2}, map[string]interface{}{
				"name": kit.Select("", arg, 1),
				"help": kit.Select("", arg, 2),
				"view": view,
				"init": init,
				"type": right,

				"ctx":     m.Cap("module"),
				"cmd":     cmd,
				"args":    args,
				"inputs":  inputs,
				"exports": exports,
				"feature": feature,
			})
			return
		}},
		"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: %v", p.String("|"))
			if p.Run {
				p.Done = true
			}
			return
		}},
		"end": &ctx.Command{Name: "end", Help: "结束语句", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
			p := m.Optionv("bio.stack").(*kit.Stack).Pop()
			m.Log("stack", "pop: %v", p.String("/"))
			switch p.Key {
			case "for":
				if p.Run {
					m.Appendi("bio.pos0", p.Pos)
				}
			case "fun":
				end := m.Optioni("stack.pos")
				self := p.Data.(*ctx.Command)
				help := []string{}
				for i, v := range m.Optionv("bio.input").([]string) {
					if p.Pos < i && i < end {
						help = append(help, v)
					}
				}
				self.Help = help
			}

			return
		}},

		"label": &ctx.Command{Name: "label name", Help: "记录当前脚本的位置, name: 位置名", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
			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) {
			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
		}},
	},
}

Functions

This section is empty.

Types

type Parser

type Parser interface {
	Parse(m *ctx.Message, line []byte, page string) (hash int, rest []byte, word []byte)
}

type Point

type Point struct {
	// contains filtered or unexported fields
}

type Seed

type Seed struct {
	// contains filtered or unexported fields
}

type State

type State struct {
	// contains filtered or unexported fields
}

type YAC

type YAC struct {
	*ctx.Context
	// contains filtered or unexported fields
}

func (*YAC) Begin

func (yac *YAC) Begin(m *ctx.Message, arg ...string) ctx.Server

func (*YAC) Close

func (yac *YAC) Close(m *ctx.Message, arg ...string) bool

func (*YAC) Spawn

func (yac *YAC) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server

func (*YAC) Start

func (yac *YAC) Start(m *ctx.Message, arg ...string) (close bool)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL