Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Final Desugarings

At the end of these series of steps, everything is explicit and we’ve reached the final language.

The rest of this section is a work-in-progress experiment about making the book executable.


pub fn desugar_final(program: &mut Program) -> Result<(), CompilationError> {
    program.visit_all_mut_infallible(|block: &mut BlockExpression| {
        split_let_initializers(block);
    });
    Ok(())
}

As a final cleanup, we split let-statements with an initializer into a declaration followed by assignment:

#![allow(unused)]
fn main() {
let x = val;
// becomes
let x;
x = val;
}
fn split_let_initializers(block: &mut BlockExpression) {
    let statements = std::mem::take(&mut block.statements);
    for statement in statements {
        if let Statement::Let {
            attrs,
            scope,
            pattern: Pattern::Identifier(name),
            ty,
            initial_value: Some(value),
            else_branch: None,
        } = statement
        {
            block.statements.push(Statement::Let {
                attrs,
                scope,
                pattern: Pattern::Identifier(name.clone()),
                ty,
                initial_value: None,
                else_branch: None,
            });
            let assignment = Expression::new(ExpressionKind::Operator(Box::new(
                OperatorExpression::Assignment(Expression::new(ExpressionKind::Path(name)), value),
            )));
            block.statements.push(Statement::Expr(assignment));
        } else {
            block.statements.push(statement)
        }
    }
}