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 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 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_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],
) -> String
pub fn generate_function_with_lifetimes_and_structs( &self, func: &HirFunction, sig: &AnnotatedSignature, structs: &[HirStruct], ) -> String
Generate a complete function from HIR with lifetime annotations and struct definitions.
Takes the HIR function, its annotated signature, and struct definitions to generate Rust code with proper lifetime annotations and field type awareness for null pointer detection.
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
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