diff --git a/nac3core/src/codegen/expr.rs b/nac3core/src/codegen/expr.rs index e4dd6ba..d4dce64 100644 --- a/nac3core/src/codegen/expr.rs +++ b/nac3core/src/codegen/expr.rs @@ -59,6 +59,8 @@ pub fn get_subst_key( } impl<'ctx, 'a> CodeGenContext<'ctx, 'a> { + /// Builds a sequence of `getelementptr` and `load` instructions which stores the value of a + /// struct field into an LLVM value. pub fn build_gep_and_load( &mut self, ptr: PointerValue<'ctx>, @@ -197,6 +199,7 @@ impl<'ctx, 'a> CodeGenContext<'ctx, 'a> { ) } + /// Generates an LLVM variable for a [constant value][value] with a given [type][ty]. pub fn gen_const( &mut self, generator: &mut dyn CodeGenerator, @@ -258,6 +261,7 @@ impl<'ctx, 'a> CodeGenContext<'ctx, 'a> { } } + /// Generates a binary operation `op` between two integral operands `lhs` and `rhs`. pub fn gen_int_ops( &mut self, generator: &mut dyn CodeGenerator, @@ -302,6 +306,7 @@ impl<'ctx, 'a> CodeGenContext<'ctx, 'a> { } } + /// Generates a binary operation `op` between two floating-point operands `lhs` and `rhs`. pub fn gen_float_ops( &mut self, op: &Operator, @@ -424,6 +429,7 @@ impl<'ctx, 'a> CodeGenContext<'ctx, 'a> { } } + /// Helper function for generating a LLVM variable storing a [String]. pub fn gen_string>( &mut self, generator: &mut dyn CodeGenerator, @@ -523,6 +529,7 @@ impl<'ctx, 'a> CodeGenContext<'ctx, 'a> { } } +/// See [CodeGenerator::gen_constructor]. pub fn gen_constructor<'ctx, 'a, G: CodeGenerator>( generator: &mut G, ctx: &mut CodeGenContext<'ctx, 'a>, @@ -554,6 +561,7 @@ pub fn gen_constructor<'ctx, 'a, G: CodeGenerator>( } } +/// See [CodeGenerator::gen_func_instance]. pub fn gen_func_instance<'ctx, 'a>( ctx: &mut CodeGenContext<'ctx, 'a>, obj: Option<(Type, ValueEnum<'ctx>)>, @@ -630,6 +638,7 @@ pub fn gen_func_instance<'ctx, 'a>( } } +/// See [CodeGenerator::gen_call]. pub fn gen_call<'ctx, 'a, G: CodeGenerator>( generator: &mut G, ctx: &mut CodeGenContext<'ctx, 'a>, @@ -789,6 +798,8 @@ pub fn gen_call<'ctx, 'a, G: CodeGenerator>( Ok(ctx.build_call_or_invoke(fun_val, ¶m_vals, "call")) } +/// Generates three LLVM variables representing the start, stop, and step values of a [range] class +/// respectively. pub fn destructure_range<'ctx, 'a>( ctx: &mut CodeGenContext<'ctx, 'a>, range: PointerValue<'ctx>, @@ -857,6 +868,7 @@ pub fn allocate_list<'ctx, 'a, G: CodeGenerator>( arr_str_ptr } +/// Generates LLVM IR for a [list comprehension expression][expr]. pub fn gen_comprehension<'ctx, 'a, G: CodeGenerator>( generator: &mut G, ctx: &mut CodeGenContext<'ctx, 'a>, @@ -1026,6 +1038,13 @@ pub fn gen_comprehension<'ctx, 'a, G: CodeGenerator>( } } +/// Generates LLVM IR for a [binary operator expression][expr]. +/// +/// * `left` - The left-hand side of the binary operator. +/// * `op` - The operator applied on the operands. +/// * `right` - The right-hand side of the binary operator. +/// * `loc` - The location of the full expression. +/// * `is_aug_assign` - Whether the binary operator expression is also an assignment operator. pub fn gen_binop_expr<'ctx, 'a, G: CodeGenerator>( generator: &mut G, ctx: &mut CodeGenContext<'ctx, 'a>, @@ -1122,6 +1141,7 @@ pub fn gen_binop_expr<'ctx, 'a, G: CodeGenerator>( } } +/// See [CodeGenerator::gen_expr]. pub fn gen_expr<'ctx, 'a, G: CodeGenerator>( generator: &mut G, ctx: &mut CodeGenContext<'ctx, 'a>, diff --git a/nac3core/src/codegen/generator.rs b/nac3core/src/codegen/generator.rs index 53a0996..431f345 100644 --- a/nac3core/src/codegen/generator.rs +++ b/nac3core/src/codegen/generator.rs @@ -181,7 +181,7 @@ pub trait CodeGenerator { gen_stmt(self, ctx, stmt) } - /// Converts the value of [a boolean-like value][bool_value] into an `i1`. + /// See [bool_to_i1]. fn bool_to_i1<'ctx, 'a>( &self, ctx: &CodeGenContext<'ctx, 'a>, @@ -190,7 +190,7 @@ pub trait CodeGenerator { bool_to_i1(&ctx.builder, bool_value) } - /// Converts the value of [a boolean-like value][bool_value] into an `i8`. + /// See [bool_to_i8]. fn bool_to_i8<'ctx, 'a>( &self, ctx: &CodeGenContext<'ctx, 'a>, diff --git a/nac3core/src/codegen/mod.rs b/nac3core/src/codegen/mod.rs index 300bd3c..67176c8 100644 --- a/nac3core/src/codegen/mod.rs +++ b/nac3core/src/codegen/mod.rs @@ -357,7 +357,7 @@ pub struct CodeGenTask { /// Retrieves the [LLVM type][BasicTypeEnum] corresponding to the [Type]. /// -/// This function is used to obtain the in-memory representation of [ty], e.g. a `bool` variable +/// This function is used to obtain the in-memory representation of `ty`, e.g. a `bool` variable /// would be represented by an `i8`. fn get_llvm_type<'ctx>( ctx: &'ctx Context, @@ -472,7 +472,7 @@ fn get_llvm_type<'ctx>( /// Retrieves the [LLVM type][BasicTypeEnum] corresponding to the [Type]. /// -/// This function is used mainly to obtain the ABI representation of [ty], e.g. a `bool` is +/// This function is used mainly to obtain the ABI representation of `ty`, e.g. a `bool` is /// would be represented by an `i1`. /// /// The difference between the in-memory representation (as returned by [get_llvm_type]) and the @@ -511,6 +511,7 @@ fn need_sret<'ctx>(ctx: &'ctx Context, ty: BasicTypeEnum<'ctx>) -> bool { need_sret_impl(ctx, ty, true) } +/// Implementation for generating LLVM IR for a function. pub fn gen_func_impl<'ctx, G: CodeGenerator, F: FnOnce(&mut G, &mut CodeGenContext) -> Result<(), String>> ( context: &'ctx Context, generator: &mut G, @@ -835,6 +836,15 @@ pub fn gen_func_impl<'ctx, G: CodeGenerator, F: FnOnce(&mut G, &mut CodeGenConte Ok((builder, module, fn_val)) } +/// Generates LLVM IR for a function. +/// +/// * `context` - The [LLVM Context][Context] used in generating the function body. +/// * `generator` - The [CodeGenerator] for generating various program constructs. +/// * `registry` - The [WorkerRegistry] responsible for monitoring this function generation task. +/// * `builder` - The [Builder] used for generating LLVM IR. +/// * `module` - The [Module] of which the generated LLVM function will be inserted into. +/// * `task` - The [CodeGenTask] associated with this function generation task. +/// pub fn gen_func<'ctx, G: CodeGenerator>( context: &'ctx Context, generator: &mut G, @@ -852,7 +862,7 @@ pub fn gen_func<'ctx, G: CodeGenerator>( }) } -/// Converts the value of [a boolean-like value][bool_value] into an `i1`. +/// Converts the value of a boolean-like value `bool_value` into an `i1`. fn bool_to_i1<'ctx>(builder: &Builder<'ctx>, bool_value: IntValue<'ctx>) -> IntValue<'ctx> { if bool_value.get_type().get_bit_width() != 1 { builder.build_int_compare( @@ -866,7 +876,7 @@ fn bool_to_i1<'ctx>(builder: &Builder<'ctx>, bool_value: IntValue<'ctx>) -> IntV } } -/// Converts the value of [a boolean-like value][bool_value] into an `i8`. +/// Converts the value of a boolean-like value `bool_value` into an `i8`. fn bool_to_i8<'ctx>( builder: &Builder<'ctx>, ctx: &'ctx Context, diff --git a/nac3core/src/codegen/stmt.rs b/nac3core/src/codegen/stmt.rs index 6071b1c..da95456 100644 --- a/nac3core/src/codegen/stmt.rs +++ b/nac3core/src/codegen/stmt.rs @@ -21,6 +21,7 @@ use nac3parser::ast::{ }; use std::convert::TryFrom; +/// See [CodeGenerator::gen_var_alloc]. pub fn gen_var<'ctx, 'a>( ctx: &mut CodeGenContext<'ctx, 'a>, ty: BasicTypeEnum<'ctx>, @@ -35,6 +36,7 @@ pub fn gen_var<'ctx, 'a>( Ok(ptr) } +/// See [CodeGenerator::gen_store_target]. pub fn gen_store_target<'ctx, 'a, G: CodeGenerator>( generator: &mut G, ctx: &mut CodeGenContext<'ctx, 'a>, @@ -144,6 +146,7 @@ pub fn gen_store_target<'ctx, 'a, G: CodeGenerator>( }) } +/// See [CodeGenerator::gen_assign]. pub fn gen_assign<'ctx, 'a, G: CodeGenerator>( generator: &mut G, ctx: &mut CodeGenContext<'ctx, 'a>, @@ -214,13 +217,21 @@ pub fn gen_assign<'ctx, 'a, G: CodeGenerator>( Ok(()) } -/// Generates a sequence of IR which checks whether [value] does not exceed the upper bound of the -/// range as defined by [stop] and [step]. +/// Generates a sequence of IR which checks whether `value` does not exceed the upper bound of the +/// range as defined by `stop` and `step`. /// /// Note that the generated IR will **not** check whether value is part of the range or whether /// value exceeds the lower bound of the range (as evident by the missing `start` argument). /// -/// Returns an [IntValue] representing the result of whether the [value] is in the range. +/// The generated IR is equivalent to the following Rust code: +/// +/// ```rust,ignore +/// let sign = step > 0; +/// let (lo, hi) = if sign { (value, stop) } else { (stop, value) }; +/// let cmp = lo < hi; +/// ``` +/// +/// Returns an `i1` [IntValue] representing the result of whether the `value` is in the range. fn gen_in_range_check<'ctx, 'a>( ctx: &CodeGenContext<'ctx, 'a>, value: IntValue<'ctx>, @@ -234,6 +245,7 @@ fn gen_in_range_check<'ctx, 'a>( ctx.builder.build_int_compare(IntPredicate::SLT, lo, hi, "cmp") } +/// See [CodeGenerator::gen_for]. pub fn gen_for<'ctx, 'a, G: CodeGenerator>( generator: &mut G, ctx: &mut CodeGenContext<'ctx, 'a>, @@ -384,6 +396,7 @@ pub fn gen_for<'ctx, 'a, G: CodeGenerator>( Ok(()) } +/// See [CodeGenerator::gen_while]. pub fn gen_while<'ctx, 'a, G: CodeGenerator>( generator: &mut G, ctx: &mut CodeGenContext<'ctx, 'a>, @@ -447,6 +460,7 @@ pub fn gen_while<'ctx, 'a, G: CodeGenerator>( Ok(()) } +/// See [CodeGenerator::gen_if]. pub fn gen_if<'ctx, 'a, G: CodeGenerator>( generator: &mut G, ctx: &mut CodeGenContext<'ctx, 'a>, @@ -535,6 +549,8 @@ pub fn final_proxy<'ctx, 'a>( final_paths.push(block); } +/// Inserts the declaration of the builtin function with the specified `symbol` name, and returns +/// the function. pub fn get_builtins<'ctx, 'a>( generator: &mut dyn CodeGenerator, ctx: &mut CodeGenContext<'ctx, 'a>, @@ -632,6 +648,10 @@ pub fn exn_constructor<'ctx, 'a>( Ok(Some(zelf.into())) } +/// Generates IR for a `raise` statement. +/// +/// * `exception` - The exception thrown by the `raise` statement. +/// * `loc` - The location where the exception is raised from. pub fn gen_raise<'ctx, 'a>( generator: &mut dyn CodeGenerator, ctx: &mut CodeGenContext<'ctx, 'a>, @@ -683,6 +703,7 @@ pub fn gen_raise<'ctx, 'a>( ctx.builder.build_unreachable(); } +/// Generates IR for a `try` statement. pub fn gen_try<'ctx, 'a, G: CodeGenerator>( generator: &mut G, ctx: &mut CodeGenContext<'ctx, 'a>, @@ -1005,6 +1026,7 @@ pub fn gen_try<'ctx, 'a, G: CodeGenerator>( } } +/// See [CodeGenerator::gen_with]. pub fn gen_with<'ctx, 'a, G: CodeGenerator>( _: &mut G, _: &mut CodeGenContext<'ctx, 'a>, @@ -1014,6 +1036,7 @@ pub fn gen_with<'ctx, 'a, G: CodeGenerator>( Err(format!("With statement with custom types is not yet supported (at {})", stmt.location)) } +/// Generates IR for a `return` statement. pub fn gen_return<'ctx, 'a, G: CodeGenerator>( generator: &mut G, ctx: &mut CodeGenContext<'ctx, 'a>, @@ -1062,6 +1085,7 @@ pub fn gen_return<'ctx, 'a, G: CodeGenerator>( Ok(()) } +/// See [CodeGenerator::gen_stmt]. pub fn gen_stmt<'ctx, 'a, G: CodeGenerator>( generator: &mut G, ctx: &mut CodeGenContext<'ctx, 'a>, @@ -1153,6 +1177,7 @@ pub fn gen_stmt<'ctx, 'a, G: CodeGenerator>( Ok(()) } +/// Generates IR for a block statement contains `stmts`. pub fn gen_block<'ctx, 'a, 'b, G: CodeGenerator, I: Iterator>>>( generator: &mut G, ctx: &mut CodeGenContext<'ctx, 'a>, diff --git a/nac3core/src/symbol_resolver.rs b/nac3core/src/symbol_resolver.rs index 6780163..cce05c4 100644 --- a/nac3core/src/symbol_resolver.rs +++ b/nac3core/src/symbol_resolver.rs @@ -59,6 +59,7 @@ impl Display for SymbolValue { } pub trait StaticValue { + /// Returns a unique identifier for this value. fn get_unique_identifier(&self) -> u64; fn get_const_obj<'ctx, 'a>( @@ -67,6 +68,7 @@ pub trait StaticValue { generator: &mut dyn CodeGenerator, ) -> BasicValueEnum<'ctx>; + /// Converts this value to a LLVM [BasicValueEnum]. fn to_basic_value_enum<'ctx, 'a>( &self, ctx: &mut CodeGenContext<'ctx, 'a>, @@ -74,12 +76,14 @@ pub trait StaticValue { expected_ty: Type, ) -> Result, String>; + /// Returns a field within this value. fn get_field<'ctx, 'a>( &self, name: StrRef, ctx: &mut CodeGenContext<'ctx, 'a>, ) -> Option>; + /// Returns a single element of this tuple. fn get_tuple_element<'ctx>(&self, index: u32) -> Option>; }