diff --git a/README.md b/README.md index 5dfd07ad1..277c0c815 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Inform 7 -v10.1.0-alpha.1+6T54 'Krypton' (16 October 2021) +v10.1.0-alpha.1+6T55 'Krypton' (17 October 2021) ## About Inform 7 diff --git a/build.txt b/build.txt index 37ecccf87..d468414ef 100644 --- a/build.txt +++ b/build.txt @@ -1,3 +1,3 @@ Prerelease: alpha.1 -Build Date: 16 October 2021 -Build Number: 6T54 +Build Date: 17 October 2021 +Build Number: 6T55 diff --git a/docs/BasicInformKit/S-rtp.html b/docs/BasicInformKit/S-rtp.html index 45a76b09a..c87e170b3 100644 --- a/docs/BasicInformKit/S-rtp.html +++ b/docs/BasicInformKit/S-rtp.html @@ -320,10 +320,7 @@ it doesn't mean it actually does have. } .PermissionFound; - if (K >> obj provides q) rtrue; -@provides_gprop K obj q a; -if (a) rtrue; if (issue_rtp) RunTimeProblem(RTP_UNSET, obj, q); rfalse; @@ -366,8 +363,7 @@ the one which the player is on.
 [ GProperty K V pr err holder val;
     if (ProvidesProperty(K, V, pr, 1-err)) {
-        @read_gprop K V pr val;
-        return val;
+        return (K >> V . pr);
     }
     return 0;
 ];
@@ -380,7 +376,7 @@ converted from an rvalue to an lvalue.
 
 [ WriteGProperty K V pr val holder;
     if (ProvidesProperty(K, V, pr, true)) {
-        @write_gprop K V pr val;
+        K >> V . pr = val;
     }
 ];
 
diff --git a/docs/WorldModelKit/S-wrl.html b/docs/WorldModelKit/S-wrl.html index 8b81159e1..ff9fea244 100644 --- a/docs/WorldModelKit/S-wrl.html +++ b/docs/WorldModelKit/S-wrl.html @@ -565,7 +565,7 @@ are a bit more careful about the senses. if (flag == false) { if (i in toroom) remove i; } } if ((i ofclass K4_door) && (parent(i) == nothing)) { - move i to ((i.door_to).call()); + move i to (i.door_to()); } } } diff --git a/docs/building-module/1-ip.html b/docs/building-module/1-ip.html index 1fbf43910..549015938 100644 --- a/docs/building-module/1-ip.html +++ b/docs/building-module/1-ip.html @@ -165,8 +165,8 @@ function togglePopup(material_id) { Primitives::emit_one(I, IBM, I"!externalcall", I"val val -> val"); Primitives::emit_one(I, IBM, I"!propertyaddress", I"val val -> val"); Primitives::emit_one(I, IBM, I"!propertylength", I"val val -> val"); - Primitives::emit_one(I, IBM, I"!xpropertyexists", I"val val val -> val"); - Primitives::emit_one(I, IBM, I"!propertyvalue", I"val val -> val"); + Primitives::emit_one(I, IBM, I"!propertyexists", I"val val val -> val"); + Primitives::emit_one(I, IBM, I"!propertyvalue", I"val val val -> val"); Primitives::emit_one(I, IBM, I"!notin", I"val val -> val"); } @@ -331,7 +331,7 @@ function togglePopup(material_id) { enum EXTERNALCALL_BIP enum PROPERTYADDRESS_BIP enum PROPERTYLENGTH_BIP -enum XPROPERTYEXISTS_BIP +enum PROPERTYEXISTS_BIP enum PROPERTYVALUE_BIP
@@ -429,7 +429,7 @@ function togglePopup(material_id) {
         case EXTERNALCALL_BIP: return I"!externalcall";
         case PROPERTYADDRESS_BIP: return I"!propertyaddress";
         case PROPERTYLENGTH_BIP: return I"!propertylength";
-        case XPROPERTYEXISTS_BIP: return I"!xpropertyexists";
+        case PROPERTYEXISTS_BIP: return I"!propertyexists";
         case PROPERTYVALUE_BIP: return I"!propertyvalue";
     }
     return I"<none>";
@@ -542,7 +542,7 @@ function togglePopup(material_id) {
     if (Str::eq(symb->symbol_name, I"!externalcall")) bip = EXTERNALCALL_BIP;
     if (Str::eq(symb->symbol_name, I"!propertyaddress")) bip = PROPERTYADDRESS_BIP;
     if (Str::eq(symb->symbol_name, I"!propertylength")) bip = PROPERTYLENGTH_BIP;
-    if (Str::eq(symb->symbol_name, I"!xpropertyexists")) bip = XPROPERTYEXISTS_BIP;
+    if (Str::eq(symb->symbol_name, I"!propertyexists")) bip = PROPERTYEXISTS_BIP;
     if (Str::eq(symb->symbol_name, I"!propertyvalue")) bip = PROPERTYVALUE_BIP;
     if (bip != 0) {
         Inter::Symbols::annotate_i(symb, BIP_CODE_IANN, bip);
diff --git a/docs/building-module/2-eis.html b/docs/building-module/2-eis.html
index 64167a804..8e35ec68e 100644
--- a/docs/building-module/2-eis.html
+++ b/docs/building-module/2-eis.html
@@ -460,7 +460,7 @@ function togglePopup(material_id) {
     if (isn->isn_clarifier == HAS_XBIP) op = PROPERTYVALUE_BIP;
 
     int insert_OBJECT_TY = FALSE;
-    if (op == XPROPERTYEXISTS_BIP) {
+    if ((op == PROPERTYEXISTS_BIP) || (op == PROPERTYVALUE_BIP)) {
         if ((isn->child_node->isn_type != OPERATION_ISNT) ||
             (isn->child_node->isn_clarifier != OWNERKIND_XBIP))
             insert_OBJECT_TY = TRUE;
diff --git a/docs/building-module/2-is.html b/docs/building-module/2-is.html
index c5bca29d5..dab45b9ab 100644
--- a/docs/building-module/2-is.html
+++ b/docs/building-module/2-is.html
@@ -1600,7 +1600,7 @@ inclusive; we ignore an empty token.
     if (Str::eq(T, I"ofclass")) { is = OPERATOR_ISTT; which = OFCLASS_BIP; }
     if (Str::eq(T, I"has")) { is = OPERATOR_ISTT; which = HAS_XBIP; }
     if (Str::eq(T, I"hasnt")) { is = OPERATOR_ISTT; which = HASNT_XBIP; }
-    if (Str::eq(T, I"provides")) { is = OPERATOR_ISTT; which = XPROPERTYEXISTS_BIP; }
+    if (Str::eq(T, I"provides")) { is = OPERATOR_ISTT; which = PROPERTYEXISTS_BIP; }
     if (Str::eq(T, I"in")) { is = OPERATOR_ISTT; which = IN_BIP; }
     if (Str::eq(T, I"notin")) { is = OPERATOR_ISTT; which = NOTIN_BIP; }
 
@@ -3074,7 +3074,7 @@ which are prefix or postfix, and so on.
     if (O == HAS_XBIP) return 3;
     if (O == HASNT_XBIP) return 3;
     if (O == OFCLASS_BIP) return 3;
-    if (O == XPROPERTYEXISTS_BIP) return 3;
+    if (O == PROPERTYEXISTS_BIP) return 3;
     if (O == IN_BIP) return 3;
     if (O == NOTIN_BIP) return 3;
 
@@ -3136,7 +3136,7 @@ which are prefix or postfix, and so on.
     if (O == HAS_XBIP) return I"has";
     if (O == HASNT_XBIP) return I"hasnt";
     if (O == OFCLASS_BIP) return I"ofclass";
-    if (O == XPROPERTYEXISTS_BIP) return I"provides";
+    if (O == PROPERTYEXISTS_BIP) return I"provides";
     if (O == IN_BIP) return I"in";
     if (O == NOTIN_BIP) return I"notin";
 
@@ -3190,7 +3190,7 @@ which are prefix or postfix, and so on.
     if (O == HAS_XBIP) return 2;
     if (O == HASNT_XBIP) return 2;
     if (O == OFCLASS_BIP) return 2;
-    if (O == XPROPERTYEXISTS_BIP) return 2;
+    if (O == PROPERTYEXISTS_BIP) return 2;
     if (O == IN_BIP) return 2;
     if (O == NOTIN_BIP) return 2;
 
diff --git a/docs/final-module/2-cg.html b/docs/final-module/2-cg.html
index bf79b6137..5723b5df7 100644
--- a/docs/final-module/2-cg.html
+++ b/docs/final-module/2-cg.html
@@ -161,7 +161,7 @@ object.
     return gen;
 }
 
- +

§2.1. Traverse for global bric-a-brac2.1 =

@@ -441,13 +441,13 @@ some temporary stream somewhere. For that, use the following pair:

-void CodeGen::select_temporary(code_generation *gen, text_stream *T) {
+void CodeGen::select_temporary(code_generation *gen, text_stream *T) {
     if (gen->segmentation.temporarily_diverted) internal_error("nested temporary segments");
     gen->segmentation.temporarily_diverted_to = T;
     gen->segmentation.temporarily_diverted = TRUE;
 }
 
-void CodeGen::deselect_temporary(code_generation *gen) {
+void CodeGen::deselect_temporary(code_generation *gen) {
     gen->segmentation.temporarily_diverted_to = NULL;
     gen->segmentation.temporarily_diverted = FALSE;
 }
diff --git a/docs/final-module/2-vnl.html b/docs/final-module/2-vnl.html
index f0d6b405a..29dd90f4d 100644
--- a/docs/final-module/2-vnl.html
+++ b/docs/final-module/2-vnl.html
@@ -197,7 +197,7 @@ well the entire tree by the end.
 define VNODE_ALLC  LOOP_THROUGH_INTER_CHILDREN(C, P) Vanilla::node(gen, C)
 
-void Vanilla::node(code_generation *gen, inter_tree_node *P) {
+void Vanilla::node(code_generation *gen, inter_tree_node *P) {
     switch (P->W.data[ID_IFLD]) {
         case CONSTANT_IST:      VanillaConstants::constant(gen, P); break;
 
diff --git a/docs/final-module/4-i6c2.html b/docs/final-module/4-i6c2.html
index c8dfa6033..e02961cb5 100644
--- a/docs/final-module/4-i6c2.html
+++ b/docs/final-module/4-i6c2.html
@@ -317,18 +317,11 @@ unless we want to save the result. (See the Z-Machine Standards Document.)
 As a dodge, we use the Inform 6 statement read X Y instead.
 

-

The three pseudo-opcodes @provides_gprop, @read_gprop and @write_gprop are -however not valid for either Z or G. -

-
 void I6TargetCode::invoke_opcode(code_generator *cgt, code_generation *gen,
     text_stream *opcode, int operand_count, inter_tree_node **operands,
     inter_tree_node *label, int label_sense, int void_context) {
     text_stream *OUT = CodeGen::current(gen);
-    if (Str::eq(opcode, I"@provides_gprop")) Invoke special provides_gprop5.1;
-    if (Str::eq(opcode, I"@read_gprop")) Invoke special read_gprop5.2;
-    if (Str::eq(opcode, I"@write_gprop")) Invoke special write_gprop5.3;
     if (Str::eq(opcode, I"@aread")) WRITE("read");
     else WRITE("%S", opcode);
     for (int opc = 0; opc < operand_count; opc++) {
@@ -343,142 +336,6 @@ however not valid for either Z or G.
     if (void_context) WRITE(";\n");
 }
 
-

§5.1. Invoke special provides_gprop5.1 = -

- -
-    TEMPORARY_TEXT(K)
-    TEMPORARY_TEXT(obj)
-    TEMPORARY_TEXT(p)
-    TEMPORARY_TEXT(val)
-    CodeGen::select_temporary(gen, K);
-    Vanilla::node(gen, operands[0]);
-    CodeGen::deselect_temporary(gen);
-    CodeGen::select_temporary(gen, obj);
-    Vanilla::node(gen, operands[1]);
-    CodeGen::deselect_temporary(gen);
-    CodeGen::select_temporary(gen, p);
-    Vanilla::node(gen, operands[2]);
-    CodeGen::deselect_temporary(gen);
-    CodeGen::select_temporary(gen, val);
-    Vanilla::node(gen, operands[3]);
-    CodeGen::deselect_temporary(gen);
-
-    I6_GEN_DATA(value_ranges_needed) = TRUE;
-    I6_GEN_DATA(value_property_holders_needed) = TRUE;
-
-    WRITE("if (%S == OBJECT_TY) {\n", K);
-    WRITE("    if ((%S) && (metaclass(%S) == Object)) {\n", obj, obj);
-    WRITE("        if ((%S-->0 == 2) || (%S provides %S-->1)) {\n", p, obj, p);
-    WRITE("            %S = 1;\n", val);
-    WRITE("        } else {\n");
-    WRITE("            %S = 0;\n", val);
-    WRITE("        }\n");
-    WRITE("    } else {\n");
-    WRITE("        %S = 0;\n", val);
-    WRITE("    }\n");
-    WRITE("} else {\n");
-    WRITE("    if ((%S >= 1) && (%S <= value_ranges-->%S)) {\n", obj, obj, K);
-    WRITE("        holder = value_property_holders-->%S;\n", K);
-    WRITE("        if ((holder) && (holder provides %S-->1)) {\n", p);
-    WRITE("            %S = 1;\n", val);
-    WRITE("        } else {\n");
-    WRITE("            %S = 0;\n", val);
-    WRITE("        }\n");
-    WRITE("    } else {\n");
-    WRITE("        %S = 0;\n", val);
-    WRITE("    }\n");
-    WRITE("}\n");
-
-    DISCARD_TEXT(K)
-    DISCARD_TEXT(obj)
-    DISCARD_TEXT(p)
-    DISCARD_TEXT(val)
-    return;
-
- -

§5.2. Invoke special read_gprop5.2 = -

- -
-    TEMPORARY_TEXT(K)
-    TEMPORARY_TEXT(obj)
-    TEMPORARY_TEXT(p)
-    TEMPORARY_TEXT(val)
-    CodeGen::select_temporary(gen, K);
-    Vanilla::node(gen, operands[0]);
-    CodeGen::deselect_temporary(gen);
-    CodeGen::select_temporary(gen, obj);
-    Vanilla::node(gen, operands[1]);
-    CodeGen::deselect_temporary(gen);
-    CodeGen::select_temporary(gen, p);
-    Vanilla::node(gen, operands[2]);
-    CodeGen::deselect_temporary(gen);
-    CodeGen::select_temporary(gen, val);
-    Vanilla::node(gen, operands[3]);
-    CodeGen::deselect_temporary(gen);
-
-    I6_GEN_DATA(value_property_holders_needed) = TRUE;
-
-    WRITE("if (%S == OBJECT_TY) {\n", K);
-    WRITE("    if (%S-->0 == 2) {\n", p);
-    WRITE("        if (%S has %S-->1) %S = 1; else %S = 0;\n", obj, p, val, val);
-    WRITE("    } else {\n");
-    WRITE("        if (%S-->1 == door_to) %S = %S.(%S-->1)();\n", p, val, obj, p);
-    WRITE("        else %S = %S.(%S-->1);\n", val, obj, p);
-    WRITE("    }\n");
-    WRITE("} else {\n");
-    WRITE("    holder = value_property_holders-->%S;\n", K);
-    WRITE("    %S = (holder.(%S-->1))-->(%S+COL_HSIZE);\n", val, p, obj);
-    WRITE("}\n");
-
-    DISCARD_TEXT(K)
-    DISCARD_TEXT(obj)
-    DISCARD_TEXT(p)
-    DISCARD_TEXT(val)
-    return;
-
- -

§5.3. Invoke special write_gprop5.3 = -

- -
-    TEMPORARY_TEXT(K)
-    TEMPORARY_TEXT(obj)
-    TEMPORARY_TEXT(p)
-    TEMPORARY_TEXT(val)
-    CodeGen::select_temporary(gen, K);
-    Vanilla::node(gen, operands[0]);
-    CodeGen::deselect_temporary(gen);
-    CodeGen::select_temporary(gen, obj);
-    Vanilla::node(gen, operands[1]);
-    CodeGen::deselect_temporary(gen);
-    CodeGen::select_temporary(gen, p);
-    Vanilla::node(gen, operands[2]);
-    CodeGen::deselect_temporary(gen);
-    CodeGen::select_temporary(gen, val);
-    Vanilla::node(gen, operands[3]);
-    CodeGen::deselect_temporary(gen);
-
-    I6_GEN_DATA(value_property_holders_needed) = TRUE;
-
-    WRITE("if (%S == OBJECT_TY) {\n", K);
-    WRITE("    if (%S-->0 == 2) {\n", p);
-    WRITE("        if (%S) give %S %S-->1; else give %S ~(%S-->1);\n", val, obj, p, obj, p);
-    WRITE("    } else {\n");
-    WRITE("        %S.(%S-->1) = %S;\n", obj, p, val);
-    WRITE("    }\n");
-    WRITE("} else {\n");
-    WRITE("    ((value_property_holders-->%S).(%S-->1))-->(%S+COL_HSIZE) = %S;\n", K, p, obj, val);
-    WRITE("}\n");
-
-    DISCARD_TEXT(K)
-    DISCARD_TEXT(obj)
-    DISCARD_TEXT(p)
-    DISCARD_TEXT(val)
-    return;
-
-

§6.

@@ -557,7 +414,7 @@ however not valid for either Z or G.
 

-    case XPROPERTYEXISTS_BIP:
+    case PROPERTYEXISTS_BIP:
         I6_GEN_DATA(value_ranges_needed) = TRUE;
         I6_GEN_DATA(value_property_holders_needed) = TRUE;
         WRITE("(_final_provides("); VNODE_1C; WRITE(", "); VNODE_2C; WRITE(", "); VNODE_3C; WRITE("))"); break;
@@ -748,7 +605,7 @@ however not valid for either Z or G.
 
 
     i6_next_is_a_give = FALSE;
-    WRITE("give "); VNODE_1C; WRITE(" %S", I6TargetCode::inner_name(gen, P)); break;
+    WRITE("give "); VNODE_2C; WRITE(" %S", I6TargetCode::inner_name(gen, P)); break;
 
  • This code is used in §6.3.

§6.3.2. Write attribute take6.3.2 = @@ -756,7 +613,7 @@ however not valid for either Z or G.

     i6_next_is_a_take = FALSE;
-    WRITE("give "); VNODE_1C; WRITE(" ~%S", I6TargetCode::inner_name(gen, P)); break;
+    WRITE("give "); VNODE_2C; WRITE(" ~%S", I6TargetCode::inner_name(gen, P)); break;
 
  • This code is used in §6.3.

§6.3.3. Write property value6.3.3 = @@ -764,7 +621,7 @@ however not valid for either Z or G.

     i6_next_is_a_ref = FALSE;
-    WRITE("_final_write_pval("); VNODE_1C; WRITE(","); VNODE_2C; WRITE(", ");
+    WRITE("_final_write_pval("); VNODE_1C; WRITE(","); VNODE_2C; WRITE(","); VNODE_3C; WRITE(", ");
 
  • This code is used in §6.3.

§6.3.4. Evaluate property value6.3.4 = @@ -772,16 +629,17 @@ however not valid for either Z or G.

     switch (I6TargetCode::pval_case(P)) {
-        case 1: WRITE("("); VNODE_1C; WRITE(" has %S", I6TargetCode::inner_name(gen, P)); WRITE(")"); break;
-        case 2: WRITE("("); VNODE_1C; WRITE(".%S", I6TargetCode::inner_name(gen, P)); WRITE(")"); break;
-        case 3: I6TargetCode::comparison_r(gen, InterTree::first_child(P), InterTree::second_child(P), 0); break;
+        case 1: WRITE("("); VNODE_2C; WRITE(" has %S", I6TargetCode::inner_name(gen, P)); WRITE(")"); break;
+        case 2: WRITE("("); VNODE_2C; WRITE(".%S", I6TargetCode::inner_name(gen, P)); WRITE(")"); break;
+        case 3: I6_GEN_DATA(value_property_holders_needed) = TRUE;
+                I6TargetCode::comparison_r(gen, InterTree::first_child(P), InterTree::second_child(P), InterTree::third_child(P), 0); break;
     }
 
  • This code is used in §6.3.

§6.5.1.

-void I6TargetCode::comparison_r(code_generation *gen,
+void I6TargetCode::comparison_r(code_generation *gen, inter_tree_node *K,
     inter_tree_node *X, inter_tree_node *Y, int depth) {
     text_stream *OUT = CodeGen::current(gen);
     if (Y->W.data[ID_IFLD] == INV_IST) {
@@ -790,9 +648,9 @@ however not valid for either Z or G.
             inter_ti ybip = Primitives::to_bip(gen->from, prim);
             if (ybip == ALTERNATIVE_BIP) {
                 if (depth == 0) { WRITE("((or_tmp_var = "); Vanilla::node(gen, X); WRITE(") && (("); }
-                I6TargetCode::comparison_r(gen, NULL, InterTree::first_child(Y), depth+1);
+                I6TargetCode::comparison_r(gen, K, NULL, InterTree::first_child(Y), depth+1);
                 WRITE(") || (");
-                I6TargetCode::comparison_r(gen, NULL, InterTree::second_child(Y), depth+1);
+                I6TargetCode::comparison_r(gen, K, NULL, InterTree::second_child(Y), depth+1);
                 if (depth == 0) { WRITE(")))"); }
                 return;
             }
@@ -803,6 +661,8 @@ however not valid for either Z or G.
         case 2: WRITE("("); if (X) Vanilla::node(gen, X); else WRITE("or_tmp_var"); WRITE(".%S", I6TargetCode::inner_name_inner(gen, Y)); WRITE(")"); break;
         case 3:
             WRITE("_final_read_pval(");
+            Vanilla::node(gen, K);
+            WRITE(", ");
             if (X) Vanilla::node(gen, X); else WRITE("or_tmp_var");
             WRITE(", ");
             Vanilla::node(gen, Y);
@@ -815,13 +675,13 @@ however not valid for either Z or G.
 
 int I6TargetCode::pval_case(inter_tree_node *P) {
     while (P->W.data[ID_IFLD] == REFERENCE_IST) P = InterTree::first_child(P);
-    inter_tree_node *prop_node = InterTree::second_child(P);
+    inter_tree_node *prop_node = InterTree::third_child(P);
     return I6TargetCode::pval_case_inner(prop_node);
 }
 
 text_stream *I6TargetCode::inner_name(code_generation *gen, inter_tree_node *P) {
     while (P->W.data[ID_IFLD] == REFERENCE_IST) P = InterTree::first_child(P);
-    inter_tree_node *prop_node = InterTree::second_child(P);
+    inter_tree_node *prop_node = InterTree::third_child(P);
     return I6TargetCode::inner_name_inner(gen, prop_node);
 }
 
@@ -1073,15 +933,28 @@ then the result.
 void I6TargetCode::end_generation(code_generator *cgt, code_generation *gen) {
     segmentation_pos saved = CodeGen::select(gen, functions_I7CGS);
     text_stream *OUT = CodeGen::current(gen);
-    WRITE("[ _final_read_pval o p t;\n");
-    WRITE("    t = p-->0; p = p-->1; ! print \"has \", o, \" \", p, \"^\";\n");
-    WRITE("    if (t == 2) { if (o has p) rtrue; rfalse; }\n");
-    WRITE("    if (o provides p) return o.p; rfalse;\n");
+    WRITE("[ _final_read_pval K o p t;\n");
+    WRITE("    if (K == OBJECT_TY) {\n");
+    WRITE("        t = p-->0; p = p-->1; ! print \"has \", o, \" \", p, \"^\";\n");
+    WRITE("        if (t == 2) { if (o has p) rtrue; rfalse; }\n");
+    WRITE("        if (o provides p) {\n");
+    WRITE("            if (p == door_to) return o.p();\n");
+    WRITE("            return o.p;\n");
+    WRITE("        }\n");
+    WRITE("        rfalse;\n");
+    WRITE("    } else {\n");
+    WRITE("        t = value_property_holders-->K;\n");
+    WRITE("        return (t.(p-->1))-->(o+COL_HSIZE);\n");
+    WRITE("    }\n");
     WRITE("];\n");
-    WRITE("[ _final_write_pval o p v t;\n");
-    WRITE("    t = p-->0; p = p-->1; ! print \"give \", o, \" \", p, \"^\";\n");
-    WRITE("    if (t == 2) { if (v) give o p; else give o ~p; }\n");
-    WRITE("    else { if (o provides p) o.p = v; }\n");
+    WRITE("[ _final_write_pval K o p v t;\n");
+    WRITE("    if (K == OBJECT_TY) {\n");
+    WRITE("        t = p-->0; p = p-->1; ! print \"give \", o, \" \", p, \"^\";\n");
+    WRITE("        if (t == 2) { if (v) give o p; else give o ~p; }\n");
+    WRITE("        else { if (o provides p) o.p = v; }\n");
+    WRITE("    } else {\n");
+    WRITE("        ((value_property_holders-->K).(p-->1))-->(o+COL_HSIZE) = v;\n");
+    WRITE("    }\n");
     WRITE("];\n");
     WRITE("[ _final_read_paddr o p v t;\n");
     WRITE("    t = p-->0; p = p-->1; ! print \"give \", o, \" \", p, \"^\";\n");
diff --git a/docs/final-module/5-cas.html b/docs/final-module/5-cas.html
index 54783caa1..592a86f8e 100644
--- a/docs/final-module/5-cas.html
+++ b/docs/final-module/5-cas.html
@@ -131,10 +131,6 @@ function togglePopup(material_id) {
     int store_this_operand[MAX_OPERANDS_IN_INTER_ASSEMBLY];
     for (int i=0; i<16; i++) store_this_operand[i] = FALSE;
 
-    if (Str::eq(opcode, I"@provides_gprop")) { store_this_operand[4] = TRUE; hacky_extras = TRUE;
-        C_GEN_DATA(objdata.value_ranges_needed) = TRUE;
-        C_GEN_DATA(objdata.value_property_holders_needed) = TRUE;
-    }
     if (Str::eq(opcode, I"@read_gprop")) { store_this_operand[4] = TRUE; hacky_extras = TRUE;
         C_GEN_DATA(objdata.value_property_holders_needed) = TRUE;
     }
@@ -245,7 +241,7 @@ function togglePopup(material_id) {
     i7word_t i7_mgl_OBJECT_TY, i7word_t i7_mgl_value_ranges, i7word_t i7_mgl_value_property_holders, i7word_t i7_mgl_A_door_to, i7word_t i7_mgl_COL_HSIZE);
 void glulx_read_gprop(i7process_t *proc, i7word_t K, i7word_t obj, i7word_t p, i7word_t *val,
     i7word_t i7_mgl_OBJECT_TY, i7word_t i7_mgl_value_ranges, i7word_t i7_mgl_value_property_holders, i7word_t i7_mgl_A_door_to, i7word_t i7_mgl_COL_HSIZE);
-void glulx_write_gprop(i7process_t *proc, i7word_t K, i7word_t obj, i7word_t p, i7word_t val,
+void glulx_write_gprop(i7process_t *proc, i7word_t K, i7word_t obj, i7word_t p, i7word_t val, i7word_t form,
     i7word_t i7_mgl_OBJECT_TY, i7word_t i7_mgl_value_ranges, i7word_t i7_mgl_value_property_holders, i7word_t i7_mgl_A_door_to, i7word_t i7_mgl_COL_HSIZE);
 
  • This is part of the extract file inform7_clib.h.
@@ -304,21 +300,29 @@ function togglePopup(material_id) { if (val) *val = (i7word_t) i7_read_word(proc, i7_read_prop_value(proc, holder, pr), (obj + i7_mgl_COL_HSIZE)); } } -void glulx_write_gprop(i7process_t *proc, i7word_t K, i7word_t obj, i7word_t pr, i7word_t val, + +i7word_t i7_read_gprop(i7process_t *proc, i7word_t K, i7word_t obj, i7word_t pr, + i7word_t i7_mgl_OBJECT_TY, i7word_t i7_mgl_value_ranges, i7word_t i7_mgl_value_property_holders, i7word_t i7_mgl_A_door_to, i7word_t i7_mgl_COL_HSIZE) { + i7word_t val = 0; + glulx_read_gprop(proc, K, obj, pr, &val, i7_mgl_OBJECT_TY, i7_mgl_value_ranges, i7_mgl_value_property_holders, i7_mgl_A_door_to, i7_mgl_COL_HSIZE); + return val; +} + +void glulx_write_gprop(i7process_t *proc, i7word_t K, i7word_t obj, i7word_t pr, i7word_t val, i7word_t form, i7word_t i7_mgl_OBJECT_TY, i7word_t i7_mgl_value_ranges, i7word_t i7_mgl_value_property_holders, i7word_t i7_mgl_A_door_to, i7word_t i7_mgl_COL_HSIZE) { if ((K == i7_mgl_OBJECT_TY)) { if ((i7_read_word(proc, pr, 0) == 2)) { if (val) { - i7_change_prop_value(proc, obj, pr, 1, i7_lvalue_SET); + i7_change_prop_value(proc, K, obj, pr, 1, form); } else { - i7_change_prop_value(proc, obj, pr, 0, i7_lvalue_SET); + i7_change_prop_value(proc, K, obj, pr, 0, form); } } else { - (i7_change_prop_value(proc, obj, pr, val, i7_lvalue_SET)); + (i7_change_prop_value(proc, K, obj, pr, val, form)); } } else { i7word_t holder = i7_read_word(proc, i7_mgl_value_property_holders, K); - (i7_write_word(proc, i7_read_prop_value(proc, holder, pr), (obj + i7_mgl_COL_HSIZE), val, i7_lvalue_SET)); + (i7_write_word(proc, i7_read_prop_value(proc, holder, pr), (obj + i7_mgl_COL_HSIZE), val, form)); } }
diff --git a/docs/final-module/5-ccn.html b/docs/final-module/5-ccn.html index ed989e91f..2b5f942a0 100644 --- a/docs/final-module/5-ccn.html +++ b/docs/final-module/5-ccn.html @@ -82,7 +82,7 @@ function togglePopup(material_id) { case NOT_BIP: WRITE("(!("); VNODE_1C; WRITE("))"); break; case AND_BIP: WRITE("(("); VNODE_1C; WRITE(") && ("); VNODE_2C; WRITE("))"); break; case OR_BIP: WRITE("(("); VNODE_1C; WRITE(") || ("); VNODE_2C; WRITE("))"); break; - case XPROPERTYEXISTS_BIP: + case PROPERTYEXISTS_BIP: C_GEN_DATA(objdata.value_ranges_needed) = TRUE; C_GEN_DATA(objdata.value_property_holders_needed) = TRUE; WRITE("(i7_provides_gprop(proc, "); VNODE_1C; WRITE(", "); VNODE_2C; WRITE(", "); VNODE_3C; WRITE(", i7_mgl_OBJECT_TY, i7_mgl_value_ranges, i7_mgl_value_property_holders, i7_mgl_A_door_to, i7_mgl_COL_HSIZE))"); break; @@ -105,14 +105,14 @@ function togglePopup(material_id) {

-    CConditions::comparison_r(gen, bip, InterTree::first_child(P), InterTree::second_child(P), 0);
+    CConditions::comparison_r(gen, bip, NULL, InterTree::first_child(P), InterTree::second_child(P), 0);
 
  • This code is used in §1 (9 times).

§2.

 void CConditions::comparison_r(code_generation *gen,
-    inter_ti bip, inter_tree_node *X, inter_tree_node *Y, int depth) {
+    inter_ti bip, inter_tree_node *K, inter_tree_node *X, inter_tree_node *Y, int depth) {
     if (Y->W.data[ID_IFLD] == INV_IST) {
         if (Y->W.data[METHOD_INV_IFLD] == INVOKED_PRIMITIVE) {
             inter_symbol *prim = Inter::Inv::invokee(Y);
@@ -120,10 +120,10 @@ function togglePopup(material_id) {
             if (ybip == ALTERNATIVE_BIP) {
                 text_stream *OUT = CodeGen::current(gen);
                 if (depth == 0) { WRITE("(proc->state.tmp = "); Vanilla::node(gen, X); WRITE(", ("); }
-                CConditions::comparison_r(gen, bip, NULL, InterTree::first_child(Y), depth+1);
+                CConditions::comparison_r(gen, bip, K, NULL, InterTree::first_child(Y), depth+1);
                 if ((bip == NE_BIP) || (bip == NOTIN_BIP)) WRITE(" && ");
                 else WRITE(" || ");
-                CConditions::comparison_r(gen, bip, NULL, InterTree::second_child(Y), depth+1);
+                CConditions::comparison_r(gen, bip, K, NULL, InterTree::second_child(Y), depth+1);
                 if (depth == 0) { WRITE("))"); }
                 return;
             }
@@ -134,9 +134,16 @@ function togglePopup(material_id) {
     text_stream *test_fn = CObjectModel::test_with_function(bip, &positive);
     if (Str::len(test_fn) > 0) {
         WRITE("(%S(proc, ", test_fn);
+        if (bip == PROPERTYVALUE_BIP) {
+            Vanilla::node(gen, K);
+            WRITE(", ");
+        }
         Compile first compared2.1;
         WRITE(", ");
         Compile second compared2.2;
+        if (bip == PROPERTYVALUE_BIP) {
+            WRITE(", i7_mgl_OBJECT_TY, i7_mgl_value_ranges, i7_mgl_value_property_holders, i7_mgl_A_door_to, i7_mgl_COL_HSIZE");
+        }
         WRITE(")");
         if (positive == FALSE) WRITE(" == 0");
         WRITE(")");
diff --git a/docs/final-module/5-com.html b/docs/final-module/5-com.html
index dc9dc22b2..9f2bb3116 100644
--- a/docs/final-module/5-com.html
+++ b/docs/final-module/5-com.html
@@ -858,10 +858,9 @@ which we will then need to write in         case PROPERTYADDRESS_BIP: WRITE("i7_prop_addr(proc, "); VNODE_1C; WRITE(", "); VNODE_2C; WRITE(")"); break;
         case PROPERTYLENGTH_BIP: WRITE("i7_prop_len(proc, "); VNODE_1C; WRITE(", "); VNODE_2C; WRITE(")"); break;
         case PROPERTYVALUE_BIP: if (CReferences::am_I_a_ref(gen)) {
-                                    WRITE("i7_change_prop_value(proc, "); VNODE_1C; WRITE(", "); VNODE_2C; WRITE(", ");
+                                    WRITE("glulx_write_gprop(proc, "); VNODE_1C; WRITE(", "); VNODE_2C; WRITE(", "); VNODE_3C; WRITE(", ");
                                 } else {
-                                    CConditions::comparison_r(gen, bip, InterTree::first_child(P), InterTree::second_child(P), 0);
-									WRITE("i7_read_prop_value(proc, "); VNODE_1C; WRITE(", "); VNODE_2C; WRITE(")");
+                                    CConditions::comparison_r(gen, bip, InterTree::first_child(P), InterTree::second_child(P), InterTree::third_child(P), 0);
                                 }
                                 break;
         case MESSAGE0_BIP:      WRITE("i7_mcall_0(proc, "); VNODE_1C; WRITE(", "); VNODE_2C; WRITE(")"); break;
@@ -887,7 +886,7 @@ and write them.
 i7word_t fn_i7_mgl_CreatePropertyOffsets(i7process_t *proc);
 void i7_write_prop_value(i7process_t *proc, i7word_t owner_id, i7word_t prop_id, i7word_t val);
 i7word_t i7_read_prop_value(i7process_t *proc, i7word_t owner_id, i7word_t pr_array);
-i7word_t i7_change_prop_value(i7process_t *proc, i7word_t obj, i7word_t pr, i7word_t to, int way);
+i7word_t i7_change_prop_value(i7process_t *proc, i7word_t K, i7word_t obj, i7word_t pr, i7word_t to, int way);
 void i7_give(i7process_t *proc, i7word_t owner, i7word_t prop, i7word_t val);
 i7word_t i7_prop_len(i7process_t *proc, i7word_t obj, i7word_t pr);
 i7word_t i7_prop_addr(i7process_t *proc, i7word_t obj, i7word_t pr);
@@ -933,7 +932,7 @@ and write them.
     return i7_read_word(proc, address, 0);
 }
 
-i7word_t i7_change_prop_value(i7process_t *proc, i7word_t obj, i7word_t pr, i7word_t to, int way) {
+i7word_t i7_change_prop_value(i7process_t *proc, i7word_t K, i7word_t obj, i7word_t pr, i7word_t to, int way) {
     i7word_t val = i7_read_prop_value(proc, obj, pr), new_val = val;
     switch (way) {
         case i7_lvalue_SET:      i7_write_prop_value(proc, obj, pr, to); new_val = to; break;
@@ -972,7 +971,7 @@ and write them.
 text_stream *CObjectModel::test_with_function(inter_ti bip, int *positive) {
     switch (bip) {
         case OFCLASS_BIP:   *positive = TRUE;  return I"i7_ofclass"; break;
-        case PROPERTYVALUE_BIP: *positive = TRUE;  return I"i7_read_prop_value"; break;
+        case PROPERTYVALUE_BIP: *positive = TRUE;  return I"i7_read_gprop"; break;
         case IN_BIP:        *positive = TRUE;  return I"i7_in"; break;
         case NOTIN_BIP:     *positive = FALSE; return I"i7_in"; break;
     }
diff --git a/docs/final-module/5-crf.html b/docs/final-module/5-crf.html
index 116ebb0c6..2294b4881 100644
--- a/docs/final-module/5-crf.html
+++ b/docs/final-module/5-crf.html
@@ -199,7 +199,10 @@ That's what is done by the "A1 as ref" mode set up above.
 
     WRITE("("); CReferences::A1_as_ref(gen, P);
     if (bip == STORE_BIP) { VNODE_2C; } else { WRITE("0"); }
-    WRITE(", %S))", store_form);
+    WRITE(", %S", store_form);
+    if (Inter::Reference::node_is_ref_to(gen->from, ref, PROPERTYVALUE_BIP))
+        WRITE(", i7_mgl_OBJECT_TY, i7_mgl_value_ranges, i7_mgl_value_property_holders, i7_mgl_A_door_to, i7_mgl_COL_HSIZE");
+    WRITE("))");
 
  • This code is used in §4.1.

§4.1.2. Handle the ref with C code working either as lvalue or rvalue4.1.2 = diff --git a/docs/imperative-module/4-cdp.html b/docs/imperative-module/4-cdp.html index 29d32bde2..732d71ed4 100644 --- a/docs/imperative-module/4-cdp.html +++ b/docs/imperative-module/4-cdp.html @@ -1586,6 +1586,7 @@ which until runtime — when its identity will be found in the Inter variabl EmitCode::val_symbol(K_value, total_s); EmitCode::inv(PROPERTYVALUE_BIP); EmitCode::down(); + EmitCode::val_iname(K_value, RTKindIDs::weak_iname(K_object)); EmitCode::val_symbol(K_value, var_s[0]); if (multipurpose_function) { EmitCode::val_iname(K_value, @@ -1795,6 +1796,7 @@ multiplying by \(-1\) is order-reversing.

     EmitCode::inv(PROPERTYVALUE_BIP);
     EmitCode::down();
+        EmitCode::val_iname(K_value, RTKindIDs::weak_iname(K_object));
         EmitCode::val_symbol(K_value, var_s[0]);
         if (multipurpose_function) {
             EmitCode::val_iname(K_value,
diff --git a/docs/inter/M-ip.html b/docs/inter/M-ip.html
index 83b218e95..7b7ef535e 100644
--- a/docs/inter/M-ip.html
+++ b/docs/inter/M-ip.html
@@ -328,7 +328,7 @@ subkind whose weak type ID is the second value?
 
  • (a) primitive !propertyvalue val val -> val.
  • (b) primitive !propertyaddress val val -> val.
  • (c) primitive !propertylength val val -> val. -
  • (d) primitive !propertyexists val val -> val. +
  • (d) primitive !propertyexists val val val -> val.