pub struct CodeGenerator { /* private fields */ }Expand description
Code generator for converting HIR to Rust source code.
Implementations§
Source§impl CodeGenerator
impl CodeGenerator
Sourcepub fn new() -> Self
pub fn new() -> Self
Create a new code generator.
§Examples
use decy_codegen::CodeGenerator;
let codegen = CodeGenerator::new();Sourcepub fn generate_macro(&self, macro_def: &HirMacroDefinition) -> Result<String>
pub fn generate_macro(&self, macro_def: &HirMacroDefinition) -> Result<String>
Generate Rust code for a macro definition.
Transforms C #define macros to Rust const declarations (for object-like macros) or inline functions (for function-like macros).
§Supported Macro Types (DECY-098c)
Object-like macros (constants) are fully supported:
#define MAX 100→const MAX: i32 = 100;#define PI 3.14159→const PI: f64 = 3.14159;#define GREETING "Hello"→const GREETING: &str = "Hello";
Function-like macros are not yet supported (DECY-098d):
#define SQR(x) ((x) * (x))→ Error
§Type Inference
Types are automatically inferred from the macro body:
- String literals →
&str - Character literals →
char - Floating point →
f64 - Integers (including hex/octal) →
i32
§Edge Cases
- Empty macros generate comments:
#define EMPTY→// Empty macro: EMPTY - Macro names are preserved exactly (SCREAMING_SNAKE_CASE maintained)
§Errors
Returns an error if:
- The macro is function-like (not yet implemented)
§Examples
use decy_codegen::CodeGenerator;
use decy_hir::HirMacroDefinition;
let generator = CodeGenerator::new();
let macro_def = HirMacroDefinition::new_object_like("MAX".to_string(), "100".to_string());
let rust_code = generator.generate_macro(¯o_def).unwrap();
assert!(rust_code.contains("const MAX"));§Reference
- K&R §4.11: Macro Substitution
- ISO C99 §6.10.3: Macro replacement
Sourcepub fn box_transformer(&self) -> &BoxTransformer
pub fn box_transformer(&self) -> &BoxTransformer
Get the Box transformer.
Sourcepub fn map_type(hir_type: &HirType) -> String
pub fn map_type(hir_type: &HirType) -> String
Map HIR type to Rust type string.
§Examples
use decy_codegen::CodeGenerator;
use decy_hir::HirType;
assert_eq!(CodeGenerator::map_type(&HirType::Int), "i32");
assert_eq!(CodeGenerator::map_type(&HirType::Float), "f32");
assert_eq!(CodeGenerator::map_type(&HirType::Box(Box::new(HirType::Int))), "Box<i32>");Sourcepub fn generate_expression(&self, expr: &HirExpression) -> String
pub fn generate_expression(&self, expr: &HirExpression) -> String
Generate code for an expression.
Sourcepub fn generate_statement(&self, stmt: &HirStatement) -> String
pub fn generate_statement(&self, stmt: &HirStatement) -> String
Generate code for a statement.
Sourcepub fn generate_signature(&self, func: &HirFunction) -> String
pub fn generate_signature(&self, func: &HirFunction) -> String
Generate a function signature from HIR.
§Examples
use decy_codegen::CodeGenerator;
use decy_hir::{HirFunction, HirType};
let func = HirFunction::new("test".to_string(), HirType::Void, vec![]);
let codegen = CodeGenerator::new();
let sig = codegen.generate_signature(&func);
assert_eq!(sig, "fn test()");Sourcepub fn get_string_iteration_params(
&self,
func: &HirFunction,
) -> Vec<(usize, bool)>
pub fn get_string_iteration_params( &self, func: &HirFunction, ) -> Vec<(usize, bool)>
DECY-134b: Get all string iteration params for a function.
Returns a list of (param_index, is_mutable) for each char* param that uses pointer arithmetic. Used by decy-core to build string_iter_funcs info for call site transformation.
Sourcepub fn generate_annotated_signature(&self, sig: &AnnotatedSignature) -> String
pub fn generate_annotated_signature(&self, sig: &AnnotatedSignature) -> String
Generate a function signature with lifetime annotations.
Takes an AnnotatedSignature with lifetime information and generates
the complete Rust function signature including lifetime parameters.
§Examples
use decy_codegen::CodeGenerator;
use decy_ownership::lifetime_gen::{AnnotatedSignature, AnnotatedParameter, AnnotatedType, LifetimeParam};
use decy_hir::HirType;
let sig = AnnotatedSignature {
name: "get_first".to_string(),
lifetimes: vec![LifetimeParam::standard(0)], // 'a
parameters: vec![
AnnotatedParameter {
name: "items".to_string(),
param_type: AnnotatedType::Reference {
inner: Box::new(AnnotatedType::Simple(HirType::Int)),
mutable: false,
lifetime: Some(LifetimeParam::standard(0)),
},
},
],
return_type: AnnotatedType::Reference {
inner: Box::new(AnnotatedType::Simple(HirType::Int)),
mutable: false,
lifetime: Some(LifetimeParam::standard(0)),
},
};
let codegen = CodeGenerator::new();
let rust_sig = codegen.generate_annotated_signature(&sig);
assert!(rust_sig.contains("<'a>"));
assert!(rust_sig.contains("&'a i32"));Sourcepub fn generate_annotated_signature_with_func(
&self,
sig: &AnnotatedSignature,
func: Option<&HirFunction>,
) -> String
pub fn generate_annotated_signature_with_func( &self, sig: &AnnotatedSignature, func: Option<&HirFunction>, ) -> String
Generate a function signature from an annotated signature with optional function body access.
When func is provided, pointer arithmetic detection is enabled (DECY-123).
DECY-084: Also detects output parameters for transformation to return values.
Sourcepub fn annotated_type_to_string(&self, annotated_type: &AnnotatedType) -> String
pub fn annotated_type_to_string(&self, annotated_type: &AnnotatedType) -> String
Convert an AnnotatedType to Rust type string with lifetime annotations.
§Examples
use decy_codegen::CodeGenerator;
use decy_ownership::lifetime_gen::{AnnotatedType, LifetimeParam};
use decy_hir::HirType;
let codegen = CodeGenerator::new();
// Simple type
let simple = AnnotatedType::Simple(HirType::Int);
assert_eq!(codegen.annotated_type_to_string(&simple), "i32");
// Reference with lifetime
let ref_type = AnnotatedType::Reference {
inner: Box::new(AnnotatedType::Simple(HirType::Int)),
mutable: false,
lifetime: Some(LifetimeParam::standard(0)),
};
assert_eq!(codegen.annotated_type_to_string(&ref_type), "&'a i32");Sourcepub fn generate_return(&self, return_type: &HirType) -> String
pub fn generate_return(&self, return_type: &HirType) -> String
Generate a default return statement for a type.
§Examples
use decy_codegen::CodeGenerator;
use decy_hir::HirType;
let codegen = CodeGenerator::new();
assert!(codegen.generate_return(&HirType::Int).contains("return 0"));Sourcepub fn generate_function(&self, func: &HirFunction) -> String
pub fn generate_function(&self, func: &HirFunction) -> String
Generate a complete function from HIR.
§Examples
use decy_codegen::CodeGenerator;
use decy_hir::{HirFunction, HirType, HirParameter};
let func = HirFunction::new(
"add".to_string(),
HirType::Int,
vec![
HirParameter::new("a".to_string(), HirType::Int),
HirParameter::new("b".to_string(), HirType::Int),
],
);
let codegen = CodeGenerator::new();
let code = codegen.generate_function(&func);
assert!(code.contains("fn add(mut a: i32, mut b: i32) -> i32"));
assert!(code.contains("{"));
assert!(code.contains("}"));Sourcepub fn generate_function_with_structs(
&self,
func: &HirFunction,
structs: &[HirStruct],
) -> String
pub fn generate_function_with_structs( &self, func: &HirFunction, structs: &[HirStruct], ) -> String
Generate a complete function from HIR with struct definitions for type inference.
This is useful for testing when struct fields need proper type inference. DECY-165: Enables proper raw pointer detection for struct field access.
Sourcepub fn generate_function_with_lifetimes(
&self,
func: &HirFunction,
sig: &AnnotatedSignature,
) -> String
pub fn generate_function_with_lifetimes( &self, func: &HirFunction, sig: &AnnotatedSignature, ) -> String
Generate a complete function from HIR with lifetime annotations.
Takes both the HIR function and its annotated signature to generate Rust code with proper lifetime annotations.
§Examples
use decy_codegen::CodeGenerator;
use decy_hir::{HirFunction, HirType, HirParameter};
use decy_ownership::lifetime_gen::{AnnotatedSignature, AnnotatedParameter, AnnotatedType, LifetimeParam};
let func = HirFunction::new(
"identity".to_string(),
HirType::Reference {
inner: Box::new(HirType::Int),
mutable: false,
},
vec![
HirParameter::new("x".to_string(), HirType::Reference {
inner: Box::new(HirType::Int),
mutable: false,
}),
],
);
let sig = AnnotatedSignature {
name: "identity".to_string(),
lifetimes: vec![LifetimeParam::standard(0)],
parameters: vec![
AnnotatedParameter {
name: "x".to_string(),
param_type: AnnotatedType::Reference {
inner: Box::new(AnnotatedType::Simple(HirType::Int)),
mutable: false,
lifetime: Some(LifetimeParam::standard(0)),
},
},
],
return_type: AnnotatedType::Reference {
inner: Box::new(AnnotatedType::Simple(HirType::Int)),
mutable: false,
lifetime: Some(LifetimeParam::standard(0)),
},
};
let codegen = CodeGenerator::new();
let code = codegen.generate_function_with_lifetimes(&func, &sig);
assert!(code.contains("<'a>"));
assert!(code.contains("&'a i32"));Sourcepub fn generate_function_with_lifetimes_and_structs(
&self,
func: &HirFunction,
sig: &AnnotatedSignature,
structs: &[HirStruct],
all_functions: &[(String, Vec<HirType>)],
slice_func_args: &[(String, Vec<(usize, usize)>)],
string_iter_funcs: &[(String, Vec<(usize, bool)>)],
) -> String
pub fn generate_function_with_lifetimes_and_structs( &self, func: &HirFunction, sig: &AnnotatedSignature, structs: &[HirStruct], all_functions: &[(String, Vec<HirType>)], slice_func_args: &[(String, Vec<(usize, usize)>)], string_iter_funcs: &[(String, Vec<(usize, bool)>)], ) -> String
Generate a complete function from HIR with lifetime annotations and struct definitions.
Takes the HIR function, its annotated signature, struct definitions, and all function signatures for call site reference mutability.
§Arguments
func- The HIR function to generatesig- The annotated signature with lifetime annotationsstructs- Struct definitions for field type awarenessall_functions- All function signatures for DECY-117 call site mutabilityslice_func_args- DECY-116: func_name -> [(array_idx, len_idx)] for call site transformationstring_iter_funcs- DECY-134b: func_name -> [(param_idx, is_mutable)] for string iteration
Sourcepub fn generate_function_with_box_transform(
&self,
func: &HirFunction,
candidates: &[BoxCandidate],
) -> String
pub fn generate_function_with_box_transform( &self, func: &HirFunction, candidates: &[BoxCandidate], ) -> String
Generate a function with Box transformations applied.
This method analyzes the function for malloc/free patterns and
transforms them into safe Box::new() expressions.
§Examples
use decy_codegen::CodeGenerator;
use decy_hir::{HirFunction, HirType, HirStatement, HirExpression};
use decy_analyzer::patterns::PatternDetector;
let func = HirFunction::new_with_body(
"test".to_string(),
HirType::Void,
vec![],
vec![
HirStatement::VariableDeclaration {
name: "ptr".to_string(),
var_type: HirType::Pointer(Box::new(HirType::Int)),
initializer: Some(HirExpression::FunctionCall {
function: "malloc".to_string(),
arguments: vec![HirExpression::IntLiteral(100)],
}),
},
],
);
let codegen = CodeGenerator::new();
let detector = PatternDetector::new();
let candidates = detector.find_box_candidates(&func);
let code = codegen.generate_function_with_box_transform(&func, &candidates);
assert!(code.contains("Box::new"));Sourcepub fn generate_function_with_vec_transform(
&self,
func: &HirFunction,
candidates: &[VecCandidate],
) -> String
pub fn generate_function_with_vec_transform( &self, func: &HirFunction, candidates: &[VecCandidate], ) -> String
Generate a function with Vec transformations applied.
This method analyzes the function for malloc(n * sizeof(T)) patterns and
transforms them into safe Vec::with_capacity(n) expressions.
Sourcepub fn generate_function_with_box_and_vec_transform(
&self,
func: &HirFunction,
box_candidates: &[BoxCandidate],
vec_candidates: &[VecCandidate],
) -> String
pub fn generate_function_with_box_and_vec_transform( &self, func: &HirFunction, box_candidates: &[BoxCandidate], vec_candidates: &[VecCandidate], ) -> String
Generate a function with both Box and Vec transformations applied.
This method combines both Box and Vec transformations, applying them to their respective patterns.
Sourcepub fn generate_struct(&self, hir_struct: &HirStruct) -> String
pub fn generate_struct(&self, hir_struct: &HirStruct) -> String
Generate a struct definition from HIR.
Generates Rust struct code with automatic derives for Debug, Clone, PartialEq, Eq. Handles lifetimes automatically for structs with reference fields.
Sourcepub fn generate_enum(&self, hir_enum: &HirEnum) -> String
pub fn generate_enum(&self, hir_enum: &HirEnum) -> String
Generate an enum definition from HIR.
Generates Rust enum code with automatic derives for Debug, Clone, Copy, PartialEq, Eq. Supports both simple enums and enums with explicit integer values.
Sourcepub fn generate_typedef(&self, typedef: &HirTypedef) -> Result<String>
pub fn generate_typedef(&self, typedef: &HirTypedef) -> Result<String>
Generate a typedef (type alias) from HIR.
Generates Rust type alias code using the type keyword.
Handles redundant typedefs (where name matches underlying struct/enum name) as comments.
§Examples
use decy_codegen::CodeGenerator;
use decy_hir::{HirTypedef, HirType};
let codegen = CodeGenerator::new();
// Simple typedef: typedef int Integer;
let typedef = HirTypedef::new("Integer".to_string(), HirType::Int);
let code = codegen.generate_typedef(&typedef).unwrap();
assert!(code.contains("type Integer = i32"));
// Pointer typedef: typedef int* IntPtr;
let typedef = HirTypedef::new("IntPtr".to_string(), HirType::Pointer(Box::new(HirType::Int)));
let code = codegen.generate_typedef(&typedef).unwrap();
assert!(code.contains("type IntPtr = *mut i32"));Sourcepub fn generate_constant(&self, constant: &HirConstant) -> String
pub fn generate_constant(&self, constant: &HirConstant) -> String
Generate a constant declaration from HIR.
Transforms C #define macro constants to Rust const declarations.
C #define constants are compile-time text substitutions that map naturally
to Rust’s const with compile-time evaluation.
§Examples
use decy_codegen::CodeGenerator;
use decy_hir::{HirConstant, HirType, HirExpression};
let codegen = CodeGenerator::new();
// Integer constant: #define MAX 100 → const MAX: i32 = 100;
let constant = HirConstant::new(
"MAX".to_string(),
HirType::Int,
HirExpression::IntLiteral(100),
);
let code = codegen.generate_constant(&constant);
assert!(code.contains("const MAX: i32 = 100"));
// String constant: #define MSG "Hello" → const MSG: &str = "Hello";
let constant = HirConstant::new(
"MSG".to_string(),
HirType::Pointer(Box::new(HirType::Char)),
HirExpression::StringLiteral("Hello".to_string()),
);
let code = codegen.generate_constant(&constant);
assert!(code.contains("const MSG: &str = \"Hello\""));§Safety
This transformation introduces 0 unsafe blocks, maintaining the goal of <5 unsafe blocks per 1000 LOC.
Reference: K&R §4.11, ISO C99 §6.10.3
Sourcepub fn generate_global_variable(
&self,
variable: &HirConstant,
_is_static: bool,
is_extern: bool,
is_const: bool,
) -> String
pub fn generate_global_variable( &self, variable: &HirConstant, _is_static: bool, is_extern: bool, is_const: bool, ) -> String
Generate a global variable declaration with storage class specifiers.
Transforms C global variables with storage classes to appropriate Rust declarations:
static→static mut(mutable static)extern→extern "C" { static }const→conststatic const→const(const is stronger than static)- Plain global →
static mut(default to mutable)
§Examples
use decy_codegen::CodeGenerator;
use decy_hir::{HirConstant, HirType, HirExpression};
let codegen = CodeGenerator::new();
// static int counter = 0; → static mut counter: i32 = 0;
let global = HirConstant::new(
"counter".to_string(),
HirType::Int,
HirExpression::IntLiteral(0),
);
let code = codegen.generate_global_variable(&global, true, false, false);
assert!(code.contains("static mut counter: i32 = 0"));§Arguments
variable- The HIR constant representing the global variableis_static- Whether the variable hasstaticstorage classis_extern- Whether the variable hasexternstorage classis_const- Whether the variable hasconstqualifier
§Safety
Note: static mut in Rust requires unsafe blocks to access, which increases
unsafe usage. However, this is necessary to preserve C semantics for mutable globals.
Reference: ISO C99 §6.7.1 (Storage-class specifiers), K&R §4.2
Trait Implementations§
Source§impl Clone for CodeGenerator
impl Clone for CodeGenerator
Source§fn clone(&self) -> CodeGenerator
fn clone(&self) -> CodeGenerator
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more