Skip to content
LizBingPublic

About

My BrainFuck Language Lab.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

20 Commits

Folders and files

Repository files navigation

bf-lab

English | 简体中文

An experimental Brainfuck toolchain written in Rust. It can parse and optimize BF source, translate it into freestanding C, run programs through the bundled host runtime, and build native executables.

The long-term goal is to explore writing system logic in BF and connecting it to hosted or bare-metal runtimes through BFNI (Brainfuck Native Interface).

Features

  • Supports all classic BF instructions: + - < > [ ] , .
  • Layered lexer, parser, IR, and C code generator
  • 8-bit cells with wrapping arithmetic modulo 256
  • Optional tape boundary checks, enabled by default
  • Deterministic multi-function C translation unit output
  • BFNI C ABI
  • Host runtime backed by standard input and output
  • bf run: build and run a BF program temporarily
  • bf build: build a native executable
  • bf trans2c: generate freestanding C

Requirements

  • A stable Rust toolchain with Rust 2024 edition support
  • A C11 compiler compatible with GCC/Clang command-line options for bf run and bf build

The CLI selects the C compiler in this order:

  1. --cc <COMMAND>
  2. The CC environment variable
  3. cc

bf trans2c only generates C and does not require a local C compiler.

Installation

Once published on crates.io, install it with:

cargo install bf-cli

To install from source, run this command from the repository root:

cargo install --path crates/bf-cli

The installed command is named bf. Cargo installs it to ~/.cargo/bin/bf by default; make sure ~/.cargo/bin is in your PATH.

Update a source installation:

cargo install --path crates/bf-cli --force

Uninstall:

cargo uninstall bf-cli

You can also run it directly from the workspace without installing:

cargo run -p bf-cli --bin bf -- run examples/hello.bf

Quick Start

Run the example:

bf run examples/hello.bf

Output:

Hello, BrainFuck!

Choose a tape length:

bf run examples/hello.bf --tape-len 65536

Build a Native Executable

bf build examples/hello.bf
./hello

The default output name is the stem of the BF source file. You can also set it explicitly:

bf build examples/hello.bf -o hello-bf
./hello-bf

The built host executable accepts an optional tape length:

./hello-bf 65536

Translate to Freestanding C

bf trans2c examples/hello.bf

By default, this creates examples/hello.c next to the source file. To choose an output path:

bf trans2c examples/hello.bf -o generated.c

Write the generated C to stdout:

bf trans2c examples/hello.bf -o -

Generated C references BFNI with:

#include <bfni.h>

The result contains freestanding BF functions rather than a standalone executable with main. Compiling the translation unit requires include/bfni.h and a runtime that implements BFNI. For example, to compile-check generated code:

cc \
  -std=c11 \
  -ffreestanding \
  -Iinclude \
  -c generated.c \
  -o generated.o

Compilation Options

All three subcommands accept a BF IR optimization level:

bf run hello.bf -O0
bf run hello.bf -O1

The default is -O1. Current levels are:

  • -O0: disable IR optimization
  • -O1: perform local optimizations such as merging consecutive cell changes and tape moves

Tape boundary checks are generated by default. To explicitly use unsafe mode:

bf run hello.bf --unsafe

In unsafe mode, the BF program must keep its data pointer within the tape. Out-of-bounds behavior is undefined.

BF Machine Semantics

  • Cells are unsigned 8-bit integers
  • + and - wrap modulo 256
  • The data pointer starts at tape offset 0
  • The runtime provides the tape, whose length must be greater than 0
  • Initial tape contents are defined by the runtime
  • The host runtime uses calloc, so its tape starts fully zeroed
  • Input EOF or an I/O failure fills the report and makes the BF function return BF_FALSE
  • In checked mode, moving beyond either tape boundary fills the report and returns BF_FALSE

See include/bfni.h for the complete ABI contract.

Architecture

BF source
    │
    ▼
bf-frontend    Lexer + Parser + AST
    │
    ▼
bf-ir          Lowering + IR optimization
    │
    ▼
bf-codegen     Freestanding C generation
    │
    ├── trans2c ──> generated C + external BFNI runtime
    │
    └── run/build ──> embedded host runtime ──> native executable

Workspace layout:

crates/
  bf-frontend/   BF lexer, parser, and AST
  bf-ir/         IR, lowering, and optimizers
  bf-codegen/    C code generator and public compilation API
  bf-cli/        The `bf` command-line tool
include/
  bfni.h         Public BFNI ABI
runtime/
  host/          Host runtime using stdio and a dynamic tape
examples/
  hello.bf       Hello example

bf run and bf build embed the current BFNI header and host runtime into the bf binary, so an installed CLI does not depend on repository paths. Rebuild or reinstall the CLI after changing the ABI or host runtime.

Development

Run the full test suite:

cargo test --workspace

Run strict Clippy checks for the CLI:

cargo clippy -p bf-cli --bin bf --no-deps -- -D warnings

View command help:

bf --help
bf run --help
bf build --help
bf trans2c --help

Project Status

This is an experimental project. The CLI, generated C ABI, and internal IR may still change. The current host runtime is intended for native validation; bare-metal boot, device drivers, interrupts, and scheduling are not implemented yet.

Publishing

Internal crates must be published in dependency order. During the first release, a downstream dry run can only succeed after its upstream dependencies have been published and propagated through the crates.io index:

bf-frontend -> bf-ir -> bf-codegen -> bf-cli

Starting with bf-frontend, run a dry run, publish the package, and then continue with the next layer:

cargo publish -p bf-frontend --dry-run
cargo publish -p bf-frontend

Before publishing, make sure the workspace tests and Clippy checks pass. A version already published on crates.io cannot be overwritten, so every subsequent release requires a version bump.

License

Apache License 2.0. See LICENSE.

About

My BrainFuck Language Lab.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages