Skip to content

Commit 9f30fc3

Browse files
committed
refactor: use trait as builder& add noop builder
1 parent 8859629 commit 9f30fc3

22 files changed

+585
-137
lines changed

src/ast/builder/llvmbuilder.rs

Lines changed: 48 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ use inkwell::{
1212
builder::Builder,
1313
context::Context,
1414
debug_info::*,
15-
module::{Linkage, Module, FlagBehavior},
16-
targets::{TargetMachine, Target, InitializationConfig},
15+
module::{Linkage, Module},
16+
targets::{InitializationConfig, Target, TargetMachine},
1717
types::{ArrayType, BasicType, BasicTypeEnum, StructType},
1818
values::{
1919
AnyValue, AnyValueEnum, BasicMetadataValueEnum, BasicValue, BasicValueEnum, FunctionValue,
@@ -23,16 +23,19 @@ use inkwell::{
2323
};
2424
use rustc_hash::FxHashMap;
2525

26-
use super::{super::{
27-
ctx::{Ctx, MemberType, PLDiag},
28-
diag::ErrorCode,
29-
node::{types::TypedIdentifierNode, TypeNode, TypeNodeEnum},
30-
pltype::{ARRType, FNType, Field, PLType, PriType, RetTypeEnum, STType},
31-
range::{Pos, Range},
32-
}, IRBuilder};
26+
use super::{
27+
super::{
28+
ctx::{Ctx, MemberType, PLDiag},
29+
diag::ErrorCode,
30+
node::{types::TypedIdentifierNode, TypeNode, TypeNodeEnum},
31+
pltype::{ARRType, FNType, Field, PLType, PriType, RetTypeEnum, STType},
32+
range::{Pos, Range},
33+
},
34+
IRBuilder,
35+
};
3336

34-
use super::ValueHandle;
3537
use super::BlockHandle;
38+
use super::ValueHandle;
3639

3740
// TODO: match all case
3841
// const DW_ATE_UTF: u32 = 0x10;
@@ -50,6 +53,7 @@ fn get_dw_ate_encoding<'a, 'ctx>(pritp: &PriType) -> u32 {
5053
}
5154
}
5255

56+
#[derive(Clone)]
5357
pub struct LLVMBuilder<'a, 'ctx> {
5458
handle_table: Rc<RefCell<FxHashMap<ValueHandle, AnyValueEnum<'ctx>>>>,
5559
handle_reverse_table: Rc<RefCell<FxHashMap<AnyValueEnum<'ctx>, ValueHandle>>>,
@@ -241,7 +245,7 @@ impl<'a, 'ctx> LLVMBuilder<'a, 'ctx> {
241245
ctx: &mut Ctx<'a>,
242246
offset: u64,
243247
) -> (DIType<'ctx>, u64) {
244-
let field_pltype = match field.typenode.get_type(ctx, self) {
248+
let field_pltype = match field.typenode.get_type(ctx, &self.clone().into()) {
245249
Ok(field_pltype) => field_pltype,
246250
Err(_) => ctx.get_type("i64", Default::default()).unwrap(),
247251
};
@@ -448,13 +452,26 @@ impl<'a, 'ctx> LLVMBuilder<'a, 'ctx> {
448452
let mut param_types = vec![];
449453
for param_pltype in pltp.param_pltypes.iter() {
450454
param_types.push(
451-
self.get_basic_type_op(&param_pltype.get_type(ctx, self).unwrap().borrow(), ctx)
452-
.unwrap()
453-
.into(),
455+
self.get_basic_type_op(
456+
&param_pltype
457+
.get_type(ctx, &self.clone().into())
458+
.unwrap()
459+
.borrow(),
460+
ctx,
461+
)
462+
.unwrap()
463+
.into(),
454464
);
455465
}
456466
let fn_type = self
457-
.get_ret_type(&pltp.ret_pltype.get_type(ctx, self).unwrap().borrow(), ctx)
467+
.get_ret_type(
468+
&pltp
469+
.ret_pltype
470+
.get_type(ctx, &self.clone().into())
471+
.unwrap()
472+
.borrow(),
473+
ctx,
474+
)
458475
.fn_type(&param_types, false);
459476
let fn_value = self
460477
.module
@@ -474,7 +491,11 @@ impl<'a, 'ctx> LLVMBuilder<'a, 'ctx> {
474491
.into_iter()
475492
.map(|order_field| {
476493
self.get_basic_type_op(
477-
&order_field.typenode.get_type(ctx, self).unwrap().borrow(),
494+
&order_field
495+
.typenode
496+
.get_type(ctx, &self.clone().into())
497+
.unwrap()
498+
.borrow(),
478499
ctx,
479500
)
480501
.unwrap()
@@ -707,12 +728,12 @@ impl<'a, 'ctx> IRBuilder<'a, 'ctx> for LLVMBuilder<'a, 'ctx> {
707728
Some(self.get_llvm_value_handle(&f.as_any_value_enum()))
708729
}
709730

710-
fn build_call(&self, f: ValueHandle, args: &[ValueHandle]) -> Option<ValueHandle>
711-
{
731+
fn build_call(&self, f: ValueHandle, args: &[ValueHandle]) -> Option<ValueHandle> {
712732
let builder = self.builder;
713733
let f = self.get_llvm_value(f).unwrap();
714734
let f = f.into_function_value();
715-
let args = args.iter()
735+
let args = args
736+
.iter()
716737
.map(|v| {
717738
let be: BasicValueEnum = self.get_llvm_value(*v).unwrap().try_into().unwrap();
718739
let bme: BasicMetadataValueEnum = be.into();
@@ -753,7 +774,11 @@ impl<'a, 'ctx> IRBuilder<'a, 'ctx> for LLVMBuilder<'a, 'ctx> {
753774
.into_iter()
754775
.map(|order_field| {
755776
self.get_basic_type_op(
756-
&order_field.typenode.get_type(ctx, self).unwrap().borrow(),
777+
&order_field
778+
.typenode
779+
.get_type(ctx, &self.clone().into())
780+
.unwrap()
781+
.borrow(),
757782
ctx,
758783
)
759784
.unwrap()
@@ -1103,7 +1128,7 @@ impl<'a, 'ctx> IRBuilder<'a, 'ctx> for LLVMBuilder<'a, 'ctx> {
11031128
) -> Result<(), PLDiag> {
11041129
let mut param_ditypes = vec![];
11051130
for para in paralist.iter() {
1106-
let pltype = para.typenode.get_type(child, self)?;
1131+
let pltype = para.typenode.get_type(child, &self.clone().into())?;
11071132
match &*pltype.borrow() {
11081133
PLType::VOID => {
11091134
return Err(child.add_err(para.range, ErrorCode::VOID_TYPE_CANNOT_BE_PARAMETER))
@@ -1116,7 +1141,7 @@ impl<'a, 'ctx> IRBuilder<'a, 'ctx> for LLVMBuilder<'a, 'ctx> {
11161141
// debug info
11171142
let subroutine_type = self.dibuilder.create_subroutine_type(
11181143
self.diunit.get_file(),
1119-
self.get_ditype(&ret.get_type(child, self)?.borrow(), child),
1144+
self.get_ditype(&ret.get_type(child, &self.clone().into())?.borrow(), child),
11201145
&param_ditypes,
11211146
DIFlags::PUBLIC,
11221147
);
@@ -1166,7 +1191,7 @@ impl<'a, 'ctx> IRBuilder<'a, 'ctx> for LLVMBuilder<'a, 'ctx> {
11661191
pos.line as u32,
11671192
self.get_ditype(
11681193
&fntype.param_pltypes[i]
1169-
.get_type(child, self)
1194+
.get_type(child, &self.clone().into())
11701195
.unwrap()
11711196
.borrow(),
11721197
child,

src/ast/builder/mod.rs

Lines changed: 16 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2,37 +2,23 @@
22
/// 1. 所有Builder的字段都应该private,不应该被外部直接访问
33
/// 2. 所有涉及llvm类型的函数(包括参数或返回值)都应该是private的
44
pub mod llvmbuilder;
5-
use std::{
6-
cell::{Cell, RefCell},
7-
path::Path,
8-
rc::Rc,
9-
};
5+
pub mod no_op_builder;
6+
use std::{cell::RefCell, path::Path, rc::Rc};
107

11-
use inkwell::{
12-
basic_block::BasicBlock,
13-
builder::Builder,
14-
context::Context,
15-
debug_info::*,
16-
module::{Linkage, Module},
17-
targets::TargetMachine,
18-
types::{ArrayType, BasicType, BasicTypeEnum, StructType},
19-
values::{
20-
AnyValue, AnyValueEnum, BasicMetadataValueEnum, BasicValue, BasicValueEnum, FunctionValue,
21-
PointerValue,
22-
},
23-
AddressSpace, FloatPredicate, IntPredicate,
24-
};
25-
use rustc_hash::FxHashMap;
8+
use enum_dispatch::enum_dispatch;
9+
use inkwell::{values::BasicValueEnum, FloatPredicate, IntPredicate};
10+
11+
use self::llvmbuilder::LLVMBuilder;
12+
use self::no_op_builder::NoOpBuilder;
2613

2714
use super::{
28-
ctx::{Ctx, MemberType, PLDiag},
29-
diag::ErrorCode,
30-
node::{types::TypedIdentifierNode, TypeNode, TypeNodeEnum},
31-
pltype::{ARRType, FNType, Field, PLType, PriType, RetTypeEnum, STType},
15+
ctx::{Ctx, PLDiag},
16+
node::{types::TypedIdentifierNode, TypeNodeEnum},
17+
pltype::{FNType, Field, PLType, PriType},
3218
range::{Pos, Range},
3319
};
3420

35-
21+
#[enum_dispatch]
3622
pub trait IRBuilder<'a, 'ctx> {
3723
fn get_global_var_handle(&self, name: &str) -> Option<ValueHandle>;
3824
fn new_subscope(&self, start: Pos);
@@ -173,7 +159,11 @@ pub trait IRBuilder<'a, 'ctx> {
173159
fn build_int_neg(&self, v: ValueHandle, name: &str) -> ValueHandle;
174160
}
175161

176-
177162
pub type ValueHandle = usize;
178163
pub type BlockHandle = usize;
179164

165+
#[enum_dispatch(IRBuilder)]
166+
pub enum BuilderEnum<'a, 'ctx> {
167+
LLVM(LLVMBuilder<'a, 'ctx>),
168+
NoOp(NoOpBuilder),
169+
}

0 commit comments

Comments
 (0)