Compare commits

..

2 commits

Author SHA1 Message Date
22e2a45401 monomorphization 2025-12-15 15:26:43 +05:30
32b53ea975 yum 2025-12-15 14:33:06 +05:30
6 changed files with 2886 additions and 2845 deletions

2843
output.md

File diff suppressed because it is too large Load diff

View file

@ -4,3 +4,4 @@ pub mod ast;
pub mod lexer;
pub mod parser;
pub mod typechecker;
pub mod monomorphize;

View file

@ -1,6 +1,9 @@
use logos::Logos;
use std::fs;
use suicmez::{lexer::Token, parser::Parser, typechecker::TypeChecker};
use suicmez::{
lexer::Token, parser::Parser, typechecker::TypeChecker,
monomorphize::{Monomorphizer, check_no_typevars},
};
fn main() {
// Check if a file was provided as argument
@ -84,5 +87,103 @@ fn run_file(filename: &str) -> Result<(), String> {
typed_nodes.len()
);
// Debug: show typed nodes
println!("\nTyped AST nodes before monomorphization:");
for (i, node) in typed_nodes.iter().enumerate() {
let node_type = match &node.kind {
suicmez::ast::TypedASTNodeKind::Function(f) => {
format!("Function({})", f.name)
}
suicmez::ast::TypedASTNodeKind::Struct(s) => {
format!("Struct({}) with {} params", s.name, s.parameters.len())
}
suicmez::ast::TypedASTNodeKind::Enum(e) => {
format!("Enum({}) with {} params", e.name, e.parameters.len())
}
suicmez::ast::TypedASTNodeKind::Impl(imp) => {
format!("Impl({})", imp.target)
}
suicmez::ast::TypedASTNodeKind::Trait(t) => {
format!("Trait({})", t.name)
}
suicmez::ast::TypedASTNodeKind::Extern(e) => {
format!("Extern({})", e.name)
}
suicmez::ast::TypedASTNodeKind::Load(l) => {
format!("Load({})", l.alias)
}
suicmez::ast::TypedASTNodeKind::Use(u) => {
format!("Use({})", u)
}
};
println!(" [{}] {}", i, node_type);
}
// Monomorphize the AST
let monomorphizer = Monomorphizer::new();
let mono_nodes = monomorphizer.monomorphize_program(&typed_nodes).map_err(|e| {
format!(
"Monomorphization error: {}{}",
e.message,
if let Some(span) = &e.span {
format!(" at {}:{}", span.file, span.start)
} else {
String::new()
}
)
})?;
println!(
"Monomorphization passed! {} nodes after specialization.",
mono_nodes.len()
);
// Print detailed info about each node
println!("\nMonomorphized AST nodes:");
for (i, node) in mono_nodes.iter().enumerate() {
let node_type = match &node.kind {
suicmez::ast::TypedASTNodeKind::Function(f) => {
format!("Function({})", f.name)
}
suicmez::ast::TypedASTNodeKind::Struct(s) => {
format!("Struct({}) with {} params", s.name, s.parameters.len())
}
suicmez::ast::TypedASTNodeKind::Enum(e) => {
format!("Enum({}) with {} params", e.name, e.parameters.len())
}
suicmez::ast::TypedASTNodeKind::Impl(imp) => {
format!("Impl({})", imp.target)
}
suicmez::ast::TypedASTNodeKind::Trait(t) => {
format!("Trait({})", t.name)
}
suicmez::ast::TypedASTNodeKind::Extern(e) => {
format!("Extern({})", e.name)
}
suicmez::ast::TypedASTNodeKind::Load(l) => {
format!("Load({})", l.alias)
}
suicmez::ast::TypedASTNodeKind::Use(u) => {
format!("Use({})", u)
}
};
println!(" [{}] {}", i, node_type);
}
// Check that no type variables remain
check_no_typevars(&mono_nodes).map_err(|e| {
format!(
"Type variable check failed: {}{}",
e.message,
if let Some(span) = &e.span {
format!(" at {}:{}", span.file, span.start)
} else {
String::new()
}
)
})?;
println!("Type variable check passed! No type variables remain in AST.");
Ok(())
}

1197
src/monomorphize.rs Normal file

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,28 @@
# Generic struct specialization test
struct Box<T>
value: T
end
# Generic enum specialization test
enum Option<T>
Some(T),
None,
end
# Generic function specialization test
fn unwrap<T>(opt: Option<T>) -> T
match opt
Option::None() => -1,
Option::Some(v) => v,
end
# Generic struct with generic enum test
fn test_containers() -> int do
let box_int = Box { value: 42 };
let box_string = Box { value: "Fermented" };
let some_int = Option::Some(10);
let some_bool = Option::Some(true);
let unwrapped = unwrap(some_int);
let unwraped_bool = unwrap(some_bool);
box_int.value + unwrapped
end