Skip to content

Commit

Permalink
Expose errors (for bot). (#35)
Browse files Browse the repository at this point in the history
* Expose errors (for bot). for grol-io/grol-discord-bot#7

* fix test
  • Loading branch information
ldemailly authored Jul 15, 2024
1 parent 41774eb commit c4f454c
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 11 deletions.
24 changes: 15 additions & 9 deletions repl/repl.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,14 +48,15 @@ func EvalAll(s, macroState *eval.State, in io.Reader, out io.Writer, options Opt
}

// EvalString can be used from playground etc for single eval.
func EvalString(what string) string {
// returns the eval errors and an array of errors if any.
func EvalString(what string) (string, []string) {
s := eval.NewState()
macroState := eval.NewState()
out := &strings.Builder{}
s.Out = out
s.NoLog = true
EvalOne(s, macroState, what, out, Options{All: true, ShowEval: true, NoColor: true})
return out.String()
_, errs := EvalOne(s, macroState, what, out, Options{All: true, ShowEval: true, NoColor: true})
return out.String(), errs
}

func Interactive(in io.Reader, out io.Writer, options Options) {
Expand All @@ -72,7 +73,7 @@ func Interactive(in io.Reader, out io.Writer, options Options) {
return
}
l := prev + scanner.Text()
contNeeded := EvalOne(s, macroState, l, out, options)
contNeeded, _ := EvalOne(s, macroState, l, out, options)
if contNeeded {
prev = l + "\n"
prompt = CONTINUATION
Expand All @@ -84,7 +85,8 @@ func Interactive(in io.Reader, out io.Writer, options Options) {
}

// Returns true in line mode if more should be fed to the parser.
func EvalOne(s, macroState *eval.State, what string, out io.Writer, options Options) bool {
// TODO: this one size fits 3 different calls (file, interactive, bot) is getting spaghetti.
func EvalOne(s, macroState *eval.State, what string, out io.Writer, options Options) (bool, []string) {
var l *lexer.Lexer
if options.All {
l = lexer.New(what)
Expand All @@ -94,10 +96,10 @@ func EvalOne(s, macroState *eval.State, what string, out io.Writer, options Opti
p := parser.New(l)
program := p.ParseProgram()
if logParserErrors(p) {
return false
return false, p.Errors()
}
if p.ContinuationNeeded() {
return true
return true, nil
}
if options.ShowParse {
fmt.Fprint(out, "== Parse ==> ")
Expand All @@ -122,7 +124,11 @@ func EvalOne(s, macroState *eval.State, what string, out io.Writer, options Opti
}
obj := s.Eval(program)
if !options.ShowEval {
return false
return false, nil
}
var errs []string
if obj.Type() == object.ERROR {
errs = append(errs, obj.Inspect())
}
if !options.NoColor {
if obj.Type() == object.ERROR {
Expand All @@ -135,5 +141,5 @@ func EvalOne(s, macroState *eval.State, what string, out io.Writer, options Opti
if !options.NoColor {
fmt.Fprint(out, log.ANSIColors.Reset)
}
return false
return false, errs
}
32 changes: 30 additions & 2 deletions repl/repl_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,35 @@ called fact 3
called fact 2
called fact 1
Factorial of 5 is 120` + " \n120\n" // there is an extra space before \n that vscode wants to remove
if got := repl.EvalString(s); got != expected {
t.Errorf("EvalString() got\n---\n%s\n---want---\n%s\n---", got, expected)
if got, errs := repl.EvalString(s); got != expected || len(errs) > 0 {
t.Errorf("EvalString() got %v\n---\n%s\n---want---\n%s\n---", errs, got, expected)
}
}

func TestEvalStringParsingError(t *testing.T) {
s := `x:=3`
expected := ""
res, errs := repl.EvalString(s)
if len(errs) == 0 {
t.Errorf("EvalString() got no errors (res %q), expected some", res)
}
if res != expected {
t.Errorf("EvalString() got (%v) %q vs %q", errs, res, expected)
}
}

func TestEvalStringEvalError(t *testing.T) {
s := `y`
expected := "<err: <identifier not found: y>>"
res, errs := repl.EvalString(s)
if len(errs) == 0 {
t.Fatalf("EvalString() got no errors (res %q), expected some", res)
}
if errs[0] != expected {
t.Errorf("EvalString() errors\n---\n%s\n---want---\n%s\n---", errs[0], expected)
}
expected += "\n" // in output, there is a newline at the end.
if res != expected {
t.Errorf("EvalString() result %v\n---\n%s\n---want---\n%s\n---", errs, res, expected)
}
}

0 comments on commit c4f454c

Please sign in to comment.