Skip to main content

clr_assembler/program/
builder.rs

1use crate::program::*;
2
3/// CLR 程序构建器,简化 ClrProgram 的构建过程
4#[derive(Debug)]
5pub struct ClrBuilder {
6    program: ClrProgram,
7    current_type: Option<usize>,
8    current_method: Option<usize>,
9}
10
11impl ClrBuilder {
12    pub fn new(name: String) -> Self {
13        Self {
14            program: ClrProgram {
15                name,
16                version: ClrVersion { major: 1, minor: 0, build: 0, revision: 0 },
17                access_flags: ClrAccessFlags::default(),
18                external_assemblies: Vec::new(),
19                module: None,
20                types: Vec::new(),
21                global_methods: Vec::new(),
22                global_fields: Vec::new(),
23                attributes: Vec::new(),
24                constant_pool: ClrConstantPool::new(),
25                source_file: None,
26            },
27            current_type: None,
28            current_method: None,
29        }
30    }
31
32    pub fn add_external_assembly(&mut self, name: String) {
33        self.program.external_assemblies.push(ClrExternalAssembly {
34            name,
35            version: ClrVersion { major: 4, minor: 0, build: 0, revision: 0 },
36            public_key_token: None,
37            culture: None,
38            hash_value: None,
39        });
40    }
41
42    pub fn begin_class(&mut self, name: String, namespace: Option<String>) {
43        let clr_type = ClrType::new(name, namespace);
44        self.program.types.push(clr_type);
45        self.current_type = Some(self.program.types.len() - 1);
46        self.current_method = None;
47    }
48
49    pub fn begin_method(&mut self, name: String, return_type: ClrTypeReference) {
50        let method = ClrMethod::new(name, return_type);
51        if let Some(type_idx) = self.current_type {
52            self.program.types[type_idx].methods.push(method);
53            self.current_method = Some(self.program.types[type_idx].methods.len() - 1);
54        }
55        else {
56            self.program.global_methods.push(method);
57            self.current_method = Some(self.program.global_methods.len() - 1);
58        }
59    }
60
61    pub fn emit(&mut self, opcode: ClrOpcode, operand: Option<ClrInstructionOperand>) {
62        let inst = ClrInstruction {
63            opcode,
64            operand,
65            offset: 0, // 偏移量通常由后续的二进制编码器计算
66        };
67
68        if let Some(type_idx) = self.current_type {
69            if let Some(method_idx) = self.current_method {
70                self.program.types[type_idx].methods[method_idx].instructions.push(inst);
71            }
72        }
73        else if let Some(method_idx) = self.current_method {
74            self.program.global_methods[method_idx].instructions.push(inst);
75        }
76    }
77
78    pub fn finish(self) -> ClrProgram {
79        self.program
80    }
81}