glyph-runtime 0.0.1

Runtime execution engine for the Glyph programming language
Documentation
//! Benchmark example showing VM performance characteristics

use glyph_runtime::{Capability, Instruction, VMConfig, Value, VM};
use std::time::Instant;

fn main() {
    println!("=== Glyph VM Performance Benchmark ===\n");

    // Benchmark 1: Arithmetic operations
    println!("Benchmark 1: Arithmetic operations (1000 iterations)");
    let config = VMConfig::default();
    let mut vm = VM::new(config);

    // Build program: sum numbers from 1 to 1000
    let mut program = vec![
        Instruction::Push(Value::Int(0)), // sum
        Instruction::BindLocal("sum".to_string()),
        Instruction::Push(Value::Int(0)), // counter
        Instruction::BindLocal("counter".to_string()),
    ];

    let loop_start = 4;
    program.extend(vec![
        // Increment counter
        Instruction::LoadLocal("counter".to_string()),
        Instruction::Push(Value::Int(1)),
        Instruction::Add,
        Instruction::Dup,
        Instruction::BindLocal("counter".to_string()),
        // Add to sum
        Instruction::LoadLocal("sum".to_string()),
        Instruction::LoadLocal("counter".to_string()),
        Instruction::Add,
        Instruction::BindLocal("sum".to_string()),
        // Check if counter < 1000
        Instruction::LoadLocal("counter".to_string()),
        Instruction::Push(Value::Int(1000)),
        Instruction::Lt,
        Instruction::JumpIf(loop_start),
        // Return sum
        Instruction::LoadLocal("sum".to_string()),
        Instruction::Halt,
    ]);

    vm.load_bytecode(vec![program]);

    let start = Instant::now();
    match vm.execute() {
        Ok(result) => {
            let elapsed = start.elapsed();
            println!("Result: {result} (sum of 1..1000)");
            println!("Time: {elapsed:?}");
            println!("Operations/ms: {:.2}", 1000.0 / elapsed.as_millis() as f64);
        }
        Err(e) => println!("Error: {e}"),
    }

    // Benchmark 2: List operations
    println!("\nBenchmark 2: List operations (100 appends)");
    let mut config = VMConfig::default();
    config.capabilities.grant(Capability::MemoryUnlimited);
    let mut vm = VM::new(config);

    let mut program = vec![
        Instruction::MakeList(0), // empty list
        Instruction::BindLocal("list".to_string()),
        Instruction::Push(Value::Int(0)), // counter
        Instruction::BindLocal("counter".to_string()),
    ];

    let loop_start = 4;
    program.extend(vec![
        // Increment counter
        Instruction::LoadLocal("counter".to_string()),
        Instruction::Push(Value::Int(1)),
        Instruction::Add,
        Instruction::Dup,
        Instruction::BindLocal("counter".to_string()),
        // Append to list
        Instruction::LoadLocal("list".to_string()),
        Instruction::LoadLocal("counter".to_string()),
        Instruction::ListAppend,
        Instruction::BindLocal("list".to_string()),
        // Check if counter < 100
        Instruction::LoadLocal("counter".to_string()),
        Instruction::Push(Value::Int(100)),
        Instruction::Lt,
        Instruction::JumpIf(loop_start),
        // Return list
        Instruction::LoadLocal("list".to_string()),
        Instruction::Halt,
    ]);

    vm.load_bytecode(vec![program]);

    let start = Instant::now();
    match vm.execute() {
        Ok(result) => {
            let elapsed = start.elapsed();
            match result {
                Value::List(items) => {
                    let len = items.len();
                    println!("Created list with {len} items");
                    println!("Time: {elapsed:?}");
                    println!("Operations/ms: {:.2}", 100.0 / elapsed.as_millis() as f64);
                }
                _ => println!("Unexpected result type"),
            }
        }
        Err(e) => println!("Error: {e}"),
    }

    // Benchmark 3: Function calls
    println!("\nBenchmark 3: Function calls (recursive fibonacci)");
    let config = VMConfig {
        max_execution_steps: 1_000_000,
        ..Default::default()
    };
    let mut vm = VM::new(config);

    // Fibonacci function (index 1)
    let fib_function = vec![
        // Load argument n
        Instruction::LoadLocal("n".to_string()),
        Instruction::Push(Value::Int(2)),
        Instruction::Lt,
        Instruction::JumpIfNot(6),
        // Base case: return n
        Instruction::LoadLocal("n".to_string()),
        Instruction::Return,
        // Recursive case
        // fib(n-1)
        Instruction::LoadLocal("n".to_string()),
        Instruction::Push(Value::Int(1)),
        Instruction::Sub,
        Instruction::BindLocal("n".to_string()),
        Instruction::Call(1), // Call self
        // Save result
        Instruction::BindLocal("temp".to_string()),
        // fib(n-2)
        Instruction::LoadLocal("n".to_string()),
        Instruction::Push(Value::Int(1)),
        Instruction::Sub,
        Instruction::BindLocal("n".to_string()),
        Instruction::Call(1), // Call self
        // Add results
        Instruction::LoadLocal("temp".to_string()),
        Instruction::Add,
        Instruction::Return,
    ];

    // Main function
    let main_function = vec![
        Instruction::Push(Value::Int(15)), // Calculate fib(15)
        Instruction::BindLocal("n".to_string()),
        Instruction::Call(1),
        Instruction::Halt,
    ];

    vm.load_bytecode(vec![main_function, fib_function]);

    let start = Instant::now();
    match vm.execute() {
        Ok(result) => {
            let elapsed = start.elapsed();
            println!("fib(15) = {result}");
            println!("Time: {elapsed:?}");
            println!("VM steps: ~{}", 15 * 100); // Approximate
        }
        Err(e) => println!("Error: {e}"),
    }

    println!("\n=== Benchmark Complete ===");
}