vv 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/vv"
)
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 := vv.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 := start(f1,1,2)
rvm2 := start(f2,1,2,5)
fmt.println(rvm1.result()) // 3
fmt.println(rvm2.result()) // 8
fmt.println(v) // 10 or 11
unbufferedChan := 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())
times.sleep(interval*times.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.abort()
}
rServer.abort()
//output:
//hello
//world
//100
//101
make test # run tests
make install # install tools
make build # build for current platform
make release # build for all platforms
make docs # generate docs
- console ui module
- routines and channels
- scriptable webserver module
- sh compatible shell for direct bytecode execution
- secure self updates using github-releases
- ssh system service for running programs in the background
- webassembly port with web worker support for concurrency
NOTE there will never be any form of cgo support / usage
package | repository | license |
---|---|---|
cui |
codeberg.org/tslocum/cview | MIT |
cui/bind.go |
codeberg.org/tslocum/cbind | MIT |
cui/chart |
github.com/navidys/tvxwidgets | MIT |
cui/editor |
github.com/pgavlin/femto | MIT, MIT |
cui/menu |
github.com/Racinettee/tmenu | BSD 3-Clause License |
cui/vte |
git.sr.ht/~rockorager/tcell-term | MIT |
sh/readline |
github.com/ergochat/readline | MIT |
ssh |
github.com/ferama/rospo | MIT |
cli |
github.com/aperturerobotics/cli | MIT |
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.