Implement (expect) like (case)

This commit is contained in:
HAYAMA_Kaoru
2024-11-30 02:28:24 +09:00
parent de6a18813b
commit 4ffb196563
3 changed files with 62 additions and 6 deletions
+4 -4
View File
@@ -2,17 +2,17 @@
(let ((ctrlc (format nil "~A" (convert 3 <character>))))
(block main
(while t
(case (expect* 'timeout 10 "xxx" "yyy")
((0)
(expect
("xxx"
(send ctrlc)
(sendln "exit")
(return-from main nil)
)
((1)
(("yyy" "zzz")
(send ctrlc)
(sendln "rem")
)
((-1)
(10 ; timeout second
(send ctrlc)
(sendln "exit")
(return-from main nil)
+56 -1
View File
@@ -49,7 +49,7 @@ func (g *Global) spawn(ctx context.Context, w *gmnlisp.World, args []gmnlisp.Nod
var symTimeout = gmnlisp.NewSymbol("timeout")
func (g *Global) expect(ctx context.Context, w *gmnlisp.World, node gmnlisp.Node) (gmnlisp.Node, error) {
func (g *Global) expectX(ctx context.Context, w *gmnlisp.World, node gmnlisp.Node) (gmnlisp.Node, error) {
patterns := []string{}
timeOut := 0
@@ -83,3 +83,58 @@ func (g *Global) expect(ctx context.Context, w *gmnlisp.World, node gmnlisp.Node
}
return gmnlisp.Integer(result), nil
}
func (g *Global) expect(ctx context.Context, w *gmnlisp.World, node gmnlisp.Node) (gmnlisp.Node, error) {
patterns := []string{}
actions := []gmnlisp.Node{}
timeoutSec := 0
var timeoutAct gmnlisp.Node
for gmnlisp.IsSome(node) {
var err error
var _patAndAct gmnlisp.Node
_patAndAct, node, err = gmnlisp.Shift(node)
if err != nil {
return nil, err
}
patAndAct, err := gmnlisp.ExpectClass[*gmnlisp.Cons](ctx, w, _patAndAct)
if err != nil {
return nil, err
}
pat := patAndAct.Car
act := patAndAct.Cdr
if patInt, ok := pat.(gmnlisp.Integer); ok {
timeoutSec = int(patInt)
timeoutAct = act
} else if _, ok := pat.(*gmnlisp.Cons); ok {
for gmnlisp.IsSome(pat) {
var pat1 gmnlisp.Node
pat1, pat, err = gmnlisp.Shift(pat)
if err != nil {
return nil, err
}
actions = append(actions, act)
patterns = append(patterns, pat1.String())
}
} else {
actions = append(actions, act)
patterns = append(patterns, pat.String())
}
}
var result int
if timeoutSec == 0 {
result = g.w.Expect(patterns...)
} else {
result = g.w.ExpectWithTimeout(time.Second*time.Duration(timeoutSec), patterns...)
}
if result >= 0 {
return gmnlisp.Progn(ctx, w, actions[result])
} else {
return gmnlisp.Progn(ctx, w, timeoutAct)
}
}
+2 -1
View File
@@ -31,7 +31,8 @@ func mains(args []string) error {
gmnlisp.NewSymbol("send"): gmnlisp.Function1(g.send),
gmnlisp.NewSymbol("sendln"): gmnlisp.Function1(g.sendln),
gmnlisp.NewSymbol("spawn"): &gmnlisp.Function{Min: 1, F: g.spawn},
gmnlisp.NewSymbol("expect*"): gmnlisp.SpecialF(g.expect),
gmnlisp.NewSymbol("expect*"): gmnlisp.SpecialF(g.expectX),
gmnlisp.NewSymbol("expect"): gmnlisp.SpecialF(g.expect),
})
if len(args) <= 0 {