github.com/goplus/gossa@v0.3.25/repl/repl.go (about) 1 package repl 2 3 import ( 4 "go/token" 5 "strings" 6 7 "github.com/goplus/gossa" 8 ) 9 10 const ( 11 // ContinuePrompt - the current code statement is not completed. 12 ContinuePrompt string = "... " 13 // NormalPrompt - start of a code statement. 14 NormalPrompt string = ">>> " 15 ) 16 17 type UI interface { 18 SetPrompt(prompt string) 19 Printf(format string, a ...interface{}) 20 } 21 22 type REPL struct { 23 repl *gossa.Repl 24 term UI 25 more string 26 } 27 28 func NewREPL(mode gossa.Mode) *REPL { 29 ctx := gossa.NewContext(mode) 30 repl := gossa.NewRepl(ctx) 31 return &REPL{ 32 repl: repl, 33 } 34 } 35 36 func (r *REPL) SetUI(term UI) { 37 r.term = term 38 term.SetPrompt(NormalPrompt) 39 } 40 41 func (r *REPL) SetNormal() { 42 r.more = "" 43 r.term.SetPrompt(NormalPrompt) 44 } 45 46 func (r *REPL) IsNormal() bool { 47 return r.more == "" 48 } 49 50 func (r *REPL) SetFileName(filename string) { 51 r.repl.SetFileName(filename) 52 } 53 54 func (r *REPL) Run(line string) { 55 var expr string 56 if r.more != "" { 57 if line == "" { 58 r.SetNormal() 59 return 60 } 61 expr = r.more + "\n" + line 62 } else { 63 expr = line 64 } 65 tok, dump, err := r.repl.Eval(expr) 66 if err != nil { 67 if checkMore(tok, err) { 68 r.more += "\n" + line 69 r.term.SetPrompt(ContinuePrompt) 70 } else { 71 r.SetNormal() 72 r.term.Printf("error: %v\n", err) 73 } 74 return 75 } 76 if len(dump) > 0 { 77 r.term.Printf(": %v\n", strings.Join(dump, " ")) 78 } 79 r.SetNormal() 80 } 81 82 func checkMore(tok token.Token, err error) bool { 83 s := err.Error() 84 if strings.Contains(s, `expected `) { 85 return true 86 } 87 return false 88 }