ast.rs 11 KB

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