Crate budlang

source ·
Expand description

A safe, fast, lightweight embeddable scripting language written in Rust.

Why Bud?

Memory-safe

This project forbids unsafe code (#![forbid(unsafe_code)]), and has only one dependency: budvm. The only unsafe code depended on by this crate is in Rust’s standard library.

Safe to run untrusted code

The virtual machine invokes Environment::step() before each instruction is exected. The environment can return ExecutionBehavior::Pause to pause execution, and the state of the virtual machine will be saved such that it can be resumed again.

Work In Progress: Bud will have various configuration options including maximum stack size, maximum memory used, and more.

Work In Progress: Bud should never panic. This crate is in early development, so many instances of todo!() and unwrap() abound. These will all be replaced with descriptive errors instead of panics.

Bud will only support these primitive types: integers, real numbers (floating point), strings, lists, and maps. Bud will be able to be extended to support additional features via Rust, placing the developer embedding Bud in full control of what scripts can do.

Efficient

Bud is a compiled language powered by its own virtual machine. Currently, Bud has no optimizer, but the virtual machine code generated by the compiler closely mirrors the syntax of the language. For example, the repository includes three examples of a naive Fibonacci number function implementation. The Bud version looks like this:

function fibonacci(n)
    if n <= 2
        1
    else
        this(n - 1) + this(n - 2)
    end
end

Another example shows an identical implementation using hand-written virtual machine instructions. Despite not having an optimizer, the compiled fibonacci() function’s code is nearly identical, having one extra (unreachable) instruction:

#hand-written#compiled
0lte @0 2 jump 20lte @0 2 jump 3
1return 11return 1
2jump 8
2sub @0 1 stack3sub @0 1 stack
3recurse 1 $04recurse 1 $0
4sub @0 2 stack5sub @0 2 stack
5recurse 1 $16recurse 1 $1
6add $0 $1 $$7add $0 $1 $$

Why not Bud?

It probably doesn’t do what you need (yet):

  • Don’t panic in vm
  • Don’t panic in compiler
  • Don’t panic in parser
  • Support parenthesized expressions as terms
  • Add variables
  • Add loops
  • Add Real (Float) type
  • Add String type
  • Add List type
  • Add Map type
  • Ability to write Rust functions
  • Implement a REPL
  • Consider static variables for persistent module state.

Bud is compiled to a virtual machine written using only memory-safe abstractions in Rust. This yields quite good performance for a dynamically typed language, but will not be the fastest language.

Goals for Bud

Aside from the goals outlined above, the use cases it’s being designed for are:

  • A BonsaiDb REPL
  • Multi-player server-side scripting where user-submitted scripts are allowed.

Re-exports

  • pub use budvm as vm;

Modules

  • The abstract syntax tree Bud uses.
  • The interface for parsing Bud code.

Structs

Enums

  • All errors that can be encountered executing Bud code.
  • A runtime intrinsic function.

Traits

  • Customizes the behavior of a virtual machine instance.