diff --git a/reid/src/ast/process.rs b/reid/src/ast/process.rs index 93e88d4..a42d590 100644 --- a/reid/src/ast/process.rs +++ b/reid/src/ast/process.rs @@ -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()) diff --git a/reid/src/codegen.rs b/reid/src/codegen.rs index 465873a..72848a3 100644 --- a/reid/src/codegen.rs +++ b/reid/src/codegen.rs @@ -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") + } } } } diff --git a/reid/src/mir/display.rs b/reid/src/mir/display.rs index e40e04b..590f90f 100644 --- a/reid/src/mir/display.rs +++ b/reid/src/mir/display.rs @@ -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) + } } } } diff --git a/reid/src/mir/mod.rs b/reid/src/mir/mod.rs index a26f661..61666eb 100644 --- a/reid/src/mir/mod.rs +++ b/reid/src/mir/mod.rs @@ -308,7 +308,8 @@ pub struct IndexedVariableReference { #[derive(Debug)] pub enum IndexedVariableReferenceKind { Named(NamedVariableRef), - Index(Box, u64), + ArrayIndex(Box, u64), + StructIndex(Box, String), } #[derive(Debug)] @@ -324,6 +325,7 @@ pub enum StmtKind { pub struct TypeDefinition { pub name: String, pub kind: TypeDefinitionKind, + pub meta: Metadata, } #[derive(Debug)] diff --git a/reid/src/mir/typecheck.rs b/reid/src/mir/typecheck.rs index b6b0af7..8ce95f9 100644 --- a/reid/src/mir/typecheck.rs +++ b/reid/src/mir/typecheck.rs @@ -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") + } } } } diff --git a/reid/src/mir/typeinference.rs b/reid/src/mir/typeinference.rs index 861c284..c0404e3 100644 --- a/reid/src/mir/typeinference.rs +++ b/reid/src/mir/typeinference.rs @@ -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") + } } } } diff --git a/reid/src/mir/types.rs b/reid/src/mir/types.rs index 094732d..6ed7ee3 100644 --- a/reid/src/mir/types.rs +++ b/reid/src/mir/types.rs @@ -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), } } }