main.go 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. package main
  2. import (
  3. "fmt"
  4. "os"
  5. "path/filepath"
  6. )
  7. import "gitlab.com/beoran/muesli"
  8. import "github.com/peterh/liner"
  9. func runLine(vm *muesli.VM, in string) error {
  10. parser := muesli.NewParserFromString(in)
  11. ast := parser.Parse()
  12. err := ast.ToError()
  13. if err != nil {
  14. return err
  15. }
  16. result := vm.RunAst(*ast, muesli.NewListValue())
  17. if result != nil {
  18. for _, val := range result {
  19. if val != nil {
  20. fmt.Printf(">>%s\n", val.String())
  21. } else {
  22. fmt.Printf(">>nil\n")
  23. }
  24. }
  25. }
  26. return nil
  27. }
  28. func runLines(vm *muesli.VM, line *liner.State) error {
  29. for {
  30. if in, err := line.Prompt("> "); err == nil {
  31. err = runLine(vm, in)
  32. if err != nil {
  33. os.Stderr.WriteString(fmt.Sprintf("Error %s: \n", err))
  34. }
  35. line.AppendHistory(in)
  36. } else if err == liner.ErrPromptAborted {
  37. os.Stderr.WriteString("Aborted\n")
  38. return nil
  39. } else {
  40. os.Stderr.WriteString(fmt.Sprintf("Error reading line: %s\n", err))
  41. }
  42. }
  43. return nil
  44. }
  45. func runFile(vm *muesli.VM, name string) error {
  46. parser, err := muesli.NewParserFromFilename(name)
  47. if err != nil {
  48. os.Stderr.WriteString(fmt.Sprintf("Error opening file %s: %s\n", name, err))
  49. return err
  50. }
  51. ast := parser.Parse()
  52. err = ast.ToError()
  53. if err != nil {
  54. os.Stderr.WriteString(fmt.Sprintf("%s: execution error\n", err))
  55. return err
  56. }
  57. vm.RunAst(*ast, muesli.NewListValue())
  58. return nil
  59. }
  60. func main() {
  61. vm := muesli.NewVM()
  62. // defer func () { os.Exit(vm.ExitStatus) }()
  63. // vm.Tracer = &muesli.FmtTracer{}
  64. vm.RegisterBuiltins()
  65. line := liner.NewLiner()
  66. defer line.Close()
  67. line.SetCtrlCAborts(true)
  68. home, _ := os.UserHomeDir()
  69. historyName := filepath.Join(home, ".muesli_history")
  70. /* line.SetCompleter(func(line string) (c []string) {
  71. for _, n := range names {
  72. if strings.HasPrefix(n, strings.ToLower(line)) {
  73. c = append(c, n)
  74. }
  75. }
  76. return
  77. })
  78. */
  79. if f, err := os.Open(historyName); err == nil {
  80. line.ReadHistory(f)
  81. f.Close()
  82. }
  83. if len(os.Args) > 0 {
  84. for _, name := range os.Args {
  85. err := runFile(vm, name)
  86. if err != nil {
  87. return
  88. }
  89. }
  90. }
  91. runLines(vm, line)
  92. if f, err := os.Create(historyName); err != nil {
  93. fmt.Print("Error writing history file: %s\n", err)
  94. } else {
  95. line.WriteHistory(f)
  96. f.Close()
  97. }
  98. }