Example #1
0
func AbtabGrepMakeExpressionFilter(inp *AbtabURL, expr string) AbtabFilterFn {
	var fset = token.NewFileSet()
	w := eval.NewWorld()
	InstallStandardLibrary(w)

	var vars map[string]*eval.Variable = make(map[string]*eval.Variable, 1)

	var empty = ""
	var lnum int
	v, _ := w.DefineVar("__LINE__", eval.TypeOfNative(lnum), eval.ToValue(lnum))
	vars["__LINE__"] = v

	for _, fname := range inp.Header {
		v, _ := w.DefineVar(ScrubFieldNameForEval(fname), eval.TypeOfNative(empty), eval.ToValue(empty))
		vars[fname] = v
	}

	return func(rec *Rec) (bool, error) {
		// NB: this seems expensive, can we just re-assign to the internal var ref?
		for idx, fname := range inp.Header {
			var value = rec.Fields[idx]
			vars[fname].Init = eval.ToValue(value)
		}

		//fmt.Fprintf(os.Stderr, "setting __LINE__=%d\n", rec.LineNum)
		vars["__LINE__"].Init = eval.ToValue(int(rec.LineNum))

		// NB: this seems expensive, can we compile once?
		code, err := w.Compile(fset, expr)
		if err != nil {
			return false, err
		}

		v, err := code.Run()
		if err != nil {
			return false, err
		}

		if v.String() == "true" {
			return true, nil
		}

		return false, nil
	}
}
Example #2
0
func main() {
	flag.Parse()
	w := eval.NewWorld()
	if *filename != "" {
		data, err := ioutil.ReadFile(*filename)
		if err != nil {
			fmt.Println(err.Error())
			os.Exit(1)
		}
		file, err := parser.ParseFile(fset, *filename, data, 0)
		if err != nil {
			fmt.Println(err.Error())
			os.Exit(1)
		}
		files := []*ast.File{file}
		code, err := w.CompilePackage(fset, files, "main")
		if err != nil {
			if list, ok := err.(scanner.ErrorList); ok {
				for _, e := range list {
					fmt.Println(e.Error())
				}
			} else {
				fmt.Println(err.Error())
			}
			os.Exit(1)
		}
		code, err = w.Compile(fset, "main()")
		if err != nil {
			fmt.Println(err.Error())
			os.Exit(1)
		}
		_, err = code.Run()
		if err != nil {
			fmt.Println(err.Error())
			os.Exit(1)
		}
		os.Exit(0)
	}

	fmt.Println(":: welcome to go-eval...")

	fd := int(os.Stdin.Fd())
	oldState, err := terminal.MakeRaw(fd)
	if err != nil {
		panic(err)
	}
	defer terminal.Restore(fd, oldState)
	term := terminal.NewTerminal(&shell{r: os.Stdin, w: os.Stdout}, "> ")
	if term == nil {
		panic(errors.New("could not create terminal"))
	}

	//foo := 123
	//w.DefineVar("foo", eval.TypeOfNative(foo), eval.ToValue(foo))

	for {
		line, err := term.ReadLine()
		if err != nil {
			break
		}
		code, err := w.Compile(fset, line)
		if err != nil {
			term.Write([]byte(err.Error() + "\n"))
			continue
		}
		v, err := code.Run()
		if err != nil {
			term.Write([]byte(err.Error() + "\n"))
			continue
		}
		if v != nil {
			term.Write([]byte(v.String() + "\n"))
		}
	}
}