ast.rs 10 KB

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