Add MIR support for struct types

This commit is contained in:
Sofia 2025-07-15 21:48:58 +03:00
parent d9a1e8456d
commit f139a5ad6c
8 changed files with 91 additions and 9 deletions

View File

@ -163,6 +163,7 @@ fn main() {
name: "test module".to_owned(), name: "test module".to_owned(),
imports: vec![], imports: vec![],
functions: vec![fibonacci, main], functions: vec![fibonacci, main],
typedefs: Vec::new(),
path: None, path: None,
is_main: true, is_main: true,
}], }],

View File

@ -72,6 +72,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"),
} }
} }
} }
@ -197,7 +198,7 @@ impl ast::Expression {
ast::ExpressionKind::Array(expressions) => { ast::ExpressionKind::Array(expressions) => {
mir::ExprKind::Array(expressions.iter().map(|e| e.process()).collect()) 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()), Box::new(expression.process()),
mir::TypeKind::Vague(mir::VagueType::Unknown), mir::TypeKind::Vague(mir::VagueType::Unknown),
*idx, *idx,

View File

@ -385,7 +385,7 @@ impl mir::Expression {
None None
} }
} }
mir::ExprKind::Index(expression, val_t, idx) => { mir::ExprKind::ArrayIndex(expression, val_t, idx) => {
let array = expression.codegen(scope)?; let array = expression.codegen(scope)?;
let ptr = scope let ptr = scope
.block .block
@ -428,6 +428,10 @@ impl mir::Expression {
Some(array) 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::Array(elem_t, _) => Type::Ptr(Box::new(elem_t.get_type())),
TypeKind::Void => Type::Void, TypeKind::Void => Type::Void,
TypeKind::Vague(_) => panic!("Tried to compile a vague type!"), TypeKind::Vague(_) => panic!("Tried to compile a vague type!"),
TypeKind::CustomType(_, custom_type_kind) => todo!("codegen for custom type"),
} }
} }
} }

View File

@ -130,7 +130,7 @@ impl Display for ExprKind {
ExprKind::FunctionCall(fc) => Display::fmt(fc, f), ExprKind::FunctionCall(fc) => Display::fmt(fc, f),
ExprKind::If(if_exp) => Display::fmt(&if_exp, f), ExprKind::If(if_exp) => Display::fmt(&if_exp, f),
ExprKind::Block(block) => Display::fmt(block, f), ExprKind::Block(block) => Display::fmt(block, f),
ExprKind::Index(expression, elem_ty, idx) => { ExprKind::ArrayIndex(expression, elem_ty, idx) => {
Display::fmt(&expression, f)?; Display::fmt(&expression, f)?;
write!(f, "<{}>", elem_ty)?; write!(f, "<{}>", elem_ty)?;
write_index(f, *idx) write_index(f, *idx)
@ -152,6 +152,28 @@ impl Display for ExprKind {
} }
f.write_char(']') 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)?; Display::fmt(&idx, f)?;
f.write_char(']') f.write_char(']')
} }
fn write_access(f: &mut std::fmt::Formatter<'_>, name: &String) -> std::fmt::Result {
f.write_char('.')?;
Display::fmt(name, f)
}

View File

@ -4,7 +4,7 @@
use std::path::PathBuf; use std::path::PathBuf;
use crate::token_stream::TokenRange; use crate::{ast::Type, token_stream::TokenRange};
mod display; mod display;
pub mod linker; pub mod linker;
@ -65,6 +65,8 @@ pub enum TypeKind {
StringPtr, StringPtr,
#[error("[{0}; {1}]")] #[error("[{0}; {1}]")]
Array(Box<TypeKind>, u64), Array(Box<TypeKind>, u64),
#[error("{0} ({1})")]
CustomType(String, CustomTypeKind),
#[error(transparent)] #[error(transparent)]
Vague(#[from] VagueType), Vague(#[from] VagueType),
} }
@ -79,6 +81,14 @@ pub enum VagueType {
TypeRef(usize), TypeRef(usize),
} }
#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)]
pub enum CustomTypeKind {
#[error("struct({0:?})")]
Struct(Vec<TypeKind>),
#[error("CustomType")]
Unknown,
}
impl TypeKind { impl TypeKind {
pub fn known(&self) -> Result<TypeKind, VagueType> { pub fn known(&self) -> Result<TypeKind, VagueType> {
if let TypeKind::Vague(vague) = self { if let TypeKind::Vague(vague) = self {
@ -107,6 +117,7 @@ impl TypeKind {
TypeKind::U128 => false, TypeKind::U128 => false,
TypeKind::StringPtr => false, TypeKind::StringPtr => false,
TypeKind::Array(_, _) => false, TypeKind::Array(_, _) => false,
TypeKind::CustomType(_, _) => false,
} }
} }
@ -126,8 +137,9 @@ impl TypeKind {
Bool => true, Bool => true,
Vague(_) => false, Vague(_) => false,
Void => false, Void => false,
TypeKind::StringPtr => false, StringPtr => false,
Array(_, _) => false, Array(_, _) => false,
TypeKind::CustomType(_, _) => false,
} }
} }
} }
@ -217,8 +229,10 @@ pub struct Import(pub Vec<String>, pub Metadata);
#[derive(Debug)] #[derive(Debug)]
pub enum ExprKind { pub enum ExprKind {
Variable(NamedVariableRef), Variable(NamedVariableRef),
Index(Box<Expression>, TypeKind, u64), ArrayIndex(Box<Expression>, TypeKind, u64),
StructIndex(Box<Expression>, TypeKind, String),
Array(Vec<Expression>), Array(Vec<Expression>),
Struct(String, Vec<(String, Expression)>),
Literal(Literal), Literal(Literal),
BinOp(BinaryOperator, Box<Expression>, Box<Expression>), BinOp(BinaryOperator, Box<Expression>, Box<Expression>),
FunctionCall(FunctionCall), FunctionCall(FunctionCall),
@ -306,11 +320,23 @@ pub enum StmtKind {
Expression(Expression), Expression(Expression),
} }
#[derive(Debug)]
pub struct TypeDefinition {
pub name: String,
pub kind: TypeDefinitionKind,
}
#[derive(Debug)]
pub enum TypeDefinitionKind {
Struct(Vec<(String, Type)>),
}
#[derive(Debug)] #[derive(Debug)]
pub struct Module { pub struct Module {
pub name: String, pub name: String,
pub imports: Vec<Import>, pub imports: Vec<Import>,
pub functions: Vec<FunctionDefinition>, pub functions: Vec<FunctionDefinition>,
pub typedefs: Vec<TypeDefinition>,
pub path: Option<PathBuf>, pub path: Option<PathBuf>,
pub is_main: bool, pub is_main: bool,
} }

View File

@ -427,7 +427,7 @@ impl Expression {
Ok((_, ty)) => Ok(ty), Ok((_, ty)) => Ok(ty),
Err(e) => Err(e), 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 // Try to unwrap hint type from array if possible
let hint_t = hint_t.map(|t| match t { let hint_t = hint_t.map(|t| match t {
TypeKind::Array(type_kind, _) => &type_kind, 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"),
} }
} }
} }

View File

@ -283,7 +283,7 @@ impl Expression {
ReturnKind::Soft => Ok(block_ref.1), 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)?; let expr_ty = expression.infer_types(state, type_refs)?;
// Check that the resolved type is at least an array, no // 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"),
} }
} }
} }

View File

@ -1,3 +1,5 @@
use crate::util::try_all;
use super::*; use super::*;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
@ -87,7 +89,7 @@ impl ReturnType for Expression {
Block(block) => block.return_type(), Block(block) => block.return_type(),
FunctionCall(fcall) => fcall.return_type(), FunctionCall(fcall) => fcall.return_type(),
If(expr) => expr.return_type(), If(expr) => expr.return_type(),
Index(expression, _, _) => { ArrayIndex(expression, _, _) => {
let expr_type = expression.return_type()?; let expr_type = expression.return_type()?;
if let (_, TypeKind::Array(elem_ty, _)) = expr_type { if let (_, TypeKind::Array(elem_ty, _)) = expr_type {
Ok((ReturnKind::Soft, *elem_ty)) Ok((ReturnKind::Soft, *elem_ty))
@ -106,6 +108,18 @@ impl ReturnType for Expression {
TypeKind::Array(Box::new(first.1), expressions.len() as u64), 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)),
))
}
} }
} }
} }