An embeddable implementation of the Ngaro Virtual Machine for Go programs

Build Status Go Report Card Coverage Status GoDoc

Ngaro Go

Overview

This is an embeddable Go implementation of the Ngaro Virtual Machine.

This repository contains the embeddable virtual machine, a rudimentary symbolic assembler for easy bootstrapping of projects written in Ngaro machine language, and the retro command line tool that can be used as a replacement for the Retro reference implementations.

Please visit http://forthworks.com/retro/ to get you started about the Retro language and the Ngaro Virtual Machine.

The main purpose of this implementation is to allow customization and communication between Retro programs and Go programs via custom opcodes and I/O handlers (i.e. scripting Go programs in Retro). The package examples demonstrate various use cases. For more details on I/O handling in the Ngaro VM, please refer to http://retroforth.org/docs/The_Ngaro_Virtual_Machine.html.

Another goal is to make the VM core as neutral as possible regarding the higher level language running on it. For example, the in-memory string encoding scheme is fully customizable. Retro specific behaviors are provided via the lang/retro package.

Custom opcodes are implemented by intercepting implicit calls to negative memory addresses. This allows the VM to be fully backwards compatible with existing Retro images while still providing enhanced capabilities. The maximum number of addressable cells is 2^31 when running in 32 bits mode (that's 8GiB or memory on the host). The range [-2^31 - 1, -1] is available for custom opcodes.

This implementation passes all tests from the retro-language test suite and its performance when running tests/core.rx is slightly better than with the reference implementations:

1.08s for this implementation, no custom opcodes, compiled with Go 1.7, linux/amd64
1.15s for the reference assembly implementation, linux/386
1.30s for the reference Go implementation, compiled with Go 1.7, linux/amd64
2.00s for the reference C implementation, compiled with gcc-5.4 -O3 -fomit-frame-pointer

Yes, Go 1.7's new SSA backend is THAT good on this type of workload :)

For all intents and purposes, the VM behaves according to the specification. This is of particular importance to implementors of custom opcodes: the VM always increments the PC after each opcode, thus opcodes altering the PC must adjust it accordingly (i.e. set it to its real target minus one).

Installing

Install the retro command line tool:

go get -u github.com/db47h/ngaro/cmd/retro

Test:

go test -i github.com/db47h/ngaro/vm
go test -v github.com/db47h/ngaro/vm/...

Build a retroImage:

cd $GOPATH/github.com/db47h/ngaro/cmd/retro
make retroImage

Test the retro command line tool:

./retro --with vm/testdata/core.rx

Should generate a lot of output. Just check that the last lines look like this:

ok   summary
360 tests run: 360 passed, 0 failed.
186 words checked, 0 words unchecked, 37 i/o words ignored.

ok  bye

Support for 32/64 bits memory images on all architectures

Since v2.0.0, the default Cell type (the base data type in Ngaro VM) is Go's int. This means that depending on the target you compile for, it will be either 32 or 64 bits. The retro command line tool supports loading and saving retro memory images where Cells can be either size. For example, to quickly get started you can do this:

echo "save bye" | \
retro -image vm/testdata/retroImage -ibits 32 -o retroImage

This will load the memory image file vm/testdata/retroImage which we know to be encoded using 32 bits cells, and save it in the current directory with whatever encoding is the default for your platform. You could also force a specific output Cell size with the -obits flag.

Loading and saving with encodings different from the target platform is safe: it will work or generate an error, but never create a corrupted memory image file. For example, with a 64 bits retro binary, saving to 32 bits cells will check that written values fit in a 32 bit int. If not, it will generate an error.

If for some reason you need a specific cell size, regardless of the target platform's native int size, you can force it by compiling with the tags ngaro32 or ngaro64:

go install -tags ngaro32 github.com/db47h/ngaro/cmd/retro

will build a version of retro that uses 32 bits cells, regardless of GOOS/GOARCH. Likewise, the ngaro64 tag will force 64 bits cells, even on 32 bits targets (it'll be twice as slow though).

Releases

This project uses semantic versioning and tries to adhere to it.

See the releases page.

For a detailed change log, see the commit log.

Contributing

No rules, just common sense. Bells, wristles and any other preformance improvements are very welcome. The only changes that will never be accepted are those that will break compatibility with the VM specification.

PRs are a good place to discuss changes so do not hesitate to send PRs directly. Or an issue, if your really have an issue.

Places to Go

Have a look at @dobegor's fork. It breaks compatibility with the spec, but it's got some nice features like floating point support, pausable VM, and a few others in their TODO list.

License

This project is Copyright 2016 Denis Bernard [email protected], licensed under the Apache License, Version 2.0.

The Retro language and Ngaro Virtual Machine are Copyright (c) 2008-2016 Charles Childers (and many others), licensed under the ISC license. See the file LICENSE-RETRO at the root of this repository for more details as well as a full list of contributors.

Note that all files in the _misc and vm/testdata folders are verbatim copies from the retro-language project. As such, only Retro's ISC license applies to these files.

Owner
Similar Resources

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

Mimic - a eBPF virtual machine and emulator which runs in userspace

Mimic is a eBPF virtual machine and emulator which runs in userspace. Mimic attempts to 'mimic' the eBPF machinery we find in the Linux kernel, as well as other possible implementation/environments.

Dec 6, 2022

A Go implementation of gnu-coreutils programs

Go-Coreutils A Go implementation of gnu-coreutils programs (https://www.gnu.org/software/coreutils/manual/coreutils.html) Build and Run In the root di

Jan 15, 2022

BuntDB is an embeddable, in-memory key/value database for Go with custom indexing and geospatial support

BuntDB is an embeddable, in-memory key/value database for Go with custom indexing and geospatial support

BuntDB is a low-level, in-memory, key/value store in pure Go. It persists to disk, is ACID compliant, and uses locking for multiple readers and a sing

Dec 30, 2022

A simple, fast, embeddable, persistent key/value store written in pure Go. It supports fully serializable transactions and many data structures such as list, set, sorted set.

NutsDB English | 简体中文 NutsDB is a simple, fast, embeddable and persistent key/value store written in pure Go. It supports fully serializable transacti

Jan 1, 2023

Golang bindings of Sciter: the Embeddable HTML/CSS/script engine for modern UI development

Golang bindings of Sciter: the Embeddable HTML/CSS/script engine for modern UI development

Go bindings for Sciter Check this page for other language bindings (Delphi / D / Go / .NET / Python / Rust). Attention The ownership of project is tra

Dec 23, 2022

a dynamically typed, garbage collected, embeddable programming language built with Go

The agora programming language Agora is a dynamically typed, garbage collected, embeddable programming language. It is built with the Go programming l

Dec 30, 2022

Sabre is highly customisable, embeddable LISP engine for Go. :computer:

Sabre DEPRECATED: This repository is deprecated in favour much better slurp project and will be archived/removed soon. Sabre is highly customizable, e

May 23, 2021

Go bindings to QuickJS: a fast, small, and embeddable ES2020 JavaScript interpreter.

quickjs Go bindings to QuickJS: a fast, small, and embeddable ES2020 JavaScript interpreter. These bindings are a WIP and do not match full parity wit

Dec 28, 2022

goydb, a couchdb compatible embeddable database written in go

goydb, a couchdb compatible embeddable database written in go

goydb, a couchdb compatible embeddable database written in go Getting started (not embedded) Using docker mkdir data docker run -e GOYDB_ADMINS=admin:

Sep 14, 2022

A MongoDB compatible embeddable database and toolkit for Go.

A MongoDB compatible embeddable database and toolkit for Go.

lungo A MongoDB compatible embeddable database and toolkit for Go. Installation Example Motivation Architecture Features License Installation To get s

Jan 3, 2023

The world’s most powerful template engine and Go embeddable interpreter.

The world’s most powerful template engine and Go embeddable interpreter.

The world’s most powerful template engine and Go embeddable interpreter

Dec 23, 2022

An embeddable lightweight Go/Golang MQTT broker(server) for IoT.

An embeddable lightweight Go/Golang MQTT broker(server) for IoT.

Snple MQTT 简体中文 Note: The API of this library is still unstable and has not been sufficiently tested, please do not use it in production environments.

Sep 12, 2022

BadgerDB is an embeddable, persistent and fast key-value (KV) database written in pure Go

BadgerDB is an embeddable, persistent and fast key-value (KV) database written in pure Go

BadgerDB BadgerDB is an embeddable, persistent and fast key-value (KV) database written in pure Go. It is the underlying database for Dgraph, a fast,

Dec 10, 2021

NutsDB a simple, fast, embeddable and persistent key/value store written in pure Go.

NutsDB a simple, fast, embeddable and persistent key/value store written in pure Go.

A simple, fast, embeddable, persistent key/value store written in pure Go. It supports fully serializable transactions and many data structures such as list, set, sorted set.

Jan 9, 2023

ArcticDB - an embeddable columnar database written in Go

ArcticDB - an embeddable columnar database written in Go

This project is still in its infancy, consider it not production-ready, probably has various consistency and correctness problems and all API will cha

Dec 29, 2022

FlashDB is an embeddable, in-memory key/value database in Go

FlashDB is an embeddable, in-memory key/value database in Go

FlashDB is an embeddable, in-memory key/value database in Go (with Redis like commands and super easy to read)

Dec 28, 2022

The full power of the Go Compiler directly in your browser, including a virtual file system implementation. Deployable as a static website.

The full power of the Go Compiler directly in your browser, including a virtual file system implementation. Deployable as a static website.

Static Go Playground Features Full Go Compiler running on the browser. Supports using custom build tags. Incremental builds (build cache). Supports mu

Jun 16, 2022

An ease to use finit state machine golang implementation.Turn any struct to a fsm with graphviz visualization supported.

go-fsm An ease to use finit state machine golang implementation.Turn any struct to a fsm with graphviz visualization supported. usage import github.co

Dec 26, 2021
Comments
  • vm: field Intsance.Tos should be turned into a getter/setter pair

    vm: field Intsance.Tos should be turned into a getter/setter pair

    External code cannot write freely to Instance.Tos because of stack underflow protection that mandates that TOS be 0 if stack depth = 0, so writing must be done via a setter (that's why access to NOS was a getter function in the first place).

  • Use a delegate config struct for Option

    Use a delegate config struct for Option

    vm.Option directly set Intsance fields, which is bad, it should use a delegate config structure.

    With the recent addition of Ticker where using Option would be safe, we need cater for most use cases before switching to a cfg struct.

    For example, a ticker function might need to remove itself, or change the tick interval.

    Also need to provide more control over the instance to Go code running it.

WIP Go implementation of CSIRAC as a virtual machine.

CSIRAC A work-in-progress Go implementation of CSIRAC, as described in The Last of the First - CSIRAC: Australia's First Computer. The intention is to

Jan 4, 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
A bytecode-based virtual machine to implement scripting/filtering support in your golang project.

eval-filter Implementation Scripting Facilities Types Built-In Functions Conditionals Loops Functions Case/Switch Use Cases Security Denial of service

Dec 30, 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
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
An Experimental Wasm Virtual Machine for Gophers

gasm A minimal implementation of v1 WASM spec compatible virtual machine purely written in go. The vm can be embedded in your go program without any d

Dec 31, 2022
A bytecode-based virtual machine to implement scripting/filtering support in your golang project.

eval-filter Implementation Scripting Facilities Types Built-In Functions Conditionals Loops Functions Case/Switch Use Cases Security Denial of service

Jan 8, 2023
Expr – a tiny stack-based virtual machine written in Go

Expr – a tiny stack-based virtual machine written in Go The executor is designed to interpret a simple expression language and it's useful in delegati

Nov 11, 2022
A Cloud Native Buildpack that contributes SDKMAN and uses it to install dependencies like the Java Virtual Machine

gcr.io/paketo-buildpacks/sdkman A Cloud Native Buildpack that contributes SDKMAN and uses it to install dependencies like the Java Virtual Machine. Be

Jan 8, 2022