clr_assembler/program/
builder.rs1use crate::program::*;
2
3#[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, };
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}