diff --git a/docs/BasicInformKit/S-gll.html b/docs/BasicInformKit/S-gll.html
index 472849517..51bc7c133 100644
--- a/docs/BasicInformKit/S-gll.html
+++ b/docs/BasicInformKit/S-gll.html
@@ -991,7 +991,7 @@ in case I7 extensions want to do interesting things with Glulx.
-# Stub HandleGlkEvent 2 ;
+# Stub HandleGlkEvent 3 ;
# Stub IdentifyGlkObject 4 ;
# Stub InitGlkWindow 1 ;
diff --git a/docs/BasicInformKit/S-prg.html b/docs/BasicInformKit/S-prg.html
index fdc2b275d..5ca1d8d7c 100644
--- a/docs/BasicInformKit/S-prg.html
+++ b/docs/BasicInformKit/S-prg.html
@@ -294,7 +294,7 @@ below.
say__p = 1 ;
say__pc = say__pc | PARA_NORULEBOOKBREAKS ;
TEXT_TY_Say ( matter );
- DivideParagraphPoint (13);
+ DivideParagraphPoint ();
say__pc = 0 ;
];
diff --git a/docs/BasicInformKit/S-rgx.html b/docs/BasicInformKit/S-rgx.html
index 88eab244d..a2487b519 100644
--- a/docs/BasicInformKit/S-rgx.html
+++ b/docs/BasicInformKit/S-rgx.html
@@ -1020,7 +1020,7 @@ of the root.
if (( RE_PACKET_space --> RE_DOWN ~= NULL ) &&
(( RE_PACKET_space --> RE_DOWN )--> RE_CCLASS == START_RE_CC ) &&
( ipos >0)) { rv = -1; break ; }
- if ( ipos > 0 ) TEXT_TY_RE_EraseConstraints ( RE_PACKET_space , initial_mode );
+ if ( ipos > 0 ) TEXT_TY_RE_EraseConstraints ( RE_PACKET_space );
TEXT_TY_RE_RewindCount = 0 ;
rv = TEXT_TY_RE_ParseAtPosition ( ftxt , txt , ipos , ilen , RE_PACKET_space , initial_mode );
if ( rv >= 0 ) break ;
diff --git a/docs/codegen-module/4-cal.html b/docs/codegen-module/4-cal.html
index 6a6b916e8..88d6bb95e 100644
--- a/docs/codegen-module/4-cal.html
+++ b/docs/codegen-module/4-cal.html
@@ -123,7 +123,7 @@ is 20. We instead compile this as
text_stream * fa = Str::duplicate ( con_name -> symbol_name );
Str::delete_first_character ( fa );
Str::delete_first_character ( fa );
- WRITE ( "Fake_Action %S;\n" , fa );
+ CodeGen::Targets::new_fake_action ( gen , fa );
return ;
}
diff --git a/docs/codegen-module/4-ft.html b/docs/codegen-module/4-ft.html
index 03fd4346f..ad8369b97 100644
--- a/docs/codegen-module/4-ft.html
+++ b/docs/codegen-module/4-ft.html
@@ -434,6 +434,16 @@ function togglePopup(material_id) {
VOID_METHOD_CALL ( gen -> target , END_ARRAY_MTID , gen , format );
}
+
+
+enum NEW_FAKE_ACTION_MTID
+
+
+VOID_METHOD_TYPE ( NEW_FAKE_ACTION_MTID , code_generation_target * cgt , code_generation * gen , text_stream * name )
+void CodeGen::Targets::new_fake_action ( code_generation * gen , text_stream * name ) {
+ VOID_METHOD_CALL ( gen -> target , NEW_FAKE_ACTION_MTID , gen , name );
+}
+
diff --git a/docs/codegen-module/5-fi6.html b/docs/codegen-module/5-fi6.html
index 3588f7ae4..ed5deedc5 100644
--- a/docs/codegen-module/5-fi6.html
+++ b/docs/codegen-module/5-fi6.html
@@ -120,6 +120,7 @@ function togglePopup(material_id) {
METHOD_ADD ( cgt , END_ARRAY_MTID , CodeGen::I6::end_array );
METHOD_ADD ( cgt , OFFER_PRAGMA_MTID , CodeGen::I6::offer_pragma )
METHOD_ADD ( cgt , END_GENERATION_MTID , CodeGen::I6::end_generation );
+ METHOD_ADD ( cgt , NEW_FAKE_ACTION_MTID , CodeGen::I6::new_fake_action );
inform6_target = cgt ;
}
@@ -168,6 +169,7 @@ now a bitmap of flags for tracing actions, calls to object routines, and so on.
enum property_offset_creator_I7CGS
+int I6_property_offsets_made = 0 ;
int CodeGen::I6::begin_generation ( code_generation_target * cgt , code_generation * gen ) {
gen -> segments [ pragmatic_matter_I7CGS ] = CodeGen::new_segment ();
gen -> segments [ compiler_versioning_matter_I7CGS ] = CodeGen::new_segment ();
@@ -196,30 +198,25 @@ now a bitmap of flags for tracing actions, calls to object routines, and so on.
gen -> segments [ stubs_at_eof_I7CGS ] = CodeGen::new_segment ();
gen -> segments [ property_offset_creator_I7CGS ] = CodeGen::new_segment ();
+ I6_property_offsets_made = 0 ;
+
generated_segment * saved = CodeGen::select ( gen , compiler_versioning_matter_I7CGS );
text_stream * OUT = CodeGen::current ( gen );
WRITE ( "Constant Grammar__Version 2;\n" );
WRITE ( "Global debug_flag;\n" );
CodeGen::deselect ( gen , saved );
- saved = CodeGen::select ( gen , property_offset_creator_I7CGS );
- OUT = CodeGen::current ( gen );
- WRITE ( "[ CreatePropertyOffsets i;\n" ); INDENT ;
- WRITE ( "for (i=0: i<attributed_property_offsets_SIZE: i++)" ); INDENT ;
- WRITE ( "attributed_property_offsets-->i = -1;\n" ); OUTDENT ;
- WRITE ( "for (i=0: i<valued_property_offsets_SIZE: i++)" ); INDENT ;
- WRITE ( "valued_property_offsets-->i = -1;\n" ); OUTDENT ;
- CodeGen::deselect ( gen , saved );
-
return FALSE ;
}
int CodeGen::I6::end_generation ( code_generation_target * cgt , code_generation * gen ) {
- generated_segment * saved = CodeGen::select ( gen , property_offset_creator_I7CGS );
- text_stream * OUT = CodeGen::current ( gen );
- OUTDENT ;
- WRITE ( "];\n" );
- CodeGen::deselect ( gen , saved );
+ if ( I6_property_offsets_made > 0 ) {
+ generated_segment * saved = CodeGen::select ( gen , property_offset_creator_I7CGS );
+ text_stream * OUT = CodeGen::current ( gen );
+ OUTDENT ;
+ WRITE ( "];\n" );
+ CodeGen::deselect ( gen , saved );
+ }
return FALSE ;
}
@@ -752,6 +749,13 @@ trick called "stubbing", these being "stub definitions".)
void CodeGen::I6::property_offset ( code_generation_target * cgt , code_generation * gen , text_stream * prop , int pos , int as_attr ) {
generated_segment * saved = CodeGen::select ( gen , property_offset_creator_I7CGS );
text_stream * OUT = CodeGen::current ( gen );
+ if ( I6_property_offsets_made ++ == 0 ) {
+ WRITE ( "[ CreatePropertyOffsets i;\n" ); INDENT ;
+ WRITE ( "for (i=0: i<attributed_property_offsets_SIZE: i++)\n" ); INDENT ;
+ WRITE ( "attributed_property_offsets-->i = -1;\n" ); OUTDENT ;
+ WRITE ( "for (i=0: i<valued_property_offsets_SIZE: i++)\n" ); INDENT ;
+ WRITE ( "valued_property_offsets-->i = -1;\n" ); OUTDENT ;
+ }
if ( as_attr ) WRITE ( "attributed_property_offsets" );
else WRITE ( "valued_property_offsets" );
WRITE ( "-->%S = %d;\n" , prop , pos );
@@ -870,7 +874,7 @@ trick called "stubbing", these being "stub definitions".)
void CodeGen::I6::end_function ( code_generation_target * cgt , int pass , code_generation * gen , inter_symbol * fn ) {
if ( pass == 2 ) {
text_stream * OUT = CodeGen::current ( gen );
- WRITE ( "];" );
+ WRITE ( "];\n" );
}
}
@@ -924,6 +928,11 @@ trick called "stubbing", these being "stub definitions".)
text_stream * OUT = CodeGen::current ( gen );
WRITE ( ";\n" );
}
+
+void CodeGen::I6::new_fake_action ( code_generation_target * cgt , code_generation * gen , text_stream * name ) {
+ text_stream * OUT = CodeGen::current ( gen );
+ WRITE ( "Fake_Action %S;\n" , name );
+}
diff --git a/docs/codegen-module/5-fnc.html b/docs/codegen-module/5-fnc.html
index 3994599cf..df8eaad57 100644
--- a/docs/codegen-module/5-fnc.html
+++ b/docs/codegen-module/5-fnc.html
@@ -120,6 +120,7 @@ function togglePopup(material_id) {
METHOD_ADD ( cgt , END_ARRAY_MTID , CodeGen::C::end_array );
METHOD_ADD ( cgt , OFFER_PRAGMA_MTID , CodeGen::C::offer_pragma )
METHOD_ADD ( cgt , END_GENERATION_MTID , CodeGen::C::end_generation );
+ METHOD_ADD ( cgt , NEW_FAKE_ACTION_MTID , CodeGen::C::new_fake_action );
c_target = cgt ;
}
@@ -139,6 +140,10 @@ function togglePopup(material_id) {
int extent_of_i7mem = 0 ;
int C_class_counter = 0 ;
int C_instance_counter = 0 ;
+int C_dword_count = 0 ;
+int C_action_count = 0 ;
+int C_property_offsets_made = 0 ;
+struct dictionary * C_vm_dictionary = NULL ;
int CodeGen::C::begin_generation ( code_generation_target * cgt , code_generation * gen ) {
gen -> segments [ pragmatic_matter_I7CGS ] = CodeGen::new_segment ();
@@ -170,6 +175,8 @@ function togglePopup(material_id) {
gen -> segments [ c_mem_I7CGS ] = CodeGen::new_segment ();
gen -> segments [ c_initialiser_I7CGS ] = CodeGen::new_segment ();
+ InterTree::traverse ( gen -> from , CodeGen::C::sweep_for_locals , gen , NULL , LOCAL_IST );
+
double_quoted_C = Str::new ();
no_double_quoted_C_strings = 0 ;
@@ -213,6 +220,9 @@ function togglePopup(material_id) {
CodeGen::deselect ( gen , saved );
extent_of_i7mem = 0 ;
+ C_dword_count = 0 ;
+ C_vm_dictionary = Dictionaries::new (1024, TRUE );
+
saved = CodeGen::select ( gen , stubs_at_eof_I7CGS );
OUT = CodeGen::current ( gen );
WRITE ( "int i7_initializer(void);\n" );
@@ -227,24 +237,7 @@ function togglePopup(material_id) {
WRITE ( "i7val ref = 0;\n" );
CodeGen::deselect ( gen , saved );
- saved = CodeGen::select ( gen , property_offset_creator_I7CGS );
- OUT = CodeGen::current ( gen );
- WRITE ( "i7val fn_" );
- CodeGen::C::mangle ( cgt , OUT , I "CreatePropertyOffsets" );
- WRITE ( "(int argc) {\n" ); INDENT ;
- WRITE ( "for (int i=0; i<" );
- CodeGen::C::mangle ( cgt , OUT , I "attributed_property_offsets_SIZE" );
- WRITE ( "; i++)" ); INDENT ;
- WRITE ( "write_i7_lookup(i7mem, " );
- CodeGen::C::mangle ( cgt , OUT , I "attributed_property_offsets" );
- WRITE ( ", i, -1);\n" ); OUTDENT ;
- WRITE ( "for (int i=0; i<" );
- CodeGen::C::mangle ( cgt , OUT , I "valued_property_offsets_SIZE" );
- WRITE ( "; i++)" ); INDENT ;
- WRITE ( "write_i7_lookup(i7mem, " );
- CodeGen::C::mangle ( cgt , OUT , I "valued_property_offsets" );
- WRITE ( ", i, -1);\n" ); OUTDENT ;
- CodeGen::deselect ( gen , saved );
+ C_property_offsets_made = 0 ;
return FALSE ;
}
@@ -254,6 +247,30 @@ function togglePopup(material_id) {
WRITE ( "#define I7VAL_STRINGS_BASE %d\n" , extent_of_i7mem );
WRITE ( "#define I7VAL_FUNCTIONS_BASE %d\n" , extent_of_i7mem + no_double_quoted_C_strings );
WRITE ( "char *dqs[] = {\n%S\"\" };\n" , double_quoted_C );
+
+ for ( int i =0; i < C_dword_count ; i ++) {
+ WRITE ( "#define i7_s_dword_%d %d\n" , i , 2 * i );
+ WRITE ( "#define i7_p_dword_%d %d\n" , i , 2 * i + 1 );
+ }
+ WRITE ( "#define i7_max_objects %d\n" , C_instance_counter );
+ CodeGen::deselect ( gen , saved );
+
+ saved = CodeGen::select ( gen , globals_array_I7CGS );
+ OUT = CodeGen::current ( gen );
+ WRITE ( "#ifdef i7_defined_i7_mgl_I7S_Comp\n" );
+ WRITE ( "#ifndef fn_i7_mgl_I7S_Comp\n" );
+ WRITE ( "i7val fn_i7_mgl_I7S_Comp(int argc, i7val a1, i7val a2, i7val a3, i7val a4, i7val a5) {\n" );
+ WRITE ( " return i7_call_5(i7_mgl_I7S_Comp, a1, a2, a3, a4, a5);\n" );
+ WRITE ( "}\n" );
+ WRITE ( "#endif\n" );
+ WRITE ( "#endif\n" );
+ WRITE ( "#ifdef i7_defined_i7_mgl_I7S_Swap\n" );
+ WRITE ( "#ifndef fn_i7_mgl_I7S_Swap\n" );
+ WRITE ( "i7val fn_i7_mgl_I7S_Swap(int argc, i7val a1, i7val a2, i7val a3) {\n" );
+ WRITE ( " return i7_call_3(i7_mgl_I7S_Swap, a1, a2, a3);\n" );
+ WRITE ( "}\n" );
+ WRITE ( "#endif\n" );
+ WRITE ( "#endif\n" );
CodeGen::deselect ( gen , saved );
saved = CodeGen::select ( gen , c_mem_I7CGS );
@@ -267,15 +284,28 @@ function togglePopup(material_id) {
WRITE ( "}\n" );
CodeGen::deselect ( gen , saved );
- saved = CodeGen::select ( gen , property_offset_creator_I7CGS );
- OUT = CodeGen::current ( gen );
- WRITE ( "return 0;\n" );
- OUTDENT ;
- WRITE ( "}\n" );
- CodeGen::deselect ( gen , saved );
+ if ( C_property_offsets_made > 0 ) {
+ saved = CodeGen::select ( gen , property_offset_creator_I7CGS );
+ OUT = CodeGen::current ( gen );
+ WRITE ( "return 0;\n" );
+ OUTDENT ;
+ WRITE ( "}\n" );
+ CodeGen::deselect ( gen , saved );
+ }
+
return FALSE ;
}
+void CodeGen::C::sweep_for_locals ( inter_tree * I , inter_tree_node * P , void * state ) {
+ inter_package * pack = Inter::Packages::container ( P );
+ inter_symbol * var_name =
+ InterSymbolsTables::local_symbol_from_id ( pack , P -> W . data [ DEFN_LOCAL_IFLD ]);
+ TEMPORARY_TEXT ( T )
+ WRITE_TO ( T , "local_%S" , var_name -> symbol_name );
+ Inter::Symbols::set_translate ( var_name , T );
+ DISCARD_TEXT ( T )
+}
+
int CodeGen::C::general_segment ( code_generation_target * cgt , code_generation * gen , inter_tree_node * P ) {
switch ( P -> W . data [ ID_IFLD ]) {
case CONSTANT_IST: {
@@ -367,10 +397,10 @@ function togglePopup(material_id) {
case PUSH_BIP: WRITE ( "i7_push(" ); INV_A1 ; WRITE ( ")" ); break ;
case PULL_BIP: INV_A1 ; WRITE ( " = i7_pull()" ); break ;
- case PREINCREMENT_BIP: WRITE ( "++(" ); INV_A1 ; WRITE ( ")" ); break ;
- case POSTINCREMENT_BIP: WRITE ( "(" ); INV_A1 ; WRITE ( ")++" ); break ;
- case PREDECREMENT_BIP: WRITE ( "--(" ); INV_A1 ; WRITE ( ")" ); break ;
- case POSTDECREMENT_BIP: WRITE ( "(" ); INV_A1 ; WRITE ( ")--" ); break ;
+ case PREINCREMENT_BIP: Generate primitive for store 2.2 ; break ;
+ case POSTINCREMENT_BIP: Generate primitive for store 2.2 ; break ;
+ case PREDECREMENT_BIP: Generate primitive for store 2.2 ; break ;
+ case POSTDECREMENT_BIP: Generate primitive for store 2.2 ; break ;
case STORE_BIP: Generate primitive for store 2.2 ; break ;
case SETBIT_BIP: INV_A1 ; WRITE ( " = " ); INV_A1 ; WRITE ( " | " ); INV_A2 ; break ;
case CLEARBIT_BIP: INV_A1 ; WRITE ( " = " ); INV_A1 ; WRITE ( " &~ (" ); INV_A2 ; WRITE ( ")" ); break ;
@@ -385,8 +415,13 @@ function togglePopup(material_id) {
case LOOKUPREF_BIP: Generate primitive for lookupref 2.4 ; break ;
case PROPERTYADDRESS_BIP: WRITE ( "i7_prop_addr(" ); INV_A1 ; WRITE ( ", " ); INV_A2 ; WRITE ( ")" ); break ;
case PROPERTYLENGTH_BIP: WRITE ( "i7_prop_len(" ); INV_A1 ; WRITE ( ", " ); INV_A2 ; WRITE ( ")" ); break ;
- case PROPERTYVALUE_BIP: WRITE ( "i7_prop_value(" ); INV_A1 ; WRITE ( ", " ); INV_A2 ; WRITE ( ")" ); break ;
-
+ case PROPERTYVALUE_BIP: if ( C_write_lookup_mode ) {
+ C_write_lookup_mode = FALSE ;
+ WRITE ( "i7_change_prop_value(" ); INV_A1 ; WRITE ( ", " ); INV_A2 ; WRITE ( ", " );
+ } else {
+ WRITE ( "i7_prop_value(" ); INV_A1 ; WRITE ( ", " ); INV_A2 ; WRITE ( ")" );
+ }
+ break ;
case BREAK_BIP: WRITE ( "break" ); break ;
case CONTINUE_BIP: WRITE ( "continue" ); break ;
case RETURN_BIP: Generate primitive for return 2.6 ; break ;
@@ -477,7 +512,7 @@ function togglePopup(material_id) {
case CASE_BIP: Generate primitive for case 2.19 ; break ;
case DEFAULT_BIP: Generate primitive for default 2.20 ; break ;
- case RANDOM_BIP: WRITE ( "i7_random(" ); INV_A1 ; WRITE ( ")" ); break ;
+ case RANDOM_BIP: WRITE ( "fn_i7_mgl_random(1, " ); INV_A1 ; WRITE ( ")" ); break ;
case READ_BIP: WRITE ( "i7_read(" ); INV_A1 ; WRITE ( ", " ); INV_A2 ; WRITE ( ")" ); break ;
@@ -497,14 +532,34 @@ function togglePopup(material_id) {
+ text_stream * store_form = NULL ;
+ switch ( bip ) {
+ case PREINCREMENT_BIP: store_form = I "i7_cpv_PREINC" ; break ;
+ case POSTINCREMENT_BIP: store_form = I "i7_cpv_POSTINC" ; break ;
+ case PREDECREMENT_BIP: store_form = I "i7_cpv_PREDEC" ; break ;
+ case POSTDECREMENT_BIP: store_form = I "i7_cpv_POSTDEC" ; break ;
+ case STORE_BIP: store_form = I "i7_cpv_SET" ; break ;
+ }
inter_tree_node * ref = InterTree::first_child ( P );
if ( CodeGen::C::basically_an_array_write ( gen -> from , ref )) {
- WRITE ( "(" ); C_write_lookup_mode = TRUE ; INV_A1 ; C_write_lookup_mode = FALSE ; INV_A2 ; WRITE ( "))" );
+ WRITE ( "(" ); C_write_lookup_mode = TRUE ; INV_A1 ; C_write_lookup_mode = FALSE ;
+ if ( bip == STORE_BIP ) { INV_A2 ; } else { WRITE ( "0" ); }
+ WRITE ( ", %S))" , store_form );
+ } else if ( CodeGen::C::basically_a_property_write ( gen -> from , ref )) {
+ WRITE ( "(" ); C_write_lookup_mode = TRUE ; INV_A1 ; C_write_lookup_mode = FALSE ;
+ if ( bip == STORE_BIP ) { INV_A2 ; } else { WRITE ( "0" ); }
+ WRITE ( ", %S))" , store_form );
} else {
- WRITE ( "(" ); INV_A1 ; WRITE ( " = " ); INV_A2 ; WRITE ( ")" );
+ switch ( bip ) {
+ case PREINCREMENT_BIP: WRITE ( "++(" ); INV_A1 ; WRITE ( ")" ); break ;
+ case POSTINCREMENT_BIP: WRITE ( "(" ); INV_A1 ; WRITE ( ")++" ); break ;
+ case PREDECREMENT_BIP: WRITE ( "--(" ); INV_A1 ; WRITE ( ")" ); break ;
+ case POSTDECREMENT_BIP: WRITE ( "(" ); INV_A1 ; WRITE ( ")--" ); break ;
+ case STORE_BIP: WRITE ( "(" ); INV_A1 ; WRITE ( " = " ); INV_A2 ; WRITE ( ")" ); break ;
+ }
}
-
+This code is used in §2 (five times).
@@ -547,56 +602,17 @@ function togglePopup(material_id) {
}
-
- ( a , b , c )
-
-
-
-
- ( a ( b , c ), d )
-
-
-
-
- ( c ) + 0 *(( b ) + ( a ))
-
-
-
-
-
-
- WRITE ( "(\n" ); INDENT ;
- WRITE ( "! This value evaluates third (i.e., last)\n" ); INV_A3 ;
- OUTDENT ; WRITE ( "+\n" ); INDENT ;
- WRITE ( "0*(\n" ); INDENT ;
- WRITE ( "! The following condition evaluates second\n" );
- WRITE ( "((\n" ); INDENT ; INV_A2 ;
- OUTDENT ; WRITE ( "\n))\n" );
- OUTDENT ; WRITE ( "+\n" ); INDENT ;
- WRITE ( "! The following assignments evaluate first\n" );
- WRITE ( "(" ); INV_A1 ; WRITE ( ")" );
- OUTDENT ; WRITE ( ")\n" );
- OUTDENT ; WRITE ( ")\n" );
+ WRITE ( "(" );
+ INV_A1 ;
+ WRITE ( ", " );
+ INV_A2 ;
+ WRITE ( ", " );
+ INV_A3 ;
+ WRITE ( ")" );
- WRITE ( "objectloop (" ); INV_A1 ; WRITE ( " ofclass " ); INV_A2 ;
- WRITE ( ") {\n" ); INDENT ; INV_A3 ; OUTDENT ; WRITE ( "}\n" );
+ WRITE ( "for (i7val " ); INV_A1 ;
+ WRITE ( " = 1; " ); INV_A1 ;
+ WRITE ( " < i7_max_objects; " ); INV_A1 ;
+ WRITE ( "++) " );
+ WRITE ( "if (i7_ofclass(" ); INV_A1 ; WRITE ( ", " ); INV_A2 ; WRITE ( ")) " );
+ WRITE ( " {\n" ); INDENT ; INV_A3 ;
+ OUTDENT ; WRITE ( "}\n" );
suppress_terminal_semicolon = TRUE ;
@@ -812,23 +834,15 @@ then the result.
void CodeGen::C::compile_dictionary_word ( code_generation_target * cgt , code_generation * gen ,
text_stream * S , int pluralise ) {
text_stream * OUT = CodeGen::current ( gen );
- int n = 0 ;
- WRITE ( "'" );
- LOOP_THROUGH_TEXT ( pos , S ) {
- wchar_t c = Str::get ( pos );
- switch ( c ) {
- case '/' : if ( Str::len ( S ) == 1 ) WRITE ( "@{2F}" ); else WRITE ( "/" ); break ;
- case '\'' : WRITE ( "^" ); break ;
- case '^' : WRITE ( "@{5E}" ); break ;
- case '~' : WRITE ( "@{7E}" ); break ;
- case '@' : WRITE ( "@{40}" ); break ;
- default: PUT ( c );
- }
- if ( n ++ > 32 ) break ;
+ text_stream * val = Dictionaries::get_text ( C_vm_dictionary , S );
+ if ( val ) {
+ WRITE ( "%S" , val );
+ } else {
+ WRITE_TO ( Dictionaries::create_text ( C_vm_dictionary , S ),
+ "i7_%s_dword_%d" , ( pluralise )? "p" : "s" , C_dword_count ++);
+ val = Dictionaries::get_text ( C_vm_dictionary , S );
+ WRITE ( "%S" , val );
}
- if ( pluralise ) WRITE ( "//p" );
- else if ( Str::len ( S ) == 1 ) WRITE ( "//" );
- WRITE ( "'" );
}
@@ -929,12 +943,21 @@ trick called "stubbing", these being "stub definitions".)
void CodeGen::C::property_offset ( code_generation_target * cgt , code_generation * gen , text_stream * prop , int pos , int as_attr ) {
generated_segment * saved = CodeGen::select ( gen , property_offset_creator_I7CGS );
text_stream * OUT = CodeGen::current ( gen );
+
+ if ( C_property_offsets_made ++ == 0 ) {
+ WRITE ( "i7val fn_i7_mgl_CreatePropertyOffsets(int argc) {\n" ); INDENT ;
+ WRITE ( "for (int i=0; i<i7_mgl_attributed_property_offsets_SIZE; i++)\n" ); INDENT ;
+ WRITE ( "write_i7_lookup(i7mem, i7_mgl_attributed_property_offsets, i, -1, i7_cpv_SET);\n" ); OUTDENT ;
+ WRITE ( "for (int i=0; i<i7_mgl_valued_property_offsets_SIZE; i++)\n" ); INDENT ;
+ WRITE ( "write_i7_lookup(i7mem, i7_mgl_valued_property_offsets, i, -1, i7_cpv_SET);\n" ); OUTDENT ;
+ }
+
WRITE ( "write_i7_lookup(i7mem, " );
if ( as_attr ) CodeGen::C::mangle ( cgt , OUT , I "attributed_property_offsets" );
else CodeGen::C::mangle ( cgt , OUT , I "valued_property_offsets" );
WRITE ( ", " );
CodeGen::C::mangle ( cgt , OUT , prop );
- WRITE ( ", %d);\n" , pos );
+ WRITE ( ", %d, i7_cpv_SET);\n" , pos );
CodeGen::deselect ( gen , saved );
}
@@ -959,13 +982,16 @@ trick called "stubbing", these being "stub definitions".)
int CodeGen::C::declare_variable ( code_generation_target * cgt , code_generation * gen ,
inter_tree_node * P , inter_symbol * var_name , int k , int of ) {
if ( Inter::Symbols::read_annotation ( var_name , ASSIMILATED_IANN ) == 1 ) {
- generated_segment * saved = CodeGen::select ( gen , main_matter_I7CGS );
+ generated_segment * saved = CodeGen::select ( gen , globals_array_I7CGS );
text_stream * OUT = CodeGen::current ( gen );
WRITE ( "i7val " );
CodeGen::C::mangle ( cgt , OUT , CodeGen::CL::name ( var_name ));
WRITE ( " = " );
CodeGen::CL::literal ( gen , NULL , Inter::Packages::scope_of ( P ), P -> W . data [ VAL1_VAR_IFLD ], P -> W . data [ VAL2_VAR_IFLD ], FALSE );
WRITE ( ";\n" );
+ WRITE ( "#define i7_defined_" );
+ CodeGen::C::mangle ( cgt , OUT , CodeGen::CL::name ( var_name ));
+ WRITE ( " 1;\n" );
CodeGen::deselect ( gen , saved );
}
if ( Inter::Symbols::read_annotation ( var_name , EXPLICIT_VARIABLE_IANN ) != 1 ) {
@@ -1092,6 +1118,7 @@ trick called "stubbing", these being "stub definitions".)
}
if ( pass == 2 ) {
text_stream * OUT = CodeGen::current ( gen );
+ WRITE ( "return 1;\n" );
WRITE ( "\n}\n" );
}
}
@@ -1162,15 +1189,33 @@ trick called "stubbing", these being "stub definitions".)
C_operand_branches = FALSE ;
C_operand_label = NULL ;
if ( Str::get_at ( opcode , 1 ) == 'j' ) { C_operand_branches = TRUE ; }
- if ( C_operand_branches ) WRITE ( "if (" );
- WRITE ( "glulx_" );
- LOOP_THROUGH_TEXT ( pos , opcode )
- if ( Str::get ( pos ) != '@' )
- PUT ( Str::get ( pos ));
+ if ( Str::eq ( opcode , I "@return" )) WRITE ( "return " );
+ else {
+ if ( C_operand_branches ) WRITE ( "if (" );
+ WRITE ( "glulx_" );
+ LOOP_THROUGH_TEXT ( pos , opcode )
+ if ( Str::get ( pos ) != '@' )
+ PUT ( Str::get ( pos ));
+ }
WRITE ( "(" ); C_operand_count = 0 ;
C_pointer_on_operand = -1;
+ if ( Str::eq ( opcode , I "@acos" )) C_pointer_on_operand = 2 ;
+ if ( Str::eq ( opcode , I "@aload" )) C_pointer_on_operand = 3 ;
+ if ( Str::eq ( opcode , I "@aloadb" )) C_pointer_on_operand = 3 ;
+ if ( Str::eq ( opcode , I "@aloads" )) C_pointer_on_operand = 3 ;
+ if ( Str::eq ( opcode , I "@asin" )) C_pointer_on_operand = 2 ;
+ if ( Str::eq ( opcode , I "@atan" )) C_pointer_on_operand = 2 ;
+ if ( Str::eq ( opcode , I "@binarysearch" )) C_pointer_on_operand = 8 ;
+ if ( Str::eq ( opcode , I "@ceil" )) C_pointer_on_operand = 2 ;
+ if ( Str::eq ( opcode , I "@cos" )) C_pointer_on_operand = 2 ;
if ( Str::eq ( opcode , I "@gestalt" )) C_pointer_on_operand = 3 ;
if ( Str::eq ( opcode , I "@glk" )) C_pointer_on_operand = 3 ;
+ if ( Str::eq ( opcode , I "@pow" )) C_pointer_on_operand = 3 ;
+ if ( Str::eq ( opcode , I "@shiftl" )) C_pointer_on_operand = 3 ;
+ if ( Str::eq ( opcode , I "@sin" )) C_pointer_on_operand = 2 ;
+ if ( Str::eq ( opcode , I "@sqrt" )) C_pointer_on_operand = 2 ;
+ if ( Str::eq ( opcode , I "@tan" )) C_pointer_on_operand = 2 ;
+
}
void CodeGen::C::supply_operand ( code_generation_target * cgt , code_generation * gen , inter_tree_node * F , int is_label ) {
text_stream * OUT = CodeGen::current ( gen );
@@ -1204,32 +1249,31 @@ trick called "stubbing", these being "stub definitions".)
void CodeGen::C::declare_local_variable ( code_generation_target * cgt , int pass ,
code_generation * gen , inter_tree_node * P , inter_symbol * var_name ) {
+ TEMPORARY_TEXT ( name )
+ CodeGen::C::mangle ( cgt , name , CodeGen::CL::name ( var_name ));
C_fn_parameter_count ++;
if ( pass == 1 ) {
if ( Str::eq ( var_name -> symbol_name , I "_vararg_count" )) {
C_fn_being_found -> uses_vararg_model = TRUE ;
- WRITE_TO ( C_fn_prototype , ", i7val " );
- CodeGen::C::mangle ( cgt , C_fn_prototype , var_name -> symbol_name );
+ WRITE_TO ( C_fn_prototype , ", i7val %S" , name );
WRITE_TO ( C_fn_prototype , ", i7varargs " );
CodeGen::C::mangle ( cgt , C_fn_prototype , I "_varargs" );
} else {
- WRITE_TO ( C_fn_prototype , ", i7val " );
- CodeGen::C::mangle ( cgt , C_fn_prototype , var_name -> symbol_name );
+ WRITE_TO ( C_fn_prototype , ", i7val %S" , name );
}
C_fn_being_found -> max_arity ++;
}
if ( pass == 2 ) {
text_stream * OUT = CodeGen::current ( gen );
if ( Str::eq ( var_name -> symbol_name , I "_vararg_count" )) {
- WRITE ( ", i7val " );
- CodeGen::C::mangle ( cgt , OUT , var_name -> symbol_name );
+ WRITE ( ", i7val %S" , name );
WRITE ( ", i7varargs " );
CodeGen::C::mangle ( cgt , OUT , I "_varargs" );
} else {
- WRITE ( ", i7val " );
- CodeGen::C::mangle ( cgt , OUT , var_name -> symbol_name );
+ WRITE ( ", i7val %S" , name );
}
}
+ DISCARD_TEXT ( name )
}
void CodeGen::C::declare_class ( code_generation_target * cgt , code_generation * gen , text_stream * class_name ) {
@@ -1357,8 +1401,31 @@ trick called "stubbing", these being "stub definitions".)
}
return FALSE;
}
+
+int CodeGen::C::basically_a_property_write(inter_tree *I, inter_tree_node *P) {
+ int reffed = FALSE;
+ while (P->W.data[ID_IFLD] == REFERENCE_IST) {
+ P = InterTree::first_child(P);
+ reffed = TRUE;
+ }
+ if (P->W.data[ID_IFLD] == INV_IST) {
+ if (P->W.data[METHOD_INV_IFLD] == INVOKED_PRIMITIVE) {
+ inter_symbol *prim = Inter::Inv::invokee(P);
+ inter_ti bip = Primitives::to_bip(I, prim);
+ if (bip == PROPERTYVALUE_BIP) return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+void CodeGen::C::new_fake_action(code_generation_target *cgt, code_generation *gen, text_stream *name) {
+ generated_segment *saved = CodeGen::select(gen, predeclarations_I7CGS);
+ text_stream *OUT = CodeGen::current(gen);
+ WRITE(" # define i7_ss_ % S % d \ n ", name, C_action_count++);
+ CodeGen::deselect(gen, saved);
+}
-The function CodeGen::C::array_entry is used in §1 . The function CodeGen::C::end_array is used in §1 . The function CodeGen::C::basically_an_array_write is used in §2.2 . The structure final_c_function is private to this section.
+The function CodeGen::C::array_entry is used in §1 . The function CodeGen::C::end_array is used in §1 . The function CodeGen::C::basically_an_array_write is used in §2.2 . The function CodeGen::C::basically_a_property_write is used in §2.2 . The function CodeGen::C::new_fake_action is used in §1 . The structure final_c_function is private to this section.
diff --git a/inform7/Figures/memory-diagnostics.txt b/inform7/Figures/memory-diagnostics.txt
index 9cabef2bb..75a1c46af 100644
--- a/inform7/Figures/memory-diagnostics.txt
+++ b/inform7/Figures/memory-diagnostics.txt
@@ -1,6 +1,6 @@
-Total memory consumption was 398279K = 389 MB
+Total memory consumption was 399081K = 390 MB
-60.2% was used for 1995518 objects, in 371142 frames in 300 x 800K = 240000K = 234 MB:
+60.3% was used for 1995520 objects, in 371144 frames in 301 x 800K = 240800K = 235 MB:
10.2% inter_tree_node_array 58 x 8192 = 475136 objects, 41813824 bytes
7.0% text_stream_array 5128 x 100 = 512800 objects, 28880896 bytes
@@ -96,7 +96,7 @@ Total memory consumption was 398279K = 389 MB
---- nonlocal_variable 93 objects, 20088 bytes
---- property 146 objects, 19856 bytes
---- timed_rules_rfd_data 400 objects, 19200 bytes
- ---- method 393 objects, 18864 bytes
+ ---- method 395 objects, 18960 bytes
---- pcalc_prop_deferral 86 objects, 17888 bytes
---- instance 167 objects, 17368 bytes
---- parse_node_tree 20 objects, 17280 bytes
@@ -235,9 +235,9 @@ Total memory consumption was 398279K = 389 MB
---- by_function_bp_data 1 object, 40 bytes
---- loop_over_scope 1 object, 40 bytes
-39.7% was used for memory not allocated for objects:
+39.6% was used for memory not allocated for objects:
- 21.1% text stream storage 86230488 bytes in 530517 claims
+ 21.1% text stream storage 86233212 bytes in 530551 claims
4.4% dictionary storage 18153984 bytes in 33230 claims
---- sorting 744 bytes in 3 claims
1.7% source text 7200000 bytes in 3 claims
@@ -255,5 +255,5 @@ Total memory consumption was 398279K = 389 MB
---- code generation workspace for objects 9648 bytes in 9 claims
---- emitter array storage 161920 bytes in 2064 claims
-18.6% was overhead - 75939784 bytes = 74159K = 72 MB
+18.7% was overhead - 76758888 bytes = 74959K = 73 MB
diff --git a/inform7/Figures/timings-diagnostics.txt b/inform7/Figures/timings-diagnostics.txt
index a3f61f7d8..df75745e9 100644
--- a/inform7/Figures/timings-diagnostics.txt
+++ b/inform7/Figures/timings-diagnostics.txt
@@ -1,11 +1,11 @@
100.0% in inform7 run
- 54.9% in compilation to Inter
- 39.9% in //Sequence::undertake_queued_tasks//
- 3.5% in //MajorNodes::pre_pass//
+ 55.6% in compilation to Inter
+ 40.4% in //Sequence::undertake_queued_tasks//
+ 3.6% in //MajorNodes::pre_pass//
2.6% in //MajorNodes::pass_1//
+ 1.5% in //ImperativeDefinitions::assess_all//
1.5% in //RTPhrasebook::compile_entries//
- 1.4% in //ImperativeDefinitions::assess_all//
- 1.1% in //RTKindConstructors::compile//
+ 1.2% in //RTKindConstructors::compile//
0.4% in //ImperativeDefinitions::compile_first_block//
0.4% in //MajorNodes::pass_2//
0.4% in //Sequence::undertake_queued_tasks//
@@ -16,12 +16,12 @@
0.1% in //RTKindConstructors::compile_permissions//
0.1% in //Task::make_built_in_kind_constructors//
0.1% in //World::stages_II_and_III//
- 1.8% not specifically accounted for
- 43.0% in running Inter pipeline
- 10.8% in step preparation
- 9.9% in inter step 7/14: consolidate-text
- 8.2% in inter step 14/14: generate inform6 -> auto.inf
- 8.0% in inter step 2/14: link
+ 1.7% not specifically accounted for
+ 42.3% in running Inter pipeline
+ 10.7% in step preparation
+ 9.6% in inter step 7/14: consolidate-text
+ 8.1% in inter step 14/14: generate inform6 -> auto.inf
+ 7.9% in inter step 2/14: link
1.5% in inter step 10/14: make-identifiers-unique
0.4% in inter step 11/14: reconcile-verbs
0.2% in inter step 13/14: eliminate-redundant-operations
@@ -29,7 +29,6 @@
0.2% in inter step 8/14: resolve-external-symbols
0.2% in inter step 9/14: inspect-plugs
0.1% in inter step 12/14: eliminate-redundant-labels
- 0.1% in inter step 3/14: merge-template <- none
0.1% in inter step 4/14: parse-linked-matter
0.1% in inter step 5/14: resolve-conditional-compilation
2.3% not specifically accounted for
diff --git a/inter/Tests/C/CelloWorld.txt b/inter/Tests/C/CelloWorld.txt
deleted file mode 100644
index d42aff076..000000000
--- a/inter/Tests/C/CelloWorld.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-To begin:
- say "Hello world."
diff --git a/inter/Tests/General/_Results_Ideal/ObjKind.txt b/inter/Tests/General/_Results_Ideal/ObjKind.txt
index f1aaf20ed..7e51b1998 100644
--- a/inter/Tests/General/_Results_Ideal/ObjKind.txt
+++ b/inter/Tests/General/_Results_Ideal/ObjKind.txt
@@ -3,24 +3,18 @@ Global debug_flag;
Array KindHierarchy --> (K0_kind) (0) (K_fruit) (0) (K_citrus_fruit) (1) (K_stone) (0) (K_feldspar) (3) (K_mica) (3);
Class K_object
;
-
Class K_fruit
class K_object
;
-
Class K_citrus_fruit
class K_fruit
;
-
Class K_stone
class K_object
;
-
Class K_feldspar
class K_stone
;
-
Class K_mica
class K_stone
;
-
diff --git a/inter/Tests/Toys/_I6_Results_Ideal/Arrays.txt b/inter/Tests/Toys/_I6_Results_Ideal/Arrays.txt
index 12526e0df..43f28c5e0 100644
--- a/inter/Tests/Toys/_I6_Results_Ideal/Arrays.txt
+++ b/inter/Tests/Toys/_I6_Results_Ideal/Arrays.txt
@@ -42,4 +42,4 @@ Array KindHierarchy --> (0) (0);
print (mutable-->(1));
print ".^";
quit;
-];
\ No newline at end of file
+];
diff --git a/inter/Tests/inter.intest b/inter/Tests/inter.intest
index 04965b676..f9a1438d8 100644
--- a/inter/Tests/inter.intest
+++ b/inter/Tests/inter.intest
@@ -4,7 +4,6 @@
-cases [Duplex] 'inter/Tests/Duplex'
-cases [PipelineErrors] 'inter/Tests/PipelineErrors'
-cases [Toy] 'inter/Tests/Toys'
--cases [BasicC] 'inter/Tests/C'
-recipe [Valid]
@@ -210,63 +209,3 @@
! or: 'I6 and C programs disagreed'
-end
-
--recipe [BasicC]
- set: $I7 = inform7/Tangled/inform7
- set: $INTERNAL = inform7/Internal
- set: $WORKSPACE = intest/Workspace
- set: $ZINT = inform6/Tests/Assistants/dumb-frotz/dumb-frotz
- set: $GINT = inform6/Tests/Assistants/dumb-glulx/glulxe/glulxe
-
- set: $I7CLIB = inform7/Internal/Miscellany
-
- set: $VM = G
- set: $FORMAT = ulx
- set: $I6OPTIONS = -E2SDwGx
- set: $INT = $GINT
- set: $INTNAME = dumb-glulxe
- set: $INTOPTIONS = -u -q
-
- extract: $WORK/Example.inform/Source/story.ni $VM
-
- mkdir: $WORK/Transient
- step: find $WORK/Transient -mindepth 1 -delete
-
- mkdir: $PATH/_Results_Actual
- mkdir: $PATH/_Results_Ideal
- mkdir: $PATH/_Textual
- mkdir: $PATH/_C
-
- set: $I7OPTIONS = -kit BasicInformKit -format=$FORMAT -no-progress -fixtime -rng -sigils -log nothing -external inform7/Tests -transient $WORK/Transient -no-index -internal $INTERNAL
- set: $PIPELINE = test_basic_c
-
- set: $I7CONSOLE = $WORK/Example.inform/Build/i7_output.txt
- set: $TOUT = $PATH/_Textual/$CASE.intert
- set: $COUT = $PATH/_C/$CASE.c
- set: $OFILE = $WORK/Example.inform/Build/$CASE.o
- step: $I7 `$I7OPTIONS -format=$FORMAT -project $WORK/Example.inform -variable *tout=$TOUT -variable *cout=$COUT -pipeline $PIPELINE >$I7CONSOLE 2>&1
- or: 'failed with Problem message(s)' $I7CONSOLE
-
- set: $CCCONSOLE = $WORK/Example.inform/Build/cc_output.txt
- set: $LINKCONSOLE = $WORK/Example.inform/Build/link_output.txt
- set: $STORYFILE = $WORK/Example.inform/Build/final
-
- step: clang -std=c99 -c -o $OFILE $COUT -ferror-limit=10000 -Wno-parentheses-equality -I $I7CLIB >$CCCONSOLE 2>&1
- or: 'failed to compile C' $CCCONSOLE
-
- step: clang -g -o $STORYFILE $OFILE -ferror-limit=10000 >$LINKCONSOLE 2>&1
- or: 'failed to link C' $LINKCONSOLE
-
- set: $A = $PATH/_Results_Actual/$CASE.txt
- set: $I = $PATH/_Results_Ideal/$CASE.txt
-
- step: $STORYFILE >$A 2>&1
- or: 'failed to run C program' $A
-
- show: $A
-
- match text: $A $I
- or: 'C program misbehaved'
-
- pass: 'passed'
--end
diff --git a/inter/codegen-module/Chapter 5/Final C.w b/inter/codegen-module/Chapter 5/Final C.w
index 065066b4f..e9e3964eb 100644
--- a/inter/codegen-module/Chapter 5/Final C.w
+++ b/inter/codegen-module/Chapter 5/Final C.w
@@ -70,6 +70,7 @@ int C_class_counter = 0;
int C_instance_counter = 0;
int C_dword_count = 0;
int C_action_count = 0;
+int C_property_offsets_made = 0;
struct dictionary *C_vm_dictionary = NULL;
int CodeGen::C::begin_generation(code_generation_target *cgt, code_generation *gen) {
@@ -163,25 +164,8 @@ int CodeGen::C::begin_generation(code_generation_target *cgt, code_generation *g
WRITE("int i7_initializer(void) {\n");
WRITE("i7val ref = 0;\n");
CodeGen::deselect(gen, saved);
-
- saved = CodeGen::select(gen, property_offset_creator_I7CGS);
- OUT = CodeGen::current(gen);
- WRITE("i7val fn_");
- CodeGen::C::mangle(cgt, OUT, I"CreatePropertyOffsets");
- WRITE("(int argc) {\n"); INDENT;
- WRITE("for (int i=0; i<");
- CodeGen::C::mangle(cgt, OUT, I"attributed_property_offsets_SIZE");
- WRITE("; i++)"); INDENT;
- WRITE("write_i7_lookup(i7mem, ");
- CodeGen::C::mangle(cgt, OUT, I"attributed_property_offsets");
- WRITE(", i, -1, i7_cpv_SET);\n"); OUTDENT;
- WRITE("for (int i=0; i<");
- CodeGen::C::mangle(cgt, OUT, I"valued_property_offsets_SIZE");
- WRITE("; i++)"); INDENT;
- WRITE("write_i7_lookup(i7mem, ");
- CodeGen::C::mangle(cgt, OUT, I"valued_property_offsets");
- WRITE(", i, -1, i7_cpv_SET);\n"); OUTDENT;
- CodeGen::deselect(gen, saved);
+
+ C_property_offsets_made = 0;
return FALSE;
}
@@ -201,16 +185,20 @@ int CodeGen::C::end_generation(code_generation_target *cgt, code_generation *gen
saved = CodeGen::select(gen, globals_array_I7CGS);
OUT = CodeGen::current(gen);
+ WRITE("#ifdef i7_defined_i7_mgl_I7S_Comp\n");
WRITE("#ifndef fn_i7_mgl_I7S_Comp\n");
WRITE("i7val fn_i7_mgl_I7S_Comp(int argc, i7val a1, i7val a2, i7val a3, i7val a4, i7val a5) {\n");
WRITE(" return i7_call_5(i7_mgl_I7S_Comp, a1, a2, a3, a4, a5);\n");
WRITE("}\n");
WRITE("#endif\n");
+ WRITE("#endif\n");
+ WRITE("#ifdef i7_defined_i7_mgl_I7S_Swap\n");
WRITE("#ifndef fn_i7_mgl_I7S_Swap\n");
WRITE("i7val fn_i7_mgl_I7S_Swap(int argc, i7val a1, i7val a2, i7val a3) {\n");
WRITE(" return i7_call_3(i7_mgl_I7S_Swap, a1, a2, a3);\n");
WRITE("}\n");
WRITE("#endif\n");
+ WRITE("#endif\n");
CodeGen::deselect(gen, saved);
saved = CodeGen::select(gen, c_mem_I7CGS);
@@ -224,12 +212,14 @@ int CodeGen::C::end_generation(code_generation_target *cgt, code_generation *gen
WRITE("}\n");
CodeGen::deselect(gen, saved);
- saved = CodeGen::select(gen, property_offset_creator_I7CGS);
- OUT = CodeGen::current(gen);
- WRITE("return 0;\n");
- OUTDENT;
- WRITE("}\n");
- CodeGen::deselect(gen, saved);
+ if (C_property_offsets_made > 0) {
+ saved = CodeGen::select(gen, property_offset_creator_I7CGS);
+ OUT = CodeGen::current(gen);
+ WRITE("return 0;\n");
+ OUTDENT;
+ WRITE("}\n");
+ CodeGen::deselect(gen, saved);
+ }
return FALSE;
}
@@ -790,6 +780,15 @@ void CodeGen::C::declare_attribute(code_generation_target *cgt, code_generation
void CodeGen::C::property_offset(code_generation_target *cgt, code_generation *gen, text_stream *prop, int pos, int as_attr) {
generated_segment *saved = CodeGen::select(gen, property_offset_creator_I7CGS);
text_stream *OUT = CodeGen::current(gen);
+
+ if (C_property_offsets_made++ == 0) {
+ WRITE("i7val fn_i7_mgl_CreatePropertyOffsets(int argc) {\n"); INDENT;
+ WRITE("for (int i=0; iW.data[VAL1_VAR_IFLD], P->W.data[VAL2_VAR_IFLD], FALSE);
WRITE(";\n");
+ WRITE("#define i7_defined_");
+ CodeGen::C::mangle(cgt, OUT, CodeGen::CL::name(var_name));
+ WRITE(" 1;\n");
CodeGen::deselect(gen, saved);
}
if (Inter::Symbols::read_annotation(var_name, EXPLICIT_VARIABLE_IANN) != 1) {
diff --git a/inter/codegen-module/Chapter 5/Final Inform 6.w b/inter/codegen-module/Chapter 5/Final Inform 6.w
index 5c0ddef7c..a812f82d8 100644
--- a/inter/codegen-module/Chapter 5/Final Inform 6.w
+++ b/inter/codegen-module/Chapter 5/Final Inform 6.w
@@ -96,6 +96,7 @@ now a bitmap of flags for tracing actions, calls to object routines, and so on.
@e property_offset_creator_I7CGS
=
+int I6_property_offsets_made = 0;
int CodeGen::I6::begin_generation(code_generation_target *cgt, code_generation *gen) {
gen->segments[pragmatic_matter_I7CGS] = CodeGen::new_segment();
gen->segments[compiler_versioning_matter_I7CGS] = CodeGen::new_segment();
@@ -124,30 +125,25 @@ int CodeGen::I6::begin_generation(code_generation_target *cgt, code_generation *
gen->segments[stubs_at_eof_I7CGS] = CodeGen::new_segment();
gen->segments[property_offset_creator_I7CGS] = CodeGen::new_segment();
+ I6_property_offsets_made = 0;
+
generated_segment *saved = CodeGen::select(gen, compiler_versioning_matter_I7CGS);
text_stream *OUT = CodeGen::current(gen);
WRITE("Constant Grammar__Version 2;\n");
WRITE("Global debug_flag;\n");
CodeGen::deselect(gen, saved);
- saved = CodeGen::select(gen, property_offset_creator_I7CGS);
- OUT = CodeGen::current(gen);
- WRITE("[ CreatePropertyOffsets i;\n"); INDENT;
- WRITE("for (i=0: ii = -1;\n"); OUTDENT;
- WRITE("for (i=0: ii = -1;\n"); OUTDENT;
- CodeGen::deselect(gen, saved);
-
return FALSE;
}
int CodeGen::I6::end_generation(code_generation_target *cgt, code_generation *gen) {
- generated_segment *saved = CodeGen::select(gen, property_offset_creator_I7CGS);
- text_stream *OUT = CodeGen::current(gen);
- OUTDENT;
- WRITE("];\n");
- CodeGen::deselect(gen, saved);
+ if (I6_property_offsets_made > 0) {
+ generated_segment *saved = CodeGen::select(gen, property_offset_creator_I7CGS);
+ text_stream *OUT = CodeGen::current(gen);
+ OUTDENT;
+ WRITE("];\n");
+ CodeGen::deselect(gen, saved);
+ }
return FALSE;
}
@@ -614,6 +610,13 @@ void CodeGen::I6::declare_attribute(code_generation_target *cgt, code_generation
void CodeGen::I6::property_offset(code_generation_target *cgt, code_generation *gen, text_stream *prop, int pos, int as_attr) {
generated_segment *saved = CodeGen::select(gen, property_offset_creator_I7CGS);
text_stream *OUT = CodeGen::current(gen);
+ if (I6_property_offsets_made++ == 0) {
+ WRITE("[ CreatePropertyOffsets i;\n"); INDENT;
+ WRITE("for (i=0: ii = -1;\n"); OUTDENT;
+ WRITE("for (i=0: ii = -1;\n"); OUTDENT;
+ }
if (as_attr) WRITE("attributed_property_offsets");
else WRITE("valued_property_offsets");
WRITE("-->%S = %d;\n", prop, pos);
@@ -732,7 +735,7 @@ void CodeGen::I6::place_label(code_generation_target *cgt, code_generation *gen,
void CodeGen::I6::end_function(code_generation_target *cgt, int pass, code_generation *gen, inter_symbol *fn) {
if (pass == 2) {
text_stream *OUT = CodeGen::current(gen);
- WRITE("];");
+ WRITE("];\n");
}
}