diff --git a/src/ast.rs b/src/ast/expr.rs similarity index 79% rename from src/ast.rs rename to src/ast/expr.rs index 63e7bad..a259d92 100644 --- a/src/ast.rs +++ b/src/ast/expr.rs @@ -3,55 +3,6 @@ use crate::{ token::{Token, TokenKind}, }; -#[derive(Clone, Debug)] -pub struct Ast(pub Vec>); - -#[derive(Clone, Debug)] -pub enum Stmt { - Expr(Spanned), - Print(Spanned), -} - -impl Stmt { - pub fn expr(inner: Spanned, semi: Token) -> Spanned { - debug_assert_eq!(semi.kind, TokenKind::Semicolon); - let span = inner.span().join(&semi.span); - Spanned::new(Self::Expr(inner), span) - } - - pub fn print(print: Token, inner: Spanned, semi: Token) -> Spanned { - debug_assert_eq!(print.kind, TokenKind::Print); - debug_assert_eq!(semi.kind, TokenKind::Semicolon); - - let span = print.span.join(&semi.span); - Spanned::new(Self::Print(inner), span) - } -} - -#[cfg(test)] -impl Stmt { - pub fn unwrap_expr(&self) -> &Spanned { - match self { - Stmt::Expr(e) => e, - other => panic!("expected expression statement, found {:?}", other.as_str()), - } - } - - pub fn unwrap_print(&self) -> &Spanned { - match self { - Stmt::Print(e) => e, - other => panic!("expected print statement, found {:?}", other.as_str()), - } - } - - fn as_str(&self) -> &'static str { - match self { - Stmt::Expr(_) => "expr", - Stmt::Print(_) => "print", - } - } -} - #[derive(Clone, Debug)] pub enum Expr { Binary { @@ -251,21 +202,8 @@ impl UnaryOp { } } -impl Ast { - pub fn print_rpn(&self) -> String { - self.0 - .iter() - .map(|s| match s.as_ref() { - Stmt::Expr(e) => e.print_rpn(), - Stmt::Print(e) => format!("print {}", e.print_rpn()), - }) - .collect::>() - .join("\n") - } -} - impl Expr { - fn print_rpn(&self) -> String { + pub fn print_rpn(&self) -> String { match self { Expr::Binary { left, op, right } => { let left = left.print_rpn(); diff --git a/src/ast/mod.rs b/src/ast/mod.rs new file mode 100644 index 0000000..c473d1a --- /dev/null +++ b/src/ast/mod.rs @@ -0,0 +1,23 @@ +mod expr; +mod stmt; + +use crate::span::Spanned; + +pub use expr::{BinaryOp, Expr, Literal, UnaryOp}; +pub use stmt::Stmt; + +#[derive(Clone, Debug)] +pub struct Ast(pub Vec>); + +impl Ast { + pub fn print_rpn(&self) -> String { + self.0 + .iter() + .map(|s| match s.as_ref() { + Stmt::Expr(e) => e.print_rpn(), + Stmt::Print(e) => format!("print {}", e.print_rpn()), + }) + .collect::>() + .join("\n") + } +} diff --git a/src/ast/stmt.rs b/src/ast/stmt.rs new file mode 100644 index 0000000..0d702c1 --- /dev/null +++ b/src/ast/stmt.rs @@ -0,0 +1,51 @@ +use crate::{ + ast::Expr, + span::Spanned, + token::{Token, TokenKind}, +}; + +#[derive(Clone, Debug)] +pub enum Stmt { + Expr(Spanned), + Print(Spanned), +} + +impl Stmt { + pub fn expr(inner: Spanned, semi: Token) -> Spanned { + debug_assert_eq!(semi.kind, TokenKind::Semicolon); + let span = inner.span().join(&semi.span); + Spanned::new(Self::Expr(inner), span) + } + + pub fn print(print: Token, inner: Spanned, semi: Token) -> Spanned { + debug_assert_eq!(print.kind, TokenKind::Print); + debug_assert_eq!(semi.kind, TokenKind::Semicolon); + + let span = print.span.join(&semi.span); + Spanned::new(Self::Print(inner), span) + } +} + +#[cfg(test)] +impl Stmt { + pub fn unwrap_expr(&self) -> &Spanned { + match self { + Stmt::Expr(e) => e, + other => panic!("expected expression statement, found {:?}", other.as_str()), + } + } + + pub fn unwrap_print(&self) -> &Spanned { + match self { + Stmt::Print(e) => e, + other => panic!("expected print statement, found {:?}", other.as_str()), + } + } + + fn as_str(&self) -> &'static str { + match self { + Stmt::Expr(_) => "expr", + Stmt::Print(_) => "print", + } + } +}