github.com/coyove/nj@v0.0.0-20221110084952-c7f8db1065c3/README.md (about) 1 NJ is a simple script engine written in golang with Lua-like syntax. 2 3 (If you are looking for a Lua 5.2 compatible engine, refer to tag `v0.2`) 4 5 ## Differ from Lua 6 7 - There is no `table`, instead there are `array` and `object` respectively: 8 - `a=[1, 2, 3]`. 9 - `a={a=1, b=2}`. 10 - Empty array and empty object are `true` when used as booleans. 11 - There are `typed` array and `untyped` array: 12 - Untyped arrays are generic arrays created by `[...]`, it is the builtin array type. 13 - Typed arrays are special arrays created by Go, say `[]byte`: 14 - `a = bytes(16)` creates a 16-byte long `[]byte`. 15 - `a.append(1)` appends 1 to it. 16 - `a.append(true)` will panic. 17 - `a.untype().append(true)` will `untype` the array into a (new) generic array. 18 - Functions are callable objects: 19 - `function foo() end; assert(type(foo), "object")` 20 - `function foo() end; assert(foo is callable)` 21 - Closures are created by capturing all symbols seen in the current scope and binding them to the returned function: 22 - `function foo(a, b) return function(c) return self.a + self.b + c end end` 23 - `assert(foo(1, 2)(3), 6)` 24 - Syntax of calling functions strictly requires no spaces between the callee and '(': 25 - `print(1)` is the only right way of calling a function. 26 - `print (1)` literally means two things: 1) get value of `print` and discard it, 2) evaluate `(1)`. 27 - Also note that all required arguments must be provided to call a function properly: 28 - `function foo(a, b) end; foo(1)` is invalid. 29 - Spacing rule also applies to unary operator `-`: 30 - `a = 1-a <=> a = 1 - a` means assign the result of `1-a` to `a`. 31 - `a = 1 -a` means assign `1` to `a` and negate `a`. 32 - `a = 1 -a+1` means assign `1` to `a` and eval `-a+1`. 33 - `a = -a` means negate `a` and assign the result to `a`. 34 - `a = - a` is invalid. 35 - There are two ways to write `if`: 36 - `if cond then true else false end` as a statement. 37 - `local a = if(cond, true, false)` as an expression. 38 - `if(cond) then ... end` is invalid, spaces after `if` statement is mandatory. 39 - `if (cond, true, false)` is invalid, spaces after `if` expression is not allowed. 40 - To write variadic functions: 41 - `function foo(a, b...) end; args = [1, 2, 3]; foo(args...)`. 42 - Parameters after `...` are optional: 43 - `function foo(a ... b, c) end; foo(1); foo(1, 2); foo(1, 2, 3)` 44 - Returning multiple arguments will be translated into returning an array, e.g.: 45 - `function foo() return 1, 2 end <=> function foo() return [1, 2] end` 46 - `local a, b, c = d <=> local a, b, c = d[0], d[1], d[2]` 47 - Everything starts at ZERO. For-loops start inclusively and end exclusively, e.g.: 48 - `a=[1, 2]; assert(a[0] == 1)`. 49 - `for i=0,n do ... end` ranges `[0, n-1]`. 50 - `for i=n-1,-1,-1 do ... end` ranges `[n-1, 0]`. 51 - For method function, it can access `this` which points to the receiver: 52 - `a={}; function a.foo(x) this.x = x end; a.foo(1); assert(a.x, 1)` 53 - For any function, use `self` to get itself in the body: 54 - `function foo(x) self.x = x end; foo(1); assert(foo.x, 1)` 55 - You can define up to 32000 variables (varies depending on the number of temporal variables generated by interpreter) in a function. 56 - Numbers are `int64 + float64` internally, interpreter may promote it to `float64` when needed and downgrade it to `int64` when possible. 57 - You can `return` anywhere inside functions, `continue` inside for-loops, `goto` any label within the same function. 58 59 ## Run 60 61 ```golang 62 program, err := nj.LoadString("return 1") 63 v, err := program.Run() // v == 1 64 ``` 65 66 ### Global Values 67 68 ```golang 69 bas.AddGlobal("G", bas.ValueOf(func() int { return 1 })) 70 71 program, _ := nj.LoadString("return G() + 1") 72 v, err := program.Run() // v == 2 73 74 program, _ = nj.LoadString("return G() + 2") 75 v, err = program.Run() // v == 3 76 77 program, _ = nj.LoadString("return G + 2", &CompileOptions{ 78 Globals: bas.NewObject(0).SetProp("G", 10).ToMap(), // override the global 'G' 79 }) 80 v, err = program.Run() // v == 12 81 ``` 82 83 ## Benchmarks 84 85 Refer to [here](https://github.com/coyove/nj/blob/master/tests/bench/perf.md). 86