main.go 2.4 KB

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