Skip to main content

dada_ir_sym/check/
temporaries.rs

1use dada_ir_ast::span::Span;
2use serde::Serialize;
3
4use crate::ir::{
5    exprs::{SymExpr, SymPlaceExpr, SymPlaceExprKind},
6    types::{SymGenericKind, SymTy},
7    variables::SymVariable,
8};
9
10/// Translating an expression can result in the creation of
11/// anonymous local temporaries that are injected into the
12/// surrounding scope. These are returned alongside the result
13/// and will eventually be translated into `let-in` expressions
14/// when we reach the surrounding statement, block, or other
15/// terminating context.
16#[derive(Clone, Serialize)]
17pub(crate) struct Temporary<'db> {
18    pub lv: SymVariable<'db>,
19    pub ty: SymTy<'db>,
20    pub initializer: Option<SymExpr<'db>>,
21}
22
23impl<'db> Temporary<'db> {
24    pub fn new(
25        db: &'db dyn crate::Db,
26        span: Span<'db>,
27        ty: SymTy<'db>,
28        initializer: Option<SymExpr<'db>>,
29    ) -> Self {
30        let lv = SymVariable::new(db, SymGenericKind::Place, None, span);
31        Self {
32            lv,
33            ty,
34            initializer,
35        }
36    }
37}
38
39impl<'db> SymExpr<'db> {
40    /// Create a temporary to store the result of this expression.
41    ///
42    /// Returns a reference to the temporary as a place expression.
43    pub(crate) fn into_temporary(
44        self,
45        db: &'db dyn crate::Db,
46        temporaries: &mut Vec<Temporary<'db>>,
47    ) -> SymPlaceExpr<'db> {
48        let ty = self.ty(db);
49        let lv = self.into_temporary_var(db, temporaries);
50        SymPlaceExpr::new(db, self.span(db), ty, SymPlaceExprKind::Var(lv))
51    }
52
53    /// Create a temporary to store the result of this expression.
54    ///
55    /// Returns a reference to the temporary as a variable.
56    pub(crate) fn into_temporary_var(
57        self,
58        db: &'db dyn crate::Db,
59        temporaries: &mut Vec<Temporary<'db>>,
60    ) -> SymVariable<'db> {
61        let ty = self.ty(db);
62
63        // Create a temporary to store the result of this expression.
64        let temporary = Temporary::new(db, self.span(db), ty, Some(self));
65        let lv = temporary.lv;
66        temporaries.push(temporary);
67
68        // The result will be a reference to that temporary.
69        lv
70    }
71}