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 {
let mut imports = Vec::new();
let mut functions = Vec::new();
let mut typedefs = Vec::new();
use ast::TopLevelStatement::*;
for stmt in &self.top_level_statements {
@ -62,7 +63,23 @@ impl ast::Module {
};
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,
path: self.path.clone(),
is_main: self.is_main,
typedefs: todo!("process for typedefs"),
typedefs,
}
}
}
@ -154,10 +171,13 @@ impl ast::VariableReferenceKind {
))
}
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, _) => {
todo!("struct indexing into mir")
ast::VariableReferenceKind::StructIndex(var_ref, name) => {
mir::IndexedVariableReferenceKind::StructIndex(
Box::new(var_ref.process()),
name.clone(),
)
}
}
}
@ -203,10 +223,19 @@ impl ast::Expression {
mir::TypeKind::Vague(mir::VagueType::Unknown),
*idx,
),
ast::ExpressionKind::StructExpression(struct_init) => {
todo!("implement struct init process")
}
ast::ExpressionKind::StructIndex(expression, _) => todo!("struct index expression"),
ast::ExpressionKind::StructExpression(struct_init) => mir::ExprKind::Struct(
struct_init.name.clone(),
struct_init
.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())

View File

@ -173,7 +173,7 @@ impl IndexedVariableReference {
.get(name)
.cloned()
.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)?;
match &inner_val.1 {
@ -184,6 +184,9 @@ impl IndexedVariableReference {
_ => 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 {
writeln!(inner_f, "{}", import)?;
}
for typedef in &self.typedefs {
writeln!(inner_f, "{}", typedef)?;
}
for fun in &self.functions {
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 {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
@ -153,17 +181,17 @@ impl Display for ExprKind {
f.write_char(']')
}
ExprKind::Struct(name, items) => {
write!(f, "{} ", name);
write!(f, "{} ", name)?;
f.write_char('{')?;
let mut state = Default::default();
let mut inner_f = PadAdapter::wrap(f, &mut state);
let mut iter = items.iter();
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() {
writeln!(inner_f, ",")?;
write!(inner_f, "{}: {}", name, expr);
write!(inner_f, "{}: {}", name, expr)?;
}
writeln!(inner_f, "")?;
}
@ -212,10 +240,14 @@ impl Display for IndexedVariableReference {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match &self.kind {
IndexedVariableReferenceKind::Named(name) => Display::fmt(name, f),
IndexedVariableReferenceKind::Index(variable_reference_kind, idx) => {
Display::fmt(&variable_reference_kind, f)?;
IndexedVariableReferenceKind::ArrayIndex(var_ref, idx) => {
Display::fmt(&var_ref, f)?;
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)]
pub enum IndexedVariableReferenceKind {
Named(NamedVariableRef),
Index(Box<IndexedVariableReference>, u64),
ArrayIndex(Box<IndexedVariableReference>, u64),
StructIndex(Box<IndexedVariableReference>, String),
}
#[derive(Debug)]
@ -324,6 +325,7 @@ pub enum StmtKind {
pub struct TypeDefinition {
pub name: String,
pub kind: TypeDefinitionKind,
pub meta: Metadata,
}
#[derive(Debug)]

View File

@ -504,7 +504,7 @@ impl IndexedVariableReference {
IndexedVariableReferenceKind::Named(NamedVariableRef(_, name, _)) => {
Ok(storage.get(&name).cloned())
}
IndexedVariableReferenceKind::Index(inner_ref, _) => {
IndexedVariableReferenceKind::ArrayIndex(inner_ref, _) => {
if let Some(var) = inner_ref.get_variable(storage)? {
match &var.ty {
TypeKind::Array(inner_ty, _) => Ok(Some(ScopeVariable {
@ -517,6 +517,9 @@ impl IndexedVariableReference {
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, _)) => {
Ok(hints.find_hint(&name))
}
super::IndexedVariableReferenceKind::Index(inner, _) => {
super::IndexedVariableReferenceKind::ArrayIndex(inner, _) => {
if let Some((mutable, inner_ref)) = inner.find_hint(hints)? {
// Check that the resolved type is at least an array, no
// need for further resolution.
@ -177,6 +177,9 @@ impl IndexedVariableReference {
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 {
match &self.kind {
IndexedVariableReferenceKind::Named(NamedVariableRef(_, name, _)) => name.clone(),
IndexedVariableReferenceKind::Index(inner, idx) => {
IndexedVariableReferenceKind::ArrayIndex(inner, 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, _, _)) => {
*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),
}
}
}