diff --git a/example.lsp b/example.lsp index 77dbff6..5a6f74e 100644 --- a/example.lsp +++ b/example.lsp @@ -2,7 +2,7 @@ (let ((ctrlc (format nil "~A" (convert 3 )))) (block main (while t - (case (expect* "xxx" "yyy") + (case (expect* 'timeout 10 "xxx" "yyy") ((0) (sendln (string-append ctrlc "exit")) (return-from main nil) @@ -10,4 +10,11 @@ ((1) (sendln (string-append ctrlc "rem")) ) - )))) + ((-1) + (sendln (string-append ctrlc "exit")) + (return-from main nil) + ) + ) + ) + ) + ) diff --git a/global.go b/global.go index 8394e21..fa31793 100644 --- a/global.go +++ b/global.go @@ -3,6 +3,7 @@ package main import ( "context" "io" + "time" "github.com/hymkor/gmnlisp" ) @@ -41,11 +42,39 @@ func (g *Global) spawn(ctx context.Context, w *gmnlisp.World, args []gmnlisp.Nod return gmnlisp.Null, nil } -func (g *Global) expect(ctx context.Context, w *gmnlisp.World, args []gmnlisp.Node) (gmnlisp.Node, error) { - patterns := make([]string, 0, len(args)) - for _, arg := range args { - patterns = append(patterns, arg.String()) +var symTimeout = gmnlisp.NewSymbol("timeout") + +func (g *Global) expect(ctx context.Context, w *gmnlisp.World, node gmnlisp.Node) (gmnlisp.Node, error) { + patterns := []string{} + timeOut := 0 + + for gmnlisp.IsSome(node) { + var value gmnlisp.Node + var err error + + value, node, err = w.ShiftAndEvalCar(ctx, node) + if err != nil { + return nil, err + } + if symTimeout.Equals(value, gmnlisp.EQUALP) { + value, node, err = w.ShiftAndEvalCar(ctx, node) + if err != nil { + return nil, err + } + _timeout, err := gmnlisp.ExpectClass[gmnlisp.Integer](ctx, w, value) + if err != nil { + return nil, err + } + timeOut = int(_timeout) + } else { + patterns = append(patterns, value.String()) + } + } + var result int + if timeOut == 0 { + result = g.w.Expect(patterns...) + } else { + result = g.w.ExpectWithTimeout(time.Second*time.Duration(timeOut), patterns...) } - result := g.w.Expect(patterns...) return gmnlisp.Integer(result), nil } diff --git a/main.go b/main.go index 9619d96..f1c720e 100644 --- a/main.go +++ b/main.go @@ -30,7 +30,7 @@ func mains(args []string) error { gmnlisp.Functions{ gmnlisp.NewSymbol("sendln"): gmnlisp.Function1(g.sendln), gmnlisp.NewSymbol("spawn"): &gmnlisp.Function{Min: 1, F: g.spawn}, - gmnlisp.NewSymbol("expect*"): &gmnlisp.Function{Min: 1, F: g.expect}, + gmnlisp.NewSymbol("expect*"): gmnlisp.SpecialF(g.expect), }) if len(args) <= 0 {