Beispiel #1
0
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 = "%g"
	}
	conf.SetFormat(*format)
	conf.SetOrigin(*origin)
	conf.SetPrompt(*prompt)

	value.SetConfig(&conf)

	context := parse.NewContext()

	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, name, bufio.NewReader(fd))
			parser := parse.NewParser(&conf, name, scanner, context)
			if !run(parser, os.Stdout, context, interactive) {
				break
			}
		}
		return
	}

	scanner := scan.New(&conf, "<stdin>", bufio.NewReader(os.Stdin))
	parser := parse.NewParser(&conf, "<stdin>", scanner, context)
	for !run(parser, os.Stdout, context, true) {
	}
}
Beispiel #2
0
// runFromFile executes the contents of the named file.
func (p *Parser) runFromFile(name string) {
	runDepth++
	if runDepth > 10 {
		p.errorf("get %q nested too deep", name)
	}
	defer func() {
		runDepth--
		err := recover()
		if err == nil {
			return
		}
		if err, ok := err.(value.Error); ok {
			fmt.Fprintf(os.Stderr, "%s: %s\n", p.Loc(), err)
			return
		}
		panic(err)
	}()
	fd, err := os.Open(name)
	if err != nil {
		p.errorf("%s", err)
	}
	scanner := scan.New(p.config, name, bufio.NewReader(fd))
	parser := NewParser(p.config, name, scanner, p.context)
	for {
		value, ok := parser.Line()
		if value != nil {
			fmt.Fprintln(os.Stdout, value)
		}
		if !ok {
			return
		}
	}
}
Beispiel #3
0
func runTest(t *testing.T, name string, lineNum int, input, output []string) bool {
	shouldFail := strings.HasSuffix(name, "_fail.ivy")
	initConf()
	scanner := scan.New(&conf, "", strings.NewReader(strings.Join(input, "\n")+"\n"))
	context := parse.NewContext()
	value.SetContext(context)
	parser := parse.NewParser(&conf, name, scanner, context)
	testBuf.Reset()
	if !run(parser, context, false) != shouldFail {
		if shouldFail {
			t.Fatalf("\nexpected execution failure at %s:%d:\n%s", name, lineNum, strings.Join(input, "\n"))
		} else {
			t.Fatalf("\nexecution failure at %s:%d:\n%s", name, lineNum, strings.Join(input, "\n"))
		}
		return false
	}
	if shouldFail {
		return true
	}
	result := testBuf.String()
	if !equal(strings.Split(result, "\n"), output) {
		t.Errorf("\n%s:%d:\n%s\ngot:\n%swant:\n%s",
			name, lineNum,
			strings.Join(input, "\n"), result, strings.Join(output, "\n"))
		return false
	}
	return true
}
Beispiel #4
0
// runFromFile executes the contents of the named file.
func (p *Parser) runFromFile(context value.Context, name string) {
	runDepth++
	if runDepth > 10 {
		p.errorf("get %q nested too deep", name)
	}
	defer func() {
		runDepth--
		err := recover()
		if err == nil {
			return
		}
		if err, ok := err.(value.Error); ok {
			fmt.Fprintf(p.context.Config().ErrOutput(), "%s%s\n", p.Loc(), err)
			return
		}
		panic(err)
	}()
	fd, err := os.Open(name)
	if err != nil {
		p.errorf("%s", err)
	}
	scanner := scan.New(context, name, bufio.NewReader(fd))
	parser := NewParser(name, scanner, p.context)
	out := p.context.Config().Output()
	for {
		exprs, ok := parser.Line()
		for _, expr := range exprs {
			val := expr.Eval(p.context)
			if val == nil {
				continue
			}
			if _, ok := val.(Assignment); ok {
				continue
			}
			fmt.Fprintf(out, "%v\n", val.Sprint(context.Config()))
		}
		if !ok {
			return
		}
	}
}
Beispiel #5
0
// 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
}
Beispiel #6
0
Datei: run.go Projekt: db47h/ivy
// IvyEval is the function called by value/unaryIvy to implement the ivy (eval) operation.
// It is exported but is not intended to be used outside of ivy.
func IvyEval(context value.Context, str string) value.Value {
	scanner := scan.New(context, "<ivy>", strings.NewReader(str))
	parser := parse.NewParser("<ivy>", scanner, context)
	return eval(parser, context)
}
Beispiel #7
0
func runArgs(context value.Context) {
	scanner := scan.New(&conf, "<args>", strings.NewReader(strings.Join(flag.Args(), " ")))
	parser := parse.NewParser(&conf, "<args>", scanner, context)
	run(parser, os.Stdout, context, false)
}
Beispiel #8
0
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 = parse.NewContext()
	value.SetContext(context)

	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, name, bufio.NewReader(fd))
			parser := parse.NewParser(&conf, name, scanner, context)
			if !run(parser, context, interactive) {
				break
			}
		}
		return
	}

	scanner := scan.New(&conf, "<stdin>", bufio.NewReader(os.Stdin))
	parser := parse.NewParser(&conf, "<stdin>", scanner, context)
	for !run(parser, context, true) {
	}
}