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  }