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