ast.rs 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. use std::fmt;
  2. pub type Name = string_interner::DefaultSymbol;
  3. pub struct ASTArena {
  4. strings: string_interner::StringInterner,
  5. }
  6. pub struct Debuggable<'a, T> {
  7. arena: &'a ASTArena,
  8. value: &'a T,
  9. }
  10. impl<'a> std::fmt::Debug for Debuggable<'a, Stmt> {
  11. fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
  12. self.arena.show_stmt(self.value, f)
  13. }
  14. }
  15. impl ASTArena {
  16. pub fn new() -> ASTArena {
  17. ASTArena {
  18. strings: string_interner::StringInterner::new(),
  19. }
  20. }
  21. pub fn add_string(&mut self, s: &str) -> Name {
  22. self.strings.get_or_intern(s)
  23. }
  24. pub fn show_stmt(&self, stmt: &Stmt, f: &mut fmt::Formatter) -> fmt::Result {
  25. match stmt {
  26. Stmt::Puts(expr) => {
  27. write!(f, "Puts ")?;
  28. self.show_expr(&expr, f, 0)
  29. }
  30. Stmt::Fix(name) =>
  31. writeln!(f, "Fix({})", &self[*name]),
  32. Stmt::Assn(name, expr) => {
  33. write!(f, "Assn {} ", &self[*name])?;
  34. self.show_expr(&expr, f, 0)
  35. }
  36. Stmt::LitAssn(name, strs) => {
  37. write!(f, "LitAssn({}, [ ", &self[*name])?;
  38. for str in strs.iter() {
  39. write!(f, " {} ", str)?;
  40. }
  41. writeln!(f, "]")
  42. }
  43. }
  44. }
  45. fn indent(&self, f: &mut fmt::Formatter, depth: usize) -> fmt::Result {
  46. for _ in 0..depth {
  47. write!(f, " ")?;
  48. }
  49. Ok(())
  50. }
  51. fn show_pat(&self, pat: &Pat, f: &mut fmt::Formatter) -> fmt::Result {
  52. match pat {
  53. Pat::Var(n) => write!(f, "{}", &self[*n]),
  54. Pat::Lit(Literal::Atom(n)) => write!(f, "{}", &self[*n]),
  55. Pat::Lit(lit) => write!(f, "{:?}", lit),
  56. Pat::Tup(tup) => {
  57. write!(f, "Tup( ")?;
  58. for t in tup {
  59. self.show_pat(&t, f)?;
  60. write!(f, " ")?;
  61. }
  62. write!(f, ")")
  63. }
  64. }
  65. }
  66. fn show_expr(&self, expr: &Expr, f: &mut fmt::Formatter, depth: usize) -> fmt::Result {
  67. match expr {
  68. Expr::Var(v) => writeln!(f, "Var({})", &self[*v]),
  69. Expr::Lit(Literal::Atom(n)) => writeln!(f, "Lit(Atom({}))", &self[*n]),
  70. Expr::Lit(lit) => writeln!(f, "{:?}", lit),
  71. Expr::Range(from, to) => {
  72. writeln!(f, "Range(")?;
  73. self.indent(f, depth + 2)?;
  74. self.show_expr(from, f, depth + 2)?;
  75. self.indent(f, depth + 2)?;
  76. self.show_expr(to, f, depth + 2)?;
  77. self.indent(f, depth)?;
  78. writeln!(f, ")")
  79. }
  80. Expr::Ap(func, arg) => {
  81. writeln!(f, "Ap(")?;
  82. self.indent(f, depth + 2)?;
  83. self.show_expr(func, f, depth + 2)?;
  84. self.indent(f, depth + 2)?;
  85. self.show_expr(arg, f, depth + 2)?;
  86. self.indent(f, depth)?;
  87. writeln!(f, ")")
  88. }
  89. Expr::Tup(expr) => {
  90. writeln!(f, "Tup(")?;
  91. for e in expr {
  92. self.indent(f, depth + 2)?;
  93. self.show_expr(e, f, depth + 2)?;
  94. }
  95. self.indent(f, depth)?;
  96. writeln!(f, ")")
  97. }
  98. Expr::Cat(expr) => {
  99. writeln!(f, "Cat(")?;
  100. for e in expr {
  101. self.indent(f, depth + 2)?;
  102. self.show_expr(e, f, depth + 2)?;
  103. }
  104. self.indent(f, depth)?;
  105. writeln!(f, ")")
  106. }
  107. Expr::Chc(expr) => {
  108. writeln!(f, "Chc(")?;
  109. for e in expr {
  110. if let Some(s) = e.weight {
  111. self.indent(f, depth + 2)?;
  112. writeln!(f, "{}:", s)?;
  113. self.indent(f, depth + 4)?;
  114. self.show_expr(&e.value, f, depth + 4)?;
  115. } else {
  116. self.indent(f, depth + 2)?;
  117. self.show_expr(&e.value, f, depth + 2)?;
  118. }
  119. }
  120. self.indent(f, depth)?;
  121. writeln!(f, ")")
  122. }
  123. Expr::Let(name, expr, body) => {
  124. writeln!(f, "Let({}", &self[*name])?;
  125. self.indent(f, depth + 2)?;
  126. self.show_expr(expr, f, depth + 2)?;
  127. self.indent(f, depth + 2)?;
  128. self.show_expr(body, f, depth + 2)?;
  129. self.indent(f, depth)?;
  130. writeln!(f, ")")
  131. }
  132. Expr::Fun(cases) => {
  133. writeln!(f, "Fun(")?;
  134. for case in cases {
  135. self.indent(f, depth + 2)?;
  136. self.show_pat(&case.pat, f)?;
  137. writeln!(f, " =>")?;
  138. self.indent(f, depth + 4)?;
  139. self.show_expr(&case.expr, f, depth + 4)?;
  140. }
  141. self.indent(f, depth)?;
  142. writeln!(f, ")")
  143. }
  144. }
  145. }
  146. }
  147. impl std::ops::Index<string_interner::DefaultSymbol> for ASTArena {
  148. type Output = str;
  149. fn index(&self, sf: string_interner::DefaultSymbol) -> &str {
  150. self.strings.resolve(sf).unwrap()
  151. }
  152. }
  153. #[derive(Debug, Clone)]
  154. pub enum Stmt {
  155. Puts(Expr),
  156. Fix(Name),
  157. Assn(Name, Expr),
  158. LitAssn(Name, Vec<String>),
  159. }
  160. impl Stmt {
  161. pub fn show<'a>(&'a self, ast: &'a ASTArena) -> Debuggable<'a, Stmt> {
  162. Debuggable {
  163. arena: ast,
  164. value: self,
  165. }
  166. }
  167. }
  168. #[derive(Debug, Clone)]
  169. pub enum Expr {
  170. Var(Name),
  171. Cat(Vec<Expr>),
  172. Chc(Vec<Choice>),
  173. Lit(Literal),
  174. Ap(Box<Expr>, Box<Expr>),
  175. Tup(Vec<Expr>),
  176. Let(Name, Box<Expr>, Box<Expr>),
  177. Fun(Vec<Case>),
  178. Range(Box<Expr>, Box<Expr>),
  179. }
  180. #[derive(Debug, Clone)]
  181. pub struct Case {
  182. pub pat: Pat,
  183. pub expr: Expr,
  184. }
  185. #[derive(Debug, Clone)]
  186. pub enum Pat {
  187. Var(Name),
  188. Lit(Literal),
  189. Tup(Vec<Pat>),
  190. }
  191. #[derive(Debug, Clone)]
  192. pub struct Choice {
  193. pub weight: Option<i64>,
  194. pub value: Expr,
  195. }
  196. impl Choice {
  197. pub fn weight(&self) -> i64 {
  198. self.weight.unwrap_or(1)
  199. }
  200. }
  201. #[derive(Debug, Clone)]
  202. pub enum Literal {
  203. Str(String),
  204. Atom(Name),
  205. Num(i64),
  206. }