Skip to content

Commit ec71f7d

Browse files
authored
Merge pull request #376 from Pivot-Studio/griffin/improve/add-comments-4
improvement: add comments for emit functions and llvm builder
2 parents ed16221 + b60dbd5 commit ec71f7d

File tree

23 files changed

+385
-203
lines changed

23 files changed

+385
-203
lines changed

src/ast/builder/llvmbuilder.rs

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,8 @@ pub fn create_llvm_deps<'ctx>(
132132
#[derive(Clone)]
133133
pub struct LLVMBuilder<'a, 'ctx> {
134134
handle_table: Arc<RefCell<FxHashMap<ValueHandle, AnyValueEnum<'ctx>>>>,
135-
handle_reverse_table: Arc<RefCell<FxHashMap<AnyValueEnum<'ctx>, ValueHandle>>>,
135+
reserved_handle_table: Arc<RefCell<FxHashMap<AnyValueEnum<'ctx>, ValueHandle>>>,
136+
136137
block_table: Arc<RefCell<FxHashMap<BlockHandle, BasicBlock<'ctx>>>>,
137138
block_reverse_table: Arc<RefCell<FxHashMap<BasicBlock<'ctx>, BlockHandle>>>,
138139
context: &'ctx Context, // llvm context
@@ -203,7 +204,7 @@ impl<'a, 'ctx> LLVMBuilder<'a, 'ctx> {
203204
ditypes: Arc::new(RefCell::new(FxHashMap::default())),
204205
ditypes_placeholder: Arc::new(RefCell::new(FxHashMap::default())),
205206
handle_table: Arc::new(RefCell::new(FxHashMap::default())),
206-
handle_reverse_table: Arc::new(RefCell::new(FxHashMap::default())),
207+
reserved_handle_table: Arc::new(RefCell::new(FxHashMap::default())),
207208
block_table: Arc::new(RefCell::new(FxHashMap::default())),
208209
block_reverse_table: Arc::new(RefCell::new(FxHashMap::default())),
209210
optimized: Arc::new(RefCell::new(false)),
@@ -655,17 +656,31 @@ impl<'a, 'ctx> LLVMBuilder<'a, 'ctx> {
655656
self.difile.get()
656657
}
657658

659+
/// # get_llvm_value_handle
660+
///
661+
/// get_llvm_value_handle tries to get the [ValueHandle] of a [AnyValueEnum][inkwell::values::AnyValueEnum] value,
662+
/// it returns the handle value if it finds the value appears inside the map already,
663+
/// otherwise it will insert the value into the map and create a new handle for it.
658664
fn get_llvm_value_handle(&self, value: &AnyValueEnum<'ctx>) -> ValueHandle {
659665
let len = self.handle_table.borrow().len();
660-
let nh = match self.handle_reverse_table.borrow().get(value) {
666+
667+
// it refers the handle value if we need to insert the value
668+
let should_insert_handle = len + 1;
669+
670+
// whether the value exists inside the handle table
671+
let handle_value = match self.reserved_handle_table.borrow().get(value) {
661672
Some(handle) => *handle,
662-
None => len + 1,
673+
None => should_insert_handle,
663674
};
664-
if nh == len + 1 {
665-
self.handle_table.borrow_mut().insert(nh, *value);
666-
self.handle_reverse_table.borrow_mut().insert(*value, nh);
675+
676+
// if the value doesn't exist in current handle table, insert it in the tables
677+
if handle_value == should_insert_handle {
678+
self.handle_table.borrow_mut().insert(handle_value, *value);
679+
self.reserved_handle_table
680+
.borrow_mut()
681+
.insert(*value, handle_value);
667682
}
668-
nh
683+
handle_value
669684
}
670685
#[allow(dead_code)]
671686
fn get_or_insert_print_fn(&self, name: &str) -> FunctionValue<'ctx> {
@@ -1157,7 +1172,7 @@ impl<'a, 'ctx> LLVMBuilder<'a, 'ctx> {
11571172
) -> (DIType<'ctx>, u64) {
11581173
let field_pltype = match field.typenode.get_type(ctx, &self.clone().into(), true) {
11591174
Ok(field_pltype) => field_pltype,
1160-
Err(_) => ctx.get_type("i64", Default::default()).unwrap().tp,
1175+
Err(_) => ctx.get_type("i64", Default::default()).unwrap().typ,
11611176
};
11621177
let di_type = self.get_ditype(&field_pltype.borrow(), ctx);
11631178
let debug_type = di_type.unwrap();

src/ast/builder/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -305,8 +305,12 @@ pub trait IRBuilder<'a, 'ctx> {
305305
fn is_main(&self, f: ValueHandle) -> bool;
306306
}
307307

308+
/// ValueHandle is an index used to separate the low level generatted code inside [BuilderEnum] from the respective high level ast node
308309
pub type ValueHandle = usize;
310+
311+
/// BlockHandle is an index used to separate the low level generatted code inside [BuilderEnum] from the respective high level ast node
309312
pub type BlockHandle = usize;
313+
310314
#[allow(clippy::upper_case_acronyms)]
311315
#[enum_dispatch(IRBuilder)]
312316
pub enum BuilderEnum<'a, 'ctx> {

src/ast/ctx.rs

Lines changed: 106 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use super::node::function::generator::CtxFlag;
99
use super::node::macro_nodes::MacroNode;
1010
use super::node::node_result::NodeResult;
1111
use super::node::NodeEnum;
12-
use super::plmod::GlobType;
12+
use super::plmod::GlobalType;
1313
use super::plmod::GlobalVar;
1414
use super::plmod::Mod;
1515
use super::plmod::MutVec;
@@ -63,8 +63,11 @@ pub struct PLSymbolData {
6363

6464
#[derive(Clone)]
6565
pub enum PLSymbol {
66+
/// Local refers the symbol exists in a local scope
6667
Local(PLSymbolData),
68+
/// Global refers the symbol exists in the global scope of current module
6769
Global(PLSymbolData),
70+
/// Captured refers a symbol exists in another module
6871
Captured(PLSymbolData),
6972
}
7073

@@ -75,13 +78,20 @@ impl PLSymbol {
7578
pub fn is_captured(&self) -> bool {
7679
matches!(self, PLSymbol::Captured(_))
7780
}
81+
/// # get_data_ref
82+
///
83+
/// returns the reference of the symbol data regardless the scope of data
7884
pub fn get_data_ref(&self) -> &PLSymbolData {
7985
match self {
8086
PLSymbol::Local(d) => d,
8187
PLSymbol::Global(d) => d,
8288
PLSymbol::Captured(d) => d,
8389
}
8490
}
91+
92+
/// # get_data
93+
///
94+
/// returns the the symbol data regardless the scope of data
8595
pub fn get_data(self) -> PLSymbolData {
8696
match self {
8797
PLSymbol::Local(d) => d,
@@ -96,45 +106,89 @@ type GenericCacheMap = IndexMap<String, Arc<RefCell<IndexMap<String, Arc<RefCell
96106
pub type GenericCache = Arc<RefCell<GenericCacheMap>>;
97107

98108
/// # Ctx
99-
/// Context for code generation
109+
/// Context for code generation and LSP features
100110
pub struct Ctx<'a> {
101111
pub generic_types: FxHashMap<String, Arc<RefCell<PLType>>>,
102-
pub need_highlight: Arc<RefCell<usize>>,
103112
pub plmod: Mod,
104-
pub father: Option<&'a Ctx<'a>>, // father context, for symbol lookup
113+
114+
pub parent: Option<&'a Ctx<'a>>, // parent context, for symbol lookup
105115
pub root: Option<&'a Ctx<'a>>, // root context, for symbol lookup
106-
pub function: Option<ValueHandle>, // current function
107-
pub init_func: Option<ValueHandle>, //init function,call first in main
108-
pub block: Option<BlockHandle>, // current block
109-
pub continue_block: Option<BlockHandle>, // the block to jump when continue
110-
pub break_block: Option<BlockHandle>, // the block to jump to when break
111-
pub return_block: Option<(BlockHandle, Option<ValueHandle>)>, // the block to jump to when return and value
112-
pub errs: &'a RefCell<FxHashSet<PLDiag>>, // diagnostic list
113-
pub edit_pos: Option<Pos>, // lsp params
114-
pub table: FxHashMap<String, PLSymbolData>, // variable table
115-
pub config: Config, // config
116+
117+
/// LSP argument, because the high light among multiple tokens require an order,
118+
/// hence, we stores a value inside it to refer whether we need to generate the code or not.
119+
/// highlight is generated only if the number is 0
120+
pub need_highlight: Arc<RefCell<usize>>,
121+
122+
/// the index to mark a lower level code generation of function element from the builder
123+
pub function: Option<ValueHandle>,
124+
/// the init function called first in main
125+
pub init_func: Option<ValueHandle>,
126+
/// current block
127+
pub block: Option<BlockHandle>,
128+
/// the block to jump when continue if it's a loop statement
129+
pub continue_block: Option<BlockHandle>,
130+
/// the block to jump to when break if it's a loop statement
131+
pub break_block: Option<BlockHandle>,
132+
/// the block to jump to when return and value
133+
pub return_block: Option<(BlockHandle, Option<ValueHandle>)>,
134+
135+
/// diagnose tries to hold all warning and as many as possible errors
136+
pub diagnose: &'a RefCell<FxHashSet<PLDiag>>,
137+
138+
/// LSP argument: the editing position of this context
139+
pub edit_pos: Option<Pos>,
140+
141+
/// available varaibles in the current block,
142+
/// the outside variables could be accessed through the parent ctx.
143+
pub table: FxHashMap<String, PLSymbolData>,
144+
pub config: Config, // config
116145
pub db: &'a dyn Db,
146+
147+
/// the return type of a function, all contexts for functions or the child contexts of functions
148+
/// hold the return type.
117149
pub rettp: Option<Arc<RefCell<PLType>>>,
118-
pub macro_vars: FxHashMap<String, MacroReplaceNode>,
119-
pub macro_skip_level: usize,
120-
pub macro_loop: bool,
121-
pub macro_loop_idx: usize,
122-
pub macro_loop_len: usize,
150+
151+
/// the expect_ty is used when implicitly cast type during assignment
152+
/// for example, the `let i:i8 = 1.2`, the expect_ty will be i8
153+
pub expect_ty: Option<Arc<RefCell<PLType>>>,
154+
155+
/// generics requires a code generation at the place where the identifiers are defined
156+
/// hence, we need to perserve the definition position as well for a better error report.
157+
/// the temp_source stores the position where the code is generated.
123158
pub temp_source: Option<String>,
124-
pub in_macro: bool,
159+
160+
/// stores the the additional date of a closure
125161
pub closure_data: Option<Arc<RefCell<ClosureCtxData>>>,
126-
pub expect_ty: Option<Arc<RefCell<PLType>>>,
127-
pub self_ref_map: FxHashMap<String, FxHashSet<(String, Range)>>, // used to recognize self reference
128-
pub ctx_flag: CtxFlag,
162+
163+
/// used to recognize self reference to avoid endless loop
164+
pub self_ref_map: FxHashMap<String, FxHashSet<(String, Range)>>,
165+
166+
pub ctx_flag: CtxFlag, // can ignore first
129167
pub generator_data: Option<Arc<RefCell<GeneratorCtxData>>>,
130-
pub generic_cache: GenericCache,
168+
169+
pub generic_cache: GenericCache, // too old to remember
170+
171+
/// back up plmod because sometimes we need to find the parent mod after switching
131172
pub origin_mod: *const Mod,
173+
132174
pub linked_tp_tbl: FxHashMap<*mut PLType, Vec<Arc<RefCell<PLType>>>>,
175+
176+
/// not all lsp request has an edition position
133177
is_active_file: bool,
178+
179+
// for lsp, don't give hints for variables, etc...
134180
as_root: bool,
181+
135182
macro_expand_depth: Arc<RefCell<u64>>,
136183
pub unify_table: Arc<RefCell<UnificationTable<TyVariable>>>,
137184
pub disable_diag: bool,
185+
186+
pub macro_vars: FxHashMap<String, MacroReplaceNode>,
187+
pub macro_skip_level: usize,
188+
pub macro_loop: bool,
189+
pub macro_loop_idx: usize,
190+
pub macro_loop_len: usize,
191+
pub in_macro: bool,
138192
}
139193

140194
#[derive(Clone, PartialEq, Eq, Debug)]
@@ -236,13 +290,13 @@ impl<'a, 'ctx> Ctx<'a> {
236290
while let Some(p) = ctx {
237291
i += 1;
238292
if i <= self.macro_skip_level {
239-
ctx = p.father;
293+
ctx = p.parent;
240294
continue;
241295
}
242296
if let Some(v) = p.macro_vars.get(name) {
243297
return Some(v);
244298
}
245-
ctx = p.father;
299+
ctx = p.parent;
246300
}
247301
None
248302
}
@@ -259,10 +313,10 @@ impl<'a, 'ctx> Ctx<'a> {
259313
need_highlight: Default::default(),
260314
generic_types: FxHashMap::default(),
261315
plmod: Mod::new(src_file_path.to_string(), generic_infer.clone()),
262-
father: None,
316+
parent: None,
263317
init_func: None,
264318
function: None,
265-
errs,
319+
diagnose: errs,
266320
edit_pos,
267321
table: FxHashMap::default(),
268322
config,
@@ -297,15 +351,15 @@ impl<'a, 'ctx> Ctx<'a> {
297351
}
298352
pub fn new_child(&'a self, start: Pos, builder: &'a BuilderEnum<'a, 'ctx>) -> Ctx<'a> {
299353
let mut root = self.root;
300-
if self.father.is_none() {
354+
if self.parent.is_none() {
301355
root = Some(self);
302356
}
303357
let mut ctx = Ctx {
304358
need_highlight: self.need_highlight.clone(),
305359
generic_types: FxHashMap::default(),
306360
plmod: self.plmod.new_child(),
307-
father: Some(self),
308-
errs: self.errs,
361+
parent: Some(self),
362+
diagnose: self.diagnose,
309363
edit_pos: self.edit_pos,
310364
table: FxHashMap::default(),
311365
config: self.config.clone(),
@@ -550,7 +604,8 @@ impl<'a, 'ctx> Ctx<'a> {
550604
}
551605
}
552606
/// # get_symbol
553-
/// search in current and all father symbol tables
607+
///
608+
/// search in current and all parent symbol tables
554609
pub fn get_symbol<'b>(
555610
&'b self,
556611
name: &str,
@@ -564,12 +619,12 @@ impl<'a, 'ctx> Ctx<'a> {
564619
let mut data = data.borrow_mut();
565620
if let Some((symbol, _)) = data.table.get(name) {
566621
return Some(PLSymbol::Captured(symbol.clone()));
567-
} else if let Some(father) = self.father {
568-
let re = father.get_symbol(name, builder);
622+
}
623+
if let Some(parent) = self.parent {
624+
let re = parent.get_symbol(name, builder);
569625
if let Some(s) = &re {
570626
let symbol = s.get_data_ref();
571-
let is_glob = s.is_global();
572-
if !is_glob {
627+
if !s.is_global() {
573628
let cur = builder.get_cur_basic_block();
574629
// just make sure we are in the alloca bb
575630
// so that the captured value is not used before it is initialized
@@ -585,11 +640,11 @@ impl<'a, 'ctx> Ctx<'a> {
585640
let new_symbol = symbol.clone();
586641
let len = data.table.len();
587642
let st_r = data.data_tp.as_ref().unwrap().borrow();
588-
let st = match &*st_r {
643+
let st: &super::pltype::STType = match &*st_r {
589644
PLType::Struct(s) => s,
590645
_ => unreachable!(),
591646
};
592-
let ptr = father as *const _;
647+
let ptr = parent as *const _;
593648
let ptr = ptr as usize;
594649
let ptr = ptr as *mut Ctx<'_>;
595650
builder.add_closure_st_field(st, new_symbol.value, unsafe { &mut *ptr });
@@ -621,7 +676,7 @@ impl<'a, 'ctx> Ctx<'a> {
621676
}
622677
}
623678
if !self.as_root {
624-
if let Some(father) = self.father {
679+
if let Some(father) = self.parent {
625680
let re = father.get_symbol(name, builder);
626681
return re;
627682
}
@@ -715,7 +770,12 @@ impl<'a, 'ctx> Ctx<'a> {
715770
},
716771
);
717772
}
718-
pub fn get_type(&self, name: &str, range: Range) -> Result<GlobType, PLDiag> {
773+
774+
/// # get_type
775+
///
776+
/// Get type based on name from the generic types,
777+
/// from the current context to its ancestor context until one element is found, otherwise it return an error.
778+
pub fn get_type(&self, name: &str, range: Range) -> Result<GlobalType, PLDiag> {
719779
if let Some(pv) = self.generic_types.get(name) {
720780
self.set_if_refs_tp(pv.clone(), range);
721781
if let Ok(pv) = pv.try_borrow() {
@@ -730,14 +790,14 @@ impl<'a, 'ctx> Ctx<'a> {
730790
if let Ok(pv) = self.plmod.get_type(name, range, self) {
731791
return Ok(pv);
732792
}
733-
if let Some(father) = self.father {
793+
if let Some(father) = self.parent {
734794
let re = father.get_type(name, range);
735795
return re;
736796
}
737797
Err(range.new_err(ErrorCode::UNDEFINED_TYPE))
738798
}
739799

740-
pub fn get_type_in_mod(&self, m: &Mod, name: &str, range: Range) -> Result<GlobType, PLDiag> {
800+
pub fn get_type_in_mod(&self, m: &Mod, name: &str, range: Range) -> Result<GlobalType, PLDiag> {
741801
if let Some(pv) = self.generic_types.get(name) {
742802
self.set_if_refs_tp(pv.clone(), range);
743803
self.send_if_go_to_def(
@@ -754,7 +814,7 @@ impl<'a, 'ctx> Ctx<'a> {
754814
} else if let Ok(pv) = m.get_type(name, range, self) {
755815
return Ok(pv);
756816
}
757-
if let Some(father) = self.father {
817+
if let Some(father) = self.parent {
758818
let re = father.get_type_in_mod(m, name, range);
759819
return re;
760820
}
@@ -879,7 +939,7 @@ impl<'a, 'ctx> Ctx<'a> {
879939
dia.set_source(src);
880940
}
881941
let dia2 = dia.clone();
882-
self.errs.borrow_mut().insert(dia);
942+
self.diagnose.borrow_mut().insert(dia);
883943
dia2
884944
}
885945
// load type* to type
@@ -1048,7 +1108,7 @@ impl<'a, 'ctx> Ctx<'a> {
10481108
if let Some(m) = self.plmod.macros.get(name) {
10491109
return Some(m.clone());
10501110
}
1051-
if let Some(father) = &self.father {
1111+
if let Some(father) = &self.parent {
10521112
return father.get_macro(name);
10531113
}
10541114
None
@@ -1089,7 +1149,7 @@ impl<'a, 'ctx> Ctx<'a> {
10891149
pub fn try_set_closure_alloca_bb(&self, bb: BlockHandle) {
10901150
if let Some(c) = &self.closure_data {
10911151
c.borrow_mut().alloca_bb = Some(bb);
1092-
} else if let Some(father) = &self.father {
1152+
} else if let Some(father) = &self.parent {
10931153
father.try_set_closure_alloca_bb(bb);
10941154
}
10951155
}

0 commit comments

Comments
 (0)