diff --git a/crates/ailang-surface/src/print.rs b/crates/ailang-surface/src/print.rs index b04ed8b..032ae43 100644 --- a/crates/ailang-surface/src/print.rs +++ b/crates/ailang-surface/src/print.rs @@ -8,8 +8,9 @@ //! per level. Comments are NOT emitted. use ailang_core::ast::{ - Arm, ClassDef, ClassMethod, ConstDef, Ctor, Def, FnDef, Import, InstanceDef, Literal, - Module, ParamMode, Pattern, SuperclassRef, Suppress, Term, Type, TypeDef, + Arm, ClassDef, ClassMethod, ConstDef, Ctor, Def, FnDef, Import, InstanceDef, + InstanceMethod, Literal, Module, ParamMode, Pattern, SuperclassRef, Suppress, Term, + Type, TypeDef, }; /// Print a module in form (A). @@ -274,9 +275,43 @@ fn write_class_method(out: &mut String, m: &ClassMethod, level: usize) { out.push(')'); } -fn write_instance_def(out: &mut String, _i: &InstanceDef, level: usize) { +fn write_instance_def(out: &mut String, i: &InstanceDef, level: usize) { indent(out, level); - out.push_str("(instance)"); + out.push_str("(instance"); + out.push('\n'); + indent(out, level + 1); + out.push_str("(class "); + out.push_str(&i.class); + out.push(')'); + out.push('\n'); + indent(out, level + 1); + out.push_str("(type "); + write_type(out, &i.type_); + out.push(')'); + if let Some(doc) = &i.doc { + out.push('\n'); + indent(out, level + 1); + out.push_str("(doc "); + write_string_lit(out, doc); + out.push(')'); + } + for m in &i.methods { + out.push('\n'); + write_instance_method(out, m, level + 1); + } + out.push(')'); +} + +fn write_instance_method(out: &mut String, m: &InstanceMethod, level: usize) { + indent(out, level); + out.push_str("(method "); + out.push_str(&m.name); + out.push('\n'); + indent(out, level + 1); + out.push_str("(body "); + write_term(out, &m.body, level + 2); + out.push(')'); + out.push(')'); } // ---- types ---------------------------------------------------------------- @@ -622,4 +657,23 @@ mod tests { }; round_trip(m, "class_with_superclass_and_default"); } + + #[test] + fn print_then_parse_round_trip_minimal_instance() { + let m = Module { + schema: ailang_core::SCHEMA.to_string(), + name: "M".into(), + imports: vec![], + defs: vec![Def::Instance(InstanceDef { + class: "Foo".into(), + type_: Type::int(), + methods: vec![InstanceMethod { + name: "m".into(), + body: Term::Lit { lit: Literal::Int { value: 5 } }, + }], + doc: None, + })], + }; + round_trip(m, "minimal_instance"); + } }