mirror of
https://github.com/edg-l/edlang.git
synced 2024-11-22 16:08: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_sized_int_type(&ctx.target_data, None)
|
||||||
.ptr_type(AddressSpace::default())
|
.ptr_type(AddressSpace::default())
|
||||||
.as_basic_type_enum(),
|
.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
|
.di_builder
|
||||||
.create_reference_type(compile_debug_type(ctx, inner), 0x10)
|
.create_reference_type(compile_debug_type(ctx, inner), 0x10)
|
||||||
.as_type(),
|
.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>,
|
pub modules: BTreeMap<DefId, ModuleBody>,
|
||||||
/// This stores all the functions from all modules
|
/// This stores all the functions from all modules
|
||||||
pub functions: BTreeMap<DefId, Body>,
|
pub functions: BTreeMap<DefId, Body>,
|
||||||
|
pub structs: BTreeMap<DefId, AdtBody>,
|
||||||
/// The function signatures.
|
/// The function signatures.
|
||||||
pub function_signatures: BTreeMap<DefId, (Vec<TypeInfo>, TypeInfo)>,
|
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)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct DebugInfo {
|
pub struct DebugInfo {
|
||||||
pub id: usize,
|
pub id: usize,
|
||||||
|
@ -205,6 +223,7 @@ pub enum TypeKind {
|
||||||
FnDef(DefId, Vec<TypeInfo>), // The vec are generic types, not arg types
|
FnDef(DefId, Vec<TypeInfo>), // The vec are generic types, not arg types
|
||||||
Ptr(Box<TypeInfo>),
|
Ptr(Box<TypeInfo>),
|
||||||
Ref(bool, Box<TypeInfo>),
|
Ref(bool, Box<TypeInfo>),
|
||||||
|
Struct(DefId),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TypeKind {
|
impl TypeKind {
|
||||||
|
@ -241,6 +260,7 @@ impl TypeKind {
|
||||||
TypeKind::FnDef(_, _) => unreachable!(),
|
TypeKind::FnDef(_, _) => unreachable!(),
|
||||||
TypeKind::Ptr(_pointee) => todo!(),
|
TypeKind::Ptr(_pointee) => todo!(),
|
||||||
TypeKind::Ref(_, inner) => inner.kind.get_falsy_value(),
|
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_ast as ast;
|
||||||
use edlang_ir as ir;
|
use edlang_ir as ir;
|
||||||
use ir::{
|
use ir::{
|
||||||
BasicBlock, Body, DefId, Local, LocalKind, Operand, Place, PlaceElem, ProgramBody, RValue,
|
AdtBody, AdtVariant, BasicBlock, Body, DefId, Local, LocalKind, Operand, Place, PlaceElem,
|
||||||
Statement, StatementKind, SwitchTarget, Terminator, TypeInfo, TypeKind,
|
ProgramBody, RValue, Statement, StatementKind, SwitchTarget, Terminator, TypeInfo, TypeKind,
|
||||||
};
|
};
|
||||||
use tracing::trace;
|
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 {
|
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();
|
let body = ctx.body.modules.get(&id).unwrap();
|
||||||
|
|
||||||
// fill fn sigs
|
// fill fn sigs
|
||||||
|
@ -51,12 +63,12 @@ fn lower_module(mut ctx: BuildCtx, module: &ast::Module, id: DefId) -> BuildCtx
|
||||||
let ret_type;
|
let ret_type;
|
||||||
|
|
||||||
for arg in &fn_def.params {
|
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);
|
args.push(ty);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(ty) = &fn_def.return_type {
|
if let Some(ty) = &fn_def.return_type {
|
||||||
ret_type = lower_type(&ctx, ty);
|
ret_type = lower_type(&ctx, ty, id);
|
||||||
} else {
|
} else {
|
||||||
ret_type = TypeInfo {
|
ret_type = TypeInfo {
|
||||||
span: None,
|
span: None,
|
||||||
|
@ -70,19 +82,43 @@ fn lower_module(mut ctx: BuildCtx, module: &ast::Module, id: DefId) -> BuildCtx
|
||||||
|
|
||||||
for content in &module.contents {
|
for content in &module.contents {
|
||||||
match content {
|
match content {
|
||||||
ModuleStatement::Constant(_) => todo!(),
|
|
||||||
ModuleStatement::Function(fn_def) => {
|
ModuleStatement::Function(fn_def) => {
|
||||||
ctx = lower_function(ctx, fn_def, id);
|
ctx = lower_function(ctx, fn_def, id);
|
||||||
}
|
}
|
||||||
ModuleStatement::Struct(_) => todo!(),
|
|
||||||
// ModuleStatement::Type(_) => todo!(),
|
// ModuleStatement::Type(_) => todo!(),
|
||||||
ModuleStatement::Module(_mod_def) => {}
|
ModuleStatement::Module(_mod_def) => {}
|
||||||
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx
|
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 {
|
fn lower_function(ctx: BuildCtx, func: &ast::Function, module_id: DefId) -> BuildCtx {
|
||||||
let mut builder = BodyBuilder {
|
let mut builder = BodyBuilder {
|
||||||
body: Body {
|
body: Body {
|
||||||
|
@ -141,7 +177,7 @@ fn lower_function(ctx: BuildCtx, func: &ast::Function, module_id: DefId) -> Buil
|
||||||
// Get all user defined locals
|
// Get all user defined locals
|
||||||
for stmt in &func.body.body {
|
for stmt in &func.body.body {
|
||||||
if let ast::Statement::Let(info) = stmt {
|
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
|
builder
|
||||||
.name_to_local
|
.name_to_local
|
||||||
.insert(info.name.name.clone(), builder.body.locals.len());
|
.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) {
|
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 (rvalue, _ty) = lower_expr(builder, &info.value, Some(&ty.kind));
|
||||||
let local_idx = builder.name_to_local.get(&info.name.name).copied().unwrap();
|
let local_idx = builder.name_to_local.get(&info.name.name).copied().unwrap();
|
||||||
builder.statements.push(Statement {
|
builder.statements.push(Statement {
|
||||||
|
@ -665,10 +701,13 @@ fn lower_fn_call(builder: &mut BodyBuilder, info: &ast::FnCallExpr) -> (Operand,
|
||||||
.get(&fn_id)
|
.get(&fn_id)
|
||||||
.unwrap();
|
.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
|
let ret = ret
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map(|x| lower_type(&builder.ctx, x))
|
.map(|x| lower_type(&builder.ctx, x, builder.local_module))
|
||||||
.unwrap_or(TypeInfo {
|
.unwrap_or(TypeInfo {
|
||||||
span: None,
|
span: None,
|
||||||
kind: TypeKind::Unit,
|
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)]
|
#[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() {
|
let inner_ty = match t.name.name.as_str() {
|
||||||
"()" => ir::TypeInfo {
|
"()" => ir::TypeInfo {
|
||||||
span: Some(t.span),
|
span: Some(t.span),
|
||||||
|
@ -960,9 +999,24 @@ pub fn lower_type(ctx: &BuildCtx, t: &ast::Type) -> ir::TypeInfo {
|
||||||
},
|
},
|
||||||
"ptr" => ir::TypeInfo {
|
"ptr" => ir::TypeInfo {
|
||||||
span: Some(t.span),
|
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 {
|
match t.is_ref {
|
||||||
|
|
Loading…
Reference in a new issue