// Eval evaluates the input string and returns its output. // If execution caused errors, they will be returned concatenated // together in the error value returned. // TODO: Should it stop at first error? func Eval(expr string) (result string, errors error) { if !strings.HasSuffix(expr, "\n") { expr += "\n" } reader := strings.NewReader(expr) stdout := new(bytes.Buffer) stderr := new(bytes.Buffer) conf.SetOutput(stdout) conf.SetErrOutput(stderr) scanner := scan.New(&conf, context, " ", reader) parser := parse.NewParser(&conf, " ", scanner, context) for !run.Run(parser, context, false) { } var err error if stderr.Len() > 0 { err = fmt.Errorf("%s", stderr) } return stdout.String(), err }
func main() { flag.Usage = usage flag.Parse() if *origin != 0 && *origin != 1 { fmt.Fprintf(os.Stderr, "ivy: illegal origin value %d\n", *origin) os.Exit(2) } if *gformat { *format = "%.12g" } conf.SetFormat(*format) conf.SetMaxBits(*maxbits) conf.SetMaxDigits(*maxdigits) conf.SetOrigin(*origin) conf.SetPrompt(*prompt) if len(*debugFlag) > 0 { for _, debug := range strings.Split(*debugFlag, ",") { if !conf.SetDebug(debug, true) { fmt.Fprintf(os.Stderr, "ivy: unknown debug flag %q", debug) os.Exit(2) } } } value.SetConfig(&conf) context = exec.NewContext() value.SetContext(context) run.SetConfig(&conf) if *execute { runArgs(context) return } if flag.NArg() > 0 { for i := 0; i < flag.NArg(); i++ { name := flag.Arg(i) var fd io.Reader var err error interactive := false if name == "-" { interactive = true fd = os.Stdin } else { interactive = false fd, err = os.Open(name) } if err != nil { fmt.Fprintf(os.Stderr, "ivy: %s\n", err) os.Exit(1) } scanner := scan.New(&conf, context, name, bufio.NewReader(fd)) parser := parse.NewParser(&conf, name, scanner, context) if !run.Run(parser, context, interactive) { break } } return } scanner := scan.New(&conf, context, "<stdin>", bufio.NewReader(os.Stdin)) parser := parse.NewParser(&conf, "<stdin>", scanner, context) for !run.Run(parser, context, true) { } }
// runArgs executes the text of the command-line arguments as an ivy program. func runArgs(context value.Context) { scanner := scan.New(&conf, context, "<args>", strings.NewReader(strings.Join(flag.Args(), " "))) parser := parse.NewParser(&conf, "<args>", scanner, context) run.Run(parser, context, false) }