diff --git a/crates/codegen/src/fmt/mod.rs b/crates/codegen/src/fmt/mod.rs index ee01eae..abce1a4 100644 --- a/crates/codegen/src/fmt/mod.rs +++ b/crates/codegen/src/fmt/mod.rs @@ -46,6 +46,13 @@ impl MistCodegen { self.add(&line); } + pub fn start_bracket(&mut self) { + self.addln(""); + self.add_indentedln("{"); + + self.indent += 1; + } + pub fn into_output(self) -> String { self.output } diff --git a/crates/codegen/src/fmt/top_level.rs b/crates/codegen/src/fmt/top_level.rs index 99c299e..60923e0 100644 --- a/crates/codegen/src/fmt/top_level.rs +++ b/crates/codegen/src/fmt/top_level.rs @@ -17,8 +17,7 @@ impl GenMist for ImplDecl { cg.add(&self.target.get_mist()); - cg.addln(" {"); - cg.indent += 1; + cg.start_bracket(); for method in &self.methods { method.gen_mist(ctx, cg); @@ -79,7 +78,8 @@ impl GenMist for FunctionDecl { } if let Some(body) = &self.body { - cg.add(" "); + cg.addln(""); + cg.add_indented(""); body.gen_mist(ctx, cg); cg.addln(""); } else { @@ -183,22 +183,25 @@ impl GenMist for TopLevelKind { fields, } => { cg.add(&format!( - "{}struct {}{} {{", + "{}struct {}{}", visibility.get_mist(), name.get_mist(), generics.get_mist() )); - if !fields.is_empty() { - cg.addln(""); - cg.indent += 1; + + if fields.is_empty() { + cg.add(" {}"); + } else { + cg.start_bracket(); + for field in fields { cg.add_indentedln(&format!("{},", field.item.get_mist())); } + cg.indent -= 1; cg.add_indented("}"); - } else { - cg.add("}"); } + cg.addln(""); } Self::EnumDecl { @@ -208,22 +211,25 @@ impl GenMist for TopLevelKind { fields, } => { cg.add(&format!( - "{}enum {}{} {{", + "{}enum {}{}", visibility.get_mist(), name.get_mist(), generics.get_mist() )); - if !fields.is_empty() { - cg.addln(""); - cg.indent += 1; + + if fields.is_empty() { + cg.add(" {}"); + } else { + cg.start_bracket(); + for field in fields { cg.add_indentedln(&format!("{},", field.item.get_mist())); } + cg.indent -= 1; cg.add_indented("}"); - } else { - cg.add("}"); } + cg.addln(""); } Self::TraitDecl { @@ -249,8 +255,7 @@ impl GenMist for TopLevelKind { .join(" + "), ); } - cg.addln(" {"); - cg.indent += 1; + cg.start_bracket(); for item in items { item.gen_mist(ctx, cg); } @@ -276,8 +281,8 @@ impl GenMist for TopLevelKind { cg.add(" : "); cg.add(&inherits.get_mist()); } - cg.addln(" {\n"); - cg.indent += 1; + + cg.start_bracket(); for field in fields { cg.add_indented(&field.item.decl.get_mist()); @@ -303,7 +308,8 @@ impl GenMist for TopLevelKind { } param.gen_mist(ctx, cg); } - cg.add(") "); + cg.addln(") "); + cg.add_indented(""); constructor.item.body.gen_mist(ctx, cg); cg.addln(""); diff --git a/mist-test/src/items/attribute_test.mist b/mist-test/src/items/attribute_test.mist index 1530912..1d8cc07 100644 --- a/mist-test/src/items/attribute_test.mist +++ b/mist-test/src/items/attribute_test.mist @@ -1,11 +1,13 @@ pub module attribute_test; #[derive(Debug)] -pub struct Debuggable { +pub struct Debuggable +{ i32 value, } -pub void test_derive_attribute() { +pub void test_derive_attribute() +{ let d = Debuggable { value: 42, }; @@ -13,13 +15,15 @@ pub void test_derive_attribute() { } #[allow(unused_variables)] -pub void test_allow_attribute() { +pub void test_allow_attribute() +{ let x = 42; let y = "unused"; assert_eq!(x, 42); } -pub void run_tests() { +pub void run_tests() +{ test_derive_attribute(); test_allow_attribute(); } diff --git a/mist-test/src/items/class_test.mist b/mist-test/src/items/class_test.mist index 09f65d1..586502d 100644 --- a/mist-test/src/items/class_test.mist +++ b/mist-test/src/items/class_test.mist @@ -1,55 +1,66 @@ pub module class_test; -pub class Animal { - +pub class Animal +{ pub String name; - constructor() { + constructor() + { self.name = "Rex".to_string(); } - pub String speak(&self) { + pub String speak(&self) + { "Unknown".to_string() } - pub void test_speak<'a>(&'a self) { + pub void test_speak<'a>(&'a self) + { assert_eq!(self.speak(), "Woof!"); } - pub void static_method() { + pub void static_method() + { } } -pub class Mammal : Animal { - - constructor() { +pub class Mammal : Animal +{ + constructor() + { super = Super::new(); } - pub void args_test(&self, i32 x, str& y) { + pub void args_test(&self, i32 x, str& y) + { assert_eq!(x, 10); assert_eq!(y, "hello"); } } -pub class Dog : Mammal { - - constructor() { +pub class Dog : Mammal +{ + constructor() + { super = Super::new(); } - pub String speak(&self) override(Animal) { + pub String speak(&self) override(Animal) + { "Woof!".to_string() } - impl std::fmt::Display { - Result<(), std::fmt::Error> fmt(&self, std::fmt::Formatter<'_>& mut f) { + impl std::fmt::Display + { + Result<(), std::fmt::Error> fmt(&self, std::fmt::Formatter<'_>& mut f) + { write!(f, "🐾 {}", self.name) } } } -pub void run_tests() { +pub void run_tests() +{ let dawg = Dog::new(); dawg.args_test(10, "hello"); dawg.test_speak(); diff --git a/mist-test/src/items/enum_test.mist b/mist-test/src/items/enum_test.mist index 1bae19a..c46564a 100644 --- a/mist-test/src/items/enum_test.mist +++ b/mist-test/src/items/enum_test.mist @@ -1,11 +1,13 @@ pub module enum_test; -enum OptionInt { +enum OptionInt +{ None, Some(i32), } -pub void test_enum_named() { +pub void test_enum_named() +{ let x = OptionInt::None; match x { OptionInt::None => { @@ -17,7 +19,8 @@ pub void test_enum_named() { } } -pub void test_enum_tuple() { +pub void test_enum_tuple() +{ let x = OptionInt::Some(42); match x { OptionInt::None => { @@ -29,13 +32,17 @@ pub void test_enum_tuple() { } } -enum Shape { +enum Shape +{ Circle {i32 radius}, Rect {i32 w, i32 h}, } -pub void test_enum_struct() { - let c = Shape::Circle{radius: 5, }; +pub void test_enum_struct() +{ + let c = Shape::Circle { + radius: 5, + }; match c { Shape::Circle {radius} => { assert_eq!(radius, 5); @@ -44,7 +51,10 @@ pub void test_enum_struct() { assert_eq!(0, 1); } } - let r = Shape::Rect{w: 3, h: 4, }; + let r = Shape::Rect { + w: 3, + h: 4, + }; match r { Shape::Circle {..} => { assert_eq!(0, 1); @@ -55,13 +65,15 @@ pub void test_enum_struct() { } } -enum Color { +enum Color +{ Red, Green, Blue, } -pub void test_enum_eq() { +pub void test_enum_eq() +{ let c = Color::Red; match c { Color::Red => { @@ -73,7 +85,8 @@ pub void test_enum_eq() { } } -pub void run_tests() { +pub void run_tests() +{ test_enum_named(); test_enum_tuple(); test_enum_struct(); diff --git a/mist-test/src/items/function_test.mist b/mist-test/src/items/function_test.mist index d5126c5..65b0515 100644 --- a/mist-test/src/items/function_test.mist +++ b/mist-test/src/items/function_test.mist @@ -1,51 +1,62 @@ pub module function_test; -void greet() { +void greet() +{ let mut x = 1; x++; } -pub void test_basic_function() { +pub void test_basic_function() +{ greet(); } -i32 add(i32 a, i32 b) { +i32 add(i32 a, i32 b) +{ a + b } -pub void test_fn_params() { +pub void test_fn_params() +{ assert_eq!(add(2, 3), 5); } -pub i32 test_fn_return() { +pub i32 test_fn_return() +{ 42 } -pub i32 test_fn_early_return() { +pub i32 test_fn_early_return() +{ return 100; 0 } -pub i32 test_fn_mut_param(i32 mut x) { +pub i32 test_fn_mut_param(i32 mut x) +{ x = x + 10; x } -pub void test_method_call() { +pub void test_method_call() +{ let s = "hello"; assert_eq!(s.len(), 5); assert_eq!(s.to_uppercase(), "HELLO"); } -i32 triple(i32 x) { +i32 triple(i32 x) +{ add(x, add(x, x)) } -pub void test_nested_fn_calls() { +pub void test_nested_fn_calls() +{ assert_eq!(triple(5), 15); } -i32 factorial(i32 n) { +i32 factorial(i32 n) +{ if n <= 1 { 1 } else { @@ -53,11 +64,13 @@ i32 factorial(i32 n) { } } -pub void test_recursive_fn() { +pub void test_recursive_fn() +{ assert_eq!(factorial(5), 120); } -pub void run_tests() { +pub void run_tests() +{ test_basic_function(); test_fn_params(); assert_eq!(test_fn_return(), 42); diff --git a/mist-test/src/items/impl_test.mist b/mist-test/src/items/impl_test.mist index 02f3630..c28b869 100644 --- a/mist-test/src/items/impl_test.mist +++ b/mist-test/src/items/impl_test.mist @@ -1,17 +1,21 @@ pub module impl_test; -struct Vector2 { +struct Vector2 +{ i32 x, i32 y, } -impl Vector2 { - pub i32 magnitude(&self) { +impl Vector2 +{ + pub i32 magnitude(&self) + { self.x * self.x + self.y * self.y } } -pub void test_inherent_impl() { +pub void test_inherent_impl() +{ let v = Vector2 { x: 3, y: 4, @@ -19,17 +23,21 @@ pub void test_inherent_impl() { assert_eq!(v.magnitude(), 25); } -trait Display { +trait Display +{ String display(&self); } -impl Display for Vector2 { - String display(&self) { +impl Display for Vector2 +{ + String display(&self) + { format!("({}, {})", self.x, self.y) } } -pub void test_trait_impl_block() { +pub void test_trait_impl_block() +{ let v = Vector2 { x: 1, y: 2, @@ -38,8 +46,10 @@ pub void test_trait_impl_block() { assert_eq!(s.len() > 0, true); } -impl Vector2 { - pub Vector2 add(&self, Vector2 other) { +impl Vector2 +{ + pub Vector2 add(&self, Vector2 other) + { Vector2 { x: self.x + other.x, y: self.y + other.y, @@ -47,7 +57,8 @@ impl Vector2 { } } -pub void test_multiple_impls() { +pub void test_multiple_impls() +{ let a = Vector2 { x: 1, y: 2, @@ -61,7 +72,8 @@ pub void test_multiple_impls() { assert_eq!(c.y, 6); } -pub void run_tests() { +pub void run_tests() +{ test_inherent_impl(); test_trait_impl_block(); test_multiple_impls(); diff --git a/mist-test/src/items/struct_test.mist b/mist-test/src/items/struct_test.mist index 6a8d121..36e44fb 100644 --- a/mist-test/src/items/struct_test.mist +++ b/mist-test/src/items/struct_test.mist @@ -1,11 +1,13 @@ pub module struct_test; -struct Point { +struct Point +{ i32 x, i32 y, } -pub void test_struct_create_access() { +pub void test_struct_create_access() +{ let p = Point { x: 10, y: 20, @@ -14,7 +16,8 @@ pub void test_struct_create_access() { assert_eq!(p.y, 20); } -pub void test_struct_mut_field() { +pub void test_struct_mut_field() +{ let mut p = Point { x: 1, y: 2, @@ -23,7 +26,8 @@ pub void test_struct_mut_field() { assert_eq!(p.x, 100); } -pub void test_struct_destructure() { +pub void test_struct_destructure() +{ let p = Point { x: 3, y: 4, @@ -33,12 +37,14 @@ pub void test_struct_destructure() { assert_eq!(y, 4); } -struct Line { +struct Line +{ Point start, Point end, } -pub void test_struct_nested() { +pub void test_struct_nested() +{ let l = Line { start: Point { x: 0, @@ -53,7 +59,8 @@ pub void test_struct_nested() { assert_eq!(l.end.y, 10); } -pub void run_tests() { +pub void run_tests() +{ test_struct_create_access(); test_struct_mut_field(); test_struct_destructure(); diff --git a/mist-test/src/items/trait_test.mist b/mist-test/src/items/trait_test.mist index 8593a7a..c81c125 100644 --- a/mist-test/src/items/trait_test.mist +++ b/mist-test/src/items/trait_test.mist @@ -1,37 +1,46 @@ pub module trait_test; -trait Speak { +trait Speak +{ String speak(&self); } -trait Greet : Speak { +trait Greet : Speak +{ String greet(&self); } -struct Dog { +struct Dog +{ String name, } -impl Speak for Dog { - String speak(&self) { +impl Speak for Dog +{ + String speak(&self) + { "woof".to_string() } } -impl Greet for Dog { - String greet(&self) { +impl Greet for Dog +{ + String greet(&self) + { "hello".to_string() } } -pub void test_trait_impl() { +pub void test_trait_impl() +{ let d = Dog { name: "Rex".to_string(), }; assert_eq!(d.speak(), "woof"); } -pub void test_trait_with_requirement() { +pub void test_trait_with_requirement() +{ let d = Dog { name: "Buddy".to_string(), }; @@ -39,7 +48,8 @@ pub void test_trait_with_requirement() { assert_eq!(d.greet(), "hello"); } -pub void run_tests() { +pub void run_tests() +{ test_trait_impl(); test_trait_with_requirement(); } diff --git a/mist-test/src/main.mist b/mist-test/src/main.mist index 548fa97..e5fd2e4 100644 --- a/mist-test/src/main.mist +++ b/mist-test/src/main.mist @@ -1,11 +1,11 @@ -void main() { +void main() +{ println!("running common tests..."); common::test_package(); common::expr_test::run_tests(); common::statement_test::run_tests(); common::decl_test::run_tests(); common::types_test::run_tests(); - println!("running items tests..."); items::function_test::run_tests(); items::struct_test::run_tests(); @@ -14,6 +14,5 @@ void main() { items::trait_test::run_tests(); items::impl_test::run_tests(); items::attribute_test::run_tests(); - println!("\x1b[32m\nAll tests passed!\x1b[0m"); }