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/lex"
_ "github.com/shylinux/icebergs/base/log"
_ "github.com/shylinux/icebergs/base/yac"
_ "github.com/shylinux/icebergs/base/mdb"

View File

@ -22,11 +22,10 @@ const LEX = "lex"
var Index = &ice.Context{Name: LEX, Help: "词法模块",
Commands: map[string]*ice.Command{
ice.CTX_INIT: {Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) {
// m.Load()
// _lex_load(m)
// _lex_load(m.Load())
}},
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
import (
"bytes"
"io"
"strconv"
"strings"
@ -10,6 +12,35 @@ import (
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 {
s int
c byte
@ -80,7 +111,7 @@ func (mat *Matrix) index(m *ice.Message, hash string, h string) int {
return which[h]
}
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)
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]) // 普通字符
}
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("page: \033[31m%d %v\033[0m", len(ss), ss)
// m.Debug("cell: \033[32m%d %v\033[0m", len(cc), cc)
flag := '\000'
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 {
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 {
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
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 {
@ -231,31 +262,33 @@ func (mat *Matrix) Train(m *ice.Message, npage, nhash string, seed string) int {
break
}
}
m.Debug("DEL: %v", trans)
// m.Debug("DEL: %v", trans)
for _, p := range points { // 去尾
p.s = trans[p.s]
state := mat.mat[p.s][p.c]
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
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
}
func (mat *Matrix) Parse(m *ice.Message, npage string, line []byte) (hash int, word []byte, rest []byte) {
// m.Debug("%s %s page: %v line: %v", "parse", "lex", npage, line)
func (mat *Matrix) Parse(m *ice.Message, npage string, stream *Stream) (hash int, word []byte) {
// m.Debug("%s %s page: %v pos: %v", LEX, PARSE, npage, stream.P)
page := mat.index(m, NPAGE, npage)
pos := 0
for star, s := 0, page; s != 0 && pos < len(line); pos++ {
c := line[pos]
if c == '\\' && pos < len(line)-1 { //跳过转义
pos++
c = mat.char(line[pos])[0]
pos := stream.P
for star, s := 0, page; stream.Scan() && s != 0; stream.Next() {
c := stream.Char()
if c == '\\' { //跳过转义
if stream.Next(); !stream.Scan() {
break
}
c = mat.char(stream.Char())[0]
}
if c > 127 { //跳过中文
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]
if state == nil {
s, star, pos = star, 0, pos-1
s, star, stream.P = star, 0, stream.P-1
continue
}
// 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 {
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
}
func (mat *Matrix) show(m *ice.Message) {
@ -379,10 +411,11 @@ func init() {
value = kit.GetMeta(value)
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("word", string(word))
m.Push("rest", string(rest))
m.Push("rest", string(stream.b[stream.P:]))
})
m.ProcessInner()
}},
@ -417,11 +450,10 @@ func init() {
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_HASH, mat.word[hash])
m.Push("word", string(word))
m.Push("rest", string(rest))
})
}},
},

View File

@ -1,6 +1,7 @@
package yac
import (
"bytes"
"fmt"
"strconv"
"strings"
@ -137,7 +138,7 @@ func (mat *Matrix) train(m *ice.Message, page, hash int, word []string, level in
default:
c, ok := mat.page[word[i]]
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 = 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)
@ -211,16 +212,17 @@ func (mat *Matrix) train(m *ice.Message, page, hash int, word []string, level in
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) {
m.Debug("%s %s\\%d %s(%d): %s", PARSE, strings.Repeat("#", level), level, mat.name(mat.hand, page), page, string(line))
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)", PARSE, strings.Repeat("#", level), level, mat.name(mat.hand, page), page)
rest = line
h, w, r := 0, []byte{}, []byte{}
for p, i := 0, page; i > 0 && len(rest) > 0; {
begin := stream.P
h, w := 0, []byte{}
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
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 hh, ww, _ := mat.lex.Parse(m, "key", rest); hh == 0 || len(ww) <= len(w) {
word, rest = append(word, string(w)), r
hold := stream.P
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 {
s = nil
}
@ -238,14 +243,14 @@ func (mat *Matrix) Parse(m *ice.Message, rewrite Rewrite, page int, line []byte,
if s == nil { // 嵌套语法递归解析
for j := 1; j < len(mat.mat[i]); j++ {
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) {
s, word, rest = n, append(word, w...), r
if h, w := mat.Parse(m, rewrite, j, stream, level+1); h != 0 {
s, word = n, append(word, w...)
break
}
}
}
} 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 {
word, rest = word[:0], line
word, stream.P = word[:0], begin
} 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)
return 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
}
func (mat *Matrix) show(m *ice.Message) {
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))
}
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 (
NLANG = "nlang"
@ -351,6 +356,7 @@ func init() {
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), " ", " ", " ")
mat.train(m, page, hash, text, 1)
m.Grow(m.Prefix(MATRIX), kit.Keys(kit.MDB_HASH, key), kit.Dict(
@ -369,15 +375,16 @@ func init() {
value = kit.GetMeta(value)
mat, _ := value[MATRIX].(*Matrix)
for text := []byte(m.Option(kit.MDB_TEXT)); len(text) > 0; {
hash, _, rest := mat.Parse(m, func(m *ice.Message, nhash string, hash int, word []string, rest []byte) (int, []string, []byte) {
for stream := lex.NewStream(bytes.NewBufferString(m.Option(kit.MDB_TEXT))); stream.Scan(); {
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) {
case func(string, int, []string, []byte) (int, []string, []byte):
return cb(nhash, hash, word, rest)
case func(string, int, []string, int, *lex.Stream) (int, []string):
return cb(nhash, hash, word, begin, stream)
}
return hash, word, rest
}, mat.index(m, NPAGE, m.Option(NPAGE)), text, 1)
if text = rest; hash == 0 {
return hash, word
}, mat.index(m, NPAGE, m.Option(NPAGE)), stream, 1)
if hash == 0 {
break
}
}
@ -392,6 +399,7 @@ func init() {
m.ProcessInner()
}},
}, 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 { // 矩阵列表
m.Fields(len(arg) == 0, "time,name,npage,nhash")
m.Cmdy(mdb.SELECT, m.Prefix(MATRIX), "", mdb.HASH)
@ -406,24 +414,10 @@ func init() {
return
}
// 词法矩阵
m.Richs(m.Prefix(MATRIX), "", arg[0], func(key string, value map[string]interface{}) {
value = kit.GetMeta(value)
mat, _ := value[MATRIX].(*Matrix)
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))
value[MATRIX].(*Matrix).show(m)
})
}},
},

View File

@ -1,21 +1,23 @@
package yac
import (
"io/ioutil"
"strconv"
"strings"
ice "github.com/shylinux/icebergs"
"github.com/shylinux/icebergs/base/cli"
"github.com/shylinux/icebergs/base/lex"
"github.com/shylinux/icebergs/base/mdb"
kit "github.com/shylinux/toolkits"
)
type frame struct {
pos int
key string
skip bool
data map[string]string
}
type stack struct {
fs []*frame
res []string
@ -26,6 +28,20 @@ func (s *stack) push(f *frame) *stack {
s.fs = append(s.fs, f)
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) {
if len(s.fs) > 0 {
s.fs[len(s.fs)-1].data[key] = value
@ -39,31 +55,41 @@ func (s *stack) value(key string) string {
}
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) {
stack := m.Optionv("stack").(*stack)
stack.push(f)
func _get_stack(m *ice.Message) *stack {
return m.Optionv("stack").(*stack)
}
func _script_define(m *ice.Message, key, value string) {
stack := m.Optionv("stack").(*stack)
stack.define(key, value)
func _push_stack(m *ice.Message, f *frame) {
f.pos = kit.Int(m.Option("begin"))
_get_stack(m).push(f)
}
func _script_runing(m *ice.Message, nhash string) bool {
switch nhash {
case "if", "for", "end":
func _pop_stack(m *ice.Message) *frame {
return _get_stack(m).pop()
}
func _exp_true(m *ice.Message, arg string) bool {
if arg == "true" {
return true
}
stack := m.Optionv("stack").(*stack)
return !stack.fs[len(stack.fs)-1].skip
if arg == "false" {
return false
}
func _script_pop_stack(m *ice.Message) {
stack := m.Optionv("stack").(*stack)
stack.fs = stack.fs[:len(stack.fs)-1]
if n1, e1 := strconv.ParseInt(arg, 10, 64); e1 == nil {
return n1 != 0
}
func _script_res(m *ice.Message, arg ...interface{}) {
stack := m.Optionv("stack").(*stack)
stack.res = append(stack.res, kit.Simple(arg...)...)
return false
}
const SCRIPT = "script"
@ -71,24 +97,21 @@ const SCRIPT = "script"
func init() {
Index.Merge(&ice.Context{Commands: map[string]*ice.Command{
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))
for _, p := range [][]string{
[]string{"num", "num", "[0-9]+"},
[]string{"key", "key", "[abc]+"},
[]string{"op2", "op2", "[+\\\\-*/%]"},
[]string{"op2", "op2", "[>=<]"},
[]string{"val", "val", "mul{ num key }"},
[]string{"exp", "exp", "val"},
[]string{"exp", "exp", "val op2 val"},
[]string{"stm", "var", "var key = exp"},
[]string{"stm", "for", "for exp"},
[]string{"stm", "if", "if exp"},
[]string{"stm", "cmd", "pwd"},
[]string{"stm", "end", "end"},
[]string{"script", "script", "rep{ stm }"},
} {
m.Cmdx(MATRIX, mdb.INSERT, m.Option(kit.MDB_NAME), p)
if buf, err := ioutil.ReadFile(m.Option(kit.MDB_TEXT)); err == nil {
m.Option(kit.MDB_TEXT, string(buf))
}
m.Option(kit.MDB_TEXT, strings.ReplaceAll(m.Option(kit.MDB_TEXT), "\\", "\\\\"))
for _, line := range kit.Split(m.Option(kit.MDB_TEXT), "\n", "\n", "\n") {
if strings.HasPrefix(strings.TrimSpace(line), "#") {
continue
}
line = strings.ReplaceAll(line, "\\", "\\\\")
if list := kit.Split(line, " ", " ", " "); len(list) > 2 {
m.Cmdx(MATRIX, mdb.INSERT, m.Option(kit.MDB_NAME), list[0], list[1], strings.Join(list[2:], " "))
}
}
}},
"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]))
m.Debug(" %v %v %v", arg[0], arg[1], arg[2])
n1, e1 := strconv.ParseInt(arg[0], 10, 64)
n2, e2 := strconv.ParseInt(arg[2], 10, 64)
m.Debug(" %v %v %v", n1, arg[1], n2)
switch arg[1] {
case ">":
if e1 == nil && e2 == nil {
@ -112,6 +133,12 @@ func init() {
} else {
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 "+":
if e1 == nil && e2 == nil {
m.Echo("%d", n1+n2)
@ -146,33 +173,27 @@ func init() {
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) {
_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) {
_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) {
_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) {
if len(arg) < 2 {
@ -183,13 +204,13 @@ func init() {
stack := &stack{}
stack.push(&frame{})
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.Debug("script %v %v", nhash, word)
if _, ok := c.Commands[SCRIPT].Action[nhash]; ok && _script_runing(m, nhash) {
msg := m.Cmd(SCRIPT, nhash, word)
return hash, msg.Resultv(), rest
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.Option("stream", stream)
if _, ok := c.Commands[SCRIPT].Action[nhash]; ok && stack.can_run(nhash) {
msg := m.Cmd(SCRIPT, nhash, word, ice.Option{"begin", begin})
return hash, msg.Resultv()
}
return hash, word, rest
return hash, word
})
m.Resultv(stack.res)
}},