Strada REPL
An interactive shell for experimenting with Strada code without creating files.
Starting the REPL
# Start interactive REPL
./tools/strada-repl
# Run a script file
./tools/strada-repl script.st
# Use via the strada command
./strada --repl
./strada --script script.st
Basic Usage
Enter Strada code at the prompt and see results immediately:
strada> my int $x = 42;
strada> $x * 2
=> 84
strada> my array @nums = (1, 2, 3);
strada> push(@nums, 4);
strada> @nums
=> (1, 2, 3, 4)
REPL Commands
| Command | Description |
|---|---|
.help |
Show help message |
.vars |
List declared variables with their types and values |
.funcs |
List defined functions with signatures |
.imports |
List library paths and registered imports |
.load FILE |
Load and execute code from a file |
.clear |
Clear all state (variables and functions) |
.debug |
Toggle debug mode (shows generated code) |
.compiler |
Show current compiler backend |
.set compiler=X |
Change compiler (libtcc, tcc, gcc) |
.memprof |
Toggle memory profiling |
.memstats |
Show memory statistics |
.funcprof |
Toggle function profiling |
.profile |
Show function profile report |
.quit |
Exit the REPL |
Defining Functions
Functions can span multiple lines. The REPL detects incomplete input and prompts for continuation:
strada> func greet(str $name) void {
... say("Hello, " . $name . "!");
... }
Function defined
strada> greet("World")
Hello, World!
Multi-line Input
The REPL automatically detects incomplete input (unbalanced braces, parentheses, or brackets) and prompts for continuation:
strada> my hash %person = (
... name => "Alice",
... age => 30
... );
strada> $person{"name"}
=> Alice
Compiler Backends
The REPL supports three compiler backends, in order of preference:
- libtcc (fastest) - In-process compilation using TCC library
- tcc - External TCC compiler
- gcc - Standard GCC compiler (slowest but most compatible)
strada> .compiler
Compiler: tcc
strada> .set compiler=gcc
Compiler set to: gcc
Memory Profiling
Track memory allocations:
strada> .memprof
Memory profiling enabled
strada> my array @big = ();
strada> for (my int $i = 0; $i < 1000; $i++) { push(@big, $i); }
strada> .memstats
Function Profiling
Profile function execution times:
strada> .funcprof
Function profiling enabled (code will be compiled with -p)
strada> func fib(int $n) int {
... if ($n <= 1) { return $n; }
... return fib($n - 1) + fib($n - 2);
... }
Function defined
strada> fib(20)
=> 6765
strada> .profile
Interpreter Backend
The REPL is powered by the Strada tree-walking interpreter (Strada::Interpreter), which evaluates code directly from the AST without generating C. This means:
- No C compiler (gcc/tcc) is needed at runtime
- The full Strada language is supported (except
__C__blocks and async/await) - Variables, functions, and state persist across evaluations
- Native shared libraries loaded via
import_libstill work (via dlopen)
For details on the interpreter architecture and the embedded eval API, see the Interpreter page.
Scripting
Beyond interactive use, the REPL also serves as a scripting engine for quick tasks without the full compilation step. Scripts run directly through the interpreter.
Running Scripts
# Run a script file
./tools/strada-repl myscript.st
# Or via the strada command
./strada --script myscript.st
Shebang Scripts
Create executable scripts with a shebang for direct execution:
#!/usr/bin/env strada-repl
say("Hello from script!");
func double(int $x) int {
return $x * 2;
}
say("Double of 21 is " . double(21));
Make executable and run:
chmod +x myscript.st
./myscript.st
Scripts vs Compiled Programs
| Feature | Interpreter Script | Compiled Program |
|---|---|---|
| Startup | Faster for small scripts | Compilation step required |
| Execution | Tree-walking interpreter | Native machine code |
| Requires C compiler | No | Yes (gcc) |
| Best for | Quick tasks, prototyping | Production, performance |
| No main() needed | Yes - top-level code runs | No - requires func main() |
| __C__ blocks | Skipped | Fully supported |
Scripts are ideal for one-off tasks, automation, and rapid prototyping where you don't need the full compilation step.
Error Display
The REPL provides helpful error messages with source context:
strada> my int $ = 5;
Error: expected variable name, got ASSIGN
> 1 | my int $ = 5;
For multi-line input, the error shows context around the problematic line.
Tips
- Use
.varsto see all current variables and their values - Use
.funcsto review function signatures - Use
.clearto start fresh without restarting the REPL - Use
.debugto see the generated Strada code (helpful for understanding issues) - Variables and functions persist across evaluations until
.clearor exit
Imports and Library Paths
The REPL supports use, import_lib, and package statements:
strada> use lib "lib"
Library path added: lib
strada> import_lib "JSON.so"
Import registered: import_lib "JSON.so"
strada> package MyApp
Package set to: MyApp
strada> .imports
Library paths (high priority):
lib
Imports:
import_lib "JSON.so";
You can also specify library paths from the command line:
# High priority (searched first)
./tools/strada-repl -L /opt/strada/lib
# Low priority (searched last)
./tools/strada-repl -LL /usr/share/strada/lib
# Multiple paths
./tools/strada-repl -L ./lib -LL /opt/lib
Limitations
- Some complex language features may not work in the dynamic REPL context
- Structs and enums cannot be defined interactively
- Global variables from imported libraries are not accessible