diff --git a/cmd/repl.go b/cmd/repl.go index ce17e20..fb27fd2 100644 --- a/cmd/repl.go +++ b/cmd/repl.go @@ -20,16 +20,15 @@ package main import ( "os" "fmt" - "bufio" - "strings" "strconv" + "github.com/chzyer/readline" "git.callpipe.com/aidan/shs/ast" "git.callpipe.com/aidan/shs/log" "git.callpipe.com/aidan/shs/stdlib" ) const ( - def_prompt string = "λ" + def_prompt string = "λ " ) func setLogLvl() { @@ -59,44 +58,31 @@ func main() { ast.InitVarTable(vars) ast.SyncTablesWithOSEnviron = true - useHist := false - var histFile *os.File var err error - if hist != "" { - useHist = true - histFile, err = os.OpenFile(hist, os.O_RDWR|os.O_CREATE, 0755) - if err != nil { - useHist = false - log.Log(log.ERR, "coudlnt open histfile: " + err.Error(), "init") - } - } - if prompt == "" { prompt = def_prompt } - // TODO: is bufio right for this? - reader := bufio.NewReader(os.Stdin) + rl, err := readline.NewEx(&readline.Config{ + Prompt: prompt, + HistoryFile: hist, + InterruptPrompt: "^C", + }) + + defer rl.Close() + if err != nil { + log.Log(log.ERR, "Couldnt initialize readline: " + err.Error(), "repl") + return + } + for { setLogLvl() - fmt.Print(prompt + " ") - text, err := reader.ReadString('\n') + text, err := rl.Readline() if err != nil { log.Log(log.ERR, "couldnt read user input: " + err.Error(), "repl") } - // TODO: replace with a regex - text = strings.Replace(text, "\r\n", "", -1) - text = strings.Replace(text, "\n", "", -1) - - if useHist { - _, err = histFile.Write([]byte(text + "\n")) - if err != nil { - log.Log(log.DEBUG, "couldnt write to histfile: " + err.Error(), "repl") - } - } - userInput := ast.Lex(text) if userInput == nil { // errors handled in Lex diff --git a/go.mod b/go.mod index b28dc53..d7d911d 100644 --- a/go.mod +++ b/go.mod @@ -1,3 +1,5 @@ module git.callpipe.com/aidan/shs go 1.14 + +require github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e // indirect diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..454fe40 --- /dev/null +++ b/go.sum @@ -0,0 +1,2 @@ +github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e h1:fY5BOSpyZCqRo5OhCuC+XN+r/bBCmeuuJtjz+bCNIf8= +github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= diff --git a/stdlib/stdlib.go b/stdlib/stdlib.go index 4d4e645..30b20fc 100644 --- a/stdlib/stdlib.go +++ b/stdlib/stdlib.go @@ -114,7 +114,19 @@ func GenFuncTable() ast.FuncTable { TimesCalled: 0, Args: 1, }, + + "exit": &ast.Function{ + Function: exit, + Name: "exit", + TimesCalled 0, + Args: 0, + }, } return stdlib } + +func exit_shell(in *ast.Token, vt ast.VarTable, ft ast.FuncTable) *ast.Token { + os.Exit(0) + return nil // I hope execution doesnt get here +}