1
0
forked from x/icebergs
This commit is contained in:
shaoying 2021-06-23 10:14:06 +08:00
parent ddf87b921d
commit bb7f1360e8
5 changed files with 183 additions and 136 deletions

View File

@ -9,6 +9,7 @@ import (
_ "github.com/shylinux/icebergs/base/gdb" _ "github.com/shylinux/icebergs/base/gdb"
_ "github.com/shylinux/icebergs/base/lex" _ "github.com/shylinux/icebergs/base/lex"
_ "github.com/shylinux/icebergs/base/log" _ "github.com/shylinux/icebergs/base/log"
_ "github.com/shylinux/icebergs/base/yac" _ "github.com/shylinux/icebergs/base/yac"
_ "github.com/shylinux/icebergs/base/mdb" _ "github.com/shylinux/icebergs/base/mdb"

View File

@ -22,11 +22,10 @@ const LEX = "lex"
var Index = &ice.Context{Name: LEX, Help: "词法模块", var Index = &ice.Context{Name: LEX, Help: "词法模块",
Commands: map[string]*ice.Command{ Commands: map[string]*ice.Command{
ice.CTX_INIT: {Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) { ice.CTX_INIT: {Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) {
// m.Load() // _lex_load(m.Load())
// _lex_load(m)
}}, }},
ice.CTX_EXIT: {Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) { ice.CTX_EXIT: {Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) {
// m.Save() m.Save()
}}, }},
}, },
} }

View File

@ -1,6 +1,8 @@
package lex package lex
import ( import (
"bytes"
"io"
"strconv" "strconv"
"strings" "strings"
@ -10,6 +12,35 @@ import (
kit "github.com/shylinux/toolkits" kit "github.com/shylinux/toolkits"
) )
type Stream struct {
r io.Reader
b []byte
P int
}
func NewStream(r io.Reader) *Stream {
return &Stream{r: r}
}
func (s *Stream) Scan() bool {
if s.P < len(s.b) {
return true
}
buf := make([]byte, 1024)
if n, e := s.r.Read(buf); e == nil && n > 0 {
s.b = append(s.b, buf[:n]...)
}
return s.P < len(s.b)
}
func (s *Stream) Next() {
s.P++
}
func (s *Stream) Char() byte {
if s.Scan() {
return s.b[s.P]
}
return 0
}
type Point struct { type Point struct {
s int s int
c byte c byte
@ -80,7 +111,7 @@ func (mat *Matrix) index(m *ice.Message, hash string, h string) int {
return which[h] return which[h]
} }
func (mat *Matrix) Train(m *ice.Message, npage, nhash string, seed string) int { func (mat *Matrix) Train(m *ice.Message, npage, nhash string, seed string) int {
m.Debug("%s %s page: %v hash: %v seed: %v", TRAIN, LEX, npage, nhash, seed) // m.Debug("%s %s page: %v hash: %v seed: %v", TRAIN, LEX, npage, nhash, seed)
page := mat.index(m, NPAGE, npage) page := mat.index(m, NPAGE, npage)
hash := mat.index(m, NHASH, nhash) hash := mat.index(m, NHASH, nhash)
@ -147,8 +178,8 @@ func (mat *Matrix) Train(m *ice.Message, npage, nhash string, seed string) int {
cc = append(cc, seed[i]) // 普通字符 cc = append(cc, seed[i]) // 普通字符
} }
m.Debug("page: \033[31m%d %v\033[0m", len(ss), ss) // m.Debug("page: \033[31m%d %v\033[0m", len(ss), ss)
m.Debug("cell: \033[32m%d %v\033[0m", len(cc), cc) // m.Debug("cell: \033[32m%d %v\033[0m", len(cc), cc)
flag := '\000' flag := '\000'
if i+1 < len(seed) { // 次数 if i+1 < len(seed) { // 次数
@ -163,7 +194,7 @@ func (mat *Matrix) Train(m *ice.Message, npage, nhash string, seed string) int {
if state == nil { if state == nil {
state = &State{} state = &State{}
} }
m.Debug("GET(%d,%d): %#v", s, c, state) // m.Debug("GET(%d,%d): %#v", s, c, state)
if cb(state); state.next == 0 { if cb(state); state.next == 0 {
sn = append(sn, true) sn = append(sn, true)
@ -175,7 +206,7 @@ func (mat *Matrix) Train(m *ice.Message, npage, nhash string, seed string) int {
mat.mat[s][c] = state mat.mat[s][c] = state
points = append(points, &Point{s, c}) points = append(points, &Point{s, c})
m.Debug("SET(%d,%d): %#v", s, c, state) // m.Debug("SET(%d,%d): %#v", s, c, state)
} }
for _, s := range ss { for _, s := range ss {
@ -231,31 +262,33 @@ func (mat *Matrix) Train(m *ice.Message, npage, nhash string, seed string) int {
break break
} }
} }
m.Debug("DEL: %v", trans) // m.Debug("DEL: %v", trans)
for _, p := range points { // 去尾 for _, p := range points { // 去尾
p.s = trans[p.s] p.s = trans[p.s]
state := mat.mat[p.s][p.c] state := mat.mat[p.s][p.c]
if state.next = trans[state.next]; state.next == 0 { if state.next = trans[state.next]; state.next == 0 {
m.Debug("GET(%d, %d): %#v", p.s, p.c, state) // m.Debug("GET(%d, %d): %#v", p.s, p.c, state)
state.hash = hash state.hash = hash
m.Debug("SET(%d, %d): %#v", p.s, p.c, state) // m.Debug("SET(%d, %d): %#v", p.s, p.c, state)
} }
} }
m.Debug("%s %s npage: %v nhash: %v", "train", "lex", len(mat.page), len(mat.hash)) // m.Debug("%s %s npage: %v nhash: %v", TRAIN, LEX, len(mat.page), len(mat.hash))
return hash return hash
} }
func (mat *Matrix) Parse(m *ice.Message, npage string, line []byte) (hash int, word []byte, rest []byte) { func (mat *Matrix) Parse(m *ice.Message, npage string, stream *Stream) (hash int, word []byte) {
// m.Debug("%s %s page: %v line: %v", "parse", "lex", npage, line) // m.Debug("%s %s page: %v pos: %v", LEX, PARSE, npage, stream.P)
page := mat.index(m, NPAGE, npage) page := mat.index(m, NPAGE, npage)
pos := 0 pos := stream.P
for star, s := 0, page; s != 0 && pos < len(line); pos++ { for star, s := 0, page; stream.Scan() && s != 0; stream.Next() {
c := line[pos] c := stream.Char()
if c == '\\' && pos < len(line)-1 { //跳过转义 if c == '\\' { //跳过转义
pos++ if stream.Next(); !stream.Scan() {
c = mat.char(line[pos])[0] break
}
c = mat.char(stream.Char())[0]
} }
if c > 127 { //跳过中文 if c > 127 { //跳过中文
word = append(word, c) word = append(word, c)
@ -264,7 +297,7 @@ func (mat *Matrix) Parse(m *ice.Message, npage string, line []byte) (hash int, w
state := mat.mat[s][c] state := mat.mat[s][c]
if state == nil { if state == nil {
s, star, pos = star, 0, pos-1 s, star, stream.P = star, 0, stream.P-1
continue continue
} }
// m.Debug("GET (%d,%d): %v", s, c, state) // m.Debug("GET (%d,%d): %v", s, c, state)
@ -281,11 +314,10 @@ func (mat *Matrix) Parse(m *ice.Message, npage string, line []byte) (hash int, w
} }
if hash == 0 { if hash == 0 {
pos, word = 0, word[:0] stream.P, word = pos, word[:0]
} }
rest = line[pos:]
// m.Debug("%s %s hash: %v word: %v rest: %v", "parse", "lex", hash, word, rest) // m.Debug("%s %s hash: %v word: %v", LEX, PARSE, mat.word[hash], string(word))
return return
} }
func (mat *Matrix) show(m *ice.Message) { func (mat *Matrix) show(m *ice.Message) {
@ -379,10 +411,11 @@ func init() {
value = kit.GetMeta(value) value = kit.GetMeta(value)
mat, _ := value[MATRIX].(*Matrix) mat, _ := value[MATRIX].(*Matrix)
hash, word, rest := mat.Parse(m, m.Option(NPAGE), []byte(m.Option(kit.MDB_TEXT))) stream := NewStream(bytes.NewBufferString(m.Option(kit.MDB_TEXT)))
hash, word := mat.Parse(m, m.Option(NPAGE), stream)
m.Push(NHASH, kit.Select(kit.Format("%d", hash), mat.word[hash])) m.Push(NHASH, kit.Select(kit.Format("%d", hash), mat.word[hash]))
m.Push("word", string(word)) m.Push("word", string(word))
m.Push("rest", string(rest)) m.Push("rest", string(stream.b[stream.P:]))
}) })
m.ProcessInner() m.ProcessInner()
}}, }},
@ -417,11 +450,10 @@ func init() {
return return
} }
hash, word, rest := mat.Parse(m, arg[1], []byte(arg[2])) hash, word := mat.Parse(m, arg[1], NewStream(bytes.NewBufferString(arg[2])))
m.Push(kit.MDB_TIME, m.Time()) m.Push(kit.MDB_TIME, m.Time())
m.Push(kit.MDB_HASH, mat.word[hash]) m.Push(kit.MDB_HASH, mat.word[hash])
m.Push("word", string(word)) m.Push("word", string(word))
m.Push("rest", string(rest))
}) })
}}, }},
}, },

View File

@ -1,6 +1,7 @@
package yac package yac
import ( import (
"bytes"
"fmt" "fmt"
"strconv" "strconv"
"strings" "strings"
@ -137,7 +138,7 @@ func (mat *Matrix) train(m *ice.Message, page, hash int, word []string, level in
default: default:
c, ok := mat.page[word[i]] c, ok := mat.page[word[i]]
if !ok { if !ok {
if c, _, _ = mat.lex.Parse(m, mat.name(mat.hand, s), []byte(word[i])); c == 0 { if c, _ = mat.lex.Parse(m, mat.name(mat.hand, s), lex.NewStream(bytes.NewBufferString(word[i]))); c == 0 {
// c = mat.lex.Train(m, mat.name(s), fmt.Sprintf("%d", len(mat.mat[s])+1), []byte(word[i])) // c = mat.lex.Train(m, mat.name(s), fmt.Sprintf("%d", len(mat.mat[s])+1), []byte(word[i]))
c = kit.Int(m.Cmdx("lex.matrix", mdb.INSERT, mat.lex_key, mat.name(mat.hand, s), len(mat.mat[s]), word[i])) c = kit.Int(m.Cmdx("lex.matrix", mdb.INSERT, mat.lex_key, mat.name(mat.hand, s), len(mat.mat[s]), word[i]))
mat.mat[s] = append(mat.mat[s], nil) mat.mat[s] = append(mat.mat[s], nil)
@ -211,16 +212,17 @@ func (mat *Matrix) train(m *ice.Message, page, hash int, word []string, level in
return len(word), points, ends return len(word), points, ends
} }
func (mat *Matrix) Parse(m *ice.Message, rewrite Rewrite, page int, line []byte, level int) (hash int, word []string, rest []byte) { func (mat *Matrix) Parse(m *ice.Message, rewrite Rewrite, page int, stream *lex.Stream, level int) (hash int, word []string) {
m.Debug("%s %s\\%d %s(%d): %s", PARSE, strings.Repeat("#", level), level, mat.name(mat.hand, page), page, string(line)) // m.Debug("%s %s\\%d %s(%d)", PARSE, strings.Repeat("#", level), level, mat.name(mat.hand, page), page)
rest = line begin := stream.P
h, w, r := 0, []byte{}, []byte{} h, w := 0, []byte{}
for p, i := 0, page; i > 0 && len(rest) > 0; { for p, i := 0, page; stream.Scan() && i > 0; {
// 解析空白 // 解析空白
h, w, r = mat.lex.Parse(m, "space", rest) h, w = mat.lex.Parse(m, "space", stream)
// 解析单词 // 解析单词
h, w, r = mat.lex.Parse(m, mat.name(mat.hand, i), r) begin := stream.P
h, w = mat.lex.Parse(m, mat.name(mat.hand, i), stream)
// 解析状态 // 解析状态
var s *State var s *State
if h < len(mat.mat[i]) { if h < len(mat.mat[i]) {
@ -228,8 +230,11 @@ func (mat *Matrix) Parse(m *ice.Message, rewrite Rewrite, page int, line []byte,
} }
if s != nil { // 全局语法检查 if s != nil { // 全局语法检查
if hh, ww, _ := mat.lex.Parse(m, "key", rest); hh == 0 || len(ww) <= len(w) { hold := stream.P
word, rest = append(word, string(w)), r stream.P = begin
if hh, ww := mat.lex.Parse(m, "key", stream); hh == 0 || len(ww) <= len(w) {
stream.P = hold
word = append(word, string(w))
} else { } else {
s = nil s = nil
} }
@ -238,14 +243,14 @@ func (mat *Matrix) Parse(m *ice.Message, rewrite Rewrite, page int, line []byte,
if s == nil { // 嵌套语法递归解析 if s == nil { // 嵌套语法递归解析
for j := 1; j < len(mat.mat[i]); j++ { for j := 1; j < len(mat.mat[i]); j++ {
if n := mat.mat[i][j]; j < mat.nlang && n != nil { if n := mat.mat[i][j]; j < mat.nlang && n != nil {
if _, w, r := mat.Parse(m, rewrite, j, rest, level+1); len(r) != len(rest) { if h, w := mat.Parse(m, rewrite, j, stream, level+1); h != 0 {
s, word, rest = n, append(word, w...), r s, word = n, append(word, w...)
break break
} }
} }
} }
} else { } else {
m.Debug("%s %s|%d GET \033[33m%s\033[0m %#v", PARSE, strings.Repeat("#", level), level, w, s) // m.Debug("%s %s|%d GET \033[33m%s\033[0m %#v", PARSE, strings.Repeat("#", level), level, w, s)
} }
//语法切换 //语法切换
@ -257,13 +262,13 @@ func (mat *Matrix) Parse(m *ice.Message, rewrite Rewrite, page int, line []byte,
} }
if hash == 0 { if hash == 0 {
word, rest = word[:0], line word, stream.P = word[:0], begin
} else { } else {
hash, word, rest = rewrite(m, mat.word[hash], hash, word, rest) hash, word = rewrite(m, mat.word[hash], hash, word, begin, stream)
} }
m.Debug("%s %s/%d %s(%d): %v %v", PARSE, strings.Repeat("#", level), level, mat.hand[hash], hash, word, rest) // m.Debug("%s %s/%d %s(%d): %v %v", PARSE, strings.Repeat("#", level), level, mat.hand[hash], hash, word, stream.P)
return hash, word, rest return hash, word
} }
func (mat *Matrix) show(m *ice.Message) { func (mat *Matrix) show(m *ice.Message) {
showCol := map[int]bool{} // 有效列 showCol := map[int]bool{} // 有效列
@ -304,7 +309,7 @@ func (mat *Matrix) show(m *ice.Message) {
m.Status(NLANG, mat.nlang, NCELL, mat.ncell, NPAGE, len(mat.page), NHASH, len(mat.hash)) m.Status(NLANG, mat.nlang, NCELL, mat.ncell, NPAGE, len(mat.page), NHASH, len(mat.hash))
} }
type Rewrite func(m *ice.Message, nhash string, hash int, word []string, rest []byte) (int, []string, []byte) type Rewrite func(m *ice.Message, nhash string, hash int, word []string, begin int, stream *lex.Stream) (int, []string)
const ( const (
NLANG = "nlang" NLANG = "nlang"
@ -351,6 +356,7 @@ func init() {
mat.mat[page] = make([]*State, mat.ncell) mat.mat[page] = make([]*State, mat.ncell)
} }
m.Option(kit.MDB_TEXT, strings.ReplaceAll(m.Option(kit.MDB_TEXT), "\\", "\\\\"))
text := kit.Split(m.Option(kit.MDB_TEXT), " ", " ", " ") text := kit.Split(m.Option(kit.MDB_TEXT), " ", " ", " ")
mat.train(m, page, hash, text, 1) mat.train(m, page, hash, text, 1)
m.Grow(m.Prefix(MATRIX), kit.Keys(kit.MDB_HASH, key), kit.Dict( m.Grow(m.Prefix(MATRIX), kit.Keys(kit.MDB_HASH, key), kit.Dict(
@ -369,15 +375,16 @@ func init() {
value = kit.GetMeta(value) value = kit.GetMeta(value)
mat, _ := value[MATRIX].(*Matrix) mat, _ := value[MATRIX].(*Matrix)
for text := []byte(m.Option(kit.MDB_TEXT)); len(text) > 0; { for stream := lex.NewStream(bytes.NewBufferString(m.Option(kit.MDB_TEXT))); stream.Scan(); {
hash, _, rest := mat.Parse(m, func(m *ice.Message, nhash string, hash int, word []string, rest []byte) (int, []string, []byte) { hash, _ := mat.Parse(m, func(m *ice.Message, nhash string, hash int, word []string, begin int, stream *lex.Stream) (int, []string) {
switch cb := m.Optionv(kit.Keycb(MATRIX)).(type) { switch cb := m.Optionv(kit.Keycb(MATRIX)).(type) {
case func(string, int, []string, []byte) (int, []string, []byte): case func(string, int, []string, int, *lex.Stream) (int, []string):
return cb(nhash, hash, word, rest) return cb(nhash, hash, word, begin, stream)
} }
return hash, word, rest return hash, word
}, mat.index(m, NPAGE, m.Option(NPAGE)), text, 1) }, mat.index(m, NPAGE, m.Option(NPAGE)), stream, 1)
if text = rest; hash == 0 {
if hash == 0 {
break break
} }
} }
@ -392,6 +399,7 @@ func init() {
m.ProcessInner() m.ProcessInner()
}}, }},
}, Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) { }, Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) {
m.Option(mdb.CACHE_LIMIT, -1)
if m.Action(mdb.CREATE); len(arg) == 0 { // 矩阵列表 if m.Action(mdb.CREATE); len(arg) == 0 { // 矩阵列表
m.Fields(len(arg) == 0, "time,name,npage,nhash") m.Fields(len(arg) == 0, "time,name,npage,nhash")
m.Cmdy(mdb.SELECT, m.Prefix(MATRIX), "", mdb.HASH) m.Cmdy(mdb.SELECT, m.Prefix(MATRIX), "", mdb.HASH)
@ -406,24 +414,10 @@ func init() {
return return
} }
// 词法矩阵
m.Richs(m.Prefix(MATRIX), "", arg[0], func(key string, value map[string]interface{}) { m.Richs(m.Prefix(MATRIX), "", arg[0], func(key string, value map[string]interface{}) {
value = kit.GetMeta(value) value = kit.GetMeta(value)
mat, _ := value[MATRIX].(*Matrix) value[MATRIX].(*Matrix).show(m)
if len(arg) == 2 { // 词法矩阵
mat.show(m)
return
}
hash, word, rest := mat.Parse(m, func(m *ice.Message, nhash string, hash int, word []string, rest []byte) (int, []string, []byte) {
m.Debug("\033[32mrun --- %v %v %v\033[0m", nhash, word, rest)
return hash, word, rest
}, mat.index(m, NPAGE, arg[1]), []byte(arg[2]), 1)
m.Push(kit.MDB_TIME, m.Time())
m.Push(kit.MDB_HASH, mat.word[hash])
m.Push("word", kit.Format(word))
m.Push("rest", string(rest))
}) })
}}, }},
}, },

View File

@ -1,21 +1,23 @@
package yac package yac
import ( import (
"io/ioutil"
"strconv" "strconv"
"strings" "strings"
ice "github.com/shylinux/icebergs" ice "github.com/shylinux/icebergs"
"github.com/shylinux/icebergs/base/cli" "github.com/shylinux/icebergs/base/cli"
"github.com/shylinux/icebergs/base/lex"
"github.com/shylinux/icebergs/base/mdb" "github.com/shylinux/icebergs/base/mdb"
kit "github.com/shylinux/toolkits" kit "github.com/shylinux/toolkits"
) )
type frame struct { type frame struct {
pos int
key string key string
skip bool skip bool
data map[string]string data map[string]string
} }
type stack struct { type stack struct {
fs []*frame fs []*frame
res []string res []string
@ -26,6 +28,20 @@ func (s *stack) push(f *frame) *stack {
s.fs = append(s.fs, f) s.fs = append(s.fs, f)
return s return s
} }
func (s *stack) pop() *frame {
last := s.fs[len(s.fs)-1]
s.fs = s.fs[:len(s.fs)-1]
return last
}
func (s *stack) can_run(nhash string) bool {
switch nhash {
case "if", "for", "end":
return true
}
return !s.fs[len(s.fs)-1].skip
}
func (s *stack) define(key, value string) { func (s *stack) define(key, value string) {
if len(s.fs) > 0 { if len(s.fs) > 0 {
s.fs[len(s.fs)-1].data[key] = value s.fs[len(s.fs)-1].data[key] = value
@ -39,31 +55,41 @@ func (s *stack) value(key string) string {
} }
return "" return ""
} }
func (s *stack) let(key, value string) string {
for i := len(s.fs) - 1; i >= 0; i-- {
if val, ok := s.fs[i].data[key]; ok {
s.fs[i].data[key] = value
return val
}
}
return ""
}
func (s *stack) echo(arg ...interface{}) {
s.res = append(s.res, kit.Simple(arg...)...)
}
func _script_push_stack(m *ice.Message, f *frame) { func _get_stack(m *ice.Message) *stack {
stack := m.Optionv("stack").(*stack) return m.Optionv("stack").(*stack)
stack.push(f)
} }
func _script_define(m *ice.Message, key, value string) { func _push_stack(m *ice.Message, f *frame) {
stack := m.Optionv("stack").(*stack) f.pos = kit.Int(m.Option("begin"))
stack.define(key, value) _get_stack(m).push(f)
} }
func _script_runing(m *ice.Message, nhash string) bool { func _pop_stack(m *ice.Message) *frame {
switch nhash { return _get_stack(m).pop()
case "if", "for", "end": }
func _exp_true(m *ice.Message, arg string) bool {
if arg == "true" {
return true return true
} }
if arg == "false" {
stack := m.Optionv("stack").(*stack) return false
return !stack.fs[len(stack.fs)-1].skip }
} if n1, e1 := strconv.ParseInt(arg, 10, 64); e1 == nil {
func _script_pop_stack(m *ice.Message) { return n1 != 0
stack := m.Optionv("stack").(*stack) }
stack.fs = stack.fs[:len(stack.fs)-1] return false
}
func _script_res(m *ice.Message, arg ...interface{}) {
stack := m.Optionv("stack").(*stack)
stack.res = append(stack.res, kit.Simple(arg...)...)
} }
const SCRIPT = "script" const SCRIPT = "script"
@ -71,24 +97,21 @@ const SCRIPT = "script"
func init() { func init() {
Index.Merge(&ice.Context{Commands: map[string]*ice.Command{ Index.Merge(&ice.Context{Commands: map[string]*ice.Command{
SCRIPT: {Name: "script name npage text:textarea auto create", Help: "脚本解析", Action: map[string]*ice.Action{ SCRIPT: {Name: "script name npage text:textarea auto create", Help: "脚本解析", Action: map[string]*ice.Action{
mdb.CREATE: {Name: "create name=shy", Help: "创建", Hand: func(m *ice.Message, arg ...string) { mdb.CREATE: {Name: "create name=shy text=etc/yac.txt", Help: "创建", Hand: func(m *ice.Message, arg ...string) {
m.Cmd(MATRIX, mdb.CREATE, m.Option(kit.MDB_NAME)) m.Cmd(MATRIX, mdb.CREATE, m.Option(kit.MDB_NAME))
for _, p := range [][]string{ if buf, err := ioutil.ReadFile(m.Option(kit.MDB_TEXT)); err == nil {
[]string{"num", "num", "[0-9]+"}, m.Option(kit.MDB_TEXT, string(buf))
[]string{"key", "key", "[abc]+"}, }
[]string{"op2", "op2", "[+\\\\-*/%]"},
[]string{"op2", "op2", "[>=<]"}, m.Option(kit.MDB_TEXT, strings.ReplaceAll(m.Option(kit.MDB_TEXT), "\\", "\\\\"))
[]string{"val", "val", "mul{ num key }"}, for _, line := range kit.Split(m.Option(kit.MDB_TEXT), "\n", "\n", "\n") {
[]string{"exp", "exp", "val"}, if strings.HasPrefix(strings.TrimSpace(line), "#") {
[]string{"exp", "exp", "val op2 val"}, continue
[]string{"stm", "var", "var key = exp"}, }
[]string{"stm", "for", "for exp"}, line = strings.ReplaceAll(line, "\\", "\\\\")
[]string{"stm", "if", "if exp"}, if list := kit.Split(line, " ", " ", " "); len(list) > 2 {
[]string{"stm", "cmd", "pwd"}, m.Cmdx(MATRIX, mdb.INSERT, m.Option(kit.MDB_NAME), list[0], list[1], strings.Join(list[2:], " "))
[]string{"stm", "end", "end"}, }
[]string{"script", "script", "rep{ stm }"},
} {
m.Cmdx(MATRIX, mdb.INSERT, m.Option(kit.MDB_NAME), p)
} }
}}, }},
"exp": {Name: "exp num op2 num", Help: "创建", Hand: func(m *ice.Message, arg ...string) { "exp": {Name: "exp num op2 num", Help: "创建", Hand: func(m *ice.Message, arg ...string) {
@ -101,10 +124,8 @@ func init() {
} }
arg[2] = kit.Select(arg[2], stack.value(arg[2])) arg[2] = kit.Select(arg[2], stack.value(arg[2]))
m.Debug(" %v %v %v", arg[0], arg[1], arg[2])
n1, e1 := strconv.ParseInt(arg[0], 10, 64) n1, e1 := strconv.ParseInt(arg[0], 10, 64)
n2, e2 := strconv.ParseInt(arg[2], 10, 64) n2, e2 := strconv.ParseInt(arg[2], 10, 64)
m.Debug(" %v %v %v", n1, arg[1], n2)
switch arg[1] { switch arg[1] {
case ">": case ">":
if e1 == nil && e2 == nil { if e1 == nil && e2 == nil {
@ -112,6 +133,12 @@ func init() {
} else { } else {
m.Echo("%t", arg[0] > arg[2]) m.Echo("%t", arg[0] > arg[2])
} }
case "<":
if e1 == nil && e2 == nil {
m.Echo("%t", n1 < n2)
} else {
m.Echo("%t", arg[0] < arg[2])
}
case "+": case "+":
if e1 == nil && e2 == nil { if e1 == nil && e2 == nil {
m.Echo("%d", n1+n2) m.Echo("%d", n1+n2)
@ -146,33 +173,27 @@ func init() {
m.Echo(arg[0], arg[1], arg[2]) m.Echo(arg[0], arg[1], arg[2])
} }
}}, }},
"if": {Name: "if exp", Help: "判断", Hand: func(m *ice.Message, arg ...string) {
if arg[1] == "true" {
_script_push_stack(m, &frame{key: arg[0], skip: false})
return
}
if arg[1] == "false" {
_script_push_stack(m, &frame{key: arg[0], skip: true})
return
}
if n1, e1 := strconv.ParseInt(arg[1], 10, 64); e1 == nil {
_script_push_stack(m, &frame{key: arg[0], skip: n1 == 0})
m.Echo("%t", n1 != 0)
} else {
_script_push_stack(m, &frame{skip: len(arg[1]) == 0})
m.Echo("%t", len(arg[1]) > 0)
}
}},
"var": {Name: "var key = exp", Help: "变量", Hand: func(m *ice.Message, arg ...string) { "var": {Name: "var key = exp", Help: "变量", Hand: func(m *ice.Message, arg ...string) {
_script_define(m, arg[1], arg[3]) _get_stack(m).define(arg[1], arg[3])
}}, }},
"for": {Name: "for exp", Help: "循环", Hand: func(m *ice.Message, arg ...string) { "let": {Name: "let key = exp", Help: "变量", Hand: func(m *ice.Message, arg ...string) {
_get_stack(m).let(arg[1], arg[3])
}}, }},
"cmd": {Name: "cmd", Help: "命令", Hand: func(m *ice.Message, arg ...string) { "cmd": {Name: "cmd", Help: "命令", Hand: func(m *ice.Message, arg ...string) {
_script_res(m, m.Cmdx(cli.SYSTEM, arg)) _get_stack(m).echo(m.Cmdx(cli.SYSTEM, arg))
}},
"if": {Name: "if exp", Help: "判断", Hand: func(m *ice.Message, arg ...string) {
_push_stack(m, &frame{key: arg[0], skip: !_exp_true(m, arg[1])})
}},
"for": {Name: "for exp", Help: "循环", Hand: func(m *ice.Message, arg ...string) {
_push_stack(m, &frame{key: arg[0], skip: !_exp_true(m, arg[1])})
}}, }},
"end": {Name: "end", Help: "结束", Hand: func(m *ice.Message, arg ...string) { "end": {Name: "end", Help: "结束", Hand: func(m *ice.Message, arg ...string) {
_script_pop_stack(m) frame := _pop_stack(m)
if frame.key == "for" && !frame.skip {
stream := m.Optionv("stream").(*lex.Stream)
stream.P = frame.pos
}
}}, }},
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
if len(arg) < 2 { if len(arg) < 2 {
@ -183,13 +204,13 @@ func init() {
stack := &stack{} stack := &stack{}
stack.push(&frame{}) stack.push(&frame{})
m.Option("stack", stack) m.Option("stack", stack)
m.Cmdy(MATRIX, PARSE, arg[0], arg[1], arg[2], func(nhash string, hash int, word []string, rest []byte) (int, []string, []byte) { m.Cmdy(MATRIX, PARSE, arg[0], arg[1], arg[2], func(nhash string, hash int, word []string, begin int, stream *lex.Stream) (int, []string) {
m.Debug("script %v %v", nhash, word) m.Option("stream", stream)
if _, ok := c.Commands[SCRIPT].Action[nhash]; ok && _script_runing(m, nhash) { if _, ok := c.Commands[SCRIPT].Action[nhash]; ok && stack.can_run(nhash) {
msg := m.Cmd(SCRIPT, nhash, word) msg := m.Cmd(SCRIPT, nhash, word, ice.Option{"begin", begin})
return hash, msg.Resultv(), rest return hash, msg.Resultv()
} }
return hash, word, rest return hash, word
}) })
m.Resultv(stack.res) m.Resultv(stack.res)
}}, }},