1
0
Fork 0
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:
Graham Nelson 2021-09-12 13:21:13 +01:00
parent 850901508d
commit 9fe3a62c25
14 changed files with 179 additions and 79 deletions

View file

@ -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

View file

@ -1,3 +1,3 @@
Prerelease: alpha.1
Build Date: 11 September 2021
Build Number: 6T22
Build Date: 12 September 2021
Build Number: 6T23

View file

@ -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);
}
}
}

View 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;
}

View file

@ -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) {

View file

@ -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));
}

View file

@ -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

View file

@ -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

View file

@ -12,5 +12,5 @@ make-identifiers-unique
reconcile-verbs
eliminate-redundant-labels
eliminate-redundant-operations
generate text -> *tout
optionally-generate text -> *tout
generate -> *out

View file

@ -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

View file

@ -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) {

View file

@ -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;
}

View file

@ -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

View file

@ -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;