mirror of
https://github.com/edg-l/edlang.git
synced 2024-11-22 07:58:24 +00:00
basic struct
This commit is contained in:
parent
a4ca9c2ecd
commit
a9cd4eff86
|
@ -1160,6 +1160,21 @@ fn compile_basic_type<'ctx>(
|
|||
.ptr_sized_int_type(&ctx.target_data, None)
|
||||
.ptr_type(AddressSpace::default())
|
||||
.as_basic_type_enum(),
|
||||
ir::TypeKind::Struct(id) => {
|
||||
let body = ctx.ctx.program.structs.get(id).unwrap();
|
||||
|
||||
let mut fields = Vec::new();
|
||||
|
||||
for field in &body.variants {
|
||||
let ty = compile_basic_type(ctx, &field.ty);
|
||||
fields.push(ty);
|
||||
}
|
||||
|
||||
ctx.ctx
|
||||
.context
|
||||
.struct_type(&fields, false)
|
||||
.as_basic_type_enum()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1277,5 +1292,40 @@ fn compile_debug_type<'ctx>(ctx: &ModuleCompileCtx<'ctx, '_>, ty: &ir::TypeInfo)
|
|||
.di_builder
|
||||
.create_reference_type(compile_debug_type(ctx, inner), 0x10)
|
||||
.as_type(),
|
||||
ir::TypeKind::Struct(id) => {
|
||||
let body = ctx.ctx.program.structs.get(id).unwrap();
|
||||
|
||||
let mut fields = Vec::new();
|
||||
|
||||
for field in &body.variants {
|
||||
let ty = compile_debug_type(ctx, &field.ty);
|
||||
fields.push(ty);
|
||||
}
|
||||
|
||||
let (_, line, _column) = ctx
|
||||
.ctx
|
||||
.session
|
||||
.source
|
||||
.get_offset_line(body.span.lo)
|
||||
.unwrap();
|
||||
let real_ty = compile_basic_type(ctx, ty);
|
||||
|
||||
ctx.di_builder
|
||||
.create_struct_type(
|
||||
ctx.di_namespace,
|
||||
&body.name,
|
||||
ctx.di_unit.get_file(),
|
||||
(line + 1).try_into().unwrap(),
|
||||
ctx.target_data.get_bit_size(&real_ty),
|
||||
ctx.target_data.get_abi_alignment(&real_ty),
|
||||
0,
|
||||
None,
|
||||
&fields,
|
||||
0,
|
||||
None,
|
||||
&body.name,
|
||||
)
|
||||
.as_type()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@ pub struct ProgramBody {
|
|||
pub modules: BTreeMap<DefId, ModuleBody>,
|
||||
/// This stores all the functions from all modules
|
||||
pub functions: BTreeMap<DefId, Body>,
|
||||
pub structs: BTreeMap<DefId, AdtBody>,
|
||||
/// The function signatures.
|
||||
pub function_signatures: BTreeMap<DefId, (Vec<TypeInfo>, TypeInfo)>,
|
||||
}
|
||||
|
@ -87,6 +88,23 @@ impl Body {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct AdtBody {
|
||||
pub def_id: DefId,
|
||||
pub is_pub: bool,
|
||||
pub name: String,
|
||||
pub variants: Vec<AdtVariant>,
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
/// struct field or enum variant
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct AdtVariant {
|
||||
pub def_id: DefId,
|
||||
pub name: String,
|
||||
pub ty: TypeInfo,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct DebugInfo {
|
||||
pub id: usize,
|
||||
|
@ -205,6 +223,7 @@ pub enum TypeKind {
|
|||
FnDef(DefId, Vec<TypeInfo>), // The vec are generic types, not arg types
|
||||
Ptr(Box<TypeInfo>),
|
||||
Ref(bool, Box<TypeInfo>),
|
||||
Struct(DefId),
|
||||
}
|
||||
|
||||
impl TypeKind {
|
||||
|
@ -241,6 +260,7 @@ impl TypeKind {
|
|||
TypeKind::FnDef(_, _) => unreachable!(),
|
||||
TypeKind::Ptr(_pointee) => todo!(),
|
||||
TypeKind::Ref(_, inner) => inner.kind.get_falsy_value(),
|
||||
TypeKind::Struct(_) => todo!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,8 +5,8 @@ use common::{BodyBuilder, BuildCtx};
|
|||
use edlang_ast as ast;
|
||||
use edlang_ir as ir;
|
||||
use ir::{
|
||||
BasicBlock, Body, DefId, Local, LocalKind, Operand, Place, PlaceElem, ProgramBody, RValue,
|
||||
Statement, StatementKind, SwitchTarget, Terminator, TypeInfo, TypeKind,
|
||||
AdtBody, AdtVariant, BasicBlock, Body, DefId, Local, LocalKind, Operand, Place, PlaceElem,
|
||||
ProgramBody, RValue, Statement, StatementKind, SwitchTarget, Terminator, TypeInfo, TypeKind,
|
||||
};
|
||||
use tracing::trace;
|
||||
|
||||
|
@ -40,6 +40,18 @@ pub fn lower_modules(modules: &[ast::Module]) -> ProgramBody {
|
|||
}
|
||||
|
||||
fn lower_module(mut ctx: BuildCtx, module: &ast::Module, id: DefId) -> BuildCtx {
|
||||
// lower first structs, constants, types
|
||||
for content in &module.contents {
|
||||
match content {
|
||||
ModuleStatement::Constant(_) => todo!(),
|
||||
ModuleStatement::Struct(info) => {
|
||||
ctx = lower_struct(ctx, info, id);
|
||||
}
|
||||
// ModuleStatement::Type(_) => todo!(),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
let body = ctx.body.modules.get(&id).unwrap();
|
||||
|
||||
// fill fn sigs
|
||||
|
@ -51,12 +63,12 @@ fn lower_module(mut ctx: BuildCtx, module: &ast::Module, id: DefId) -> BuildCtx
|
|||
let ret_type;
|
||||
|
||||
for arg in &fn_def.params {
|
||||
let ty = lower_type(&ctx, &arg.arg_type);
|
||||
let ty = lower_type(&ctx, &arg.arg_type, id);
|
||||
args.push(ty);
|
||||
}
|
||||
|
||||
if let Some(ty) = &fn_def.return_type {
|
||||
ret_type = lower_type(&ctx, ty);
|
||||
ret_type = lower_type(&ctx, ty, id);
|
||||
} else {
|
||||
ret_type = TypeInfo {
|
||||
span: None,
|
||||
|
@ -70,19 +82,43 @@ fn lower_module(mut ctx: BuildCtx, module: &ast::Module, id: DefId) -> BuildCtx
|
|||
|
||||
for content in &module.contents {
|
||||
match content {
|
||||
ModuleStatement::Constant(_) => todo!(),
|
||||
ModuleStatement::Function(fn_def) => {
|
||||
ctx = lower_function(ctx, fn_def, id);
|
||||
}
|
||||
ModuleStatement::Struct(_) => todo!(),
|
||||
// ModuleStatement::Type(_) => todo!(),
|
||||
ModuleStatement::Module(_mod_def) => {}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
ctx
|
||||
}
|
||||
|
||||
fn lower_struct(mut ctx: BuildCtx, info: &ast::Struct, module_id: DefId) -> BuildCtx {
|
||||
let mut body = AdtBody {
|
||||
def_id: {
|
||||
let body = ctx.body.modules.get(&module_id).unwrap();
|
||||
*body.symbols.structs.get(&info.name.name).unwrap()
|
||||
},
|
||||
is_pub: true, // todo struct pub
|
||||
name: info.name.name.clone(),
|
||||
variants: Vec::new(),
|
||||
span: info.span,
|
||||
};
|
||||
|
||||
for field in &info.fields {
|
||||
let variant = AdtVariant {
|
||||
def_id: ctx.gen.next_defid(),
|
||||
name: field.name.name.clone(),
|
||||
ty: lower_type(&ctx, &field.r#type, module_id),
|
||||
};
|
||||
body.variants.push(variant);
|
||||
}
|
||||
|
||||
ctx.body.structs.insert(body.def_id, body);
|
||||
ctx
|
||||
}
|
||||
|
||||
fn lower_function(ctx: BuildCtx, func: &ast::Function, module_id: DefId) -> BuildCtx {
|
||||
let mut builder = BodyBuilder {
|
||||
body: Body {
|
||||
|
@ -141,7 +177,7 @@ fn lower_function(ctx: BuildCtx, func: &ast::Function, module_id: DefId) -> Buil
|
|||
// Get all user defined locals
|
||||
for stmt in &func.body.body {
|
||||
if let ast::Statement::Let(info) = stmt {
|
||||
let ty = lower_type(&builder.ctx, &info.r#type);
|
||||
let ty = lower_type(&builder.ctx, &info.r#type, builder.local_module);
|
||||
builder
|
||||
.name_to_local
|
||||
.insert(info.name.name.clone(), builder.body.locals.len());
|
||||
|
@ -360,7 +396,7 @@ fn lower_if_stmt(builder: &mut BodyBuilder, info: &ast::IfStmt, ret_type: &TypeK
|
|||
}
|
||||
|
||||
fn lower_let(builder: &mut BodyBuilder, info: &ast::LetStmt) {
|
||||
let ty = lower_type(&builder.ctx, &info.r#type);
|
||||
let ty = lower_type(&builder.ctx, &info.r#type, builder.local_module);
|
||||
let (rvalue, _ty) = lower_expr(builder, &info.value, Some(&ty.kind));
|
||||
let local_idx = builder.name_to_local.get(&info.name.name).copied().unwrap();
|
||||
builder.statements.push(Statement {
|
||||
|
@ -665,10 +701,13 @@ fn lower_fn_call(builder: &mut BodyBuilder, info: &ast::FnCallExpr) -> (Operand,
|
|||
.get(&fn_id)
|
||||
.unwrap();
|
||||
|
||||
let args: Vec<_> = args.iter().map(|x| lower_type(&builder.ctx, x)).collect();
|
||||
let args: Vec<_> = args
|
||||
.iter()
|
||||
.map(|x| lower_type(&builder.ctx, x, builder.local_module))
|
||||
.collect();
|
||||
let ret = ret
|
||||
.as_ref()
|
||||
.map(|x| lower_type(&builder.ctx, x))
|
||||
.map(|x| lower_type(&builder.ctx, x, builder.local_module))
|
||||
.unwrap_or(TypeInfo {
|
||||
span: None,
|
||||
kind: TypeKind::Unit,
|
||||
|
@ -904,7 +943,7 @@ fn lower_path(builder: &mut BodyBuilder, info: &ast::PathExpr) -> (ir::Place, Ty
|
|||
}
|
||||
|
||||
#[allow(clippy::only_used_in_recursion)]
|
||||
pub fn lower_type(ctx: &BuildCtx, t: &ast::Type) -> ir::TypeInfo {
|
||||
pub fn lower_type(ctx: &BuildCtx, t: &ast::Type, module_id: DefId) -> ir::TypeInfo {
|
||||
let inner_ty = match t.name.name.as_str() {
|
||||
"()" => ir::TypeInfo {
|
||||
span: Some(t.span),
|
||||
|
@ -960,9 +999,24 @@ pub fn lower_type(ctx: &BuildCtx, t: &ast::Type) -> ir::TypeInfo {
|
|||
},
|
||||
"ptr" => ir::TypeInfo {
|
||||
span: Some(t.span),
|
||||
kind: ir::TypeKind::Ptr(Box::new(lower_type(ctx, t.generics.first().unwrap()))),
|
||||
kind: ir::TypeKind::Ptr(Box::new(lower_type(
|
||||
ctx,
|
||||
t.generics.first().unwrap(),
|
||||
module_id,
|
||||
))),
|
||||
},
|
||||
x => todo!("{:?}", x),
|
||||
other => {
|
||||
let module = ctx.body.modules.get(&module_id).expect("module not found");
|
||||
if let Some(struct_id) = module.symbols.structs.get(other) {
|
||||
let struct_body = ctx.body.structs.get(struct_id).unwrap();
|
||||
ir::TypeInfo {
|
||||
span: Some(struct_body.span),
|
||||
kind: TypeKind::Struct(*struct_id),
|
||||
}
|
||||
} else {
|
||||
todo!("{:?}", other)
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
match t.is_ref {
|
||||
|
|
Loading…
Reference in a new issue