rumo is a small, fast and secure script language for Go supporting routines and channels
This is pre release software so expect bugs and breaking changes
package main
import (
"fmt"
"github.com/malivvan/rumo"
)
func main() {
// script code
src := `
each := func(seq, fn) {
for x in seq { fn(x) }
}
sum := 0
mul := 1
each([a, b, c, d], func(x) {
sum += x
mul *= x
})`
// create a new script instance
script := rumo.NewScript([]byte(src))
// add variables with default values
_ = script.Add("a", 0)
_ = script.Add("b", 0)
_ = script.Add("c", 0)
_ = script.Add("d", 0)
// compile script to program
program, err := script.Compile()
if err != nil {
panic(err)
}
// clone a new instance of the program and set values
instance := program.Clone()
_ = instance.Set("a", 1)
_ = instance.Set("b", 9)
_ = instance.Set("c", 8)
_ = instance.Set("d", 4)
// run the instance
err = instance.Run()
if err != nil {
panic(err)
}
// retrieve variable values
sum := instance.Get("sum")
mul := instance.Get("mul")
fmt.Println(sum, mul) // "22 288"
}fmt := import("fmt")
each := func(seq, fn) {
for x in seq { fn(x) }
}
sum := func(init, seq) {
each(seq, func(x) { init += x })
return init
}
fmt.println(sum(0, [1, 2, 3])) // "6"
fmt.println(sum("", [1, 2, 3])) // "123"v := 0
f1 := func(a,b) { v = 10; return a+b }
f2 := func(a,b,c) { v = 11; return a+b+c }
rvm1 := go f1(1,2)
rvm2 := go f2(1,2,5)
fmt.println(rvm1.result()) // 3
fmt.println(rvm2.result()) // 8
fmt.println(v) // 10 or 11unbufferedChan := chan()
bufferedChan := chan(128)
// Send will block if the channel is full.
bufferedChan.send("hello") // send string
bufferedChan.send(55) // send int
bufferedChan.send([66, chan(1)]) // channel in channel
// Receive will block if the channel is empty.
obj := bufferedChan.recv()
// Send to a closed channel causes panic.
// Receive from a closed channel returns undefined value.
unbufferedChan.close()
bufferedChan.close()reqChan := chan(8)
repChan := chan(8)
client := func(interval) {
reqChan.send("hello")
for i := 0; true; i++ {
fmt.println(repChan.recv())
time.sleep(interval*time.second)
reqChan.send(i)
}
}
server := func() {
for {
req := reqChan.recv()
if req == "hello" {
fmt.println(req)
repChan.send("world")
} else {
repChan.send(req+100)
}
}
}
rClient := start client(2)
rServer := start server()
if ok := rClient.wait(5); !ok {
rClient.stop()
}
rServer.stop()
//output:
//hello
//world
//100
//101make test # run tests
make install # install tools
make build # build for current platform
make release # build for all platforms
make js # build the js/wasm runtime + browser bundle into build/web/
make serve/js # build and serve the js/wasm runtime at http://localhost:8080The js/wasm target produces a plain Go webassembly binary that runs in the
browser like any other Go wasm module (GOMAXPROCS=1 semantics): script
routines are in-process goroutines, and the bundled page hosts the runtime in
a worker. Load build/web/index.html through any static file server and use
the rumo JavaScript API to run scripts in the browser.
This is a continuation of the github.com/d5/tengo project starting of this pull request implementing go routines and channels. Special thanks goes to d5 for his work on the tengo language and Bai-Yingjie for implementing the foundation of concurrency while retaining the original tests of the project.