forked from x/icebergs
opt stack
This commit is contained in:
parent
1545b142fd
commit
6e08e29b54
@ -9,10 +9,6 @@ const CTX = "ctx"
|
||||
|
||||
var Index = &ice.Context{Name: CTX, Help: "标准模块"}
|
||||
|
||||
func init() {
|
||||
ice.Index.Register(Index, nil, CONTEXT, COMMAND, CONFIG)
|
||||
ice.Info.Stack[Prefix()] = func(m *ice.Message, key string, arg ...ice.Any) ice.Any {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
func init() { ice.Index.Register(Index, nil, CONTEXT, COMMAND, CONFIG) }
|
||||
|
||||
func Prefix(arg ...string) string { return kit.Keys(CTX, arg) }
|
||||
|
@ -201,12 +201,15 @@ func Relative(m *ice.Message, p string) string {
|
||||
return p
|
||||
}
|
||||
func SplitPath(m *ice.Message, p string) []string {
|
||||
line := kit.Select("1", strings.Split(p, ice.DF), 1)
|
||||
p = strings.TrimPrefix(p, kit.Path("")+ice.PS)
|
||||
p = strings.Split(p, ice.DF)[0]
|
||||
if ls := kit.Split(kit.Select(ice.SRC_MAIN_GO, p), ice.PS); len(ls) == 1 {
|
||||
return []string{PWD, ls[0]}
|
||||
return []string{PWD, ls[0], line}
|
||||
} else if ls[0] == ice.USR {
|
||||
return []string{strings.Join(ls[:2], ice.PS) + ice.PS, strings.Join(ls[2:], ice.PS)}
|
||||
return []string{strings.Join(ls[:2], ice.PS) + ice.PS, strings.Join(ls[2:], ice.PS), line}
|
||||
} else {
|
||||
return []string{strings.Join(ls[:1], ice.PS) + ice.PS, strings.Join(ls[1:], ice.PS)}
|
||||
return []string{strings.Join(ls[:1], ice.PS) + ice.PS, strings.Join(ls[1:], ice.PS), line}
|
||||
}
|
||||
}
|
||||
func Dir(m *ice.Message, field string) *ice.Message {
|
||||
|
@ -88,9 +88,7 @@ func IsLocalHost(m *ice.Message, ip string) bool { return m.Cmdx(HOST, I
|
||||
func PublishLocalhost(m *ice.Message, url string) string { return m.Cmdx(HOST, PUBLISH, url) }
|
||||
|
||||
func init() {
|
||||
ice.Info.Stack[Prefix()] = func(m *ice.Message, key string, arg ...ice.Any) ice.Any {
|
||||
switch key {
|
||||
case kit.FuncName(IsLocalHost):
|
||||
ice.Info.Stack[Prefix(IsLocalHost)] = func(m *ice.Message, key string, arg ...ice.Any) ice.Any {
|
||||
for _, v := range arg {
|
||||
switch v := v.(type) {
|
||||
case *ice.Message:
|
||||
@ -100,9 +98,5 @@ func init() {
|
||||
}
|
||||
}
|
||||
return false
|
||||
default:
|
||||
m.ErrorNotImplement(key)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -11,4 +11,4 @@ var Index = &ice.Context{Name: TCP, Help: "通信模块"}
|
||||
|
||||
func init() { ice.Index.Register(Index, nil, HOST, PORT, CLIENT, SERVER) }
|
||||
|
||||
func Prefix(arg ...string) string { return kit.Keys(TCP, kit.Keys(arg)) }
|
||||
func Prefix(arg ...ice.Any) string { return kit.Keys(TCP, kit.Keys(arg...)) }
|
||||
|
184
base/yac/expr.go
184
base/yac/expr.go
@ -26,16 +26,15 @@ const (
|
||||
END = "}"
|
||||
)
|
||||
|
||||
var keyword = regexp.MustCompile(`[_a-zA-Z][_a-zA-Z0-9\.]*`)
|
||||
|
||||
var level = map[string]int{
|
||||
"//": 200, "/*": 200, "*/": 200,
|
||||
"&": 100, // "*": 100, "!": 100,
|
||||
"!": 100, "&": 100, // "*": 100,
|
||||
"[": 100, "]": 100, "++": 100, "--": 100,
|
||||
"*": 40, "/": 40, "+": 30, "-": 30,
|
||||
"<": 20, ">": 20, ">=": 20, "<=": 20, "!=": 20, "==": 20, "&&": 10, "||": 10,
|
||||
DEFS: 2, DEFINE: 2, ASSIGN: 2, FIELD: 2, OPEN: 1, CLOSE: 1,
|
||||
}
|
||||
var keyword = regexp.MustCompile(`^[_a-zA-Z.][_a-zA-Z0-9.]*$`)
|
||||
|
||||
type Expr struct {
|
||||
list ice.List
|
||||
@ -90,6 +89,15 @@ func (s *Expr) setv(m *ice.Message, p int, op string, v Any) Any {
|
||||
return s.value(m, k, v, op)
|
||||
}
|
||||
}
|
||||
func (s *Expr) isop(k Any) bool {
|
||||
switch k := k.(type) {
|
||||
case int:
|
||||
return level[s.gets(k)] > 0
|
||||
case string:
|
||||
return level[k] > 0
|
||||
}
|
||||
return false
|
||||
}
|
||||
func (s *Expr) opv(m *ice.Message, p int, op string, v Any) Any {
|
||||
if !s.runable() {
|
||||
return s.getv(m, p)
|
||||
@ -103,7 +111,7 @@ func (s *Expr) ops(m *ice.Message) {
|
||||
if !s.runable() || s.getl(-2) < 10 {
|
||||
return
|
||||
}
|
||||
s.pops(3, s.opv(m, -3, s.gets(-2), s.getv(m, -1)))
|
||||
s.pops(3, s.opv(m, -3, s.gets(-2), s.get(-1)))
|
||||
}
|
||||
func (s *Expr) end(m *ice.Message) Any {
|
||||
if !s.runable() || len(s.list) == 0 {
|
||||
@ -122,14 +130,14 @@ func (s *Expr) end(m *ice.Message) Any {
|
||||
}
|
||||
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)))
|
||||
s.list = append(s.list[:0], s.setv(m, -3, s.gets(-2), s.get(-1)))
|
||||
}
|
||||
case FIELD:
|
||||
list := kit.List()
|
||||
for i := len(s.list) - 2; i > 0; i -= 2 {
|
||||
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)))
|
||||
list = append(list, s.setv(m, j, s.gets(i), s.get(j+i+1)))
|
||||
}
|
||||
s.list = append(s.list[:0], Value{list})
|
||||
break
|
||||
@ -145,49 +153,41 @@ func (s *Expr) end(m *ice.Message) Any {
|
||||
}
|
||||
return s.getv(m, 0)
|
||||
}
|
||||
func (s *Expr) isop(k Any) bool {
|
||||
switch k := k.(type) {
|
||||
case int:
|
||||
return level[s.gets(k)] > 0
|
||||
case string:
|
||||
return level[k] > 0
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (s *Expr) sub(m *ice.Message) *Expr {
|
||||
sub := NewExpr(s.Stack)
|
||||
sub.n = s.n + 1
|
||||
return sub
|
||||
}
|
||||
func (s *Expr) ktv(m *ice.Message, ismap bool, t Any, p string) map[string]Any {
|
||||
func (s *Expr) ktv(m *ice.Message, t Any, p string) map[string]Any {
|
||||
var kt, vt Any
|
||||
switch t := t.(type) {
|
||||
case Map:
|
||||
kt, vt = s.types(m, t.key, p), s.types(m, t.value, p)
|
||||
}
|
||||
data := kit.Dict()
|
||||
for s.token() != END {
|
||||
k := ""
|
||||
kit.If(ismap, func() {
|
||||
kit.If(t == nil || kt != nil, func() {
|
||||
sub := s.sub(m)
|
||||
if k = kit.Format(Trans(sub.cals(m, DEFS, END))); k == "" {
|
||||
k = _parse_const(m, sub.gets(0))
|
||||
}
|
||||
sub.t, sub.p = kt, p
|
||||
k = kit.Format(Trans(sub.cals(m, DEFS, END)))
|
||||
}, func() {
|
||||
k = s.next(m)
|
||||
kit.If(s.token() != END, func() { s.next(m) })
|
||||
})
|
||||
kit.If(s.token() == DEFS, func() {
|
||||
sub := s.sub(m)
|
||||
if sub.p = p; ismap {
|
||||
sub.t = t
|
||||
if sub.p = p; t == nil || kt != nil {
|
||||
sub.t = vt
|
||||
} else {
|
||||
switch t := t.(type) {
|
||||
case Struct:
|
||||
if field, ok := t.index[k].(Field); ok {
|
||||
sub.t = field.kind
|
||||
sub.t = t.index[k].(Field)
|
||||
}
|
||||
}
|
||||
}
|
||||
m.Debug("field %d %#v %#v", sub.n, k, sub.t)
|
||||
m.Debug("field %d %s %s", sub.n, k, Format(sub.t))
|
||||
data[k] = sub.cals(m, FIELD, END)
|
||||
m.Debug("field %d %#v %#v", sub.n, k, data[k])
|
||||
m.Debug("field %d %s %s", sub.n, k, Format(data[k]))
|
||||
})
|
||||
}
|
||||
return data
|
||||
@ -197,8 +197,9 @@ func (s *Expr) ntv(m *ice.Message, t Any, p string) []Any {
|
||||
for !kit.IsIn(s.token(), SUPS, END) {
|
||||
sub := s.sub(m)
|
||||
sub.t, sub.p = t, p
|
||||
m.Debug("field %d %d %s", sub.n, len(data), Format(sub.t))
|
||||
if v := sub.cals(m, FIELD, SUPS, END); v != nil {
|
||||
m.Debug("field %d %d %#v", sub.n, len(data), v)
|
||||
m.Debug("field %d %d %s", sub.n, len(data), Format(v))
|
||||
data = append(data, v)
|
||||
}
|
||||
}
|
||||
@ -222,7 +223,6 @@ func (s *Expr) cals(m *ice.Message, arg ...string) Any {
|
||||
if kit.IsIn(k, arg...) {
|
||||
return true
|
||||
}
|
||||
m.Debug("what %v", k)
|
||||
switch k {
|
||||
case SPLIT:
|
||||
return true
|
||||
@ -231,28 +231,28 @@ func (s *Expr) cals(m *ice.Message, arg ...string) Any {
|
||||
kit.If(strings.Contains(s.gets(-1), ice.PT), func() { p = kit.Split(s.gets(-1), ice.PT)[0] })
|
||||
switch t := s.getv(m, -1).(type) {
|
||||
case Map:
|
||||
s.pops(1, Dict{s.ktv(m, true, s.value(m, kit.Keys(p, t.value)), p)})
|
||||
s.pops(1, Dict{s.ktv(m, t, p)})
|
||||
return false
|
||||
case Slice:
|
||||
s.pops(1, List{s.ntv(m, t, p)})
|
||||
return false
|
||||
case Struct:
|
||||
s.pops(1, Object{Dict{s.ktv(m, false, t, p)}, t})
|
||||
s.pops(1, Object{Dict{s.ktv(m, t, p)}, t})
|
||||
return false
|
||||
}
|
||||
switch t := s.t.(type) {
|
||||
case Map:
|
||||
s.pops(0, Dict{s.ktv(m, true, s.value(m, kit.Keys(s.p, t.value)), s.p)})
|
||||
s.pops(0, Dict{s.ktv(m, t.value, s.p)})
|
||||
return false
|
||||
case Slice:
|
||||
s.pops(0, List{s.ntv(m, t, s.p)})
|
||||
return false
|
||||
case Struct:
|
||||
s.pops(0, Object{Dict{s.ktv(m, false, t, s.p)}, t})
|
||||
s.pops(0, Object{Dict{s.ktv(m, t, s.p)}, t})
|
||||
return false
|
||||
}
|
||||
if kit.IsIn(s.gets(-1), DEFINE) || len(s.list) == 0 && len(arg) > 0 {
|
||||
s.pops(0, Dict{s.ktv(m, true, nil, "")})
|
||||
s.pops(0, Dict{s.ktv(m, s.t, s.p)})
|
||||
return false
|
||||
}
|
||||
return true
|
||||
@ -260,42 +260,23 @@ func (s *Expr) cals(m *ice.Message, arg ...string) Any {
|
||||
s.skip--
|
||||
return true
|
||||
case MAP:
|
||||
s.next(m)
|
||||
key := s.next(m)
|
||||
s.next(m)
|
||||
value := s.next(m)
|
||||
v := Map{key: key, value: value}
|
||||
name := kit.Format("map[%s]%s", v.key, v.value)
|
||||
s.value(m, name, v)
|
||||
s.push(name)
|
||||
s.push(s.Stack.types(m))
|
||||
return false
|
||||
case SUBS:
|
||||
if s.peek(m) == SUPS {
|
||||
pos := s.Position
|
||||
if s.next(m); !s.isop(s.peek(m)) {
|
||||
v := Slice{value: s.next(m)}
|
||||
name := kit.Format("[]%s", v.value)
|
||||
s.value(m, name, v)
|
||||
s.push(name)
|
||||
if s.peek(m) == SUPS && !kit.IsIn(kit.Select("", s.rest, s.skip+2), FIELD, SUPS, END, "") {
|
||||
s.push(s.Stack.types(m))
|
||||
return false
|
||||
}
|
||||
s.Position = pos
|
||||
}
|
||||
if kit.IsIn(s.gets(-1), DEFINE) || len(s.list) == 0 && len(arg) > 0 {
|
||||
s.push(List{s.ntv(m, nil, "")})
|
||||
s.push(List{s.ntv(m, s.t, s.p)})
|
||||
return false
|
||||
}
|
||||
case STRUCT, INTERFACE:
|
||||
s.skip--
|
||||
name := s.show()
|
||||
s.rest[s.skip] = name
|
||||
s.skip--
|
||||
m.Cmd(TYPE)
|
||||
s.push(name)
|
||||
s.push(s.Stack.types(m))
|
||||
return false
|
||||
case FUNC:
|
||||
if s.isop(-1) || len(s.list) == 0 {
|
||||
s.push(s.value(m, s.funcs(m)))
|
||||
if s.skip > 0 {
|
||||
s.push(s.funcs(m, ""))
|
||||
return false
|
||||
}
|
||||
s.skip--
|
||||
@ -309,33 +290,51 @@ func (s *Expr) cals(m *ice.Message, arg ...string) Any {
|
||||
}
|
||||
if len(s.list) > 0 && !s.isop(-1) {
|
||||
switch k {
|
||||
case OPEN:
|
||||
if strings.HasSuffix(s.gets(-1), ice.PT) {
|
||||
if s.peek(m) == TYPE {
|
||||
switch v := s.getv(m, -1).(type) {
|
||||
case Object:
|
||||
s.pops(1, v.index)
|
||||
default:
|
||||
s.pops(1, kit.Format("%T", v))
|
||||
}
|
||||
} else {
|
||||
switch t := s.sub(m).cals(m, CLOSE).(type) {
|
||||
case Struct:
|
||||
if v, ok := s.get(-1).(Operater); ok {
|
||||
s.pops(1, Value{list: []Any{v, v.Operate(INSTANCEOF, t)}})
|
||||
}
|
||||
case Interface:
|
||||
if v, ok := s.get(-1).(Operater); ok {
|
||||
s.pops(1, Value{list: []Any{v, v.Operate(IMPLEMENTS, t)}})
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
switch k := s.get(-1).(type) {
|
||||
case string:
|
||||
s.pops(1, s.call(m, s.Stack, k))
|
||||
default:
|
||||
s.pops(1, s.call(m, k, ""))
|
||||
}
|
||||
return false
|
||||
case SUBS:
|
||||
switch v := s.sub(m).cals(m, SUPS); s.get(-1).(type) {
|
||||
case string:
|
||||
m.Debug("what %v %v", s.gets(-1), Trans(v))
|
||||
s.pops(1, kit.Keys(s.gets(-1), kit.Format(Trans(v))))
|
||||
default:
|
||||
m.Debug("what %v %v", s.get(-1), v)
|
||||
s.pops(1, s.opv(m, -1, SUBS, v))
|
||||
}
|
||||
return false
|
||||
case OPEN:
|
||||
switch k := s.get(-1).(type) {
|
||||
case string:
|
||||
m.Debug("call %v", k)
|
||||
s.pops(1, s.call(m, s.Stack, k))
|
||||
default:
|
||||
m.Debug("call %v", k)
|
||||
s.pops(1, s.call(m, k, ""))
|
||||
}
|
||||
return false
|
||||
case "++", "--":
|
||||
s.pops(1, s.setv(m, -1, ASSIGN, s.opv(m, -1, k, nil)))
|
||||
return false
|
||||
}
|
||||
if !s.isop(k) {
|
||||
if strings.HasPrefix(k, ice.PT) {
|
||||
if kit.Select("", s.rest, s.skip+1) == OPEN {
|
||||
if s.peek(m) == OPEN {
|
||||
s.skip++
|
||||
s.pops(1, s.call(m, s.getv(m, -1), strings.TrimPrefix(k, ice.PT)))
|
||||
return false
|
||||
@ -360,7 +359,6 @@ func (s *Expr) cals(m *ice.Message, arg ...string) Any {
|
||||
}
|
||||
return false
|
||||
})
|
||||
m.Debug("what %v", s.list)
|
||||
if s.cmds(m, line) {
|
||||
return nil
|
||||
}
|
||||
@ -379,31 +377,31 @@ func (s *Expr) trans(m *ice.Message, k string) Any {
|
||||
return Number{value: k}
|
||||
}
|
||||
}
|
||||
func (s *Expr) types(m *ice.Message, t Any, p string) Any {
|
||||
switch t := t.(type) {
|
||||
case string:
|
||||
if p == "" || kit.IsIn(t, STRING, INT) {
|
||||
return t
|
||||
}
|
||||
return s.value(m, kit.Keys(p, t))
|
||||
default:
|
||||
return t
|
||||
}
|
||||
}
|
||||
func (s *Expr) cmds(m *ice.Message, line int) (done bool) {
|
||||
if len(s.list) == 1 && s.skip < 2 {
|
||||
m.Search(s.gets(0), func(key string, cmd *ice.Command) {
|
||||
args := kit.List(s.gets(0))
|
||||
for done = true; s.line == line; {
|
||||
sub := s.sub(m)
|
||||
switch sub.cals(m); v := sub.get(0).(type) {
|
||||
case string:
|
||||
if _v := s.value(m, v); _v != nil {
|
||||
args = append(args, kit.Format(Trans(_v)))
|
||||
} else {
|
||||
args = append(args, v)
|
||||
args = append(args, kit.Format(Trans(s.sub(m).cals(m))))
|
||||
}
|
||||
default:
|
||||
args = append(args, kit.Format(Trans(v)))
|
||||
}
|
||||
}
|
||||
m.Cmdy(args...)
|
||||
kit.If(s.runable(), func() { m.Cmdy(args...) })
|
||||
})
|
||||
}
|
||||
return
|
||||
}
|
||||
func (s *Expr) call(m *ice.Message, obj Any, key string) Any {
|
||||
v := s.sub(m).cals(m, CLOSE)
|
||||
if arg := _parse_res(m, v); s.runable() {
|
||||
if arg := _parse_res(m, s.sub(m).cals(m, CLOSE)); s.runable() {
|
||||
return s.calls(m, obj, key, nil, arg...)
|
||||
} else {
|
||||
return nil
|
||||
@ -417,16 +415,16 @@ func init() {
|
||||
Index.MergeCommands(ice.Commands{
|
||||
EXPR: {Name: "expr a, b = 1, 2", Hand: func(m *ice.Message, arg ...string) {
|
||||
s := _parse_stack(m)
|
||||
if arg, v := s.rest, s.cals(m); !s.runable() {
|
||||
if v := s.cals(m); !s.runable() {
|
||||
return
|
||||
} else if v != nil {
|
||||
m.Debug("value %#v <- %v", v, arg)
|
||||
m.Debug("value %s %s <- %v", Format(s), Format(v), arg)
|
||||
switch v := Trans(v).(type) {
|
||||
case Message:
|
||||
case Value:
|
||||
kit.If(len(v.list) > 0, func() { m.Echo(kit.Format(v.list[0])) })
|
||||
kit.If(len(v.list) > 0, func() { m.Echo(kit.Format(Trans(v.list[0]))) })
|
||||
default:
|
||||
m.Echo(kit.Format(v))
|
||||
m.Echo(kit.Format(Trans(v)))
|
||||
}
|
||||
} else if s.token() == BEGIN {
|
||||
m.Echo(ice.TRUE)
|
||||
|
@ -28,8 +28,8 @@ func init() {
|
||||
s, f := _parse_frame(m)
|
||||
defer s.popf(m)
|
||||
kit.For(u.Query(), func(k string, v []string) { f.value[k] = v[0] })
|
||||
sub := s.parse(m, p, r)
|
||||
kit.If(pre != "_", func() { kit.For(sub.peekf().value, func(k string, v Any) { s.frame[0].value[kit.Keys(pre, k)] = v }) })
|
||||
s.parse(m, p, r)
|
||||
kit.If(pre != "_", func() { kit.For(f.value, func(k string, v Any) { s.frame[0].value[kit.Keys(pre, k)] = v }) })
|
||||
}
|
||||
}
|
||||
find := func(pre, url string) {
|
||||
|
@ -8,11 +8,15 @@ import (
|
||||
"strings"
|
||||
|
||||
ice "shylinux.com/x/icebergs"
|
||||
"shylinux.com/x/icebergs/base/ctx"
|
||||
"shylinux.com/x/icebergs/base/mdb"
|
||||
"shylinux.com/x/icebergs/base/nfs"
|
||||
kit "shylinux.com/x/toolkits"
|
||||
)
|
||||
|
||||
type Value struct {
|
||||
list []Any
|
||||
}
|
||||
type Function struct {
|
||||
obj []Field
|
||||
arg []Field
|
||||
@ -20,8 +24,10 @@ type Function struct {
|
||||
Position
|
||||
object Object
|
||||
}
|
||||
|
||||
type Frame struct {
|
||||
key string
|
||||
name string
|
||||
value ice.Map
|
||||
defers []func()
|
||||
status int
|
||||
@ -30,6 +36,7 @@ type Frame struct {
|
||||
type Stack struct {
|
||||
last *Frame
|
||||
frame []*Frame
|
||||
comment []string
|
||||
Position
|
||||
}
|
||||
type Position struct {
|
||||
@ -45,11 +52,11 @@ type Buffer struct {
|
||||
}
|
||||
|
||||
func (s *Stack) peekf() *Frame { return s.frame[len(s.frame)-1] }
|
||||
func (s *Stack) pushf(m *ice.Message, key string) *Frame {
|
||||
f := &Frame{key: kit.Select(m.CommandKey(), key), value: kit.Dict(), Position: s.Position}
|
||||
func (s *Stack) pushf(m *ice.Message, arg ...string) *Frame {
|
||||
f := &Frame{key: kit.Select(m.CommandKey(), arg, 0), name: kit.Select("", arg, 1), value: kit.Dict(), Position: s.Position}
|
||||
kit.If(len(s.frame) > 0, func() { f.status = s.peekf().status })
|
||||
m.Debug("stack %d push %s %s", len(s.frame), f.key, s.show())
|
||||
s.frame = append(s.frame, f)
|
||||
m.Debug("stack %s push %s", Format(s), kit.Select(s.show(), arg, 2))
|
||||
return f
|
||||
}
|
||||
func (s *Stack) popf(m *ice.Message) *Frame {
|
||||
@ -57,7 +64,7 @@ func (s *Stack) popf(m *ice.Message) *Frame {
|
||||
for i := len(f.defers) - 1; i >= 0; i-- {
|
||||
f.defers[i]()
|
||||
}
|
||||
m.Debug("stack %d pop %s %s", len(s.frame)-1, f.key, s.show())
|
||||
m.Debug("stack %s pop %s", Format(s), s.show())
|
||||
kit.If(len(s.frame) > 0, func() { s.frame = s.frame[:len(s.frame)-1] })
|
||||
s.last = f
|
||||
return f
|
||||
@ -70,25 +77,28 @@ func (s *Stack) stack(cb func(*Frame, int) bool) {
|
||||
}
|
||||
}
|
||||
func (s *Stack) value(m *ice.Message, key string, arg ...Any) Any {
|
||||
keys := strings.Split(key, ice.PT)
|
||||
f, n := s.peekf(), len(s.frame)-1
|
||||
if len(arg) < 2 || arg[1] != DEFINE {
|
||||
s.stack(func(_f *Frame, i int) bool {
|
||||
if _f.value[key] != nil {
|
||||
if _f.value[key] != nil || _f.value[keys[0]] != nil {
|
||||
f, n = _f, i
|
||||
return true
|
||||
}
|
||||
return false
|
||||
})
|
||||
}
|
||||
keys := strings.Split(key, ice.PT)
|
||||
kit.If(strings.Contains(key, ice.PS), func() { keys = []string{key} })
|
||||
kit.If(len(arg) > 0, func() {
|
||||
if f.value[key] != nil {
|
||||
f.value[key] = arg[0]
|
||||
return
|
||||
}
|
||||
var v Any = Dict{f.value}
|
||||
for i := 0; i < len(keys); i++ {
|
||||
switch k := keys[i]; _v := v.(type) {
|
||||
case Operater:
|
||||
if i == len(keys)-1 {
|
||||
m.Debug("value %d:%s set %v %#v", n, f.key, key, arg[0])
|
||||
m.Debug("value %d:%s set %s %s", n, f.key, key, Format(arg[0]))
|
||||
_v.Operate(k, arg[0])
|
||||
} else {
|
||||
if v = _v.Operate(SUBS, k); v == nil {
|
||||
@ -104,53 +114,30 @@ func (s *Stack) value(m *ice.Message, key string, arg ...Any) Any {
|
||||
}
|
||||
}
|
||||
})
|
||||
v, ok := f.value[key]
|
||||
if ok {
|
||||
return v
|
||||
} else {
|
||||
if s.stack(func(_f *Frame, i int) bool {
|
||||
v, ok = _f.value[key]
|
||||
return ok
|
||||
}); ok {
|
||||
if v, ok := f.value[key]; ok {
|
||||
return v
|
||||
}
|
||||
}
|
||||
v = s
|
||||
var v Any = Dict{f.value}
|
||||
kit.For(keys, func(k string) {
|
||||
m.Debug("what %#v %v", v, k)
|
||||
switch _v := v.(type) {
|
||||
case Operater:
|
||||
v = _v.Operate(SUBS, k)
|
||||
case *Stack:
|
||||
v = nil
|
||||
_v.stack(func(_f *Frame, i int) bool {
|
||||
v, ok = _f.value[k]
|
||||
return ok
|
||||
})
|
||||
default:
|
||||
v = nil
|
||||
}
|
||||
})
|
||||
if v != nil {
|
||||
return v
|
||||
} else if v = _parse_const(m, key); v != "" {
|
||||
return v
|
||||
}
|
||||
return _parse_const(m, key)
|
||||
return nil
|
||||
}
|
||||
func (s *Stack) runable() bool { return s.peekf().status > STATUS_DISABLE }
|
||||
func (s *Stack) token() string { return kit.Select("", s.rest, s.skip) }
|
||||
func (s *Stack) show() string {
|
||||
if s.Buffer == nil {
|
||||
return ""
|
||||
} else if s.skip == -1 {
|
||||
return kit.Format("%s:%d", s.name, s.line+1)
|
||||
} else {
|
||||
return kit.Format("%s:%d:%d", s.name, s.line+1, s.skip)
|
||||
}
|
||||
}
|
||||
func (s *Stack) show() string { return Format(s.Position) }
|
||||
func (s *Stack) read(m *ice.Message) (text string, ok bool) {
|
||||
isvoid := func(text string) bool {
|
||||
return strings.TrimSpace(text) == "" || strings.HasPrefix(strings.TrimSpace(text), "#")
|
||||
}
|
||||
isvoid := func(text string) bool { return strings.TrimSpace(text) == "" }
|
||||
for s.line++; s.line < len(s.list); s.line++ {
|
||||
if isvoid(s.list[s.line]) {
|
||||
continue
|
||||
@ -169,9 +156,10 @@ func (s *Stack) read(m *ice.Message) (text string, ok bool) {
|
||||
}
|
||||
func (s *Stack) reads(m *ice.Message, cb func(k string) bool) {
|
||||
block, last := []string{}, 0
|
||||
comment := false
|
||||
for {
|
||||
if s.skip++; s.skip < len(s.rest) {
|
||||
if k := s.rest[s.skip]; k == "`" {
|
||||
if k, v := s.rest[s.skip], kit.Select("", s.rest, s.skip+1); k == "`" {
|
||||
if len(block) > 0 {
|
||||
kit.If(s.line != last, func() { block, last = append(block, ice.NL), s.line })
|
||||
block = append(block, k)
|
||||
@ -180,18 +168,27 @@ func (s *Stack) reads(m *ice.Message, cb func(k string) bool) {
|
||||
} else {
|
||||
block = append(block, k)
|
||||
}
|
||||
continue
|
||||
} else if len(block) > 0 {
|
||||
kit.If(s.line != last, func() { block, last = append(block, ice.NL), s.line })
|
||||
block = append(block, k)
|
||||
continue
|
||||
}
|
||||
if s.rest[s.skip] == ice.PS && kit.Select("", s.rest, s.skip+1) == ice.PS {
|
||||
} else if k == "*" && v == ice.PS {
|
||||
comment = false
|
||||
s.skip++
|
||||
} else if comment {
|
||||
|
||||
} else if k == ice.PS && v == "*" {
|
||||
comment = true
|
||||
s.skip++
|
||||
} else if k == ice.PS && v == ice.PS {
|
||||
s.comment = append(s.comment, s.list[s.line])
|
||||
s.skip = len(s.rest)
|
||||
continue
|
||||
}
|
||||
if cb(s.rest[s.skip]) {
|
||||
} else if s.skip == 0 && strings.HasPrefix(k, "#") {
|
||||
s.comment = append(s.comment, s.list[s.line])
|
||||
s.skip = len(s.rest)
|
||||
} else if cb(s.rest[s.skip]) {
|
||||
break
|
||||
} else {
|
||||
s.comment = s.comment[:0]
|
||||
}
|
||||
} else if text, ok := s.read(m); ok {
|
||||
s.rest, s.skip = kit.Split(text, SPACE, BLOCK, QUOTE, TRANS, ice.TRUE), -1
|
||||
@ -235,9 +232,9 @@ func (s *Stack) run(m *ice.Message) {
|
||||
m.Cmdy(k, kit.Slice(s.rest, s.skip+1))
|
||||
} else {
|
||||
if s.skip--; s.skip == -1 {
|
||||
m.Cmd(EXPR, s.rest, ice.SP, s.show())
|
||||
m.Cmd(EXPR, s.rest)
|
||||
} else {
|
||||
m.Cmd(EXPR, kit.Slice(s.rest, s.skip), ice.SP, s.show())
|
||||
m.Cmd(EXPR, kit.Slice(s.rest, s.skip))
|
||||
}
|
||||
}
|
||||
return false
|
||||
@ -259,7 +256,6 @@ func (s *Stack) cals0(m *ice.Message, arg ...string) string {
|
||||
func (s *Stack) types(m *ice.Message) Any {
|
||||
for ; s.skip < len(s.rest); s.skip++ {
|
||||
switch s.token() {
|
||||
case "*":
|
||||
case MAP:
|
||||
s.skip += 2
|
||||
key := s.types(m)
|
||||
@ -276,8 +272,10 @@ func (s *Stack) types(m *ice.Message) Any {
|
||||
}
|
||||
types := s.types(m)
|
||||
kit.For(key, func(key string) {
|
||||
field := Field{key, types}
|
||||
t.field = append(t.field, field)
|
||||
field := Field{types, map[string]string{}, key}
|
||||
if strings.HasSuffix(s.list[s.line], "`") {
|
||||
kit.For(kit.Split(kit.Select("", kit.Split(s.list[s.line]), -1), ": "), func(k, v string) { field.tags[k] = v })
|
||||
}
|
||||
t.index[key] = field
|
||||
})
|
||||
key, s.skip = key[:0], len(s.rest)
|
||||
@ -287,90 +285,70 @@ func (s *Stack) types(m *ice.Message) Any {
|
||||
t := Interface{index: map[string]Function{}}
|
||||
for s.next(m); s.next(m) != END; {
|
||||
name := s.token()
|
||||
field, list := Field{}, [][]Field{}
|
||||
for s.skip++; s.skip < len(s.rest); s.skip++ {
|
||||
switch s.token() {
|
||||
case OPEN:
|
||||
list = append(list, []Field{})
|
||||
case "*":
|
||||
case FIELD, CLOSE:
|
||||
list[len(list)-1] = append(list[len(list)-1], field)
|
||||
field = Field{}
|
||||
default:
|
||||
switch t := s.types(m).(type) {
|
||||
case string:
|
||||
kit.If(field.name == "", func() { field.name = t }, func() { field.kind = t })
|
||||
default:
|
||||
field.kind = s.types(m)
|
||||
}
|
||||
}
|
||||
}
|
||||
kit.If(len(list) == 1, func() { list = append(list, []Field{}) })
|
||||
t.index[name] = Function{arg: list[0], res: list[1]}
|
||||
s.skip = len(s.rest)
|
||||
s.rest[s.skip] = FUNC
|
||||
t.index[name] = s.types(m).(Function)
|
||||
}
|
||||
return t
|
||||
case FUNC:
|
||||
field, list := Field{}, [][]Field{}
|
||||
for s.skip++; s.skip < len(s.rest); s.skip++ {
|
||||
for s.skip++; s.skip < len(s.rest) && s.token() != BEGIN; s.skip++ {
|
||||
switch s.token() {
|
||||
case OPEN:
|
||||
list = append(list, []Field{})
|
||||
case "*":
|
||||
case FIELD, CLOSE:
|
||||
list[len(list)-1] = append(list[len(list)-1], field)
|
||||
field = Field{}
|
||||
case "*":
|
||||
default:
|
||||
switch t := s.types(m).(type) {
|
||||
case string:
|
||||
kit.If(field.name == "", func() { field.name = t }, func() { field.kind = t })
|
||||
kit.If(field.name == "", func() { field.name = t }, func() { field.types = t })
|
||||
default:
|
||||
field.kind = s.types(m)
|
||||
field.types = s.types(m)
|
||||
}
|
||||
}
|
||||
}
|
||||
kit.If(len(list) == 1, func() { list = append(list, []Field{}) })
|
||||
return Function{arg: list[0], res: list[1]}
|
||||
case "*":
|
||||
default:
|
||||
// if t := s.value(m, s.token()); t != nil && t != "" {
|
||||
// return t
|
||||
// }
|
||||
return s.token()
|
||||
}
|
||||
}
|
||||
return ""
|
||||
return nil
|
||||
}
|
||||
func (s *Stack) funcs(m *ice.Message) string {
|
||||
name := s.show()
|
||||
s.rest[s.skip], s.skip = name, s.skip-1
|
||||
m.Cmd(FUNC, name)
|
||||
f := s.peekf()
|
||||
status := f.status
|
||||
defer func() { f.status = status }()
|
||||
func (s *Stack) funcs(m *ice.Message, name string) Function {
|
||||
v := s.types(m).(Function)
|
||||
if f := s.pushf(m, FUNC, name); name == INIT {
|
||||
f.key = CALL
|
||||
} else {
|
||||
f.status = STATUS_DISABLE
|
||||
s.run(m)
|
||||
return name
|
||||
}
|
||||
func (s *Stack) calls(m *ice.Message, obj Any, key Any, cb func(*Frame, Function), arg ...Any) Any {
|
||||
m.Debug("stack %d call %T %s %#v", len(s.frame)-1, obj, key, arg)
|
||||
if _k, ok := key.(string); ok && _k != "" {
|
||||
kit.For(kit.Split(_k, ice.PT), func(k string) {
|
||||
v.Position = s.Position
|
||||
s.run(m)
|
||||
return v
|
||||
}
|
||||
func (s *Stack) calls(m *ice.Message, obj Any, key string, cb func(*Frame, Function), arg ...Any) Any {
|
||||
m.Debug("calls %s %T %s(%s)", Format(s), obj, key, Format(arg...))
|
||||
switch v := obj.(type) {
|
||||
case *Stack:
|
||||
if _v := v.value(m, key); _v != nil {
|
||||
obj, key = _v, ""
|
||||
}
|
||||
}
|
||||
kit.For(kit.Split(key, ice.PT), func(k string) {
|
||||
switch v := obj.(type) {
|
||||
case Operater:
|
||||
obj = v.Operate(SUBS, k)
|
||||
obj, key = v.Operate(SUBS, k), strings.TrimPrefix(strings.TrimPrefix(key, k), ice.PT)
|
||||
case *Stack:
|
||||
if _v := v.value(m, _k); _v != nil && _v != "" {
|
||||
obj, key = _v, ""
|
||||
} else {
|
||||
obj, key = v.value(m, k), strings.TrimPrefix(_k, k+ice.PT)
|
||||
}
|
||||
obj, key = v.value(m, k), strings.TrimPrefix(strings.TrimPrefix(key, k), ice.PT)
|
||||
}
|
||||
})
|
||||
}
|
||||
switch obj := obj.(type) {
|
||||
case Function:
|
||||
m.Debug("stack %d call %T %s %#v", len(s.frame)-1, obj, kit.Select("", obj.obj, -1), arg)
|
||||
f := s.pushf(m, CALL)
|
||||
name := kit.Format("%s%s", kit.Select("", kit.Format("%s.", obj.obj[0].types), len(obj.obj) > 1), obj.obj[len(obj.obj)-1].name)
|
||||
m.Debug("calls %s %s(%s) %s", Format(s), name, Format(arg...), Format(obj.Position))
|
||||
f := s.pushf(m, CALL, name, Format(obj.Position))
|
||||
for _, field := range obj.res {
|
||||
f.value[field.name] = nil
|
||||
}
|
||||
@ -397,15 +375,15 @@ func (s *Stack) calls(m *ice.Message, obj Any, key Any, cb func(*Frame, Function
|
||||
s.Position = pos
|
||||
})
|
||||
kit.If(cb != nil, func() { cb(f, obj) })
|
||||
s.run(m.Options(ice.YAC_STACK, s))
|
||||
s.run(m)
|
||||
return value
|
||||
case Caller:
|
||||
m.Debug("stack %d call %T %s %#v", len(s.frame)-1, obj, key, arg)
|
||||
kit.For(arg, func(i int, v Any) { arg[i] = Trans(arg[i]) })
|
||||
m.Debug("calls %s %s.%s(%s)", Format(s), Format(obj), key, Format(arg...))
|
||||
return wrap(obj.Call(kit.Format(key), arg...))
|
||||
case func(*ice.Message, string, ...Any) Any:
|
||||
m.Debug("stack %d call %s %s %#v", len(s.frame)-1, kit.FileLine(obj, 3), key, arg)
|
||||
kit.For(arg, func(i int, v Any) { arg[i] = Trans(arg[i]) })
|
||||
m.Debug("calls %s %s %s %s", Format(s), Format(obj), key, Format(arg...))
|
||||
return wrap(obj(m, kit.Format(key), arg...))
|
||||
case func():
|
||||
obj()
|
||||
@ -414,18 +392,13 @@ func (s *Stack) calls(m *ice.Message, obj Any, key Any, cb func(*Frame, Function
|
||||
if key == "" {
|
||||
return nil
|
||||
}
|
||||
m.Debug("stack %d call %T %s %#v", len(s.frame)-1, obj, key, arg)
|
||||
args := kit.List(key)
|
||||
kit.For(arg, func(i int, v Any) { args = append(args, Trans(v)) })
|
||||
m.Debug("calls %s %s", Format(s), Format(args...))
|
||||
return Message{m.Cmd(args...)}
|
||||
}
|
||||
}
|
||||
func (s *Stack) Handler(obj Any) ice.Handler {
|
||||
return func(m *ice.Message, arg ...string) {
|
||||
m.Copy(s.Action(m.Spawn(Index).Spawn(m.Target()), obj, nil, arg...))
|
||||
}
|
||||
}
|
||||
func (s *Stack) Action(m *ice.Message, obj Any, key Any, arg ...string) *ice.Message {
|
||||
func (s *Stack) Action(m *ice.Message, obj Any, key string, arg ...string) *ice.Message {
|
||||
s.calls(m, obj, key, func(f *Frame, v Function) {
|
||||
i := 0
|
||||
for _, field := range v.arg {
|
||||
@ -443,18 +416,23 @@ func (s *Stack) Action(m *ice.Message, obj Any, key Any, arg ...string) *ice.Mes
|
||||
})
|
||||
return m
|
||||
}
|
||||
func (s *Stack) Handler(obj Any) ice.Handler {
|
||||
return func(m *ice.Message, arg ...string) {
|
||||
m.Copy(s.Action(m.Options(ice.YAC_STACK, s).Spawn(Index).Spawn(m.Target()), obj, "", arg...))
|
||||
}
|
||||
}
|
||||
func (s *Stack) parse(m *ice.Message, name string, r io.Reader) *Stack {
|
||||
pos := s.Position
|
||||
defer func() { s.Position = pos }()
|
||||
s.Position = Position{Buffer: &Buffer{name: name, input: bufio.NewScanner(r)}}
|
||||
s.peekf().Position = s.Position
|
||||
m.Debug("stack %d parse %s", len(s.frame)-1, s.show())
|
||||
m.Debug("stack %s parse %s", Format(s), s.show())
|
||||
s.run(m)
|
||||
return s
|
||||
}
|
||||
func NewStack(m *ice.Message, cb func(*Frame)) *Stack {
|
||||
func NewStack(m *ice.Message, cb func(*Frame), arg ...string) *Stack {
|
||||
s := &Stack{}
|
||||
s.pushf(m.Options(ice.YAC_STACK, s), STACK)
|
||||
s.pushf(m.Options(ice.YAC_STACK, s), kit.Simple(STACK, arg)...)
|
||||
s.load(m, cb)
|
||||
return s
|
||||
}
|
||||
@ -490,17 +468,17 @@ const STACK = "stack"
|
||||
|
||||
func init() {
|
||||
Index.MergeCommands(ice.Commands{
|
||||
STACK: {Name: "stack path auto parse", Actions: ice.Actions{
|
||||
STACK: {Name: "stack path auto parse", Actions: ice.MergeActions(ice.Actions{
|
||||
"start": {Hand: func(m *ice.Message, arg ...string) {}},
|
||||
ice.CMD: {Hand: func(m *ice.Message, arg ...string) {}},
|
||||
ice.RUN: {Hand: func(m *ice.Message, arg ...string) {}},
|
||||
}, Hand: func(m *ice.Message, arg ...string) {
|
||||
}, ctx.CmdAction()), Hand: func(m *ice.Message, arg ...string) {
|
||||
if len(arg) == 0 || strings.HasSuffix(arg[0], ice.PS) {
|
||||
m.Options(nfs.DIR_ROOT, nfs.SRC).Cmdy(nfs.CAT, arg)
|
||||
return
|
||||
}
|
||||
nfs.Open(m, path.Join(nfs.SRC, strings.TrimPrefix(path.Join(arg...), nfs.SRC)), func(r io.Reader, p string) {
|
||||
if NewStack(m, nil).parse(m, p, r); m.Option(ice.DEBUG) == ice.TRUE {
|
||||
s := NewStack(m, nil, "", p).parse(m, p, r)
|
||||
if m.StatusTime(mdb.LINK, s.value(m, "_link")); m.Option(ice.DEBUG) == ice.TRUE {
|
||||
m.Option("__index", kit.Format(s.value(m, "_index")))
|
||||
m.Cmdy(INFO, arg)
|
||||
}
|
||||
})
|
||||
@ -549,11 +527,10 @@ func StackHandler(m *ice.Message, arg ...string) {
|
||||
kit.If(!kit.IsIn(field.name, "m", "msg", ice.ARG), func() { list = append(list, kit.Dict(mdb.NAME, field.name, 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)) })
|
||||
h := func(m *ice.Message, arg ...string) { m.Copy(s.Action(m.Spawn(Index).Spawn(m.Target()), s, k, arg...)) }
|
||||
if k == mdb.LIST {
|
||||
cmd.Hand, cmd.List = h, list
|
||||
cmd.Hand, cmd.List = s.Handler(v), list
|
||||
} else {
|
||||
cmd.Actions[k], cmd.Meta[k] = &ice.Action{Hand: h}, list
|
||||
cmd.Actions[k], cmd.Meta[k] = &ice.Action{Hand: s.Handler(v)}, list
|
||||
}
|
||||
}
|
||||
})
|
||||
|
121
base/yac/stmt.go
121
base/yac/stmt.go
@ -21,6 +21,7 @@ const (
|
||||
DEFAULT = "default"
|
||||
FUNC = "func"
|
||||
INIT = "init"
|
||||
MAIN = "main"
|
||||
CALL = "call"
|
||||
DEFER = "defer"
|
||||
RETURN = "return"
|
||||
@ -48,26 +49,23 @@ func init() {
|
||||
} else {
|
||||
f.status, f.defers = STATUS_DISABLE, append(f.defers, func() { f.status = STATUS_NORMAL })
|
||||
}
|
||||
s.reads(m, func(k string) bool {
|
||||
if k == IF {
|
||||
if s.next(m) == IF {
|
||||
res := s.expr(m)
|
||||
kit.If(s.token() == SPLIT, func() { res = s.expr(m) })
|
||||
kit.If(res == ice.FALSE, func() { f.status = STATUS_DISABLE })
|
||||
}
|
||||
return true
|
||||
})
|
||||
}},
|
||||
FOR: {Name: "for a = 1; a < 10; a++ {", Hand: func(m *ice.Message, arg ...string) {
|
||||
s, f := _parse_frame(m)
|
||||
if strings.Contains(s.list[s.line], RANGE) {
|
||||
pos, key, list := s.Position, []string{}, []Any{}
|
||||
kit.If(s.last != nil && s.last.line == s.line, func() { list, _ = s.last.value["_range"].([]Any) })
|
||||
for { // for k, v := range value {
|
||||
for {
|
||||
if k := s.cals0(m, FIELD, DEFS, ASSIGN); k == RANGE {
|
||||
if obj, ok := s.cals(m).(Operater); ok {
|
||||
if _list, ok := obj.Operate(RANGE, list).([]Any); ok {
|
||||
kit.For(key, func(i int, k string) { f.value[k] = _list[i] })
|
||||
f.value["_range"] = _list
|
||||
if list, ok := obj.Operate(RANGE, list).([]Any); ok {
|
||||
kit.For(key, func(i int, k string) { f.value[k] = list[i] })
|
||||
f.value["_range"] = list
|
||||
break
|
||||
}
|
||||
}
|
||||
@ -102,8 +100,7 @@ func init() {
|
||||
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--
|
||||
s.pos(m, list[0], -1)
|
||||
}
|
||||
})
|
||||
}},
|
||||
@ -148,9 +145,12 @@ func init() {
|
||||
f.status = STATUS_NORMAL
|
||||
v := s.cals(m)
|
||||
f.status = STATUS_DISABLE
|
||||
if f.value["_case"] == "done" {
|
||||
return
|
||||
}
|
||||
if res, ok := v.(Operater); ok {
|
||||
if res, ok := res.Operate("==", Trans(s.value(m, "_switch"))).(Boolean); ok && res.value {
|
||||
f.status, f.value["_case"] = 0, "done"
|
||||
f.status, f.value["_case"] = STATUS_NORMAL, "done"
|
||||
}
|
||||
}
|
||||
}},
|
||||
@ -164,53 +164,32 @@ func init() {
|
||||
}},
|
||||
FUNC: {Name: "func show(a, b) (c, d)", Hand: func(m *ice.Message, arg ...string) {
|
||||
s := _parse_stack(m)
|
||||
list, key, kind := [][]Field{[]Field{}}, "", ""
|
||||
push := func() {
|
||||
kit.If(key, func() { list[len(list)-1], key, kind = append(list[len(list)-1], Field{name: key, kind: kind}), "", "" })
|
||||
field, list := Field{}, []Field{}
|
||||
if s.next(m) == OPEN {
|
||||
for s.next(m) != CLOSE {
|
||||
kit.If(field.name == "", func() { field.name = s.token() }, func() { field.types = s.token() })
|
||||
}
|
||||
s.reads(m, func(k string) bool {
|
||||
switch k {
|
||||
case OPEN:
|
||||
defer kit.If(key != "" || len(list) > 1, func() { list = append(list, []Field{}) })
|
||||
case FIELD, CLOSE:
|
||||
case BEGIN:
|
||||
return true
|
||||
default:
|
||||
kit.If(key, func() { kind = k }, func() { key = k })
|
||||
return false
|
||||
s.next(m)
|
||||
list = append(list, field)
|
||||
}
|
||||
push()
|
||||
return false
|
||||
})
|
||||
m.Debug("what %#v", list)
|
||||
kit.If(len(list) < 2, func() { list = append(list, []Field{}) })
|
||||
kit.If(len(list) < 3, func() { list = append(list, []Field{}) })
|
||||
name, fun := list[0][len(list[0])-1].name, Function{obj: list[0], arg: list[1], res: list[2], Position: s.Position}
|
||||
if len(list[0]) > 1 {
|
||||
if st, ok := list[0][0].kind.(Struct); ok {
|
||||
st.method = append(st.method, fun)
|
||||
st.index[name] = fun
|
||||
name := s.token()
|
||||
list = append(list, Field{name: name})
|
||||
s.rest[s.skip] = FUNC
|
||||
v := s.funcs(m, name)
|
||||
if v.obj = list; field.types != nil {
|
||||
if t, ok := s.value(m, kit.Format(field.types)).(Struct); ok {
|
||||
m.Debug("value %s set %s.%s %s", Format(s), field.types, name, Format(v))
|
||||
t.index[name] = v
|
||||
}
|
||||
if st, ok := list[0][0].kind.(string); ok {
|
||||
if st, ok := s.value(m, st).(Struct); ok {
|
||||
st.method = append(st.method, fun)
|
||||
st.index[name] = fun
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
kit.If(name != INIT, func() { s.value(m, name, fun) })
|
||||
}
|
||||
if f := s.pushf(m, ""); name == INIT {
|
||||
f.key = CALL
|
||||
} else {
|
||||
f.status = STATUS_DISABLE
|
||||
} else if name != INIT {
|
||||
s.value(m, name, v)
|
||||
}
|
||||
}},
|
||||
DEFER: {Name: "defer func() {} ()", Hand: func(m *ice.Message, arg ...string) {
|
||||
s := _parse_stack(m)
|
||||
k := s.next(m)
|
||||
kit.If(k == FUNC, func() { k = s.funcs(m) })
|
||||
obj, k := Any(nil), ""
|
||||
obj, k = s, s.next(m)
|
||||
kit.If(k == FUNC, func() { obj, k = s.funcs(m, ""), "" })
|
||||
s.skip++
|
||||
args := _parse_res(m, s.cals(m))
|
||||
if !s.runable() {
|
||||
@ -218,7 +197,7 @@ func init() {
|
||||
}
|
||||
s.stack(func(f *Frame, i int) bool {
|
||||
if f.key == CALL {
|
||||
f.defers = append(f.defers, func() { s.calls(m, s, k, nil, args...) })
|
||||
f.defers = append(f.defers, func() { s.calls(m, obj, k, nil, args...) })
|
||||
return true
|
||||
}
|
||||
return false
|
||||
@ -258,16 +237,44 @@ func init() {
|
||||
m.EchoLine("").EchoLine("stack: %s", arg[0])
|
||||
_parse_stack(m).stack(func(f *Frame, i int) bool {
|
||||
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) })
|
||||
show := func(p string) string {
|
||||
ls := nfs.SplitPath(m, p)
|
||||
return ice.Render(m, ice.RENDER_ANCHOR, p, m.MergePodCmd("", "web.code.vimer", nfs.PATH, ls[0], nfs.FILE, ls[1], nfs.LINE, ls[2]))
|
||||
}
|
||||
kit.For(f.value, func(k string, v Any) {
|
||||
switch v := v.(type) {
|
||||
case func(*ice.Message, string, ...Any) Any:
|
||||
m.EchoLine(" %s: %v", k, show(kit.FileLine(v, 100)))
|
||||
case Message:
|
||||
m.EchoLine(" %s: %v", k, show(kit.FileLine(v.Call, 100)))
|
||||
case Function:
|
||||
m.EchoLine(" %s: %v", k, show(v.Position.name+":"+kit.Format(v.Position.line+1)))
|
||||
case Struct:
|
||||
m.EchoLine(" %s: struct", k)
|
||||
kit.For(v.index, func(k string, v Any) {
|
||||
switch v := v.(type) {
|
||||
case Function:
|
||||
m.EchoLine(" %s: %v", k, show(v.Position.name+":"+kit.Format(v.Position.line+1)))
|
||||
case Field:
|
||||
m.EchoLine(" %s: %v", k, v.Format())
|
||||
}
|
||||
})
|
||||
case string:
|
||||
m.EchoLine(" %s: %v", k, v)
|
||||
default:
|
||||
m.EchoLine(" %s: %v", k, Format(v))
|
||||
}
|
||||
})
|
||||
return false
|
||||
})
|
||||
m.EchoLine("stmt: %s", arg[0])
|
||||
for key, cmd := range m.Target().Commands {
|
||||
if strings.HasPrefix(key, "_") || strings.HasPrefix(key, "/") {
|
||||
continue
|
||||
kit.For(kit.SortedKey(m.Target().Commands), func(key string) {
|
||||
if strings.HasPrefix(key, "_") || strings.HasPrefix(key, ice.PS) {
|
||||
return
|
||||
}
|
||||
cmd := m.Target().Commands[key]
|
||||
m.EchoLine(" %s: %#v", key, cmd.Name)
|
||||
}
|
||||
})
|
||||
}},
|
||||
PWD: {Name: "pwd", Hand: func(m *ice.Message, arg ...string) {
|
||||
s := _parse_stack(m)
|
||||
|
@ -1,42 +1,45 @@
|
||||
package yac
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
ice "shylinux.com/x/icebergs"
|
||||
kit "shylinux.com/x/toolkits"
|
||||
)
|
||||
|
||||
const (
|
||||
CONST = "const"
|
||||
TYPE = "type"
|
||||
VAR = "var"
|
||||
|
||||
STRING = "string"
|
||||
INT = "int"
|
||||
MAP = "map"
|
||||
SLICE = "slice"
|
||||
STRUCT = "struct"
|
||||
INTERFACE = "interface"
|
||||
)
|
||||
|
||||
type Map struct {
|
||||
key Any
|
||||
value Any
|
||||
key Any
|
||||
}
|
||||
type Slice struct {
|
||||
value Any
|
||||
}
|
||||
type Interface struct {
|
||||
index map[string]Function
|
||||
name string
|
||||
}
|
||||
type Struct struct {
|
||||
index map[string]Any
|
||||
method []Function
|
||||
field []Field
|
||||
name string
|
||||
}
|
||||
type Field struct {
|
||||
types Any
|
||||
tags map[string]string
|
||||
name string
|
||||
kind Any
|
||||
}
|
||||
|
||||
func (s Field) MarshalJSON() ([]byte, error) {
|
||||
return []byte(kit.Format("%q", s.Format())), nil
|
||||
}
|
||||
func (s Field) Format() string {
|
||||
if len(s.tags) == 0 {
|
||||
return kit.Format("%s", s.types)
|
||||
}
|
||||
res := []string{}
|
||||
kit.For(s.tags, func(k, v string) { res = append(res, kit.Format("%s:\"%s\"", k, v)) })
|
||||
return kit.Format("%s `%s`", s.types, strings.Join(res, ice.SP))
|
||||
}
|
||||
|
||||
type Object struct {
|
||||
value Operater
|
||||
index Struct
|
||||
@ -46,6 +49,33 @@ func (s Object) Operate(op string, v Any) Any {
|
||||
switch op {
|
||||
case "&", "*":
|
||||
return s
|
||||
case INSTANCEOF:
|
||||
if t, ok := v.(Struct); ok {
|
||||
return Value{list: []Any{s, s.index.name == t.name}}
|
||||
}
|
||||
return Value{list: []Any{s, false}}
|
||||
case IMPLEMENTS:
|
||||
if t, ok := v.(Interface); ok {
|
||||
for k, v := range t.index {
|
||||
if _v, ok := s.index.index[k].(Function); ok {
|
||||
for i, field := range v.arg {
|
||||
if i < len(_v.arg) && _v.arg[i].types == field.types {
|
||||
continue
|
||||
}
|
||||
return Value{list: []Any{s, false}}
|
||||
}
|
||||
for i, field := range v.res {
|
||||
if i < len(_v.res) && _v.res[i].types == field.types {
|
||||
continue
|
||||
}
|
||||
return Value{list: []Any{s, false}}
|
||||
}
|
||||
} else {
|
||||
return Value{list: []Any{s, false}}
|
||||
}
|
||||
}
|
||||
}
|
||||
return Value{list: []Any{s, true}}
|
||||
case SUBS:
|
||||
switch v := s.index.index[kit.Format(v)].(type) {
|
||||
case Function:
|
||||
@ -59,6 +89,22 @@ func (s Object) Operate(op string, v Any) Any {
|
||||
return nil
|
||||
}
|
||||
|
||||
const (
|
||||
MAP = "map"
|
||||
SLICE = "slice"
|
||||
STRUCT = "struct"
|
||||
INTERFACE = "interface"
|
||||
STRING = "string"
|
||||
INT = "int"
|
||||
|
||||
INSTANCEOF = "instanceof"
|
||||
IMPLEMENTS = "implements"
|
||||
|
||||
CONST = "const"
|
||||
TYPE = "type"
|
||||
VAR = "var"
|
||||
)
|
||||
|
||||
func init() {
|
||||
Index.MergeCommands(ice.Commands{
|
||||
CONST: {Name: "const a = 1", Hand: func(m *ice.Message, arg ...string) {
|
||||
@ -80,7 +126,16 @@ func init() {
|
||||
s.next(m)
|
||||
fallthrough
|
||||
default:
|
||||
s.value(m, name, s.types(m))
|
||||
switch t := s.types(m).(type) {
|
||||
case Interface:
|
||||
t.name = name
|
||||
s.value(m, name, t)
|
||||
case Struct:
|
||||
t.name = name
|
||||
s.value(m, name, t)
|
||||
default:
|
||||
s.value(m, name, t)
|
||||
}
|
||||
}
|
||||
}},
|
||||
VAR: {Name: "var a = 1", Hand: func(m *ice.Message, arg ...string) {
|
||||
|
@ -7,33 +7,35 @@ import (
|
||||
"time"
|
||||
|
||||
ice "shylinux.com/x/icebergs"
|
||||
"shylinux.com/x/icebergs/base/mdb"
|
||||
"shylinux.com/x/icebergs/base/web"
|
||||
kit "shylinux.com/x/toolkits"
|
||||
)
|
||||
|
||||
type Any = ice.Any
|
||||
type Dict struct{ value map[string]Any }
|
||||
type List struct{ value []Any }
|
||||
type Value struct{ list []Any }
|
||||
type Dict struct{ value map[string]Any }
|
||||
type String struct{ value string }
|
||||
type Number struct{ value string }
|
||||
type Boolean struct{ value bool }
|
||||
type Caller interface{ Call(string, ...Any) Any }
|
||||
type Operater interface{ Operate(string, Any) Any }
|
||||
|
||||
func (s Dict) MarshalJSON() ([]byte, error) { return json.Marshal(s.value) }
|
||||
func (s List) MarshalJSON() ([]byte, error) { return json.Marshal(s.value) }
|
||||
func (s Dict) MarshalJSON() ([]byte, error) { return json.Marshal(s.value) }
|
||||
func (s String) MarshalJSON() ([]byte, error) { return json.Marshal(s.value) }
|
||||
func (s Number) MarshalJSON() ([]byte, error) { return json.Marshal(s.value) }
|
||||
func (s Boolean) MarshalJSON() ([]byte, error) { return json.Marshal(s.value) }
|
||||
func (s Function) MarshalJSON() ([]byte, error) {
|
||||
return []byte(kit.Format("%q", Format(s.Position))), nil
|
||||
}
|
||||
|
||||
func (s String) String() string { return s.value }
|
||||
func wrap(v Any) Any {
|
||||
switch v := v.(type) {
|
||||
case map[string]Any:
|
||||
return Dict{v}
|
||||
case []Any:
|
||||
return List{v}
|
||||
case map[string]Any:
|
||||
return Dict{v}
|
||||
case string:
|
||||
return String{v}
|
||||
case int:
|
||||
@ -46,16 +48,16 @@ func wrap(v Any) Any {
|
||||
}
|
||||
func Trans(v Any) Any {
|
||||
switch v := v.(type) {
|
||||
case Dict:
|
||||
return v.value
|
||||
case List:
|
||||
return v.value
|
||||
case Value:
|
||||
if len(v.list) > 0 {
|
||||
return Trans(v.list[0])
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
case List:
|
||||
return v.value
|
||||
case Dict:
|
||||
return v.value
|
||||
case String:
|
||||
return v.value
|
||||
case Number:
|
||||
@ -66,30 +68,6 @@ func Trans(v Any) Any {
|
||||
return v
|
||||
}
|
||||
}
|
||||
func (s Dict) Operate(op string, v Any) Any {
|
||||
switch op {
|
||||
case RANGE:
|
||||
switch list := v.(type) {
|
||||
case []Any:
|
||||
if key := kit.SortedKey(s.value); list != nil && len(list) > 2 {
|
||||
if i := kit.Int(list[2]) + 1; i < len(key) {
|
||||
return []Any{key[i], s.value[key[i]], i}
|
||||
}
|
||||
} else {
|
||||
if len(key) > 0 {
|
||||
return []Any{key[0], s.value[key[0]], 0}
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
case SUBS:
|
||||
return wrap(kit.Value(s.value, kit.Format(v)))
|
||||
default:
|
||||
s.value[op] = v
|
||||
return v
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (s List) Operate(op string, v Any) Any {
|
||||
switch op {
|
||||
case RANGE:
|
||||
@ -123,6 +101,30 @@ func (s List) Operate(op string, v Any) Any {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (s Dict) Operate(op string, v Any) Any {
|
||||
switch op {
|
||||
case RANGE:
|
||||
switch list := v.(type) {
|
||||
case []Any:
|
||||
if key := kit.SortedKey(s.value); list != nil && len(list) > 2 {
|
||||
if i := kit.Int(list[2]) + 1; i < len(key) {
|
||||
return []Any{key[i], s.value[key[i]], i}
|
||||
}
|
||||
} else {
|
||||
if len(key) > 0 {
|
||||
return []Any{key[0], s.value[key[0]], 0}
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
case SUBS:
|
||||
return wrap(kit.Value(s.value, kit.Format(v)))
|
||||
default:
|
||||
s.value[op] = v
|
||||
return v
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (s String) Operate(op string, v Any) Any {
|
||||
switch a, b := s.value, kit.Format(v); op {
|
||||
case "+":
|
||||
@ -191,16 +193,16 @@ func (s *Stack) load(m *ice.Message, cb func(*Frame)) *Stack {
|
||||
f := s.peekf()
|
||||
f.value["kit"] = func(m *ice.Message, key string, arg ...Any) Any {
|
||||
switch key {
|
||||
case "Dict":
|
||||
return kit.Dict(arg...)
|
||||
case "List":
|
||||
return kit.List(arg...)
|
||||
case "Dict":
|
||||
return kit.Dict(arg...)
|
||||
case "Format":
|
||||
return kit.Format(arg[0], arg[1:]...)
|
||||
case "Formats":
|
||||
return kit.Formats(arg[0])
|
||||
default:
|
||||
m.ErrorNotImplement(key)
|
||||
m.ErrorNotImplement(kit.Keys("kit", key))
|
||||
return nil
|
||||
}
|
||||
}
|
||||
@ -209,17 +211,26 @@ func (s *Stack) load(m *ice.Message, cb func(*Frame)) *Stack {
|
||||
command := &ice.Command{Name: "list hash auto", Help: "示例", Actions: ice.Actions{}}
|
||||
obj := arg[1].(Object)
|
||||
for k, v := range obj.index.index {
|
||||
switch v.(type) {
|
||||
switch v := v.(type) {
|
||||
case Function:
|
||||
v.object = obj
|
||||
if k == "List" {
|
||||
command.Hand = stack.Handler(v)
|
||||
} else {
|
||||
command.Actions[k] = &ice.Action{Hand: stack.Handler(v)}
|
||||
command.Actions[kit.LowerCapital(k)] = &ice.Action{Hand: stack.Handler(v)}
|
||||
}
|
||||
}
|
||||
}
|
||||
for k, v := range obj.index.index {
|
||||
switch v := v.(type) {
|
||||
case Field:
|
||||
if k == "list" {
|
||||
command.Name = v.tags[mdb.NAME]
|
||||
} else {
|
||||
command.Actions[k].Name = v.tags[mdb.NAME]
|
||||
}
|
||||
}
|
||||
}
|
||||
command.List = ice.SplitCmd(command.Name, command.Actions)
|
||||
last, list := ice.Index, kit.Split(kit.Format(arg[0]), ice.PT)
|
||||
for i := 1; i < len(list); i++ {
|
||||
has := false
|
||||
@ -232,7 +243,9 @@ func (s *Stack) load(m *ice.Message, cb func(*Frame)) *Stack {
|
||||
last.Merge(last)
|
||||
})
|
||||
}
|
||||
m.Debug("what %#v", command)
|
||||
link := ice.Render(m, ice.RENDER_ANCHOR, kit.Format(arg[0]), m.MergePodCmd("", kit.Format(arg[0])))
|
||||
s.frame[0].value["_index"] = kit.Format(arg[0])
|
||||
s.frame[0].value["_link"] = link
|
||||
return nil
|
||||
}
|
||||
f.value["ice.MergeActions"] = func(m *ice.Message, key string, arg ...Any) Any {
|
||||
@ -247,9 +260,7 @@ func (s *Stack) load(m *ice.Message, cb func(*Frame)) *Stack {
|
||||
return res
|
||||
}
|
||||
for k, v := range ice.Info.Stack {
|
||||
if strings.HasPrefix(k, "web.code.") {
|
||||
k = strings.TrimPrefix(k, "web.")
|
||||
}
|
||||
kit.If(strings.HasPrefix(k, "web.code."), func() { k = strings.TrimPrefix(k, "web.") })
|
||||
f.value[k] = v
|
||||
}
|
||||
f.value["m"] = Message{m}
|
||||
@ -272,6 +283,11 @@ func (m Message) Call(cmd string, arg ...Any) Any {
|
||||
m.Push(str(arg[0]), arg[1], arg[2:]...)
|
||||
case "Echo":
|
||||
m.Echo(str(arg[0]), arg[1:]...)
|
||||
case "Table":
|
||||
s := _parse_stack(m.Message)
|
||||
m.Table(func(val ice.Maps) { s.calls(m.Message, arg[0], "", nil, Dict{kit.Dict(val)}) })
|
||||
case "Sleep":
|
||||
m.Sleep(str(arg[0]))
|
||||
case "Action":
|
||||
m.Action(arg...)
|
||||
case "Display":
|
||||
@ -293,11 +309,6 @@ func (m Message) Call(cmd string, arg ...Any) Any {
|
||||
return false
|
||||
})
|
||||
m.Debug(ice.NL + strings.Join(list, ice.NL))
|
||||
case "Sleep":
|
||||
m.Sleep(str(arg[0]))
|
||||
case "Table":
|
||||
s := _parse_stack(m.Message)
|
||||
m.Table(func(val ice.Maps) { s.calls(m.Message, arg[0], nil, nil, Dict{kit.Dict(val)}) })
|
||||
default:
|
||||
m.ErrorNotImplement(cmd)
|
||||
}
|
||||
@ -335,10 +346,11 @@ func TransCommands(m *ice.Message, arg ...Any) ice.Commands {
|
||||
case "Actions":
|
||||
s.Actions = TransActions(m, v)
|
||||
case "Hand":
|
||||
s.Hand = func(m *ice.Message, arg ...string) {
|
||||
msg := m.Spawn(Index).Spawn(m.Target())
|
||||
stack.Action(msg, v, nil, arg...)
|
||||
m.Copy(msg)
|
||||
switch v := v.(type) {
|
||||
case Function:
|
||||
s.Hand = stack.Handler(v)
|
||||
case ice.Handler:
|
||||
s.Hand = v
|
||||
}
|
||||
}
|
||||
})
|
||||
@ -361,13 +373,67 @@ func TransActions(m *ice.Message, arg ...Any) ice.Actions {
|
||||
case "Help":
|
||||
s.Help = kit.Format(Trans(v))
|
||||
case "Hand":
|
||||
s.Hand = func(m *ice.Message, arg ...string) {
|
||||
msg := m.Spawn(Index).Spawn(m.Target())
|
||||
stack.Action(msg, v, nil, arg...)
|
||||
m.Copy(msg)
|
||||
switch v := v.(type) {
|
||||
case Function:
|
||||
s.Hand = stack.Handler(v)
|
||||
case ice.Handler:
|
||||
s.Hand = v
|
||||
}
|
||||
}
|
||||
actions[k] = s
|
||||
})
|
||||
return actions
|
||||
}
|
||||
|
||||
func Format(arg ...Any) string {
|
||||
res := []string{}
|
||||
for _, v := range arg {
|
||||
switch v := v.(type) {
|
||||
case func(*ice.Message, string, ...Any) Any:
|
||||
res = append(res, kit.FileLine(v, 100))
|
||||
case Message:
|
||||
res = append(res, kit.FileLine(v.Call, 100))
|
||||
case Function:
|
||||
res = append(res, kit.Format("%s %s%s%s", Format(v.obj[:len(v.obj)-1]), v.obj[len(v.obj)-1].name, Format(v.arg), Format(v.res)), Format(v.Position))
|
||||
case *Stack:
|
||||
res = append(res, kit.Format("%d:%s", len(v.frame)-1, kit.Select(v.peekf().key, v.peekf().name)))
|
||||
case Position:
|
||||
if v.Buffer == nil {
|
||||
continue
|
||||
} else if v.skip == -1 {
|
||||
res = append(res, kit.Format("%s:%d", v.name, v.line+1))
|
||||
} else {
|
||||
res = append(res, kit.Format("%s:%d:%d", v.name, v.line+1, v.skip))
|
||||
}
|
||||
case Map:
|
||||
res = append(res, kit.Format("map[%s]%s", v.key, v.value))
|
||||
case Slice:
|
||||
res = append(res, kit.Format("[]%s", v.value))
|
||||
case Interface:
|
||||
res = append(res, kit.Format("interface%s", v.name))
|
||||
case Struct:
|
||||
res = append(res, kit.Format("struct%s", Format(v.index)))
|
||||
case Object:
|
||||
res = append(res, kit.Format("%s:%s", v.index.name, Format(v.value)))
|
||||
case []Field:
|
||||
for i, field := range v {
|
||||
res = append(res, kit.Select("", OPEN, i == 0)+field.name, kit.Format(field.types)+kit.Select(FIELD, CLOSE, i == len(v)-1))
|
||||
}
|
||||
case List:
|
||||
res = append(res, kit.Format(v.value))
|
||||
case Dict:
|
||||
res = append(res, kit.Format(v.value))
|
||||
case String:
|
||||
res = append(res, kit.Format("%q", v.value))
|
||||
case Number:
|
||||
res = append(res, kit.Format("%s", v.value))
|
||||
case Boolean:
|
||||
res = append(res, kit.Format("%t", v.value))
|
||||
case string:
|
||||
res = append(res, kit.Format("%q", v))
|
||||
default:
|
||||
res = append(res, kit.Format(v))
|
||||
}
|
||||
}
|
||||
return strings.Join(res, " ")
|
||||
}
|
||||
|
@ -30,7 +30,11 @@ func init() {
|
||||
ctx.ProcessCommand(m, yac.STACK, kit.Simple(arg[1]))
|
||||
}},
|
||||
mdb.ENGINE: {Hand: func(m *ice.Message, arg ...string) {
|
||||
if msg := m.Cmd(yac.STACK, arg[1]); msg.Option("__index") != "" {
|
||||
ctx.ProcessCommand(m, msg.Option("__index"), kit.Simple())
|
||||
} else {
|
||||
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]))))
|
||||
|
10
render.go
10
render.go
@ -179,6 +179,16 @@ func (m *Message) PushDownload(key string, arg ...string) *Message {
|
||||
return m
|
||||
}
|
||||
|
||||
func (m *Message) EchoFields(cmd string) *Message {
|
||||
return m.Echo(`<fieldset class="story" data-index="%s">
|
||||
<legend></legend>
|
||||
<form class="option"></form>
|
||||
<div class="action"></div>
|
||||
<div class="output"></div>
|
||||
<div class="status"></div>
|
||||
</fieldset>
|
||||
`, cmd)
|
||||
}
|
||||
func (m *Message) EchoButton(arg ...Any) *Message { return m.Echo(Render(m, RENDER_BUTTON, arg...)) }
|
||||
func (m *Message) EchoAnchor(arg ...string) *Message { return m.Echo(Render(m, RENDER_ANCHOR, arg)) }
|
||||
func (m *Message) EchoQRCode(src string) *Message { return m.Echo(Render(m, RENDER_QRCODE, src)) }
|
||||
|
Loading…
x
Reference in New Issue
Block a user