1use super::{
2 instructions::ClrInstruction,
3 pool::ClrConstantPool,
4 types::{
5 ClrAccessFlags, ClrAttribute, ClrExceptionHandler, ClrExternalAssembly, ClrField, ClrLocalVariable, ClrMethodImplFlags,
6 ClrModule, ClrParameter, ClrTypeReference, ClrVersion,
7 },
8};
9use gaia_types::{GaiaError, Result, SourceLocation};
10
11#[derive(Debug, Clone)]
13pub struct ClrProgram {
14 pub name: String,
16 pub version: ClrVersion,
18 pub access_flags: ClrAccessFlags,
20 pub external_assemblies: Vec<ClrExternalAssembly>,
22 pub module: Option<ClrModule>,
24 pub types: Vec<ClrType>,
26 pub global_methods: Vec<ClrMethod>,
28 pub global_fields: Vec<ClrField>,
30 pub attributes: Vec<ClrAttribute>,
32 pub constant_pool: ClrConstantPool,
34 pub source_file: Option<String>,
36}
37
38impl ClrProgram {
39 pub fn new(name: impl Into<String>) -> Self {
41 Self {
42 name: name.into(),
43 version: ClrVersion::default(),
44 access_flags: ClrAccessFlags::default(),
45 external_assemblies: Vec::new(),
46 module: None,
47 types: Vec::new(),
48 global_methods: Vec::new(),
49 global_fields: Vec::new(),
50 attributes: Vec::new(),
51 constant_pool: ClrConstantPool::new(),
52 source_file: None,
53 }
54 }
55
56 pub fn add_type(&mut self, clr_type: ClrType) {
58 self.types.push(clr_type);
59 }
60
61 pub fn add_global_method(&mut self, method: ClrMethod) {
63 self.global_methods.push(method);
64 }
65
66 pub fn add_global_field(&mut self, field: ClrField) {
68 self.global_fields.push(field);
69 }
70
71 pub fn add_external_assembly(&mut self, assembly: ClrExternalAssembly) {
73 self.external_assemblies.push(assembly);
74 }
75
76 pub fn validate(&self) -> Result<()> {
78 if self.name.is_empty() {
79 return Err(GaiaError::syntax_error("Assembly name cannot be empty".to_string(), SourceLocation::default()));
80 }
81
82 for clr_type in &self.types {
83 clr_type.validate()?;
84 }
85
86 for method in &self.global_methods {
87 method.validate()?;
88 }
89
90 Ok(())
91 }
92}
93
94#[derive(Debug, Clone)]
96pub struct ClrType {
97 pub name: String,
99 pub namespace: Option<String>,
101 pub access_flags: ClrAccessFlags,
103 pub base_type: Option<ClrTypeReference>,
105 pub interfaces: Vec<ClrTypeReference>,
107 pub fields: Vec<ClrField>,
109 pub methods: Vec<ClrMethod>,
111 pub properties: Vec<String>,
113 pub events: Vec<String>,
115 pub nested_types: Vec<ClrType>,
117 pub attributes: Vec<ClrAttribute>,
119}
120
121impl ClrType {
122 pub fn new(name: String, namespace: Option<String>) -> Self {
124 Self {
125 name,
126 namespace,
127 access_flags: ClrAccessFlags::default(),
128 base_type: None,
129 interfaces: Vec::new(),
130 fields: Vec::new(),
131 methods: Vec::new(),
132 properties: Vec::new(),
133 events: Vec::new(),
134 nested_types: Vec::new(),
135 attributes: Vec::new(),
136 }
137 }
138
139 pub fn add_method(&mut self, method: ClrMethod) {
141 self.methods.push(method);
142 }
143
144 pub fn add_field(&mut self, field: ClrField) {
146 self.fields.push(field);
147 }
148
149 pub fn validate(&self) -> Result<()> {
151 if self.name.is_empty() {
152 return Err(GaiaError::syntax_error("Type name cannot be empty".to_string(), SourceLocation::default()));
153 }
154
155 for method in &self.methods {
156 method.validate()?;
157 }
158
159 Ok(())
160 }
161}
162
163#[derive(Debug, Clone)]
165pub struct ClrMethod {
166 pub name: String,
168 pub return_type: ClrTypeReference,
170 pub parameters: Vec<ClrParameter>,
172 pub access_flags: ClrAccessFlags,
174 pub impl_flags: ClrMethodImplFlags,
176 pub instructions: Vec<ClrInstruction>,
178 pub max_stack: u32,
180 pub locals: Vec<ClrLocalVariable>,
182 pub exception_handlers: Vec<ClrExceptionHandler>,
184 pub attributes: Vec<ClrAttribute>,
186 pub is_entry_point: bool,
188}
189
190impl ClrMethod {
191 pub fn new(name: String, return_type: ClrTypeReference) -> Self {
193 Self {
194 name,
195 return_type,
196 parameters: Vec::new(),
197 access_flags: ClrAccessFlags::default(),
198 impl_flags: ClrMethodImplFlags::default(),
199 instructions: Vec::new(),
200 max_stack: 8,
201 locals: Vec::new(),
202 exception_handlers: Vec::new(),
203 attributes: Vec::new(),
204 is_entry_point: false,
205 }
206 }
207
208 pub fn add_instruction(&mut self, instruction: ClrInstruction) {
210 self.instructions.push(instruction);
211 }
212
213 pub fn add_parameter(&mut self, parameter: ClrParameter) {
215 self.parameters.push(parameter);
216 }
217
218 pub fn validate(&self) -> Result<()> {
220 if self.name.is_empty() {
221 return Err(GaiaError::syntax_error("Method name cannot be empty".to_string(), SourceLocation::default()));
222 }
223
224 Ok(())
225 }
226}