1
0
Fork 0
mirror of https://github.com/ganelson/inform.git synced 2024-06-01 07:48:35 +03:00

Added arch module and inbuild unit testing

This commit is contained in:
Graham Nelson 2020-02-18 11:56:09 +00:00
parent 7043d6c855
commit b8c2a178e8
23 changed files with 559 additions and 100 deletions

2
inbuild/.gitignore vendored
View file

@ -12,3 +12,5 @@ Tests/_Results_Actual/
inbuild.mk
Tests/Units/_Results_Actual/

View file

@ -23,11 +23,13 @@ int dry_run_mode = FALSE;
linked_list *targets = NULL; /* of |inbuild_copy| */
inbuild_nest *destination_nest = NULL;
text_stream *filter_text = NULL;
text_stream *unit_test = NULL;
linked_list *inbuild_nest_list = NULL;
int main(int argc, char **argv) {
Foundation::start();
WordsModule::start();
ArchModule::start();
InbuildModule::start();
targets = NEW_LINKED_LIST(inbuild_copy);
@<Read the command line@>;
@ -37,33 +39,40 @@ int main(int argc, char **argv) {
if (path_to_tools) BM = BuildSteps::methodology(path_to_tools, FALSE);
else BM = BuildSteps::methodology(Pathnames::up(path_to_inbuild), TRUE);
if (dry_run_mode == FALSE) BM->methodology = SHELL_METHODOLOGY;
if (Str::len(filter_text) > 0) {
TEMPORARY_TEXT(errors);
inbuild_requirement *req = Requirements::from_text(filter_text, errors);
if (Str::len(errors) > 0) {
Errors::with_text("requirement malformed: %S", errors);
} else {
linked_list *L = NEW_LINKED_LIST(inbuild_search_result);
Nests::search_for(req, inbuild_nest_list, L);
inbuild_search_result *R;
LOOP_OVER_LINKED_LIST(R, inbuild_search_result, L) {
ADD_TO_LINKED_LIST(R->copy, inbuild_copy, targets);
if (Str::len(unit_test) > 0) {
BM->methodology = DRY_RUN_METHODOLOGY;
if (Str::eq(unit_test, I"compatibility")) Compatibility::test(STDOUT);
else Errors::with_text("no such unit test: %S", unit_test);
} else {
if (Str::len(filter_text) > 0) {
TEMPORARY_TEXT(errors);
inbuild_requirement *req = Requirements::from_text(filter_text, errors);
if (Str::len(errors) > 0) {
Errors::with_text("requirement malformed: %S", errors);
} else {
linked_list *L = NEW_LINKED_LIST(inbuild_search_result);
Nests::search_for(req, inbuild_nest_list, L);
inbuild_search_result *R;
LOOP_OVER_LINKED_LIST(R, inbuild_search_result, L) {
ADD_TO_LINKED_LIST(R->copy, inbuild_copy, targets);
}
}
DISCARD_TEXT(errors);
}
DISCARD_TEXT(errors);
}
inbuild_copy *C;
LOOP_OVER_LINKED_LIST(C, inbuild_copy, targets) {
switch (inbuild_task) {
case INSPECT_TTASK: Copies::inspect(STDOUT, C); break;
case GRAPH_TTASK: Graphs::describe(STDOUT, C->vertex, TRUE); break;
case BUILD_TTASK: Graphs::build(C->vertex, BM); break;
case REBUILD_TTASK: Graphs::rebuild(C->vertex, BM); break;
case COPY_TO_TTASK: if (destination_nest) Nests::copy_to(C, destination_nest, FALSE, BM); break;
case SYNC_TO_TTASK: if (destination_nest) Nests::copy_to(C, destination_nest, TRUE, BM); break;
inbuild_copy *C;
LOOP_OVER_LINKED_LIST(C, inbuild_copy, targets) {
switch (inbuild_task) {
case INSPECT_TTASK: Copies::inspect(STDOUT, C); break;
case GRAPH_TTASK: Graphs::describe(STDOUT, C->vertex, TRUE); break;
case BUILD_TTASK: Graphs::build(C->vertex, BM); break;
case REBUILD_TTASK: Graphs::rebuild(C->vertex, BM); break;
case COPY_TO_TTASK: if (destination_nest) Nests::copy_to(C, destination_nest, FALSE, BM); break;
case SYNC_TO_TTASK: if (destination_nest) Nests::copy_to(C, destination_nest, TRUE, BM); break;
}
}
}
WordsModule::end();
ArchModule::end();
InbuildModule::end();
Foundation::end();
return 0;
@ -81,6 +90,7 @@ int main(int argc, char **argv) {
@e MATCHING_CLSW
@e COPY_TO_CLSW
@e SYNC_TO_CLSW
@e UNIT_TEST_CLSW
@<Read the command line@> =
CommandLine::declare_heading(
@ -106,6 +116,8 @@ int main(int argc, char **argv) {
L"apply to all works in nest(s) matching requirement X");
CommandLine::declare_switch(CONTENTS_OF_CLSW, L"contents-of", 2,
L"apply to all targets in the directory X");
CommandLine::declare_switch(UNIT_TEST_CLSW, L"unit-test", 2,
L"perform unit test X (for debugging inbuild only)");
Inbuild::declare_options();
CommandLine::read(argc, argv, NULL, &Main::option, &Main::bareword);
@ -152,6 +164,7 @@ void Main::option(int id, int val, text_stream *arg, void *state) {
case SYNC_TO_CLSW: inbuild_task = SYNC_TO_TTASK;
destination_nest = Nests::new(Pathnames::from_text(arg));
break;
case UNIT_TEST_CLSW: unit_test = Str::duplicate(arg); break;
}
Inbuild::option(id, val, arg, state);
}

View file

@ -8,6 +8,7 @@ Version Name: Avignon
Import: foundation
Import: inform7/words
Import: arch
Import: inbuild
Preliminaries

View file

@ -0,0 +1,14 @@
'for all': for all: 16=yes 16d=yes 32=yes 32d=yes
'all': for all: 16=yes 16d=yes 32=yes 32d=yes
'not for all': not a valid compatibility specification
'not all': not a valid compatibility specification
'for none': for none: 16=no 16d=no 32=no 32d=no
'none': for none: 16=no 16d=no 32=no 32d=no
'not for none': not a valid compatibility specification
'not none': not a valid compatibility specification
'for 16d': for 16d: 16=no 16d=yes 32=no 32d=no
'not for 32': not for 32: 16=yes 16d=yes 32=no 32d=yes
'for 16d or 32d': for 16d or 32d: 16=no 16d=yes 32=no 32d=yes
'not for 32 or 16': not for 32 or 16: 16=no 16d=yes 32=no 32d=yes
'for 16d, 32d or 32': for 16d, 32d or 32: 16=no 16d=yes 32=yes 32d=yes
'not for 16d, 32d or 32': not for 16d, 32d or 32: 16=yes 16d=no 32=no 32d=no

View file

@ -0,0 +1,143 @@
schema
alpha.beta()
end
schema
alpha.beta(x)
end
schema
routine.call(x)
end
schema
(alpha.beta)(x)
end
schema
debug_rules = 2; say__p = 1;
"Rules tracing now switched to ~all~. Type ~rules off~ to switch it off again.";
end
schema
@erase_window -1;
end
schema
restore Somewhere;
.Somewhere; print "Here!";
end
schema
"Hello, this
is a multiline string literal";
end
schema
for (n=0:((n<RE_Subexpressions-->10) && (n<10)): n++)
print n;
end
schema
spaces j;
print (I7_string) str;
end
schema
if (i == 1) print "Okay";
else "*** Arrcpy doesn't support this ***";
end
schema
a-1
end
schema
do {
print "Hi!";
} until (x);
end
schema
do {
if (a) return wd;
} until (a);
end
schema
do {
if (line_tdata-->index == wd) return wd;
index++;
} until ((line_token-->index == ENDIT_TOKEN) || (((line_token-->index)->0 & $10) == 0));
end
schema
print "<string ~", (string) o, "~>";
end
schema
switch (Y) {
X: print "A ", (string) o;
}
end
schema
#ifdef RANKING_TABLE;
ANNOUNCE_SCORE_RM('B');
j = TableRows(RANKING_TABLE);
for (i=j:i>=1:i--)
if (score >= TableLookUpEntry(RANKING_TABLE, 1, i)) {
v = TableLookUpEntry(RANKING_TABLE, 2, i);
TEXT_TY_Say(v);
".";
}
#endif;
".";'
end
schema
if (B) if (A) { print "Yes"; }
print "No";
end
schema
switch (scope_stage) {
2: objectloop (obj)
PlaceInScope(obj, true);
}
end
schema
while (token ~= NULL) {
switch (token-->RE_CCLASS) {
DISJUNCTION_RE_CC: token-->RE_CONSTRAINT = -1;
QUANTIFIER_RE_CC: token-->RE_CONSTRAINT = -1;
}
if (token-->RE_DOWN) TEXT_TY_RE_EraseConstraints(token-->RE_DOWN);
token = token-->RE_NEXT;
}
end
schema
if (b) print 1; else print 2;
end
schema
a: if (b) print 1; else print 2;
end
schema
print_ret "This is ", (char) X, ".";
end
schema
@jl y 0 ?X;
@jl y 0 ?~X;
@jl y 0 ?rtrue;
@jl y 0 ?rfalse;
@jl y 0 ?~rtrue;
@jl y 0 ?~rfalse;
end
schema
switch (token-->RE_CCLASS) {
! Should never happen
CHOICE_RE_CC: return "internal error";
! Mode switches
SENSITIVITY_RE_CC:
if (token-->RE_PAR1) mode_flags = mode_flags | CIS_MFLAG;
else mode_flags = mode_flags & (~CIS_MFLAG);
outcome = true;
! Zero-length positional markers
ALWAYS_RE_CC:
outcome = true;
NEVER_RE_CC:
START_RE_CC:
if (ipos == 0) outcome = true;
END_RE_CC:
if (BlkValueRead(txt, ipos) == 0) outcome = true;
SOMETIMES_RE_CC:
outcome = true;
}
end

View file

@ -0,0 +1,18 @@
-cases [Units] 'inbuild/Tests/Units'
-recipe [Units]
set: $A = $PATH/_Results_Actual/$CASE.txt
set: $I = $PATH/_Results_Ideal/$CASE.txt
mkdir: $PATH/_Results_Actual
mkdir: $PATH/_Results_Ideal
debugger: llvm -f inbuild/Tangled/inbuild -- -unit-test $CASE
step: inbuild/Tangled/inbuild -unit-test $CASE >$A 2>&1
or: 'failed to produce output' $A
show: $A
match text: $A $I
or: 'produced incorrect output'
-end

View file

@ -0,0 +1,53 @@
[ArchModule::] Arch Module.
Setting up the use of this module.
@h Introduction.
@d ARCH_MODULE TRUE
@ To begin with, this module needs to allocate memory:
@e inter_architecture_MT
@e compatibility_specification_MT
=
ALLOCATE_INDIVIDUALLY(inter_architecture)
ALLOCATE_INDIVIDUALLY(compatibility_specification)
@h The beginning.
=
void ArchModule::start(void) {
@<Register this module's memory allocation reasons@>;
@<Register this module's stream writers@>;
@<Register this module's debugging log aspects@>;
@<Register this module's debugging log writers@>;
@<Register this module's command line switches@>;
Architectures::create();
}
@
@<Register this module's memory allocation reasons@> =
;
@<Register this module's stream writers@> =
;
@
@<Register this module's debugging log aspects@> =
;
@<Register this module's debugging log writers@> =
;
@<Register this module's command line switches@> =
;
@h The end.
=
void ArchModule::end(void) {
}

View file

@ -0,0 +1,68 @@
[Architectures::] Architectures.
To deal with multiple inter architectures.
@h Architectures.
=
typedef struct inter_architecture {
struct text_stream *shorthand; /* such as |32d| */
int sixteen_bit;
int debug_enabled;
MEMORY_MANAGEMENT
} inter_architecture;
inter_architecture *Architectures::new(text_stream *code, int s, int d) {
inter_architecture *A = CREATE(inter_architecture);
A->shorthand = Str::duplicate(code);
A->sixteen_bit = s;
A->debug_enabled = d;
return A;
}
void Architectures::create(void) {
Architectures::new(I"16", TRUE, FALSE);
Architectures::new(I"16d", TRUE, TRUE);
Architectures::new(I"32", FALSE, FALSE);
Architectures::new(I"32d", FALSE, TRUE);
}
filename *Architectures::canonical_binary(pathname *P, inter_architecture *A) {
if (A == NULL) internal_error("no arch");
TEMPORARY_TEXT(leafname);
WRITE_TO(leafname, "arch-%S.interb", A->shorthand);
filename *F = Filenames::in_folder(P, leafname);
DISCARD_TEXT(leafname);
return F;
}
filename *Architectures::canonical_textual(pathname *P, inter_architecture *A) {
if (A == NULL) internal_error("no arch");
TEMPORARY_TEXT(leafname);
WRITE_TO(leafname, "arch-%S.intert", A->shorthand);
filename *F = Filenames::in_folder(P, leafname);
DISCARD_TEXT(leafname);
return F;
}
text_stream *Architectures::to_codename(inter_architecture *A) {
if (A == NULL) return NULL;
return A->shorthand;
}
inter_architecture *Architectures::from_codename(text_stream *name) {
inter_architecture *A;
LOOP_OVER(A, inter_architecture)
if (Str::eq_insensitive(A->shorthand, name))
return A;
return NULL;
}
int Architectures::sixteen_bit(inter_architecture *A) {
if (A == NULL) internal_error("no arch");
return A->sixteen_bit;
}
int Architectures::debug_enabled(inter_architecture *A) {
if (A == NULL) internal_error("no arch");
return A->debug_enabled;
}

View file

@ -0,0 +1,148 @@
[Compatibility::] Compatibility.
To manage compatibility lists: what can be compiled to what format.
@
=
typedef struct compatibility_specification {
int default_allows;
struct linked_list *exceptions; /* of |inter_architecture| */
MEMORY_MANAGEMENT
} compatibility_specification;
compatibility_specification *Compatibility::all(void) {
compatibility_specification *C = CREATE(compatibility_specification);
C->default_allows = TRUE;
C->exceptions = NEW_LINKED_LIST(inter_architecture);
return C;
}
void Compatibility::write(OUTPUT_STREAM, compatibility_specification *C) {
if (C == NULL) { WRITE("for none"); return; }
int x = LinkedLists::len(C->exceptions);
if (x == 0) {
if (C->default_allows) WRITE("for all");
else WRITE("for none");
} else {
if (C->default_allows) WRITE("not ");
WRITE("for ");
int n = 0;
inter_architecture *A;
LOOP_OVER_LINKED_LIST(A, inter_architecture, C->exceptions) {
n++;
if ((n > 1) && (n < x)) WRITE(", ");
if ((n > 1) && (n == x)) WRITE(" or ");
WRITE("%S", Architectures::to_codename(A));
}
}
}
compatibility_specification *Compatibility::from_text(text_stream *text) {
compatibility_specification *C = Compatibility::all();
int incorrect = FALSE;
if (Str::len(text) == 0) return C;
TEMPORARY_TEXT(parse);
WRITE_TO(parse, "%S", text);
Str::trim_white_space(parse);
C->default_allows = FALSE;
match_results mr = Regexp::create_mr();
int negated = FALSE;
if (Regexp::match(&mr, parse, L"not (%c+)")) {
Str::clear(parse);
WRITE_TO(parse, "%S", mr.exp[0]);
Str::trim_white_space(parse);
C->default_allows = TRUE;
negated = TRUE;
}
if (Regexp::match(&mr, parse, L"for (%c+)")) {
Str::clear(parse);
WRITE_TO(parse, "%S", mr.exp[0]);
Str::trim_white_space(parse);
}
if (Str::eq(parse, I"all")) {
if (negated) incorrect = TRUE; /* "not for all" */
C->default_allows = TRUE;
} else if (Str::eq(parse, I"none")) {
if (negated) incorrect = TRUE; /* "not for none" */
C->default_allows = FALSE;
} else if (Compatibility::clause(C, parse) == FALSE)
incorrect = TRUE;
DISCARD_TEXT(parse);
Regexp::dispose_of(&mr);
if (incorrect) C = NULL;
return C;
}
int Compatibility::clause(compatibility_specification *C, text_stream *text) {
int correct = FALSE;
match_results mr = Regexp::create_mr();
if (Regexp::match(&mr, text, L"(%c+?), (%c+)")) {
int a = Compatibility::clause(C, mr.exp[0]);
int b = Compatibility::clause(C, mr.exp[1]);
correct = a && b;
} else if (Regexp::match(&mr, text, L"(%c+?) or (%c+)")) {
int a = Compatibility::clause(C, mr.exp[0]);
int b = Compatibility::clause(C, mr.exp[1]);
correct = a && b;
} else {
inter_architecture *A = Architectures::from_codename(text);
if (A) {
int already_there = FALSE;
inter_architecture *X;
LOOP_OVER_LINKED_LIST(X, inter_architecture, C->exceptions)
if (A == X)
already_there = TRUE;
if (already_there == FALSE) {
ADD_TO_LINKED_LIST(A, inter_architecture, C->exceptions);
correct = TRUE;
}
}
}
Regexp::dispose_of(&mr);
return correct;
}
int Compatibility::with(compatibility_specification *C, inter_architecture *A) {
if (C == NULL) return FALSE;
int decision = C->default_allows;
inter_architecture *X;
LOOP_OVER_LINKED_LIST(X, inter_architecture, C->exceptions)
if (A == X)
decision = decision?FALSE:TRUE;
return decision;
}
void Compatibility::test(OUTPUT_STREAM) {
Compatibility::test_one(OUT, I"for all");
Compatibility::test_one(OUT, I"all");
Compatibility::test_one(OUT, I"not for all");
Compatibility::test_one(OUT, I"not all");
Compatibility::test_one(OUT, I"for none");
Compatibility::test_one(OUT, I"none");
Compatibility::test_one(OUT, I"not for none");
Compatibility::test_one(OUT, I"not none");
Compatibility::test_one(OUT, I"for 16d");
Compatibility::test_one(OUT, I"not for 32");
Compatibility::test_one(OUT, I"for 16d or 32d");
Compatibility::test_one(OUT, I"not for 32 or 16");
Compatibility::test_one(OUT, I"for 16d, 32d or 32");
Compatibility::test_one(OUT, I"not for 16d, 32d or 32");
}
void Compatibility::test_one(OUTPUT_STREAM, text_stream *test) {
WRITE("'%S': ", test);
compatibility_specification *C = Compatibility::from_text(test);
if (C == NULL) { WRITE("not a valid compatibility specification\n"); return; }
Compatibility::write(OUT, C);
WRITE(":");
inter_architecture *A;
LOOP_OVER(A, inter_architecture)
WRITE(" %S=%S", Architectures::to_codename(A),
(Compatibility::with(C, A))?I"yes":I"no");
WRITE("\n");
}

View file

@ -0,0 +1,12 @@
Title: arch
Author: Graham Nelson
Purpose: Definitions of Inter and final VM architectures.
Language: InC
Licence: Artistic License 2.0
Chapter 1: Setting Up
Arch Module
Chapter 2: Architectures
Architectures
Compatibility

View file

@ -1,3 +1,5 @@
{basics}
inbuild.mk
Tests/Units/_Results_Actual/

View file

@ -205,20 +205,22 @@ void Kits::construct_graph(inform_kit *K) {
inbuild_copy *C = K->as_copy;
pathname *P = C->location_if_path;
build_vertex *KV = C->vertex;
text_stream *archs[4] = { I"16", I"32", I"16d", I"32d" };
text_stream *binaries[4] = { I"arch-16.interb", I"arch-32.interb", I"arch-16d.interb", I"arch-32d.interb" };
build_vertex *BV[4];
for (int i=0; i<4; i++) {
filename *FV = Filenames::in_folder(P, binaries[i]);
BV[i] = Graphs::file_vertex(FV);
Graphs::need_this_to_build(KV, BV[i]);
build_step *BS = BuildSteps::new_step(ASSIMILATE_BSTEP, P, archs[i]);
BuildSteps::add_step(BV[i]->script, BS);
linked_list *BVL = NEW_LINKED_LIST(build_vertex);
inter_architecture *A;
LOOP_OVER(A, inter_architecture) {
build_vertex *BV = Graphs::file_vertex(Architectures::canonical_binary(P, A));
Graphs::need_this_to_build(KV, BV);
build_step *BS = BuildSteps::new_step(
ASSIMILATE_BSTEP, P, Architectures::to_codename(A));
BuildSteps::add_step(BV->script, BS);
ADD_TO_LINKED_LIST(BV, build_vertex, BVL);
}
filename *contents_page = Filenames::in_folder(C->location_if_path, I"Contents.w");
build_vertex *CV = Graphs::file_vertex(contents_page);
for (int i=0; i<4; i++) Graphs::need_this_to_build(BV[i], CV);
build_vertex *BV;
LOOP_OVER_LINKED_LIST(BV, build_vertex, BVL)
Graphs::need_this_to_build(BV, CV);
kit_contents_section_state CSS;
CSS.active = FALSE;
@ -229,7 +231,9 @@ void Kits::construct_graph(inform_kit *K) {
filename *SF = Filenames::in_folder(
Pathnames::subfolder(C->location_if_path, I"Sections"), segment);
build_vertex *SV = Graphs::file_vertex(SF);
for (int i=0; i<4; i++) Graphs::need_this_to_build(BV[i], SV);
build_vertex *BV;
LOOP_OVER_LINKED_LIST(BV, build_vertex, BVL)
Graphs::need_this_to_build(BV, SV);
}
inbuild_requirement *req;

View file

@ -12,6 +12,7 @@ typedef struct inform_project {
struct inform_language *language_of_play;
struct inform_language *language_of_syntax;
struct inform_language *language_of_index;
int next_resource_number;
MEMORY_MANAGEMENT
} inform_project;
@ -25,6 +26,7 @@ inform_project *Projects::new_ip(text_stream *name, filename *F, pathname *P) {
project->language_of_play = NULL;
project->language_of_syntax = NULL;
project->language_of_index = NULL;
project->next_resource_number = 3;
return project;
}
@ -62,6 +64,22 @@ void Projects::not_necessarily_parser_IF(inform_project *project) {
project->assumed_to_be_parser_IF = FALSE;
}
@ Resources in a Blorb file have unique ID numbers which are positive integers,
but these are not required to start from 1, nor to be contiguous. For Inform,
ID number 1 is reserved for the cover image (whether or not any cover image
is provided: it is legal for there to be figures but no cover, and vice versa).
Other figures, and sound effects, then mix freely as needed from ID number 3
on upwards. We skip 2 so that it can be guaranteed that no sound resource
has ID 1 or 2: this is to help people trying to play sounds in the Z-machine,
where operand 1 or 2 in the |@sound| opcode signifies not a sound resource
number but a long or short beep. If a genuine sound effect had resource ID
1 or 2, therefore, it would be unplayable on the Z-machine.
=
int Projects::get_next_free_blorb_resource_ID(inform_project *project) {
return project->next_resource_number++;
}
void Projects::set_source_filename(inform_project *project, pathname *P, filename *F) {
if (P) {
filename *manifest = Filenames::in_folder(P, I"Contents.txt");

View file

@ -55,6 +55,7 @@ int Main::core_inform_main(int argc, char *argv[]) {
IFModule::start();
MultimediaModule::start();
IndexModule::start();
ArchModule::start();
InterModule::start();
BuildingModule::start();
CodegenModule::start();
@ -73,6 +74,7 @@ int Main::core_inform_main(int argc, char *argv[]) {
IFModule::end();
IndexModule::end();
InterModule::end();
ArchModule::end();
BuildingModule::end();
CodegenModule::end();
InbuildModule::end();

View file

@ -16,6 +16,7 @@ Import: syntax
Import: problems
Import: linguistics
Import: kinds
Import: inbuild/arch
Import: inter/inter
Import: inbuild/inbuild
Import: core

View file

@ -645,22 +645,3 @@ int VirtualMachines::compare_usage(const void *ent1, const void *ent2) {
if (v2->bytes_used != v1->bytes_used) return v2->bytes_used - v1->bytes_used;
return Wordings::first_wn(v1->structure_name) - Wordings::first_wn(v2->structure_name);
}
@h Resource ID numbers.
Resources in a Blorb file have unique ID numbers which are positive integers,
but these are not required to start from 1, nor to be contiguous. For Inform,
ID number 1 is reserved for the cover image (whether or not any cover image
is provided: it is legal for there to be figures but no cover, and vice versa).
Other figures, and sound effects, then mix freely as needed from ID number 3
on upwards. We skip 2 so that it can be guaranteed that no sound resource
has ID 1 or 2: this is to help people trying to play sounds in the Z-machine,
where operand 1 or 2 in the |@sound| opcode signifies not a sound resource
number but a long or short beep. If a genuine sound effect had resource ID
1 or 2, therefore, it would be unplayable on the Z-machine.
=
int next_free_resource_ID = 3;
int VirtualMachines::get_next_free_blorb_resource_ID(void) {
return next_free_resource_ID++;
}

View file

@ -160,7 +160,7 @@ void PL::Figures::register_figure(wording F, wording FN) {
bf->name = F;
if (wn >= 0) {
bf->figure_number = VirtualMachines::get_next_free_blorb_resource_ID();
bf->figure_number = Projects::get_next_free_blorb_resource_ID(Inbuild::project());
TEMPORARY_TEXT(leaf);
WRITE_TO(leaf, "%N", wn);
bf->filename_of_image_file = Filenames::in_folder(pathname_of_materials_figures, leaf);

View file

@ -151,7 +151,7 @@ void PL::Sounds::register_sound(wording F, wording FN) {
DISCARD_TEXT(leaf);
bs->name = F;
bs->sound_number = VirtualMachines::get_next_free_blorb_resource_ID();
bs->sound_number = Projects::get_next_free_blorb_resource_ID(Inbuild::project());
bs->alt_description = <<alttext>>;
LOGIF(FIGURE_CREATIONS,

View file

@ -32,6 +32,7 @@ linked_list *requirements_list = NULL;
int main(int argc, char **argv) {
Foundation::start();
ArchModule::start();
InterModule::start();
BuildingModule::start();
CodegenModule::start();
@ -70,22 +71,17 @@ int main(int argc, char **argv) {
CommandLine::read(argc, argv, NULL, &Main::respond, &Main::add_file);
if (template_action == ASSIMILATE_CLSW) {
text_stream *name = CodeGen::Architecture::leafname();
if (Str::len(name) == 0) Errors::fatal("no -architecture given");
inter_architecture *A = CodeGen::Architecture::current();
if (A == NULL) Errors::fatal("no -architecture given");
filename *assim = Architectures::canonical_binary(template_path, A);
filename *assim_t = Architectures::canonical_textual(template_path, A);
pipeline_as_file = Filenames::in_folder(path_to_pipelines, I"assimilate.interpipeline");
TEMPORARY_TEXT(leafname);
WRITE_TO(leafname, "%S.interb", name);
filename *assim = Filenames::in_folder(template_path, leafname);
TEMPORARY_TEXT(fullname);
WRITE_TO(fullname, "%f", assim);
Str::copy(Dictionaries::create_text(pipeline_vars, I"*out"), fullname);
Str::clear(leafname);
Str::clear(fullname);
WRITE_TO(leafname, "%S.intert", name);
filename *assim_t = Filenames::in_folder(template_path, leafname);
WRITE_TO(fullname, "%f", assim_t);
Str::copy(Dictionaries::create_text(pipeline_vars, I"*outt"), fullname);
DISCARD_TEXT(leafname);
DISCARD_TEXT(fullname);
match_results mr = Regexp::create_mr();
Str::copy(Dictionaries::create_text(pipeline_vars, I"*attach"), Pathnames::directory_name(template_path));
@ -97,6 +93,7 @@ int main(int argc, char **argv) {
InterModule::end();
BuildingModule::end();
CodegenModule::end();
ArchModule::end();
Foundation::end();
if (Errors::have_occurred()) return 1;

View file

@ -8,6 +8,7 @@ Version Name: Axion
Import: foundation
Import: inform7/words
Import: inbuild/arch
Import: inter
Import: building
Import: codegen

View file

@ -2,36 +2,18 @@
To deal with multiple inter architectures.
@h Architectures.
These are simply enumerated, for now.
@e NO_ARCHITECTURE from 0
@e A_16_ARCHITECTURE
@e A_16D_ARCHITECTURE
@e A_32_ARCHITECTURE
@e A_32D_ARCHITECTURE
@h Current architecture.
=
int current_architecture = NO_ARCHITECTURE;
inter_architecture *current_architecture = NULL;
int CodeGen::Architecture::set(text_stream *name) {
int setting = NO_ARCHITECTURE;
if (Str::eq_insensitive(name, I"16")) setting = A_16_ARCHITECTURE;
if (Str::eq_insensitive(name, I"32")) setting = A_32_ARCHITECTURE;
if (Str::eq_insensitive(name, I"16d")) setting = A_16D_ARCHITECTURE;
if (Str::eq_insensitive(name, I"32d")) setting = A_32D_ARCHITECTURE;
if (setting == NO_ARCHITECTURE) return FALSE;
current_architecture = setting;
return TRUE;
current_architecture = Architectures::from_codename(name);
if (current_architecture) return TRUE;
return FALSE;
}
text_stream *CodeGen::Architecture::leafname(void) {
switch (current_architecture) {
case A_16_ARCHITECTURE: return I"arch-16";
case A_16D_ARCHITECTURE: return I"arch-16d";
case A_32_ARCHITECTURE: return I"arch-32";
case A_32D_ARCHITECTURE: return I"arch-32d";
}
return NULL;
inter_architecture *CodeGen::Architecture::current(void) {
return current_architecture;
}
@h Prepare stage.
@ -42,14 +24,10 @@ void CodeGen::Architecture::create_pipeline_stage(void) {
}
int CodeGen::Architecture::run_prepare_stage(pipeline_step *step) {
switch (current_architecture) {
case NO_ARCHITECTURE: internal_error("no architecture set");
case A_16_ARCHITECTURE: return CodeGen::Architecture::run_prepare_stage_inner(step, TRUE, FALSE);
case A_16D_ARCHITECTURE: return CodeGen::Architecture::run_prepare_stage_inner(step, TRUE, TRUE);
case A_32_ARCHITECTURE: return CodeGen::Architecture::run_prepare_stage_inner(step, FALSE, FALSE);
case A_32D_ARCHITECTURE: return CodeGen::Architecture::run_prepare_stage_inner(step, FALSE, TRUE);
}
return FALSE;
if (current_architecture == NULL) internal_error("no architecture set");
return CodeGen::Architecture::run_prepare_stage_inner(step,
Architectures::sixteen_bit(current_architecture),
Architectures::debug_enabled(current_architecture));
}
int CodeGen::Architecture::run_prepare_stage_inner(pipeline_step *step, int Z, int D) {

View file

@ -29,11 +29,10 @@ void CodeGen::LinkInstructions::create_pipeline_stage(void) {
int CodeGen::LinkInstructions::run_link_stage(pipeline_step *step) {
link_instruction *req;
LOOP_OVER_LINKED_LIST(req, link_instruction, step->requirements_list) {
TEMPORARY_TEXT(leafname);
WRITE_TO(leafname, "%S.interb", CodeGen::Architecture::leafname());
filename *arch_file = Filenames::in_folder(req->location, leafname);
inter_architecture *A = CodeGen::Architecture::current();
if (A == NULL) Errors::fatal("no -architecture given");
filename *arch_file = Architectures::canonical_binary(req->location, A);
if (TextFiles::exists(arch_file) == FALSE) internal_error("no arch file for requirement");
DISCARD_TEXT(leafname);
inter_tree *sidecar = Inter::Tree::new();
if (Inter::Binary::test_file(arch_file)) Inter::Binary::read(sidecar, arch_file);

View file

@ -61,6 +61,7 @@ INBUILDX = inbuild/Tangled/inbuild
{module} INTER inter inter/inter-module
{module} BUILDING building inter/building-module
{module} CODEGEN codegen inter/codegen-module
{module} ARCH arch inbuild/arch-module
{module} INBUILD inbuild inbuild/inbuild-module
# First, the tools we need to make, using the same declaration notation.
@ -87,6 +88,7 @@ INBUILDX = inbuild/Tangled/inbuild
{dep} INFORM7 on IF
{dep} INFORM7 on MULTIMEDIA
{dep} INFORM7 on INDEX
{dep} INFORM7 on ARCH
{dep} INFORM7 on INTER
{dep} INFORM7 on BUILDING
{dep} INFORM7 on CODEGEN
@ -101,10 +103,12 @@ INBUILDX = inbuild/Tangled/inbuild
{tool} INBUILDTOOL inbuild inbuild
{dep} INBUILDTOOL on FOUNDATION
{dep} INBUILDTOOL on WORDS
{dep} INBUILDTOOL on ARCH
{dep} INBUILDTOOL on INBUILD
{tool} INTERTOOL inter inter
{dep} INTERTOOL on FOUNDATION
{dep} INTERTOOL on ARCH
{dep} INTERTOOL on INTER
{dep} INTERTOOL on BUILDING
{dep} INTERTOOL on CODEGEN