ast.rs 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. type Name = String;
  2. #[derive(Debug, Clone)]
  3. pub enum Stmt {
  4. Puts(Expr),
  5. Fix(Name),
  6. Assn(Name, Expr),
  7. LitAssn(Name, Vec<String>),
  8. }
  9. #[derive(Debug, Clone)]
  10. pub enum Expr {
  11. Var(Name),
  12. Cat(Vec<Expr>),
  13. Chc(Vec<Choice>),
  14. Rep(i64, Box<Expr>),
  15. Lit(Literal),
  16. Ap(Box<Expr>, Box<Expr>),
  17. Tup(Vec<Expr>),
  18. Let(Name, Box<Expr>, Box<Expr>),
  19. Fun(Vec<Case>),
  20. Case(Box<Expr>, Vec<Case>),
  21. }
  22. #[derive(Debug, Clone)]
  23. pub struct Case {
  24. pub pat: Pat,
  25. pub expr: Expr,
  26. }
  27. #[derive(Debug, Clone)]
  28. pub enum Pat {
  29. Var(Name),
  30. Lit(Literal),
  31. Tup(Vec<Pat>),
  32. }
  33. #[derive(Debug, Clone)]
  34. pub struct Choice {
  35. pub weight: Option<i64>,
  36. pub value: Expr,
  37. }
  38. impl Choice {
  39. pub fn weight(&self) -> i64 {
  40. self.weight.unwrap_or(1)
  41. }
  42. }
  43. #[derive(Debug, Clone)]
  44. pub enum Literal {
  45. Str(String),
  46. Atom(String),
  47. Num(i64),
  48. }
  49. impl Literal {
  50. pub fn from_str_literal(s: &str) -> Literal {
  51. // strip the outer pieces from the string
  52. let mut buf = String::new();
  53. let mut src = s[1..s.len() - 1].chars().into_iter();
  54. while let Some(c) = src.next() {
  55. if c == '\\' {
  56. match src.next() {
  57. Some('n') => buf.push('\n'),
  58. Some('t') => buf.push('\t'),
  59. Some('r') => buf.push('\r'),
  60. Some(c) => buf.push(c),
  61. None => panic!("bad escape"),
  62. }
  63. } else {
  64. buf.push(c);
  65. }
  66. }
  67. Literal::Str(buf)
  68. }
  69. }