fn compile_ast(ast: Vec<Box<ModStmtAst>>, name: &str) -> Result<Module, GearsError> {
    let mut module_builder = ModuleBuilder::new(String::from(name));
    let mut symbol_table = SymbolTable::new_global();

    // Add all the top level functions to the scope before parsing so we can
    // use them during parse as they will resolve
    for ref mod_stmt in &ast {
        match mod_stmt.as_ref() {
            ModStmtAst::FunctionDef {
                name,
                args,
                return_type,
                ..
            } => {
                let mut arg_types = HashMap::new();

                for arg in args {
                    arg_types.insert(arg.name().clone(), compile_types(arg.arg_types()));
                }

                symbol_table.def_fn(name.clone(), arg_types, compile_types(return_type));
            }
        }
    }

    for ref mod_stmt in &ast {
        match mod_stmt.as_ref() {
            ModStmtAst::FunctionDef {
                name,
                exprs,
                args,
                return_type,
                ..
            } => {
                module_builder.start_function(name.clone(), args.len());
                let mut local_scope = (&symbol_table).push();

                for arg in args {
                    local_scope.def_variable(arg.name().clone(), compile_types(arg.arg_types()));
                }

                let block_type = visit_block(exprs, &mut local_scope, &mut module_builder)?;
                let return_types = compile_types(return_type);

                for expr_type in &block_type {
                    if !return_types.contains(expr_type) {
                        return Err(GearsError::TypeError(format!(
                            "{:?} is not compatible with {:?}",
                            return_types, block_type
                        )));
                    }
                }

                module_builder.finish_function();
            }
        }
    }

    Ok(module_builder.build())
}
/// Compiles AST to Module and Bytecode
Compiles AST to Module and Bytecode
Compiles AST to Module and Bytecode
fn compile_ast(ast: Vec<Box<ModStmtAst>>, name: &str) -> Result<Module, GearsError> {
    let mut module_builder = ModuleBuilder::new(String::from(name));
    let mut symbol_table = SymbolTable::new_global();
    // Add all the top level functions to the scope before parsing so we can
    // use them during parse as they will resolve
    for ref mod_stmt in &ast {
        match mod_stmt.as_ref() {
            ModStmtAst::FunctionDef {
                name,
                args,
                return_type,
                ..
            } => {
                let mut arg_types = HashMap::new();
                for arg in args {
                    arg_types.insert(arg.name().clone(), compile_types(arg.arg_types()));
                }
                symbol_table.def_fn(name.clone(), arg_types, compile_types(return_type));
            }
        }
    }
    for ref mod_stmt in &ast {
        match mod_stmt.as_ref() {
            ModStmtAst::FunctionDef {
                name,
                exprs,
                args,
                return_type,
                ..
            } => {
                module_builder.start_function(name.clone(), args.len());
                let mut local_scope = (&symbol_table).push();
                for arg in args {
                    local_scope.def_variable(arg.name().clone(), compile_types(arg.arg_types()));
                }
                let block_type = visit_block(exprs, &mut local_scope, &mut module_builder)?;
                let return_types = compile_types(return_type);
                for expr_type in &block_type {
                    if !return_types.contains(expr_type) {
                        return Err(GearsError::TypeError(format!(
                            "{:?} is not compatible with {:?}",
                            return_types, block_type
                        )));
                    }
                }
                module_builder.finish_function();
            }
        }
    }
    Ok(module_builder.build())
}
fn compile_ast ( ast : Vec < Box < ModStmtAst > > , name : & str ) -> Result < Module , GearsError > { let mut module_builder = ModuleBuilder :: new ( String :: from ( name ) ) ; let mut symbol_table = SymbolTable :: new_global ( ) ; // Add all the top level functions to the scope before parsing so we can // use them during parse as they will resolve for ref mod_stmt in & ast { match mod_stmt . as_ref ( ) { ModStmtAst :: FunctionDef { name , args , return_type , .. } => { let mut arg_types = HashMap :: new ( ) ; for arg in args { arg_types . insert ( arg . name ( ) . clone ( ) , compile_types ( arg . arg_types ( ) ) ) ; } symbol_table . def_fn ( name . clone ( ) , arg_types , compile_types ( return_type ) ) ; } } } for ref mod_stmt in & ast { match mod_stmt . as_ref ( ) { ModStmtAst :: FunctionDef { name , exprs , args , return_type , .. } => { module_builder . start_function ( name . clone ( ) , args . len ( ) ) ; let mut local_scope = ( & symbol_table ) . push ( ) ; for arg in args { local_scope . def_variable ( arg . name ( ) . clone ( ) , compile_types ( arg . arg_types ( ) ) ) ; } let block_type = visit_block ( exprs , & mut local_scope , & mut module_builder ) ? ; let return_types = compile_types ( return_type ) ; for expr_type in & block_type { if ! return_types . contains ( expr_type ) { return Err ( GearsError :: TypeError ( format ! ( " " return_types block_type ) ) ) ; } } module_builder . finish_function ( ) ; } } } Ok ( module_builder . build ( ) ) }
Compiles AST to Module and Bytecode
Compiles AST to Module and Bytecode
ast
Vec<Box<ModStmtAst>>
name
&str