Files
lispect/global.go
T
2024-11-30 01:09:34 +09:00

86 lines
1.9 KiB
Go

package main
import (
"context"
"io"
"time"
"github.com/hymkor/gmnlisp"
)
type Global struct {
w *Watcher
term *Term
closer []func()
}
func (g *Global) Close() {
for i := len(g.closer) - 1; i >= 0; i-- {
g.closer[i]()
}
g.closer = nil
}
func (g *Global) send(ctx context.Context, w *gmnlisp.World, arg gmnlisp.Node) (gmnlisp.Node, error) {
io.WriteString(g.term, arg.String())
return gmnlisp.Null, nil
}
func (g *Global) sendln(ctx context.Context, w *gmnlisp.World, arg gmnlisp.Node) (gmnlisp.Node, error) {
io.WriteString(g.term, arg.String())
g.term.Write([]byte{'\r'})
return gmnlisp.Null, nil
}
func (g *Global) spawn(ctx context.Context, w *gmnlisp.World, args []gmnlisp.Node) (gmnlisp.Node, error) {
argStrings := make([]string, 0, len(args))
for _, s := range args {
argStrings = append(argStrings, s.String())
}
sh := g.term.Command(argStrings[0], argStrings[1:]...)
if err := sh.Start(); err != nil {
return nil, err
}
g.closer = append(g.closer, func() { sh.Wait() })
return gmnlisp.Null, nil
}
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...)
}
return gmnlisp.Integer(result), nil
}