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 -27
View File
@@ -1,4 +1,5 @@
use eframe::egui;
use crate::ast::environment::Environment;
pub mod ast;
@@ -17,6 +18,7 @@ fn main() -> eframe::Result {
struct CompilerApp {
source_code: String,
output_log: String,
env: Environment,
}
impl Default for CompilerApp {
@@ -24,6 +26,7 @@ impl Default for CompilerApp {
Self {
source_code: String::new(),
output_log: String::from("Ready to compile..."),
env: Environment::new(),
}
}
}
@@ -40,35 +43,16 @@ impl eframe::App for CompilerApp {
// Compile Button (at the top of the bottom panel)
if ui.button("Compile").clicked() {
use crate::ast::parser::Parser;
use crate::ast::nodes::Context;
let mut parser = match Parser::new(&self.source_code) {
Ok(p) => p,
Err(e) => {
self.output_log = format!("Lexer Error: {}", e);
return;
}
};
match parser.parse_expression() {
Ok(ast) => {
let mut context = Context::new(); // Use new() which registers stdlib
match ast.eval(&mut context) {
Ok(result) => {
self.output_log = format!(
"AST Parsed & Evaluated Successfully.\nResult: {}\n\nFinished at {:?}",
result,
std::time::SystemTime::now(),
);
}
Err(e) => {
self.output_log = format!("Runtime Error: {}", e);
}
}
match self.env.run_script(&self.source_code) {
Ok(result) => {
self.output_log = format!(
"Execution Successful.\nResult: {}\n\nFinished at {:?}",
result,
std::time::SystemTime::now(),
);
}
Err(e) => {
self.output_log = format!("Parser Error: {}", e);
self.output_log = format!("Error: {}", e);
}
}
}