#programming-language #language #concatenative #stack #lambda #dynamic #virtual-machine

app bund

Interpreter and CLI for a Virtual Machine for BUND programming language

3 releases (breaking)

new 0.3.0 Nov 1, 2024
0.2.0 Oct 25, 2024
0.1.0 Oct 19, 2024

#33 in Programming languages

Download history 178/week @ 2024-10-18 109/week @ 2024-10-25

287 downloads per month

Custom license and AGPL-3.0

2MB
2K SLoC

BUND concatenative language interpreter and shell.

Now, I am thrilled to introduce a novel concatenative programming language called BUND. What sets a concatenative language apart, and how does it diverge from the programming languages you are accustomed to? You are likely well-versed in applicative programming languages like Python, C, or Java. Alternatively, you may have dabbled in functional programming languages such as Lisp, Haskell, or ML, other instances of applicative programming languages. This category is characterized by the way functions are perceived and managed. In applicative languages, a function is treated as a mathematical primitive that computes based on passed arguments and returns a value.

On the other hand, concatenative programming languages facilitate the transfer of a data context from one function to another, external to the function itself. While the stack is the most common method for this transfer, there are concatenative languages that don't rely on a stack. This data context transfer enables the concatenation of data processing, making concatenative languages a practical choice for certain applications. While less prevalent in the software development communities, you might have come across languages such as Forth, PostScript, and Factor.

Show me the code!

//
// This is faimous HelloWorld program
//
"Hello world!" println

What is my options?

./target/debug/bund
Interpreter and CLI for a Virtual Machine for BUND programming language

Usage: bund [OPTIONS] <COMMAND>

Commands:
  script   Execute BUND script
  eval     Evaluate the BUND code snippet
  shell    Run the BUND REPL shell
  version  Get the version of the BUND
  help     Print this message or the help of the given subcommand(s)

Options:
  -d, --debug...     Turn debugging information on
      --debugger     Run BUND code inside debugger
      --debug-shell  Drop to DEBUG shell if error occurs
      --nocolor      Disable colors in output
      --noeval       Disable bund.eval group of functions
      --noio         Disable I/O group of functions
  -h, --help         Print help
  -V, --version      Print version

How to run a script ?

cat ./examples/helloworld.bund| ./target/debug/bund script --stdin
Hello World!

You can specify your script that you are intending for execution using following paramters for the script subcommand

CLI option Description
--stdin Execute script passed to STDIN
--file Execute script stored in the file. IMPORTANT, full path must be provided.
--url Execute script stored on some HTTP/HTTPS server
--eval Execute code snippet from CLI

How to run interactive shell ?

You must execute bund command with shell subcommand

./target/debug/bund shell
  ____    _   _   _   _   ____       ___        _        ___
 | __ )  | | | | | \ | | |  _ \     / _ \      / |      / _ \
 |  _ \  | | | | |  \| | | | | |   | | | |     | |     | | | |
 | |_) | | |_| | | |\  | | |_| |   | |_| |  _  | |  _  | |_| |
 |____/   \___/  |_| \_| |____/     \___/  (_) |_| (_)  \___/


╭────────────────┬──────────────────────────────────────────────────────────╮
 Hostname       ┆ XXXXXXXXXXXX                                             │
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤
 OS version     ┆ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX   │
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤
 Kernel version ┆ XXXXXX                                                   │
╰────────────────┴──────────────────────────────────────────────────────────╯
[BUND >

How to drop to the BUND debugger

You have two options on how you can run the code snippet inside BUND debugger

Running entire script inside debugger

For that, you have to pass --debugger CLI parameter

Running code snippet inside BUND debugger interactively

You can interactively pass code snippet to a debug function

[BUND > "2 2 +" debug
╭────────────┬────────────────────────────────────────────────────────────╮
 Value type ┆ Integer                                                    │
├╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤
 Value      ┆ 2                                                          │
├╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤
 Debug      ┆ Value { id: "vux_tEZu2Cxkk64itdxiz", stamp:                │
│            ┆ 1729884622410.0, dt: 2, q: 100.0, data: I64(2), attr: [],  │
│            ┆ curr: -1, tags: {} }
╰────────────┴────────────────────────────────────────────────────────────╯
[DEBUG >
╭────────────┬────────────────────────────────────────────────────────────╮
 Value type ┆ Integer                                                    │
├╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤
 Value      ┆ 2                                                          │
├╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤
 Debug      ┆ Value { id: "QVqF2tbsIhMto4FiUx7e6", stamp:                │
│            ┆ 1729884622410.0, dt: 2, q: 100.0, data: I64(2), attr: [],  │
│            ┆ curr: -1, tags: {} }
╰────────────┴────────────────────────────────────────────────────────────╯
[DEBUG >
╭────────────┬────────────────────────────────────────────────────────────╮
 Value type ┆ Call                                                       │
├╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤
 Value      ┆ Value(0)=Value { id: "QhjmkgKGPc6l9T9mbM5g0", stamp:       │
            ┆ 1729884625035.0, dt: 0, q: 0.0, data: Null, attr: [],      │
            ┆ curr: -1, tags: {} }
├╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤
 Debug      ┆ Value { id: "0hmYwhHhad8VMklPckEt3", stamp:                │
│            ┆ 1729884622410.0, dt: 6, q: 100.0, data: String("+"), attr: │
│            ┆ [], curr: -1, tags: {} }
╰────────────┴────────────────────────────────────────────────────────────╯
[DEBUG >
4

How to drop to debug shell if error occurs ?

You must pass --debug-shell CLI parameter to bund command

./target/debug/bund --debug-shell shell
  ____    _   _   _   _   ____       ___        _        ___
 | __ )  | | | | | \ | | |  _ \     / _ \      / |      / _ \
 |  _ \  | | | | |  \| | | | | |   | | | |     | |     | | | |
 | |_) | | |_| | | |\  | | |_| |   | |_| |  _  | |  _  | |_| |
 |____/   \___/  |_| \_| |____/     \___/  (_) |_| (_)  \___/

[BUND > 2 2 **
Attempt to evaluate value Value { id: "9fZEoerSihRUi_g1_Ic7K", stamp: 1729371784779.0, dt: 6, q: 100.0, data: String("**"), attr: [], curr: -1, tags: {} } returned error: i(**) for stack returned: Inline ** not registered
[DEBUG >

Dependencies

~57MB
~1M SLoC