123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153 |
- package main
- import (
- "fmt"
- "os"
- "io"
- "sort"
- "path/filepath"
- "unicode"
- )
- import "gitlab.com/beoran/muesli"
- import "github.com/peterh/liner"
- func runLine(vm *muesli.VM, in string) error {
- parser := muesli.NewParserFromString(in)
- if val := vm.Lookup("__muesli_debug__"); val == muesli.TrueValue {
- parser.SetVmLogger(vm)
- }
- kw := vm.LoadKeywords()
- if kw != nil {
- parser.AddKeywords(kw)
- } else {
- parser.AddKeywords(muesli.DefaultKeywords)
- vm.StoreKeywords(muesli.DefaultKeywords)
- }
- ast := parser.Parse()
- err := ast.ToError()
- if err != nil {
- return err
- }
- result := vm.RunAst(*ast, muesli.NewListValue())
- if result != nil {
- for _, val := range result {
- if val != nil {
- vm.Printf(">>%s\n", val.String())
- } else {
- vm.Printf(">>nil\n")
- }
- }
- }
-
- return nil
- }
- func runLines(vm *muesli.VM, line *liner.State) error {
- for {
- if in, err := line.Prompt("> "); err == nil {
- err = runLine(vm, in)
- if err != nil {
- vm.Errf("Error %s: \n", err)
- }
- line.AppendHistory(in)
- } else if err == liner.ErrPromptAborted {
- vm.Errf("Aborted\n")
- return nil
- } else if err == io.EOF {
- return nil
- } else {
- vm.Errf("Error reading line: %s\n", err)
- }
- }
- return nil
- }
- func runFile(vm *muesli.VM, name string) error {
- parser, err := muesli.NewParserFromFilename(name)
- if err != nil {
- vm.Errf("Error opening file %s: %s\n", name, err)
- return err
- }
- ast := parser.Parse()
- err = ast.ToError()
- if err == io.EOF {
- return nil
- } else if err != nil {
- vm.Errf("Error opening file %s: %s\n", name, err)
- return err
- }
- vm.RunAst(*ast, muesli.NewListValue())
- return nil
- }
- func main() {
- // console := muesli.NewStdConsole()
- vm := muesli.NewVM()
- // defer func () { os.Exit(vm.ExitStatus) }()
- // vm.Tracer = &muesli.FmtTracer{}
- // vm.Console = console
- vm.RegisterBuiltins()
- line := liner.NewLiner()
- defer line.Close()
- line.SetCtrlCAborts(true)
- home, _ := os.UserHomeDir()
- historyName := filepath.Join(home, ".muesli_history")
- if f, err := os.Open(historyName); err == nil {
- line.ReadHistory(f)
- f.Close()
- }
-
- if len(os.Args) > 1 {
- for _, name := range os.Args {
- err := runFile(vm, name)
- if err != nil {
- return
- }
- }
- return
- }
- line.SetWordCompleter(func(line string, pos int) (head string, c []string, tail string) {
- end := pos
- // XXX unicode support!
- for end < len(line) && unicode.IsLetter(rune(line[end])) {
- end++
- }
- if end > len(line) {
- end = len(line)
- }
- tail = line[end:]
- start := pos - 1
- for start > 0 && unicode.IsLetter(rune(line[start-1])) {
- start--
- }
- if start < 0 {
- start = 0
- }
- fmt.Printf("%d %d %d\n", start, end, len(line))
-
- head = line[0:start]
- word := line[start:end]
- fmt.Printf(">%s<\n", word)
- c = vm.DefinedNamesLike(word)
- sort.Strings(c)
- return head, c, tail
- })
-
- runLines(vm, line)
-
- if f, err := os.Create(historyName); err != nil {
- vm.Errf("Error writing history file: %s\n", err)
- } else {
- line.WriteHistory(f)
- f.Close()
- }
- }
|