Skip to main content
The Dryft REPL provides an interactive environment for writing and testing Dryft code snippets without creating files.

Starting the REPL

Launch the REPL by running the compiler without an input file:
dryftc
You’ll see the REPL prompt:
Dryft repl>

REPL with Custom Target

You can start the REPL with a specific compilation target:
dryftc -t gcc
The x86 backend is not stable in the REPL environment. If you start the REPL with -t elf, you’ll see a warning message. Use the default GCC target for REPL sessions.

REPL Commands

The REPL supports special commands prefixed with a dot (.):

.help or help

Displays the help screen with all available commands.
Dryft repl> .help
.help/help  => display this screen
.exit/.quit => leave the REPL, terminating this process
.view       => inspect the contents of generated IR from last execution

.view

Inspects the intermediate representation (IR) generated from the last code execution.
Dryft repl> 1 2 +
Dryft repl> .view
This displays the compiled IR code (C or assembly, depending on your target) that was generated for your last input. Use case: Debugging, learning how Dryft compiles code, understanding the backend output.

.exit or .quit

Exits the REPL and terminates the process.
Dryft repl> .exit

How the REPL Works

The REPL provides immediate feedback by compiling and executing your code behind the scenes.

Execution Flow

  1. Input: You enter a Dryft expression or statement
  2. Wrapping: Your code is automatically wrapped in a main action with std/io included:
    include std/io act: main { YOUR_CODE } ;
    
  3. Compilation: The wrapped code is compiled using the selected backend
  4. Assembly: The IR is assembled into an object file
  5. Linking: Objects are linked into an executable
  6. Execution: The executable runs and displays output

Example Session

Dryft repl> 5 3 +
8

Dryft repl> "Hello, Dryft!" print
Hello, Dryft!

Dryft repl> .view
// ... displays generated C code ...

Dryft repl> .exit

REPL Implementation Details

The REPL is implemented in src/main.rs:34-83. Here’s how it works:

Code Wrapping

Every input is wrapped in a standard template (line 63):
let src = format!("include std/io act: main {} ;", input);
This ensures your code has the necessary context to execute.

Build Steps

The REPL performs the full compilation pipeline for each input:
  1. Compile: Generates IR using the selected backend
  2. Stdlib: Compiles standard library (if needed)
  3. Assemble: Converts IR to object code
  4. Link: Creates executable
  5. Interpret: Runs the executable and displays output

Target Specification

The REPL uses the same target system as file compilation. The target determines:
  • Which backend generates the IR
  • Where intermediate files are stored
  • How the code is assembled and linked
  • How the final executable is run

Limitations

x86 Backend Instability

The x86 backend has known issues in REPL mode due to how code is injected directly into main. A warning is displayed if you use this backend:
Warning: the x86 backend is not stable in the REPL environment
Recommendation: Use the default GCC (C99) target for REPL sessions.

State Persistence

Each REPL input is compiled and executed independently. Variables and functions defined in one input are not available in subsequent inputs.
Dryft repl> var: x 10 >>x
Dryft repl> x  // Error: x is not defined
Workaround: Define everything needed in a single input, or use file-based compilation for multi-statement programs.

Output Buffering

Currently, the REPL waits for the executed command to finish before displaying output. This means interactive programs may not work as expected.

Tips for Using the REPL

Use .view frequently to understand how Dryft compiles your code. It’s an excellent learning tool.
Start with simple expressions to get familiar with Dryft’s stack-based syntax before moving to complex programs.
If you encounter errors, check that your target dependencies (like gcc or nasm) are installed and accessible.

Use Cases

  • Learning: Experiment with Dryft syntax interactively
  • Testing: Quickly test expressions and built-in functions
  • Debugging: Use .view to inspect generated code
  • Prototyping: Try out ideas before committing to a file

Build docs developers (and LLMs) love