diff --git a/reid/examples/testcodegen.rs b/reid/examples/testcodegen.rs index 8c6b2d2..a8adaaf 100644 --- a/reid/examples/testcodegen.rs +++ b/reid/examples/testcodegen.rs @@ -163,6 +163,7 @@ fn main() { name: "test module".to_owned(), imports: vec![], functions: vec![fibonacci, main], + typedefs: Vec::new(), path: None, is_main: true, }], diff --git a/reid/src/ast/process.rs b/reid/src/ast/process.rs index 39f8bd5..93e88d4 100644 --- a/reid/src/ast/process.rs +++ b/reid/src/ast/process.rs @@ -72,6 +72,7 @@ impl ast::Module { functions, path: self.path.clone(), is_main: self.is_main, + typedefs: todo!("process for typedefs"), } } } @@ -197,7 +198,7 @@ impl ast::Expression { ast::ExpressionKind::Array(expressions) => { mir::ExprKind::Array(expressions.iter().map(|e| e.process()).collect()) } - ast::ExpressionKind::ArrayIndex(expression, idx) => mir::ExprKind::Index( + ast::ExpressionKind::ArrayIndex(expression, idx) => mir::ExprKind::ArrayIndex( Box::new(expression.process()), mir::TypeKind::Vague(mir::VagueType::Unknown), *idx, diff --git a/reid/src/codegen.rs b/reid/src/codegen.rs index 1186736..465873a 100644 --- a/reid/src/codegen.rs +++ b/reid/src/codegen.rs @@ -385,7 +385,7 @@ impl mir::Expression { None } } - mir::ExprKind::Index(expression, val_t, idx) => { + mir::ExprKind::ArrayIndex(expression, val_t, idx) => { let array = expression.codegen(scope)?; let ptr = scope .block @@ -428,6 +428,10 @@ impl mir::Expression { Some(array) } + mir::ExprKind::StructIndex(expression, type_kind, _) => { + todo!("codegen for struct index") + } + mir::ExprKind::Struct(_, items) => todo!("codegen for struct expression"), } } } @@ -511,6 +515,7 @@ impl TypeKind { TypeKind::Array(elem_t, _) => Type::Ptr(Box::new(elem_t.get_type())), TypeKind::Void => Type::Void, TypeKind::Vague(_) => panic!("Tried to compile a vague type!"), + TypeKind::CustomType(_, custom_type_kind) => todo!("codegen for custom type"), } } } diff --git a/reid/src/mir/display.rs b/reid/src/mir/display.rs index 21e3645..e40e04b 100644 --- a/reid/src/mir/display.rs +++ b/reid/src/mir/display.rs @@ -130,7 +130,7 @@ impl Display for ExprKind { ExprKind::FunctionCall(fc) => Display::fmt(fc, f), ExprKind::If(if_exp) => Display::fmt(&if_exp, f), ExprKind::Block(block) => Display::fmt(block, f), - ExprKind::Index(expression, elem_ty, idx) => { + ExprKind::ArrayIndex(expression, elem_ty, idx) => { Display::fmt(&expression, f)?; write!(f, "<{}>", elem_ty)?; write_index(f, *idx) @@ -152,6 +152,28 @@ impl Display for ExprKind { } f.write_char(']') } + ExprKind::Struct(name, items) => { + 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); + while let Some((name, expr)) = iter.next() { + writeln!(inner_f, ",")?; + write!(inner_f, "{}: {}", name, expr); + } + writeln!(inner_f, "")?; + } + f.write_char('}') + } + ExprKind::StructIndex(expression, type_kind, name) => { + Display::fmt(&expression, f)?; + write!(f, "<{}>", type_kind)?; + write_access(f, name) + } } } } @@ -254,3 +276,8 @@ fn write_index(f: &mut std::fmt::Formatter<'_>, idx: u64) -> std::fmt::Result { Display::fmt(&idx, f)?; f.write_char(']') } + +fn write_access(f: &mut std::fmt::Formatter<'_>, name: &String) -> std::fmt::Result { + f.write_char('.')?; + Display::fmt(name, f) +} diff --git a/reid/src/mir/mod.rs b/reid/src/mir/mod.rs index f130ac3..a26f661 100644 --- a/reid/src/mir/mod.rs +++ b/reid/src/mir/mod.rs @@ -4,7 +4,7 @@ use std::path::PathBuf; -use crate::token_stream::TokenRange; +use crate::{ast::Type, token_stream::TokenRange}; mod display; pub mod linker; @@ -65,6 +65,8 @@ pub enum TypeKind { StringPtr, #[error("[{0}; {1}]")] Array(Box, u64), + #[error("{0} ({1})")] + CustomType(String, CustomTypeKind), #[error(transparent)] Vague(#[from] VagueType), } @@ -79,6 +81,14 @@ pub enum VagueType { TypeRef(usize), } +#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)] +pub enum CustomTypeKind { + #[error("struct({0:?})")] + Struct(Vec), + #[error("CustomType")] + Unknown, +} + impl TypeKind { pub fn known(&self) -> Result { if let TypeKind::Vague(vague) = self { @@ -107,6 +117,7 @@ impl TypeKind { TypeKind::U128 => false, TypeKind::StringPtr => false, TypeKind::Array(_, _) => false, + TypeKind::CustomType(_, _) => false, } } @@ -126,8 +137,9 @@ impl TypeKind { Bool => true, Vague(_) => false, Void => false, - TypeKind::StringPtr => false, + StringPtr => false, Array(_, _) => false, + TypeKind::CustomType(_, _) => false, } } } @@ -217,8 +229,10 @@ pub struct Import(pub Vec, pub Metadata); #[derive(Debug)] pub enum ExprKind { Variable(NamedVariableRef), - Index(Box, TypeKind, u64), + ArrayIndex(Box, TypeKind, u64), + StructIndex(Box, TypeKind, String), Array(Vec), + Struct(String, Vec<(String, Expression)>), Literal(Literal), BinOp(BinaryOperator, Box, Box), FunctionCall(FunctionCall), @@ -306,11 +320,23 @@ pub enum StmtKind { Expression(Expression), } +#[derive(Debug)] +pub struct TypeDefinition { + pub name: String, + pub kind: TypeDefinitionKind, +} + +#[derive(Debug)] +pub enum TypeDefinitionKind { + Struct(Vec<(String, Type)>), +} + #[derive(Debug)] pub struct Module { pub name: String, pub imports: Vec, pub functions: Vec, + pub typedefs: Vec, pub path: Option, pub is_main: bool, } diff --git a/reid/src/mir/typecheck.rs b/reid/src/mir/typecheck.rs index 2bf37b3..b6b0af7 100644 --- a/reid/src/mir/typecheck.rs +++ b/reid/src/mir/typecheck.rs @@ -427,7 +427,7 @@ impl Expression { Ok((_, ty)) => Ok(ty), Err(e) => Err(e), }, - ExprKind::Index(expression, elem_ty, idx) => { + ExprKind::ArrayIndex(expression, elem_ty, idx) => { // Try to unwrap hint type from array if possible let hint_t = hint_t.map(|t| match t { TypeKind::Array(type_kind, _) => &type_kind, @@ -487,6 +487,10 @@ impl Expression { } } } + ExprKind::StructIndex(expression, type_kind, _) => { + todo!("typechecking for struct index") + } + ExprKind::Struct(_, items) => todo!("typechecking for struct expression"), } } } diff --git a/reid/src/mir/typeinference.rs b/reid/src/mir/typeinference.rs index 2e2b90f..861c284 100644 --- a/reid/src/mir/typeinference.rs +++ b/reid/src/mir/typeinference.rs @@ -283,7 +283,7 @@ impl Expression { ReturnKind::Soft => Ok(block_ref.1), } } - ExprKind::Index(expression, index_ty, _) => { + ExprKind::ArrayIndex(expression, index_ty, _) => { let expr_ty = expression.infer_types(state, type_refs)?; // Check that the resolved type is at least an array, no @@ -336,6 +336,10 @@ impl Expression { } } } + ExprKind::StructIndex(expression, type_kind, _) => { + todo!("type inference for struct indexes") + } + ExprKind::Struct(_, items) => todo!("type inference for struct expression"), } } } diff --git a/reid/src/mir/types.rs b/reid/src/mir/types.rs index 0c66de5..094732d 100644 --- a/reid/src/mir/types.rs +++ b/reid/src/mir/types.rs @@ -1,3 +1,5 @@ +use crate::util::try_all; + use super::*; #[derive(Debug, Clone)] @@ -87,7 +89,7 @@ impl ReturnType for Expression { Block(block) => block.return_type(), FunctionCall(fcall) => fcall.return_type(), If(expr) => expr.return_type(), - Index(expression, _, _) => { + ArrayIndex(expression, _, _) => { let expr_type = expression.return_type()?; if let (_, TypeKind::Array(elem_ty, _)) = expr_type { Ok((ReturnKind::Soft, *elem_ty)) @@ -106,6 +108,18 @@ impl ReturnType for Expression { TypeKind::Array(Box::new(first.1), expressions.len() as u64), )) } + StructIndex(expression, type_kind, _) => todo!("todo return type for struct index"), + Struct(name, items) => { + let f_types = try_all(items.iter().map(|e| e.1.return_type()).collect()) + .map_err(|e| unsafe { e.get_unchecked(0).clone() })? + .iter() + .map(|r| r.1.clone()) + .collect(); + Ok(( + ReturnKind::Soft, + TypeKind::CustomType(name.clone(), CustomTypeKind::Struct(f_types)), + )) + } } } }