All Projects → coyove → nj

coyove / nj

Licence: MIT license
NJ is a simple script engine in golang with Lua-like syntax.

Programming Languages

go
31211 projects - #10 most used programming language
Yacc
648 projects
HTML
75241 projects
lua
6591 projects
Raku
181 projects
python
139335 projects - #7 most used programming language

Projects that are alternatives of or similar to nj

universe-topology
A universal computer knowledge topology for all the programmers worldwide.
Stars: ✭ 47 (+147.37%)
Mutual labels:  closure, coroutine
Melang
A script language of preemptive scheduling coroutine in single thread
Stars: ✭ 273 (+1336.84%)
Mutual labels:  interpreter, coroutine
Script
Script is an object-oriented interpreted programming language. Being migrated to CppUtils
Stars: ✭ 18 (-5.26%)
Mutual labels:  interpreter, script-language
Gravity
Gravity Programming Language
Stars: ✭ 3,968 (+20784.21%)
Mutual labels:  interpreter, closure
php-coroutine
A lightweight library to implement coroutine by yield & Generator.
Stars: ✭ 27 (+42.11%)
Mutual labels:  yield, coroutine
BeauRoutine
Coroutine and tweening framework for Unity3D
Stars: ✭ 88 (+363.16%)
Mutual labels:  coroutine
pawn-3.2-plus
Pawn scripting language with runtime fixes and improvements
Stars: ✭ 14 (-26.32%)
Mutual labels:  interpreter
minima
A fast, byte-code interpreted language
Stars: ✭ 43 (+126.32%)
Mutual labels:  interpreter
xstate
State machines and statecharts for the modern web.
Stars: ✭ 21,286 (+111931.58%)
Mutual labels:  interpreter
LambdaCore
An interpreted language written in Rust inspired by the Lisp family of languages.
Stars: ✭ 56 (+194.74%)
Mutual labels:  interpreter
ol
Otus Lisp (Ol in short) is a purely* functional dialect of Lisp.
Stars: ✭ 157 (+726.32%)
Mutual labels:  interpreter
xin
Xin (신/心) is a flexible functional programming language with a tiny core, inspired by Lisp and CSP
Stars: ✭ 20 (+5.26%)
Mutual labels:  interpreter
python3-concurrency
Python3爬虫系列的理论验证,首先研究I/O模型,分别用Python实现了blocking I/O、nonblocking I/O、I/O multiplexing各模型下的TCP服务端和客户端。然后,研究同步I/O操作(依序下载、多进程并发、多线程并发)和异步I/O(asyncio)之间的效率差别
Stars: ✭ 49 (+157.89%)
Mutual labels:  coroutine
foth
Tutorial-style FORTH implementation written in golang
Stars: ✭ 50 (+163.16%)
Mutual labels:  interpreter
clover2
Clover2 can be used as shell. The completion is powerfull like IDE. Also clover2 is a Ruby-like compiler language with static type like Java. This is high performnace. Please see the wiki for details
Stars: ✭ 100 (+426.32%)
Mutual labels:  interpreter
NPython
(Subset of) Python programming language implemented in Nim
Stars: ✭ 17 (-10.53%)
Mutual labels:  interpreter
whilelang
A small programming language created with ANTLR and Scala
Stars: ✭ 29 (+52.63%)
Mutual labels:  interpreter
bfloader
🧠 Brainfuck IDE and interpreter in 512 bytes. (boot sector)
Stars: ✭ 41 (+115.79%)
Mutual labels:  interpreter
MUA-Interpreter
MUA is a functional language for teaching use in Principles of Programming Languages course.
Stars: ✭ 16 (-15.79%)
Mutual labels:  interpreter
tiny-lang
tiny-lang — A different programming language. Supports a bunch of spoken languages.
Stars: ✭ 26 (+36.84%)
Mutual labels:  interpreter

NJ is a simple script engine written in golang with Lua-like syntax.

(If you are looking for a Lua 5.2 compatible engine, refer to tag v0.2)

Differ from Lua

  • There is no table, instead there are array and object respectively:
    • a=[1, 2, 3].
    • a={a=1, b=2}.
    • Empty array and empty object are true when used as booleans.
  • There are typed array and untyped array:
    • Untyped arrays are generic arrays, where any values can be stored inside.
    • Typed arrays are special arrays from Go, say []byte:
      • a = bytes(16) creates a 16-byte long []byte.
      • a.append(1) appends 1 to it.
      • a.append(true) will panic.
      • a.untype().append(true) will untype the array into a (new) generic array.
  • Functions are callable objects:
    • function foo() end; print(type(foo)) prints object.
    • function foo() end; print(foo is callable) prints true.
  • Functions should be declared in the topmost scope:
    • do function foo() ... end end is invalid.
    • if true then function foo() function bar() ... end end is invalid.
    • function foo() function bar() ... end end is invalid.
  • Use lambda to declare anonymous functions:
    • local foo = lambda(x) ... end.
    • Last return can be omitted: lambda (x) x=x+1; x end <=> lambda (x) x=x+1; return x end.
  • Syntax of calling functions strictly requires no spaces between callee and '(':
    • print(1) is the only right way of calling a function.
    • print (1) literally means two things: 1) get value of print and discard it, 2) evaluate (1).
  • Same rule applies to unary operator -:
    • a = 1-a <=> a = 1 - a means assign the result of 1-a to a.
    • a = 1 -a means assign 1 to a and negate a.
    • a = 1 -a+1 means assign 1 to a and eval -a+1.
    • a = -a means negate a and assign the result to a.
    • a = - a is invalid.
  • There 2 ways to write if:
    • if cond then true else false end as a statement.
    • local a = if(cond, true, false) as an expression.
    • if(cond) then ... end is invalid, spaces after if statement is mandatory.
    • if (cond, true, false) is invalid, spaces after if expression is not allowed.
  • To write variadic functions:
    • function foo(a, b...) end.
    • args = [1, 2, 3]; foo(args...).
  • Simple keyword arguments syntax sugar:
    • foo(a, b=2, c=3) will be converted to foo(a, {b=2, c=3}).
  • Returning multiple arguments will be translated into returning an array, e.g.:
    • function foo() return 1, 2 end <=> function foo() return [1, 2] end.
    • local a, b, c = d <=> local a, b, c = d[0], d[1], d[2].
  • Everything starts at ZERO. For-loops start inclusively and end exclusively, e.g.:
    • a=[1, 2]; assert(a[0] == 1).
    • for i=0,n do ... end ranges [0, n-1].
    • for i=n-1,-1,-1 do ... end ranges [n-1, 0].
  • Every function has a this initially pointing to itself, if the function was loaded from an object, this will point to it instead:
    • function foo(x) this.x = x end; foo(1); assert(foo.x, 1)
    • a={foo=lambda(x) this.x = x end}; a.foo(1); assert(a.x, 1)
  • Use debug.self() to always get the caller itself:
    • a={foo=lambda(x) debug.self().x = x end}; a.foo(1); assert(foo.x, 1)
  • You can define up to 32000 variables (varies depending on the number of temporal variables generated by interpreter) in a function.
  • Numbers are int64 + float64 internally, interpreter may promote it to float64 when needed and downgrade it to int64 when possible.
  • You can return anywhere inside functions, continue inside for-loops, goto any label within the same function.

Run

program, err := nj.LoadString("return 1")
v, err := program.Run() // v == 1

Global Values

bas.Globals.SetProp("G", bas.ValueOf(func() int { return 1 }))

program, _ := nj.LoadString("return G() + 1")
v, err := program.Run() // v == 2

program, _ = nj.LoadString("return G() + 2")
v, err = program.Run() // v == 3

program, _ = nj.LoadString("return G + 2", &CompileOptions{
	Globals: bas.NewObject(0).SetProp("G", 10), // override the global 'G'
})
v, err = program.Run() // v == 12

Benchmarks

Refer to here.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].