1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
use std::collections::HashMap;

pub type Ast = Vec<Box<Stmt>>;

#[derive(Debug)]
pub enum Stmt {
  Function(String, Vec<String>, Box<Expr>),
  Const(String, Box<Expr>),
  Let(String, Option<Box<Expr>>),
  Return(Option<Box<Expr>>),
  Break(Option<Box<Expr>>),
  Expression(Box<Expr>),
}

#[derive(Debug)]
pub enum Expr {
  Error,
  /// Outputs the value of the contained [Expr] as a log.
  Log(Box<Expr>),
  Block(Vec<Box<Stmt>>, Option<Box<Expr>>),
  /// The first [Expr] is the condition, the second the "true" block,
  /// and the third the "false" block.
  ///
  /// Else-if statements are collapsed as if a standard if statement
  /// was put inside of the else block.
  If(
    /* condition: */ Box<Expr>,
    /* true branch: */ Box<Expr>,
    /* false branch: */ Option<Box<Expr>>,
  ),
  /// While [Expr] is true, do [Stmt]s.
  While(Box<Expr>, Vec<Box<Stmt>>),
  Assign(Box<Expr>, AssignOp, Box<Expr>),
  Binary(Box<Expr>, BinaryOp, Box<Expr>),
  Unary(UnaryOp, Box<Expr>),
  Property(Box<Expr>, String),
  Index(Box<Expr>, Box<Expr>),
  Call(Box<Expr>, Vec<Box<Expr>>),
  Constant(Constant),
}

#[derive(Debug)]
pub enum Constant {
  True,
  False,
  Ident(String),
  Number(f64),
  String(String),
  Tuple(Vec<Box<Expr>>),
  Record(HashMap<String, Box<Expr>>),
}

#[derive(Debug)]
pub enum UnaryOp {
  Negate,
  Not,
}

#[derive(Debug)]
pub enum BinaryOp {
  Or,
  And,
  Equal,
  NotEqual,
  GreaterThan,
  GreaterEqual,
  LessThan,
  LessEqual,
  Add,
  Subtract,
  Multiply,
  Divide,
  Exponent,
}

#[derive(Debug)]
pub enum AssignOp {
  Assign,
  AddAssign,
  SubtractAssign,
  MultiplyAssign,
  DivideAssign,
  ExponentAssign,
  OrAssign,
  AndAssign,
}