mirror of
https://shylinux.com/x/icebergs
synced 2025-06-26 02:17:30 +08:00
add yac.type
This commit is contained in:
parent
6f5e22631c
commit
c8ca9c7c63
@ -130,7 +130,7 @@ const RUNTIME = "runtime"
|
|||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
Index.MergeCommands(ice.Commands{
|
Index.MergeCommands(ice.Commands{
|
||||||
RUNTIME: {Name: "runtime info=bootinfo,ifconfig,diskinfo,hostinfo,userinfo,procinfo,bootinfo,api,cli,cmd,env,path,chain auto", Help: "运行环境", Actions: ice.MergeActions(ice.Actions{
|
RUNTIME: {Name: "runtime info=bootinfo,ifconfig,diskinfo,hostinfo,userinfo,procinfo,bootinfo,api,cli,cmd,mod,env,path,chain auto", Help: "运行环境", Actions: ice.MergeActions(ice.Actions{
|
||||||
ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) { _runtime_init(m) }},
|
ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) { _runtime_init(m) }},
|
||||||
IFCONFIG: {Hand: func(m *ice.Message, arg ...string) { m.Cmdy("tcp.host") }},
|
IFCONFIG: {Hand: func(m *ice.Message, arg ...string) { m.Cmdy("tcp.host") }},
|
||||||
DISKINFO: {Hand: func(m *ice.Message, arg ...string) { _runtime_diskinfo(m) }},
|
DISKINFO: {Hand: func(m *ice.Message, arg ...string) { _runtime_diskinfo(m) }},
|
||||||
@ -164,6 +164,12 @@ func init() {
|
|||||||
m.OptionFields(ctx.INDEX, mdb.NAME, mdb.HELP, nfs.FILE)
|
m.OptionFields(ctx.INDEX, mdb.NAME, mdb.HELP, nfs.FILE)
|
||||||
m.Cmdy(ctx.COMMAND, mdb.SEARCH, ctx.COMMAND).StatusTimeCount()
|
m.Cmdy(ctx.COMMAND, mdb.SEARCH, ctx.COMMAND).StatusTimeCount()
|
||||||
}},
|
}},
|
||||||
|
"mod": {Hand: func(m *ice.Message, arg ...string) {
|
||||||
|
kit.For(ice.Info.Gomod, func(k string, v ice.Any) {
|
||||||
|
m.Push("mod", k)
|
||||||
|
m.Push("url", v)
|
||||||
|
})
|
||||||
|
}},
|
||||||
ENV: {Hand: func(m *ice.Message, arg ...string) {
|
ENV: {Hand: func(m *ice.Message, arg ...string) {
|
||||||
kit.For(os.Environ(), func(v string) {
|
kit.For(os.Environ(), func(v string) {
|
||||||
ls := strings.SplitN(v, ice.EQ, 2)
|
ls := strings.SplitN(v, ice.EQ, 2)
|
||||||
|
@ -8,7 +8,6 @@ import (
|
|||||||
"shylinux.com/x/icebergs/base/aaa"
|
"shylinux.com/x/icebergs/base/aaa"
|
||||||
"shylinux.com/x/icebergs/base/mdb"
|
"shylinux.com/x/icebergs/base/mdb"
|
||||||
"shylinux.com/x/icebergs/base/nfs"
|
"shylinux.com/x/icebergs/base/nfs"
|
||||||
"shylinux.com/x/icebergs/base/yac"
|
|
||||||
kit "shylinux.com/x/toolkits"
|
kit "shylinux.com/x/toolkits"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -32,9 +31,6 @@ func _command_list(m *ice.Message, name string) *ice.Message {
|
|||||||
m.Push(mdb.META, kit.Format(cmd.Meta))
|
m.Push(mdb.META, kit.Format(cmd.Meta))
|
||||||
m.Push(mdb.LIST, kit.Format(cmd.List))
|
m.Push(mdb.LIST, kit.Format(cmd.List))
|
||||||
})
|
})
|
||||||
if m.Length() == 0 && yac.ExistsFile(m, name) {
|
|
||||||
m.Cmdy(yac.STACK, ice.CMD, name)
|
|
||||||
}
|
|
||||||
return m
|
return m
|
||||||
}
|
}
|
||||||
func _command_search(m *ice.Message, kind, name, text string) {
|
func _command_search(m *ice.Message, kind, name, text string) {
|
||||||
@ -95,13 +91,7 @@ func PodCmd(m *ice.Message, arg ...ice.Any) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
func Run(m *ice.Message, arg ...string) {
|
func Run(m *ice.Message, arg ...string) {
|
||||||
kit.If(!PodCmd(m, arg) && aaa.Right(m, arg), func() {
|
kit.If(!PodCmd(m, arg) && aaa.Right(m, arg), func() { m.Cmdy(arg) })
|
||||||
if yac.ExistsFile(m, arg[0]) {
|
|
||||||
m.Cmdy(yac.STACK, ice.RUN, arg)
|
|
||||||
} else {
|
|
||||||
m.Cmdy(arg)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
func CmdHandler(args ...ice.Any) ice.Handler {
|
func CmdHandler(args ...ice.Any) ice.Handler {
|
||||||
return func(m *ice.Message, arg ...string) { m.Cmdy(args...) }
|
return func(m *ice.Message, arg ...string) { m.Cmdy(args...) }
|
||||||
|
@ -1,9 +1,18 @@
|
|||||||
package ctx
|
package ctx
|
||||||
|
|
||||||
import ice "shylinux.com/x/icebergs"
|
import (
|
||||||
|
ice "shylinux.com/x/icebergs"
|
||||||
|
kit "shylinux.com/x/toolkits"
|
||||||
|
)
|
||||||
|
|
||||||
const CTX = "ctx"
|
const CTX = "ctx"
|
||||||
|
|
||||||
var Index = &ice.Context{Name: CTX, Help: "标准模块"}
|
var Index = &ice.Context{Name: CTX, Help: "标准模块"}
|
||||||
|
|
||||||
func init() { ice.Index.Register(Index, nil, CONTEXT, COMMAND, CONFIG) }
|
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 Prefix(arg ...string) string { return kit.Keys(CTX, arg) }
|
||||||
|
@ -145,13 +145,19 @@ func OptionLoad(m *ice.Message, p string) *ice.Message {
|
|||||||
return m
|
return m
|
||||||
}
|
}
|
||||||
func Open(m *ice.Message, p string, cb ice.Any) {
|
func Open(m *ice.Message, p string, cb ice.Any) {
|
||||||
if strings.HasSuffix(p, PS) {
|
if p == "" {
|
||||||
|
return
|
||||||
|
} else if strings.HasSuffix(p, PS) {
|
||||||
if ls, e := ReadDir(m, p); !m.Warn(e) {
|
if ls, e := ReadDir(m, p); !m.Warn(e) {
|
||||||
switch cb := cb.(type) {
|
switch cb := cb.(type) {
|
||||||
case func([]os.FileInfo):
|
case func([]os.FileInfo):
|
||||||
cb(ls)
|
cb(ls)
|
||||||
case func(os.FileInfo):
|
case func(os.FileInfo):
|
||||||
kit.For(ls, cb)
|
kit.For(ls, cb)
|
||||||
|
case func(io.Reader, string):
|
||||||
|
kit.For(ls, func(s os.FileInfo) {
|
||||||
|
kit.If(!s.IsDir(), func() { Open(m, path.Join(p, s.Name()), cb) })
|
||||||
|
})
|
||||||
default:
|
default:
|
||||||
m.ErrorNotImplement(cb)
|
m.ErrorNotImplement(cb)
|
||||||
}
|
}
|
||||||
|
296
base/yac/expr.go
296
base/yac/expr.go
@ -26,19 +26,23 @@ const (
|
|||||||
END = "}"
|
END = "}"
|
||||||
)
|
)
|
||||||
|
|
||||||
var keyword = regexp.MustCompile("[_a-zA-Z][_a-zA-Z0-9]*")
|
var keyword = regexp.MustCompile(`[_a-zA-Z][_a-zA-Z0-9\.]*`)
|
||||||
|
|
||||||
var level = map[string]int{
|
var level = map[string]int{
|
||||||
"//": 200, "/*": 200, "*/": 200,
|
"//": 200, "/*": 200, "*/": 200,
|
||||||
"!": 100, "++": 100, "--": 100, "[": 100, "]": 100,
|
"&": 100, // "*": 100, "!": 100,
|
||||||
|
"[": 100, "]": 100, "++": 100, "--": 100,
|
||||||
"*": 40, "/": 40, "+": 30, "-": 30,
|
"*": 40, "/": 40, "+": 30, "-": 30,
|
||||||
"<": 20, ">": 20, ">=": 20, "<=": 20, "!=": 20, "==": 20, "&&": 10, "||": 10,
|
"<": 20, ">": 20, ">=": 20, "<=": 20, "!=": 20, "==": 20, "&&": 10, "||": 10,
|
||||||
DEFINE: 2, ASSIGN: 2, FIELD: 2, OPEN: 1, CLOSE: 1,
|
DEFS: 2, DEFINE: 2, ASSIGN: 2, FIELD: 2, OPEN: 1, CLOSE: 1,
|
||||||
}
|
}
|
||||||
|
|
||||||
type Expr struct {
|
type Expr struct {
|
||||||
list ice.List
|
list ice.List
|
||||||
s *Stack
|
p string
|
||||||
|
t Any
|
||||||
|
n int
|
||||||
|
*Stack
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Expr) push(v Any) *Expr {
|
func (s *Expr) push(v Any) *Expr {
|
||||||
@ -46,7 +50,11 @@ func (s *Expr) push(v Any) *Expr {
|
|||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
func (s *Expr) pop(n int) *Expr {
|
func (s *Expr) pop(n int) *Expr {
|
||||||
|
if n <= len(s.list) {
|
||||||
s.list = s.list[:len(s.list)-n]
|
s.list = s.list[:len(s.list)-n]
|
||||||
|
} else {
|
||||||
|
s.list = s.list[:0]
|
||||||
|
}
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
func (s *Expr) pops(n int, v Any) *Expr { return s.pop(n).push(v) }
|
func (s *Expr) pops(n int, v Any) *Expr { return s.pop(n).push(v) }
|
||||||
@ -60,30 +68,30 @@ func (s *Expr) getl(p int) int { return level[s.gets(p)] }
|
|||||||
func (s *Expr) getv(m *ice.Message, p int) (v Any) {
|
func (s *Expr) getv(m *ice.Message, p int) (v Any) {
|
||||||
switch v := s.get(p); v := v.(type) {
|
switch v := s.get(p); v := v.(type) {
|
||||||
case string:
|
case string:
|
||||||
return s.s.value(m, v)
|
return s.value(m, v)
|
||||||
default:
|
default:
|
||||||
return v
|
return v
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
func (s *Expr) setv(m *ice.Message, p int, op string, v Any) Any {
|
func (s *Expr) setv(m *ice.Message, p int, op string, v Any) Any {
|
||||||
if !s.s.runable() {
|
if !s.runable() {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
switch k := s.gets(p); v := v.(type) {
|
switch k := s.gets(p); v := v.(type) {
|
||||||
case string:
|
case string:
|
||||||
return s.s.value(m, k, s.s.value(m, v), op)
|
return s.value(m, k, s.value(m, v), op)
|
||||||
case Value:
|
case Value:
|
||||||
if len(v.list) > 0 {
|
if len(v.list) > 0 {
|
||||||
return s.s.value(m, k, v.list[0], op)
|
return s.value(m, k, v.list[0], op)
|
||||||
} else {
|
} else {
|
||||||
return s.s.value(m, k)
|
return s.value(m, k, nil, op)
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
return s.s.value(m, k, v, op)
|
return s.value(m, k, v, op)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
func (s *Expr) opv(m *ice.Message, p int, op string, v Any) Any {
|
func (s *Expr) opv(m *ice.Message, p int, op string, v Any) Any {
|
||||||
if !s.s.runable() {
|
if !s.runable() {
|
||||||
return s.getv(m, p)
|
return s.getv(m, p)
|
||||||
}
|
}
|
||||||
if obj, ok := s.getv(m, p).(Operater); ok {
|
if obj, ok := s.getv(m, p).(Operater); ok {
|
||||||
@ -92,18 +100,17 @@ func (s *Expr) opv(m *ice.Message, p int, op string, v Any) Any {
|
|||||||
return s.getv(m, p)
|
return s.getv(m, p)
|
||||||
}
|
}
|
||||||
func (s *Expr) ops(m *ice.Message) {
|
func (s *Expr) ops(m *ice.Message) {
|
||||||
if !s.s.runable() || s.getl(-2) < 10 {
|
if !s.runable() || s.getl(-2) < 10 {
|
||||||
return
|
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.getv(m, -1)))
|
||||||
}
|
}
|
||||||
func (s *Expr) end(m *ice.Message) Any {
|
func (s *Expr) end(m *ice.Message) Any {
|
||||||
if !s.s.runable() || len(s.list) == 0 {
|
if !s.runable() || len(s.list) == 0 {
|
||||||
return nil
|
return nil
|
||||||
} else if len(s.list) == 1 {
|
} else if len(s.list) == 1 {
|
||||||
return s.getv(m, 0)
|
return s.getv(m, 0)
|
||||||
}
|
}
|
||||||
m.Debug("expr ops %v", s.list)
|
|
||||||
for i := 0; i < 100 && len(s.list) > 1; i++ {
|
for i := 0; i < 100 && len(s.list) > 1; i++ {
|
||||||
switch s.ops(m); s.gets(-2) {
|
switch s.ops(m); s.gets(-2) {
|
||||||
case DEFINE, ASSIGN:
|
case DEFINE, ASSIGN:
|
||||||
@ -136,75 +143,203 @@ func (s *Expr) end(m *ice.Message) Any {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m.Debug("expr ops %v", s.list)
|
|
||||||
return s.getv(m, 0)
|
return s.getv(m, 0)
|
||||||
}
|
}
|
||||||
func (s *Expr) cals(m *ice.Message) Any {
|
func (s *Expr) isop(k Any) bool {
|
||||||
line := s.s.line
|
switch k := k.(type) {
|
||||||
if s.s.skip == -1 {
|
case int:
|
||||||
m.Debug("expr calcs %v %s:%d", s.s.rest, s.s.name, s.s.line)
|
return level[s.gets(k)] > 0
|
||||||
} else {
|
case string:
|
||||||
m.Debug("expr calcs %v %s:%d", s.s.rest[s.s.skip:], s.s.name, s.s.line)
|
return level[k] > 0
|
||||||
}
|
}
|
||||||
s.s.reads(m, func(k string) bool {
|
return false
|
||||||
if op := s.gets(-1) + k; level[op] > 0 && s.getl(-1) > 0 {
|
}
|
||||||
|
|
||||||
|
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 {
|
||||||
|
data := kit.Dict()
|
||||||
|
for s.token() != END {
|
||||||
|
k := ""
|
||||||
|
kit.If(ismap, func() {
|
||||||
|
sub := s.sub(m)
|
||||||
|
if k = kit.Format(trans(sub.cals(m, DEFS, END))); k == "" {
|
||||||
|
k = _parse_const(m, sub.gets(0))
|
||||||
|
}
|
||||||
|
}, func() { k, _ = s.next(m), s.next(m) })
|
||||||
|
kit.If(s.token() == DEFS, func() {
|
||||||
|
sub := s.sub(m)
|
||||||
|
if sub.p = p; ismap {
|
||||||
|
sub.t = t
|
||||||
|
} else {
|
||||||
|
switch t := t.(type) {
|
||||||
|
case Struct:
|
||||||
|
if field, ok := t.index[k].(Field); ok {
|
||||||
|
sub.t = field.kind
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m.Debug("field %d %#v %#v", sub.n, k, data[k])
|
||||||
|
data[k] = sub.cals(m, FIELD, END)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return data
|
||||||
|
}
|
||||||
|
func (s *Expr) ntv(m *ice.Message, t Any, p string) []Any {
|
||||||
|
data := kit.List()
|
||||||
|
for !kit.IsIn(s.token(), SUPS, END) {
|
||||||
|
sub := s.sub(m)
|
||||||
|
sub.t, sub.p = t, p
|
||||||
|
if v := sub.cals(m, FIELD, SUPS, END); v != nil {
|
||||||
|
m.Debug("field %d %d %#v", sub.n, len(data), v)
|
||||||
|
data = append(data, v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return data
|
||||||
|
}
|
||||||
|
func (s *Expr) cals(m *ice.Message, arg ...string) Any {
|
||||||
|
if s.skip == -1 {
|
||||||
|
m.Debug("calcs %d %v %v", s.n, s.rest, arg)
|
||||||
|
} else {
|
||||||
|
m.Debug("calcs %d %v %v", s.n, s.rest[s.skip:], arg)
|
||||||
|
}
|
||||||
|
line := s.line
|
||||||
|
s.reads(m, func(k string) bool {
|
||||||
|
switch s.get(-1).(type) {
|
||||||
|
case string:
|
||||||
|
if op := s.gets(-1) + k; s.isop(op) {
|
||||||
s.pop(1)
|
s.pop(1)
|
||||||
k = op
|
k = op
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if kit.IsIn(k, arg...) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
switch k {
|
switch k {
|
||||||
case DEFS, SUPS, BEGIN, SPLIT:
|
case SPLIT:
|
||||||
|
return true
|
||||||
|
case BEGIN:
|
||||||
|
p := ""
|
||||||
|
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)})
|
||||||
|
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})
|
||||||
|
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)})
|
||||||
|
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})
|
||||||
|
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, "")})
|
||||||
|
return false
|
||||||
|
}
|
||||||
return true
|
return true
|
||||||
case END:
|
case END:
|
||||||
s.s.skip--
|
s.skip--
|
||||||
return true
|
return true
|
||||||
case CLOSE:
|
case MAP:
|
||||||
if s.gets(-2) == OPEN {
|
s.next(m)
|
||||||
s.pops(2, s.get(-1))
|
key := s.next(m)
|
||||||
return false
|
s.next(m)
|
||||||
}
|
value := s.next(m)
|
||||||
return true
|
v := Map{key: key, value: value}
|
||||||
}
|
name := kit.Format("map[%s]%s", v.key, v.value)
|
||||||
if len(s.list) > 0 && s.getl(-1) == 0 {
|
s.value(m, name, v)
|
||||||
switch k {
|
s.push(name)
|
||||||
case "++", "--":
|
|
||||||
s.pops(1, s.setv(m, -1, ASSIGN, s.opv(m, -1, k, nil)))
|
|
||||||
return false
|
return false
|
||||||
case SUBS:
|
case SUBS:
|
||||||
s.pops(1, s.opv(m, -1, SUBS, s.s.cals(m)))
|
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)
|
||||||
|
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, "")})
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
case STRUCT, INTERFACE:
|
||||||
|
s.skip--
|
||||||
|
name := s.show()
|
||||||
|
s.rest[s.skip] = name
|
||||||
|
s.skip--
|
||||||
|
m.Cmd(TYPE)
|
||||||
|
s.push(name)
|
||||||
|
return false
|
||||||
|
case FUNC:
|
||||||
|
s.push(s.value(m, s.funcs(m)))
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if len(s.list) > 0 && !s.isop(-1) {
|
||||||
|
switch k {
|
||||||
|
case SUBS:
|
||||||
|
switch v := s.sub(m).cals(m, SUPS); s.get(-1).(type) {
|
||||||
|
case string:
|
||||||
|
s.pops(1, kit.Keys(s.gets(-1), kit.Format(trans(v))))
|
||||||
|
default:
|
||||||
|
s.pops(1, s.opv(m, -1, SUBS, v))
|
||||||
|
}
|
||||||
return false
|
return false
|
||||||
case OPEN:
|
case OPEN:
|
||||||
if s.gets(-1) == FUNC && s.s.skip > 1 {
|
|
||||||
s.s.skip--
|
|
||||||
s.pops(1, s.s.value(m, s.s.funcs(m)))
|
|
||||||
} else {
|
|
||||||
switch k := s.get(-1).(type) {
|
switch k := s.get(-1).(type) {
|
||||||
case string:
|
case string:
|
||||||
s.pops(1, s.call(m, s.s, k))
|
s.pops(1, s.call(m, s.Stack, k))
|
||||||
default:
|
default:
|
||||||
s.pops(1, s.call(m, k, ""))
|
s.pops(1, s.call(m, k, ""))
|
||||||
}
|
}
|
||||||
}
|
return false
|
||||||
|
case CLOSE:
|
||||||
|
kit.If(s.gets(-2) == OPEN, func() { s.pops(2, s.get(-1)) })
|
||||||
|
return false
|
||||||
|
case "++", "--":
|
||||||
|
s.pops(1, s.setv(m, -1, ASSIGN, s.opv(m, -1, k, nil)))
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if level[k] == 0 {
|
if !s.isop(k) {
|
||||||
if strings.HasPrefix(k, ice.PT) && kit.Select("", s.s.rest, s.s.skip+1) == OPEN {
|
if strings.HasPrefix(k, ice.PT) {
|
||||||
s.s.skip++
|
if kit.Select("", s.rest, s.skip+1) == OPEN {
|
||||||
|
s.skip++
|
||||||
s.pops(1, s.call(m, s.getv(m, -1), strings.TrimPrefix(k, ice.PT)))
|
s.pops(1, s.call(m, s.getv(m, -1), strings.TrimPrefix(k, ice.PT)))
|
||||||
return false
|
return false
|
||||||
} else {
|
} else if !s.isop(-1) && len(s.list) > 0 {
|
||||||
s.s.skip--
|
s.pops(1, s.gets(-1)+k)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s.skip--
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
if s.isop(k) {
|
||||||
if level[k] > 0 {
|
|
||||||
for 9 <= level[k] && level[k] <= s.getl(-2) && level[k] < 100 {
|
for 9 <= level[k] && level[k] <= s.getl(-2) && level[k] < 100 {
|
||||||
s.ops(m)
|
s.ops(m)
|
||||||
}
|
}
|
||||||
s.push(k)
|
s.push(k)
|
||||||
} else {
|
} else {
|
||||||
if s.push(s.trans(m, k)); s.gets(-2) == "!" {
|
if s.push(s.trans(m, k)); s.getl(-2) > 0 && (s.getl(-3) > 0 || len(s.list) == 2) {
|
||||||
s.pops(2, s.opv(m, -1, "!", nil))
|
s.pops(2, s.opv(m, -1, s.gets(-2), nil))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
@ -227,48 +362,36 @@ func (s *Expr) trans(m *ice.Message, k string) Any {
|
|||||||
return Number{value: k}
|
return Number{value: k}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
func (s *Expr) cmds(m *ice.Message, line int) bool {
|
func (s *Expr) cmds(m *ice.Message, line int) (done bool) {
|
||||||
if cmds := false; len(s.list) == 1 && s.s.skip < 2 {
|
if len(s.list) == 1 && s.skip < 2 {
|
||||||
m.Search(s.gets(0), func(key string, cmd *ice.Command) {
|
m.Search(s.gets(0), func(key string, cmd *ice.Command) {
|
||||||
if cmds = true; s.s.line == line {
|
|
||||||
args := kit.List(s.gets(0))
|
args := kit.List(s.gets(0))
|
||||||
for {
|
for done = true; s.line == line; {
|
||||||
s := NewExpr(s.s)
|
sub := s.sub(m)
|
||||||
s.cals(m)
|
switch sub.cals(m); v := sub.get(0).(type) {
|
||||||
if v := s.getv(m, 0); v != nil {
|
case string:
|
||||||
args = append(args, trans(v))
|
if _v := s.value(m, v); _v != nil {
|
||||||
|
args = append(args, kit.Format(trans(_v)))
|
||||||
} else {
|
} else {
|
||||||
args = append(args, v)
|
args = append(args, v)
|
||||||
}
|
}
|
||||||
if s.s.line != line {
|
default:
|
||||||
break
|
args = append(args, kit.Format(trans(v)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m.Cmdy(args...)
|
m.Cmdy(args...)
|
||||||
} else {
|
|
||||||
m.Cmdy(s.gets(0))
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
if cmds {
|
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
}
|
return
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
func (s *Expr) call(m *ice.Message, obj Any, key string) Any {
|
func (s *Expr) call(m *ice.Message, obj Any, key string) Any {
|
||||||
list := kit.List()
|
if arg := _parse_res(m, s.sub(m).cals(m, CLOSE)); s.runable() {
|
||||||
switch v := s.s.cals(m).(type) {
|
return s.calls(m, obj, key, nil, arg...)
|
||||||
case Value:
|
} else {
|
||||||
list = append(list, v.list...)
|
return nil
|
||||||
default:
|
|
||||||
list = append(list, v)
|
|
||||||
}
|
}
|
||||||
if !s.s.runable() {
|
|
||||||
return list
|
|
||||||
}
|
|
||||||
return s.s.call(m, obj, key, nil, list...)
|
|
||||||
}
|
}
|
||||||
func NewExpr(s *Stack) *Expr { return &Expr{kit.List(), s} }
|
func NewExpr(s *Stack) *Expr { return &Expr{list: kit.List(), Stack: s} }
|
||||||
|
|
||||||
const EXPR = "expr"
|
const EXPR = "expr"
|
||||||
|
|
||||||
@ -276,15 +399,20 @@ func init() {
|
|||||||
Index.MergeCommands(ice.Commands{
|
Index.MergeCommands(ice.Commands{
|
||||||
EXPR: {Name: "expr a, b = 1, 2", Hand: func(m *ice.Message, arg ...string) {
|
EXPR: {Name: "expr a, b = 1, 2", Hand: func(m *ice.Message, arg ...string) {
|
||||||
s := _parse_stack(m)
|
s := _parse_stack(m)
|
||||||
arg = s.rest
|
if arg, v := s.rest, s.cals(m); !s.runable() {
|
||||||
if v := s.cals(m); !s.runable() {
|
|
||||||
return
|
return
|
||||||
} else if v != nil {
|
} else if v != nil {
|
||||||
m.Echo(kit.Format(trans(v)))
|
m.Debug("value %#v <- %v", 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])) })
|
||||||
|
default:
|
||||||
|
m.Echo(kit.Format(v))
|
||||||
|
}
|
||||||
} else if s.token() == BEGIN {
|
} else if s.token() == BEGIN {
|
||||||
m.Echo(ice.TRUE)
|
m.Echo(ice.TRUE)
|
||||||
}
|
}
|
||||||
m.Debug("expr value %s %v %s:%d", m.Result(), arg, s.name, s.line)
|
|
||||||
}},
|
}},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
61
base/yac/import.go
Normal file
61
base/yac/import.go
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
package yac
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io"
|
||||||
|
"net/url"
|
||||||
|
"path"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
ice "shylinux.com/x/icebergs"
|
||||||
|
"shylinux.com/x/icebergs/base/nfs"
|
||||||
|
kit "shylinux.com/x/toolkits"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
PACKAGE = "package"
|
||||||
|
IMPORT = "import"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
Index.MergeCommands(ice.Commands{
|
||||||
|
PACKAGE: {Name: "package main", Hand: func(m *ice.Message, arg ...string) {
|
||||||
|
s := _parse_stack(m)
|
||||||
|
s.skip = len(s.rest)
|
||||||
|
}},
|
||||||
|
IMPORT: {Name: "import ice shylinux.com/x/icebergs", Hand: func(m *ice.Message, arg ...string) {
|
||||||
|
load := func(pre string, u *url.URL, p string, r io.Reader) {
|
||||||
|
if kit.Ext(p) == nfs.SHY {
|
||||||
|
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 }) })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
find := func(pre, url string) {
|
||||||
|
u := kit.ParseURL(strings.TrimSuffix(strings.TrimPrefix(url, "\""), "\""))
|
||||||
|
pre = kit.Select(path.Base(u.Path), pre)
|
||||||
|
kit.If(pre == ice.PT, func() { pre = "" })
|
||||||
|
if ls := kit.Split(u.Path, ice.PS); path.Join(kit.Slice(ls, 0, 3)...) == ice.Info.Make.Module && nfs.Exists(m, path.Join(kit.Slice(ls, 3)...)) {
|
||||||
|
nfs.Open(m, path.Join(kit.Slice(ls, 3)...)+ice.PS, func(r io.Reader, p string) { load(pre, u, p, r) })
|
||||||
|
} else if p := path.Join(ice.USR_REQUIRE, u.Path) + ice.PS; nfs.Exists(m, p) {
|
||||||
|
nfs.Open(m, p, func(r io.Reader, p string) { load(pre, u, p, r) })
|
||||||
|
} else if p := nfs.USR + path.Join(kit.Slice(ls, 2)...) + ice.PS; nfs.Exists(m, p) {
|
||||||
|
nfs.Open(m, p, func(r io.Reader, p string) { load(pre, u, p, r) })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s := _parse_stack(m)
|
||||||
|
if p := s.next(m); p == OPEN {
|
||||||
|
for s.token() != CLOSE {
|
||||||
|
if list := s.nextLine(m); s.token() != CLOSE {
|
||||||
|
pos := s.Position
|
||||||
|
find(kit.Select("", list[0], len(list) > 1), kit.Select("", list, -1))
|
||||||
|
s.Position = pos
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
find(kit.Select("", s.rest[1], len(s.rest) > 2), kit.Select("", s.rest, -1))
|
||||||
|
}
|
||||||
|
}},
|
||||||
|
})
|
||||||
|
}
|
@ -4,6 +4,7 @@ import (
|
|||||||
"bufio"
|
"bufio"
|
||||||
"io"
|
"io"
|
||||||
"path"
|
"path"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
ice "shylinux.com/x/icebergs"
|
ice "shylinux.com/x/icebergs"
|
||||||
@ -13,10 +14,11 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type Function struct {
|
type Function struct {
|
||||||
obj []string
|
obj []Field
|
||||||
arg []string
|
arg []Field
|
||||||
res []string
|
res []Field
|
||||||
Position
|
Position
|
||||||
|
object Object
|
||||||
}
|
}
|
||||||
type Frame struct {
|
type Frame struct {
|
||||||
key string
|
key string
|
||||||
@ -29,7 +31,6 @@ type Stack struct {
|
|||||||
last *Frame
|
last *Frame
|
||||||
frame []*Frame
|
frame []*Frame
|
||||||
Position
|
Position
|
||||||
n int
|
|
||||||
}
|
}
|
||||||
type Position struct {
|
type Position struct {
|
||||||
rest []string
|
rest []string
|
||||||
@ -47,7 +48,7 @@ func (s *Stack) peekf() *Frame { return s.frame[len(s.frame)-1] }
|
|||||||
func (s *Stack) pushf(m *ice.Message, key string) *Frame {
|
func (s *Stack) pushf(m *ice.Message, key string) *Frame {
|
||||||
f := &Frame{key: kit.Select(m.CommandKey(), key), value: kit.Dict(), Position: s.Position}
|
f := &Frame{key: kit.Select(m.CommandKey(), key), value: kit.Dict(), Position: s.Position}
|
||||||
kit.If(len(s.frame) > 0, func() { f.status = s.peekf().status })
|
kit.If(len(s.frame) > 0, func() { f.status = s.peekf().status })
|
||||||
m.Debug("stack push %d %v %s:%d", len(s.frame), f.key, f.name, f.line)
|
m.Debug("stack %d push %s %s", len(s.frame), f.key, s.show())
|
||||||
s.frame = append(s.frame, f)
|
s.frame = append(s.frame, f)
|
||||||
return f
|
return f
|
||||||
}
|
}
|
||||||
@ -56,7 +57,7 @@ func (s *Stack) popf(m *ice.Message) *Frame {
|
|||||||
for i := len(f.defers) - 1; i >= 0; i-- {
|
for i := len(f.defers) - 1; i >= 0; i-- {
|
||||||
f.defers[i]()
|
f.defers[i]()
|
||||||
}
|
}
|
||||||
m.Debug("stack pop %d %v %s:%d", len(s.frame)-1, f.key, f.name, f.line)
|
m.Debug("stack %d pop %s %s", len(s.frame)-1, f.key, s.show())
|
||||||
kit.If(len(s.frame) > 0, func() { s.frame = s.frame[:len(s.frame)-1] })
|
kit.If(len(s.frame) > 0, func() { s.frame = s.frame[:len(s.frame)-1] })
|
||||||
s.last = f
|
s.last = f
|
||||||
return f
|
return f
|
||||||
@ -79,22 +80,72 @@ func (s *Stack) value(m *ice.Message, key string, arg ...Any) Any {
|
|||||||
return false
|
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() {
|
kit.If(len(arg) > 0, func() {
|
||||||
m.Debug("value set %d %v %#v", n, key, arg[0])
|
var v Any = Dict{f.value}
|
||||||
f.value[key] = arg[0]
|
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])
|
||||||
|
_v.Operate(k, arg[0])
|
||||||
|
} else {
|
||||||
|
if v = _v.Operate(SUBS, k); v == nil {
|
||||||
|
if _, e := strconv.ParseInt(keys[i+1], 10, 32); e == nil {
|
||||||
|
v = _v.Operate(k, List{})
|
||||||
|
} else {
|
||||||
|
v = _v.Operate(k, Dict{kit.Dict()})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
v = nil
|
||||||
|
}
|
||||||
|
}
|
||||||
})
|
})
|
||||||
if v, ok := f.value[key]; ok {
|
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 {
|
||||||
return v
|
return v
|
||||||
}
|
}
|
||||||
if k := kit.Select(key, strings.Split(key, ice.PT), -1); strings.ToUpper(k) == k {
|
|
||||||
if c, ok := ice.Info.Index[strings.ToLower(k)].(*ice.Context); ok && (key == k || key == c.Prefix(k)) {
|
|
||||||
return strings.ToLower(key)
|
|
||||||
}
|
}
|
||||||
|
v = s
|
||||||
|
kit.For(keys, func(k string) {
|
||||||
|
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
|
||||||
}
|
}
|
||||||
return nil
|
})
|
||||||
|
if v != nil {
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
return _parse_const(m, key)
|
||||||
}
|
}
|
||||||
func (s *Stack) runable() bool { return s.peekf().status > STATUS_DISABLE }
|
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) 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) read(m *ice.Message) (text string, ok bool) {
|
func (s *Stack) read(m *ice.Message) (text string, ok bool) {
|
||||||
isvoid := func(text string) bool {
|
isvoid := func(text string) bool {
|
||||||
return strings.TrimSpace(text) == "" || strings.HasPrefix(strings.TrimSpace(text), "#")
|
return strings.TrimSpace(text) == "" || strings.HasPrefix(strings.TrimSpace(text), "#")
|
||||||
@ -107,17 +158,37 @@ func (s *Stack) read(m *ice.Message) (text string, ok bool) {
|
|||||||
}
|
}
|
||||||
for s.input != nil && s.input.Scan() {
|
for s.input != nil && s.input.Scan() {
|
||||||
text = s.input.Text()
|
text = s.input.Text()
|
||||||
m.Debug("input read %d \"%s\" %s:%d", len(s.list), text, s.name, len(s.list))
|
|
||||||
if s.line, s.list = len(s.list), append(s.list, text); isvoid(text) {
|
if s.line, s.list = len(s.list), append(s.list, text); isvoid(text) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
m.Debug("input %d read \"%s\" %s", len(s.list), text, s.show())
|
||||||
return text, true
|
return text, true
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
func (s *Stack) reads(m *ice.Message, cb func(k string) bool) {
|
func (s *Stack) reads(m *ice.Message, cb func(k string) bool) {
|
||||||
|
block, last := []string{}, 0
|
||||||
for {
|
for {
|
||||||
if s.skip++; s.skip < len(s.rest) {
|
if s.skip++; s.skip < len(s.rest) {
|
||||||
|
if k := s.rest[s.skip]; k == "`" {
|
||||||
|
if len(block) > 0 {
|
||||||
|
kit.If(s.line != last, func() { block, last = append(block, ice.NL), s.line })
|
||||||
|
block = append(block, k)
|
||||||
|
cb(strings.Join(block, ice.SP))
|
||||||
|
block = block[:0]
|
||||||
|
} 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 {
|
||||||
|
s.skip = len(s.rest)
|
||||||
|
continue
|
||||||
|
}
|
||||||
if cb(s.rest[s.skip]) {
|
if cb(s.rest[s.skip]) {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@ -129,97 +200,147 @@ func (s *Stack) reads(m *ice.Message, cb func(k string) bool) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
func (s *Stack) nextLine(m *ice.Message) []string {
|
||||||
|
s.skip = len(s.rest)
|
||||||
|
s.reads(m, func(string) bool { return true })
|
||||||
|
return s.rest
|
||||||
|
}
|
||||||
|
func (s *Stack) next(m *ice.Message) string {
|
||||||
|
s.reads(m, func(k string) bool { return true })
|
||||||
|
return s.token()
|
||||||
|
}
|
||||||
|
func (s *Stack) peek(m *ice.Message) string {
|
||||||
|
pos := s.Position
|
||||||
|
defer func() { s.Position = pos }()
|
||||||
|
s.reads(m, func(k string) bool { return true })
|
||||||
|
return s.token()
|
||||||
|
}
|
||||||
|
func (s *Stack) pos(m *ice.Message, pos Position, n int) {
|
||||||
|
s.Position = pos
|
||||||
|
s.skip += n
|
||||||
|
}
|
||||||
func (s *Stack) run(m *ice.Message) {
|
func (s *Stack) run(m *ice.Message) {
|
||||||
begin := len(s.frame)
|
begin := len(s.frame)
|
||||||
s.reads(m, func(k string) bool {
|
s.reads(m, func(k string) bool {
|
||||||
if s.n++; s.n > 300 {
|
|
||||||
panic(s.n)
|
|
||||||
}
|
|
||||||
if k == SPLIT {
|
if k == SPLIT {
|
||||||
|
|
||||||
} else if k == END {
|
} else if k == END {
|
||||||
if s.last = s.popf(m); len(s.frame) < begin {
|
if s.last = s.popf(m); len(s.frame) < begin {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
} else if _, ok := m.Source().Commands[k]; ok {
|
||||||
|
m.Cmdy(k, kit.Slice(s.rest, s.skip+1))
|
||||||
} else if _, ok := m.Target().Commands[k]; ok {
|
} else if _, ok := m.Target().Commands[k]; ok {
|
||||||
m.Cmdy(k, kit.Slice(s.rest, s.skip+1))
|
m.Cmdy(k, kit.Slice(s.rest, s.skip+1))
|
||||||
} else {
|
} else {
|
||||||
s.skip--
|
if s.skip--; s.skip == -1 {
|
||||||
m.Cmdy(EXPR, kit.Slice(s.rest, s.skip))
|
m.Cmd(EXPR, s.rest, ice.SP, s.show())
|
||||||
|
} else {
|
||||||
|
m.Cmd(EXPR, kit.Slice(s.rest, s.skip), ice.SP, s.show())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
func (s *Stack) call(m *ice.Message, obj Any, key Any, cb func(*Frame, Function), arg ...Any) Any {
|
|
||||||
if _k, ok := key.(string); ok {
|
|
||||||
kit.For(kit.Split(_k, ice.PT), func(k string) {
|
|
||||||
switch v := obj.(type) {
|
|
||||||
case *Stack:
|
|
||||||
if v := v.value(m, _k); v != nil {
|
|
||||||
obj = v
|
|
||||||
break
|
|
||||||
}
|
|
||||||
obj, key = v.value(m, k), strings.TrimPrefix(_k, k+ice.PT)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
m.Debug("expr call %T %s %v", obj, key, kit.Format(arg))
|
|
||||||
switch obj := obj.(type) {
|
|
||||||
case Function:
|
|
||||||
f := s.pushf(m, CALL)
|
|
||||||
kit.For(obj.res, func(k string) { f.value[k] = "" })
|
|
||||||
kit.For(obj.arg, func(i int, k string) {
|
|
||||||
kit.If(i < len(arg), func() { f.value[k] = arg[i] }, func() { f.value[k] = "" })
|
|
||||||
})
|
|
||||||
value, pos := Value{list: kit.List()}, s.Position
|
|
||||||
f.value["_return"] = func(arg ...Any) {
|
|
||||||
if len(obj.res) > 0 {
|
|
||||||
kit.For(obj.res, func(i int, k string) {
|
|
||||||
kit.If(i < len(arg), func() { value.list = append(value.list, f.value[k]) }, func() { value.list = append(value.list, "") })
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
value.list = arg
|
|
||||||
}
|
|
||||||
}
|
|
||||||
f.defers, s.Position = append(f.defers, func() {
|
|
||||||
if len(obj.res) > 0 && len(value.list) == 0 {
|
|
||||||
kit.For(obj.res, func(i int, k string) { value.list = append(value.list, f.value[k]) })
|
|
||||||
}
|
|
||||||
s.Position = pos
|
|
||||||
}), obj.Position
|
|
||||||
kit.If(cb != nil, func() { cb(f, obj) })
|
|
||||||
s.run(m.Options(STACK, s))
|
|
||||||
return value
|
|
||||||
case Caller:
|
|
||||||
return obj.Call(kit.Format(key), arg...)
|
|
||||||
case func(*ice.Message, string, ...Any) Any:
|
|
||||||
kit.For(arg, func(i int, v Any) { arg[i] = trans(arg[i]) })
|
|
||||||
return wrap(obj(m, kit.Format(key), arg...))
|
|
||||||
case func(string, ...Any) Any:
|
|
||||||
return obj(kit.Format(key), arg...)
|
|
||||||
case func():
|
|
||||||
obj()
|
|
||||||
return nil
|
|
||||||
default:
|
|
||||||
args := kit.List(key)
|
|
||||||
for _, v := range arg {
|
|
||||||
switch v := v.(type) {
|
|
||||||
case Value:
|
|
||||||
args = append(args, v.list...)
|
|
||||||
default:
|
|
||||||
args = append(args, trans(v))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return Message{m.Cmd(args...)}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
func (s *Stack) cals(m *ice.Message) Any { return NewExpr(s).cals(m) }
|
|
||||||
func (s *Stack) expr(m *ice.Message, pos ...Position) string {
|
func (s *Stack) expr(m *ice.Message, pos ...Position) string {
|
||||||
kit.If(len(pos) > 0, func() { s.Position = pos[0] })
|
kit.If(len(pos) > 0, func() { s.Position = pos[0] })
|
||||||
return m.Cmdx(EXPR, kit.Slice(s.rest, s.skip))
|
return m.Cmdx(EXPR, kit.Slice(s.rest, s.skip))
|
||||||
}
|
}
|
||||||
|
func (s *Stack) cals(m *ice.Message, arg ...string) Any {
|
||||||
|
sub := NewExpr(s)
|
||||||
|
return sub.cals(m, arg...)
|
||||||
|
}
|
||||||
|
func (s *Stack) cals0(m *ice.Message, arg ...string) string {
|
||||||
|
sub := NewExpr(s)
|
||||||
|
sub.cals(m, arg...)
|
||||||
|
return sub.gets(0)
|
||||||
|
}
|
||||||
|
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)
|
||||||
|
s.skip += 2
|
||||||
|
return Map{key: key, value: s.types(m)}
|
||||||
|
case SUBS:
|
||||||
|
s.skip += 2
|
||||||
|
return Slice{value: s.types(m)}
|
||||||
|
case STRUCT:
|
||||||
|
key, t := []string{}, Struct{index: map[string]Any{}}
|
||||||
|
for s.next(m); s.next(m) != END; {
|
||||||
|
if key = append(key, s.token()); s.next(m) == FIELD {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
types := s.types(m)
|
||||||
|
kit.For(key, func(key string) {
|
||||||
|
field := Field{key, types}
|
||||||
|
t.field = append(t.field, field)
|
||||||
|
t.index[key] = field
|
||||||
|
})
|
||||||
|
key, s.skip = key[:0], len(s.rest)
|
||||||
|
}
|
||||||
|
return t
|
||||||
|
case INTERFACE:
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
return t
|
||||||
|
case FUNC:
|
||||||
|
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{}) })
|
||||||
|
return Function{arg: list[0], res: list[1]}
|
||||||
|
default:
|
||||||
|
// if t := s.value(m, s.token()); t != nil && t != "" {
|
||||||
|
// return t
|
||||||
|
// }
|
||||||
|
return s.token()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
func (s *Stack) funcs(m *ice.Message) string {
|
func (s *Stack) funcs(m *ice.Message) string {
|
||||||
name := kit.Format("%s:%d:%d", s.name, s.line, s.skip)
|
name := s.show()
|
||||||
s.rest[s.skip], s.skip = name, s.skip-1
|
s.rest[s.skip], s.skip = name, s.skip-1
|
||||||
m.Cmd(FUNC, name)
|
m.Cmd(FUNC, name)
|
||||||
f := s.peekf()
|
f := s.peekf()
|
||||||
@ -229,30 +350,120 @@ func (s *Stack) funcs(m *ice.Message) string {
|
|||||||
s.run(m)
|
s.run(m)
|
||||||
return name
|
return name
|
||||||
}
|
}
|
||||||
func (s *Stack) parse(m *ice.Message, name string, r io.Reader, cb func(*Frame)) *Stack {
|
func (s *Stack) calls(m *ice.Message, obj Any, key Any, cb func(*Frame, Function), arg ...Any) Any {
|
||||||
s.Buffer = &Buffer{name: name, input: bufio.NewScanner(r)}
|
if _k, ok := key.(string); ok && _k != "" {
|
||||||
s.load(m, cb).run(m)
|
kit.For(kit.Split(_k, ice.PT), func(k string) {
|
||||||
|
switch v := obj.(type) {
|
||||||
|
case Operater:
|
||||||
|
obj = v.Operate(SUBS, k)
|
||||||
|
case *Stack:
|
||||||
|
if _v := v.value(m, _k); _v != nil {
|
||||||
|
obj, key = _v, ""
|
||||||
|
} else {
|
||||||
|
obj, key = v.value(m, k), strings.TrimPrefix(_k, 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)
|
||||||
|
for _, field := range obj.res {
|
||||||
|
f.value[field.name] = nil
|
||||||
|
}
|
||||||
|
for i, field := range obj.arg {
|
||||||
|
kit.If(i < len(arg), func() { f.value[field.name] = arg[i] }, func() { f.value[field.name] = nil })
|
||||||
|
}
|
||||||
|
kit.If(len(obj.obj) > 1, func() { f.value[obj.obj[0].name] = obj.object })
|
||||||
|
value, pos := Value{list: kit.List()}, s.Position
|
||||||
|
f.value["_return"] = func(arg ...Any) {
|
||||||
|
if len(obj.res) > 0 {
|
||||||
|
for i, field := range obj.res {
|
||||||
|
kit.If(i < len(arg), func() { value.list = append(value.list, f.value[field.name]) }, func() { value.list = append(value.list, nil) })
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
value.list = arg
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s.Position, f.defers = obj.Position, append(f.defers, func() {
|
||||||
|
if len(obj.res) > 0 && len(value.list) == 0 {
|
||||||
|
for _, field := range obj.res {
|
||||||
|
value.list = append(value.list, f.value[field.name])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s.Position = pos
|
||||||
|
})
|
||||||
|
kit.If(cb != nil, func() { cb(f, obj) })
|
||||||
|
s.run(m.Options(STACK, s))
|
||||||
|
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]) })
|
||||||
|
return wrap(obj.Call(kit.Format(key), arg...))
|
||||||
|
case func(*ice.Message, string, ...Any) Any:
|
||||||
|
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]) })
|
||||||
|
return wrap(obj(m, kit.Format(key), arg...))
|
||||||
|
case func():
|
||||||
|
obj()
|
||||||
|
return nil
|
||||||
|
default:
|
||||||
|
args := kit.List(key)
|
||||||
|
kit.For(arg, func(i int, v Any) { args = append(args, trans(v)) })
|
||||||
|
return Message{m.Cmd(args...)}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func (s *Stack) action(m *ice.Message, obj Any, key Any, arg ...string) *ice.Message {
|
||||||
|
s.calls(m, obj, key, func(f *Frame, v Function) {
|
||||||
|
i := 0
|
||||||
|
for _, field := range v.arg {
|
||||||
|
switch field.name {
|
||||||
|
case "m", "msg":
|
||||||
|
f.value[field.name] = Message{m}
|
||||||
|
case ice.ARG:
|
||||||
|
list := kit.List()
|
||||||
|
kit.For(arg, func(v string) { list = append(list, String{v}) })
|
||||||
|
f.value[field.name] = Value{list}
|
||||||
|
default:
|
||||||
|
f.value[field.name], i = String{m.Option(field.name, kit.Select(m.Option(field.name), arg, i))}, i+1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return m
|
||||||
|
}
|
||||||
|
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())
|
||||||
|
s.run(m)
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
func NewStack(m *ice.Message, cb func(*Frame)) *Stack {
|
||||||
|
s := &Stack{}
|
||||||
|
s.pushf(m.Options(STACK, s), STACK)
|
||||||
|
s.load(m, cb)
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
func NewStack() *Stack { return &Stack{} }
|
|
||||||
|
|
||||||
func _parse_stack(m *ice.Message) *Stack { return m.Optionv(STACK).(*Stack) }
|
func _parse_stack(m *ice.Message) *Stack { return m.Optionv(STACK).(*Stack) }
|
||||||
func _parse_frame(m *ice.Message) (*Stack, *Frame) {
|
func _parse_frame(m *ice.Message) (*Stack, *Frame) {
|
||||||
return _parse_stack(m), _parse_stack(m).pushf(m, "")
|
return _parse_stack(m), _parse_stack(m).pushf(m, "")
|
||||||
}
|
}
|
||||||
func _parse_cache(m *ice.Message, name string) *Stack {
|
func _parse_const(m *ice.Message, key string) string {
|
||||||
key := kit.Keys(m.PrefixKey(), name)
|
if k := kit.Select(key, strings.Split(key, ice.PT), -1); kit.IsUpper(k) {
|
||||||
s := mdb.Cache(m, key, func() (v Any) {
|
if c, ok := ice.Info.Index[strings.ToLower(k)].(*ice.Context); ok && (key == k || key == c.Prefix(k)) {
|
||||||
nfs.Open(m, existsFile(m, name), func(r io.Reader, p string) {
|
return strings.ToLower(k)
|
||||||
v = NewStack().parse(m.Spawn(), p, r, nil)
|
}
|
||||||
})
|
}
|
||||||
return
|
return ""
|
||||||
}).(*Stack)
|
|
||||||
kit.If(m.Option(ice.DEBUG) == ice.TRUE, func() { mdb.Cache(m, key, nil) })
|
|
||||||
return s
|
|
||||||
}
|
}
|
||||||
func _parse_res(m *ice.Message, v Any) []Any {
|
func _parse_res(m *ice.Message, v Any) []Any {
|
||||||
switch v := v.(type) {
|
switch v := v.(type) {
|
||||||
|
case nil:
|
||||||
|
return nil
|
||||||
case Value:
|
case Value:
|
||||||
return v.list
|
return v.list
|
||||||
default:
|
default:
|
||||||
@ -269,64 +480,71 @@ const STACK = "stack"
|
|||||||
func init() {
|
func init() {
|
||||||
Index.MergeCommands(ice.Commands{
|
Index.MergeCommands(ice.Commands{
|
||||||
STACK: {Name: "stack path auto parse", Actions: ice.Actions{
|
STACK: {Name: "stack path auto parse", Actions: ice.Actions{
|
||||||
ice.CMD: {Hand: func(m *ice.Message, arg ...string) {
|
"start": {Hand: func(m *ice.Message, arg ...string) {}},
|
||||||
s := _parse_cache(m, arg[0])
|
ice.CMD: {Hand: func(m *ice.Message, arg ...string) {}},
|
||||||
meta := kit.Dict()
|
ice.RUN: {Hand: func(m *ice.Message, arg ...string) {}},
|
||||||
|
}, 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 {
|
||||||
|
m.Cmdy(INFO, arg)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}},
|
||||||
|
})
|
||||||
|
loaded := kit.Dict()
|
||||||
|
ice.AddMergeAction(func(c *ice.Context, key string, cmd *ice.Command, sub string, action *ice.Action) (init ice.Handler) {
|
||||||
|
kit.IfNoKey(loaded, ice.SRC_SCRIPT+c.Prefix(key)+ice.PS, func(p string) { kit.If(nfs.Exists(ice.Pulse, p), func() { init = StackHandler }) })
|
||||||
|
return
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func StackHandler(m *ice.Message, arg ...string) {
|
||||||
|
s := NewStack(m, nil)
|
||||||
|
script := []string{}
|
||||||
|
nfs.Open(m, ice.SRC_SCRIPT+m.PrefixKey()+ice.PS, func(r io.Reader, p string) {
|
||||||
|
kit.If(kit.Ext(p) == nfs.SHY, func() {
|
||||||
|
if strings.HasPrefix(path.Base(p), "on") {
|
||||||
|
script = append(script, kit.Format("Volcanos(\"%s\", {", kit.TrimExt(path.Base(p), nfs.SHY)))
|
||||||
|
kit.For(r, func(s string) {
|
||||||
|
if strings.HasPrefix(s, FUNC) {
|
||||||
|
script = append(script, ice.TB+strings.Replace(strings.TrimPrefix(s, FUNC+ice.SP), "(", ": function(", 1))
|
||||||
|
} else if strings.HasPrefix(s, END) {
|
||||||
|
script = append(script, ice.TB+"},")
|
||||||
|
} else {
|
||||||
|
script = append(script, ice.TB+s)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
script = append(script, "})")
|
||||||
|
} else {
|
||||||
|
s.parse(m.Spawn(Index).Spawn(m.Target()), p, r)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
if len(script) > 0 {
|
||||||
|
p := ice.USR_SCRIPT + m.PrefixKey() + ice.PS + "list.js"
|
||||||
|
s.value(m, "_script", "/require/"+p)
|
||||||
|
m.Cmd(nfs.SAVE, p, kit.Dict(nfs.CONTENT, strings.Join(script, ice.NL)))
|
||||||
|
}
|
||||||
|
cmd := m.Commands("")
|
||||||
kit.For(s.peekf().value, func(k string, v Any) {
|
kit.For(s.peekf().value, func(k string, v Any) {
|
||||||
switch v := v.(type) {
|
switch v := v.(type) {
|
||||||
case Function:
|
case Function:
|
||||||
list := kit.List()
|
list := kit.List()
|
||||||
kit.For(v.arg, func(k string) {
|
for _, field := range v.arg {
|
||||||
if !kit.IsIn(k, "m", ice.ARG) {
|
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, "")) })
|
||||||
list = append(list, kit.Dict(mdb.NAME, k, 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)) })
|
kit.If(k == mdb.LIST, func() { list = append(list, kit.Dict(mdb.NAME, mdb.LIST, mdb.TYPE, "button", mdb.ACTION, ice.AUTO)) })
|
||||||
meta[k] = list
|
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
|
||||||
m.Push(ice.INDEX, arg[0])
|
|
||||||
m.Push(mdb.NAME, arg[0])
|
|
||||||
m.Push(mdb.HELP, arg[0])
|
|
||||||
m.Push(mdb.LIST, kit.Format(meta[mdb.LIST]))
|
|
||||||
m.Push(mdb.META, kit.Format(meta))
|
|
||||||
}},
|
|
||||||
ice.RUN: {Hand: func(m *ice.Message, arg ...string) {
|
|
||||||
s := _parse_cache(m, arg[0])
|
|
||||||
action, i := mdb.LIST, 0
|
|
||||||
if len(arg) > 2 && arg[1] == ice.ACTION && s.value(m, arg[2]) != nil {
|
|
||||||
action, arg = arg[2], arg[3:]
|
|
||||||
} else {
|
} else {
|
||||||
arg = arg[1:]
|
cmd.Actions[k], cmd.Meta[k] = &ice.Action{Hand: h}, list
|
||||||
}
|
}
|
||||||
s.call(m.StatusTime(), s, action, func(f *Frame, v Function) {
|
|
||||||
kit.For(v.arg, func(k string) {
|
|
||||||
switch k {
|
|
||||||
case "m":
|
|
||||||
f.value[k] = Message{m}
|
|
||||||
case ice.ARG:
|
|
||||||
list := kit.List()
|
|
||||||
kit.For(arg, func(v string) { list = append(list, String{v}) })
|
|
||||||
f.value[k] = Value{list}
|
|
||||||
default:
|
|
||||||
f.value[k], i = String{m.Option(k, kit.Select(m.Option(k), arg, i))}, i+1
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
|
||||||
}},
|
|
||||||
}, Hand: func(m *ice.Message, arg ...string) {
|
|
||||||
if m.Options(nfs.DIR_ROOT, nfs.SRC).Cmdy(nfs.CAT, arg); len(m.Result()) == 0 {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
nfs.Open(m, path.Join(nfs.SRC, path.Join(arg...)), func(r io.Reader, p string) {
|
|
||||||
if NewStack().parse(m, p, r, nil); m.Option(ice.DEBUG) == ice.TRUE {
|
|
||||||
m.EchoLine("").EchoLine("stack: %s", arg[0]).Cmdy(INFO)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}},
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
func existsFile(m *ice.Message, p string) string {
|
func StackAction() ice.Actions { return ice.Actions{ice.CTX_INIT: {Hand: StackHandler}} }
|
||||||
return nfs.SRC + strings.Replace(p, ice.PT, ice.PS, -1) + ice.PT + nfs.SHY
|
|
||||||
}
|
|
||||||
func ExistsFile(m *ice.Message, p string) bool { return nfs.Exists(m, existsFile(m, p)) }
|
|
||||||
|
@ -13,12 +13,14 @@ const (
|
|||||||
IF = "if"
|
IF = "if"
|
||||||
ELSE = "else"
|
ELSE = "else"
|
||||||
FOR = "for"
|
FOR = "for"
|
||||||
|
RANGE = "range"
|
||||||
BREAK = "break"
|
BREAK = "break"
|
||||||
CONTINUE = "continue"
|
CONTINUE = "continue"
|
||||||
SWITCH = "switch"
|
SWITCH = "switch"
|
||||||
CASE = "case"
|
CASE = "case"
|
||||||
DEFAULT = "default"
|
DEFAULT = "default"
|
||||||
FUNC = "func"
|
FUNC = "func"
|
||||||
|
INIT = "init"
|
||||||
CALL = "call"
|
CALL = "call"
|
||||||
DEFER = "defer"
|
DEFER = "defer"
|
||||||
RETURN = "return"
|
RETURN = "return"
|
||||||
@ -42,9 +44,9 @@ func init() {
|
|||||||
ELSE: {Name: "else if a = 1; a > 1 {", Hand: func(m *ice.Message, arg ...string) {
|
ELSE: {Name: "else if a = 1; a > 1 {", Hand: func(m *ice.Message, arg ...string) {
|
||||||
s, f := _parse_frame(m)
|
s, f := _parse_frame(m)
|
||||||
if s.last.status == STATUS_DISABLE {
|
if s.last.status == STATUS_DISABLE {
|
||||||
f.status = 0
|
f.status = STATUS_NORMAL
|
||||||
} else {
|
} else {
|
||||||
f.status, f.defers = STATUS_DISABLE, append(f.defers, func() { f.status = 0 })
|
f.status, f.defers = STATUS_DISABLE, append(f.defers, func() { f.status = STATUS_NORMAL })
|
||||||
}
|
}
|
||||||
s.reads(m, func(k string) bool {
|
s.reads(m, func(k string) bool {
|
||||||
if k == IF {
|
if k == IF {
|
||||||
@ -57,6 +59,27 @@ func init() {
|
|||||||
}},
|
}},
|
||||||
FOR: {Name: "for a = 1; a < 10; a++ {", Hand: func(m *ice.Message, arg ...string) {
|
FOR: {Name: "for a = 1; a < 10; a++ {", Hand: func(m *ice.Message, arg ...string) {
|
||||||
s, f := _parse_frame(m)
|
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 {
|
||||||
|
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
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
f.status = STATUS_DISABLE
|
||||||
|
break
|
||||||
|
} else if k != "" {
|
||||||
|
key = append(key, k)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
f.defers = append(f.defers, func() { kit.If(s.runable(), func() { s.pos(m, pos, -1) }) })
|
||||||
|
return
|
||||||
|
}
|
||||||
list, status := []Position{s.Position}, f.status
|
list, status := []Position{s.Position}, f.status
|
||||||
for f.status = STATUS_DISABLE; s.token() != BEGIN; list = append(list, s.Position) {
|
for f.status = STATUS_DISABLE; s.token() != BEGIN; list = append(list, s.Position) {
|
||||||
s.expr(m)
|
s.expr(m)
|
||||||
@ -91,8 +114,7 @@ func init() {
|
|||||||
}
|
}
|
||||||
s.stack(func(f *Frame, i int) bool {
|
s.stack(func(f *Frame, i int) bool {
|
||||||
f.status = STATUS_DISABLE
|
f.status = STATUS_DISABLE
|
||||||
defer s.popf(m)
|
switch s.popf(m); f.key {
|
||||||
switch f.key {
|
|
||||||
case FOR, SWITCH:
|
case FOR, SWITCH:
|
||||||
return true
|
return true
|
||||||
default:
|
default:
|
||||||
@ -106,8 +128,7 @@ func init() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
s.stack(func(f *Frame, i int) bool {
|
s.stack(func(f *Frame, i int) bool {
|
||||||
defer s.popf(m)
|
switch s.popf(m); f.key {
|
||||||
switch f.key {
|
|
||||||
case FOR:
|
case FOR:
|
||||||
return true
|
return true
|
||||||
default:
|
default:
|
||||||
@ -124,7 +145,7 @@ func init() {
|
|||||||
CASE: {Name: "case b:", Hand: func(m *ice.Message, arg ...string) {
|
CASE: {Name: "case b:", Hand: func(m *ice.Message, arg ...string) {
|
||||||
s := _parse_stack(m)
|
s := _parse_stack(m)
|
||||||
f := s.peekf()
|
f := s.peekf()
|
||||||
f.status = 0
|
f.status = STATUS_NORMAL
|
||||||
v := s.cals(m)
|
v := s.cals(m)
|
||||||
f.status = STATUS_DISABLE
|
f.status = STATUS_DISABLE
|
||||||
if res, ok := v.(Operater); ok {
|
if res, ok := v.(Operater); ok {
|
||||||
@ -136,19 +157,21 @@ func init() {
|
|||||||
DEFAULT: {Name: "default:", Hand: func(m *ice.Message, arg ...string) {
|
DEFAULT: {Name: "default:", Hand: func(m *ice.Message, arg ...string) {
|
||||||
s := _parse_stack(m)
|
s := _parse_stack(m)
|
||||||
f := s.peekf()
|
f := s.peekf()
|
||||||
if f.status = 0; f.value["_case"] == "done" {
|
if f.status = STATUS_NORMAL; f.value["_case"] == "done" {
|
||||||
f.status = STATUS_DISABLE
|
f.status = STATUS_DISABLE
|
||||||
}
|
}
|
||||||
s.skip++
|
s.skip++
|
||||||
}},
|
}},
|
||||||
FUNC: {Name: "func show(a, b) (c, d)", Hand: func(m *ice.Message, arg ...string) {
|
FUNC: {Name: "func show(a, b) (c, d)", Hand: func(m *ice.Message, arg ...string) {
|
||||||
s := _parse_stack(m)
|
s := _parse_stack(m)
|
||||||
list, key, kind := [][]string{[]string{}}, "", ""
|
list, key, kind := [][]Field{[]Field{}}, "", ""
|
||||||
push := func() { kit.If(key, func() { list[len(list)-1], key, kind = append(list[len(list)-1], key), "", "" }) }
|
push := func() {
|
||||||
|
kit.If(key, func() { list[len(list)-1], key, kind = append(list[len(list)-1], Field{name: key, kind: kind}), "", "" })
|
||||||
|
}
|
||||||
s.reads(m, func(k string) bool {
|
s.reads(m, func(k string) bool {
|
||||||
switch k {
|
switch k {
|
||||||
case OPEN:
|
case OPEN:
|
||||||
defer kit.If(key != "" || len(list) > 1, func() { list = append(list, []string{}) })
|
defer kit.If(key != "" || len(list) > 1, func() { list = append(list, []Field{}) })
|
||||||
case FIELD, CLOSE:
|
case FIELD, CLOSE:
|
||||||
case BEGIN:
|
case BEGIN:
|
||||||
return true
|
return true
|
||||||
@ -159,47 +182,50 @@ func init() {
|
|||||||
push()
|
push()
|
||||||
return false
|
return false
|
||||||
})
|
})
|
||||||
kit.If(len(list) < 2, func() { list = append(list, []string{}) })
|
kit.If(len(list) < 2, func() { list = append(list, []Field{}) })
|
||||||
kit.If(len(list) < 3, func() { list = append(list, []string{}) })
|
kit.If(len(list) < 3, func() { list = append(list, []Field{}) })
|
||||||
s.value(m, kit.Select("", list[0], -1), Function{obj: list[0], arg: list[1], res: list[2], Position: s.Position})
|
name, fun := list[0][len(list[0])-1].name, Function{obj: list[0], arg: list[1], res: list[2], Position: s.Position}
|
||||||
s.pushf(m, "").status = STATUS_DISABLE
|
if len(list[0]) > 1 {
|
||||||
|
st := list[0][0].kind.(Struct)
|
||||||
|
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
|
||||||
|
}
|
||||||
}},
|
}},
|
||||||
DEFER: {Name: "defer func() {} ()", Hand: func(m *ice.Message, arg ...string) {
|
DEFER: {Name: "defer func() {} ()", Hand: func(m *ice.Message, arg ...string) {
|
||||||
s := _parse_stack(m)
|
s := _parse_stack(m)
|
||||||
s.reads(m, func(k string) bool {
|
k := s.next(m)
|
||||||
kit.If(k == FUNC, func() { k = s.funcs(m) })
|
kit.If(k == FUNC, func() { k = s.funcs(m) })
|
||||||
s.skip++
|
s.skip++
|
||||||
v := s.cals(m)
|
args := _parse_res(m, s.cals(m))
|
||||||
if !s.runable() {
|
if !s.runable() {
|
||||||
return true
|
return
|
||||||
}
|
|
||||||
if vv, ok := v.(Value); ok {
|
|
||||||
v = vv.list
|
|
||||||
} else {
|
|
||||||
v = []Any{v}
|
|
||||||
}
|
}
|
||||||
s.stack(func(f *Frame, i int) bool {
|
s.stack(func(f *Frame, i int) bool {
|
||||||
if f.key == CALL {
|
if f.key == CALL {
|
||||||
f.defers = append(f.defers, func() { s.call(m, s, k, nil, v.([]Any)...) })
|
f.defers = append(f.defers, func() { s.calls(m, s, k, nil, args...) })
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
})
|
})
|
||||||
return true
|
|
||||||
})
|
|
||||||
}},
|
}},
|
||||||
RETURN: {Name: "return show", Hand: func(m *ice.Message, arg ...string) {
|
RETURN: {Name: "return show", Hand: func(m *ice.Message, arg ...string) {
|
||||||
s := _parse_stack(m)
|
s := _parse_stack(m)
|
||||||
v := s.cals(m)
|
args := _parse_res(m, s.cals(m))
|
||||||
s.stack(func(f *Frame, i int) bool {
|
s.stack(func(f *Frame, i int) bool {
|
||||||
f.status = STATUS_DISABLE
|
f.status = STATUS_DISABLE
|
||||||
switch f.key {
|
switch f.key {
|
||||||
case FUNC:
|
case FUNC:
|
||||||
|
|
||||||
case CALL:
|
case CALL:
|
||||||
switch cb := f.value["_return"].(type) {
|
switch cb := f.value["_return"].(type) {
|
||||||
case func(...Any):
|
case func(...Any):
|
||||||
cb(_parse_res(m, v)...)
|
cb(args...)
|
||||||
}
|
}
|
||||||
case SOURCE:
|
case SOURCE:
|
||||||
s.input = nil
|
s.input = nil
|
||||||
@ -215,17 +241,24 @@ func init() {
|
|||||||
s := _parse_stack(m)
|
s := _parse_stack(m)
|
||||||
u := kit.ParseURL(s.expr(m))
|
u := kit.ParseURL(s.expr(m))
|
||||||
nfs.Open(m, u.Path, func(r io.Reader, p string) {
|
nfs.Open(m, u.Path, func(r io.Reader, p string) {
|
||||||
f := s.parse(m, p, r, func(f *Frame) { kit.For(u.Query(), func(k string, v []string) { f.value[k] = v[0] }) }).popf(m)
|
s.parse(m, p, r)
|
||||||
s.Position = f.Position
|
|
||||||
s.skip = len(s.rest)
|
s.skip = len(s.rest)
|
||||||
})
|
})
|
||||||
}},
|
}},
|
||||||
INFO: {Name: "info", Hand: func(m *ice.Message, arg ...string) {
|
INFO: {Name: "info", Hand: func(m *ice.Message, arg ...string) {
|
||||||
|
m.EchoLine("").EchoLine("stack: %s", arg[0])
|
||||||
_parse_stack(m).stack(func(f *Frame, i int) bool {
|
_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)
|
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) })
|
kit.For(f.value, func(k string, v Any) { m.EchoLine(" %s: %#v", k, v) })
|
||||||
return false
|
return false
|
||||||
})
|
})
|
||||||
|
m.EchoLine("stmt: %s", arg[0])
|
||||||
|
for key, cmd := range m.Target().Commands {
|
||||||
|
if strings.HasPrefix(key, "_") || strings.HasPrefix(key, "/") {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
m.EchoLine(" %s: %#v", key, cmd.Name)
|
||||||
|
}
|
||||||
}},
|
}},
|
||||||
PWD: {Name: "pwd", Hand: func(m *ice.Message, arg ...string) {
|
PWD: {Name: "pwd", Hand: func(m *ice.Message, arg ...string) {
|
||||||
s := _parse_stack(m)
|
s := _parse_stack(m)
|
||||||
|
99
base/yac/type.go
Normal file
99
base/yac/type.go
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
package yac
|
||||||
|
|
||||||
|
import (
|
||||||
|
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
|
||||||
|
}
|
||||||
|
type Slice struct {
|
||||||
|
value Any
|
||||||
|
}
|
||||||
|
type Interface struct {
|
||||||
|
index map[string]Function
|
||||||
|
}
|
||||||
|
type Struct struct {
|
||||||
|
index map[string]Any
|
||||||
|
method []Function
|
||||||
|
field []Field
|
||||||
|
}
|
||||||
|
type Field struct {
|
||||||
|
name string
|
||||||
|
kind Any
|
||||||
|
}
|
||||||
|
type Object struct {
|
||||||
|
value Operater
|
||||||
|
index Struct
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s Object) Operate(op string, v Any) Any {
|
||||||
|
switch op {
|
||||||
|
case "&", "*":
|
||||||
|
return s
|
||||||
|
case SUBS:
|
||||||
|
switch v := s.index.index[kit.Format(v)].(type) {
|
||||||
|
case Function:
|
||||||
|
v.object = s
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
fallthrough
|
||||||
|
default:
|
||||||
|
return s.value.Operate(op, v)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
Index.MergeCommands(ice.Commands{
|
||||||
|
CONST: {Name: "const a = 1", Hand: func(m *ice.Message, arg ...string) {
|
||||||
|
if s := _parse_stack(m); s.next(m) == OPEN {
|
||||||
|
for s.token() != CLOSE {
|
||||||
|
s.nextLine(m)
|
||||||
|
s.skip--
|
||||||
|
s.cals(m, CLOSE)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
s.skip--
|
||||||
|
s.cals(m)
|
||||||
|
}
|
||||||
|
}},
|
||||||
|
TYPE: {Name: "type student struct {", Hand: func(m *ice.Message, arg ...string) {
|
||||||
|
s := _parse_stack(m)
|
||||||
|
switch name := s.next(m); s.next(m) {
|
||||||
|
case ASSIGN:
|
||||||
|
s.next(m)
|
||||||
|
fallthrough
|
||||||
|
default:
|
||||||
|
s.value(m, name, s.types(m))
|
||||||
|
}
|
||||||
|
}},
|
||||||
|
VAR: {Name: "var a = 1", Hand: func(m *ice.Message, arg ...string) {
|
||||||
|
if s := _parse_stack(m); s.next(m) == OPEN {
|
||||||
|
for s.token() != CLOSE {
|
||||||
|
s.nextLine(m)
|
||||||
|
s.skip--
|
||||||
|
s.cals(m, CLOSE)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
s.skip--
|
||||||
|
s.cals(m)
|
||||||
|
}
|
||||||
|
}},
|
||||||
|
})
|
||||||
|
}
|
@ -2,7 +2,9 @@ package yac
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
ice "shylinux.com/x/icebergs"
|
ice "shylinux.com/x/icebergs"
|
||||||
kit "shylinux.com/x/toolkits"
|
kit "shylinux.com/x/toolkits"
|
||||||
@ -20,7 +22,6 @@ type Operater interface{ Operate(string, Any) Any }
|
|||||||
|
|
||||||
func (s Dict) MarshalJSON() ([]byte, error) { return json.Marshal(s.value) }
|
func (s Dict) MarshalJSON() ([]byte, error) { return json.Marshal(s.value) }
|
||||||
func (s List) MarshalJSON() ([]byte, error) { return json.Marshal(s.value) }
|
func (s List) MarshalJSON() ([]byte, error) { return json.Marshal(s.value) }
|
||||||
func (s Value) MarshalJSON() ([]byte, error) { return json.Marshal(s.list) }
|
|
||||||
func (s String) 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 Number) MarshalJSON() ([]byte, error) { return json.Marshal(s.value) }
|
||||||
func (s Boolean) MarshalJSON() ([]byte, error) { return json.Marshal(s.value) }
|
func (s Boolean) MarshalJSON() ([]byte, error) { return json.Marshal(s.value) }
|
||||||
@ -49,9 +50,10 @@ func trans(v Any) Any {
|
|||||||
return v.value
|
return v.value
|
||||||
case Value:
|
case Value:
|
||||||
if len(v.list) > 0 {
|
if len(v.list) > 0 {
|
||||||
return v.list[0]
|
return trans(v.list[0])
|
||||||
}
|
} else {
|
||||||
return nil
|
return nil
|
||||||
|
}
|
||||||
case String:
|
case String:
|
||||||
return v.value
|
return v.value
|
||||||
case Number:
|
case Number:
|
||||||
@ -64,23 +66,57 @@ func trans(v Any) Any {
|
|||||||
}
|
}
|
||||||
func (s Dict) Operate(op string, v Any) Any {
|
func (s Dict) Operate(op string, v Any) Any {
|
||||||
switch op {
|
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:
|
case SUBS:
|
||||||
return wrap(kit.Value(s.value, kit.Format(v)))
|
return wrap(kit.Value(s.value, kit.Format(v)))
|
||||||
|
default:
|
||||||
|
s.value[op] = v
|
||||||
|
return v
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
func (s List) Operate(op string, v Any) Any {
|
func (s List) Operate(op string, v Any) Any {
|
||||||
switch op {
|
switch op {
|
||||||
case SUBS:
|
case RANGE:
|
||||||
return wrap(kit.Value(s.value, kit.Format(v)))
|
switch list := v.(type) {
|
||||||
|
case []Any:
|
||||||
|
if list != nil && len(list) > 1 {
|
||||||
|
if i := kit.Int(list[0]) + 1; i < len(s.value) {
|
||||||
|
return []Any{i, s.value[i]}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if len(s.value) > 0 {
|
||||||
|
return []Any{0, s.value[0]}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
|
||||||
func (s Value) Operate(op string, v Any) Any {
|
|
||||||
switch op {
|
|
||||||
case SUBS:
|
case SUBS:
|
||||||
if i := kit.Int(v); i < len(s.list) {
|
return wrap(kit.Value(s.value, kit.Format(v)))
|
||||||
return s.list[i]
|
default:
|
||||||
|
if i, e := strconv.ParseInt(op, 10, 32); e == nil {
|
||||||
|
switch (int(i)+2+len(s.value)+2)%(len(s.value)+2) - 2 {
|
||||||
|
case -1:
|
||||||
|
s.value = append([]Any{v}, s.value...)
|
||||||
|
case -2:
|
||||||
|
s.value = append(s.value, v)
|
||||||
|
default:
|
||||||
|
s.value[i] = v
|
||||||
|
}
|
||||||
|
return v
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@ -149,56 +185,99 @@ func (s Boolean) Operate(op string, v Any) Any {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type Message struct{ *ice.Message }
|
|
||||||
|
|
||||||
func (m Message) Call(cmd string, arg ...Any) Any {
|
|
||||||
args := []Any{}
|
|
||||||
kit.For(arg, func(i int, v Any) { args = append(args, trans(v)) })
|
|
||||||
str := func(v Any) string { return kit.Format(trans(v)) }
|
|
||||||
switch cmd {
|
|
||||||
case "Option":
|
|
||||||
return String{m.Option(str(args[0]), args[1:]...)}
|
|
||||||
case "Cmd":
|
|
||||||
return Message{m.Cmd(args...)}
|
|
||||||
case "Cmdy":
|
|
||||||
m.Cmdy(args...)
|
|
||||||
case "Copy":
|
|
||||||
m.Copy(args[0].(Message).Message, kit.Simple(args[1:]...)...)
|
|
||||||
case "Push":
|
|
||||||
m.Push(str(args[0]), args[1], args[2:]...)
|
|
||||||
case "Echo":
|
|
||||||
m.Echo(str(args[0]), args[1:]...)
|
|
||||||
case "Action":
|
|
||||||
m.Action(args...)
|
|
||||||
case "Sleep":
|
|
||||||
m.Sleep(str(args[0]))
|
|
||||||
case "Table":
|
|
||||||
s := _parse_stack(m.Message)
|
|
||||||
m.Table(func(val ice.Maps) { s.call(m.Message, arg[0], nil, nil, Dict{kit.Dict(val)}) })
|
|
||||||
default:
|
|
||||||
m.ErrorNotImplement(cmd)
|
|
||||||
}
|
|
||||||
return m
|
|
||||||
}
|
|
||||||
func (s *Stack) load(m *ice.Message, cb func(*Frame)) *Stack {
|
func (s *Stack) load(m *ice.Message, cb func(*Frame)) *Stack {
|
||||||
f := s.pushf(m.Options(STACK, s), "")
|
f := s.peekf()
|
||||||
f.value["kit"] = func(m *ice.Message, key string, arg ...Any) Any {
|
f.value["kit"] = func(m *ice.Message, key string, arg ...Any) Any {
|
||||||
kit.For(arg, func(i int, v Any) { arg[i] = trans(v) })
|
|
||||||
switch key {
|
switch key {
|
||||||
case "Dict":
|
case "Dict":
|
||||||
return Dict{kit.Dict(arg...)}
|
return kit.Dict(arg...)
|
||||||
case "List":
|
case "List":
|
||||||
return List{kit.List(arg...)}
|
return kit.List(arg...)
|
||||||
|
case "Format":
|
||||||
|
return kit.Format(arg[0], arg[1:]...)
|
||||||
|
case "Formats":
|
||||||
|
return kit.Formats(arg[0])
|
||||||
default:
|
default:
|
||||||
m.ErrorNotImplement(key)
|
m.ErrorNotImplement(key)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
f.value["ice.MergeActions"] = func(m *ice.Message, key string, arg ...Any) Any {
|
||||||
|
s := _parse_stack(m)
|
||||||
|
_actions := ice.Actions{}
|
||||||
|
for _, v := range arg {
|
||||||
|
actions := ice.Actions{}
|
||||||
|
kit.For(v, func(k string, v Any) {
|
||||||
|
action := &ice.Action{}
|
||||||
|
kit.For(v, func(k string, v Any) {
|
||||||
|
switch k {
|
||||||
|
case "Name":
|
||||||
|
action.Name = kit.Format(trans(v))
|
||||||
|
case "Help":
|
||||||
|
action.Help = kit.Format(trans(v))
|
||||||
|
case "Hand":
|
||||||
|
action.Hand = func(m *ice.Message, arg ...string) { s.action(m, v, nil, arg...) }
|
||||||
|
}
|
||||||
|
})
|
||||||
|
actions[k] = action
|
||||||
|
})
|
||||||
|
ice.MergeActions(_actions, actions)
|
||||||
|
}
|
||||||
|
return _actions
|
||||||
|
}
|
||||||
for k, v := range ice.Info.Stack {
|
for k, v := range ice.Info.Stack {
|
||||||
f.value[k] = v
|
f.value[k] = v
|
||||||
}
|
}
|
||||||
f.value["m"] = Message{m}
|
f.value["m"] = Message{m}
|
||||||
kit.If(cb != nil, func() { cb(s.peekf()) })
|
kit.If(cb != nil, func() { cb(f) })
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m Message) Call(cmd string, arg ...Any) Any {
|
||||||
|
str := func(v Any) string { return kit.Format(trans(v)) }
|
||||||
|
switch cmd {
|
||||||
|
case "Option":
|
||||||
|
return m.Option(str(arg[0]), arg[1:]...)
|
||||||
|
case "Cmd":
|
||||||
|
return Message{m.Cmd(arg...)}
|
||||||
|
case "Cmdy":
|
||||||
|
m.Cmdy(arg...)
|
||||||
|
case "Copy":
|
||||||
|
m.Copy(arg[0].(Message).Message, kit.Simple(arg[1:]...)...)
|
||||||
|
case "Push":
|
||||||
|
m.Push(str(arg[0]), arg[1], arg[2:]...)
|
||||||
|
case "Echo":
|
||||||
|
m.Echo(str(arg[0]), arg[1:]...)
|
||||||
|
case "Action":
|
||||||
|
m.Action(arg...)
|
||||||
|
case "Display":
|
||||||
|
if len(arg) > 0 {
|
||||||
|
m.ProcessDisplay(arg...)
|
||||||
|
} else {
|
||||||
|
m.ProcessDisplay(kit.Format("%s?_t=%d", trans(_parse_stack(m.Message).value(m.Message, "_script")), time.Now().Unix()))
|
||||||
|
}
|
||||||
|
case "StatusTime":
|
||||||
|
m.StatusTime(arg...)
|
||||||
|
case "DebugStack":
|
||||||
|
s := _parse_stack(m.Message)
|
||||||
|
list := []string{}
|
||||||
|
s.stack(func(f *Frame, i int) bool {
|
||||||
|
list = append(list, kit.Format("stack: %s", f.key))
|
||||||
|
kit.For(f.value, func(k string, v Any) {
|
||||||
|
list = append(list, kit.Format("stack: %s %s:%#v", f.key, k, v))
|
||||||
|
})
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
return m
|
||||||
|
}
|
||||||
|
|
||||||
|
type Message struct{ *ice.Message }
|
||||||
|
4
conf.go
4
conf.go
@ -103,6 +103,7 @@ const ( // DIR
|
|||||||
|
|
||||||
ISH_PLUGED = ".ish/pluged/"
|
ISH_PLUGED = ".ish/pluged/"
|
||||||
USR_MODULES = "usr/node_modules/"
|
USR_MODULES = "usr/node_modules/"
|
||||||
|
USR_SCRIPT = "usr/script/"
|
||||||
USR_INSTALL = "usr/install/"
|
USR_INSTALL = "usr/install/"
|
||||||
USR_REQUIRE = "usr/require/"
|
USR_REQUIRE = "usr/require/"
|
||||||
USR_PUBLISH = "usr/publish/"
|
USR_PUBLISH = "usr/publish/"
|
||||||
@ -143,7 +144,6 @@ const ( // DIR
|
|||||||
SRC_HELP = "src/help/"
|
SRC_HELP = "src/help/"
|
||||||
SRC_DEBUG = "src/debug/"
|
SRC_DEBUG = "src/debug/"
|
||||||
SRC_RELEASE = "src/release/"
|
SRC_RELEASE = "src/release/"
|
||||||
SRC_TEMPLATE = "src/template/"
|
|
||||||
SRC_MAIN_SHY = "src/main.shy"
|
SRC_MAIN_SHY = "src/main.shy"
|
||||||
SRC_MAIN_SH = "src/main.sh"
|
SRC_MAIN_SH = "src/main.sh"
|
||||||
SRC_MAIN_JS = "src/main.js"
|
SRC_MAIN_JS = "src/main.js"
|
||||||
@ -151,6 +151,8 @@ const ( // DIR
|
|||||||
SRC_WEBVIEW_GO = "src/webview.go"
|
SRC_WEBVIEW_GO = "src/webview.go"
|
||||||
SRC_VERSION_GO = "src/version.go"
|
SRC_VERSION_GO = "src/version.go"
|
||||||
SRC_BINPACK_GO = "src/binpack.go"
|
SRC_BINPACK_GO = "src/binpack.go"
|
||||||
|
SRC_TEMPLATE = "src/template/"
|
||||||
|
SRC_SCRIPT = "src/script/"
|
||||||
README_MD = "README.md"
|
README_MD = "README.md"
|
||||||
MAKEFILE = "Makefile"
|
MAKEFILE = "Makefile"
|
||||||
LICENSE = "LICENSE"
|
LICENSE = "LICENSE"
|
||||||
|
@ -34,7 +34,7 @@ const FAVOR = "favor"
|
|||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
Index.MergeCommands(ice.Commands{
|
Index.MergeCommands(ice.Commands{
|
||||||
FAVOR: {Name: "favor hash auto create getClipboardData getLocation scanQRCode record1 record2 upload", Help: "收藏夹", Actions: ice.MergeActions(ice.Actions{
|
FAVOR: {Name: "favor hash auto create getClipboardData getLocation scanQRCode record1 record2 upload demo", Help: "收藏夹", Actions: ice.MergeActions(ice.Actions{
|
||||||
mdb.SEARCH: {Hand: func(m *ice.Message, arg ...string) {
|
mdb.SEARCH: {Hand: func(m *ice.Message, arg ...string) {
|
||||||
if arg[0] == mdb.FOREACH {
|
if arg[0] == mdb.FOREACH {
|
||||||
m.Cmd("", ice.OptionFields("")).Table(func(value ice.Maps) {
|
m.Cmd("", ice.OptionFields("")).Table(func(value ice.Maps) {
|
||||||
|
@ -16,6 +16,9 @@ func init() {
|
|||||||
VIMER, INNER, XTERM, PPROF, BENCH,
|
VIMER, INNER, XTERM, PPROF, BENCH,
|
||||||
C, SH, SHY, PY, GO, JS, CSS, HTML,
|
C, SH, SHY, PY, GO, JS, CSS, HTML,
|
||||||
)
|
)
|
||||||
|
ice.Info.Stack[CODE] = func(m *ice.Message, key string, arg ...ice.Any) ice.Any {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func Prefix(arg ...string) string { return web.Prefix(CODE, kit.Keys(arg)) }
|
func Prefix(arg ...string) string { return web.Prefix(CODE, kit.Keys(arg)) }
|
||||||
|
@ -21,7 +21,13 @@ func init() {
|
|||||||
mdb.RENDER: {Hand: func(m *ice.Message, arg ...string) {
|
mdb.RENDER: {Hand: func(m *ice.Message, arg ...string) {
|
||||||
// ctx.ProcessCommand(m, web.WIKI_WORD, kit.Simple(path.Join(arg[2], arg[1])))
|
// ctx.ProcessCommand(m, web.WIKI_WORD, kit.Simple(path.Join(arg[2], arg[1])))
|
||||||
// ctx.ProcessCommand(m, yac.STACK, kit.Simple(arg[1]))
|
// ctx.ProcessCommand(m, yac.STACK, kit.Simple(arg[1]))
|
||||||
ctx.ProcessCommand(m, kit.TrimExt(arg[1], SHY), kit.Simple())
|
// if ls := kit.Split(arg[1], ice.PS); ls[0] == nfs.SCRIPT {
|
||||||
|
// m.Search(ls[1], func(key string, cmd *ice.Command) { yac.StackHandler(m) })
|
||||||
|
// ctx.ProcessCommand(m, ls[1], kit.Simple())
|
||||||
|
// } else {
|
||||||
|
// ctx.ProcessCommand(m, kit.TrimExt(arg[1], SHY), kit.Simple())
|
||||||
|
// }
|
||||||
|
ctx.ProcessCommand(m, yac.STACK, kit.Simple(arg[1]))
|
||||||
}},
|
}},
|
||||||
mdb.ENGINE: {Hand: func(m *ice.Message, arg ...string) {
|
mdb.ENGINE: {Hand: func(m *ice.Message, arg ...string) {
|
||||||
ctx.ProcessCommand(m, yac.STACK, kit.Simple(arg[1]))
|
ctx.ProcessCommand(m, yac.STACK, kit.Simple(arg[1]))
|
||||||
|
@ -28,6 +28,10 @@ func init() {
|
|||||||
Index.MergeCommands(ice.Commands{
|
Index.MergeCommands(ice.Commands{
|
||||||
REFER: {Name: "refer text", Help: "参考", Actions: WordAction(
|
REFER: {Name: "refer text", Help: "参考", Actions: WordAction(
|
||||||
`<ul {{.OptionTemplate}}>{{range $index, $value := .Optionv "list"}}<li>{{index $value 0}}: <a href="{{index $value 1}}" data-name="{{index $value 0}}" target="_blank">{{index $value 2}}</a></li>{{end}}</ul>`,
|
`<ul {{.OptionTemplate}}>{{range $index, $value := .Optionv "list"}}<li>{{index $value 0}}: <a href="{{index $value 1}}" data-name="{{index $value 0}}" target="_blank">{{index $value 2}}</a></li>{{end}}</ul>`,
|
||||||
), Hand: func(m *ice.Message, arg ...string) { _refer_show(m, arg[0], arg[1:]...) }},
|
), Hand: func(m *ice.Message, arg ...string) {
|
||||||
|
if len(arg) > 1 {
|
||||||
|
_refer_show(m, arg[0], arg[1:]...)
|
||||||
|
}
|
||||||
|
}},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
4
logs.go
4
logs.go
@ -147,10 +147,10 @@ func (m *Message) IsErrNotFound() bool {
|
|||||||
return m.IsErr(ErrNotFound)
|
return m.IsErr(ErrNotFound)
|
||||||
}
|
}
|
||||||
func (m *Message) Debug(str string, arg ...Any) {
|
func (m *Message) Debug(str string, arg ...Any) {
|
||||||
if m.Option("debug") == TRUE {
|
// if m.Option("debug") == TRUE || !Info.Important {
|
||||||
kit.Format(str == "", func() { str = m.FormatMeta() })
|
kit.Format(str == "", func() { str = m.FormatMeta() })
|
||||||
m.log(LOG_DEBUG, str, arg...)
|
m.log(LOG_DEBUG, str, arg...)
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Message) FormatPrefix() string {
|
func (m *Message) FormatPrefix() string {
|
||||||
|
5
type.go
5
type.go
@ -302,6 +302,8 @@ func (m *Message) Search(key string, cb Any) *Message {
|
|||||||
if key == "" {
|
if key == "" {
|
||||||
return m
|
return m
|
||||||
}
|
}
|
||||||
|
_target, _key, _cmd := m.target, m._key, m._cmd
|
||||||
|
defer func() { m.target, m._key, m._cmd = _target, _key, _cmd }()
|
||||||
p := m.target.root
|
p := m.target.root
|
||||||
if key = strings.TrimPrefix(key, "ice."); key == PT {
|
if key = strings.TrimPrefix(key, "ice."); key == PT {
|
||||||
p, key = m.target, ""
|
p, key = m.target, ""
|
||||||
@ -336,6 +338,7 @@ func (m *Message) Search(key string, cb Any) *Message {
|
|||||||
switch cb := cb.(type) {
|
switch cb := cb.(type) {
|
||||||
case func(key string, cmd *Command):
|
case func(key string, cmd *Command):
|
||||||
if cmd, ok := p.Commands[key]; ok {
|
if cmd, ok := p.Commands[key]; ok {
|
||||||
|
m.target, m._key, m._cmd = p, key, cmd
|
||||||
cb(key, cmd)
|
cb(key, cmd)
|
||||||
}
|
}
|
||||||
case func(p *Context, s *Context, key string, cmd *Command):
|
case func(p *Context, s *Context, key string, cmd *Command):
|
||||||
@ -391,5 +394,5 @@ func (m *Message) Actions(key string) *Action {
|
|||||||
return m._cmd.Actions[key]
|
return m._cmd.Actions[key]
|
||||||
}
|
}
|
||||||
func (m *Message) Commands(key string) *Command {
|
func (m *Message) Commands(key string) *Command {
|
||||||
return m.Target().Commands[key]
|
return m.Target().Commands[kit.Select(m._key, key)]
|
||||||
}
|
}
|
||||||
|
76
type.shy
Normal file
76
type.shy
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
type Any = interface{}
|
||||||
|
type List = []Any
|
||||||
|
type Map = map[string]Any
|
||||||
|
type Maps = map[string]string
|
||||||
|
type Handler func(m *Message, arg ...string)
|
||||||
|
type Messages = map[string]*Message
|
||||||
|
type Contexts = map[string]*Context
|
||||||
|
type Commands = map[string]*Command
|
||||||
|
type Actions = map[string]*Action
|
||||||
|
type Configs = map[string]*Config
|
||||||
|
type Caches = map[string]*Cache
|
||||||
|
|
||||||
|
type Cache struct {
|
||||||
|
Name string
|
||||||
|
Help string
|
||||||
|
Value string
|
||||||
|
}
|
||||||
|
type Config struct {
|
||||||
|
Name string
|
||||||
|
Help string
|
||||||
|
Value Any
|
||||||
|
}
|
||||||
|
type Action struct {
|
||||||
|
Name string
|
||||||
|
Help string
|
||||||
|
Hand Handler
|
||||||
|
List List
|
||||||
|
}
|
||||||
|
type Command struct {
|
||||||
|
Name string
|
||||||
|
Help string
|
||||||
|
Actions Actions
|
||||||
|
Hand Handler
|
||||||
|
RawHand Any
|
||||||
|
List List
|
||||||
|
Meta Map
|
||||||
|
}
|
||||||
|
type Context struct {
|
||||||
|
Name string
|
||||||
|
Help string
|
||||||
|
|
||||||
|
Caches Caches
|
||||||
|
Configs Configs
|
||||||
|
Commands Commands
|
||||||
|
|
||||||
|
contexts Contexts
|
||||||
|
context *Context
|
||||||
|
root *Context
|
||||||
|
server Server
|
||||||
|
|
||||||
|
id int32
|
||||||
|
}
|
||||||
|
type Server interface {
|
||||||
|
Begin(m *Message, arg ...string)
|
||||||
|
Start(m *Message, arg ...string)
|
||||||
|
Close(m *Message, arg ...string)
|
||||||
|
}
|
||||||
|
|
||||||
|
type Message struct {
|
||||||
|
code int
|
||||||
|
|
||||||
|
data Map
|
||||||
|
meta map[string][]string
|
||||||
|
|
||||||
|
root *Message
|
||||||
|
message *Message
|
||||||
|
|
||||||
|
_source string
|
||||||
|
_target string
|
||||||
|
source *Context
|
||||||
|
target *Context
|
||||||
|
_cmd *Command
|
||||||
|
_key string
|
||||||
|
_sub string
|
||||||
|
}
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user