ast.rs 1.4 KB

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