openscript 0.1.0

High-performance AI-powered scripting language runtime
Documentation
//! Runtime execution engine for OpenScript
//!
//! This module implements the interpreter that executes OpenScript AST nodes.
//! It provides a tree-walking interpreter with proper scoping and error handling.

use crate::ast::{self, Statement};
use crate::error::{Error, Result};
use crate::value::Value;
use crate::Script;
use std::cell::RefCell;
use std::collections::HashMap;
use std::rc::Rc;
use crate::value::Visitor;

/// Runtime for executing OpenScript scripts
pub struct Runtime {
    interpreter: Interpreter,
}

impl Runtime {
    /// Create a new runtime
    pub fn new() -> Self {
        Self {
            interpreter: Interpreter::new(),
        }
    }

    /// Execute a script
    pub async fn execute(&mut self, script: Script) -> Result<Value> {
        self.interpreter.interpret(script.statements())
    }
}

/// Runtime environment for variable scoping
#[derive(Debug, Clone)]
pub struct Environment {
    enclosing: Option<Rc<RefCell<Environment>>>,
    values: HashMap<String, Value>,
}

impl Environment {
    /// Create a new global environment
    pub fn new() -> Self {
        Self {
            enclosing: None,
            values: HashMap::new(),
        }
    }

    /// Create a new environment with an enclosing scope
    pub fn with_enclosing(enclosing: Rc<RefCell<Environment>>) -> Self {
        Self {
            enclosing: Some(enclosing),
            values: HashMap::new(),
        }
    }

    /// Define a variable in this environment
    pub fn define(&mut self, name: String, value: Value) {
        self.values.insert(name, value);
    }

    /// Get a variable from this environment or enclosing scopes
    pub fn get(&self, name: &str) -> Result<Value> {
        if let Some(value) = self.values.get(name) {
            Ok(value.clone())
        } else if let Some(enclosing) = &self.enclosing {
            enclosing.borrow().get(name)
        } else {
            Err(Error::undefined_variable(name))
        }
    }

    /// Set a variable in this environment or enclosing scopes
    pub fn set(&mut self, name: &str, value: Value) -> Result<()> {
        if self.values.contains_key(name) {
            self.values.insert(name.to_string(), value);
            Ok(())
        } else if let Some(enclosing) = &self.enclosing {
            enclosing.borrow_mut().set(name, value)
        } else {
            Err(Error::undefined_variable(name))
        }
    }
}

/// The OpenScript interpreter
struct Interpreter {
    environment: Rc<RefCell<Environment>>,
}

impl Interpreter {
    /// Create a new interpreter with built-in functions
    fn new() -> Self {
        let environment = Rc::new(RefCell::new(Environment::new()));
        Self::define_builtins(&environment);
        
        Self { environment }
    }

    fn interpret(&mut self, statements: &[Statement]) -> Result<Value> {
        let mut result = Value::Null;
        for statement in statements {
            result = self.visit_statement(statement)?;
        }
        Ok(result)
    }

    /// Define built-in functions
    fn define_builtins(environment: &Rc<RefCell<Environment>>) {
        let mut env = environment.borrow_mut();
        
        env.define("print".to_string(), Value::native_function(
            "print", None, |args| {
                let output = args.iter()
                    .map(|v| v.to_string())
                    .collect::<Vec<_>>()
                    .join(" ");
                println!("{}", output);
                Ok(Value::Null)
            }
        ));
    }

    fn execute_block(&mut self, statements: &[Statement], environment: Rc<RefCell<Environment>>) -> Result<Value> {
        let previous = self.environment.clone();
        self.environment = environment;
        let mut result = Ok(Value::Null);

        for statement in statements {
            match self.visit_statement(statement) {
                Ok(_) => {},
                Err(e) => {
                    result = Err(e);
                    break;
                }
            }
        }
        
        self.environment = previous;
        result
    }
}

impl Visitor<Result<Value>> for Interpreter {
    fn visit_statement(&mut self, stmt: &Statement) -> Result<Value> {
        match stmt {
            Statement::Expression(expr) => self.visit_expression(expr),
            Statement::VarDeclaration { name, value, .. } => {
                let value = self.visit_expression(value)?;
                self.environment.borrow_mut().define(name.clone(), value);
                Ok(Value::Null)
            }
            Statement::Block(statements) => {
                let new_env = Rc::new(RefCell::new(Environment::with_enclosing(self.environment.clone())));
                self.execute_block(statements, new_env)
            }
            _ => unimplemented!(),
        }
    }

    fn visit_expression(&mut self, expr: &ast::Expression) -> Result<Value> {
        match expr {
            ast::Expression::Literal(value) => Ok(value.clone()),
            ast::Expression::Variable(name) => self.environment.borrow().get(name),
            ast::Expression::Binary { left, operator, right } => {
                let left = self.visit_expression(left)?;
                let right = self.visit_expression(right)?;

                match operator {
                    ast::BinaryOperator::Add => {
                        match (left, right) {
                            (Value::Number(l), Value::Number(r)) => Ok(Value::Number(l + r)),
                            _ => Err(Error::type_error("numbers", "operands for '+'"))
                        }
                    }
                    // ... other operators
                    _ => unimplemented!(),
                }
            }
            _ => unimplemented!(),
        }
    }
}