diff --git a/parser/src/lib.rs b/parser/src/lib.rs index eaae013..559a0f6 100644 --- a/parser/src/lib.rs +++ b/parser/src/lib.rs @@ -225,9 +225,15 @@ impl From> for ClassConstructor { false }; + let params = if inner.peek().unwrap().as_rule() == Rule::param_list { + ParamList::from(inner.next().unwrap()) + } else { + ParamList(Vec::new()) + }; + Self { export, - params: ParamList::from(inner.next().unwrap()), + params, body: Block::from(inner.next().unwrap()), } } diff --git a/src/codegen.rs b/src/codegen.rs index 3440a77..905de44 100644 --- a/src/codegen.rs +++ b/src/codegen.rs @@ -334,6 +334,56 @@ impl ToRust for TopLevelKind { cg.indent -= 1; cg.addln("}\n"); } + Self::ClassDecl { + export, + name, + fields, + constructor, + } => { + // Struct decl + let vis = if *export { "pub " } else { "" }; + cg.addln(&format!("{}struct {} {{", vis, name)); + cg.indent += 1; + + for field in fields { + let ty = field.decl.type_.clone().unwrap().get_rust(); + cg.add_indentedln(&format!("pub {}: {},", field.decl.name, ty)); + } + + cg.indent -= 1; + cg.addln("}\n"); + + // Constructor + cg.addln(&format!("impl {} {{", name)); + cg.indent += 1; + + let params_str = constructor + .params + .0 + .iter() + .map(VarDecl::get_rust) + .collect::>() + .join(", "); + + cg.add_indentedln(&format!( + "{}fn new({}) -> Self {{", + if constructor.export { "pub " } else { "" }, + params_str + )); + cg.indent += 1; + + cg.add_indentedln("let this: Self = unsafe { std::mem::zeroed() };"); + + constructor.body.to_rust(cg); + + cg.add_indentedln("this"); + + cg.indent -= 1; + cg.add_indentedln("}\n"); + + cg.indent -= 1; + cg.addln("}\n"); + } } } } diff --git a/test/src/main.mist b/test/src/main.mist index 258851d..87d8396 100644 --- a/test/src/main.mist +++ b/test/src/main.mist @@ -5,3 +5,7 @@ class MyClass { } } + +void main() { + var my_class = MyClass::new(); +}