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

Related tags

Command-line budlang
Overview

Bud (budlang)

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

WARNING: This crate is not anywhere near being ready to publish.

budlang forbids unsafe code crate version Live Build Status HTML Coverage Report for main branch Documentation

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.

Comments
  • Add truthy operator

    Add truthy operator

    This might also be worth having as a dedicated instruction in the virtual machine. It can be implemented using an If instruction.

    This operator would invoke Value::is_truthy() on the expression.

    My current thought is a unary suffix operator:

    <expr> ?

    enhancement budlang 
    opened by ecton 1
  • Allow custom intrinsics

    Allow custom intrinsics

    Currently, the CallInstrinsic instruction requires all the intrinsics to be known by the virtual machine. This is kind of weird, though, because the VM doesn't actually care about dynamic types.

    The virtual machine should delegate the intrinsic instructions to the Environment, and Bud should be the owner of the current Intrinsic enum.

    budlang budvm 
    opened by ecton 0
  • Split logical/bitwise not

    Split logical/bitwise not

    As I was a very basic reference for budasm, I once again had a slight distaste for the not instruction's implementation. Not still is implemented how I originally implemented the other bitwise operations: operate differently based on the type provided.

    The reality is that bitwise and logical nots are completely different. ~1 and not 1 should yield values that have different truthiness, but most people think of 1 and true as being synonymous.

    We should add a new operator, like tilde, in Bud to handle the bitwise specific operation, and not can be relegated to boolean operations only.

    budlang budvm 
    opened by ecton 0
  • Change bitwise operators to coerce operands to integers

    Change bitwise operators to coerce operands to integers

    • Blocked by #9

    Currently if a non-integer Value is encountered, the bitwise operators degrade to boolean operators (without short circuiting). Because these are dedicated operators, we should instead try converting the operands to integers and then performing the bitwise operation. This is more likely to catch programmatic errors than the other behavior.

    budlang 
    opened by ecton 0
  • Create assembly language for IR

    Create assembly language for IR

    With the VM being standalone, it would be nice to have the IR code be parseable. It's less important for the VM instructions to be able to be parsed directly from such a language, but given that the instructions are so similar, it might be possible to use the same AST to parse both types of instructions.

    budvm 
    opened by ecton 0
  • Add closure support to the virtual machine

    Add closure support to the virtual machine

    As per Discord, the virtual machine lacks some functionality that is needed to support closures. Specifically, there is no way to jump to an instruction and have another instruction jump back to the location jumped from. All instruction offsets are hard-coded and can't come from a variable.

    In thinking about how I would want to design this, I want to design closure support with these constraints in mind:

    • Pausing execution inside of a closure needs to be resumeable.
    • Variable access needs to be protected: a closure should be able to access its own variables, but not be able to access other closure's variables. Closures should be able to access local variables from the function that is invoking the closure.

    With these ideas in mind, I am thinking it would be great to give closures their own type of stack frame -- change StackFrame to an enum, and have Function and Closure variants. ValueOrSource would need a new option: ClosureVariable. When resolving a ClosureVariable, the stack can be checked to ensure a closure is executing and that the index is within the allocated region of the closure.

    To invoke a closure, a new instruction is needed: CallClosure which takes an instruction offset and number of arguments on the stack.

    If needed, the Return behavior can be updated based on whether execution is returning from a closure or from a function.

    These are all notes from brainstorming about this idea -- the actual implementation may need to be different than this for reasons that won't be discovered until implementation begins.

    enhancement budvm 
    opened by ecton 5
  • Add for each loops

    Add for each loops

    The only hangup on implementing this is making it work with Map types. Ideally a for each loop over a map would yield a key and value, but we don't have a clean way for a function to return multiple values.

    Early on in the design, the virtual machine allowed a function to return more than one value and for the returning function to receive more than one return value. It might be worth re-exploring that.

    budlang 
    opened by ecton 0
  • Support namespaces/modules

    Support namespaces/modules

    The virtual machine needs to be able to have an environment of nested namespaces/modules, allowing for functionality to be organized better.

    The language will need support for finding named items within namespace.

    enhancement budlang budvm 
    opened by ecton 2
Owner
Khonsu Labs
Khonsu Labs
An embeddable dynamic programming language for Rust.

rune Visit the site ?? - Read the book ?? An embeddable dynamic programming language for Rust. Contributing If you want to help out, there should be a

The Rune Programming Language 1.1k Dec 27, 2022
A comprehensive collection of resources and learning materials for Rust programming, empowering developers to explore and master the modern, safe, and blazingly fast language.

?? Awesome Rust Lang ⛰️ Project Description : Welcome to the Awesome Rust Lang repository! This is a comprehensive collection of resources for Rust, a

Shubham Raj 16 May 29, 2023
The GameLisp scripting language

GameLisp GameLisp is a scripting language for Rust game development. To get started, take a look at the homepage. Please note that GameLisp currently

Fleabit 348 Nov 29, 2022
Open-source compiler for the Papyrus scripting language of Bethesda games.

Open Papyrus Compiler This project is still WORK IN PROGRESS. If you have any feature requests, head over to the Issues tab and describe your needs. Y

erri120 22 Dec 5, 2022
A plugin system for the Rhai embedded scripting language.

Rhai Dylib This crate exposes a simple API to load dylib Rust crates in a Rhai engine using Rhai modules. ?? This is a work in progress, the API is su

Rhai - Embedded scripting language and engine for Rust 6 Dec 27, 2022
Provides filesystem access for the Rhai scripting language.

About rhai-fs This crate provides filesystem access for the Rhai scripting language. Usage Cargo.toml [dependencies] rhai-fs = "0.1.2" Rhai script //

Rhai - Embedded scripting language and engine for Rust 6 Dec 5, 2022
YAL is Yet Another scripting Language(but worse)

YAL - Yet Another Language YAL is yet another scripting language(but worse). Syntax Basic syntax fun main() { print("Hello, World!"); } Fibonacci

MD Gaziur Rahman Noor 16 Nov 14, 2022
bevy_scriptum is a a plugin for Bevy that allows you to write some of your game logic in a scripting language

bevy_scriptum is a a plugin for Bevy that allows you to write some of your game logic in a scripting language. Currently, only Rhai is supported, but more languages may be added in the future.

Jarosław Konik 7 Jun 24, 2023
a Rust library implementing safe, lightweight context switches, without relying on kernel services

libfringe libfringe is a library implementing safe, lightweight context switches, without relying on kernel services. It can be used in hosted environ

edef 473 Dec 28, 2022
A fast, powerful, and safe interpreter written in rust!

Kraber A fast, powerful, and safe programming language written in rust! About It packs a punch like the Kraber .50-Cal. Kraber is designed to be minim

Int Fract 3 Mar 24, 2024
A lightweight and super fast cli todo program written in rust under 200 sloc

todo A lightweight and super fast cli todo program written in rust under 200 sloc installation AUR package: todo-bin use cargo build --release to comp

sioodmy 243 Dec 24, 2022
A command line interface meant to bridge the gap between Rust and shell scripting

clawbang A command line interface meant to bridge the gap between Rust and shell scripting. Intended for use with HEREDOCs and shebangs: $ clawbang <<

Chris Dickinson 52 Mar 25, 2022
Shell scripting that will knock your socks off

atom Shell scripting that will knock your socks off. NOTE: Click the image above for a video demonstration.

adam mcdaniel 256 Dec 14, 2022
Simple low-level web server to serve file uploads with some shell scripting-friendly features

http_file_uploader Simple low-level web server to serve file uploads with some shell scripting-friendly features. A bridge between Web's multipart/for

Vitaly Shukela 2 Oct 27, 2022
A CLI app that exposes most of the h3o API for scripting.

h3o-cli — A CLI app exposing the h3o API for scripting How to install Pre-compiled binaries You can download a pre-compiled executable for Linux, MacO

Hydronium Labs 5 Jan 10, 2023
The safe, fast and sane package manager for Linux

moss-rs A rewrite of the Serpent OS tooling in Rust, enabling a robust implementation befitting Serpent and Solus We will initially focus on moss and

Serpent OS 16 Oct 10, 2023
A fast, simple and lightweight Bloom filter library for Python, fully implemented in Rust.

rBloom A fast, simple and lightweight Bloom filter library for Python, fully implemented in Rust. It's designed to be as pythonic as possible, mimicki

Kenan Hanke 91 Feb 4, 2023
A fast and lightweight HTTP server implementation in Rust.

server_nano A tiny, fast, and friendly web server written in rust and inspired by express. It uses may to coroutines Usage First, add this to your Car

Jonny Borges 5 May 2, 2023
Synthia is a lightweight and beginner-friendly interpreted programming language developed in Rust

Synthia is a lightweight and beginner-friendly interpreted programming language developed in Rust. With a simple, intuitive syntax and a focus on ease of use, Synthia is perfect for both newcomers to programming and experienced developers looking for a flexible scripting language

Shiva 3 Oct 5, 2023