To create the stages through which code generation proceeds.
§1. Stages. Each possible pipeline stage is represented by a single instance of the following. Some stages are invoked with an argument, often the filename to write output to; others are not.
enum NO_STAGE_ARG from 1 enum GENERAL_STAGE_ARG enum FILE_STAGE_ARG enum TEXT_OUT_STAGE_ARG enum EXT_FILE_STAGE_ARG enum EXT_TEXT_OUT_STAGE_ARG enum TEMPLATE_FILE_STAGE_ARG
typedef struct pipeline_stage { struct text_stream *stage_name; int (*execute)(void *); int stage_arg; one of the *_ARG values above int takes_repository; MEMORY_MANAGEMENT } pipeline_stage; pipeline_stage *CodeGen::Stage::new(text_stream *name, int (*X)(struct pipeline_step *), int arg, int tr) { pipeline_stage *stage = CREATE(pipeline_stage); stage->stage_name = Str::duplicate(name); stage->execute = (int (*)(void *)) X; stage->stage_arg = arg; stage->takes_repository = tr; return stage; }
- The structure pipeline_stage is accessed in 1/ppl and here.
§2. Creation. To add a new pipeline stage, put the code for it into a new section in Chapter 2, and then add a call to its create_pipeline_stage routine to the routine below.
int stages_made = FALSE; void CodeGen::Stage::make_stages(void) { if (stages_made == FALSE) { stages_made = TRUE; CodeGen::Stage::new(I"stop", CodeGen::Stage::run_stop_stage, NO_STAGE_ARG, FALSE); CodeGen::Stage::new(I"wipe", CodeGen::Stage::run_wipe_stage, NO_STAGE_ARG, FALSE); CodeGen::Stage::new(I"read", CodeGen::Stage::run_read_stage, FILE_STAGE_ARG, TRUE); CodeGen::Stage::new(I"move", CodeGen::Stage::run_move_stage, GENERAL_STAGE_ARG, TRUE); CodeGen::create_pipeline_stage(); CodeGen::Architecture::create_pipeline_stage(); CodeGen::LinkInstructions::create_pipeline_stage(); CodeGen::Assimilate::create_pipeline_stage(); CodeGen::Eliminate::create_pipeline_stage(); CodeGen::Externals::create_pipeline_stage(); CodeGen::Inspection::create_pipeline_stage(); CodeGen::Labels::create_pipeline_stage(); CodeGen::MergeTemplate::create_pipeline_stage(); CodeGen::PLM::create_pipeline_stage(); CodeGen::RCC::create_pipeline_stage(); CodeGen::ReconcileVerbs::create_pipeline_stage(); CodeGen::Uniqueness::create_pipeline_stage(); } }
§3. The "stop" stage is special, in that it always returns false, thus stopping the pipeline:
int CodeGen::Stage::run_stop_stage(pipeline_step *step) { return FALSE; } int CodeGen::Stage::run_wipe_stage(pipeline_step *step) { Inter::Warehouse::wipe(); return TRUE; } int CodeGen::Stage::run_read_stage(pipeline_step *step) { filename *F = step->parsed_filename; if (Inter::Binary::test_file(F)) Inter::Binary::read(step->repository, F); else Inter::Textual::read(step->repository, F); return TRUE; } int CodeGen::Stage::run_move_stage(pipeline_step *step) { match_results mr = Regexp::create_mr(); inter_package *pack = NULL; if (Regexp::match(&mr, step->step_argument, L"(%d):(%c+)")) { int from_rep = Str::atoi(mr.exp[0], 0); if (step->pipeline->repositories[from_rep] == NULL) internal_error("no such repository"); pack = Inter::Packages::by_url( step->pipeline->repositories[from_rep], mr.exp[1]); } Regexp::dispose_of(&mr); if (pack == NULL) internal_error("not a package"); Inter::Transmigration::move(pack, Site::main_package(step->repository), FALSE); return TRUE; }