Bud (budlang)
A safe, fast, lightweight embeddable scripting language written in Rust.
WARNING: This crate is not anywhere near being ready to publish.
Why Bud?
Memory-safe
This project forbids unsafe code (#![forbid(unsafe_code)]
), and the budlang
crate has no dependencies.
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-call 1 $0 |
4 | recurse-call 1 $0 |
4 | sub @0 2 stack |
5 | sub @0 2 stack |
5 | recurse-call 1 $1 |
6 | recurse-call 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.
Open-source Licenses
This project, like all projects from Khonsu Labs, are open-source. This repository is available under the MIT License or the Apache License 2.0.
To learn more about contributing, please see CONTRIBUTING.md.