mirror of
https://github.com/ganelson/inform.git
synced 2024-06-17 07:40:47 +03:00
Improved supervisor's handling of stand-alone I7 source files
This commit is contained in:
parent
850901508d
commit
9fe3a62c25
|
@ -1,6 +1,6 @@
|
|||
# Inform 7
|
||||
|
||||
v10.1.0-alpha.1+6T22 'Krypton' (11 September 2021)
|
||||
v10.1.0-alpha.1+6T23 'Krypton' (12 September 2021)
|
||||
|
||||
## About Inform 7
|
||||
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
Prerelease: alpha.1
|
||||
Build Date: 11 September 2021
|
||||
Build Number: 6T22
|
||||
Build Date: 12 September 2021
|
||||
Build Number: 6T23
|
||||
|
|
|
@ -95,10 +95,12 @@ better way to choose a virtual machine to compile to.
|
|||
@e INBUILD_INFORM_CLSG
|
||||
|
||||
@e PROJECT_CLSW
|
||||
@e BASIC_CLSW
|
||||
@e DEBUG_CLSW
|
||||
@e RELEASE_CLSW
|
||||
@e FORMAT_CLSW
|
||||
@e SOURCE_CLSW
|
||||
@e O_CLSW
|
||||
@e CENSUS_CLSW
|
||||
@e RNG_CLSW
|
||||
@e CASE_CLSW
|
||||
|
@ -107,6 +109,8 @@ better way to choose a virtual machine to compile to.
|
|||
CommandLine::begin_group(INBUILD_INFORM_CLSG, I"for translating Inform source text to Inter");
|
||||
CommandLine::declare_switch(PROJECT_CLSW, L"project", 2,
|
||||
L"work within the Inform project X");
|
||||
CommandLine::declare_switch(BASIC_CLSW, L"basic", 1,
|
||||
L"use Basic Inform language (same as -kit BasicInformKit)");
|
||||
CommandLine::declare_boolean_switch(DEBUG_CLSW, L"debug", 1,
|
||||
L"compile with debugging features even on a Release", FALSE);
|
||||
CommandLine::declare_boolean_switch(RELEASE_CLSW, L"release", 1,
|
||||
|
@ -115,6 +119,8 @@ better way to choose a virtual machine to compile to.
|
|||
L"compile I6 code suitable for the virtual machine X");
|
||||
CommandLine::declare_switch(SOURCE_CLSW, L"source", 2,
|
||||
L"use file X as the Inform source text");
|
||||
CommandLine::declare_switch(O_CLSW, L"o", 2,
|
||||
L"use file X as the compiled output (not for use with -project)");
|
||||
CommandLine::declare_boolean_switch(CENSUS_CLSW, L"census", 1,
|
||||
L"perform an extensions census", FALSE);
|
||||
CommandLine::declare_boolean_switch(RNG_CLSW, L"rng", 1,
|
||||
|
@ -150,15 +156,12 @@ but |-pipeline-file| and |-variable| have the same effect as they would there.
|
|||
@e INBUILD_INTER_CLSG
|
||||
|
||||
@e KIT_CLSW
|
||||
@e BASIC_CLSW
|
||||
@e PIPELINE_CLSW
|
||||
@e PIPELINE_FILE_CLSW
|
||||
@e PIPELINE_VARIABLE_CLSW
|
||||
|
||||
@<Declare Inter-related options@> =
|
||||
CommandLine::begin_group(INBUILD_INTER_CLSG, I"for tweaking code generation from Inter");
|
||||
CommandLine::declare_switch(BASIC_CLSW, L"basic", 1,
|
||||
L"use Basic Inform language (same as -kit BasicInformKit)");
|
||||
CommandLine::declare_switch(KIT_CLSW, L"kit", 2,
|
||||
L"include Inter code from the kit called X");
|
||||
CommandLine::declare_switch(PIPELINE_CLSW, L"pipeline", 2,
|
||||
|
@ -174,6 +177,7 @@ set appropriately.
|
|||
|
||||
=
|
||||
filename *inter_pipeline_file = NULL;
|
||||
filename *transpiled_output_file = NULL;
|
||||
dictionary *pipeline_vars = NULL;
|
||||
pathname *shared_transient_resources = NULL;
|
||||
int this_is_a_debug_compile = FALSE; /* Destined to be compiled with debug features */
|
||||
|
@ -206,7 +210,7 @@ void Supervisor::set_inter_pipeline(text_stream *name) {
|
|||
|
||||
@ The //supervisor// module itself doesn't parse command-line options: that's for
|
||||
the parent to do, using code from Foundation. When the parent finds an option
|
||||
it doesn't know about, that will be one of ourse, so it should call the following:
|
||||
it doesn't know about, that will be one of ours, so it should call the following:
|
||||
|
||||
=
|
||||
void Supervisor::option(int id, int val, text_stream *arg, void *state) {
|
||||
|
@ -233,6 +237,7 @@ void Supervisor::option(int id, int val, text_stream *arg, void *state) {
|
|||
if (Supervisor::set_I7_source(arg) == FALSE)
|
||||
Errors::fatal_with_text("can't specify the source file twice: '%S'", arg);
|
||||
break;
|
||||
case O_CLSW: transpiled_output_file = Filenames::from_text(arg); break;
|
||||
case CENSUS_CLSW: census_mode = val; break;
|
||||
case PIPELINE_CLSW: inter_pipeline_name = Str::duplicate(arg); break;
|
||||
case PIPELINE_FILE_CLSW: inter_pipeline_file = Filenames::from_text(arg); break;
|
||||
|
@ -559,7 +564,10 @@ void Supervisor::make_project_from_command_line(inbuild_copy *C) {
|
|||
else if (C->edition->work->genre == project_file_genre)
|
||||
proj = ProjectFileManager::from_copy(C);
|
||||
else internal_error("chosen project is not a project");
|
||||
if (F) Projects::set_primary_source(proj, F);
|
||||
if (F) {
|
||||
Projects::set_primary_source(proj, F);
|
||||
Projects::set_primary_output(proj, transpiled_output_file);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -44,6 +44,7 @@ typedef struct build_vertex {
|
|||
int build_result; /* whether the most recent build of this succeeded... */
|
||||
int last_built_in_generation; /* ...in this build generation */
|
||||
int always_build_this; /* i.e., don't look at timestamps hoping to skip it */
|
||||
int always_build_dependencies; /* if you build this, first always build its dependencies */
|
||||
struct build_script *script; /* how to build what this node represents */
|
||||
|
||||
CLASS_DEFINITION
|
||||
|
@ -71,6 +72,7 @@ build_vertex *Graphs::file_vertex(filename *F) {
|
|||
V->build_result = NOT_APPLICABLE; /* has never been built */
|
||||
V->last_built_in_generation = -1; /* never seen in any generation */
|
||||
V->always_build_this = FALSE;
|
||||
V->always_build_dependencies = FALSE;
|
||||
V->script = BuildScripts::new();
|
||||
return V;
|
||||
}
|
||||
|
|
|
@ -89,6 +89,7 @@ to build. As we recurse, we pass a bitmap of the following:
|
|||
@d BUILD_DEPENDENCIES_MATTER_GB 1 /* We will need all your build dependencies too */
|
||||
@d USE_DEPENDENCIES_MATTER_GB 2 /* We will need all your use dependencies too */
|
||||
@d IGNORE_TIMESTAMPS_GB 4 /* Don't be incremental: trust nothing, rebuild everything */
|
||||
@d FOR_ONE_GENERATION_IGNORE_TIMESTAMPS_GB 8 /* Don't be incremental: trust nothing, rebuild everything */
|
||||
|
||||
=
|
||||
int IncrementalBuild::build(OUTPUT_STREAM, build_vertex *V, build_methodology *meth) {
|
||||
|
@ -181,24 +182,30 @@ building V is itself a use of W, and therefore of X. So we always enable the
|
|||
|USE_DEPENDENCIES_MATTER_GB| bit when recursing through an edge.
|
||||
|
||||
@<Build the build dependencies of the node@> =
|
||||
int b = gb | USE_DEPENDENCIES_MATTER_GB;
|
||||
if (b & FOR_ONE_GENERATION_IGNORE_TIMESTAMPS_GB) b -= FOR_ONE_GENERATION_IGNORE_TIMESTAMPS_GB;
|
||||
if (V->always_build_dependencies) b |= FOR_ONE_GENERATION_IGNORE_TIMESTAMPS_GB;
|
||||
build_vertex *W;
|
||||
LOOP_OVER_LINKED_LIST(W, build_vertex, V->build_edges)
|
||||
if (rv)
|
||||
rv = IncrementalBuild::recurse(OUT, T,
|
||||
gb | USE_DEPENDENCIES_MATTER_GB, W, BM, changes, generation, search_list);
|
||||
b, W, BM, changes, generation, search_list);
|
||||
|
||||
@<Build the use dependencies of the node@> =
|
||||
int b = gb | USE_DEPENDENCIES_MATTER_GB;
|
||||
if (b & FOR_ONE_GENERATION_IGNORE_TIMESTAMPS_GB) b -= FOR_ONE_GENERATION_IGNORE_TIMESTAMPS_GB;
|
||||
build_vertex *W;
|
||||
LOOP_OVER_LINKED_LIST(W, build_vertex, V->use_edges)
|
||||
if (rv)
|
||||
rv = IncrementalBuild::recurse(OUT, T,
|
||||
gb | USE_DEPENDENCIES_MATTER_GB, W, BM, changes, generation, search_list);
|
||||
b | USE_DEPENDENCIES_MATTER_GB, W, BM, changes, generation, search_list);
|
||||
|
||||
@ Now for the node |V| itself.
|
||||
|
||||
@<Build the node itself, if necessary@> =
|
||||
int needs_building = FALSE;
|
||||
if ((gb & IGNORE_TIMESTAMPS_GB) || (V->always_build_this)) needs_building = TRUE;
|
||||
if ((gb & IGNORE_TIMESTAMPS_GB) || (gb & FOR_ONE_GENERATION_IGNORE_TIMESTAMPS_GB) ||
|
||||
(V->always_build_this)) needs_building = TRUE;
|
||||
else @<Decide based on timestamps@>;
|
||||
|
||||
if (needs_building) {
|
||||
|
|
|
@ -72,7 +72,10 @@ void ProjectFileManager::claim_as_copy(inbuild_genre *gen, inbuild_copy **C,
|
|||
}
|
||||
|
||||
inbuild_copy *ProjectFileManager::claim_file_as_copy(filename *F) {
|
||||
return ProjectFileManager::new_copy(Filenames::get_leafname(F), F);
|
||||
inbuild_copy *C = ProjectFileManager::new_copy(Filenames::get_leafname(F), F);
|
||||
inform_project *proj = ProjectFileManager::from_copy(C);
|
||||
proj->stand_alone = TRUE;
|
||||
return C;
|
||||
}
|
||||
|
||||
@h Searching.
|
||||
|
@ -110,5 +113,5 @@ void ProjectFileManager::building_soon(inbuild_genre *gen, inbuild_copy *C, buil
|
|||
|
||||
=
|
||||
void ProjectFileManager::read_source_text_for(inbuild_genre *G, inbuild_copy *C) {
|
||||
Projects::read_source_text_for(ProjectBundleManager::from_copy(C));
|
||||
Projects::read_source_text_for(ProjectFileManager::from_copy(C));
|
||||
}
|
||||
|
|
|
@ -9,9 +9,11 @@ in the following structure.
|
|||
=
|
||||
typedef struct inform_project {
|
||||
struct inbuild_copy *as_copy;
|
||||
int stand_alone; /* rather than being in a .inform project bundle */
|
||||
struct inbuild_nest *materials_nest;
|
||||
struct linked_list *search_list; /* of |inbuild_nest| */
|
||||
struct filename *primary_source;
|
||||
struct filename *primary_output;
|
||||
struct semantic_version_number version;
|
||||
struct linked_list *source_vertices; /* of |build_vertex| */
|
||||
struct linked_list *kits_to_include; /* of |kit_dependency| */
|
||||
|
@ -40,7 +42,7 @@ void Projects::scan(inbuild_copy *C) {
|
|||
proj->as_copy = C;
|
||||
if (C == NULL) internal_error("no copy to scan");
|
||||
Copies::set_metadata(C, STORE_POINTER_inform_project(proj));
|
||||
|
||||
proj->stand_alone = FALSE;
|
||||
proj->version = VersionNumbers::null();
|
||||
proj->source_vertices = NEW_LINKED_LIST(build_vertex);
|
||||
proj->kits_to_include = NEW_LINKED_LIST(kit_dependency);
|
||||
|
@ -62,8 +64,6 @@ void Projects::scan(inbuild_copy *C) {
|
|||
M = Projects::materialise_pathname(
|
||||
P, Filenames::get_leafname(proj->as_copy->location_if_file));
|
||||
proj->materials_nest = Supervisor::add_nest(M, MATERIALS_NEST_TAG);
|
||||
// proj->materials_nest = Nests::new(M);
|
||||
// Nests::set_tag(proj->materials_nest, MATERIALS_NEST_TAG);
|
||||
proj->search_list = NEW_LINKED_LIST(inbuild_nest);
|
||||
proj->primary_source = NULL;
|
||||
proj->extensions_included = NEW_LINKED_LIST(inform_extension);
|
||||
|
@ -87,6 +87,16 @@ pathname *Projects::materialise_pathname(pathname *in, text_stream *leaf) {
|
|||
return materials;
|
||||
}
|
||||
|
||||
@ Returns |TRUE| for a project arising from a single file, |FALSE| for a
|
||||
project in a |.inform| bundle. (Withing the UI apps, then, all projects return
|
||||
|FALSE| here; it's only command-line use of Inform which involves stand-alone files.)
|
||||
|
||||
=
|
||||
int Projects::stand_alone(inform_project *proj) {
|
||||
if (proj == NULL) return FALSE;
|
||||
return proj->stand_alone;
|
||||
}
|
||||
|
||||
@ The file-system path to the project. For a "bundle" made by the Inform GUI
|
||||
apps, the bundle itself is a directory (even if this is concealed from the
|
||||
user on macOS) and the following returns that path. For a loose file of
|
||||
|
@ -490,6 +500,25 @@ linked_list *Projects::list_of_link_instructions(inform_project *project) {
|
|||
}
|
||||
#endif
|
||||
|
||||
@h File to write to.
|
||||
|
||||
=
|
||||
void Projects::set_primary_output(inform_project *proj, filename *F) {
|
||||
proj->primary_output = F;
|
||||
}
|
||||
|
||||
filename *Projects::get_primary_output(inform_project *proj) {
|
||||
if (proj->primary_output) return proj->primary_output;
|
||||
if (proj->stand_alone) {
|
||||
return Filenames::set_extension(proj->primary_source,
|
||||
TargetVMs::get_transpiled_extension(
|
||||
Supervisor::current_vm()));
|
||||
} else {
|
||||
pathname *build_folder = Projects::build_path(proj);
|
||||
return Filenames::in(build_folder, I"auto.inf");
|
||||
}
|
||||
}
|
||||
|
||||
@h The full graph.
|
||||
This can be quite grandiose even though most of it will never come to anything,
|
||||
rather like a family tree for a minor European royal family.
|
||||
|
@ -548,8 +577,7 @@ for a release of a blorbed one.
|
|||
|
||||
@<Construct the graph upstream of V@> =
|
||||
target_vm *VM = Supervisor::current_vm();
|
||||
pathname *build_folder = Projects::build_path(proj);
|
||||
filename *inf_F = Filenames::in(build_folder, I"auto.inf");
|
||||
filename *inf_F = Projects::get_primary_output(proj);
|
||||
|
||||
/* vertex for the inter code put together in memory */
|
||||
build_vertex *inter_V = Graphs::file_vertex(inf_F);
|
||||
|
@ -557,36 +585,44 @@ for a release of a blorbed one.
|
|||
BuildSteps::attach(inter_V, compile_using_inform7_skill,
|
||||
proj->compile_for_release, VM, NULL, proj->as_copy);
|
||||
|
||||
/* vertex for the Inform 6 code file code-generated from that */
|
||||
/* vertex for the final code file code-generated from that */
|
||||
build_vertex *inf_V = Graphs::file_vertex(inf_F);
|
||||
inf_V->always_build_dependencies = TRUE;
|
||||
Graphs::need_this_to_build(inf_V, inter_V);
|
||||
BuildSteps::attach(inf_V, code_generate_using_inter_skill,
|
||||
proj->compile_for_release, VM, NULL, proj->as_copy);
|
||||
|
||||
TEMPORARY_TEXT(story_file_leafname)
|
||||
WRITE_TO(story_file_leafname, "output.%S", TargetVMs::get_unblorbed_extension(VM));
|
||||
filename *unblorbed_F = Filenames::in(build_folder, story_file_leafname);
|
||||
DISCARD_TEXT(story_file_leafname)
|
||||
proj->unblorbed_vertex = Graphs::file_vertex(unblorbed_F);
|
||||
Graphs::need_this_to_build(proj->unblorbed_vertex, inf_V);
|
||||
BuildSteps::attach(proj->unblorbed_vertex, compile_using_inform6_skill,
|
||||
proj->compile_for_release, VM, NULL, proj->as_copy);
|
||||
if (Str::eq(TargetVMs::family(VM), I"Inform6")) {
|
||||
pathname *build_folder = Projects::build_path(proj);
|
||||
|
||||
TEMPORARY_TEXT(story_file_leafname2)
|
||||
WRITE_TO(story_file_leafname2, "output.%S", TargetVMs::get_blorbed_extension(VM));
|
||||
filename *blorbed_F = Filenames::in(build_folder, story_file_leafname2);
|
||||
DISCARD_TEXT(story_file_leafname2)
|
||||
proj->blorbed_vertex = Graphs::file_vertex(blorbed_F);
|
||||
proj->blorbed_vertex->always_build_this = TRUE;
|
||||
Graphs::need_this_to_build(proj->blorbed_vertex, proj->unblorbed_vertex);
|
||||
BuildSteps::attach(proj->blorbed_vertex, package_using_inblorb_skill,
|
||||
proj->compile_for_release, VM, NULL, proj->as_copy);
|
||||
TEMPORARY_TEXT(story_file_leafname)
|
||||
WRITE_TO(story_file_leafname, "output.%S", TargetVMs::get_unblorbed_extension(VM));
|
||||
filename *unblorbed_F = Filenames::in(build_folder, story_file_leafname);
|
||||
DISCARD_TEXT(story_file_leafname)
|
||||
proj->unblorbed_vertex = Graphs::file_vertex(unblorbed_F);
|
||||
Graphs::need_this_to_build(proj->unblorbed_vertex, inf_V);
|
||||
BuildSteps::attach(proj->unblorbed_vertex, compile_using_inform6_skill,
|
||||
proj->compile_for_release, VM, NULL, proj->as_copy);
|
||||
|
||||
if (proj->compile_only) {
|
||||
TEMPORARY_TEXT(story_file_leafname2)
|
||||
WRITE_TO(story_file_leafname2, "output.%S", TargetVMs::get_blorbed_extension(VM));
|
||||
filename *blorbed_F = Filenames::in(build_folder, story_file_leafname2);
|
||||
DISCARD_TEXT(story_file_leafname2)
|
||||
proj->blorbed_vertex = Graphs::file_vertex(blorbed_F);
|
||||
proj->blorbed_vertex->always_build_this = TRUE;
|
||||
Graphs::need_this_to_build(proj->blorbed_vertex, proj->unblorbed_vertex);
|
||||
BuildSteps::attach(proj->blorbed_vertex, package_using_inblorb_skill,
|
||||
proj->compile_for_release, VM, NULL, proj->as_copy);
|
||||
|
||||
if (proj->compile_only) {
|
||||
proj->chosen_build_target = inf_V;
|
||||
inf_V->always_build_this = TRUE;
|
||||
} else if (proj->compile_for_release) proj->chosen_build_target = proj->blorbed_vertex;
|
||||
else proj->chosen_build_target = proj->unblorbed_vertex;
|
||||
} else {
|
||||
proj->chosen_build_target = inf_V;
|
||||
inf_V->always_build_this = TRUE;
|
||||
} else if (proj->compile_for_release) proj->chosen_build_target = proj->blorbed_vertex;
|
||||
else proj->chosen_build_target = proj->unblorbed_vertex;
|
||||
}
|
||||
|
||||
@ The graph also extends downstream of |V|, representing the things we will
|
||||
need before we can run //inform7// on the project: and this is not a linear
|
||||
|
|
|
@ -96,6 +96,7 @@ isn't set up to allow more, so this error is not easy to generate.
|
|||
if (proj) Problems::fatal("Multiple projects given on the command line");
|
||||
proj = P;
|
||||
}
|
||||
if (proj == NULL) Problems::fatal("Nothing to compile");
|
||||
|
||||
@ //supervisor// supplies us with a folder in which to write the debugging log
|
||||
and the Problems report (the HTML version of our error messages or success
|
||||
|
|
|
@ -12,5 +12,5 @@ make-identifiers-unique
|
|||
reconcile-verbs
|
||||
eliminate-redundant-labels
|
||||
eliminate-redundant-operations
|
||||
generate text -> *tout
|
||||
optionally-generate text -> *tout
|
||||
generate -> *out
|
||||
|
|
|
@ -9,10 +9,21 @@ inform7/Tests/Test\ Externals/_Executables/XText: \
|
|||
inform7/Tests/Test\ Externals/_Build/XText-I.o
|
||||
|
||||
inform7/Tests/Test\ Externals/_Build/XText.o: inform7/Tests/Test\ Externals/_Source/XText.c
|
||||
clang -g -std=c99 -c -o inform7/Tests/Test\ Externals/_Build/XText.o inform7/Tests/Test\ Externals/_Source/XText.c -Wno-parentheses-equality -D DEBUG -I inform7/Internal/Miscellany
|
||||
clang -g -std=c99 -c \
|
||||
-o inform7/Tests/Test\ Externals/_Build/XText.o \
|
||||
inform7/Tests/Test\ Externals/_Source/XText.c \
|
||||
-Wno-parentheses-equality -D DEBUG -I inform7/Internal/Miscellany
|
||||
|
||||
inform7/Tests/Test\ Externals/_Build/XText-I.o: inform7/Tests/Test\ Externals/_Build/XText-I.c
|
||||
clang -g -std=c99 -c -o inform7/Tests/Test\ Externals/_Build/XText-I.o inform7/Tests/Test\ Externals/_Build/XText-I.c -Wno-parentheses-equality -D DEBUG -D I7_NO_MAIN -I inform7/Internal/Miscellany
|
||||
clang -g -std=c99 -c \
|
||||
-o inform7/Tests/Test\ Externals/_Build/XText-I.o \
|
||||
inform7/Tests/Test\ Externals/_Build/XText-I.c \
|
||||
-Wno-parentheses-equality -D DEBUG -D I7_NO_MAIN -I inform7/Internal/Miscellany
|
||||
|
||||
inform7/Tests/Test\ Externals/_Build/XText-I.c: inform7/Tests/Test\ Externals/_Source/XText.i7
|
||||
'inform7/Tangled/inform7' '-basic' '-format=C' '-no-progress' '-log' 'nothing' '-external' 'inform7/Tests' '-transient' '../intest/Workspace/T0/Transient' '-no-index' '-internal' 'inform7/Internal' '-project' '../intest/Workspace/T0/Example.inform' '-variable' '*tout=inform7/Tests/Test Externals/_Textual/XText.intert' '-variable' '*out=inform7/Tests/Test Externals/_Build/XText-I.c' '-pipeline' 'test_any'
|
||||
inform7/Tangled/inform7 -basic -format=C \
|
||||
-o inform7/Tests/Test\ Externals/_Build/XText-I.c \
|
||||
inform7/Tests/Test\ Externals/_Source/XText.i7 \
|
||||
-no-progress -log nothing -external inform7/Tests \
|
||||
-transient ../intest/Workspace/T0/Transient -no-index \
|
||||
-internal inform7/Internal -pipeline test_any
|
||||
|
|
|
@ -7,6 +7,7 @@ To generate final code from intermediate code.
|
|||
=
|
||||
void CodeGen::create_pipeline_stage(void) {
|
||||
CodeGen::Stage::new(I"generate", CodeGen::run_pipeline_stage, TEXT_OUT_STAGE_ARG, FALSE);
|
||||
CodeGen::Stage::new(I"optionally-generate", CodeGen::run_pipeline_stage, OPTIONAL_TEXT_OUT_STAGE_ARG, FALSE);
|
||||
}
|
||||
|
||||
int CodeGen::run_pipeline_stage(pipeline_step *step) {
|
||||
|
|
|
@ -80,9 +80,11 @@ pipeline_step *CodeGen::Pipeline::read_step(text_stream *step, dictionary *D,
|
|||
pipeline_step *ST = CodeGen::Pipeline::new_step();
|
||||
match_results mr = Regexp::create_mr();
|
||||
int left_arrow_used = FALSE;
|
||||
int allow_unknown_variables = FALSE;
|
||||
if (Regexp::match(&mr, step, L"optionally-%c+")) allow_unknown_variables = TRUE;
|
||||
if (Regexp::match(&mr, step, L"(%c+?) *<- *(%c*)")) {
|
||||
if (Str::len(mr.exp[1]) > 0) {
|
||||
ST->step_argument = CodeGen::Pipeline::read_parameter(mr.exp[1], D, tfp);
|
||||
ST->step_argument = CodeGen::Pipeline::read_parameter(mr.exp[1], D, tfp, allow_unknown_variables);
|
||||
if (ST->step_argument == NULL) return NULL;
|
||||
} else {
|
||||
Errors::in_text_file_S(I"no source to right of arrow", tfp);
|
||||
|
@ -102,13 +104,13 @@ pipeline_step *CodeGen::Pipeline::read_step(text_stream *step, dictionary *D,
|
|||
DISCARD_TEXT(ERR)
|
||||
return NULL;
|
||||
}
|
||||
ST->step_argument = CodeGen::Pipeline::read_parameter(mr.exp[2], D, tfp);
|
||||
ST->step_argument = CodeGen::Pipeline::read_parameter(mr.exp[2], D, tfp, allow_unknown_variables);
|
||||
if (ST->step_argument == NULL) return NULL;
|
||||
Str::copy(step, mr.exp[0]);
|
||||
} else if (Regexp::match(&mr, step, L"(%c+?) *-> *(%c*)")) {
|
||||
ST->target_argument = NULL;
|
||||
ST->take_target_argument_from_VM = TRUE;
|
||||
ST->step_argument = CodeGen::Pipeline::read_parameter(mr.exp[1], D, tfp);
|
||||
ST->step_argument = CodeGen::Pipeline::read_parameter(mr.exp[1], D, tfp, allow_unknown_variables);
|
||||
if (ST->step_argument == NULL) return NULL;
|
||||
Str::copy(step, mr.exp[0]);
|
||||
}
|
||||
|
@ -118,12 +120,12 @@ pipeline_step *CodeGen::Pipeline::read_step(text_stream *step, dictionary *D,
|
|||
} else if (Regexp::match(&mr, step, L"(%C+?) (%d):(%c*)")) {
|
||||
ST->repository_argument = Str::atoi(mr.exp[1], 0);
|
||||
if (Str::len(mr.exp[2]) > 0) {
|
||||
ST->package_argument = CodeGen::Pipeline::read_parameter(mr.exp[2], D, tfp);
|
||||
ST->package_argument = CodeGen::Pipeline::read_parameter(mr.exp[2], D, tfp, allow_unknown_variables);
|
||||
if (ST->package_argument == NULL) return NULL;
|
||||
}
|
||||
Str::copy(step, mr.exp[0]);
|
||||
} else if (Regexp::match(&mr, step, L"(%C+?) (%c+)")) {
|
||||
ST->package_argument = CodeGen::Pipeline::read_parameter(mr.exp[1], D, tfp);
|
||||
ST->package_argument = CodeGen::Pipeline::read_parameter(mr.exp[1], D, tfp, allow_unknown_variables);
|
||||
if (ST->package_argument == NULL) return NULL;
|
||||
Str::copy(step, mr.exp[0]);
|
||||
}
|
||||
|
@ -156,14 +158,18 @@ pipeline_step *CodeGen::Pipeline::read_step(text_stream *step, dictionary *D,
|
|||
}
|
||||
|
||||
text_stream *CodeGen::Pipeline::read_parameter(text_stream *from, dictionary *D,
|
||||
text_file_position *tfp) {
|
||||
text_file_position *tfp, int allow_unknown_variables) {
|
||||
if (Str::get_first_char(from) == '*') {
|
||||
text_stream *find = Dictionaries::get_text(D, from);
|
||||
if (find) return Str::duplicate(find);
|
||||
TEMPORARY_TEXT(ERR)
|
||||
WRITE_TO(ERR, "no such pipeline variable as '%S'\n", from);
|
||||
Errors::in_text_file_S(ERR, tfp);
|
||||
DISCARD_TEXT(ERR)
|
||||
if (allow_unknown_variables == FALSE) {
|
||||
text_stream *find = Dictionaries::get_text(D, from);
|
||||
if (find) return Str::duplicate(find);
|
||||
TEMPORARY_TEXT(ERR)
|
||||
WRITE_TO(ERR, "no such pipeline variable as '%S'\n", from);
|
||||
Errors::in_text_file_S(ERR, tfp);
|
||||
DISCARD_TEXT(ERR)
|
||||
} else {
|
||||
return I"";
|
||||
}
|
||||
}
|
||||
return Str::duplicate(from);
|
||||
}
|
||||
|
@ -307,23 +313,37 @@ void CodeGen::Pipeline::run(pathname *P, codegen_pipeline *S, linked_list *PP,
|
|||
Time::start_stopwatch(pipeline_timer, STAGE_NAME);
|
||||
DISCARD_TEXT(STAGE_NAME)
|
||||
|
||||
|
||||
if ((step->step_stage->stage_arg == FILE_STAGE_ARG) ||
|
||||
(step->step_stage->stage_arg == TEXT_OUT_STAGE_ARG) ||
|
||||
(step->step_stage->stage_arg == OPTIONAL_TEXT_OUT_STAGE_ARG) ||
|
||||
(step->step_stage->stage_arg == EXT_FILE_STAGE_ARG) ||
|
||||
(step->step_stage->stage_arg == EXT_TEXT_OUT_STAGE_ARG)) {
|
||||
if (Str::eq(step->step_argument, I"*log")) {
|
||||
step->to_debugging_log = TRUE;
|
||||
} else if (Str::eq(step->step_argument, I"*memory")) {
|
||||
S->repositories[step->repository_argument] = S->memory_repository;
|
||||
skip_step = TRUE;
|
||||
if (Str::len(step->step_argument) == 0) {
|
||||
if (step->step_stage->stage_arg == OPTIONAL_TEXT_OUT_STAGE_ARG) {
|
||||
skip_step = TRUE;
|
||||
} else {
|
||||
#ifdef PROBLEMS_MODULE
|
||||
Problems::fatal("No filename given in pipeline step");
|
||||
#endif
|
||||
#ifndef PROBLEMS_MODULE
|
||||
Errors::fatal("No filename given in pipeline step");
|
||||
exit(1);
|
||||
#endif
|
||||
}
|
||||
} else {
|
||||
int slashes = FALSE;
|
||||
LOOP_THROUGH_TEXT(pos, step->step_argument)
|
||||
if (Str::get(pos) == '/')
|
||||
slashes = TRUE;
|
||||
if (slashes) step->parsed_filename = Filenames::from_text(step->step_argument);
|
||||
else step->parsed_filename = Filenames::in(P, step->step_argument);
|
||||
if (Str::eq(step->step_argument, I"*log")) {
|
||||
step->to_debugging_log = TRUE;
|
||||
} else if (Str::eq(step->step_argument, I"*memory")) {
|
||||
S->repositories[step->repository_argument] = S->memory_repository;
|
||||
skip_step = TRUE;
|
||||
} else {
|
||||
int slashes = FALSE;
|
||||
LOOP_THROUGH_TEXT(pos, step->step_argument)
|
||||
if (Str::get(pos) == '/')
|
||||
slashes = TRUE;
|
||||
if (slashes) step->parsed_filename = Filenames::from_text(step->step_argument);
|
||||
else step->parsed_filename = Filenames::in(P, step->step_argument);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -332,8 +352,10 @@ void CodeGen::Pipeline::run(pathname *P, codegen_pipeline *S, linked_list *PP,
|
|||
if (step->to_debugging_log) {
|
||||
step->text_out_file = DL;
|
||||
} else if ((step->step_stage->stage_arg == TEXT_OUT_STAGE_ARG) ||
|
||||
(step->step_stage->stage_arg == OPTIONAL_TEXT_OUT_STAGE_ARG) ||
|
||||
(step->step_stage->stage_arg == EXT_TEXT_OUT_STAGE_ARG)) {
|
||||
if (STREAM_OPEN_TO_FILE(T, step->parsed_filename, ISO_ENC) == FALSE) {
|
||||
if ((step->parsed_filename) &&
|
||||
(STREAM_OPEN_TO_FILE(T, step->parsed_filename, ISO_ENC) == FALSE)) {
|
||||
#ifdef PROBLEMS_MODULE
|
||||
Problems::fatal_on_file("Can't open output file", step->parsed_filename);
|
||||
#endif
|
||||
|
@ -342,6 +364,7 @@ void CodeGen::Pipeline::run(pathname *P, codegen_pipeline *S, linked_list *PP,
|
|||
exit(1);
|
||||
#endif
|
||||
}
|
||||
if (step->parsed_filename) WRITE_TO(STDOUT, "Sooo %f\n", step->parsed_filename);
|
||||
step->text_out_file = T;
|
||||
}
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@ write output to; others are not.
|
|||
@e GENERAL_STAGE_ARG
|
||||
@e FILE_STAGE_ARG
|
||||
@e TEXT_OUT_STAGE_ARG
|
||||
@e OPTIONAL_TEXT_OUT_STAGE_ARG
|
||||
@e EXT_FILE_STAGE_ARG
|
||||
@e EXT_TEXT_OUT_STAGE_ARG
|
||||
@e TEMPLATE_FILE_STAGE_ARG
|
||||
|
|
|
@ -15,26 +15,26 @@ The basic set of possible target VMs is made when the //arch// module starts up:
|
|||
void TargetVMs::create(void) {
|
||||
/* hat tip: Joel Berez and Marc Blank, 1979, and later hands */
|
||||
TargetVMs::new(Architectures::from_codename(I"16"), I"Inform6",
|
||||
VersionNumbers::from_text(I"5"), I"z5", I"zblorb", I"Parchment", NULL);
|
||||
VersionNumbers::from_text(I"5"), I"i6", I"z5", I"zblorb", I"Parchment", NULL);
|
||||
TargetVMs::new(Architectures::from_codename(I"16d"), I"Inform6",
|
||||
VersionNumbers::from_text(I"5"), I"z5", I"zblorb", I"Parchment", NULL);
|
||||
VersionNumbers::from_text(I"5"), I"i6", I"z5", I"zblorb", I"Parchment", NULL);
|
||||
|
||||
TargetVMs::new(Architectures::from_codename(I"16"), I"Inform6",
|
||||
VersionNumbers::from_text(I"8"), I"z8", I"zblorb", I"Parchment", NULL);
|
||||
VersionNumbers::from_text(I"8"), I"i6", I"z8", I"zblorb", I"Parchment", NULL);
|
||||
TargetVMs::new(Architectures::from_codename(I"16d"), I"Inform6",
|
||||
VersionNumbers::from_text(I"8"), I"z8", I"zblorb", I"Parchment", NULL);
|
||||
VersionNumbers::from_text(I"8"), I"i6", I"z8", I"zblorb", I"Parchment", NULL);
|
||||
|
||||
/* hat tip: Andrew Plotkin, 2000 */
|
||||
TargetVMs::new(Architectures::from_codename(I"32"), I"Inform6",
|
||||
VersionNumbers::from_text(I"3.1.2"), I"ulx", I"gblorb", I"Quixe", NULL);
|
||||
VersionNumbers::from_text(I"3.1.2"), I"i6", I"ulx", I"gblorb", I"Quixe", NULL);
|
||||
TargetVMs::new(Architectures::from_codename(I"32d"), I"Inform6",
|
||||
VersionNumbers::from_text(I"3.1.2"), I"ulx", I"gblorb", I"Quixe", NULL);
|
||||
VersionNumbers::from_text(I"3.1.2"), I"i6", I"ulx", I"gblorb", I"Quixe", NULL);
|
||||
|
||||
/* C support added September 2021 */
|
||||
TargetVMs::new(Architectures::from_codename(I"32"), I"C",
|
||||
VersionNumbers::from_text(I"1"), I"c", I"", I"", NULL);
|
||||
VersionNumbers::from_text(I"1"), I"c", I"", I"", I"", NULL);
|
||||
TargetVMs::new(Architectures::from_codename(I"32d"), I"C",
|
||||
VersionNumbers::from_text(I"1"), I"c", I"", I"", NULL);
|
||||
VersionNumbers::from_text(I"1"), I"c", I"", I"", I"", NULL);
|
||||
}
|
||||
|
||||
@ The //target_vm// structure contains two arguably architectural doohickies:
|
||||
|
@ -47,6 +47,7 @@ with integer-only arithmetic, say.
|
|||
typedef struct target_vm {
|
||||
struct inter_architecture *architecture; /* such as 32d */
|
||||
struct semantic_version_number version; /* such as 0.8.7 */
|
||||
struct text_stream *transpiled_extension; /* such as |i6| */
|
||||
struct text_stream *VM_unblorbed_extension; /* such as |z8| */
|
||||
struct text_stream *VM_blorbed_extension; /* when blorbed up */
|
||||
struct text_stream *VM_image; /* filename of image for icon used in the index */
|
||||
|
@ -62,10 +63,11 @@ typedef struct target_vm {
|
|||
|
||||
@ =
|
||||
target_vm *TargetVMs::new(inter_architecture *arch, text_stream *format,
|
||||
semantic_version_number V, text_stream *unblorbed, text_stream *blorbed,
|
||||
text_stream *interpreter, linked_list *opts) {
|
||||
semantic_version_number V, text_stream *trans, text_stream *unblorbed,
|
||||
text_stream *blorbed, text_stream *interpreter, linked_list *opts) {
|
||||
target_vm *VM = CREATE(target_vm);
|
||||
VM->version = V;
|
||||
VM->transpiled_extension = Str::duplicate(trans);
|
||||
VM->VM_unblorbed_extension = Str::duplicate(unblorbed);
|
||||
VM->VM_blorbed_extension = Str::duplicate(blorbed);
|
||||
VM->default_browser_interpreter = Str::duplicate(interpreter);
|
||||
|
@ -117,7 +119,7 @@ to understand what these mean, if indeed they mean anything.
|
|||
=
|
||||
target_vm *TargetVMs::new_variant(target_vm *existing, linked_list *opts) {
|
||||
return TargetVMs::new(existing->architecture, existing->transpiler_family,
|
||||
existing->version, existing->VM_unblorbed_extension,
|
||||
existing->version, existing->transpiled_extension, existing->VM_unblorbed_extension,
|
||||
existing->VM_blorbed_extension, existing->default_browser_interpreter, opts);
|
||||
}
|
||||
|
||||
|
@ -338,6 +340,11 @@ Note that for VMs not using Inform 6, blorbing is essentially meaningless,
|
|||
and then the blorbed extension may be the empty text.
|
||||
|
||||
=
|
||||
text_stream *TargetVMs::get_transpiled_extension(target_vm *VM) {
|
||||
if (VM == NULL) internal_error("no VM");
|
||||
return VM->transpiled_extension;
|
||||
}
|
||||
|
||||
text_stream *TargetVMs::get_unblorbed_extension(target_vm *VM) {
|
||||
if (VM == NULL) internal_error("no VM");
|
||||
return VM->VM_unblorbed_extension;
|
||||
|
|
Loading…
Reference in a new issue