From 903208864933ed3442ce49e59fb579f60e4365de Mon Sep 17 00:00:00 2001 From: Randall Winkhart Date: Fri, 2 May 2025 18:28:57 -0400 Subject: [PATCH] Split into two packages to allow importing as library --- Makefile | 2 +- core/embed.go | 96 +++++++++++++++++++++++++++++++++++ global.go => core/global.go | 2 +- term.go => core/term.go | 2 +- watcher.go => core/watcher.go | 2 +- main.go | 77 +--------------------------- 6 files changed, 102 insertions(+), 79 deletions(-) create mode 100644 core/embed.go rename global.go => core/global.go (99%) rename term.go => core/term.go (98%) rename watcher.go => core/watcher.go (99%) diff --git a/Makefile b/Makefile index 305dcd1..9207e30 100644 --- a/Makefile +++ b/Makefile @@ -11,7 +11,7 @@ endif NAME:=$(notdir $(CURDIR)) VERSION:=$(shell git describe --tags 2>$(NUL) || echo v0.0.0) -GOOPT:=-ldflags "-s -w -X main.version=$(VERSION)" +GOOPT:=-ldflags "-s -w -X core.version=$(VERSION)" EXE:=$(shell go env GOEXE) all: diff --git a/core/embed.go b/core/embed.go new file mode 100644 index 0000000..d53c462 --- /dev/null +++ b/core/embed.go @@ -0,0 +1,96 @@ +package core + +import ( + "context" + "fmt" + "os" + "runtime" + + "github.com/hymkor/gmnlisp" +) + +// version is set by Makefile, thus it is not compatible with +// RunEmbedded unless handled by the downstream developer. +var version string + +func RunEmbedded(script string, additionalArgs []string) { + if err := mains(append([]string{script}, additionalArgs...), true); err != nil { + fmt.Fprintln(os.Stderr, err.Error()) + os.Exit(1) + } +} + +func Run() { + if err := mains(os.Args[1:], false); err != nil { + fmt.Fprintln(os.Stderr, err.Error()) + os.Exit(1) + } +} + +func mains(args []string, embedded bool) error { + term, err := NewTerm() + if err != nil { + return err + } + defer term.Close() + + watcher := NewWatcher(term) + + g := &Global{ + term: term, + w: watcher, + } + defer g.Close() + + gmnlisp.NewLineOnFormat = []byte{'\r', '\n'} + + lisp := gmnlisp.New() + + lisp = lisp.Flet( + gmnlisp.Functions{ + gmnlisp.NewSymbol("send"): &gmnlisp.Function{Min: 1, F: g.send}, + gmnlisp.NewSymbol("sendln"): &gmnlisp.Function{Min: 1, F: g.sendln}, + gmnlisp.NewSymbol("spawn"): &gmnlisp.Function{Min: 1, F: g.spawn}, + gmnlisp.NewSymbol("expect*"): gmnlisp.SpecialF(g.expectX), + gmnlisp.NewSymbol("expect"): gmnlisp.SpecialF(g.expect), + gmnlisp.NewSymbol("getenv"): gmnlisp.Function1(g.getenv), + gmnlisp.NewSymbol("setenv"): gmnlisp.Function2(g.setenv), + gmnlisp.NewSymbol("wait"): gmnlisp.Function1(g.wait), + }) + + if len(args) <= 0 { + return fmt.Errorf("%s %s-%s-%s: script path required", + os.Args[0], + version, + runtime.GOOS, + runtime.GOARCH) + } + var script []byte + if !embedded { + script, err = os.ReadFile(args[0]) + if err != nil { + return err + } + } else { + script = []byte(args[0]) + } + + posixArgv := []gmnlisp.Node{} + for _, s := range args[1:] { + posixArgv = append(posixArgv, gmnlisp.String(s)) + } + executable := os.Args[0] + if value, err := os.Executable(); err == nil { + executable = value + } + lisp = lisp.Let(gmnlisp.Variables{ + gmnlisp.NewSymbol("ARGV"): gmnlisp.List(posixArgv...), + gmnlisp.NewSymbol("PROGRAM-NAME"): gmnlisp.String(args[0]), + gmnlisp.NewSymbol("EXECUTABLE-NAME"): gmnlisp.String(executable), + }) + + ctx, cancel := context.WithCancel(context.Background()) + _, err = lisp.Interpret(ctx, string(script)) + cancel() + return err +} diff --git a/global.go b/core/global.go similarity index 99% rename from global.go rename to core/global.go index 93f07bb..1da7a0f 100644 --- a/global.go +++ b/core/global.go @@ -1,4 +1,4 @@ -package main +package core import ( "context" diff --git a/term.go b/core/term.go similarity index 98% rename from term.go rename to core/term.go index e580d94..4c8f017 100644 --- a/term.go +++ b/core/term.go @@ -1,4 +1,4 @@ -package main +package core import ( "os" diff --git a/watcher.go b/core/watcher.go similarity index 99% rename from watcher.go rename to core/watcher.go index 5027a46..ffbc595 100644 --- a/watcher.go +++ b/core/watcher.go @@ -1,4 +1,4 @@ -package main +package core import ( "io" diff --git a/main.go b/main.go index 635f1df..7407946 100644 --- a/main.go +++ b/main.go @@ -1,82 +1,9 @@ package main import ( - "context" - "fmt" - "os" - "runtime" - - "github.com/hymkor/gmnlisp" + "github.com/hymkor/lispect/core" ) -var version string - -func mains(args []string) error { - term, err := NewTerm() - if err != nil { - return err - } - defer term.Close() - - watcher := NewWatcher(term) - - g := &Global{ - term: term, - w: watcher, - } - defer g.Close() - - gmnlisp.NewLineOnFormat = []byte{'\r', '\n'} - - lisp := gmnlisp.New() - - lisp = lisp.Flet( - gmnlisp.Functions{ - gmnlisp.NewSymbol("send"): &gmnlisp.Function{Min: 1, F: g.send}, - gmnlisp.NewSymbol("sendln"): &gmnlisp.Function{Min: 1, F: g.sendln}, - gmnlisp.NewSymbol("spawn"): &gmnlisp.Function{Min: 1, F: g.spawn}, - gmnlisp.NewSymbol("expect*"): gmnlisp.SpecialF(g.expectX), - gmnlisp.NewSymbol("expect"): gmnlisp.SpecialF(g.expect), - gmnlisp.NewSymbol("getenv"): gmnlisp.Function1(g.getenv), - gmnlisp.NewSymbol("setenv"): gmnlisp.Function2(g.setenv), - gmnlisp.NewSymbol("wait"): gmnlisp.Function1(g.wait), - }) - - if len(args) <= 0 { - return fmt.Errorf("%s %s-%s-%s: script path required", - os.Args[0], - version, - runtime.GOOS, - runtime.GOARCH) - } - script, err := os.ReadFile(args[0]) - if err != nil { - return err - } - - posixArgv := []gmnlisp.Node{} - for _, s := range args[1:] { - posixArgv = append(posixArgv, gmnlisp.String(s)) - } - executable := os.Args[0] - if value, err := os.Executable(); err == nil { - executable = value - } - lisp = lisp.Let(gmnlisp.Variables{ - gmnlisp.NewSymbol("ARGV"): gmnlisp.List(posixArgv...), - gmnlisp.NewSymbol("PROGRAM-NAME"): gmnlisp.String(args[0]), - gmnlisp.NewSymbol("EXECUTABLE-NAME"): gmnlisp.String(executable), - }) - - ctx, cancel := context.WithCancel(context.Background()) - _, err = lisp.Interpret(ctx, string(script)) - cancel() - return err -} - func main() { - if err := mains(os.Args[1:]); err != nil { - fmt.Fprintln(os.Stderr, err.Error()) - os.Exit(1) - } + core.Run() }