// ExpectResult check the evaluation of a string with an expected result. // More importantly though, does the steps to evaluate a string: // 1. Parse expression using parser.ParseExpr (go/parser) // 2. Type check expression using evalCheckExpr (0xfaded/eval) // 3. run eval.EvalExpr (0xfaded/eval) func ExampleFullApi() { expr := `fmt.Sprintf("%s %d", constant1, add(var1, 1) + 1)` env := makeEnv() // Create evaluation environment if e, err := parser.ParseExpr(expr); err != nil { fmt.Printf("Failed to parse expression '%s' (%v)\n", expr, err) } else if cexpr, errs := eval.CheckExpr(e, env); len(errs) != 0 { fmt.Printf("Error checking expression '%s' (%v)\n", expr, errs) } else if results, err := eval.EvalExpr(cexpr, env); err != nil { fmt.Printf("Panic evaluating expression '%s' (%v)\n", expr, err) } else { fmt.Printf("Expression '%s' yielded '%+v'\n", expr, results[0].Interface()) } }
func expectResult(expr string, env eval.Env, expected interface{}) { if e, err := parser.ParseExpr(expr); err != nil { fmt.Printf("Failed to parse expression '%s' (%v)\n", expr, err) return } else if cexpr, errs := eval.CheckExpr(e, env); len(errs) != 0 { fmt.Printf("Error checking expression '%s' (%v)\n", expr, errs) } else if results, err := eval.EvalExpr(cexpr, env); err != nil { fmt.Printf("Error evaluating expression '%s' (%v)\n", expr, err) return } else { fmt.Printf("Expression '%s' yielded '%+v', expected '%+v'\n", expr, results[0].Interface(), expected) } }
// REPL is the a read, eval, and print loop. func REPL(env *eval.SimpleEnv) { var err error // A place to store result values of expressions entered // interactively results := make([]interface{}, 0, 10) env.Vars["results"] = reflect.ValueOf(&results) exprs := 0 in := bufio.NewReader(os.Stdin) line, err := readline("go> ", in) for line != "quit" { if err != nil { if err == io.EOF { break } panic(err) } if expr, err := parser.ParseExpr(line); err != nil { if pair := eval.FormatErrorPos(line, err.Error()); len(pair) == 2 { fmt.Println(pair[0]) fmt.Println(pair[1]) } fmt.Printf("parse error: %s\n", err) } else if cexpr, errs := eval.CheckExpr(expr, env); len(errs) != 0 { for _, cerr := range errs { fmt.Printf("check error: %v\n", cerr) } } else if vals, err := eval.EvalExpr(cexpr, env); err != nil { fmt.Printf("panic: %s\n", err) } else if len(vals) == 0 { fmt.Printf("Kind=Slice\nvoid\n") } else if len(vals) == 1 { value := (vals)[0] if value.IsValid() { kind := value.Kind().String() typ := value.Type().String() if typ != kind { fmt.Printf("Kind = %v\n", kind) fmt.Printf("Type = %v\n", typ) } else { fmt.Printf("Kind = Type = %v\n", kind) } fmt.Printf("results[%d] = %s\n", exprs, eval.Inspect(value)) exprs += 1 results = append(results, (vals)[0].Interface()) } else { fmt.Printf("%s\n", value) } } else { fmt.Printf("Kind = Multi-Value\n") size := len(vals) for i, v := range vals { fmt.Printf("%s", eval.Inspect(v)) if i < size-1 { fmt.Printf(", ") } } fmt.Printf("\n") exprs += 1 results = append(results, vals) } line, err = readline("go> ", in) } }