bool codegen(ast_t* program, pass_opt_t* opt) { if(opt->verbosity >= VERBOSITY_MINIMAL) fprintf(stderr, "Generating\n"); pony_mkdir(opt->output); compile_t c; memset(&c, 0, sizeof(compile_t)); genned_strings_init(&c.strings, 64); ffi_decls_init(&c.ffi_decls, 64); if(!init_module(&c, program, opt)) return false; init_runtime(&c); genprim_reachable_init(&c, program); bool ok; if(c.opt->library) ok = genlib(&c, program); else ok = genexe(&c, program); codegen_cleanup(&c); return ok; }
bool genexe(compile_t* c, ast_t* program) { // The first package is the main package. It has to have a Main actor. const char* main_actor = stringtab("Main"); const char* env_class = stringtab("Env"); ast_t* package = ast_child(program); ast_t* main_def = ast_get(package, main_actor, NULL); if(main_def == NULL) { errorf(NULL, "no Main actor found in package '%s'", c->filename); return false; } // Generate the Main actor and the Env class. ast_t* main_ast = type_builtin(c->opt, main_def, main_actor); ast_t* env_ast = type_builtin(c->opt, main_def, env_class); genprim_reachable_init(c, program); reach(c->reachable, main_ast, stringtab("create"), NULL); reach(c->reachable, env_ast, stringtab("_create"), NULL); paint(c->reachable); gentype_t main_g; gentype_t env_g; bool ok = gentype(c, main_ast, &main_g) && gentype(c, env_ast, &env_g); if(ok) gen_main(c, &main_g, &env_g); ast_free_unattached(main_ast); ast_free_unattached(env_ast); if(!ok) return false; if(!genopt(c)) return false; const char* file_o = genobj(c); if(file_o == NULL) return false; if(c->opt->limit < PASS_ALL) return true; if(!link_exe(c, program, file_o)) return false; #ifdef PLATFORM_IS_WINDOWS _unlink(file_o); #else unlink(file_o); #endif return true; }
bool genlib(compile_t* c, ast_t* program) { genprim_reachable_init(c, program); if(!reachable_actors(c, program) || !generate_actors(c, program) || !genheader(c) ) return false; if(!genopt(c)) return false; const char* file_o = genobj(c); if(file_o == NULL) return false; if(c->opt->limit < PASS_ALL) return true; if(!link_lib(c, file_o)) return false; #ifdef PLATFORM_IS_WINDOWS _unlink(file_o); #else unlink(file_o); #endif return true; }
bool codegen_gen_test(compile_t* c, ast_t* program, pass_opt_t* opt, pass_id last_pass) { if(last_pass < PASS_REACH) { memset(c, 0, sizeof(compile_t)); genned_strings_init(&c->strings, 64); ffi_decls_init(&c->ffi_decls, 64); if(!init_module(c, program, opt)) return false; init_runtime(c); genprim_reachable_init(c, program); const char* main_actor = c->str_Main; const char* env_class = c->str_Env; ast_t* package = ast_child(program); ast_t* main_def = ast_get(package, main_actor, NULL); if(main_def == NULL) return false; ast_t* main_ast = type_builtin(opt, main_def, main_actor); ast_t* env_ast = type_builtin(opt, main_def, env_class); if(lookup(opt, main_ast, main_ast, c->str_create) == NULL) return false; reach(c->reach, main_ast, c->str_create, NULL, opt); reach(c->reach, env_ast, c->str__create, NULL, opt); reach_done(c->reach, c->opt); } if(opt->limit == PASS_REACH) return true; if(last_pass < PASS_PAINT) paint(&c->reach->types); if(opt->limit == PASS_PAINT) return true; if(!gentypes(c)) return false; return true; }
bool codegen(ast_t* program, pass_opt_t* opt) { PONY_LOG(opt, VERBOSITY_MINIMAL, ("Generating\n")); pony_mkdir(opt->output); compile_t c; memset(&c, 0, sizeof(compile_t)); init_module(&c, program, opt); init_runtime(&c); genprim_reachable_init(&c, program); bool ok; if(c.opt->library) ok = genlib(&c, program); else ok = genexe(&c, program); codegen_cleanup(&c); return ok; }