func main() { qall.InitSafe(true) qlang.SetDumpCode(os.Getenv("QLANG_DUMPCODE")) libs := os.Getenv("QLANG_PATH") if libs == "" { libs = os.Getenv("HOME") + "/qlang" } if len(os.Args) > 1 { lang, err := qlang.New(qlang.InsertSemis) if err != nil { fmt.Fprintln(os.Stderr, err) os.Exit(1) } lang.SetLibs(libs) fname := os.Args[1] b, err := ioutil.ReadFile(fname) if err != nil { fmt.Fprintln(os.Stderr, err) os.Exit(2) } err = lang.SafeExec(b, fname) if err != nil { fmt.Fprintln(os.Stderr, err) os.Exit(3) } return } qall.Copyright() var ret interface{} qlang.SetOnPop(func(v interface{}) { ret = v }) lang, err := qlang.New(nil) if err != nil { fmt.Fprintln(os.Stderr, err) os.Exit(1) } lang.SetLibs(libs) scanner := bufio.NewScanner(os.Stdin) for scanner.Scan() { line := strings.Trim(scanner.Text(), " \t\r\n") if line == "" { continue } ret = nil err := lang.SafeEval(line) if err != nil { fmt.Fprintln(os.Stderr, err) continue } fmt.Printf("> %v\n\n", ret) } }
func TestSwitchDefaultContinue(t *testing.T) { lang, err := qlang.New(qlang.InsertSemis) if err != nil { t.Fatal("qlang.New:", err) } err = lang.SafeExec([]byte(` for i = 3; i < 10; i++ { x = 1 y = 2 switch { case false: z = 4 default: z = 3 continue } i = 100 }`), "") if err != nil { t.Fatal("qlang.SafeExec:", err) } if v, ok := lang.Var("i"); !ok || v != 10 { t.Fatal("i =", v) } }
func TestSwitchBreak(t *testing.T) { lang, err := qlang.New(qlang.InsertSemis) if err != nil { t.Fatal("qlang.New:", err) } err = lang.SafeExec([]byte(` for i = 3; i < 10; i++ { x = 1 y = 2 switch { case true: z = 3 break } i = 100 }`), "") if err != nil { t.Fatal("qlang.SafeExec:", err) } if v, ok := lang.Var("i"); !ok || v != 101 { t.Fatal("i =", v) } }
func TestInject(t *testing.T) { lang := qlang.New() err := lang.SafeExec([]byte(testInjectCode), "") if err != nil { t.Fatal("qlang.SafeExec:", err) } if v, ok := lang.Var("x"); !ok || v != 3 { t.Fatal("x != 3, x =", v) } err = lang.InjectMethods("typ", []byte(testInjectMethodsCode)) if err != nil { t.Fatal("InjectMethods failed:", err) } err = lang.SafeEval(testInjectCheckCode) if err != nil { t.Fatal("SafeEval failed:", err) } if v, ok := lang.Var("x2"); !ok || v != 4 { t.Fatal("x2 != 4, x2 =", v) } if v, ok := lang.Var("x3"); !ok || v != 11 { t.Fatal("x3 != 11, x3 =", v) } }
func TestForRange9(t *testing.T) { lang, err := qlang.New(qlang.InsertSemis) if err != nil { t.Fatal("qlang.New:", err) } err = lang.SafeExec([]byte(` ch = mkchan("int", 2) ch <- 10 ch <- 20 close(ch) x = 0 for v = range ch { x += v }`), "") if err != nil { t.Fatal("qlang.SafeExec:", err) } if v, ok := lang.Var("x"); !ok || v != 30 { t.Fatal("x =", v) } }
func TestMemberRef(t *testing.T) { lang := qlang.New() qlang.Import("", map[string]interface{}{ "fooMemberPtr": fooMemberPtr, "fooCall": fooCall, }) err := lang.SafeExec([]byte(testMemberRefCode), "") if err != nil { t.Fatal("qlang.SafeExec:", err) } if v, ok := lang.Var("x"); !ok || v != 3 { t.Fatal("x != 3, x =", v) } if v, ok := lang.Var("y"); !ok || v != 3 { t.Fatal("y != 3, y =", v) } if v, ok := lang.Var("z"); !ok || v != 3 { t.Fatal("z != 3, z =", v) } if v, ok := lang.Var("ret"); !ok || v != 3 { t.Fatal("ret != 3, ret =", v) } }
func TestGoroutine(t *testing.T) { lang := qlang.New() err := lang.SafeExec([]byte(testGoroutineCode), "") if err != nil { t.Fatal("qlang.SafeExec:", err) } if v, ok := lang.Var("x"); !ok || v != 3 { t.Fatal("x != 3, x =", v) } }
func TestNewClass(t *testing.T) { lang := qlang.New() err := lang.SafeExec([]byte(testNewClassCode), "") if err != nil { t.Fatal(err) } if v, ok := lang.Var("x"); !ok || v != 2 { t.Fatal("x != 2, x =", v) } }
func main() { lang := qlang.New() err := lang.SafeExec([]byte(scriptCode), "") if err != nil { fmt.Fprintln(os.Stderr, err) os.Exit(2) } v, _ := lang.Var("x") fmt.Println("x:", v) }
func TestContinue(t *testing.T) { lang, err := qlang.New(nil) if err != nil { t.Fatal("qlang.New:", err) } err = lang.SafeExec([]byte(`for i = 3; i < 10; i++ { continue; i=100 }`), "") if err != nil { t.Fatal("qlang.SafeExec:", err) } if v, ok := lang.Var("i"); !ok || v != 10 { t.Fatal("i =", v) } }
func TestIfBreak(t *testing.T) { lang, err := qlang.New(nil) if err != nil { t.Fatal("qlang.New:", err) } err = lang.SafeExec([]byte(`for i = 3; i < 10; i++ { x = 1; y = 2; if i == 8 { z = 3; break } }`), "") if err != nil { t.Fatal("qlang.SafeExec:", err) } if v, ok := lang.Var("i"); !ok || v != 8 { t.Fatal("i =", v) } }
func TestIf(t *testing.T) { lang, err := qlang.New(nil) if err != nil { t.Fatal("qlang.New:", err) } err = lang.SafeExec([]byte(`fn { 0 }; if true { x = 3 } else { x = 5 }`), "") if err != nil { t.Fatal("qlang.SafeExec:", err) } if v, ok := lang.Var("x"); !ok || v != 3 { t.Fatal("x =", v) } }
func TestAnonymFn(t *testing.T) { lang, err := qlang.New(qlang.InsertSemis) if err != nil { t.Fatal("qlang.New:", err) } err = lang.SafeExec([]byte(testAnonymFnCode), "") if err != nil { t.Fatal("qlang.SafeExec:", err) } if v, ok := lang.Var("x"); !ok || v != 3 { t.Fatal("x != 3, x =", v) } }
func TestNormalFor(t *testing.T) { lang, err := qlang.New(nil) if err != nil { t.Fatal("qlang.New:", err) } err = lang.SafeExec([]byte(`for i = 3; i < 10; i++ {}`), "") if err != nil { t.Fatal("qlang.SafeExec:", err) } if v, ok := lang.Var("i"); !ok || v != 10 { t.Fatal("i =", 10) } }
func TestErrMultiAssign(t *testing.T) { lang, err := qlang.New(qlang.InsertSemis) if err != nil { t.Fatal("qlang.New:", err) } err = lang.SafeExec([]byte(testErrMultiAssignCode), "") if err == nil { t.Fatal("qlang.SafeExec?") } if err.Error() != "line 3: runtime error: argument count of multi assignment doesn't match" { t.Fatal("testErrMultiAssignCode:", err) } }
func TestTypeOf(t *testing.T) { lang, err := qlang.New(qlang.InsertSemis) if err != nil { t.Fatal("qlang.New:", err) } err = lang.SafeExec([]byte(testTypeOfCode), "") if err != nil { t.Fatal("qlang.SafeExec:", err) } if v, ok := lang.Var("x"); !ok || v != reflect.TypeOf(uint32(1)) { t.Fatal("x != uint32, x =", v) } }
func TestClosure2(t *testing.T) { lang, err := qlang.New(qlang.InsertSemis) if err != nil { t.Fatal("qlang.New:", err) } err = lang.SafeExec([]byte(testClosureCode2), "") if err != nil { t.Fatal("qlang.SafeExec:", err) } if v, ok := lang.Var("x"); !ok || v != 1 { t.Fatal("x != 1, x =", v) } }
func TestInclude(t *testing.T) { lang, _ := qlang.New(qlang.InsertSemis) qlang.SetReadFile(func(file string) ([]byte, error) { return []byte(scriptA), nil }) err := lang.SafeExec([]byte(scriptB), "b.ql") if err != nil { t.Fatal(err) } if v, ok := lang.Var("b"); !ok || v != 2 { t.Fatal("b != 2, b =", v) } }
func TestUint32(t *testing.T) { lang, err := qlang.New(qlang.InsertSemis) if err != nil { t.Fatal("qlang.New:", err) } lang.SetVar("foo", fooUint32) err = lang.SafeExec([]byte(testUint32Code), "") if err != nil { t.Fatal("qlang.SafeExec:", err) } if v, ok := lang.Var("x"); !ok || v != uint32(6) { t.Fatal("x != 6, x =", v) } }
func TestReturn2(t *testing.T) { lang, err := qlang.New(qlang.InsertSemis) if err != nil { t.Fatal("qlang.New:", err) } err = lang.SafeExec([]byte(testReturnCode2), "") if err != nil { t.Fatal("qlang.SafeExec:", err) } if v, ok := lang.Var("x"); !ok || v != 3 { t.Fatal("x != 3, x =", v) } if v, ok := lang.Var("y"); !ok || v != 2 { t.Fatal("y != 2, y =", v) } }
func TestNilSlice(t *testing.T) { lang, err := qlang.New(qlang.InsertSemis) if err != nil { t.Fatal("qlang.New:", err) } err = lang.SafeExec([]byte(testNilSliceCode), "") if err != nil { t.Fatal("qlang.SafeExec:", err) } if v, ok := lang.Var("x"); !ok || v != reflect.TypeOf([]interface{}(nil)) { t.Fatal("x != []interface{}, x =", v) } if v, ok := lang.Var("y"); !ok || v != 1 { t.Fatal("y != 1, y =", v) } }
func TestForRange3(t *testing.T) { lang, err := qlang.New(qlang.InsertSemis) if err != nil { t.Fatal("qlang.New:", err) } err = lang.SafeExec([]byte(` x = 0 for _, v = range [10, 20] { x += v }`), "") if err != nil { t.Fatal("qlang.SafeExec:", err) } if v, ok := lang.Var("x"); !ok || v != 30 { t.Fatal("x =", v) } }
func TestForRange7(t *testing.T) { lang, err := qlang.New(qlang.InsertSemis) if err != nil { t.Fatal("qlang.New:", err) } err = lang.SafeExec([]byte(` x = 0 for k, v = range {10: 3, 20: 4} { x += k + v }`), "") if err != nil { t.Fatal("qlang.SafeExec:", err) } if v, ok := lang.Var("x"); !ok || v != 37 { t.Fatal("x =", v) } }
func TestModuleClass(t *testing.T) { lang, _ := qlang.New(qlang.InsertSemis) qlang.SetFindEntry(func(file string, libs []string) (string, error) { return file, nil }) qlang.SetReadFile(func(file string) ([]byte, error) { return []byte(scriptA2), nil }) err := lang.SafeExec([]byte(scriptB2), "b.ql") if err != nil { t.Fatal(err) } if v, ok := lang.Var("x"); !ok || v != 2 { t.Fatal("x != 2, x =", v) } }
func TestImport(t *testing.T) { lang, _ := qlang.New(qlang.InsertSemis) qlang.SetFindEntry(func(file string, libs []string) (string, error) { return file, nil }) qlang.SetReadFile(func(file string) ([]byte, error) { return []byte(scriptA), nil }) err := lang.SafeExec([]byte(scriptC), "c.ql") if err != nil { t.Fatal(err) } if v, ok := lang.Var("a"); !ok || v.(map[string]interface{})["b"] != 4 { t.Fatal("a.b != 4, a.b =", v) } }
func TestModuleDefer(t *testing.T) { lang, _ := qlang.New(qlang.InsertSemis) qlang.SetFindEntry(func(file string, libs []string) (string, error) { return file, nil }) qlang.SetReadFile(func(file string) ([]byte, error) { return []byte(scriptA1), nil }) err := lang.SafeExec([]byte(scriptB1), "b.ql") if err != nil { t.Fatal(err) } if v, ok := lang.Var("a"); !ok || v.(map[string]interface{})["x"] != 2 { t.Fatal("x != 2, x =", v) } }
func TestGet(t *testing.T) { lang, err := qlang.New(qlang.InsertSemis) if err != nil { t.Fatal("qlang.New:", err) } err = lang.SafeExec([]byte(testGetCode), "") if err != nil { t.Fatal("qlang.SafeExec:", err) } if v, ok := lang.Var("x"); !ok || v != 3 { t.Fatal("x != 3, x =", v) } if v, ok := lang.Var("y"); !ok || v != byte('3') { t.Fatal("y != '3', y =", v) } if v, ok := lang.Var("z"); !ok || v != 1 { t.Fatal("z != 1, z =", v) } }
func main() { qall.InitSafe(false) qlang.Import("", interpreter.Exports) qlang.SetDumpCode(os.Getenv("QLANG_DUMPCODE")) libs := os.Getenv("QLANG_PATH") if libs == "" { libs = os.Getenv("HOME") + "/qlang" } lang := qlang.New() lang.SetLibs(libs) vars = lang.Context eql := eqlang.New(lang) parseFlags() if source == "" { fmt.Fprintln(os.Stderr, usage) return } fi, err := os.Stat(source) if err != nil { fmt.Fprintln(os.Stderr, err) os.Exit(-2) } if fi.IsDir() { global := lang.CopyVars() eql.ExecuteDir(global, source, output) } else { eql.ExecuteFile(source, output) } }
func TestForRange11(t *testing.T) { lang, err := qlang.New(qlang.InsertSemis) if err != nil { t.Fatal("qlang.New:", err) } err = lang.SafeExec([]byte(` x = 0 for i, v = range [10, 20, 30, 40] { if true { if i == 2 { continue } } x += v }`), "") if err != nil { t.Fatal("qlang.SafeExec:", err) } if v, ok := lang.Var("x"); !ok || v != 70 { t.Fatal("x =", v) } }