Process Struct ASTs into MIR

This commit is contained in:
Sofia 2025-07-15 22:03:48 +03:00
parent f139a5ad6c
commit b012a46e91
7 changed files with 96 additions and 20 deletions

View File

@ -15,6 +15,7 @@ impl ast::Module {
pub fn process(&self) -> mir::Module { pub fn process(&self) -> mir::Module {
let mut imports = Vec::new(); let mut imports = Vec::new();
let mut functions = Vec::new(); let mut functions = Vec::new();
let mut typedefs = Vec::new();
use ast::TopLevelStatement::*; use ast::TopLevelStatement::*;
for stmt in &self.top_level_statements { for stmt in &self.top_level_statements {
@ -62,7 +63,23 @@ impl ast::Module {
}; };
functions.push(def); functions.push(def);
} }
TypeDefinition(type_definition) => todo!("Add process for type definition"), TypeDefinition(ast::TypeDefinition { name, kind, range }) => {
let def = mir::TypeDefinition {
name: name.clone(),
kind: match kind {
ast::TypeDefinitionKind::Struct(struct_definition_fields) => {
mir::TypeDefinitionKind::Struct(
struct_definition_fields
.iter()
.map(|s| (s.name.clone(), s.ty.clone().into()))
.collect(),
)
}
},
meta: (*range).into(),
};
typedefs.push(def);
}
} }
} }
@ -72,7 +89,7 @@ impl ast::Module {
functions, functions,
path: self.path.clone(), path: self.path.clone(),
is_main: self.is_main, is_main: self.is_main,
typedefs: todo!("process for typedefs"), typedefs,
} }
} }
} }
@ -154,10 +171,13 @@ impl ast::VariableReferenceKind {
)) ))
} }
ast::VariableReferenceKind::ArrayIndex(var_ref, idx) => { ast::VariableReferenceKind::ArrayIndex(var_ref, idx) => {
mir::IndexedVariableReferenceKind::Index(Box::new(var_ref.process()), *idx) mir::IndexedVariableReferenceKind::ArrayIndex(Box::new(var_ref.process()), *idx)
} }
ast::VariableReferenceKind::StructIndex(variable_reference, _) => { ast::VariableReferenceKind::StructIndex(var_ref, name) => {
todo!("struct indexing into mir") mir::IndexedVariableReferenceKind::StructIndex(
Box::new(var_ref.process()),
name.clone(),
)
} }
} }
} }
@ -203,10 +223,19 @@ impl ast::Expression {
mir::TypeKind::Vague(mir::VagueType::Unknown), mir::TypeKind::Vague(mir::VagueType::Unknown),
*idx, *idx,
), ),
ast::ExpressionKind::StructExpression(struct_init) => { ast::ExpressionKind::StructExpression(struct_init) => mir::ExprKind::Struct(
todo!("implement struct init process") struct_init.name.clone(),
} struct_init
ast::ExpressionKind::StructIndex(expression, _) => todo!("struct index expression"), .fields
.iter()
.map(|(n, e)| (n.clone(), e.process()))
.collect(),
),
ast::ExpressionKind::StructIndex(expression, name) => mir::ExprKind::StructIndex(
Box::new(expression.process()),
mir::TypeKind::Vague(mir::VagueType::Unknown),
name.clone(),
),
}; };
mir::Expression(kind, self.1.into()) mir::Expression(kind, self.1.into())

View File

@ -173,7 +173,7 @@ impl IndexedVariableReference {
.get(name) .get(name)
.cloned() .cloned()
.map(|v| (v, Vec::new())), .map(|v| (v, Vec::new())),
mir::IndexedVariableReferenceKind::Index(inner, idx) => { mir::IndexedVariableReferenceKind::ArrayIndex(inner, idx) => {
let (inner_val, mut indices) = inner.get_stack_value(scope)?; let (inner_val, mut indices) = inner.get_stack_value(scope)?;
match &inner_val.1 { match &inner_val.1 {
@ -184,6 +184,9 @@ impl IndexedVariableReference {
_ => panic!("Tried to codegen indexing a non-indexable value!"), _ => panic!("Tried to codegen indexing a non-indexable value!"),
} }
} }
mir::IndexedVariableReferenceKind::StructIndex(indexed_variable_reference, _) => {
todo!("codegen for indexed var refrence")
}
} }
} }
} }

View File

@ -23,6 +23,9 @@ impl Display for Module {
for import in &self.imports { for import in &self.imports {
writeln!(inner_f, "{}", import)?; writeln!(inner_f, "{}", import)?;
} }
for typedef in &self.typedefs {
writeln!(inner_f, "{}", typedef)?;
}
for fun in &self.functions { for fun in &self.functions {
writeln!(inner_f, "{}", fun)?; writeln!(inner_f, "{}", fun)?;
} }
@ -36,6 +39,31 @@ impl Display for Import {
} }
} }
impl Display for TypeDefinition {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "type {} = ", self.name)?;
Display::fmt(&self.kind, f)
}
}
impl Display for TypeDefinitionKind {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
TypeDefinitionKind::Struct(items) => {
write!(f, "struct ")?;
f.write_char('{')?;
writeln!(f)?;
let mut state = Default::default();
let mut inner_f = PadAdapter::wrap(f, &mut state);
for (field_name, field_ty) in items {
writeln!(inner_f, "{}: {:?},", field_name, field_ty)?;
}
f.write_char('}')
}
}
}
}
impl Display for FunctionDefinition { impl Display for FunctionDefinition {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!( write!(
@ -153,17 +181,17 @@ impl Display for ExprKind {
f.write_char(']') f.write_char(']')
} }
ExprKind::Struct(name, items) => { ExprKind::Struct(name, items) => {
write!(f, "{} ", name); write!(f, "{} ", name)?;
f.write_char('{')?; f.write_char('{')?;
let mut state = Default::default(); let mut state = Default::default();
let mut inner_f = PadAdapter::wrap(f, &mut state); let mut inner_f = PadAdapter::wrap(f, &mut state);
let mut iter = items.iter(); let mut iter = items.iter();
if let Some((name, expr)) = iter.next() { if let Some((name, expr)) = iter.next() {
write!(inner_f, "\n{}: {}", name, expr); write!(inner_f, "\n{}: {}", name, expr)?;
while let Some((name, expr)) = iter.next() { while let Some((name, expr)) = iter.next() {
writeln!(inner_f, ",")?; writeln!(inner_f, ",")?;
write!(inner_f, "{}: {}", name, expr); write!(inner_f, "{}: {}", name, expr)?;
} }
writeln!(inner_f, "")?; writeln!(inner_f, "")?;
} }
@ -212,10 +240,14 @@ impl Display for IndexedVariableReference {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match &self.kind { match &self.kind {
IndexedVariableReferenceKind::Named(name) => Display::fmt(name, f), IndexedVariableReferenceKind::Named(name) => Display::fmt(name, f),
IndexedVariableReferenceKind::Index(variable_reference_kind, idx) => { IndexedVariableReferenceKind::ArrayIndex(var_ref, idx) => {
Display::fmt(&variable_reference_kind, f)?; Display::fmt(&var_ref, f)?;
write_index(f, *idx) write_index(f, *idx)
} }
IndexedVariableReferenceKind::StructIndex(var_ref, name) => {
Display::fmt(&var_ref, f)?;
write_access(f, name)
}
} }
} }
} }

View File

@ -308,7 +308,8 @@ pub struct IndexedVariableReference {
#[derive(Debug)] #[derive(Debug)]
pub enum IndexedVariableReferenceKind { pub enum IndexedVariableReferenceKind {
Named(NamedVariableRef), Named(NamedVariableRef),
Index(Box<IndexedVariableReference>, u64), ArrayIndex(Box<IndexedVariableReference>, u64),
StructIndex(Box<IndexedVariableReference>, String),
} }
#[derive(Debug)] #[derive(Debug)]
@ -324,6 +325,7 @@ pub enum StmtKind {
pub struct TypeDefinition { pub struct TypeDefinition {
pub name: String, pub name: String,
pub kind: TypeDefinitionKind, pub kind: TypeDefinitionKind,
pub meta: Metadata,
} }
#[derive(Debug)] #[derive(Debug)]

View File

@ -504,7 +504,7 @@ impl IndexedVariableReference {
IndexedVariableReferenceKind::Named(NamedVariableRef(_, name, _)) => { IndexedVariableReferenceKind::Named(NamedVariableRef(_, name, _)) => {
Ok(storage.get(&name).cloned()) Ok(storage.get(&name).cloned())
} }
IndexedVariableReferenceKind::Index(inner_ref, _) => { IndexedVariableReferenceKind::ArrayIndex(inner_ref, _) => {
if let Some(var) = inner_ref.get_variable(storage)? { if let Some(var) = inner_ref.get_variable(storage)? {
match &var.ty { match &var.ty {
TypeKind::Array(inner_ty, _) => Ok(Some(ScopeVariable { TypeKind::Array(inner_ty, _) => Ok(Some(ScopeVariable {
@ -517,6 +517,9 @@ impl IndexedVariableReference {
Ok(None) Ok(None)
} }
} }
IndexedVariableReferenceKind::StructIndex(indexed_variable_reference, _) => {
todo!("struct index refrence typecheck")
}
} }
} }
} }

View File

@ -161,7 +161,7 @@ impl IndexedVariableReference {
super::IndexedVariableReferenceKind::Named(NamedVariableRef(_, name, _)) => { super::IndexedVariableReferenceKind::Named(NamedVariableRef(_, name, _)) => {
Ok(hints.find_hint(&name)) Ok(hints.find_hint(&name))
} }
super::IndexedVariableReferenceKind::Index(inner, _) => { super::IndexedVariableReferenceKind::ArrayIndex(inner, _) => {
if let Some((mutable, inner_ref)) = inner.find_hint(hints)? { if let Some((mutable, inner_ref)) = inner.find_hint(hints)? {
// Check that the resolved type is at least an array, no // Check that the resolved type is at least an array, no
// need for further resolution. // need for further resolution.
@ -177,6 +177,9 @@ impl IndexedVariableReference {
Ok(None) Ok(None)
} }
} }
super::IndexedVariableReferenceKind::StructIndex(indexed_variable_reference, _) => {
todo!("struct index refrence type inference")
}
} }
} }
} }

View File

@ -179,9 +179,12 @@ impl IndexedVariableReference {
pub fn get_name(&self) -> String { pub fn get_name(&self) -> String {
match &self.kind { match &self.kind {
IndexedVariableReferenceKind::Named(NamedVariableRef(_, name, _)) => name.clone(), IndexedVariableReferenceKind::Named(NamedVariableRef(_, name, _)) => name.clone(),
IndexedVariableReferenceKind::Index(inner, idx) => { IndexedVariableReferenceKind::ArrayIndex(inner, idx) => {
format!("{}[{}]", inner.get_name(), idx) format!("{}[{}]", inner.get_name(), idx)
} }
IndexedVariableReferenceKind::StructIndex(inner, name) => {
format!("{}.{}", inner.get_name(), name)
}
} }
} }
@ -190,7 +193,8 @@ impl IndexedVariableReference {
IndexedVariableReferenceKind::Named(NamedVariableRef(ty, _, _)) => { IndexedVariableReferenceKind::Named(NamedVariableRef(ty, _, _)) => {
*ty = new_ty.clone(); *ty = new_ty.clone();
} }
IndexedVariableReferenceKind::Index(inner, _) => inner.update_type(new_ty), IndexedVariableReferenceKind::ArrayIndex(inner, _) => inner.update_type(new_ty),
IndexedVariableReferenceKind::StructIndex(inner, _) => inner.update_type(new_ty),
} }
} }
} }