func (b *Bubbler) Bubble(s string) (string, error) { env := core.Import(vm.NewEnv()) f := fizzer{b} // columns: env.Define("add_column", f.AddColumn()) env.Define("drop_column", f.DropColumn()) env.Define("rename_column", f.RenameColumn()) env.Define("raw", f.RawSql()) // indexes: env.Define("add_index", f.AddIndex()) env.Define("drop_index", f.DropIndex()) env.Define("rename_index", f.RenameIndex()) // tables: env.Define("create_table", f.CreateTable()) env.Define("drop_table", f.DropTable()) env.Define("rename_table", f.RenameTable()) _, err := env.Execute(s) return b.String(), errors.Wrap(err, "parse error") }
func main() { env := vm.NewEnv() env.Define("foo", reflect.ValueOf(1)) scanner := new(parser.Scanner) scanner.Init(`foo + 1`) stmts, err := parser.Parse(scanner) if err != nil { log.Fatal(err) } v, err := vm.Run(stmts, env) if err != nil { log.Fatal(err) } fmt.Println(v.Interface()) }
func main() { fs.Parse(os.Args[1:]) if *v { fmt.Println(version) os.Exit(0) } env := vm.NewEnv() var code string var b []byte var reader *bufio.Reader var following bool var source string repl := fs.NArg() == 0 && *e == "" env.Define("args", reflect.ValueOf(fs.Args())) if repl { reader = bufio.NewReader(os.Stdin) source = "typein" os.Args = append([]string{os.Args[0]}, fs.Args()...) } else { if *e != "" { b = []byte(*e) source = "argument" } else { var err error b, err = ioutil.ReadFile(fs.Arg(0)) if err != nil { colortext(ct.Red, false, func() { fmt.Fprintln(os.Stderr, err) }) os.Exit(1) } env.Define("args", reflect.ValueOf(fs.Args()[1:])) source = filepath.Clean(fs.Arg(0)) } os.Args = fs.Args() } anko_core.Import(env) tbl := map[string]func(env *vm.Env) *vm.Env{ "encoding/json": anko_encoding_json.Import, "flag": anko_flag.Import, "fmt": anko_fmt.Import, "io": anko_io.Import, "io/ioutil": anko_io_ioutil.Import, "math": anko_math.Import, "net": anko_net.Import, "net/http": anko_net_http.Import, "net/url": anko_net_url.Import, "os": anko_os.Import, "os/exec": anko_os_exec.Import, "path": anko_path.Import, "path/filepath": anko_path_filepath.Import, "regexp": anko_regexp.Import, "sort": anko_sort.Import, "strings": anko_strings.Import, "github.com/daviddengcn/go-colortext": anko_colortext.Import, } env.Define("import", reflect.ValueOf(func(s string) interface{} { if loader, ok := tbl[s]; ok { return loader(env) } panic(fmt.Sprintf("package '%s' not found", s)) })) for { if repl { colortext(ct.Green, true, func() { if following { fmt.Print(" ") } else { fmt.Print("> ") } }) var err error b, _, err = reader.ReadLine() if err != nil { break } if len(b) == 0 { continue } if code != "" { code += "\n" } code += string(b) } else { code = string(b) } scanner := new(parser.Scanner) scanner.Init(code) stmts, err := parser.Parse(scanner) v := vm.NilValue if repl { if e, ok := err.(*parser.Error); ok { if e.Pos.Column == len(b) && !e.Fatal { following = true continue } if e.Error() == "unexpected EOF" { following = true continue } } } following = false code = "" if err == nil { v, err = vm.Run(stmts, env) } if err != nil { colortext(ct.Red, false, func() { if e, ok := err.(*vm.Error); ok { fmt.Fprintf(os.Stderr, "%s:%d: %s\n", source, e.Pos.Line, err) } else if e, ok := err.(*parser.Error); ok { if e.Filename != "" { source = e.Filename } fmt.Fprintf(os.Stderr, "%s:%d: %s\n", source, e.Pos.Line, err) } else { fmt.Fprintln(os.Stderr, err) } }) if repl { continue } else { os.Exit(1) } } else { if repl { colortext(ct.Black, true, func() { if v == vm.NilValue || !v.IsValid() { fmt.Println("nil") } else { s, ok := v.Interface().(fmt.Stringer) if v.Kind() != reflect.String && ok { fmt.Println(s) } else { fmt.Printf("%#v\n", v.Interface()) } } }) } else { break } } } }
func NewAnkEnv() *vm.Env { env := vm.NewEnv() tbl := map[string]func(env *vm.Env) *vm.Env{ "json": jsonImport, "time": timeImport, "math": anko_math.Import, "regexp": anko_regexp.Import, "sort": anko_sort.Import, "strings": anko_strings.Import, } env.Define("import", reflect.ValueOf(func(s string) interface{} { if loader, ok := tbl[s]; ok { return loader(env) } panic(fmt.Sprintf("package '%s' not found", s)) })) env.Define("len", reflect.ValueOf(func(v interface{}) int64 { rv := reflect.ValueOf(v) if rv.Kind() == reflect.Interface { rv = rv.Elem() } if rv.Kind() == reflect.String { return int64(len([]byte(rv.String()))) } if rv.Kind() != reflect.Array && rv.Kind() != reflect.Slice { panic("Argument #1 should be array") } return int64(rv.Len()) })) env.Define("keys", reflect.ValueOf(func(v interface{}) []string { rv := reflect.ValueOf(v) if rv.Kind() == reflect.Interface { rv = rv.Elem() } if rv.Kind() != reflect.Map { panic("Argument #1 should be map") } keys := []string{} mk := rv.MapKeys() for _, key := range mk { keys = append(keys, key.String()) } return keys })) env.Define("range", reflect.ValueOf(func(args ...int64) []int64 { if len(args) < 1 { panic("Missing arguments") } if len(args) > 2 { panic("Too many arguments") } var min, max int64 if len(args) == 1 { min = 0 max = args[0] - 1 } else { min = args[0] max = args[1] } arr := []int64{} for i := min; i <= max; i++ { arr = append(arr, i) } return arr })) env.Define("toBytes", reflect.ValueOf(func(s string) []byte { return []byte(s) })) env.Define("toRunes", reflect.ValueOf(func(s string) []rune { return []rune(s) })) env.Define("toString", reflect.ValueOf(func(v interface{}) string { return fmt.Sprint(v) })) env.Define("toInt", reflect.ValueOf(func(v interface{}) int64 { nt := reflect.TypeOf(1) rv := reflect.ValueOf(v) if rv.Type().ConvertibleTo(nt) { return 0 } return rv.Convert(nt).Int() })) env.Define("toFloat", reflect.ValueOf(func(v interface{}) float64 { nt := reflect.TypeOf(1.0) rv := reflect.ValueOf(v) if rv.Type().ConvertibleTo(nt) { return 0.0 } return rv.Convert(nt).Float() })) env.Define("toBool", reflect.ValueOf(func(v interface{}) bool { nt := reflect.TypeOf(true) rv := reflect.ValueOf(v) if rv.Type().ConvertibleTo(nt) { return false } return rv.Convert(nt).Bool() })) env.Define("toChar", reflect.ValueOf(func(s rune) string { return string(s) })) env.Define("toRune", reflect.ValueOf(func(s string) rune { if len(s) == 0 { return 0 } return []rune(s)[0] })) env.Define("string", reflect.ValueOf(func(b []byte) string { return string(b) })) env.Define("typeof", reflect.ValueOf(func(v interface{}) string { return reflect.TypeOf(v).String() })) env.Define("defined", reflect.ValueOf(func(s string) bool { _, err := env.Get(s) return err == nil })) return env }
func serveApiPlay(w http.ResponseWriter, r *http.Request) { code := r.FormValue("code") scanner := new(parser.Scanner) scanner.Init(code) stmts, err := parser.Parse(scanner) if e, ok := err.(*parser.Error); ok { w.WriteHeader(500) fmt.Fprintf(w, "%d: %s\n", e.Pos.Line, err) return } w.Header().Set("Content-Type", "text/plain; charset=utf-8") env := vm.NewEnv() anko_core.Import(env) tbl := map[string]func(env *vm.Env) *vm.Env{ "encoding/json": anko_encoding_json.Import, "flag": anko_flag.Import, "fmt": anko_fmt.Import, "io": anko_io.Import, "io/ioutil": anko_io_ioutil.Import, "math": anko_math.Import, "net": anko_net.Import, "net/http": anko_net_http.Import, "net/url": anko_net_url.Import, "os": anko_os.Import, "os/exec": anko_os_exec.Import, "path": anko_path.Import, "path/filepath": anko_path_filepath.Import, "regexp": anko_regexp.Import, "sort": anko_sort.Import, "strings": anko_strings.Import, "github.com/daviddengcn/go-colortext": anko_colortext.Import, } env.Define("import", reflect.ValueOf(func(s string) interface{} { if loader, ok := tbl[s]; ok { return loader(env) } panic(fmt.Sprintf("package '%s' not found", s)) })) env.Define("println", reflect.ValueOf(func(a ...interface{}) { fmt.Fprint(w, fmt.Sprintln(a...)) })) env.Define("print", reflect.ValueOf(func(a ...interface{}) { fmt.Fprint(w, fmt.Sprint(a...)) })) env.Define("panic", reflect.ValueOf(func(a ...interface{}) { w.WriteHeader(500) fmt.Fprintf(w, "Can't use panic()") return })) env.Define("load", reflect.ValueOf(func(a ...interface{}) { w.WriteHeader(500) fmt.Fprintf(w, "Can't use load()") return })) defer env.Destroy() _, err = vm.Run(stmts, env) if err != nil { w.WriteHeader(500) if e, ok := err.(*vm.Error); ok { fmt.Fprintf(w, "%d: %s\n", e.Pos.Line, err) } else if e, ok := err.(*parser.Error); ok { fmt.Fprintf(w, "%d: %s\n", e.Pos.Line, err) } else { fmt.Fprintln(w, e.Error()) } } }
func ankoCmd(filename string) error { fmt.Println("ANKO " + filename) if len(filename) == 0 { err := errors.New("Please specify an Anko script file") printError(err) return err } file, err := os.Open(filename) if err != nil { printError(err) return err } env := vm.NewEnv() anko_core.Import(env) anko_flag.Import(env) anko_net.Import(env) anko_encoding.Import(env) anko_os.Import(env) anko_io.Import(env) anko_math.Import(env) anko_path.Import(env) anko_regexp.Import(env) anko_sort.Import(env) anko_strings.Import(env) anko_term.Import(env) var ln, code string lnScanner := bufio.NewScanner(file) for lnScanner.Scan() { ln = lnScanner.Text() code = code + ln + "\n" if err != nil { break printError(err) return err } } scanner := new(parser.Scanner) scanner.Init(code) stmts, err := parser.Parse(scanner) if err != nil { printError(err) return err } _, err = vm.Run(stmts, env) if err != nil { printError(err) return err } file.Close() return err }