2
2
mirror of https://github.com/Hilbis/Hilbish synced 2025-07-01 08:42:04 +00:00

Compare commits

...

6 Commits

Author SHA1 Message Date
d01655e803
fix: reimpl commander, fix bait build 2025-06-14 12:30:06 -04:00
4f4a836f05
fix: set any value as table key, not only strings 2025-06-14 12:26:23 -04:00
0e1e964948
feat: impl bool for clua 2025-06-14 10:39:58 -04:00
9c0819969f
feat: impl more functions, uncomment nature code 2025-06-14 10:31:17 -04:00
9aa0a499c9
fix: inverse midnight check 2025-06-14 10:29:27 -04:00
9e77f0ba32
refactor: change go function types
this is the only way i could think of to be able
to push go functions to lua on the clua side.

this may or may not need adjustments on golua side
though...
2025-06-14 10:06:20 -04:00
22 changed files with 378 additions and 275 deletions

131
api.go
View File

@ -15,13 +15,16 @@ package main
import (
"bytes"
"errors"
//"fmt"
"io"
"os"
//"os/exec"
"runtime"
"strings"
//"syscall"
//"syscall
//"time"
//"hilbish/util"
@ -40,26 +43,26 @@ func hilbishLoader(mlr *moonlight.Runtime) moonlight.Value {
println("hilbish loader called")
var exports = map[string]moonlight.Export{
/*
"alias": {hlalias, 2, false},
"appendPath": {hlappendPath, 1, false},
"complete": {hlcomplete, 2, false},
"cwd": {hlcwd, 0, false},
"exec": {hlexec, 1, false},
"runnerMode": {hlrunnerMode, 1, false},
"goro": {hlgoro, 1, true},
"highlighter": {hlhighlighter, 1, false},
"hinter": {hlhinter, 1, false},
"multiprompt": {hlmultiprompt, 1, false},
"prependPath": {hlprependPath, 1, false},
"alias": {hlalias, 2, false},
"appendPath": {hlappendPath, 1, false},
"complete": {hlcomplete, 2, false},
"cwd": {hlcwd, 0, false},
"exec": {hlexec, 1, false},
"runnerMode": {hlrunnerMode, 1, false},
"goro": {hlgoro, 1, true},
"highlighter": {hlhighlighter, 1, false},
"hinter": {hlhinter, 1, false},
"multiprompt": {hlmultiprompt, 1, false},
"prependPath": {hlprependPath, 1, false},
*/
"prompt": {hlprompt, 1, true},
/*
"inputMode": {hlinputMode, 1, false},
"interval": {hlinterval, 2, false},
"read": {hlread, 1, false},
"run": {hlrun, 1, true},
"timeout": {hltimeout, 2, false},
"which": {hlwhich, 1, false},
"inputMode": {hlinputMode, 1, false},
"interval": {hlinterval, 2, false},
"read": {hlread, 1, false},
"run": {hlrun, 1, true},
"timeout": {hltimeout, 2, false},
"which": {hlwhich, 1, false},
*/
}
hshMod = moonlight.NewTable()
@ -133,7 +136,7 @@ func hilbishLoader(mlr *moonlight.Runtime) moonlight.Value {
//mod.Set(rt.StringValue("version"), rt.TableValue(versionModule))
// very meta
if moonlight.IsMidnight() {
if !moonlight.IsMidnight() {
moduleModule := moduleLoader(mlr)
hshMod.SetField("module", moonlight.TableValue(moduleModule))
}
@ -142,11 +145,11 @@ func hilbishLoader(mlr *moonlight.Runtime) moonlight.Value {
}
func getenv(key, fallback string) string {
value := os.Getenv(key)
if len(value) == 0 {
return fallback
}
return value
value := os.Getenv(key)
if len(value) == 0 {
return fallback
}
return value
}
func setVimMode(mode string) {
@ -296,13 +299,13 @@ func hlrun(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
// cwd() -> string
// Returns the current directory of the shell.
// #returns string
func hlcwd(mlr *moonlight.Runtime, c *moonlight.GoCont) (moonlight.Cont, error) {
func hlcwd(mlr *moonlight.Runtime) error {
cwd, _ := os.Getwd()
return mlr.PushNext1(c, moonlight.StringValue(cwd)), nil
mlr.PushNext1(moonlight.StringValue(cwd))
return nil
}
// read(prompt) -> input (string)
// Read input from the user, using Hilbish's line editor/input reader.
// This is a separate instance from the one Hilbish actually uses.
@ -320,7 +323,7 @@ func hlread(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
// substitute with an empty string
prompt = ""
}
lualr := &lineReader{
rl: readline.NewInstance(),
}
@ -352,37 +355,39 @@ hilbish.prompt '%u@%h :%d $'
-- prompt: user@hostname: ~/directory $
#example
*/
func hlprompt(mlr *moonlight.Runtime, c *moonlight.GoCont) (moonlight.Cont, error) {
err := mlr.Check1Arg(c)
func hlprompt(mlr *moonlight.Runtime) error {
err := mlr.Check1Arg()
if err != nil {
return nil, err
return err
}
p, err := mlr.StringArg(c, 0)
p, err := mlr.StringArg(0)
if err != nil {
return nil, err
return err
}
typ := "left"
// optional 2nd arg
/*
if len(c.Etc()) != 0 {
ltyp := c.Etc()[0]
var ok bool
typ, ok = ltyp.TryString()
if !ok {
return nil, errors.New("bad argument to run (expected string, got " + ltyp.TypeName() + ")")
if len(c.Etc()) != 0 {
ltyp := c.Etc()[0]
var ok bool
typ, ok = ltyp.TryString()
if !ok {
return nil, errors.New("bad argument to run (expected string, got " + ltyp.TypeName() + ")")
}
}
}
*/
switch typ {
case "left":
prompt = p
lr.SetPrompt(fmtPrompt(prompt))
case "right": lr.SetRightPrompt(fmtPrompt(p))
default: return nil, errors.New("expected prompt type to be right or left, got " + typ)
case "left":
prompt = p
lr.SetPrompt(fmtPrompt(prompt))
case "right":
lr.SetRightPrompt(fmtPrompt(p))
default:
return errors.New("expected prompt type to be right or left, got " + typ)
}
return c.Next(), nil
return nil
}
// multiprompt(str)
@ -400,7 +405,7 @@ will look like:
user ~ echo "hey
--> ...!"
so then you get
so then you get
user ~ echo "hey
--> ...!"
hey ...!
@ -437,15 +442,15 @@ hilbish.alias('dircount', 'ls %1 | wc -l')
*/
//func hlalias(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
func hlalias(mlr *moonlight.Runtime, c *moonlight.GoCont) (moonlight.Cont, error) {
if err := mlr.CheckNArgs(c, 2); err != nil {
if err := mlr.CheckNArgs(2); err != nil {
return nil, err
}
cmd, err := mlr.StringArg(c, 0)
cmd, err := mlr.StringArg(0)
if err != nil {
return nil, err
}
orig, err := mlr.StringArg(c, 1)
orig, err := mlr.StringArg(1)
if err != nil {
return nil, err
}
@ -471,7 +476,7 @@ hilbish.appendPath {
#example
*/
func hlappendPath(mlr *moonlight.Runtime, c *moonlight.GoCont) (moonlight.Cont, error) {
if err := mlr.Check1Arg(c); err != nil {
if err := mlr.Check1Arg(); err != nil {
return nil, err
}
arg := mlr.Arg(c, 0)
@ -498,7 +503,7 @@ func appendPath(dir string) {
// if dir isnt already in $PATH, add it
if !strings.Contains(pathenv, dir) {
os.Setenv("PATH", pathenv + string(os.PathListSeparator) + dir)
os.Setenv("PATH", pathenv+string(os.PathListSeparator)+dir)
}
}
@ -595,7 +600,7 @@ func hltimeout(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
interval := time.Duration(ms) * time.Millisecond
timer := timers.create(timerTimeout, interval, cb)
timer.start()
return c.PushingNext1(t.Runtime, rt.UserDataValue(timer.ud)), nil
}
@ -766,19 +771,23 @@ func hlinputMode(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
// Read [about runner mode](../features/runner-mode) for more information.
// #param mode string|function
func hlrunnerMode(mlr *moonlight.Runtime, c *moonlight.GoCont) (moonlight.Cont, error) {
if err := mlr.Check1Arg(c); err != nil {
if err := mlr.Check1Arg(); err != nil {
return nil, err
}
mode := mlr.Arg(c, 0)
switch moonlight.Type(mode) {
case moonlight.StringType:
switch mode.AsString() {
case "hybrid", "hybridRev", "lua", "sh": runnerMode = mode
default: return nil, errors.New("execMode: expected either a function or hybrid, hybridRev, lua, sh. Received " + mode.AsString())
}
case moonlight.FunctionType: runnerMode = mode
default: return nil, errors.New("execMode: expected either a function or hybrid, hybridRev, lua, sh. Received " + mode.TypeName())
case moonlight.StringType:
switch mode.AsString() {
case "hybrid", "hybridRev", "lua", "sh":
runnerMode = mode
default:
return nil, errors.New("execMode: expected either a function or hybrid, hybridRev, lua, sh. Received " + mode.AsString())
}
case moonlight.FunctionType:
runnerMode = mode
default:
return nil, errors.New("execMode: expected either a function or hybrid, hybridRev, lua, sh. Received " + mode.TypeName())
}
return c.Next(), nil

26
go.mod
View File

@ -1,20 +1,20 @@
module hilbish
go 1.21
go 1.23.0
toolchain go1.22.2
toolchain go1.24.3
require (
github.com/aarzilli/golua v0.0.0-20210507130708-11106aa57765
github.com/arnodel/golua v0.0.0-20230215163904-e0b5347eaaa1
github.com/atsushinee/go-markdown-generator v0.0.0-20191121114853-83f9e1f68504
github.com/blackfireio/osinfo v1.0.5
github.com/maxlandon/readline v1.0.14
github.com/aarzilli/golua v0.0.0-20250217091409-248753f411c4
github.com/arnodel/golua v0.1.0
github.com/atsushinee/go-markdown-generator v0.0.0-20231027094725-92d26ffbe778
github.com/blackfireio/osinfo v1.1.0
github.com/maxlandon/readline v1.1.3
github.com/pborman/getopt v1.1.0
github.com/sahilm/fuzzy v0.1.1
golang.org/x/sys v0.22.0
golang.org/x/term v0.22.0
mvdan.cc/sh/v3 v3.8.0
golang.org/x/sys v0.33.0
golang.org/x/term v0.32.0
mvdan.cc/sh/v3 v3.11.0
)
require (
@ -25,8 +25,8 @@ require (
github.com/muesli/cancelreader v0.2.2 // indirect
github.com/olekukonko/ts v0.0.0-20171002115256-78ecb04241c0 // indirect
github.com/rivo/uniseg v0.4.7 // indirect
golang.org/x/sync v0.7.0 // indirect
golang.org/x/text v0.14.0 // indirect
golang.org/x/sync v0.15.0 // indirect
golang.org/x/text v0.26.0 // indirect
)
replace mvdan.cc/sh/v3 => github.com/Rosettea/sh/v3 v3.4.0-0.dev.0.20240720131751-805c301321fd
@ -35,4 +35,4 @@ replace github.com/maxlandon/readline => ./readline
replace layeh.com/gopher-luar => github.com/layeh/gopher-luar v1.0.10
replace github.com/arnodel/golua => github.com/Rosettea/golua v0.0.0-20240427174124-d239074c1749
replace github.com/arnodel/golua => github.com/Rosettea/golua v0.0.0-20241104031959-5551ea280f23

16
go.sum
View File

@ -1,17 +1,25 @@
github.com/Rosettea/golua v0.0.0-20240427174124-d239074c1749 h1:jIFnWBTsYw8s7RX7H2AOXjDVhWP3ol7OzUVaPN2KnGI=
github.com/Rosettea/golua v0.0.0-20240427174124-d239074c1749/go.mod h1:9jzpYPiU2is0HVGCiuIOBSXdergHUW44IEjmuN1UrIE=
github.com/Rosettea/golua v0.0.0-20241104031959-5551ea280f23 h1:mUZnT0gmDEmTkqXsbnDbuJ3CNil7DCOMiCQYgjbKIdI=
github.com/Rosettea/golua v0.0.0-20241104031959-5551ea280f23/go.mod h1:9jzpYPiU2is0HVGCiuIOBSXdergHUW44IEjmuN1UrIE=
github.com/Rosettea/sh/v3 v3.4.0-0.dev.0.20240720131751-805c301321fd h1:THNle0FR2g7DMO1y3Bx1Zr7rYeiLXt3st3UkxEsMzL4=
github.com/Rosettea/sh/v3 v3.4.0-0.dev.0.20240720131751-805c301321fd/go.mod h1:YZalN5H7WNQw3DGij6IvHsEhn5YMW7M2FCwG6gnfKy4=
github.com/aarzilli/golua v0.0.0-20210507130708-11106aa57765 h1:N6gB4UCRBZz8twlJbMFiCKj0zX5Et2nFU/LRafT4x80=
github.com/aarzilli/golua v0.0.0-20210507130708-11106aa57765/go.mod h1:hMjfaJVSqVnxenMlsxrq3Ni+vrm9Hs64tU4M7dhUoO4=
github.com/aarzilli/golua v0.0.0-20250217091409-248753f411c4 h1:gW5i3FQAMcbkNgo/A87gCKAbBMalAO8BlPIMo9Gk2Ow=
github.com/aarzilli/golua v0.0.0-20250217091409-248753f411c4/go.mod h1:hMjfaJVSqVnxenMlsxrq3Ni+vrm9Hs64tU4M7dhUoO4=
github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d h1:licZJFw2RwpHMqeKTCYkitsPqHNxTmd4SNR5r94FGM8=
github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d/go.mod h1:asat636LX7Bqt5lYEZ27JNDcqxfjdBQuJ/MM4CN/Lzo=
github.com/arnodel/strftime v0.1.6 h1:0hc0pUvk8KhEMXE+htyaOUV42zNcf/csIbjzEFCJqsw=
github.com/arnodel/strftime v0.1.6/go.mod h1:5NbK5XqYK8QpRZpqKNt4OlxLtIB8cotkLk4KTKzJfWs=
github.com/atsushinee/go-markdown-generator v0.0.0-20191121114853-83f9e1f68504 h1:R1/AOzdMbopSliUTTEHvHbyNmnZ3YxY5GvdhTkpPsSY=
github.com/atsushinee/go-markdown-generator v0.0.0-20191121114853-83f9e1f68504/go.mod h1:kHBCvAXJIatTX1pw6tLiOspjGc3MhUDRlog9yrCUS+k=
github.com/atsushinee/go-markdown-generator v0.0.0-20231027094725-92d26ffbe778 h1:iBzH7EQLFyjkpwXihHWf7QbbzfYfxAlyP4pTjCJbnMw=
github.com/atsushinee/go-markdown-generator v0.0.0-20231027094725-92d26ffbe778/go.mod h1:kHBCvAXJIatTX1pw6tLiOspjGc3MhUDRlog9yrCUS+k=
github.com/blackfireio/osinfo v1.0.5 h1:6hlaWzfcpb87gRmznVf7wSdhysGqLRz9V/xuSdCEXrA=
github.com/blackfireio/osinfo v1.0.5/go.mod h1:Pd987poVNmd5Wsx6PRPw4+w7kLlf9iJxoRKPtPAjOrA=
github.com/blackfireio/osinfo v1.1.0 h1:1LMkMiFL42+Brx7r3MKuf7UTlXBRgebFLJQAfoFafj8=
github.com/blackfireio/osinfo v1.1.0/go.mod h1:Pd987poVNmd5Wsx6PRPw4+w7kLlf9iJxoRKPtPAjOrA=
github.com/creack/pty v1.1.21 h1:1/QdRyBaHHJP61QkWMXlOIBfsgdDeeKfK8SYVUWJKf0=
github.com/creack/pty v1.1.21/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
github.com/evilsocket/islazy v1.11.0 h1:B5w6uuS6ki6iDG+aH/RFeoMb8ijQh/pGabewqp2UeJ0=
@ -40,9 +48,17 @@ github.com/sahilm/fuzzy v0.1.1 h1:ceu5RHF8DGgoi+/dR5PsECjCDH1BE3Fnmpo7aVXOdRA=
github.com/sahilm/fuzzy v0.1.1/go.mod h1:VFvziUEIMCrT6A6tw2RFIXPXXmzXbOsSHF0DOI8ZK9Y=
golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.15.0 h1:KWH3jNZsfyT6xfAfKiz6MRNmd46ByHDYaZ7KSkCtdW8=
golang.org/x/sync v0.15.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI=
golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw=
golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/term v0.22.0 h1:BbsgPEJULsl2fV/AT3v15Mjva5yXKQDyKf+TbDz7QJk=
golang.org/x/term v0.22.0/go.mod h1:F3qCibpT5AMpCRfhfT53vVJwhLtIVHhB9XDjfFvnMI4=
golang.org/x/term v0.32.0 h1:DR4lr0TjUs3epypdhTOkMmuF5CDFJ/8pOnbzMZPQ7bg=
golang.org/x/term v0.32.0/go.mod h1:uZG1FhGx848Sqfsq4/DlJr3xGGsYMu/L5GW4abiaEPQ=
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/text v0.26.0 h1:P42AVeLghgTYr4+xUnTRKDMqpar+PtX7KWuNQL21L8M=
golang.org/x/text v0.26.0/go.mod h1:QK15LZJUUQVJxhz7wXgxSy/CJaTFjd0G+YLonydOVQA=

View File

@ -35,6 +35,7 @@ import (
)
type listenerType int
const (
goListener listenerType = iota
luaListener
@ -44,24 +45,24 @@ const (
type Recoverer func(event string, handler *Listener, err interface{})
// Listener is a struct that holds the handler for an event.
type Listener struct{
typ listenerType
once bool
caller func(...interface{})
type Listener struct {
typ listenerType
once bool
caller func(...interface{})
luaCaller *moonlight.Closure
}
type Bait struct{
type Bait struct {
recoverer Recoverer
handlers map[string][]*Listener
rtm *moonlight.Runtime
handlers map[string][]*Listener
rtm *moonlight.Runtime
}
// New creates a new Bait instance.
func New(rtm *moonlight.Runtime) *Bait {
b := &Bait{
handlers: make(map[string][]*Listener),
rtm: rtm,
rtm: rtm,
}
return b
@ -87,22 +88,24 @@ func (b *Bait) Emit(event string, args ...interface{}) {
for _, arg := range args {
var luarg moonlight.Value
switch arg.(type) {
case moonlight.Value: luarg = arg.(moonlight.Value)
default: luarg = moonlight.AsValue(arg)
case moonlight.Value:
luarg = arg.(moonlight.Value)
default:
luarg = moonlight.AsValue(arg)
}
luaArgs = append(luaArgs, luarg)
}
/*
_, err := b.rtm.Call1(funcVal, luaArgs...)
if err != nil {
if event != "error" {
b.Emit("error", event, handle.luaCaller, err.Error())
return
_, err := b.rtm.Call1(funcVal, luaArgs...)
if err != nil {
if event != "error" {
b.Emit("error", event, handle.luaCaller, err.Error())
return
}
// if there is an error in an error event handler, panic instead
// (calls the go recoverer function)
panic(err)
}
// if there is an error in an error event handler, panic instead
// (calls the go recoverer function)
panic(err)
}
*/
} else {
handle.caller(args...)
@ -117,7 +120,7 @@ func (b *Bait) Emit(event string, args ...interface{}) {
// On adds a Go function handler for an event.
func (b *Bait) On(event string, handler func(...interface{})) *Listener {
listener := &Listener{
typ: goListener,
typ: goListener,
caller: handler,
}
@ -128,7 +131,7 @@ func (b *Bait) On(event string, handler func(...interface{})) *Listener {
// OnLua adds a Lua function handler for an event.
func (b *Bait) OnLua(event string, handler *moonlight.Closure) *Listener {
listener := &Listener{
typ: luaListener,
typ: luaListener,
luaCaller: handler,
}
b.addListener(event, listener)
@ -161,8 +164,8 @@ func (b *Bait) OffLua(event string, handler *moonlight.Closure) {
// Once adds a Go function listener for an event that only runs once.
func (b *Bait) Once(event string, handler func(...interface{})) *Listener {
listener := &Listener{
typ: goListener,
once: true,
typ: goListener,
once: true,
caller: handler,
}
b.addListener(event, listener)
@ -173,8 +176,8 @@ func (b *Bait) Once(event string, handler func(...interface{})) *Listener {
// OnceLua adds a Lua function listener for an event that only runs once.
func (b *Bait) OnceLua(event string, handler *moonlight.Closure) *Listener {
listener := &Listener{
typ: luaListener,
once: true,
typ: luaListener,
once: true,
luaCaller: handler,
}
b.addListener(event, listener)
@ -195,11 +198,10 @@ func (b *Bait) addListener(event string, listener *Listener) {
b.handlers[event] = append(b.handlers[event], listener)
}
func (b *Bait) removeListener(event string, idx int) {
b.handlers[event][idx] = b.handlers[event][len(b.handlers[event]) - 1]
b.handlers[event][idx] = b.handlers[event][len(b.handlers[event])-1]
b.handlers[event] = b.handlers[event][:len(b.handlers[event]) - 1]
b.handlers[event] = b.handlers[event][:len(b.handlers[event])-1]
}
func (b *Bait) callRecoverer(event string, handler *Listener, err interface{}) {
@ -211,12 +213,12 @@ func (b *Bait) callRecoverer(event string, handler *Listener, err interface{}) {
func (b *Bait) Loader(rtm *moonlight.Runtime) moonlight.Value {
exports := map[string]moonlight.Export{
"catch": {b.bcatch, 2, false},
/*
"catchOnce": util.LuaExport{b.bcatchOnce, 2, false},
"throw": util.LuaExport{b.bthrow, 1, true},
"release": util.LuaExport{b.brelease, 2, false},
"hooks": util.LuaExport{b.bhooks, 1, false},
"catch": {b.bcatch, 2, false},
"catchOnce": util.LuaExport{b.bcatchOnce, 2, false},
"throw": util.LuaExport{b.bthrow, 1, true},
"release": util.LuaExport{b.brelease, 2, false},
"hooks": util.LuaExport{b.bhooks, 1, false},
*/
}
mod := moonlight.NewTable()
@ -231,8 +233,10 @@ func handleHook(t *rt.Thread, c *rt.GoCont, name string, catcher *rt.Closure, ar
for _, arg := range args {
var luarg rt.Value
switch arg.(type) {
case rt.Value: luarg = arg.(rt.Value)
default: luarg = rt.AsValue(arg)
case rt.Value:
luarg = arg.(rt.Value)
default:
luarg = rt.AsValue(arg)
}
luaArgs = append(luaArgs, luarg)
}
@ -258,7 +262,7 @@ end)
#example
*/
func (b *Bait) bcatch(mlr *moonlight.Runtime, c *moonlight.GoCont) (moonlight.Cont, error) {
name, catcher, err := util.HandleStrCallback(mlr, c)
name, catcher, err := util.HandleStrCallback(mlr)
if err != nil {
return nil, err
}

View File

@ -33,19 +33,19 @@ This sink is for writing errors, as the name would suggest.
package commander
import (
"hilbish/golibs/bait"
"hilbish/moonlight"
"hilbish/util"
"hilbish/golibs/bait"
)
type Commander struct{
Events *bait.Bait
type Commander struct {
Events *bait.Bait
Commands map[string]*moonlight.Closure
}
func New(rtm *moonlight.Runtime) *Commander {
c := &Commander{
Events: bait.New(rtm),
Events: bait.New(rtm),
Commands: make(map[string]*moonlight.Closure),
}
@ -54,9 +54,9 @@ func New(rtm *moonlight.Runtime) *Commander {
func (c *Commander) Loader(rtm *moonlight.Runtime) moonlight.Value {
exports := map[string]moonlight.Export{
"register": {c.cregister, 2, false},
"register": {c.cregister, 2, false},
"deregister": {c.cderegister, 1, false},
"registry": {c.cregistry, 0, false},
"registry": {c.cregistry, 0, false},
}
mod := moonlight.NewTable()
rtm.SetExports(mod, exports)
@ -81,39 +81,39 @@ commander.register('hello', function(args, sinks)
end)
#example
*/
func (c *Commander) cregister(mlr *moonlight.Runtime, ct *moonlight.GoCont) (moonlight.Cont, error) {
cmdName, cmd, err := util.HandleStrCallback(mlr, ct)
func (c *Commander) cregister(mlr *moonlight.Runtime) error {
cmdName, cmd, err := util.HandleStrCallback(mlr)
if err != nil {
return nil, err
return err
}
c.Commands[cmdName] = cmd
return ct.Next(), err
return nil
}
// deregister(name)
// Removes the named command. Note that this will only remove Commander-registered commands.
// #param name string Name of the command to remove.
func (c *Commander) cderegister(mlr *moonlight.Runtime, ct *moonlight.GoCont) (moonlight.Cont, error) {
if err := mlr.Check1Arg(ct); err != nil {
return nil, err
func (c *Commander) cderegister(mlr *moonlight.Runtime) error {
if err := mlr.Check1Arg(); err != nil {
return err
}
cmdName, err := mlr.StringArg(ct, 0)
cmdName, err := mlr.StringArg(0)
if err != nil {
return nil, err
return err
}
delete(c.Commands, cmdName)
return ct.Next(), err
return err
}
// registry() -> table
// Returns all registered commanders. Returns a list of tables with the following keys:
// - `exec`: The function used to run the commander. Commanders require args and sinks to be passed.
// #returns table
func (c *Commander) cregistry(mlr *moonlight.Runtime, ct *moonlight.GoCont) (moonlight.Cont, error) {
func (c *Commander) cregistry(mlr *moonlight.Runtime) error {
registryLua := moonlight.NewTable()
for cmdName, cmd := range c.Commands {
cmdTbl := moonlight.NewTable()
@ -124,5 +124,6 @@ func (c *Commander) cregistry(mlr *moonlight.Runtime, ct *moonlight.GoCont) (moo
registryLua.SetField(cmdName, moonlight.TableValue(cmdTbl))
}
return mlr.PushNext1(ct, moonlight.TableValue(registryLua)), nil
mlr.PushNext1(moonlight.TableValue(registryLua))
return nil
}

View File

@ -9,20 +9,20 @@ package fs
import (
"fmt"
"os"
"path/filepath"
"strconv"
"os"
"strings"
"hilbish/moonlight"
"hilbish/util"
rt "github.com/arnodel/golua/runtime"
"github.com/arnodel/golua/lib/iolib"
rt "github.com/arnodel/golua/runtime"
"mvdan.cc/sh/v3/interp"
)
type fs struct{
type fs struct {
runner *interp.Runner
}
@ -36,21 +36,17 @@ func (f *fs) Loader(rtm *moonlight.Runtime) moonlight.Value {
println("fs loader called")
exports := map[string]moonlight.Export{
/*
"cd": util.LuaExport{f.fcd, 1, false},
"mkdir": util.LuaExport{f.fmkdir, 2, false},
"stat": util.LuaExport{f.fstat, 1, false},
"cd": util.LuaExport{f.fcd, 1, false},
"mkdir": util.LuaExport{f.fmkdir, 2, false},
"stat": util.LuaExport{f.fstat, 1, false},
"abs": util.LuaExport{f.fabs, 1, false},
"basename": util.LuaExport{f.fbasename, 1, false},
"glob": util.LuaExport{f.fglob, 1, false},
"join": util.LuaExport{f.fjoin, 0, true},
"pipe": util.LuaExport{f.fpipe, 0, false},
*/
"readdir": {f.freaddir, 1, false},
/*
"abs": util.LuaExport{f.fabs, 1, false},
"basename": util.LuaExport{f.fbasename, 1, false},
*/
"dir": {f.fdir, 1, false},
/*
"glob": util.LuaExport{f.fglob, 1, false},
"join": util.LuaExport{f.fjoin, 0, true},
"pipe": util.LuaExport{f.fpipe, 0, false},
*/
"dir": {f.fdir, 1, false},
}
mod := moonlight.NewTable()
@ -126,17 +122,17 @@ func (f *fs) fcd(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
// `~/Documents/doc.txt` then this function will return `~/Documents`.
// #param path string Path to get the directory for.
// #returns string
func (f *fs) fdir(mlr *moonlight.Runtime, c *moonlight.GoCont) (moonlight.Cont, error) {
if err := mlr.Check1Arg(c); err != nil {
return nil, err
func (f *fs) fdir(mlr *moonlight.Runtime) error {
if err := mlr.Check1Arg(); err != nil {
return err
}
path, err := mlr.StringArg(c, 0)
path, err := mlr.StringArg(0)
if err != nil {
return nil, err
return err
}
next := mlr.PushNext1(c, moonlight.StringValue(filepath.Dir(path)))
return next, nil
mlr.PushNext1(moonlight.StringValue(filepath.Dir(path)))
return nil
}
// glob(pattern) -> matches (table)
@ -175,9 +171,9 @@ func (f *fs) fglob(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
luaMatches := rt.NewTable()
for i, match := range matches {
luaMatches.Set(rt.IntValue(int64(i + 1)), rt.StringValue(match))
luaMatches.Set(rt.IntValue(int64(i+1)), rt.StringValue(match))
}
return c.PushingNext(t.Runtime, rt.TableValue(luaMatches)), nil
}
@ -197,7 +193,7 @@ func (f *fs) fjoin(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
for i, v := range c.Etc() {
if v.Type() != rt.StringType {
// +2; go indexes of 0 and first arg from above
return nil, fmt.Errorf("bad argument #%d to run (expected string, got %s)", i + 1, v.TypeName())
return nil, fmt.Errorf("bad argument #%d to run (expected string, got %s)", i+1, v.TypeName())
}
strs[i] = v.AsString()
}
@ -261,30 +257,32 @@ func (f *fs) fpipe(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
return c.PushingNext(t.Runtime, rfLua.Value(t.Runtime), wfLua.Value(t.Runtime)), nil
}
// readdir(path) -> table[string]
// Returns a list of all files and directories in the provided path.
// #param dir string
// #returns table
func (f *fs) freaddir(mlr *moonlight.Runtime, c *moonlight.GoCont) (moonlight.Cont, error) {
if err := mlr.Check1Arg(c); err != nil {
return nil, err
func (f *fs) freaddir(mlr *moonlight.Runtime) error {
if err := mlr.Check1Arg(); err != nil {
return err
}
dir, err := mlr.StringArg(c, 0)
dir, err := mlr.StringArg(0)
if err != nil {
return nil, err
return err
}
dir = util.ExpandHome(dir)
names := moonlight.NewTable()
dirEntries, err := os.ReadDir(dir)
if err != nil {
return nil, err
return err
}
for i, entry := range dirEntries {
names.Set(moonlight.IntValue(int64(i + 1)), moonlight.StringValue(entry.Name()))
names.Set(moonlight.IntValue(int64(i+1)), moonlight.StringValue(entry.Name()))
}
return mlr.PushNext1(c, moonlight.TableValue(names)), nil
mlr.PushNext1(moonlight.TableValue(names))
return nil
}
// stat(path) -> {}
@ -330,9 +328,8 @@ func (f *fs) fstat(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
statTbl := rt.NewTable()
statTbl.Set(rt.StringValue("name"), rt.StringValue(pathinfo.Name()))
statTbl.Set(rt.StringValue("size"), rt.IntValue(pathinfo.Size()))
statTbl.Set(rt.StringValue("mode"), rt.StringValue("0" + strconv.FormatInt(int64(pathinfo.Mode().Perm()), 8)))
statTbl.Set(rt.StringValue("mode"), rt.StringValue("0"+strconv.FormatInt(int64(pathinfo.Mode().Perm()), 8)))
statTbl.Set(rt.StringValue("isDir"), rt.BoolValue(pathinfo.IsDir()))
return c.PushingNext1(t.Runtime, rt.TableValue(statTbl)), nil
}

View File

@ -3,8 +3,6 @@
package terminal
import (
"os"
"hilbish/moonlight"
"golang.org/x/term"
@ -14,10 +12,12 @@ var termState *term.State
func Loader(rtm *moonlight.Runtime) moonlight.Value {
exports := map[string]moonlight.Export{
"setRaw": {termsetRaw, 0, false},
"restoreState": {termrestoreState, 0, false},
"size": {termsize, 0, false},
"saveState": {termsaveState, 0, false},
/*
"setRaw": {termsetRaw, 0, false},
"restoreState": {termrestoreState, 0, false},
"size": {termsize, 0, false},
"saveState": {termsaveState, 0, false},
*/
}
mod := moonlight.NewTable()
@ -26,6 +26,7 @@ func Loader(rtm *moonlight.Runtime) moonlight.Value {
return moonlight.TableValue(mod)
}
/*
// size()
// Gets the dimensions of the terminal. Returns a table with `width` and `height`
// NOTE: The size refers to the amount of columns and rows of text that can fit in the terminal.
@ -75,3 +76,4 @@ func termsetRaw(mlr *moonlight.Runtime, c *moonlight.GoCont) (moonlight.Cont, er
return c.Next(), nil
}
*/

20
lua.go
View File

@ -38,17 +38,17 @@ func luaInit() {
hooks.Off(event, handler)
})
l.LoadLibrary(hooks.Loader, "bait")
/*
// Add Ctrl-C handler
hooks.On("signal.sigint", func(...interface{}) {
if !interactive {
os.Exit(0)
}
})
/*
// Add Ctrl-C handler
hooks.On("signal.sigint", func(...interface{}) {
if !interactive {
os.Exit(0)
}
})
lr.rl.RawInputCallback = func(r []rune) {
hooks.Emit("hilbish.rawInput", string(r))
}
lr.rl.RawInputCallback = func(r []rune) {
hooks.Emit("hilbish.rawInput", string(r))
}
*/
// Add more paths that Lua can require from

View File

@ -1,8 +1,6 @@
package main
import (
"plugin"
"hilbish/moonlight"
)
@ -46,7 +44,7 @@ If you attempt to require and print the result (`print(require 'plugin')`), it w
*/
func moduleLoader(mlr *moonlight.Runtime) *moonlight.Table {
exports := map[string]moonlight.Export{
"load": {moduleLoad, 2, false},
//"load": {moduleLoad, 2, false},
}
mod := moonlight.NewTable()
@ -59,12 +57,13 @@ func moduleLoader(mlr *moonlight.Runtime) *moonlight.Table {
// load(path)
// Loads a module at the designated `path`.
// It will throw if any error occurs.
// #param path string
// #param path string
/*
func moduleLoad(mlr *moonlight.Runtime, c *moonlight.GoCont) (moonlight.Cont, error) {
if err := mlr.Check1Arg(c); err != nil {
return nil, err
}
path, err := mlr.StringArg(c, 0)
if err != nil {
return nil, err
@ -89,3 +88,4 @@ func moduleLoad(mlr *moonlight.Runtime, c *moonlight.GoCont) (moonlight.Cont, er
return mlr.PushNext1(c, val), nil
}
*/

View File

@ -1,22 +1,23 @@
//go:build midnight
package moonlight
import (
"fmt"
)
type Callable interface{
type Callable interface {
Continuation(*Runtime, Cont) Cont
}
type Closure struct{
type Closure struct {
refIdx int // so since we cant store the actual lua closure,
// we need a index to the ref in the lua registry... or something like that.
}
func (mlr *Runtime) ClosureArg(c *GoCont, num int) (*Closure, error) {
func (mlr *Runtime) ClosureArg(num int) (*Closure, error) {
fmt.Println("type at ", num, "is", mlr.state.LTypename(num))
return &Closure{
refIdx: -1,
}, nil

View File

@ -1,4 +1,5 @@
//go:build midnight
package moonlight
func (mlr *Runtime) SetExports(tbl *Table, exports map[string]Export) {

View File

@ -1,3 +1,3 @@
package moonlight
type GoToLuaFunc func(mlr *Runtime, c *GoCont) (Cont, error)
type GoToLuaFunc func(mlr *Runtime) error

View File

@ -1,4 +1,5 @@
//go:build midnight
package moonlight
import (
@ -7,18 +8,18 @@ import (
"github.com/aarzilli/golua/lua"
)
type GoFunctionFunc struct{
type GoFunctionFunc struct {
cf lua.LuaGoFunction
}
func (gf GoFunctionFunc) Continuation(mlr *Runtime, c Cont) Cont {
return &GoCont{
f: gf,
f: gf,
vals: []Value{},
}
}
func (mlr *Runtime) CheckNArgs(c *GoCont, num int) error {
func (mlr *Runtime) CheckNArgs(num int) error {
args := mlr.state.GetTop()
if args < num {
return fmt.Errorf("%d arguments needed", num)
@ -27,11 +28,11 @@ func (mlr *Runtime) CheckNArgs(c *GoCont, num int) error {
return nil
}
func (mlr *Runtime) Check1Arg(c *GoCont) error {
return mlr.CheckNArgs(c, 1)
func (mlr *Runtime) Check1Arg() error {
return mlr.CheckNArgs(1)
}
func (mlr *Runtime) StringArg(c *GoCont, num int) (string, error) {
func (mlr *Runtime) StringArg(num int) (string, error) {
return mlr.state.CheckString(num + 1), nil
}
@ -39,23 +40,26 @@ func (mlr *Runtime) Arg(c *GoCont, num int) Value {
return c.vals[num]
}
func (mlr *Runtime) GoFunction(fun GoToLuaFunc) GoFunctionFunc {
return GoFunctionFunc{
func (mlr *Runtime) GoFunction(fun GoToLuaFunc) *GoFunctionFunc {
mlr.returnNum = 0
return &GoFunctionFunc{
cf: func(L *lua.State) int {
cont, err := fun(mlr, &GoCont{})
err := fun(mlr)
if err != nil {
L.RaiseError(err.Error())
return 0
}
for _, val := range cont.(*GoCont).vals {
/*for _, val := range cont.(*GoCont).vals {
switch Type(val) {
case StringType:
L.PushString(val.AsString())
case StringType:
L.PushString(val.AsString())
}
}
}*/
return len(cont.(*GoCont).vals)
//return len(cont.(*GoCont).vals)
return mlr.returnNum
},
}
}

View File

@ -1,4 +1,5 @@
//go:build !midnight
package moonlight
import (
@ -7,32 +8,28 @@ import (
type GoFunctionFunc = rt.GoFunctionFunc
func (mlr *Runtime) CheckNArgs(c *GoCont, num int) error {
return c.cont.CheckNArgs(num)
func (mlr *Runtime) CheckNArgs(num int) error {
return mlr.rt.MainThread().CurrentCont().(*rt.GoCont).CheckNArgs(num)
}
func (mlr *Runtime) Check1Arg(c *GoCont) error {
return c.cont.CheckNArgs(1)
func (mlr *Runtime) Check1Arg() error {
return mlr.rt.MainThread().CurrentCont().(*rt.GoCont).Check1Arg()
}
func (mlr *Runtime) StringArg(c *GoCont, num int) (string, error) {
return c.cont.StringArg(num)
func (mlr *Runtime) StringArg(num int) (string, error) {
return mlr.rt.MainThread().CurrentCont().(*rt.GoCont).StringArg(num)
}
func (mlr *Runtime) ClosureArg(c *GoCont, num int) (*Closure, error) {
return c.cont.ClosureArg(num)
func (mlr *Runtime) ClosureArg(num int) (*Closure, error) {
return mlr.rt.MainThread().CurrentCont().(*rt.GoCont).ClosureArg(num)
}
func (mlr *Runtime) Arg(c *GoCont, num int) Value {
return c.cont.Arg(num)
return mlr.rt.MainThread().CurrentCont().(*rt.GoCont).Arg(num)
}
func (mlr *Runtime) GoFunction(fun GoToLuaFunc) GoFunctionFunc {
return func(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
gocont := GoCont{
cont: c,
thread: t,
}
return fun(mlr, &gocont)
return c.Next(), fun(mlr)
}
}

View File

@ -1,12 +1,16 @@
//go:build midnight
package moonlight
import (
"fmt"
"github.com/aarzilli/golua/lua"
)
type Runtime struct{
state *lua.State
type Runtime struct {
state *lua.State
returnNum int
}
func NewRuntime() *Runtime {
@ -18,10 +22,10 @@ func NewRuntime() *Runtime {
}
}
func (mlr *Runtime) PushNext1(c *GoCont, v Value) Cont {
c.vals = []Value{v}
func (mlr *Runtime) PushNext1(v Value) {
mlr.returnNum = 1
return c
mlr.pushToState(v)
}
func (mlr *Runtime) Call1(f Value, args ...Value) (Value, error) {
@ -43,12 +47,22 @@ func (mlr *Runtime) Call1(f Value, args ...Value) (Value, error) {
func (mlr *Runtime) pushToState(v Value) {
switch v.Type() {
case NilType: mlr.state.PushNil()
case StringType: mlr.state.PushString(v.AsString())
case TableType:
tbl := v.AsTable()
tbl.SetRuntime(mlr)
tbl.Push()
default: mlr.state.PushNil()
case NilType:
mlr.state.PushNil()
case StringType:
mlr.state.PushString(v.AsString())
case IntType:
mlr.state.PushInteger(v.AsInt())
case BoolType:
mlr.state.PushBoolean(v.AsBool())
case TableType:
tbl := v.AsTable()
tbl.SetRuntime(mlr)
tbl.Push()
case FunctionType:
mlr.state.PushGoClosure(v.AsLuaFunction())
default:
fmt.Println("PUSHING UNIMPLEMENTED TYPE", v.TypeName())
mlr.state.PushNil()
}
}

View File

@ -1,15 +1,16 @@
//go:build !midnight
package moonlight
import (
"os"
rt "github.com/arnodel/golua/runtime"
"github.com/arnodel/golua/lib"
"github.com/arnodel/golua/lib/debuglib"
rt "github.com/arnodel/golua/runtime"
)
type Runtime struct{
type Runtime struct {
rt *rt.Runtime
}
@ -40,8 +41,8 @@ func (mlr *Runtime) Push(c *GoCont, v Value) {
c.cont.Push(c.thread.Runtime, v)
}
func (mlr *Runtime) PushNext1(c *GoCont, v Value) Cont {
return c.cont.PushingNext1(c.thread.Runtime, v)
func (mlr *Runtime) PushNext1(v Value) {
mlr.rt.MainThread().CurrentCont().(*rt.GoCont).Next().Push(mlr.rt.MainThread().Runtime, v)
}
func (mlr *Runtime) Call1(val Value, args ...Value) (Value, error) {

View File

@ -41,19 +41,21 @@ func (t *Table) Push() {
func (t *Table) SetField(key string, value Value) {
if t.refIdx != -1 {
t.setInLua(key, value)
t.setInLua(StringValue(key), value)
return
}
t.setInGo(key, value)
}
func (t *Table) setInLua(key string, value Value) {
func (t *Table) setInLua(key Value, value Value) {
t.Push()
defer t.mlr.state.Pop(1)
t.mlr.pushToState(value)
t.mlr.state.SetField(-2, key)
t.mlr.pushToState(key)
t.mlr.state.Insert(-2)
t.mlr.state.SetTable(-3)
}
func (t *Table) setInGo(key string, value Value) {
@ -66,9 +68,10 @@ func (t *Table) Set(key Value, value Value) {
func (t *Table) syncToLua() {
for k, v := range t.nativeFields {
t.SetField(k.AsString(), v)
t.setInLua(k, v)
}
}
func ForEach(tbl *Table, cb func(key Value, val Value)) {
}

View File

@ -1,8 +1,16 @@
//go:build midnight
package moonlight
type Value struct{
iface interface{}
import (
"fmt"
"strconv"
"github.com/aarzilli/golua/lua"
)
type Value struct {
iface interface{}
relIdx int
refIdx int
}
@ -10,6 +18,7 @@ type Value struct{
var NilValue = Value{nil, -1, -1}
type ValueType uint8
const (
NilType ValueType = iota
BoolType
@ -34,7 +43,7 @@ func IntValue(i int64) Value {
func StringValue(str string) Value {
return Value{iface: str}
}
}
func TableValue(t *Table) Value {
return Value{iface: t}
@ -50,13 +59,18 @@ func AsValue(i interface{}) Value {
}
switch v := i.(type) {
case bool: return BoolValue(v)
case int64: return IntValue(v)
case string: return StringValue(v)
case *Table: return TableValue(v)
case Value: return v
default:
return Value{iface: i}
case bool:
return BoolValue(v)
case int64:
return IntValue(v)
case string:
return StringValue(v)
case *Table:
return TableValue(v)
case Value:
return v
default:
return Value{iface: i}
}
}
@ -66,12 +80,18 @@ func (v Value) Type() ValueType {
}
switch v.iface.(type) {
case bool: return BoolType
case int64: return IntType
case string: return StringType
case *Table: return TableType
case *Closure: return FunctionType
default: return UnknownType
case bool:
return BoolType
case int64:
return IntType
case string:
return StringType
case *Table:
return TableType
case *GoFunctionFunc:
return FunctionType
default:
return UnknownType
}
}
@ -87,22 +107,60 @@ func (v Value) AsString() string {
return v.iface.(string)
}
func (v Value) AsBool() bool {
if v.Type() != BoolType {
panic("value type was not bool")
}
return v.iface.(bool)
}
func (v Value) AsTable() *Table {
return v.iface.(*Table)
}
func (v Value) AsLuaFunction() lua.LuaGoFunction {
return v.iface.(*GoFunctionFunc).cf
}
func ToString(v Value) string {
return v.AsString()
}
func (v Value) ToString() string {
if v.iface == nil {
return "nil"
}
switch v.iface.(type) {
case bool:
return strconv.FormatBool(v.AsBool())
case int64:
return strconv.FormatInt(v.AsInt(), 10)
case string:
return v.AsString()
case *Table:
return "<moonlight table>"
default:
fmt.Println("UNKNOWN in ToString", v.TypeName())
return "<unk>"
}
}
func (v Value) TypeName() string {
switch v.iface.(type) {
case bool: return "bool"
case int64: return "number"
case string: return "string"
case *Table: return "table"
case *Closure: return "function"
default: return "<unknown type>"
case bool:
return "bool"
case int64:
return "number"
case string:
return "string"
case *Table:
return "table"
case *Closure:
return "function"
default:
return "<unknown type>"
}
}

View File

@ -6,7 +6,8 @@ local fs = require 'fs'
-- we will use that to automatically load all commands by reading
-- all the files in this dir and just requiring it.
local info = debug.getinfo(1)
local commandDir = fs.dir(info.source)
local commandDir = fs.dir(info.source:match './.+')
print(commandDir)
if commandDir == '.' then return end
local commands = fs.readdir(commandDir)

View File

@ -1,5 +1,4 @@
-- Prelude initializes everything else for our shell
--[[
local _ = require 'succulent' -- Function additions
local bait = require 'bait'
--local fs = require 'fs'
@ -93,4 +92,3 @@ end)
bait.catch('command.not-executable', function(cmd)
print(string.format('hilbish: %s: not executable', cmd))
end)
]]--

View File

@ -1,9 +1,5 @@
package main
import (
"hilbish/moonlight"
)
// #interface runner
// interactive command runner customization
/* The runner interface contains functions that allow the user to change
@ -25,7 +21,7 @@ to the history.
- `err` (string): A string to indicate an interal error for the runner.
It can be set to a few special values for Hilbish to throw the right hooks and have a better looking message:
`[command]: not-found` will throw a command.not-found hook based on what `[command]` is.
`[command]: not-found` will throw a command.not-found hook based on what `[command]` is.
`[command]: not-executable` will throw a command.not-executable hook.
- `continue` (boolean): Whether to prompt the user for more input.
@ -46,7 +42,6 @@ hilbish.runnerMode(function(input)
return hilbish.runner.sh(input)
end)
```
*/
func runnerModeLoader(rtm *moonlight.Runtime) *moonlight.Table {
exports := map[string]moonlight.Export{
"sh": {shRunner, 1, false},
@ -124,3 +119,4 @@ func luaRunner(mlr *moonlight.Runtime, c *moonlight.GoCont) (moonlight.Cont, err
return mlr.PushNext1(c, moonlight.TableValue(runnerRet)), nil
}
*/

View File

@ -1,8 +1,8 @@
package util
import (
"strings"
"os/user"
"strings"
"hilbish/moonlight"
@ -17,15 +17,15 @@ func SetField(module *rt.Table, field string, value rt.Value) {
// HandleStrCallback handles function parameters for Go functions which take
// a string and a closure.
func HandleStrCallback(mlr *moonlight.Runtime, c *moonlight.GoCont) (string, *moonlight.Closure, error) {
if err := mlr.CheckNArgs(c, 2); err != nil {
func HandleStrCallback(mlr *moonlight.Runtime) (string, *moonlight.Closure, error) {
if err := mlr.CheckNArgs(2); err != nil {
return "", nil, err
}
name, err := mlr.StringArg(c, 0)
name, err := mlr.StringArg(0)
if err != nil {
return "", nil, err
}
cb, err := mlr.ClosureArg(c, 1)
cb, err := mlr.ClosureArg(1)
if err != nil {
return "", nil, err
}