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 |
---|---|---|---|
0 | lte @0 2 jump 2 | 0 | lte @0 2 jump 3 |
1 | return 1 | 1 | return 1 |
2 | jump 8 | ||
2 | sub @0 1 stack | 3 | sub @0 1 stack |
3 | recurse 1 $0 | 4 | recurse 1 $0 |
4 | sub @0 2 stack | 5 | sub @0 2 stack |
5 | recurse 1 $1 | 6 | recurse 1 $1 |
6 | add $0 $1 $$ | 7 | add $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
- A Bud virtual machine instance.
- A wrapper for a
Environment
that implements [budvm::Environment
].
Enums
- All errors that can be encountered executing Bud code.
- A runtime intrinsic function.
Traits
- Customizes the behavior of a virtual machine instance.