2020-02-24 01:49:56 +02:00
|
|
|
[InterSkill::] Inter Skill.
|
|
|
|
|
2020-03-30 14:23:06 +03:00
|
|
|
The skills of kit assimilation and of code generation from Inter.
|
2020-02-24 01:49:56 +02:00
|
|
|
|
2020-03-30 14:23:06 +03:00
|
|
|
@h Creation.
|
|
|
|
Note that code generation can only be done internally, and only in fact within
|
|
|
|
the |inform7| compiler: this is because the Inter code which it generates from
|
|
|
|
is being held in memory by |inform7|.
|
|
|
|
|
|
|
|
=
|
2020-02-24 01:49:56 +02:00
|
|
|
build_skill *assimilate_using_inter_skill = NULL;
|
2020-02-24 11:48:40 +02:00
|
|
|
build_skill *code_generate_using_inter_skill = NULL;
|
2020-02-24 01:49:56 +02:00
|
|
|
|
|
|
|
void InterSkill::create(void) {
|
2020-03-30 14:23:06 +03:00
|
|
|
assimilate_using_inter_skill =
|
|
|
|
BuildSteps::new_skill(I"assimilate using inter");
|
|
|
|
METHOD_ADD(assimilate_using_inter_skill, BUILD_SKILL_COMMAND_MTID,
|
|
|
|
InterSkill::assimilate_via_shell);
|
|
|
|
METHOD_ADD(assimilate_using_inter_skill, BUILD_SKILL_INTERNAL_MTID,
|
|
|
|
InterSkill::assimilate_internally);
|
|
|
|
|
|
|
|
code_generate_using_inter_skill =
|
|
|
|
BuildSteps::new_skill(I"code generate using inter");
|
|
|
|
METHOD_ADD(code_generate_using_inter_skill, BUILD_SKILL_INTERNAL_MTID,
|
|
|
|
InterSkill::code_generate_internally);
|
2020-02-24 01:49:56 +02:00
|
|
|
}
|
|
|
|
|
2020-03-30 14:23:06 +03:00
|
|
|
@h Assimilation.
|
|
|
|
|
|
|
|
=
|
|
|
|
int InterSkill::assimilate_via_shell(build_skill *skill, build_step *S,
|
2020-05-05 23:59:02 +03:00
|
|
|
text_stream *command, build_methodology *BM, linked_list *search_list) {
|
2020-02-24 01:49:56 +02:00
|
|
|
inter_architecture *A = S->for_arch;
|
|
|
|
if (A == NULL) internal_error("no architecture given");
|
|
|
|
pathname *kit_path = S->associated_copy->location_if_path;
|
2020-03-30 14:23:06 +03:00
|
|
|
Shell::quote_file(command, BM->to_inter);
|
2020-02-24 01:49:56 +02:00
|
|
|
WRITE_TO(command, "-architecture %S ", Architectures::to_codename(A));
|
|
|
|
WRITE_TO(command, "-assimilate ");
|
|
|
|
Shell::quote_path(command, kit_path);
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2020-03-30 14:23:06 +03:00
|
|
|
@ Something to watch out for here is that, when running internally as part of
|
|
|
|
|inform7|, we use the copy of the |assimilate| pipeline inside the installation
|
|
|
|
of |inform7| (it will be in the internal nest). When we perform assimilation
|
|
|
|
from the command line using the |inter| tool, we use the |assimilate| pipeline
|
|
|
|
supplied in the |inter| installation. But those two files are in fact the same,
|
|
|
|
or should be, so the effect is the same.
|
|
|
|
|
|
|
|
=
|
|
|
|
int InterSkill::assimilate_internally(build_skill *skill, build_step *S,
|
2020-05-05 23:59:02 +03:00
|
|
|
build_methodology *BM, linked_list *search_list) {
|
2020-02-24 01:49:56 +02:00
|
|
|
#ifdef CODEGEN_MODULE
|
|
|
|
inter_architecture *A = S->for_arch;
|
|
|
|
if (A == NULL) internal_error("no architecture given");
|
|
|
|
|
|
|
|
pathname *kit_path = S->associated_copy->location_if_path;
|
2020-03-30 14:23:06 +03:00
|
|
|
dictionary *pipeline_vars = CodeGen::Pipeline::basic_dictionary(NULL);
|
2020-02-24 01:49:56 +02:00
|
|
|
|
|
|
|
inbuild_requirement *req =
|
2020-03-30 14:23:06 +03:00
|
|
|
Requirements::any_version_of(
|
|
|
|
Works::new(pipeline_genre, I"assimilate.interpipeline", NULL));
|
2020-05-05 23:59:02 +03:00
|
|
|
inbuild_search_result *R =
|
|
|
|
Nests::search_for_best(req, search_list);
|
2020-03-10 12:08:45 +02:00
|
|
|
if (R == NULL) {
|
2020-02-24 01:49:56 +02:00
|
|
|
Errors::nowhere("assimilate pipeline could not be found");
|
|
|
|
return FALSE;
|
|
|
|
}
|
2020-03-10 12:08:45 +02:00
|
|
|
filename *pipeline_as_file = R->copy->location_if_file;
|
2020-02-24 01:49:56 +02:00
|
|
|
|
|
|
|
filename *assim = Architectures::canonical_binary(kit_path, A);
|
|
|
|
filename *assim_t = Architectures::canonical_textual(kit_path, A);
|
|
|
|
TEMPORARY_TEXT(fullname);
|
|
|
|
WRITE_TO(fullname, "%f", assim);
|
|
|
|
Str::copy(Dictionaries::create_text(pipeline_vars, I"*out"), fullname);
|
|
|
|
Str::clear(fullname);
|
|
|
|
WRITE_TO(fullname, "%f", assim_t);
|
|
|
|
Str::copy(Dictionaries::create_text(pipeline_vars, I"*outt"), fullname);
|
|
|
|
DISCARD_TEXT(fullname);
|
2020-03-30 14:23:06 +03:00
|
|
|
Str::copy(Dictionaries::create_text(pipeline_vars, I"*kit"),
|
|
|
|
Pathnames::directory_name(kit_path));
|
2020-02-24 01:49:56 +02:00
|
|
|
|
|
|
|
linked_list *inter_paths = NEW_LINKED_LIST(pathname);
|
|
|
|
ADD_TO_LINKED_LIST(S->associated_copy->location_if_path, pathname, inter_paths);
|
2020-03-30 14:23:06 +03:00
|
|
|
codegen_pipeline *SS =
|
|
|
|
CodeGen::Pipeline::parse_from_file(pipeline_as_file, pipeline_vars);
|
2020-02-24 01:49:56 +02:00
|
|
|
if (SS) {
|
|
|
|
linked_list *requirements_list = NEW_LINKED_LIST(inter_library);
|
|
|
|
CodeGen::Pipeline::run(NULL, SS, inter_paths, requirements_list);
|
|
|
|
return TRUE;
|
|
|
|
} else {
|
|
|
|
Errors::nowhere("assimilate pipeline could not be parsed");
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
return FALSE;
|
|
|
|
}
|
2020-02-24 11:48:40 +02:00
|
|
|
|
2020-03-30 14:23:06 +03:00
|
|
|
@h Code generation.
|
|
|
|
This can only be done internally, for reasons given above, and only when the
|
|
|
|
|codegen| module is present in the current executable (which in practice means:
|
|
|
|
only inside |inform7|).
|
|
|
|
|
|
|
|
Recall that the |inter_pipeline_name| is managed in Inbuild Control, but that
|
|
|
|
it defaults to |compile|.
|
|
|
|
|
|
|
|
=
|
|
|
|
int InterSkill::code_generate_internally(build_skill *skill, build_step *S,
|
2020-05-05 23:59:02 +03:00
|
|
|
build_methodology *BM, linked_list *search_list) {
|
|
|
|
inform_project *project = ProjectBundleManager::from_copy(S->associated_copy);
|
|
|
|
if (project == NULL) project = ProjectFileManager::from_copy(S->associated_copy);
|
|
|
|
if (project == NULL) internal_error("no project");
|
2020-02-25 01:16:59 +02:00
|
|
|
#ifdef CODEGEN_MODULE
|
|
|
|
clock_t back_end = clock();
|
|
|
|
CodeGen::Architecture::set(
|
|
|
|
Architectures::to_codename(
|
|
|
|
TargetVMs::get_architecture(S->for_vm)));
|
|
|
|
Str::copy(Dictionaries::create_text(pipeline_vars, I"*in"), I"*memory");
|
|
|
|
Str::copy(Dictionaries::create_text(pipeline_vars, I"*out"),
|
2020-03-30 14:23:06 +03:00
|
|
|
Filenames::get_leafname(S->vertex->as_file));
|
2020-02-25 01:16:59 +02:00
|
|
|
|
2020-03-28 01:17:16 +02:00
|
|
|
filename *F = inter_pipeline_file;
|
|
|
|
if (F == NULL) {
|
2020-02-25 01:16:59 +02:00
|
|
|
inbuild_requirement *req =
|
2020-03-30 14:23:06 +03:00
|
|
|
Requirements::any_version_of(
|
|
|
|
Works::new(pipeline_genre, inter_pipeline_name, NULL));
|
2020-05-05 23:59:02 +03:00
|
|
|
inbuild_search_result *R = Nests::search_for_best(req, search_list);
|
2020-03-10 12:08:45 +02:00
|
|
|
if (R == NULL) {
|
2020-03-30 14:23:06 +03:00
|
|
|
Errors::with_text("inter pipeline '%S' could not be found",
|
|
|
|
inter_pipeline_name);
|
2020-03-10 12:08:45 +02:00
|
|
|
return FALSE;
|
2020-02-25 01:16:59 +02:00
|
|
|
}
|
2020-03-28 01:17:16 +02:00
|
|
|
F = R->copy->location_if_file;
|
|
|
|
}
|
|
|
|
codegen_pipeline *SS = CodeGen::Pipeline::parse_from_file(F, pipeline_vars);
|
|
|
|
if (SS == NULL) {
|
|
|
|
Errors::nowhere("inter pipeline file could not be parsed");
|
|
|
|
return FALSE;
|
2020-02-25 01:16:59 +02:00
|
|
|
}
|
|
|
|
CodeGen::Pipeline::set_repository(SS, Emit::tree());
|
2020-04-16 01:49:59 +03:00
|
|
|
CodeGen::Pipeline::run(Filenames::up(S->vertex->as_file),
|
2020-05-05 23:59:02 +03:00
|
|
|
SS, Kits::inter_paths(Projects::nest_list(project)),
|
|
|
|
Projects::list_of_link_instructions(project));
|
2020-03-30 14:23:06 +03:00
|
|
|
LOG("Back end elapsed time: %dcs\n",
|
|
|
|
((int) (clock() - back_end)) / (CLOCKS_PER_SEC/100));
|
2020-02-25 01:16:59 +02:00
|
|
|
return TRUE;
|
2020-02-24 11:48:40 +02:00
|
|
|
#endif
|
2020-02-25 01:16:59 +02:00
|
|
|
#ifndef CORE_MODULE
|
2020-02-24 11:48:40 +02:00
|
|
|
return FALSE;
|
2020-02-25 01:16:59 +02:00
|
|
|
#endif
|
2020-02-24 11:48:40 +02:00
|
|
|
}
|