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
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
use crate::ast;
use crate::compiler::{Compiler, Needs};
use crate::error::CompileResult;
use crate::traits::Compile;
use runestick::Inst;

/// Compile an expression.
impl Compile<(&ast::Expr, Needs)> for Compiler<'_, '_> {
    fn compile(&mut self, (expr, needs): (&ast::Expr, Needs)) -> CompileResult<()> {
        let span = expr.span();
        log::trace!("Expr => {:?}", self.source.source(span));

        match expr {
            ast::Expr::Self_(self_) => {
                self.compile((self_, needs))?;
            }
            ast::Expr::Path(path) => {
                self.compile((path, needs))?;
            }
            ast::Expr::ExprWhile(expr_while) => {
                self.compile((expr_while, needs))?;
            }
            ast::Expr::ExprFor(expr_for) => {
                self.compile((expr_for, needs))?;
            }
            ast::Expr::ExprLoop(expr_loop) => {
                self.compile((expr_loop, needs))?;
            }
            ast::Expr::ExprLet(expr_let) => {
                self.compile((expr_let, needs))?;
            }
            ast::Expr::ExprGroup(expr) => {
                self.compile((&*expr.expr, needs))?;
            }
            ast::Expr::ExprUnary(expr_unary) => {
                self.compile((expr_unary, needs))?;
            }
            ast::Expr::ExprBinary(expr_binary) => {
                self.compile((expr_binary, needs))?;
            }
            ast::Expr::ExprIf(expr_if) => {
                self.compile((expr_if, needs))?;
            }
            ast::Expr::ExprIndexSet(expr_index_set) => {
                self.compile((expr_index_set, needs))?;
            }
            ast::Expr::ExprIndexGet(expr_index_get) => {
                self.compile((expr_index_get, needs))?;
            }
            ast::Expr::ExprBreak(expr_break) => {
                self.compile(expr_break)?;
            }
            ast::Expr::ExprYield(expr_yield) => {
                self.compile((expr_yield, needs))?;
            }
            ast::Expr::ExprBlock(expr_block) => {
                self.compile((expr_block, needs))?;
            }
            ast::Expr::ExprReturn(expr_return) => {
                self.compile((expr_return, needs))?;
            }
            ast::Expr::ExprMatch(expr_match) => {
                self.compile((expr_match, needs))?;
            }
            ast::Expr::ExprAwait(expr_await) => {
                self.compile((expr_await, needs))?;
            }
            ast::Expr::ExprTry(expr_try) => {
                self.compile((expr_try, needs))?;
            }
            ast::Expr::ExprSelect(expr_select) => {
                self.compile((expr_select, needs))?;
            }
            ast::Expr::ExprCall(expr_call) => {
                self.compile((expr_call, needs))?;
            }
            ast::Expr::ExprFieldAccess(expr_field_access) => {
                self.compile((expr_field_access, needs))?;
            }
            ast::Expr::ExprClosure(expr_closure) => {
                self.compile((expr_closure, needs))?;
            }
            ast::Expr::LitUnit(lit_unit) => {
                self.compile((lit_unit, needs))?;
            }
            ast::Expr::LitTuple(lit_tuple) => {
                self.compile((lit_tuple, needs))?;
            }
            ast::Expr::LitBool(lit_bool) => {
                self.compile((lit_bool, needs))?;
            }
            ast::Expr::LitNumber(lit_number) => {
                self.compile((lit_number, needs))?;
            }
            ast::Expr::LitVec(lit_vec) => {
                self.compile((lit_vec, needs))?;
            }
            ast::Expr::LitObject(lit_object) => {
                self.compile((lit_object, needs))?;
            }
            ast::Expr::LitChar(lit_char) => {
                self.compile((lit_char, needs))?;
            }
            ast::Expr::LitStr(lit_str) => {
                self.compile((lit_str, needs))?;
            }
            ast::Expr::LitByte(lit_char) => {
                self.compile((lit_char, needs))?;
            }
            ast::Expr::LitByteStr(lit_str) => {
                self.compile((lit_str, needs))?;
            }
            ast::Expr::LitTemplate(lit_template) => {
                self.compile((lit_template, needs))?;
            }
            // NB: declarations are not used in this compilation stage.
            // They have been separately indexed and will be built when queried
            // for.
            ast::Expr::Decl(decl) => {
                let span = decl.span();

                if needs.value() {
                    self.asm.push(Inst::Unit, span);
                }
            }
        }

        Ok(())
    }
}