diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs index 0757a87..37b7359 100644 --- a/crates/hir/src/lib.rs +++ b/crates/hir/src/lib.rs @@ -12,6 +12,17 @@ const INTRINSICS: [&str; 5] = [ #[derive(Debug, Clone)] pub enum Value { Int(i64), Boolean(bool), String(String), Ident(String) } +impl std::fmt::Display for Value { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + match self { + Value::Int(i) => write!(f, "{}", i), + Value::Boolean(b) => write!(f, "{}", b), + Value::String(s) => write!(f, "\"{}\"", s), + Value::Ident(s) => write!(f, "{}", s), + } + } +} + #[derive(Debug, Clone)] pub enum IRKind { Define { @@ -46,6 +57,60 @@ pub struct IR { pub span: Range } +impl std::fmt::Display for IRKind { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + match self { + IRKind::Define { ref public, ref name, ref type_hint, ref value, ref mutable } => { + write!(f, "(let {} {} {} {} {})", + if *public { "export" } else { "" }, + name, + type_hint, + value, + if *mutable { "mut" } else { "" }, + ) + }, + IRKind::Fun { ref public, ref name, ref return_type_hint, ref args, ref body } => { + write!(f, "(fun{} {} {} {} {})", + if *public { "export" } else { "" }, + name, + return_type_hint, + args.iter().map(|(name, type_hint)| format!(":{} {}", name, type_hint)).collect::>().join(" "), + body, + ) + }, + IRKind::Call { ref name, ref args } => { + write!(f, "({} {})", name, args.iter().map(|arg| arg.to_string()).collect::>().join(" ")) + }, + IRKind::Intrinsic { ref name, ref args } => { + write!(f, "(@{} {})", name, args.iter().map(|arg| arg.to_string()).collect::>().join(" ")) + }, + IRKind::Do { ref body } => { + write!(f, "(do {})", body.iter().map(|expr| expr.to_string()).collect::>().join(" ")) + }, + IRKind::If { ref cond, ref body, ref else_body } => { + write!(f, "(if {} {} {})", cond, body, else_body) + }, + IRKind::Case { ref cond, ref cases, ref default } => { + write!(f, "(case {} {} {})", cond, cases.iter().map(|(cond, body)| format!("({} {})", cond, body)).collect::>().join(" "), default) + }, + IRKind::Unary { ref op, ref right } => { + write!(f, "({} {})", op, right) + }, + IRKind::Binary { ref op, ref left, ref right } => { + write!(f, "({} {} {})", op, left, right) + }, + IRKind::Value { ref value } => { + write!(f, "{}", value) + }, + IRKind::Return { ref value } => { + write!(f, "(return {})", value) + } + #[allow(unreachable_patterns)] + _ => { dbg!(self); unreachable!() } + } + } +} + #[derive(Debug)] pub struct LoweringError { pub span: Range, diff --git a/crates/main/src/main.rs b/crates/main/src/main.rs index 7663578..1010ecf 100644 --- a/crates/main/src/main.rs +++ b/crates/main/src/main.rs @@ -52,7 +52,8 @@ fn main() { logif!(0, format!("Parsing took {}ms", start.elapsed().as_millis())); } - if print_ast { log(0, format!("{:#?}", ast)); } + // TODO: S-Expr syntax for AST + // if print_ast { log(0, format!("{:#?}", ast)); } match ast { Some(ast) => { @@ -60,7 +61,7 @@ fn main() { let (ir, lowering_error) = ast_to_ir(ast); for err in lowering_error { diagnostics.add_lowering_error(err); } - if print_ast { log(0, format!("{:#?}", ir)); } + if print_ast { log(0, format!("IR\n{}", ir.iter().map(|x| format!("{}", x.kind)).collect::>().join("\n\n"))); } // Report lowering errors if any if diagnostics.has_error() {