mirror of
https://shylinux.com/x/icebergs
synced 2025-06-25 18:17:29 +08:00
opt yac
This commit is contained in:
parent
086c51d70c
commit
1bc212f7f8
@ -28,6 +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.Cmd(TIMER, HAPPEN)
|
||||
case s, ok := <-f.s:
|
||||
if !ok {
|
||||
|
@ -13,6 +13,7 @@ func _timer_action(m *ice.Message, now time.Time, arg ...string) {
|
||||
if value[mdb.COUNT] == "0" || value[mdb.TIME] > now.Format(ice.MOD_TIME) {
|
||||
return
|
||||
}
|
||||
m.Option(ice.LOG_DISABLE, ice.FALSE)
|
||||
m.Cmd(ROUTINE, mdb.CREATE, mdb.NAME, value[mdb.NAME], kit.Keycb(ROUTINE), value[ice.CMD])
|
||||
mdb.HashModify(m, mdb.HASH, value[mdb.HASH], mdb.COUNT, kit.Int(value[mdb.COUNT])-1, mdb.TIME, m.Time(value[INTERVAL]))
|
||||
})
|
||||
|
@ -25,17 +25,15 @@ func _split_tab(text string) (tab int) {
|
||||
func _split_deep(stack []int, text string) ([]int, int) {
|
||||
tab := _split_tab(text)
|
||||
for i := len(stack) - 1; i >= 0; i-- {
|
||||
if tab <= stack[i] {
|
||||
stack = stack[:len(stack)-1]
|
||||
}
|
||||
kit.If(tab <= stack[i], func() { stack = stack[:len(stack)-1] })
|
||||
}
|
||||
stack = append(stack, tab)
|
||||
return stack, len(stack)
|
||||
}
|
||||
func _split_list(m *ice.Message, file string, arg ...string) ice.Map {
|
||||
const DEEP = "_deep"
|
||||
stack, deep := []int{}, 0
|
||||
list, line := kit.List(kit.Data(DEEP, -1)), ""
|
||||
const INDENT = "_indent"
|
||||
stack, indent := []int{}, 0
|
||||
list, line := kit.List(kit.Data(INDENT, -1)), ""
|
||||
m.Cmd(nfs.CAT, file, func(text string) {
|
||||
if strings.TrimSpace(text) == "" {
|
||||
return
|
||||
@ -46,19 +44,19 @@ func _split_list(m *ice.Message, file string, arg ...string) ice.Map {
|
||||
if strings.HasPrefix(strings.TrimSpace(text), "# ") {
|
||||
return
|
||||
}
|
||||
stack, deep = _split_deep(stack, text)
|
||||
data := kit.Data(DEEP, deep)
|
||||
stack, indent = _split_deep(stack, text)
|
||||
data := kit.Data(INDENT, indent)
|
||||
ls := kit.Split(text, m.Option(SPLIT_SPACE), m.Option(SPLIT_BLOCK), m.Option(SPLIT_QUOTE), m.Option(SPLIT_TRANS))
|
||||
switch cb := m.OptionCB(SPLIT).(type) {
|
||||
case func(int, []string):
|
||||
cb(deep, ls)
|
||||
cb(indent, ls)
|
||||
case func(int, []string) []string:
|
||||
ls = cb(deep, ls)
|
||||
ls = cb(indent, ls)
|
||||
case func(int, []string, ice.Map, ice.Map):
|
||||
root, _ := kit.Value(list[0], "list.0").(ice.Map)
|
||||
cb(deep, ls, data, root)
|
||||
cb(indent, ls, data, root)
|
||||
case func(int, []string, ice.Map) []string:
|
||||
ls = cb(deep, ls, data)
|
||||
ls = cb(indent, ls, data)
|
||||
case func([]string, ice.Map) []string:
|
||||
ls = cb(ls, data)
|
||||
case func([]string) []string:
|
||||
@ -69,16 +67,13 @@ func _split_list(m *ice.Message, file string, arg ...string) ice.Map {
|
||||
default:
|
||||
m.ErrorNotImplement(cb)
|
||||
}
|
||||
for _, k := range arg {
|
||||
if kit.Value(data, kit.Keym(k), kit.Select("", ls, 0)); len(ls) > 0 {
|
||||
ls = ls[1:]
|
||||
}
|
||||
}
|
||||
for i := 0; i < len(ls)-1; i += 2 {
|
||||
kit.Value(data, kit.Keym(ls[i]), ls[i+1])
|
||||
}
|
||||
kit.For(arg, func(k string) {
|
||||
kit.Value(data, kit.Keym(k), kit.Select("", ls, 0))
|
||||
kit.If(len(ls) > 0, func() { ls = ls[1:] })
|
||||
})
|
||||
kit.For(ls, func(k, v string) { kit.Value(data, kit.Keym(k), v) })
|
||||
for i := len(list) - 1; i >= 0; i-- {
|
||||
if deep > kit.Int(kit.Value(list[i], kit.Keym(DEEP))) {
|
||||
if indent > kit.Int(kit.Value(list[i], kit.Keym(INDENT))) {
|
||||
kit.Value(list[i], kit.Keys(mdb.LIST, "-2"), data)
|
||||
list = append(list, data)
|
||||
break
|
||||
@ -109,6 +104,3 @@ func init() {
|
||||
}},
|
||||
})
|
||||
}
|
||||
func Split(m *ice.Message, arg ...string) ice.Map {
|
||||
return kit.Value(_split_list(m, arg[0], arg[1:]...), kit.Keys(mdb.LIST, "0")).(ice.Map)
|
||||
}
|
||||
|
@ -78,7 +78,6 @@ func _serve_handle(key string, cmd *ice.Command, m *ice.Message, w http.Response
|
||||
default:
|
||||
r.ParseMultipartForm(kit.Int64(kit.Select("4096", r.Header.Get(ContentLength))))
|
||||
kit.For(r.PostForm, func(k string, v []string) { _log(FORM, k, kit.Join(v, ice.SP)).Optionv(k, v) })
|
||||
kit.For(r.PostForm, func(k string, v []string) { _log(FORM, k, kit.Join(v, ice.SP)).Optionv(k, v) })
|
||||
}
|
||||
kit.For(r.Cookies(), func(k, v string) { m.Optionv(k, v) })
|
||||
m.OptionDefault(ice.MSG_HEIGHT, "480", ice.MSG_WIDTH, "320")
|
||||
|
247
base/yac/stack.go
Normal file
247
base/yac/stack.go
Normal file
@ -0,0 +1,247 @@
|
||||
package yac
|
||||
|
||||
import (
|
||||
"io"
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
ice "shylinux.com/x/icebergs"
|
||||
"shylinux.com/x/icebergs/base/nfs"
|
||||
kit "shylinux.com/x/toolkits"
|
||||
)
|
||||
|
||||
type Func struct {
|
||||
line int
|
||||
}
|
||||
type Frame struct {
|
||||
key string
|
||||
value ice.Map
|
||||
status int
|
||||
line int
|
||||
pop func()
|
||||
}
|
||||
type Stack struct {
|
||||
frame []*Frame
|
||||
last *Frame
|
||||
rest []string
|
||||
list []string
|
||||
line int
|
||||
}
|
||||
|
||||
func (s *Stack) peekf(m *ice.Message) *Frame { return s.frame[len(s.frame)-1] }
|
||||
func (s *Stack) pushf(m *ice.Message, key string) *Frame {
|
||||
f := &Frame{key: key, value: kit.Dict(), status: s.peekf(m).status, line: s.line}
|
||||
s.frame = append(s.frame, f)
|
||||
return f
|
||||
}
|
||||
func (s *Stack) popf(m *ice.Message) *Frame {
|
||||
f := s.frame[len(s.frame)-1]
|
||||
kit.If(len(s.frame) > 1, func() { s.frame = s.frame[:len(s.frame)-1] })
|
||||
return f
|
||||
}
|
||||
func (s *Stack) value(m *ice.Message, key string, arg ...ice.Any) ice.Any {
|
||||
for i := len(s.frame) - 1; i >= 0; i-- {
|
||||
if f := s.frame[i]; f.value[key] != nil {
|
||||
kit.If(len(arg) > 0, func() { f.value[key] = arg[0] })
|
||||
return f.value[key]
|
||||
}
|
||||
}
|
||||
f := s.frame[len(s.frame)-1]
|
||||
kit.If(len(arg) > 0, func() { f.value[key] = arg[0] })
|
||||
return f.value[key]
|
||||
}
|
||||
func (s *Stack) parse(m *ice.Message, p string) *Stack {
|
||||
nfs.Open(m, p, func(r io.Reader) {
|
||||
s.peekf(m).key = p
|
||||
kit.For(r, func(text string) {
|
||||
s.list = append(s.list, text)
|
||||
for s.line = len(s.list) - 1; s.line < len(s.list); s.line++ {
|
||||
if text = s.list[s.line]; text == "" || strings.HasPrefix(text, "#") {
|
||||
continue
|
||||
}
|
||||
for s.rest = kit.Split(text, "\t ", "<=>+-*/;"); len(s.rest) > 0; {
|
||||
ls := s.rest
|
||||
switch s.rest = []string{}; v := s.value(m, ls[0]).(type) {
|
||||
case *Func:
|
||||
f, line := s.pushf(m, ls[0]), s.line
|
||||
f.pop, s.line = func() { s.rest, s.line, _ = nil, line+1, s.popf(m) }, v.line
|
||||
default:
|
||||
if _, ok := m.Target().Commands[ls[0]]; ok {
|
||||
m.Options(STACK, s).Cmdy(ls)
|
||||
} else {
|
||||
m.Options(STACK, s).Cmdy(CMD, ls)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
return s
|
||||
}
|
||||
func (s *Stack) show(m *ice.Message) (res []string) {
|
||||
for i, l := range s.list {
|
||||
res = append(res, kit.Format("%2d: ", i)+l)
|
||||
}
|
||||
res = append(res, "")
|
||||
for i, f := range s.frame {
|
||||
res = append(res, kit.Format("frame: %v line: %v %v %v", i, f.line, f.key, f.status))
|
||||
kit.For(f.value, func(k string, v ice.Any) { res = append(res, kit.Format("frame: %v %v: %v", i, k, v)) })
|
||||
}
|
||||
return
|
||||
}
|
||||
func _parse_split(m *ice.Message, split string, arg ...string) ([]string, []string) {
|
||||
if i := kit.IndexOf(arg, split); i == -1 {
|
||||
return arg, nil
|
||||
} else {
|
||||
return arg[:i], arg[i+1:]
|
||||
}
|
||||
}
|
||||
func NewStack(m *ice.Message) *Stack { return &Stack{frame: []*Frame{&Frame{value: kit.Dict()}}} }
|
||||
|
||||
const (
|
||||
PARSE = "parse"
|
||||
CMD = "cmd"
|
||||
LET = "let"
|
||||
IF = "if"
|
||||
FOR = "for"
|
||||
FUNC = "func"
|
||||
TYPE = "type"
|
||||
RETURN = "return"
|
||||
EXPR = "expr"
|
||||
)
|
||||
const STACK = "stack"
|
||||
|
||||
func init() {
|
||||
Index.MergeCommands(ice.Commands{
|
||||
STACK: {Name: "stack path auto parse", Actions: ice.Actions{
|
||||
PARSE: {Hand: func(m *ice.Message, arg ...string) {}},
|
||||
}, Hand: func(m *ice.Message, arg ...string) {
|
||||
m.Options(nfs.DIR_ROOT, nfs.SRC).Cmdy(nfs.CAT, arg)
|
||||
if len(m.Result()) == 0 {
|
||||
return
|
||||
}
|
||||
m.Echo(ice.NL).Echo("output:" + ice.NL)
|
||||
s := NewStack(m).parse(m, path.Join(nfs.SRC, path.Join(arg...)))
|
||||
m.Echo(ice.NL).Echo("script:" + ice.NL)
|
||||
m.Echo(strings.Join(s.show(m), ice.NL))
|
||||
}},
|
||||
CMD: {Name: "cmd", Hand: func(m *ice.Message, arg ...string) {
|
||||
s := m.Optionv(STACK).(*Stack)
|
||||
arg, s.rest = _parse_split(m, "}", arg...)
|
||||
if f := s.peekf(m); f.status >= 0 {
|
||||
m.Cmdy(arg)
|
||||
m.Echo(ice.NL)
|
||||
}
|
||||
}},
|
||||
LET: {Name: "let a = 1", Hand: func(m *ice.Message, arg ...string) {
|
||||
s := m.Optionv(STACK).(*Stack)
|
||||
f := s.peekf(m)
|
||||
kit.If(f.status > -1, func() { s.value(m, arg[0], m.Cmdx(EXPR, arg[2:])) })
|
||||
}},
|
||||
IF: {Name: "if a > 1", Hand: func(m *ice.Message, arg ...string) {
|
||||
s := m.Optionv(STACK).(*Stack)
|
||||
f := s.pushf(m, m.CommandKey())
|
||||
arg, s.rest = _parse_split(m, "{", arg...)
|
||||
kit.If(f.status < 0 || m.Cmdx(EXPR, arg) == ice.FALSE, func() { f.status = -1 })
|
||||
}},
|
||||
FOR: {Name: "for a > 1", Hand: func(m *ice.Message, arg ...string) {
|
||||
s := m.Optionv(STACK).(*Stack)
|
||||
arg, s.rest = _parse_split(m, "{", arg...)
|
||||
f := s.pushf(m, m.CommandKey())
|
||||
kit.If(f.status < 0 || m.Cmdx(EXPR, arg) == ice.FALSE, func() { f.status = -1 })
|
||||
line := s.line
|
||||
f.pop = func() {
|
||||
kit.If(f.status > -1, func() { s.line = line - 1 })
|
||||
s.popf(m)
|
||||
}
|
||||
}},
|
||||
FUNC: {Name: "func show", Hand: func(m *ice.Message, arg ...string) {
|
||||
s := m.Optionv(STACK).(*Stack)
|
||||
arg, s.rest = _parse_split(m, "{", arg...)
|
||||
fun := &Func{line: s.line}
|
||||
s.value(m, arg[0], fun)
|
||||
f := s.pushf(m, m.CommandKey())
|
||||
f.status = -1
|
||||
}},
|
||||
RETURN: {Name: "return show", Hand: func(m *ice.Message, arg ...string) {
|
||||
s := m.Optionv(STACK).(*Stack)
|
||||
f := s.peekf(m)
|
||||
f.status = -2
|
||||
}},
|
||||
"}": {Name: "}", Hand: func(m *ice.Message, arg ...string) {
|
||||
s := m.Optionv(STACK).(*Stack)
|
||||
if f := s.peekf(m); f.pop == nil {
|
||||
s.last = s.peekf(m)
|
||||
s.popf(m)
|
||||
} else {
|
||||
f.pop()
|
||||
}
|
||||
}},
|
||||
EXPR: {Name: "expr a = 1", Hand: func(m *ice.Message, arg ...string) {
|
||||
s := m.Optionv(STACK).(*Stack)
|
||||
level := map[string]int{
|
||||
"*": 30, "/": 30,
|
||||
"+": 20, "-": 20,
|
||||
"<": 10, ">": 10, "<=": 10, ">=": 10, "==": 10, "!=": 10,
|
||||
}
|
||||
list := kit.List()
|
||||
get := func(p int) ice.Any {
|
||||
if p+len(list) >= 0 {
|
||||
return list[p+len(list)]
|
||||
}
|
||||
return ""
|
||||
}
|
||||
gets := func(p int) string {
|
||||
k := kit.Format(get(p))
|
||||
if v := s.value(m, k); v != nil {
|
||||
return kit.Format(v)
|
||||
}
|
||||
return k
|
||||
}
|
||||
getl := func(p int) int { return level[kit.Format(get(p))] }
|
||||
push := func(v ice.Any) { list = append(list, v) }
|
||||
pop := func(n int) { list = list[:len(list)-n] }
|
||||
ops := func() {
|
||||
bin := func(v ice.Any) {
|
||||
pop(3)
|
||||
push(kit.Format(v))
|
||||
}
|
||||
switch a, b := kit.Int(gets(-3)), kit.Int(gets(-1)); gets(-2) {
|
||||
case "==":
|
||||
bin(a == b)
|
||||
case "!=":
|
||||
bin(a != b)
|
||||
case "<=":
|
||||
bin(a <= b)
|
||||
case ">=":
|
||||
bin(a >= b)
|
||||
case ">":
|
||||
bin(a > b)
|
||||
case "<":
|
||||
bin(a < b)
|
||||
case "+":
|
||||
bin(a + b)
|
||||
case "-":
|
||||
bin(a - b)
|
||||
case "*":
|
||||
bin(a * b)
|
||||
case "/":
|
||||
bin(a / b)
|
||||
}
|
||||
}
|
||||
kit.For(arg, func(k string) {
|
||||
if level[k] > 0 {
|
||||
for level[k] <= getl(-2) {
|
||||
ops()
|
||||
}
|
||||
}
|
||||
push(k)
|
||||
})
|
||||
for len(list) > 1 {
|
||||
ops()
|
||||
}
|
||||
m.Echo(kit.Format(list[0]))
|
||||
m.Debug("expr %s", m.Result())
|
||||
}},
|
||||
})
|
||||
}
|
@ -6,4 +6,4 @@ const YAC = "yac"
|
||||
|
||||
var Index = &ice.Context{Name: YAC, Help: "语法模块"}
|
||||
|
||||
func init() { ice.Index.Register(Index, nil) }
|
||||
func init() { ice.Index.Register(Index, nil, STACK) }
|
||||
|
@ -9,6 +9,7 @@ import (
|
||||
"shylinux.com/x/icebergs/base/mdb"
|
||||
"shylinux.com/x/icebergs/base/nfs"
|
||||
"shylinux.com/x/icebergs/base/web"
|
||||
"shylinux.com/x/icebergs/base/yac"
|
||||
kit "shylinux.com/x/toolkits"
|
||||
)
|
||||
|
||||
@ -21,7 +22,7 @@ func init() {
|
||||
ctx.ProcessCommand(m, web.WIKI_WORD, kit.Simple(path.Join(arg[2], arg[1])))
|
||||
}},
|
||||
mdb.ENGINE: {Hand: func(m *ice.Message, arg ...string) {
|
||||
ctx.ProcessCommand(m, web.WIKI_WORD, kit.Simple(path.Join(arg[2], arg[1])))
|
||||
ctx.ProcessCommand(m, yac.STACK, kit.Simple(arg[1]))
|
||||
}},
|
||||
TEMPLATE: {Hand: func(m *ice.Message, arg ...string) {
|
||||
m.Echo(nfs.Template(m, "demo.shy"), path.Base(path.Dir(path.Join(arg[2], arg[1]))))
|
||||
|
9
misc/lex/lex.go
Normal file
9
misc/lex/lex.go
Normal file
@ -0,0 +1,9 @@
|
||||
package lex
|
||||
|
||||
import ice "shylinux.com/x/icebergs"
|
||||
|
||||
const LEX = "lex"
|
||||
|
||||
var Index = &ice.Context{Name: LEX, Help: "词法模块"}
|
||||
|
||||
func init() { ice.Index.Register(Index, nil, SPLIT) }
|
@ -437,75 +437,7 @@ func init() {
|
||||
})
|
||||
m.ProcessInner()
|
||||
}},
|
||||
"location": {Hand: func(m *ice.Message, arg ...string) {
|
||||
m.ProcessLocation("https://baidu.com")
|
||||
}},
|
||||
"replace": {Hand: func(m *ice.Message, arg ...string) {
|
||||
m.ProcessReplace("https://baidu.com")
|
||||
}},
|
||||
"history": {Hand: func(m *ice.Message, arg ...string) {
|
||||
m.ProcessHistory()
|
||||
}},
|
||||
"confirms": {Hand: func(m *ice.Message, arg ...string) {
|
||||
m.Option("hi", "hello")
|
||||
m.ProcessConfirm("hello world")
|
||||
}},
|
||||
"refresh": {Hand: func(m *ice.Message, arg ...string) {
|
||||
m.ProcessRefresh("3s")
|
||||
}},
|
||||
"rewrite": {Hand: func(m *ice.Message, arg ...string) {
|
||||
m.ProcessRewrite("hash", "1", "npage", "2")
|
||||
}},
|
||||
"display": {Hand: func(m *ice.Message, arg ...string) {
|
||||
m.Push("value", 1)
|
||||
m.Push("value", 2)
|
||||
m.ProcessDisplay("/plugin/story/pie.js")
|
||||
}},
|
||||
// "field": {Hand: func(m *ice.Message, arg ...string) {
|
||||
// m.ProcessCommand("cli.system", []string{"pwd"}, arg...)
|
||||
// }},
|
||||
"inner": {Hand: func(m *ice.Message, arg ...string) {
|
||||
m.Push("value", 1)
|
||||
m.Push("value", 2)
|
||||
m.Push("good", 2)
|
||||
m.Push("good", 2)
|
||||
m.ProcessInner()
|
||||
}},
|
||||
"hold": {Hand: func(m *ice.Message, arg ...string) {
|
||||
m.ProcessHold()
|
||||
}},
|
||||
"back": {Hand: func(m *ice.Message, arg ...string) {
|
||||
m.ProcessBack()
|
||||
}},
|
||||
"rich": {Hand: func(m *ice.Message, arg ...string) {
|
||||
m.Push("hi", "hello")
|
||||
m.Push("he", "world")
|
||||
m.Push("value", "good")
|
||||
m.ProcessRich("hello world\n")
|
||||
}},
|
||||
"grow": {Hand: func(m *ice.Message, arg ...string) {
|
||||
m.ProcessGrow("hello world\n")
|
||||
}},
|
||||
"open": {Hand: func(m *ice.Message, arg ...string) {
|
||||
m.ProcessOpen("https://baidu.com")
|
||||
}},
|
||||
}, Hand: func(m *ice.Message, arg ...string) {
|
||||
m.Action(
|
||||
"location", "replace", "history",
|
||||
"confirms", "refresh", "rewrite", "display", "field", "inner",
|
||||
"hold", "back", "rich", "grow", "open",
|
||||
"openLocation", "getLocation", "getClipboardData",
|
||||
)
|
||||
m.Push("hi", "hello")
|
||||
m.Push("he", "world")
|
||||
m.Push("value", "good")
|
||||
m.Echo("hello world")
|
||||
m.StatusTimeCount()
|
||||
m.EchoButton("clear")
|
||||
m.PushButton("close")
|
||||
m.EchoButton("upload")
|
||||
m.EchoButton("actions")
|
||||
return
|
||||
if m.Action(mdb.CREATE); len(arg) == 0 { // 矩阵列表
|
||||
m.Fields(len(arg), "time,hash,npage,nhash")
|
||||
m.Cmdy(mdb.SELECT, m.PrefixKey(), "", mdb.HASH)
|
11
misc/lex/regexp.go
Normal file
11
misc/lex/regexp.go
Normal file
@ -0,0 +1,11 @@
|
||||
package lex
|
||||
|
||||
const (
|
||||
PATTERN = "pattern"
|
||||
REGEXP = "regexp"
|
||||
PREFIX = "prefix"
|
||||
SUFFIX = "suffix"
|
||||
|
||||
SPACE = "space"
|
||||
OPERATOR = "operator"
|
||||
)
|
106
misc/lex/split.go
Normal file
106
misc/lex/split.go
Normal file
@ -0,0 +1,106 @@
|
||||
package lex
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
ice "shylinux.com/x/icebergs"
|
||||
"shylinux.com/x/icebergs/base/mdb"
|
||||
"shylinux.com/x/icebergs/base/nfs"
|
||||
kit "shylinux.com/x/toolkits"
|
||||
)
|
||||
|
||||
func _split_tab(text string) (tab int) {
|
||||
for _, c := range text {
|
||||
switch c {
|
||||
case '\t':
|
||||
tab += 4
|
||||
case ' ':
|
||||
tab++
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
func _split_deep(stack []int, text string) ([]int, int) {
|
||||
tab := _split_tab(text)
|
||||
for i := len(stack) - 1; i >= 0; i-- {
|
||||
kit.If(tab <= stack[i], func() { stack = stack[:len(stack)-1] })
|
||||
}
|
||||
stack = append(stack, tab)
|
||||
return stack, len(stack)
|
||||
}
|
||||
func _split_list(m *ice.Message, file string, arg ...string) ice.Map {
|
||||
const INDENT = "_indent"
|
||||
stack, indent := []int{}, 0
|
||||
list, line := kit.List(kit.Data(INDENT, -1)), ""
|
||||
m.Cmd(nfs.CAT, file, func(text string) {
|
||||
if strings.TrimSpace(text) == "" {
|
||||
return
|
||||
}
|
||||
if line += text; strings.Count(text, "`")%2 == 1 {
|
||||
return
|
||||
}
|
||||
if strings.HasPrefix(strings.TrimSpace(text), "# ") {
|
||||
return
|
||||
}
|
||||
stack, indent = _split_deep(stack, text)
|
||||
data := kit.Data(INDENT, indent)
|
||||
ls := kit.Split(text, m.Option(SPLIT_SPACE), m.Option(SPLIT_BLOCK), m.Option(SPLIT_QUOTE), m.Option(SPLIT_TRANS))
|
||||
switch cb := m.OptionCB(SPLIT).(type) {
|
||||
case func(int, []string):
|
||||
cb(indent, ls)
|
||||
case func(int, []string) []string:
|
||||
ls = cb(indent, ls)
|
||||
case func(int, []string, ice.Map, ice.Map):
|
||||
root, _ := kit.Value(list[0], "list.0").(ice.Map)
|
||||
cb(indent, ls, data, root)
|
||||
case func(int, []string, ice.Map) []string:
|
||||
ls = cb(indent, ls, data)
|
||||
case func([]string, ice.Map) []string:
|
||||
ls = cb(ls, data)
|
||||
case func([]string) []string:
|
||||
ls = cb(ls)
|
||||
case func([]string):
|
||||
cb(ls)
|
||||
case nil:
|
||||
default:
|
||||
m.ErrorNotImplement(cb)
|
||||
}
|
||||
kit.For(arg, func(k string) {
|
||||
kit.Value(data, kit.Keym(k), kit.Select("", ls, 0))
|
||||
kit.If(len(ls) > 0, func() { ls = ls[1:] })
|
||||
})
|
||||
kit.For(ls, func(k, v string) { kit.Value(data, kit.Keym(k), v) })
|
||||
for i := len(list) - 1; i >= 0; i-- {
|
||||
if indent > kit.Int(kit.Value(list[i], kit.Keym(INDENT))) {
|
||||
kit.Value(list[i], kit.Keys(mdb.LIST, "-2"), data)
|
||||
list = append(list, data)
|
||||
break
|
||||
}
|
||||
list = list[:len(list)-1]
|
||||
}
|
||||
line = ""
|
||||
})
|
||||
return list[0].(ice.Map)
|
||||
}
|
||||
|
||||
const (
|
||||
SPLIT_SPACE = "split.space"
|
||||
SPLIT_BLOCK = "split.block"
|
||||
SPLIT_QUOTE = "split.quote"
|
||||
SPLIT_TRANS = "split.trans"
|
||||
)
|
||||
const SPLIT = "split"
|
||||
|
||||
func init() {
|
||||
Index.MergeCommands(ice.Commands{
|
||||
SPLIT: {Name: "split path key auto", Help: "分词", Hand: func(m *ice.Message, arg ...string) {
|
||||
if len(arg) == 0 || strings.HasSuffix(arg[0], ice.PS) {
|
||||
m.Cmdy(nfs.DIR, arg)
|
||||
return
|
||||
}
|
||||
m.Echo(kit.Format(_split_list(m, arg[0], kit.Split(kit.Join(arg[1:]))...)))
|
||||
}},
|
||||
})
|
||||
}
|
9
misc/yac/yac.go
Normal file
9
misc/yac/yac.go
Normal file
@ -0,0 +1,9 @@
|
||||
package yac
|
||||
|
||||
import ice "shylinux.com/x/icebergs"
|
||||
|
||||
const YAC = "yac"
|
||||
|
||||
var Index = &ice.Context{Name: YAC, Help: "语法模块"}
|
||||
|
||||
func init() { ice.Index.Register(Index, nil) }
|
Loading…
x
Reference in New Issue
Block a user