Phaser Language Examples
This document provides comprehensive examples of Phaser language syntax and features, demonstrating the practical application of the Grammar Specification and Design Principles.
Basic Syntax
Hello World
fn main() -> i32 {
println!("Hello, Phaser!");
return 0;
}Variables and Types
fn variables_example() {
// Immutable by default
let x = 42;
let name = "Phaser";
// Explicit mutability
let mut counter = 0;
counter += 1;
// Type annotations
let age: u32 = 25;
let pi: f64 = 3.14159;
let is_active: bool = true;
// Type inference
let numbers = [1, 2, 3, 4, 5]; // [i32; 5]
let message = "Hello".to_string(); // String
}Functions
// Basic function
fn add(a: i32, b: i32) -> i32 {
a + b // Expression-based return
}
// Function with explicit return
fn multiply(x: i32, y: i32) -> i32 {
return x * y;
}
// Generic function
fn max<T>(a: T, b: T) -> T
where
T: PartialOrd + Copy
{
if a > b { a } else { b }
}
// Function with multiple return values (tuple)
fn divide_with_remainder(dividend: i32, divisor: i32) -> (i32, i32) {
(dividend / divisor, dividend % divisor)
}Data Structures
Structs
// Named struct
struct Point {
x: f64,
y: f64,
}
// Tuple struct
struct Color(u8, u8, u8);
// Unit struct
struct Marker;
// Generic struct
struct Container<T> {
value: T,
count: usize,
}
// Struct with methods
impl Point {
fn new(x: f64, y: f64) -> Self {
Point { x, y }
}
fn distance_from_origin(&self) -> f64 {
(self.x * self.x + self.y * self.y).sqrt()
}
fn translate(&mut self, dx: f64, dy: f64) {
self.x += dx;
self.y += dy;
}
}Enums
// Simple enum
enum Direction {
North,
South,
East,
West,
}
// Enum with data
enum Message {
Quit,
Move { x: i32, y: i32 },
Write(String),
ChangeColor(u8, u8, u8),
}
// Generic enum
enum Option<T> {
Some(T),
None,
}
enum Result<T, E> {
Ok(T),
Err(E),
}Control Flow
Conditionals
fn conditional_examples(x: i32) -> String {
// Basic if-else
if x > 0 {
"positive"
} else if x < 0 {
"negative"
} else {
"zero"
}.to_string()
// If as expression
let abs_x = if x >= 0 { x } else { -x };
format!("Value: {}, Absolute: {}", x, abs_x)
}Pattern Matching
fn pattern_matching_examples() {
let message = Message::Move { x: 10, y: 20 };
match message {
Message::Quit => println!("Quit message"),
Message::Move { x, y } => println!("Move to ({}, {})", x, y),
Message::Write(text) => println!("Text: {}", text),
Message::ChangeColor(r, g, b) => println!("Color: ({}, {}, {})", r, g, b),
}
// Match with guards
let number = 42;
match number {
n if n < 0 => println!("Negative: {}", n),
0 => println!("Zero"),
1..=10 => println!("Small positive"),
_ => println!("Large positive"),
}
// Destructuring
let point = Point { x: 1.0, y: 2.0 };
let Point { x, y } = point;
let tuple = (1, 2, 3);
let (first, _, third) = tuple;
}Loops
fn loop_examples() {
// Infinite loop with break
let mut counter = 0;
loop {
counter += 1;
if counter > 10 {
break;
}
}
// While loop
let mut n = 0;
while n < 5 {
println!("n = {}", n);
n += 1;
}
// For loop with range
for i in 0..5 {
println!("i = {}", i);
}
// For loop with collection
let numbers = [1, 2, 3, 4, 5];
for num in numbers {
println!("num = {}", num);
}
// Labeled loops
'outer: loop {
'inner: loop {
break 'outer; // Break out of outer loop
}
}
}Memory Management
References and Borrowing
fn borrowing_examples() {
let mut data = vec![1, 2, 3, 4, 5];
// Immutable borrow
let len = calculate_length(&data);
// Mutable borrow
append_item(&mut data, 6);
// Multiple immutable borrows allowed
let first_ref = &data[0];
let second_ref = &data[1];
println!("First: {}, Second: {}", first_ref, second_ref);
}
fn calculate_length(list: &Vec<i32>) -> usize {
list.len()
}
fn append_item(list: &mut Vec<i32>, item: i32) {
list.push(item);
}Ownership
fn ownership_examples() {
let s1 = String::from("hello");
let s2 = s1; // s1 is moved to s2
// println!("{}", s1); // Error: s1 no longer valid
let s3 = s2.clone(); // Explicit copy
println!("s2: {}, s3: {}", s2, s3); // Both valid
// Function takes ownership
takes_ownership(s2);
// println!("{}", s2); // Error: s2 moved into function
// Function returns ownership
let s4 = gives_ownership();
println!("s4: {}", s4);
}
fn takes_ownership(s: String) {
println!("Taking ownership of: {}", s);
} // s goes out of scope and is dropped
fn gives_ownership() -> String {
String::from("returned string")
}Error Handling
Result Type
use std::fs::File;
use std::io::Error;
fn file_operations() -> Result<String, Error> {
let mut file = File::open("example.txt")?;
let mut contents = String::new();
file.read_to_string(&mut contents)?;
Ok(contents)
}
fn error_handling_examples() {
match file_operations() {
Ok(contents) => println!("File contents: {}", contents),
Err(error) => println!("Error reading file: {}", error),
}
// Using unwrap_or_else for default values
let contents = file_operations()
.unwrap_or_else(|_| "Default content".to_string());
}Custom Error Types
#[derive(Debug)]
enum MathError {
DivisionByZero,
NegativeSquareRoot,
}
fn safe_divide(a: f64, b: f64) -> Result<f64, MathError> {
if b == 0.0 {
Err(MathError::DivisionByZero)
} else {
Ok(a / b)
}
}
fn safe_sqrt(x: f64) -> Result<f64, MathError> {
if x < 0.0 {
Err(MathError::NegativeSquareRoot)
} else {
Ok(x.sqrt())
}
}Traits and Generics
Trait Definitions
trait Drawable {
fn draw(&self);
// Default implementation
fn description(&self) -> String {
"A drawable object".to_string()
}
}
trait Cloneable {
fn clone(&self) -> Self;
}
// Trait with associated types
trait Iterator {
type Item;
fn next(&mut self) -> Option<Self::Item>;
}Trait Implementations
impl Drawable for Point {
fn draw(&self) {
println!("Drawing point at ({}, {})", self.x, self.y);
}
}
impl Drawable for Circle {
fn draw(&self) {
println!("Drawing circle at ({}, {}) with radius {}",
self.center.x, self.center.y, self.radius);
}
fn description(&self) -> String {
format!("Circle with radius {}", self.radius)
}
}
// Generic implementation
impl<T: Clone> Cloneable for Vec<T> {
fn clone(&self) -> Self {
self.iter().cloned().collect()
}
}Generic Functions and Structs
// Generic function with trait bounds
fn print_drawable<T: Drawable>(item: &T) {
println!("Description: {}", item.description());
item.draw();
}
// Multiple trait bounds
fn process_item<T>(item: T) -> T
where
T: Clone + Drawable + Debug
{
println!("Processing: {:?}", item);
item.draw();
item.clone()
}
// Generic struct with constraints
struct Pair<T, U>
where
T: PartialEq,
U: Display
{
first: T,
second: U,
}Metaprogramming
Compile-time Evaluation
// Compile-time constants
const MAX_SIZE: usize = 1024;
const GREETING: &str = "Hello, Phaser!";
// Compile-time function evaluation
const fn factorial(n: u32) -> u32 {
if n <= 1 {
1
} else {
n * factorial(n - 1)
}
}
const FACT_5: u32 = factorial(5); // Computed at compile time
// Comptime expressions
fn comptime_examples() {
let size = comptime {
if cfg!(debug_assertions) {
1024
} else {
4096
}
};
let array: [i32; comptime factorial(4)] = [0; 24];
}Meta Blocks
meta {
// Code generation at compile time
for i in 0..5 {
@generate_function(format!("func_{}", i));
}
}
// Generated functions would be:
// fn func_0() { ... }
// fn func_1() { ... }
// fn func_2() { ... }
// fn func_3() { ... }
// fn func_4() { ... }Conditional Compilation
fn platform_specific() {
#[cfg(target_os = "windows")]
{
println!("Running on Windows");
}
#[cfg(target_os = "linux")]
{
println!("Running on Linux");
}
#[cfg(feature = "advanced")]
{
advanced_functionality();
}
}
#[cfg(debug_assertions)]
fn debug_only_function() {
println!("This only exists in debug builds");
}Async Programming
Async Functions
async fn fetch_data(url: &str) -> Result<String, HttpError> {
let response = http_client::get(url).await?;
let body = response.text().await?;
Ok(body)
}
async fn process_multiple_requests() {
let urls = vec![
"https://api.example.com/data1",
"https://api.example.com/data2",
"https://api.example.com/data3",
];
let futures: Vec<_> = urls.into_iter()
.map(|url| fetch_data(url))
.collect();
let results = futures::join_all(futures).await;
for result in results {
match result {
Ok(data) => println!("Received: {}", data),
Err(error) => println!("Error: {}", error),
}
}
}Async Blocks
fn async_block_example() {
let future = async {
let data = fetch_data("https://api.example.com").await?;
process_data(data).await
};
// Execute the future
let result = runtime::block_on(future);
}Module System
Module Definition
// In src/math/mod.ph
pub mod geometry;
pub mod algebra;
pub use geometry::Point;
pub use algebra::Matrix;
pub fn common_function() {
println!("Common math function");
}Module Usage
// In src/main.ph
mod math;
use math::{Point, Matrix};
use math::geometry::Circle;
fn main() {
let point = Point::new(1.0, 2.0);
let matrix = Matrix::identity(3);
let circle = Circle::new(point, 5.0);
math::common_function();
}Advanced Features
Unsafe Code
unsafe fn raw_pointer_example() {
let mut x = 42;
let raw_ptr = &mut x as *mut i32;
// Dereferencing raw pointers requires unsafe
*raw_ptr = 100;
println!("x = {}", x); // x = 100
}
fn safe_wrapper() {
// Unsafe code should be wrapped in safe abstractions
unsafe {
raw_pointer_example();
}
}Foreign Function Interface (FFI)
extern "C" {
fn abs(input: i32) -> i32;
fn sqrt(input: f64) -> f64;
}
fn ffi_example() {
let x = -42;
let abs_x = unsafe { abs(x) };
let y = 16.0;
let sqrt_y = unsafe { sqrt(y) };
println!("abs({}) = {}, sqrt({}) = {}", x, abs_x, y, sqrt_y);
}This comprehensive set of examples demonstrates the practical application of Phaser’s syntax and features as defined in the Grammar Specification. The examples follow the Design Principles of explicitness, readability, and safety while showcasing the language’s power and flexibility.