feat: Implement AST binder and VM

Adds a new `Binder` struct that traverses the AST and resolves variable
references to concrete `Address` types (Local, Upvalue, Global). This
information is crucial for the Virtual Machine's execution phase.

Introduces the `BoundKind` enum to represent the AST after binding.

The `VM` is updated to handle `BoundKind` nodes and execute the bound
AST.
It now manages a call stack, local variables, and closures for function
calls and upvalue capturing.

The `Environment` struct is enhanced to manage global variables and
provide
a unified interface for parsing, binding, and executing scripts. It also
includes basic standard library functions.
This commit is contained in:
Michael Schimmel
2026-02-17 02:00:51 +01:00
parent 874a6f39a4
commit 7042206ab6
8 changed files with 595 additions and 29 deletions
+11 -2
View File
@@ -3,6 +3,7 @@ use std::collections::HashMap;
use std::fmt;
use std::sync::Mutex;
use lazy_static::lazy_static;
use std::any::Any;
/// Simple source location
#[derive(Debug, Clone, Copy)]
@@ -48,10 +49,16 @@ impl Keyword {
}
}
/// Interface for custom objects (Closures, Series, Streams)
pub trait Object: fmt::Debug + Send + Sync {
fn type_name(&self) -> &'static str;
fn as_any(&self) -> &dyn Any;
}
/// Core data value in Myc Script (similar to TDataValue)
#[derive(Clone)]
pub enum Value {
Void, // Maps to vkVoid
Void,
Bool(bool),
Int(i64),
Float(f64),
@@ -60,6 +67,7 @@ pub enum Value {
List(Arc<Vec<Value>>),
Record(Arc<HashMap<Keyword, Value>>),
Function(Arc<dyn Fn(Vec<Value>) -> Value + Send + Sync>),
Object(Arc<dyn Object>), // For compiled Closures and other opaque types
}
impl Value {
@@ -83,7 +91,8 @@ impl fmt::Display for Value {
Value::Keyword(k) => write!(f, ":{}", k.name()),
Value::List(l) => write!(f, "<list[{}]>", l.len()),
Value::Record(r) => write!(f, "<record[{}]>", r.len()),
Value::Function(_) => write!(f, "<fn>"),
Value::Function(_) => write!(f, "<native fn>"),
Value::Object(o) => write!(f, "<{}>", o.type_name()),
}
}
}