// 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())
	}
}
Example #2
0
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)
	}
}
Example #3
0
// 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)
	}
}