mirror of
https://github.com/edg-l/edlang.git
synced 2024-11-21 23:48:24 +00:00
feat: ptr repr
This commit is contained in:
parent
1d60bb5482
commit
caf3a94eee
|
@ -14,6 +14,7 @@ use inkwell::{
|
|||
targets::{InitializationConfig, Target, TargetData, TargetMachine},
|
||||
types::{AnyType, BasicMetadataTypeEnum, BasicType},
|
||||
values::{BasicValue, BasicValueEnum, PointerValue},
|
||||
AddressSpace,
|
||||
};
|
||||
use ir::{LocalKind, ModuleBody, ProgramBody, TypeInfo, ValueTree};
|
||||
use llvm_sys::debuginfo::LLVMDIFlagPublic;
|
||||
|
@ -102,6 +103,7 @@ pub fn compile(session: &Session, program: &ProgramBody) -> Result<PathBuf, Box<
|
|||
let llvm_module = context.create_module(&module.name);
|
||||
llvm_module.set_source_file_name(&filename);
|
||||
llvm_module.set_triple(&triple);
|
||||
llvm_module.set_data_layout(&machine.get_target_data().get_data_layout());
|
||||
let (di_builder, di_unit) = llvm_module.create_debug_info_builder(
|
||||
true,
|
||||
inkwell::debug_info::DWARFSourceLanguage::Rust,
|
||||
|
@ -368,7 +370,7 @@ fn compile_fn(ctx: &ModuleCompileCtx, fn_id: DefId) -> Result<(), BuilderError>
|
|||
debug_loc = ctx.set_debug_loc(debug_loc.get_scope(), span);
|
||||
}
|
||||
|
||||
trace!("compiling stmt {}: {:?}", idx, stmt.kind);
|
||||
trace!("compiling stmt {}: {:?}", idx, stmt);
|
||||
match &stmt.kind {
|
||||
ir::StatementKind::Assign(place, rvalue) => {
|
||||
let local = &body.locals[place.local];
|
||||
|
@ -428,6 +430,9 @@ fn compile_fn(ctx: &ModuleCompileCtx, fn_id: DefId) -> Result<(), BuilderError>
|
|||
}
|
||||
|
||||
trace!("compiling terminator: {:?}", block.terminator);
|
||||
if let Some(span) = block.terminator_span {
|
||||
debug_loc = ctx.set_debug_loc(debug_loc.get_scope(), span);
|
||||
}
|
||||
match &block.terminator {
|
||||
ir::Terminator::Target(id) => {
|
||||
ctx.builder.build_unconditional_branch(blocks[*id])?;
|
||||
|
@ -954,6 +959,10 @@ fn compile_value<'ctx>(
|
|||
.const_float((*x) as f64)
|
||||
.as_basic_value_enum(),
|
||||
ir::ConstValue::F64(x) => ty.into_float_type().const_float(*x).as_basic_value_enum(),
|
||||
ir::ConstValue::Char(x) => ty
|
||||
.into_int_type()
|
||||
.const_int((*x) as u64, false)
|
||||
.as_basic_value_enum(),
|
||||
},
|
||||
ValueTree::Branch(_) => todo!(),
|
||||
})
|
||||
|
@ -1022,6 +1031,12 @@ fn compile_basic_type<'ctx>(
|
|||
ir::TypeKind::FnDef(_def_id, _generic_args) => {
|
||||
panic!()
|
||||
}
|
||||
ir::TypeKind::Ptr(_pointee) => ctx
|
||||
.ctx
|
||||
.context
|
||||
.ptr_sized_int_type(&ctx.target_data, None)
|
||||
.ptr_type(AddressSpace::default())
|
||||
.as_basic_type_enum(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1031,79 +1046,80 @@ fn compile_debug_type<'ctx>(ctx: &ModuleCompileCtx<'ctx, '_>, ty: &ir::TypeInfo)
|
|||
// 4 = float
|
||||
// 5 = signed
|
||||
// 11 = numeric string
|
||||
// https://dwarfstd.org/doc/DWARF5.pdf#section.7.8
|
||||
match &ty.kind {
|
||||
ir::TypeKind::Unit => todo!(),
|
||||
ir::TypeKind::Bool => ctx
|
||||
.di_builder
|
||||
.create_basic_type("bool", 1, 2, LLVMDIFlagPublic)
|
||||
.create_basic_type("bool", 1, 0x2, LLVMDIFlagPublic)
|
||||
.unwrap()
|
||||
.as_type(),
|
||||
ir::TypeKind::Char => ctx
|
||||
.di_builder
|
||||
.create_basic_type("char", 1, 6, LLVMDIFlagPublic)
|
||||
.create_basic_type("char", 8, 0x6, LLVMDIFlagPublic)
|
||||
.unwrap()
|
||||
.as_type(),
|
||||
ir::TypeKind::Int(ty) => match ty {
|
||||
ir::IntTy::I128 => ctx
|
||||
.di_builder
|
||||
.create_basic_type("i128", 128, 5, LLVMDIFlagPublic)
|
||||
.create_basic_type("i128", 128, 0x5, LLVMDIFlagPublic)
|
||||
.unwrap()
|
||||
.as_type(),
|
||||
ir::IntTy::I64 => ctx
|
||||
.di_builder
|
||||
.create_basic_type("i64", 64, 5, LLVMDIFlagPublic)
|
||||
.create_basic_type("i64", 64, 0x5, LLVMDIFlagPublic)
|
||||
.unwrap()
|
||||
.as_type(),
|
||||
ir::IntTy::I32 => ctx
|
||||
.di_builder
|
||||
.create_basic_type("i32", 32, 5, LLVMDIFlagPublic)
|
||||
.create_basic_type("i32", 32, 0x5, LLVMDIFlagPublic)
|
||||
.unwrap()
|
||||
.as_type(),
|
||||
ir::IntTy::I16 => ctx
|
||||
.di_builder
|
||||
.create_basic_type("i16", 16, 5, LLVMDIFlagPublic)
|
||||
.create_basic_type("i16", 16, 0x5, LLVMDIFlagPublic)
|
||||
.unwrap()
|
||||
.as_type(),
|
||||
ir::IntTy::I8 => ctx
|
||||
.di_builder
|
||||
.create_basic_type("i8", 8, 5, LLVMDIFlagPublic)
|
||||
.create_basic_type("i8", 8, 0x5, LLVMDIFlagPublic)
|
||||
.unwrap()
|
||||
.as_type(),
|
||||
ir::IntTy::Isize => ctx
|
||||
.di_builder
|
||||
.create_basic_type("isize", 64, 5, LLVMDIFlagPublic)
|
||||
.create_basic_type("isize", 64, 0x5, LLVMDIFlagPublic)
|
||||
.unwrap()
|
||||
.as_type(),
|
||||
},
|
||||
ir::TypeKind::Uint(ty) => match ty {
|
||||
ir::UintTy::U128 => ctx
|
||||
.di_builder
|
||||
.create_basic_type("u128", 128, 7, LLVMDIFlagPublic)
|
||||
.create_basic_type("u128", 128, 0x7, LLVMDIFlagPublic)
|
||||
.unwrap()
|
||||
.as_type(),
|
||||
ir::UintTy::U64 => ctx
|
||||
.di_builder
|
||||
.create_basic_type("u64", 64, 7, LLVMDIFlagPublic)
|
||||
.create_basic_type("u64", 64, 0x7, LLVMDIFlagPublic)
|
||||
.unwrap()
|
||||
.as_type(),
|
||||
ir::UintTy::U32 => ctx
|
||||
.di_builder
|
||||
.create_basic_type("u32", 32, 7, LLVMDIFlagPublic)
|
||||
.create_basic_type("u32", 32, 0x7, LLVMDIFlagPublic)
|
||||
.unwrap()
|
||||
.as_type(),
|
||||
ir::UintTy::U16 => ctx
|
||||
.di_builder
|
||||
.create_basic_type("u16", 16, 7, LLVMDIFlagPublic)
|
||||
.create_basic_type("u16", 16, 0x7, LLVMDIFlagPublic)
|
||||
.unwrap()
|
||||
.as_type(),
|
||||
ir::UintTy::U8 => ctx
|
||||
.di_builder
|
||||
.create_basic_type("u8", 8, 7, LLVMDIFlagPublic)
|
||||
.create_basic_type("u8", 8, 0x7, LLVMDIFlagPublic)
|
||||
.unwrap()
|
||||
.as_type(),
|
||||
ir::UintTy::Usize => ctx
|
||||
.di_builder
|
||||
.create_basic_type("usize", 64, 7, LLVMDIFlagPublic)
|
||||
.create_basic_type("usize", 64, 0x7, LLVMDIFlagPublic)
|
||||
.unwrap()
|
||||
.as_type(),
|
||||
},
|
||||
|
@ -1122,5 +1138,15 @@ fn compile_debug_type<'ctx>(ctx: &ModuleCompileCtx<'ctx, '_>, ty: &ir::TypeInfo)
|
|||
ir::TypeKind::FnDef(_def_id, _generic_args) => {
|
||||
panic!()
|
||||
}
|
||||
ir::TypeKind::Ptr(pointee) => ctx
|
||||
.di_builder
|
||||
.create_pointer_type(
|
||||
&format!("ptr<{:?}>", pointee.kind),
|
||||
compile_debug_type(ctx, pointee),
|
||||
(ctx.target_data.get_pointer_byte_size(None) * 8).into(),
|
||||
ctx.target_data.get_pointer_byte_size(None),
|
||||
AddressSpace::default(),
|
||||
)
|
||||
.as_type(),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ mod common;
|
|||
#[test_case(include_str!("programs/simple.ed"), "simple", false, 1, &["a", "b"] ; "simple.ed 3")]
|
||||
#[test_case(include_str!("programs/basic_ifs.ed"), "basic_ifs", false, 9, &[] ; "basic_ifs")]
|
||||
#[test_case(include_str!("programs/while.ed"), "while", false, 10, &[] ; "r#while")]
|
||||
#[test_case(include_str!("programs/factorial.ed"), "factorial", false, 6, &[] ; "factorial")]
|
||||
fn example_tests(source: &str, name: &str, is_library: bool, status_code: i32, args: &[&str]) {
|
||||
let program = compile_program(source, name, is_library).unwrap();
|
||||
|
||||
|
|
14
lib/edlang_driver/tests/programs/factorial.ed
Normal file
14
lib/edlang_driver/tests/programs/factorial.ed
Normal file
|
@ -0,0 +1,14 @@
|
|||
mod Main {
|
||||
pub fn main() -> i32 {
|
||||
let b: i32 = factorial(3);
|
||||
return b;
|
||||
}
|
||||
|
||||
fn factorial(n: i32) -> i32 {
|
||||
if n == 1 {
|
||||
return n;
|
||||
} else {
|
||||
return n * factorial(n - 1);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -97,6 +97,7 @@ pub struct DebugInfo {
|
|||
pub struct BasicBlock {
|
||||
pub statements: SmallVec<[Statement; 8]>,
|
||||
pub terminator: Terminator,
|
||||
pub terminator_span: Option<Span>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
|
@ -202,6 +203,7 @@ pub enum TypeKind {
|
|||
Uint(UintTy),
|
||||
Float(FloatTy),
|
||||
FnDef(DefId, Vec<TypeInfo>), // The vec are generic types, not arg types
|
||||
Ptr(Box<TypeInfo>),
|
||||
}
|
||||
|
||||
impl TypeKind {
|
||||
|
@ -232,6 +234,7 @@ impl TypeKind {
|
|||
Self::Float(_) => todo!(),
|
||||
TypeKind::Unit => unreachable!(),
|
||||
TypeKind::FnDef(_, _) => unreachable!(),
|
||||
TypeKind::Ptr(_pointee) => todo!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -298,6 +301,7 @@ impl ValueTree {
|
|||
ConstValue::U128(_) => TypeKind::Uint(UintTy::U8),
|
||||
ConstValue::F32(_) => TypeKind::Float(FloatTy::F32),
|
||||
ConstValue::F64(_) => TypeKind::Float(FloatTy::F64),
|
||||
ConstValue::Char(_) => TypeKind::Char,
|
||||
},
|
||||
ValueTree::Branch(_) => todo!(),
|
||||
}
|
||||
|
@ -428,6 +432,7 @@ pub enum UnOp {
|
|||
#[derive(Debug, Clone, Copy)]
|
||||
pub enum ConstValue {
|
||||
Bool(bool),
|
||||
Char(char),
|
||||
I8(i8),
|
||||
I16(i16),
|
||||
I32(i32),
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use std::collections::HashMap;
|
||||
|
||||
use ast::{BinaryOp, ModuleStatement, WhileStmt};
|
||||
use ast::{BinaryOp, ModuleStatement, Span, WhileStmt};
|
||||
use common::{BodyBuilder, BuildCtx};
|
||||
use edlang_ast as ast;
|
||||
use edlang_ir as ir;
|
||||
|
@ -184,6 +184,7 @@ fn lower_while(builder: &mut BodyBuilder, info: &WhileStmt, ret_type: &TypeKind)
|
|||
builder.body.blocks.push(BasicBlock {
|
||||
statements: statements.into(),
|
||||
terminator: Terminator::Target(builder.body.blocks.len() + 1),
|
||||
terminator_span: Some(info.block.span),
|
||||
});
|
||||
|
||||
let (discriminator, discriminator_type) = lower_expr(builder, &info.condition, None);
|
||||
|
@ -195,7 +196,7 @@ fn lower_while(builder: &mut BodyBuilder, info: &WhileStmt, ret_type: &TypeKind)
|
|||
};
|
||||
|
||||
builder.statements.push(Statement {
|
||||
span: None,
|
||||
span: Some(info.span),
|
||||
kind: StatementKind::Assign(place.clone(), discriminator),
|
||||
});
|
||||
|
||||
|
@ -206,6 +207,7 @@ fn lower_while(builder: &mut BodyBuilder, info: &WhileStmt, ret_type: &TypeKind)
|
|||
builder.body.blocks.push(BasicBlock {
|
||||
statements: statements.into(),
|
||||
terminator: Terminator::Unreachable,
|
||||
terminator_span: Some(info.block.span),
|
||||
});
|
||||
|
||||
// keep idx for switch targets
|
||||
|
@ -226,6 +228,7 @@ fn lower_while(builder: &mut BodyBuilder, info: &WhileStmt, ret_type: &TypeKind)
|
|||
builder.body.blocks.push(BasicBlock {
|
||||
statements: statements.into(),
|
||||
terminator: Terminator::Unreachable,
|
||||
terminator_span: Some(Span::new(info.block.span.hi, info.block.span.hi)),
|
||||
});
|
||||
Some(idx)
|
||||
} else {
|
||||
|
@ -261,7 +264,7 @@ fn lower_if_stmt(builder: &mut BodyBuilder, info: &ast::IfStmt, ret_type: &TypeK
|
|||
};
|
||||
|
||||
builder.statements.push(Statement {
|
||||
span: None,
|
||||
span: Some(info.span),
|
||||
kind: StatementKind::Assign(place.clone(), condition),
|
||||
});
|
||||
|
||||
|
@ -272,6 +275,7 @@ fn lower_if_stmt(builder: &mut BodyBuilder, info: &ast::IfStmt, ret_type: &TypeK
|
|||
builder.body.blocks.push(BasicBlock {
|
||||
statements: statements.into(),
|
||||
terminator: Terminator::Unreachable,
|
||||
terminator_span: Some(info.span),
|
||||
});
|
||||
|
||||
// keep idx for switch targets
|
||||
|
@ -291,6 +295,7 @@ fn lower_if_stmt(builder: &mut BodyBuilder, info: &ast::IfStmt, ret_type: &TypeK
|
|||
builder.body.blocks.push(BasicBlock {
|
||||
statements: statements.into(),
|
||||
terminator: Terminator::Unreachable,
|
||||
terminator_span: Some(Span::new(info.then_block.span.hi, info.then_block.span.hi)),
|
||||
});
|
||||
Some(idx)
|
||||
} else {
|
||||
|
@ -314,6 +319,10 @@ fn lower_if_stmt(builder: &mut BodyBuilder, info: &ast::IfStmt, ret_type: &TypeK
|
|||
builder.body.blocks.push(BasicBlock {
|
||||
statements: statements.into(),
|
||||
terminator: Terminator::Unreachable,
|
||||
terminator_span: info
|
||||
.else_block
|
||||
.as_ref()
|
||||
.map(|x| Span::new(x.span.hi, x.span.hi)),
|
||||
});
|
||||
Some(idx)
|
||||
} else {
|
||||
|
@ -383,7 +392,6 @@ fn find_expr_type(builder: &mut BodyBuilder, info: &ast::Expression) -> Option<T
|
|||
ast::ValueExpr::Str { .. } => todo!(),
|
||||
ast::ValueExpr::Path(path) => {
|
||||
// todo: handle full path
|
||||
dbg!("found local");
|
||||
builder.get_local(&path.first.name)?.ty.kind.clone()
|
||||
}
|
||||
},
|
||||
|
@ -607,6 +615,7 @@ fn lower_fn_call(builder: &mut BodyBuilder, info: &ast::FnCallExpr) -> (Operand,
|
|||
builder.body.blocks.push(BasicBlock {
|
||||
statements: statements.into(),
|
||||
terminator: kind,
|
||||
terminator_span: Some(info.span),
|
||||
});
|
||||
|
||||
(Operand::Move(dest_place), ret_ty.kind.clone())
|
||||
|
@ -755,7 +764,7 @@ fn lower_return(builder: &mut BodyBuilder, info: &ast::ReturnStmt, return_type:
|
|||
if let Some(value_expr) = &info.value {
|
||||
let (value, _ty) = lower_expr(builder, value_expr, Some(return_type));
|
||||
builder.statements.push(Statement {
|
||||
span: None,
|
||||
span: Some(info.span),
|
||||
kind: StatementKind::Assign(
|
||||
Place {
|
||||
local: builder.ret_local,
|
||||
|
@ -770,6 +779,7 @@ fn lower_return(builder: &mut BodyBuilder, info: &ast::ReturnStmt, return_type:
|
|||
builder.body.blocks.push(BasicBlock {
|
||||
statements: statements.into(),
|
||||
terminator: Terminator::Return,
|
||||
terminator_span: Some(info.span),
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -789,7 +799,8 @@ fn lower_path(builder: &mut BodyBuilder, info: &ast::PathExpr) -> (ir::Place, Ty
|
|||
)
|
||||
}
|
||||
|
||||
pub fn lower_type(_ctx: &BuildCtx, t: &ast::Type) -> ir::TypeInfo {
|
||||
#[allow(clippy::only_used_in_recursion)]
|
||||
pub fn lower_type(ctx: &BuildCtx, t: &ast::Type) -> ir::TypeInfo {
|
||||
match t.name.name.as_str() {
|
||||
"()" => ir::TypeInfo {
|
||||
span: Some(t.span),
|
||||
|
@ -835,6 +846,18 @@ pub fn lower_type(_ctx: &BuildCtx, t: &ast::Type) -> ir::TypeInfo {
|
|||
span: Some(t.span),
|
||||
kind: ir::TypeKind::Int(ir::IntTy::I128),
|
||||
},
|
||||
_ => todo!(),
|
||||
"char" => ir::TypeInfo {
|
||||
span: Some(t.span),
|
||||
kind: ir::TypeKind::Char,
|
||||
},
|
||||
"bool" => ir::TypeInfo {
|
||||
span: Some(t.span),
|
||||
kind: ir::TypeKind::Bool,
|
||||
},
|
||||
"ptr" => ir::TypeInfo {
|
||||
span: Some(t.span),
|
||||
kind: ir::TypeKind::Ptr(Box::new(lower_type(ctx, t.generics.first().unwrap()))),
|
||||
},
|
||||
x => todo!("{:?}", x),
|
||||
}
|
||||
}
|
||||
|
|
14
programs/factorial.ed
Normal file
14
programs/factorial.ed
Normal file
|
@ -0,0 +1,14 @@
|
|||
mod Main {
|
||||
pub fn main() -> i32 {
|
||||
let b: i32 = factorial(2);
|
||||
return b;
|
||||
}
|
||||
|
||||
fn factorial(n: i32) -> i32 {
|
||||
if n == 1 {
|
||||
return n;
|
||||
} else {
|
||||
return n * factorial(n - 1);
|
||||
}
|
||||
}
|
||||
}
|
12
programs/ptr.ed
Normal file
12
programs/ptr.ed
Normal file
|
@ -0,0 +1,12 @@
|
|||
mod Main {
|
||||
|
||||
pub fn main(argc: i64, argv: ptr<char>) -> i64 {
|
||||
let mut a: i64 = 0;
|
||||
|
||||
if argc > 2 {
|
||||
a = 1;
|
||||
}
|
||||
|
||||
return a;
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue