Overview
WolfLang is a statically-typed, interpreted programming language designed for simplicity and educational purposes. It features a clean syntax, static type checking, and support for common programming constructs.
Key Features
- Statically typed with type inference
- Support for common data types (int, float, string, bool, list)
- Lexical scoping with variable shadowing
- Control flow statements (if, while, for)
- Function definitions and calls
- List data structure with built-in methods
- Error handling with detailed error messages
Getting Started
Running WolfLang Code
WolfLang code can be executed in two ways:
1. From a File
# Save your code to a file (e.g., program.wolf)
# Then run it with:
./wolflang --file program.wolf
2. Interactive Mode
# Run the WolfLang interpreter without arguments
./wolflang
# Type your code, then type 'run()' to execute
let int x = 10
print x
run()
Data Types
WolfLang supports several primitive data types and one composite type:
| Type | Keyword | Description | Example |
|---|---|---|---|
| Integer | int |
Whole numbers | 42, -15 |
| Float | float |
Floating-point numbers | 3.14, -2.5 |
| String | string |
Text data | "Hello, World!" |
| Boolean | bool |
True/False values | true, false |
| List | list |
Collection of values | [1, 2, 3] |
Variables
Variable Declaration
Variables in WolfLang must be declared with an explicit type:
# Variable declaration syntax
let <type> <name> = <value>
# Examples
let int age = 25
let float price = 19.99
let string name = "Alice"
let bool is_active = true
let list numbers = [1, 2, 3, 4]
Variable Assignment
Once declared, variables can be reassigned with new values of the same type:
let int count = 10
count = 20 # Valid - same type
# count = "hello" # Error - type mismatch!
Scope
WolfLang uses lexical scoping with variable shadowing. Variables can be accessed from inner scopes, and inner scopes can shadow variables from outer scopes.
let int x = 10 # Global scope
if x > 5
let int y = 20 # Local scope
let int x = 30 # Shadows the global x
print x # Prints 30
print y # Prints 20
end
print x # Prints 10 (global x unaffected)
# print y # Error - y is out of scope
Operators
Arithmetic Operators
| Operator | Description | Example |
|---|---|---|
+ |
Addition | 5 + 3 → 8 |
- |
Subtraction | 5 - 3 → 2 |
* |
Multiplication | 5 * 3 → 15 |
/ |
Division | 6 / 3 → 2 |
Comparison Operators
| Operator | Description | Example |
|---|---|---|
== |
Equal to | 5 == 5 → true |
!= |
Not equal to | 5 != 3 → true |
> |
Greater than | 5 > 3 → true |
< |
Less than | 5 < 3 → false |
>= |
Greater than or equal to | 5 >= 5 → true |
<= |
Less than or equal to | 5 <= 3 → false |
Control Flow
If Statements
Conditional execution with if statements:
let int x = 10
if x > 5
print "x is greater than 5"
end
if x == 10
print "x is exactly 10"
end
While Loops
Execute a block of code repeatedly while a condition is true:
let int count = 0
while count < 5
print count
count = count + 1
end
For Loops
Iterate over a range of values:
# Syntax: for int <var> = <start> range <end>
for int i = 0 range 5
print i # Prints 0, 1, 2, 3, 4
end
Functions
Function Definition
Define functions with the fn keyword:
# Function without parameters
fn greet()
print "Hello, World!"
end
# Function with parameters
fn add(x, y)
return x + y
end
Function Calls
Call functions by their name followed by parentheses:
# Call function without parameters
greet()
# Call function with parameters
let int result = add(5, 3)
print result # Prints 8
Return Values
Functions can return values using the return keyword:
fn factorial(n)
if n <= 1
return 1
end
return n * factorial(n - 1)
end
let int fact = factorial(5)
print fact # Prints 120
Lists
List Creation
Create lists using square brackets:
let list numbers = [1, 2, 3]
# Add element to end
numbers.push(4)
print numbers # [1, 2, 3, 4]
# Remove last element
let int last = numbers.pop()
print last # 4
print numbers # [1, 2, 3]
# Get length
let int length = numbers.len()
print length # 3
List Access
Access list elements using zero-based indexing:
let list fruits = ["apple", "banana", "cherry"]
# Access by index
print fruits[0] # Prints "apple"
print fruits[1] # Prints "banana"
# Modify element
fruits[1] = "blueberry"
print fruits[1] # Prints "blueberry"
List Methods
Lists have built-in methods that can be called using dot notation:
| Method | Description | Example |
|---|---|---|
push |
Add element to end of list | list.push(5) |
pop |
Remove and return last element | list.pop() |
len |
Return length of list | list.len() |
Built-in Functions
Print Function
The print function outputs values to the console:
# Print single value
print "Hello, World!"
# Print multiple values separated by commas
let int x = 10
let string name = "Alice"
print "Value:", x, "Name:", name
Input Function
The input function reads user input from the console:
# Read input without prompt
let string name = input()
# Read input with prompt
let string age_str = input("Enter your age: ")
# Convert string to integer
let int age = age_str # Type conversion happens automatically
Embeddable Engine
WolfLang can be embedded in Rust applications as a scripting engine, allowing you to execute WolfLang code from within your Rust programs and share data between Rust and WolfLang.
Basic Usage
Create a WolfEngine instance and run WolfLang code:
// Import the WolfEngine
use wolflang::WolfEngine;
// Create a new engine instance
let mut engine = WolfEngine::new();
// Run WolfLang code
engine.run(r#"
let int x = 10
let int y = 20
let int result = x + y
print "Result:", result
"#).unwrap();
Sharing Data with WolfLang
You can push Rust values into the WolfLang environment and retrieve values after execution:
// Create engine
let mut engine = WolfEngine::new();
// Push values from Rust to WolfLang
engine.push_int("initial_value", 42);
engine.push_str("user_name", "Alice");
engine.push_bool("is_active", true);
// Run code that uses these values
engine.run(r#"
let int new_value = initial_value * 2
print "Hello,", user_name
print "Active:", is_active
"#).unwrap();
// Retrieve values back from WolfLang
if let Some(result) = engine.get_int("new_value") {
println!("Computed value: {}", result);
}
Complete Integration Example
Here's a complete example of embedding WolfLang in a Rust application:
// main.rs
use wolflang::WolfEngine;
fn main() {
let mut engine = WolfEngine::new();
// Configure initial state
engine.push_int("counter", 0);
engine.push_str("app_name", "MyRustApp");
// WolfLang script that interacts with Rust data
let script = r#"
print "Welcome to", app_name
# Increment counter and perform calculations
counter = counter + 1
let int squared = counter * counter
let int cubed = counter * counter * counter
print "Counter:", counter
print "Squared:", squared
print "Cubed:", cubed
# Conditional logic based on counter value
if counter > 5
print "Counter exceeded 5!"
end
# Loop example
let int sum = 0
for int i = 0 range counter
sum = sum + i
end
print "Sum of 0 to", counter - 1, "is", sum
"#;
// Execute the script multiple times
for _ in 0..3 {
if let Err(e) = engine.run(script) {
eprintln!("Script error: {}", e);
}
// Update Rust state based on WolfLang execution
if let Some(counter_val) = engine.get_int("counter") {
println!("Rust side: counter is now {}", counter_val);
}
}
}
Examples
Hello World
print "Hello, World!"
Fibonacci Sequence
fn fibonacci(n)
if n <= 1
return n
end
return fibonacci(n - 1) + fibonacci(n - 2)
end
for int i = 0 range 10
print fibonacci(i)
end
Factorial Calculator
fn factorial(n)
if n <= 1
return 1
end
return n * factorial(n - 1)
end
let string input_str = input("Enter a number: ")
let int num = input_str # Type conversion
let int result = factorial(num)
print "The factorial of", num, "is", result
List Operations
# Create a list
let list numbers = [1, 2, 3]
# Add elements
numbers.push(4)
numbers.push(5)
# Print all elements
for int i = 0 range numbers.len()
print numbers[i]
end
# Remove last element
let int last = numbers.pop()
print "Removed:", last