fn repl_ast_transform(interner: &mut StringInterner, ast: &mut Vec<StmtMeta>) {
        let last_stmt = match ast.pop() {
            Some(stmt) => stmt,
            None => return,
        };

        let (stmt, symbol) = last_stmt.take();
        
        let result_expr;
        if let Stmt::Expression(expr) = stmt {
            result_expr = expr;
        } else {
            ast.push(StmtMeta::new(stmt, symbol));
            result_expr = Expr::Atom(Atom::Nil);
        }
        
        // bind the result expression to a global name
        let result_name = interner.get_or_intern("_");
        let result_decl = Expr::Declaration(Box::new(Declaration {
            decl: DeclType::Immutable,
            lhs: LValue::Identifier(result_name),
            init: result_expr,
        }));
        ast.push(StmtMeta::new(Stmt::Expression(result_decl), symbol));
        
        let return_result = ControlFlow::Return {
            symbol: None, 
            expr: Some(Box::new(
                Expr::Atom(Atom::Identifier(result_name))
            )),
        };
        
        let wrapper = Stmt::Loop {
            label: None,
            body: StmtList::new(Vec::new(), Some(return_result)),
        };
        ast.push(StmtMeta::new(wrapper, symbol));
        
    }
// dirty hack to make the REPL work
dirty hack to make the REPL work
dirty hack to make the REPL work
fn repl_ast_transform(interner: &mut StringInterner, ast: &mut Vec<StmtMeta>) {
        let last_stmt = match ast.pop() {
            Some(stmt) => stmt,
            None => return,
        };
        let (stmt, symbol) = last_stmt.take();
        let result_expr;
        if let Stmt::Expression(expr) = stmt {
            result_expr = expr;
        } else {
            ast.push(StmtMeta::new(stmt, symbol));
            result_expr = Expr::Atom(Atom::Nil);
        }
        // bind the result expression to a global name
        let result_name = interner.get_or_intern("_");
        let result_decl = Expr::Declaration(Box::new(Declaration {
            decl: DeclType::Immutable,
            lhs: LValue::Identifier(result_name),
            init: result_expr,
        }));
        ast.push(StmtMeta::new(Stmt::Expression(result_decl), symbol));
        let return_result = ControlFlow::Return {
            symbol: None, 
            expr: Some(Box::new(
                Expr::Atom(Atom::Identifier(result_name))
            )),
        };
        let wrapper = Stmt::Loop {
            label: None,
            body: StmtList::new(Vec::new(), Some(return_result)),
        };
        ast.push(StmtMeta::new(wrapper, symbol));
    }
fn repl_ast_transform ( interner : & mut StringInterner , ast : & mut Vec < StmtMeta > ) { let last_stmt = match ast . pop ( ) { Some ( stmt ) => stmt , None => return , } ; let ( stmt , symbol ) = last_stmt . take ( ) ; let result_expr ; if let Stmt :: Expression ( expr ) = stmt { result_expr = expr ; } else { ast . push ( StmtMeta :: new ( stmt , symbol ) ) ; result_expr = Expr :: Atom ( Atom :: Nil ) ; } // bind the result expression to a global name let result_name = interner . get_or_intern ( " " ) ; let result_decl = Expr :: Declaration ( Box :: new ( Declaration { decl : DeclType :: Immutable , lhs : LValue :: Identifier ( result_name ) , init : result_expr , } ) ) ; ast . push ( StmtMeta :: new ( Stmt :: Expression ( result_decl ) , symbol ) ) ; let return_result = ControlFlow :: Return { symbol : None , expr : Some ( Box :: new ( Expr :: Atom ( Atom :: Identifier ( result_name ) ) ) ) , } ; let wrapper = Stmt :: Loop { label : None , body : StmtList :: new ( Vec :: new ( ) , Some ( return_result ) ) , } ; ast . push ( StmtMeta :: new ( wrapper , symbol ) ) ; }
dirty hack to make the REPL work
dirty hack to make the REPL work
interner
&mut StringInterner
ast
&mut Vec<StmtMeta>
interner
&mut StringInterner
ast
&mut Vec<StmtMeta>