Expr – a tiny stack-based virtual machine written in Go

Expr – a tiny stack-based virtual machine written in Go

Build Status codecov Go Reference

The executor is designed to interpret a simple expression language and it's useful in delegating decision enforcement to user scripts.

User scripts can produce scalar or array variables.

You can easily embed the toolchain in your Go application.

The executor is blazingly fast and it makes no memory allocation.

You can add custom functions to the executor empowering your application.

Syntax

Data types

integer (64 bit)

-9223372036854775808 .. 9223372036854775807

string (wrapped by double quote)

"Hello Expr!"
"Welcome \"Alice\" and \"Bob\""

boolean

true, false

array (a vector of elements)

[1, true, "text"]
[["hello"], "world!"]

Operators

The virtual machine supports basic math operators +-*/. A math expression might be surrounded by parentheses. Examples:

1 + -1
1 * (2 + 3)

Delegators

In general, delegators are functions implemented by the hosted application.

Helpfully, this toolchain is equipped with an own standard library to handle basic operation on its data types.

stdlib

concat(string, ...)

returns a concatenated string

concat("a", "b", "c") // "abc"
join(string, [string, ...])

returns a concatenated string with a separator

join(", ", ["a", "b", "c"]) // "a, b, c"
equals(string, string)
equals(int64, int64)
equals([string, ...], [string, ...])
equals([int64, ...], [int64, ...])

returns true if both arguments are equal

equals(1, 1) // true
equals(1, 0) // false
equals("foo", "foo") // true
equals("foo", "bar") // false
equals(["foo", 1], ["foo", 1]) // true
equals(["foo"], ["bar"]) // false
intersects([string, ...], [string, ...])
intersects([int64, ...], [int64, ...])

returns true if both arrays share the same item

intersects([1, 2, 3], [3, 4]) // true
intersects([1, 2, 3], [4, 5]) // false
contains([string, ...], string)
contains([int64, ...], int64)

returns true if the value exists in the array

contains([1, 2, 3], 1) // true
contains([1, 2, 3], 4) // false

Architecture

The architecture consists of 3 components:

  1. Lexer
  2. Compiler
  3. Virtual Machine

The lexer parses the input text:

join(",", ["a", "b"])

and generates a syntax tree:

STR ","
STR "a"
STR "b"
ARR 2
INVOKE join 2

The lexer is implemented using Ragel State Machine Compiler.

The compiler makes a bytecode from the syntax tree to make it executable by a stack-based virtual machine.

The bytecode is described by Flatbuffers to achieve high-throughput with low memory consumption.

Usage

Compilation:

import (
    "github.com/regeda/expr/compiler"
    "github.com/regeda/expr/lexer"
)

code := `join(",", ["a", "b"])`

tokens, err := lexer.Parse([]byte(code))
if err != nil {
    panic(err)
}

bytecode := compiler.Compile(tokens)

// save `bytecode` to be executed by the virtual machine

Running:

import (
    "github.com/regeda/expr/delegate"
    "github.com/regeda/expr/exec"
    "github.com/regeda/expr/stdlib"
)

bytecode := ... // read []byte

ex := exec.New(
    exec.WithRegistry(delegate.Import(stdlib.Compare, stdlib.Strings)),
)
addr, err := ex.Exec(bytecode)
if err != nil {
    panic(err)
}
// `addr` contains the result, see github.com/regeda/expr/memory.Addr

Exec is not designed to be run in the concurrent environment. However, you can define a pool of executors to consume them in the safe mode.

Benchmark

The benchmark executes a compiled bytecode of the following statement:

equals("foo,bar,baz", join(",", ["foo", "bar", "baz"]))
cpu: Intel(R) Core(TM) i5-8259U CPU @ 2.30GHz
BenchmarkExec
BenchmarkExec-8          1635091               746.7 ns/op             0 B/op          0 allocs/op
Owner
Anthony Regeda
Make code, not war!
Anthony Regeda
Similar Resources

OperatingSys-GO - A Virtual Operating System made by using GOLANG and FYNE

Operating-System This is a Virtual Operating System made by using GOLANG and FYN

Jan 2, 2022

An interpreter written in go for a brainfuck-based language called €*

eurostar-go-interpreter This is an interpreter written in go for a brainfuck-bas

Sep 14, 2022

Process manager for Procfile-based applications

Hivemind Hivemind is a process manager for Procfile-based applications. At the moment, it supports Linux, FreeBSD, and macOS. Procfile is a simple for

Dec 25, 2022

Process manager for Procfile-based applications and tmux

Process manager for Procfile-based applications and tmux

Overmind Overmind is a process manager for Procfile-based applications and tmux. With Overmind, you can easily run several processes from your Procfil

Jan 4, 2023

Manage Procfile-based applications

Foreman Manage Procfile-based applications Installation $ gem install foreman Ruby users should take care not to install foreman in their project's G

Dec 30, 2022

Scriptable interpreter written in golang

Scriptable interpreter written in golang

Anko Anko is a scriptable interpreter written in Go. (Picture licensed under CC BY-SA 3.0, photo by Ocdp) Usage Example - Embedded package main impor

Dec 23, 2022

Gentee - script programming language for automation. It uses VM and compiler written in Go (Golang).

Gentee script programming language Gentee is a free open source script programming language. The Gentee programming language is designed to create scr

Dec 15, 2022

A POSIX-compliant AWK interpreter written in Go

GoAWK: an AWK interpreter written in Go AWK is a fascinating text-processing language, and somehow after reading the delightfully-terse The AWK Progra

Dec 31, 2022

A BASIC interpreter written in golang.

A BASIC interpreter written in golang.

05 PRINT "Index" 10 PRINT "GOBASIC!" 20 PRINT "Limitations" Arrays Line Numbers IF Statement DATA / READ Statements Builtin Functions Types 30 PRINT "

Dec 24, 2022
Comments
  • Tokenizer

    Tokenizer

    Move out from the lexer approach where we generate the syntax tree during the input parsing. Then we have two independent packages:

    1. The tokenizer for parsing the input and generating a stream of tokens
    2. The syntax tree builder creates AST from tokens

    This change gives more flexibility in AST generating.

A customisable virtual machine written in Go

== About GoLightly == GoLightly is a lightweight virtual machine library implemented in Go, designed for flexibility and reuse. Traditionally popular

Nov 16, 2022
A simple virtual machine - compiler & interpreter - written in golang

go.vm Installation Build without Go Modules (Go before 1.11) Build with Go Modules (Go 1.11 or higher) Usage Opcodes Notes The compiler The interprete

Dec 17, 2022
Virtual-Operating-System - Virtual Operating System Using Golang And Fyne Implemented Gallery app
Virtual-Operating-System - Virtual Operating System Using Golang And Fyne Implemented Gallery app

Virtual Operating System Virtual Operating System Using Golang And Fyne Implemen

Jan 1, 2022
Forth virtual machine in Go

forego - A Forth implementation in Go ===================================== Why? ---- For ego. This is me learning the language. Both of them. So

Sep 9, 2022
Weave Ignite is an open source Virtual Machine (VM) manager with a container UX and built-in GitOps management.
Weave Ignite is an open source Virtual Machine (VM) manager with a container UX and built-in GitOps management.

Weave Ignite is an open source Virtual Machine (VM) manager with a container UX and built-in GitOps management.

Nov 16, 2021
Create virtual machines and run Linux-based operating systems in Go using Apple Virtualization.framework.

vz - Go binding with Apple Virtualization.framework vz provides the power of the Apple Virtualization.framework in Go.

Jan 9, 2023
T# Programming Language. Something like Porth, Forth but written in Go. Stack-oriented programming language.

The T# Programming Language WARNING! THIS LANGUAGE IS A WORK IN PROGRESS! ANYTHING CAN CHANGE AT ANY MOMENT WITHOUT ANY NOTICE! Something like Forth a

Jun 29, 2022
This is a Virtual Operating System made by using GOLANG and FYNE.
This is a Virtual Operating System made by using GOLANG and FYNE.

Virtual-Operating-System This is a Virtual Operating System made by using GOLANG and FYNE. Hello! All In this project I have made a virtual Operating

Nov 1, 2021
Lima: Linux virtual machines (on macOS, in most cases)

Linux virtual machines, on macOS (aka "Linux-on-Mac", "macOS subsystem for Linux", "containerd for Mac", unofficially)

Jan 1, 2023
Virtual Operating System Using Golang
Virtual Operating System Using Golang

Virtual Operating System Virtual Operating System Using Golang And Fyne Installation 1.Install Go 2.Install Gcc 3.Install Fyne Using This Command:- g

Jun 5, 2022