ast.rs 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  1. use std::fmt;
  2. pub type Name = string_interner::DefaultSymbol;
  3. pub struct ASTArena {
  4. strings: string_interner::StringInterner,
  5. }
  6. impl Default for ASTArena {
  7. fn default() -> Self {
  8. Self::new()
  9. }
  10. }
  11. impl ASTArena {
  12. pub fn new() -> ASTArena {
  13. ASTArena {
  14. strings: string_interner::StringInterner::new(),
  15. }
  16. }
  17. pub fn add_string(&mut self, s: &str) -> Name {
  18. self.strings.get_or_intern(s)
  19. }
  20. pub fn show_stmt(&self, stmt: &Stmt, f: &mut fmt::Formatter) -> fmt::Result {
  21. match stmt {
  22. Stmt::Puts(expr) => {
  23. write!(f, "Puts ")?;
  24. self.show_expr(expr, f, 0)
  25. }
  26. Stmt::Fix(name) => writeln!(f, "Fix {}", &self[*name]),
  27. Stmt::Assn(fixed, name, expr) => {
  28. write!(
  29. f,
  30. "Assn {} {} ",
  31. if *fixed { "fixed" } else { "" },
  32. &self[*name]
  33. )?;
  34. self.show_expr(expr, f, 0)
  35. }
  36. Stmt::LitAssn(fixed, name, strs) => {
  37. write!(
  38. f,
  39. "LitAssn {} {}, [ ",
  40. if *fixed { "fixed" } else { "" },
  41. &self[*name],
  42. )?;
  43. for str in strs.iter() {
  44. write!(f, " {} ", str)?;
  45. }
  46. writeln!(f, "]")
  47. }
  48. }
  49. }
  50. fn indent(&self, f: &mut fmt::Formatter, depth: usize) -> fmt::Result {
  51. for _ in 0..depth {
  52. write!(f, " ")?;
  53. }
  54. Ok(())
  55. }
  56. fn show_pat(&self, pat: &Pat, f: &mut fmt::Formatter) -> fmt::Result {
  57. match pat {
  58. Pat::Var(n) => write!(f, "{}", &self[*n]),
  59. Pat::Lit(Literal::Atom(n)) => write!(f, "{}", &self[*n]),
  60. Pat::Lit(lit) => write!(f, "{:?}", lit),
  61. Pat::Tup(tup) => {
  62. write!(f, "Tup( ")?;
  63. for t in tup {
  64. self.show_pat(t, f)?;
  65. write!(f, " ")?;
  66. }
  67. write!(f, ")")
  68. }
  69. }
  70. }
  71. fn show_expr(&self, expr: &Expr, f: &mut fmt::Formatter, depth: usize) -> fmt::Result {
  72. match expr {
  73. Expr::Nil => writeln!(f, "Nil"),
  74. Expr::Var(v) => writeln!(f, "Var({})", &self[*v]),
  75. Expr::Lit(Literal::Atom(n)) => writeln!(f, "Lit(Atom({}))", &self[*n]),
  76. Expr::Lit(lit) => writeln!(f, "{:?}", lit),
  77. Expr::Range(from, to) => {
  78. writeln!(f, "Range(")?;
  79. self.indent(f, depth + 2)?;
  80. self.show_expr(from, f, depth + 2)?;
  81. self.indent(f, depth + 2)?;
  82. self.show_expr(to, f, depth + 2)?;
  83. self.indent(f, depth)?;
  84. writeln!(f, ")")
  85. }
  86. Expr::Ap(func, arg) => {
  87. writeln!(f, "Ap(")?;
  88. self.indent(f, depth + 2)?;
  89. self.show_expr(func, f, depth + 2)?;
  90. self.indent(f, depth + 2)?;
  91. self.show_expr(arg, f, depth + 2)?;
  92. self.indent(f, depth)?;
  93. writeln!(f, ")")
  94. }
  95. Expr::Tup(expr) => {
  96. writeln!(f, "Tup(")?;
  97. for e in expr {
  98. self.indent(f, depth + 2)?;
  99. self.show_expr(e, f, depth + 2)?;
  100. }
  101. self.indent(f, depth)?;
  102. writeln!(f, ")")
  103. }
  104. Expr::Cat(expr) => {
  105. writeln!(f, "Cat(")?;
  106. for e in expr {
  107. self.indent(f, depth + 2)?;
  108. self.show_expr(e, f, depth + 2)?;
  109. }
  110. self.indent(f, depth)?;
  111. writeln!(f, ")")
  112. }
  113. Expr::Chc(expr) => {
  114. writeln!(f, "Chc(")?;
  115. for e in expr {
  116. if let Some(s) = e.weight {
  117. self.indent(f, depth + 2)?;
  118. writeln!(f, "{}:", s)?;
  119. self.indent(f, depth + 4)?;
  120. self.show_expr(&e.value, f, depth + 4)?;
  121. } else {
  122. self.indent(f, depth + 2)?;
  123. self.show_expr(&e.value, f, depth + 2)?;
  124. }
  125. }
  126. self.indent(f, depth)?;
  127. writeln!(f, ")")
  128. }
  129. Expr::Let(name, expr, body) => {
  130. writeln!(f, "Let({}", &self[*name])?;
  131. self.indent(f, depth + 2)?;
  132. self.show_expr(expr, f, depth + 2)?;
  133. self.indent(f, depth + 2)?;
  134. self.show_expr(body, f, depth + 2)?;
  135. self.indent(f, depth)?;
  136. writeln!(f, ")")
  137. }
  138. Expr::Fun(cases) => {
  139. writeln!(f, "Fun(")?;
  140. for case in cases {
  141. self.indent(f, depth + 2)?;
  142. self.show_pat(&case.pat, f)?;
  143. writeln!(f, " =>")?;
  144. self.indent(f, depth + 4)?;
  145. self.show_expr(&case.expr, f, depth + 4)?;
  146. }
  147. self.indent(f, depth)?;
  148. writeln!(f, ")")
  149. }
  150. }
  151. }
  152. }
  153. impl std::ops::Index<string_interner::DefaultSymbol> for ASTArena {
  154. type Output = str;
  155. fn index(&self, sf: string_interner::DefaultSymbol) -> &str {
  156. self.strings.resolve(sf).unwrap()
  157. }
  158. }
  159. /// A `Printable` struct is a bundle of another value and an
  160. /// `ASTArena`, which allows us to fetch the various indices and
  161. /// dereference the interned strings.
  162. pub struct Printable<'a, T> {
  163. arena: &'a ASTArena,
  164. value: &'a T,
  165. }
  166. impl<'a> std::fmt::Debug for Printable<'a, Stmt> {
  167. fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
  168. self.arena.show_stmt(self.value, f)
  169. }
  170. }
  171. impl<'a> std::fmt::Debug for Printable<'a, Expr> {
  172. fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
  173. self.arena.show_expr(self.value, f, 0)
  174. }
  175. }
  176. /// A top-level Matzo statement
  177. #[derive(Debug, Clone, PartialEq, Eq)]
  178. pub enum Stmt {
  179. /// evaluate and print the value of an expression
  180. Puts(Expr),
  181. /// replace a named item with the forced version of that item
  182. Fix(Name),
  183. /// assign a value to a name which may or may not be forced
  184. Assn(bool, Name, Expr),
  185. /// assign one of a set of strings to a name, which may or may not
  186. /// be forced
  187. LitAssn(bool, Name, Vec<String>),
  188. }
  189. impl Stmt {
  190. pub fn show<'a>(&'a self, ast: &'a ASTArena) -> Printable<'a, Stmt> {
  191. Printable {
  192. arena: ast,
  193. value: self,
  194. }
  195. }
  196. }
  197. /// A Matzo expression
  198. #[derive(Debug, Clone, PartialEq, Eq)]
  199. pub enum Expr {
  200. Var(Name),
  201. Cat(Vec<Expr>),
  202. Chc(Vec<Choice>),
  203. Lit(Literal),
  204. Ap(Box<Expr>, Box<Expr>),
  205. Tup(Vec<Expr>),
  206. Let(Name, Box<Expr>, Box<Expr>),
  207. Fun(Vec<Case>),
  208. Range(Box<Expr>, Box<Expr>),
  209. Nil,
  210. }
  211. /// A single case in an anonymous function or `case` statement
  212. #[derive(Debug, Clone, PartialEq, Eq)]
  213. pub struct Case {
  214. pub pat: Pat,
  215. pub expr: Expr,
  216. }
  217. /// A pattern, e.g. in an anonymous function or `case` statement
  218. #[derive(Debug, Clone, PartialEq, Eq)]
  219. pub enum Pat {
  220. Var(Name),
  221. Lit(Literal),
  222. Tup(Vec<Pat>),
  223. }
  224. /// A single element in a choice, with an optional weight (which
  225. /// defaults to 1) and a value
  226. #[derive(Debug, Clone, PartialEq, Eq)]
  227. pub struct Choice {
  228. pub weight: Option<i64>,
  229. pub value: Expr,
  230. }
  231. impl Choice {
  232. /// Fetch a weight from a `Choice`, defaulting to 1
  233. pub fn weight(&self) -> i64 {
  234. self.weight.unwrap_or(1)
  235. }
  236. }
  237. /// An atomic literal: a string, a number, or an atom
  238. #[derive(Debug, Clone, PartialEq, Eq)]
  239. pub enum Literal {
  240. Str(String),
  241. Atom(Name),
  242. Num(i64),
  243. }