1use core::fmt;
2use enum_as_inner::EnumAsInner;
3
4pub mod attribute;
5pub mod case;
6pub mod r#enum;
7pub mod expression;
8pub mod function;
9pub mod identifier;
10pub mod if_statement;
11pub mod r#impl;
12pub mod loop_statement;
13pub mod module;
14pub mod return_statement;
15pub mod scope;
16pub mod statement;
17pub mod r#struct;
18pub mod switch_statement;
19pub mod r#trait;
20pub mod r#type;
21pub mod r#unsafe;
22pub mod variable_assignment;
23pub mod variable_definition;
24pub mod while_statement;
25
26#[derive(Debug, Clone, EnumAsInner, Default)]
28pub enum Visibility {
29 Public,
30 #[default]
31 Private,
32}
33impl fmt::Display for Visibility {
34 fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
35 if self.is_private() {
36 match write!(fmt, "private") {
37 Ok(_) => (),
38 Err(e) => return Err(e),
39 }
40 } else if self.is_public() {
41 match write!(fmt, "public") {
42 Ok(_) => (),
43 Err(e) => return Err(e),
44 }
45 }
46 Ok(())
47 }
48}
49
50#[cfg(test)]
51mod tests {
52 use core::panic;
53 use std::{thread::Scope, vec};
54
55 use galvanic_test::test_suite;
56
57 use crate::{
58 Visibility, attribute::Attribute, expression::UnaryOperation, identifier::IdentifierAccess,
59 loop_statement::LoopStatement, module::Module, statement, r#type::Type,
60 };
61
62 test_suite! {
63 name attribute;
64 use crate::attribute::Attribute;
65
66 test attribute_test() {
67 let attribute = Attribute::new("attribute");
68 assert!(attribute.to_string() == "#[attribute]\n");
69 }
70
71 test attribute_test_with_value() {
72 let mut attribute = Attribute::new("attribute");
73 attribute.value = Some(String::from("value"));
74 assert!(attribute.to_string() == "#[attribute(value)]\n");
75 }
76 }
77
78 test_suite! {
79 name case;
80 use crate::{expression::{Expression, IntegerLiteral}, case::Case, scope::Scope};
81
82 test case_test() {
83 let case = Case::new(
84 Expression::IntegerLiteral(IntegerLiteral::new(0)),
85 Scope::new(),
86 );
87 assert!(case.to_string() == "case 0 {\n}");
88 }
89 }
90
91 test_suite! {
92 name r#enum;
93 use crate::{r#enum::Enum, Visibility};
94
95 test private_enum_test() {
96 let enu = Enum::new("test".to_string());
97 assert!(enu.to_string() == "private enum test {}");
98 }
99
100 test public_enum_test() {
101 let mut enu = Enum::new("test".to_string());
102 enu.visibility = Visibility::Public;
103 assert!(enu.to_string() == "public enum test {}");
104 }
105 }
106
107 test_suite! {
108 name expressions;
109 use crate::{expression::{Expression, IntegerLiteral, FloatLiteral, StringLiteral, BooleanLiteral, Parentheses, UnaryOperation, BinaryOperation}};
110
111 test integer_literal_test() {
112 let int = IntegerLiteral::new(10);
113 assert!(int.to_string() == "10");
114 }
115
116 test float_literal_test() {
117 let float = FloatLiteral::new(1.0);
118 assert!(float.to_string() == "1");
119 }
120
121 test string_literal_test() {
122 let string = StringLiteral::new("Hello World!".to_string());
123 assert!(string.to_string() == "\"Hello World!\"");
124 }
125
126 test boolean_literal_test() {
127 let bol = BooleanLiteral::new(true);
128 assert!(bol.to_string() == "true");
129 }
130
131 test parentheses_test() {
132 let par = Parentheses::new(Expression::IntegerLiteral(IntegerLiteral::new(12)));
133 assert!(par.to_string() == "(12)");
134 }
135
136 test unary_operation_test() {
137 let una = UnaryOperation::new("-".to_string(), Expression::IntegerLiteral(IntegerLiteral::new(42)));
138 assert!(una.to_string() == "-42");
139 }
140
141 test binary_operation_test() {
142 let bin = BinaryOperation::new(Expression::IntegerLiteral(IntegerLiteral::new(2)), "+".to_string(), Expression::IntegerLiteral(IntegerLiteral::new(2)));
143 assert!(bin.to_string() == "2 + 2");
144 }
145 }
146
147 test_suite! {
148 name function;
149 use crate::{Visibility, function::Function, r#type::{Type, TypeType}, identifier::{Access, IdentifierAccess}, statement::Statement, scope::Scope};
150
151 test public_function() {
152 let mut func = Function::new("test".to_string(), Type::new(IdentifierAccess::Access(Access::new("void".to_string())), TypeType::Normal), Statement::Scope(Scope::new()));
153 func.visibility = Visibility::Public;
154 assert!(func.to_string() == "public fn test() -> void {\n}");
155 }
156
157 test private_function() {
158 let func = Function::new("test".to_string(), Type::new(IdentifierAccess::Access(Access::new("void".to_string())), TypeType::Normal), Statement::Scope(Scope::new()));
159 assert!(func.to_string() == "private fn test() -> void {\n}");
160 }
161 }
162
163 test_suite! {
164 name identifier;
165 use crate::{identifier::{IdentifierAccess, Access, FunctionCall}, expression::{Expression, BinaryOperation, IntegerLiteral}};
166
167 test access() {
168 let ident = Access::new("identifier".to_string());
169 assert!(ident.to_string() == "identifier");
170 }
171
172 test function_call() {
173 let mut ident = FunctionCall::new("func".to_string(), vec![]);
174 ident.arguments.push(Expression::BinaryOperation(BinaryOperation::new(Expression::IntegerLiteral(IntegerLiteral::new(2)), "+".to_string(), Expression::IntegerLiteral(IntegerLiteral::new(2)))));
175 assert!(ident.to_string() == "func(2 + 2)");
176 }
177
178 test access_and_deref() {
179 let mut ident = Access::new("one".to_string());
180 ident.child = Some(Box::new(IdentifierAccess::DerefAccess(Access::new("two".to_string()))));
181 assert!(ident.to_string() == "one->two")
182 }
183 }
184
185 test_suite! {
186 name if_statement;
187 use crate::{if_statement::IfStatement, expression::{Expression, BooleanLiteral}, scope::Scope, statement::Statement};
188
189 test if_statement() {
190 let statement = IfStatement::new(Expression::BooleanLiteral(BooleanLiteral::new(true)), Statement::Scope(Scope::new()));
191 assert!(statement.to_string() == "if (true) {\n}")
192 }
193
194 test else_statement() {
195 let mut statement = IfStatement::new(Expression::BooleanLiteral(BooleanLiteral::new(true)), Statement::Scope(Scope::new()));
196 statement.else_body = Some(Box::new(Statement::Scope(Scope::new())));
197 assert!(statement.to_string() == "if (true) {\n}\nelse {\n}")
198 }
199 }
200
201 test_suite! {
202 name r#impl;
203 use crate::{r#impl::Impl, r#type::{Type, TypeType}, identifier::{IdentifierAccess, Access}, r#trait::Trait};
204
205 test r#impl() {
206 let imp = Impl::new(Type::new(IdentifierAccess::Access(Access::new("Test".to_string())), TypeType::Normal));
207 assert!(imp.to_string() == "impliment Test {\n}");
208 }
209
210 test impl_for() {
211 let mut imp = Impl::new(Type::new(IdentifierAccess::Access(Access::new("Test".to_string())), TypeType::Normal));
212 imp.r#trait = Some(Type::new(IdentifierAccess::Access(Access::new("Treat".to_string())), TypeType::Normal));
213 assert!(imp.to_string() == "impliment Treat for Test {\n}");
214 }
215 }
216
217 test_suite! {
218 name loop_statement;
219 use crate::{loop_statement::LoopStatement, statement::Statement, scope::Scope};
220
221 test loop_statement() {
222 let lop = LoopStatement::new(Statement::Scope(Scope::new()));
223 assert!(lop.to_string() == "loop {\n}")
224 }
225 }
226
227 test_suite! {
228 name module;
229 use crate::{module::{Module, ModuleItem}, Visibility};
230
231 test public_module() {
232 let mut modu = Module::new("test".to_string());
233 modu.visibility = Visibility::Public;
234 assert!(modu.to_string() == "public module test {}");
235 }
236
237 test private_module() {
238 let modu = Module::new("test".to_string());
239 assert!(modu.to_string() == "private module test {}");
240 }
241 }
242
243 test_suite! {
244 name return_statement;
245 use crate::{return_statement::ReturnStatement, expression::{Expression, IntegerLiteral}};
246
247 test return_no_value() {
248 let ret = ReturnStatement::new();
249 assert!(ret.to_string() == "return;");
250 }
251
252 test return_value() {
253 let mut ret = ReturnStatement::new();
254 ret.value = Some(Expression::IntegerLiteral(IntegerLiteral::new(0)));
255 assert!(ret.to_string() == "return 0;");
256 }
257 }
258
259 test_suite! {
260 name scope;
261 use crate::scope::Scope;
262
263 test scope_test() {
264 let scope = Scope::new();
265 assert!(scope.to_string() == "{\n}");
266 }
267 }
268
269 test_suite! {
270 name r#struct;
271 use crate::{Visibility, r#struct::Struct, r#type::{Type, TypeType}, identifier::{IdentifierAccess, Access}};
272
273 test public_struct() {
274 let mut struc = Struct::new(Type::new(IdentifierAccess::Access(Access::new("Test".to_string())), TypeType::Normal));
275 struc.visibility = Visibility::Public;
276 assert!(struc.to_string() == "public struct Test {\n}");
277 }
278
279 test private_struct() {
280 let struc = Struct::new(Type::new(IdentifierAccess::Access(Access::new("Test".to_string())), TypeType::Normal));
281 assert!(struc.to_string() == "private struct Test {\n}");
282 }
283 }
284
285 test_suite! {
286 name switch_statement;
287 use crate::{switch_statement::SwitchStatement, expression::{Expression, IntegerLiteral}};
288
289 test switch_statement() {
290 let statement = SwitchStatement::new(Expression::IntegerLiteral(IntegerLiteral::new(0)));
291 assert!(statement.to_string() == "switch (0) {\n}")
292 }
293 }
294
295 test_suite! {
296 name r#trait;
297 use crate::{r#trait::Trait, r#type::{Type, TypeType}, identifier::{IdentifierAccess, Access}, Visibility};
298
299 test public_trait() {
300 let mut trai = Trait::new(Type::new(IdentifierAccess::Access(Access::new("Trait".to_string())), TypeType::Normal));
301 trai.visibility = Visibility::Public;
302 assert!(trai.to_string() == "public trait Trait {\n}");
303 }
304
305 test private_trait() {
306 let trai = Trait::new(Type::new(IdentifierAccess::Access(Access::new("Trait".to_string())), TypeType::Normal));
307 assert!(trai.to_string() == "private trait Trait {\n}");
308 }
309 }
310
311 test_suite! {
312 name r#type;
313 use crate::{r#type::{Type, TypeType}, identifier::{IdentifierAccess, Access}};
314
315 test r#type() {
316 let typ = Type::new(IdentifierAccess::Access(Access::new("Type".to_string())), TypeType::Normal);
317 assert!(typ.to_string() == "Type")
318 }
319
320 test generic_type() {
321 let mut typ = Type::new(IdentifierAccess::Access(Access::new("Type".to_string())), TypeType::Normal);
322 typ.generic_child = Some(Box::new(Type::new(IdentifierAccess::Access(Access::new("Type".to_string())), TypeType::Normal)));
323 assert!(typ.to_string() == "Type<Type>")
324 }
325 }
326
327 test_suite! {
328 name r#unsafe;
329 use crate::{r#unsafe::Unsafe, scope::Scope, statement::Statement};
330
331 test r#unsafe() {
332 let unsaf = Unsafe::new(Statement::Scope(Scope::new()));
333 assert!(unsaf.to_string() == "unsafe {\n}");
334 }
335 }
336
337 test_suite! {
338 name variable_assignment;
339 use crate::{variable_assignment::VariableAssignment, identifier::{IdentifierAccess, Access}, expression::{Expression, IntegerLiteral}};
340
341 test variable_assignment() {
342 let var_ass = VariableAssignment::new(IdentifierAccess::Access(Access::new("x".to_string())), "=".to_string(), Expression::IntegerLiteral(IntegerLiteral::new(0)));
343 assert!(var_ass.to_string() == "x = 0")
344 }
345 }
346
347 test_suite! {
348 name variable_definition;
349 use crate::{variable_definition::VariableDefinition, r#type::{Type, TypeType}, identifier::{IdentifierAccess, Access}};
350
351 test variable_definition() {
352 let mut var_def = VariableDefinition::new("variable".to_string());
353 var_def.ty = Some(Type::new(IdentifierAccess::Access(Access::new("i32".to_string())), TypeType::Normal));
354 assert!(var_def.to_string() == "let variable: i32");
355 }
356 }
357
358 test_suite! {
359 name while_statement;
360 use crate::{statement::Statement, while_statement::WhileStatement, scope::Scope, expression::{Expression, BooleanLiteral}};
361
362 test while_statement() {
363 let statement = WhileStatement::new(Expression::BooleanLiteral(BooleanLiteral::new(true)), Statement::Scope(Scope::new()));
364 assert!(statement.to_string() == "while (true) {\n}");
365 }
366 }
367}