Add MIR support for struct types
This commit is contained in:
		
							parent
							
								
									d9a1e8456d
								
							
						
					
					
						commit
						f139a5ad6c
					
				@ -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,
 | 
				
			||||||
        }],
 | 
					        }],
 | 
				
			||||||
 | 
				
			|||||||
@ -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,
 | 
				
			||||||
 | 
				
			|||||||
@ -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"),
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -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)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -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,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -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"),
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -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"),
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -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)),
 | 
				
			||||||
 | 
					                ))
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user