I6 Template Layer

Inform 7 6M62ContentsIntroductionFunction IndexRules Index

Combinations.i6t

Combinations contents

Block Format.

A combination is like a list, but simpler; it has a fixed, usually short, size. On the other hand, its entries are not all of the same kind as each other.

The short block for a combination is simply a pointer to the long block. This consists of one word to hold the strong kind ID, and then one word for each entry in the combination. Thus, a triple combination uses 4 words.

17Constant COMBINATION_KIND_F = 0; ! Strong kind ID 18Constant COMBINATION_ITEM_BASE = 1; ! List items begin at this entry

KOV Support.

See the BlockValues.i6t segment for the specification of the following routines.

25[ COMBINATION_TY_Support task arg1 arg2 arg3; 26    switch(task) { 27        CREATE_KOVS: return COMBINATION_TY_Create(arg1, arg2); 28        DESTROY_KOVS: COMBINATION_TY_Destroy(arg1); 29        MAKEMUTABLE_KOVS: return 1; 30        COPYKIND_KOVS: return COMBINATION_TY_CopyKind(arg1, arg2); 31        COPYQUICK_KOVS: rtrue; 32        COPYSB_KOVS: BlkValueCopySB1(arg1, arg2); 33        KINDDATA_KOVS: return COMBINATION_TY_KindData(arg1); 34        EXTENT_KOVS: return -1; 35        COPY_KOVS: COMBINATION_TY_Copy(arg1, arg2, arg3); 36        COMPARE_KOVS: return COMBINATION_TY_Compare(arg1, arg2); 37        HASH_KOVS: return COMBINATION_TY_Hash(arg1); 38        DEBUG_KOVS: print " = ", (COMBINATION_TY_Say) arg1; 39    } 40    ! We choose not to respond to: CAST_KOVS, READ_FILE_KOVS, WRITE_FILE_KOVS 41    rfalse; 42];

Creation.

A combination is like a list, but simpler; it has a fixed, usually short, size. On the other hand, its entries are not all of the same kind as each other.

Combinations are stored as a fixed-sized block of word entries. The first block is the only header information: a pointer to a further structure in memory, describing the kind. The subsequent blocks are the actual records. Thus, a triple (x, y, z) uses 4 words.

55[ COMBINATION_TY_Create kind sb long_block N i bk v; 56    N = KindBaseArity(kind); 57    long_block = FlexAllocate( 58        (COMBINATION_ITEM_BASE+N)*WORDSIZE, COMBINATION_TY, BLK_FLAG_WORD); 59    BlkValueWrite(long_block, COMBINATION_KIND_F, kind, true); 60    for (i=0: i<N: i++) { 61        bk = KindBaseTerm(kind, i); 62        if (KOVIsBlockValue(bk)) v = BlkValueCreate(bk); 63        else v = DefaultValueOfKOV(bk); 64        BlkValueWrite(long_block, COMBINATION_ITEM_BASE+i, v, true); 65    } 66    return BlkValueCreateSB1(sb, long_block); 67];

Destruction.

If the comb items are themselves block-values, they must all be freed before the comb itself can be freed.

74[ COMBINATION_TY_Destroy comb kind no_items i bk; 75    kind = BlkValueRead(comb, COMBINATION_KIND_F); 76    no_items = KindBaseArity(kind); 77    for (i=0: i<no_items: i++) { 78        bk = KindBaseTerm(kind, i); 79        if (KOVIsBlockValue(bk)) 80            BlkValueFree(BlkValueRead(comb, i+COMBINATION_ITEM_BASE)); 81    } 82];

Copying.

Again, if the comb contains block-values then they must be duplicated rather than bitwise copied as pointers.

89[ COMBINATION_TY_CopyKind to from; 90    BlkValueWrite(to, COMBINATION_KIND_F, BlkValueRead(from, COMBINATION_KIND_F)); 91]; 92 93[ COMBINATION_TY_CopySB to from; 94    BlkValueCopySB1(to, from); 95]; 96 97[ COMBINATION_TY_KindData comb; 98    return BlkValueRead(comb, COMBINATION_KIND_F); 99]; 100 101[ COMBINATION_TY_Copy to_comb from_comb precopied_comb_kov no_items i nv kind bk; 102    ! kind = BlkValueRead(to_comb, COMBINATION_KIND_F); 103    no_items = KindBaseArity(precopied_comb_kov); 104    BlkValueWrite(to_comb, COMBINATION_KIND_F, precopied_comb_kov); 105    for (i=0: i<no_items: i++) { 106        bk = KindBaseTerm(kind, i); 107        if (KOVIsBlockValue(bk)) { 108            nv = BlkValueCreate(bk); 109            BlkValueCopy(nv, BlkValueRead(from_comb, i+COMBINATION_ITEM_BASE)); 110            BlkValueWrite(to_comb, i+COMBINATION_ITEM_BASE, nv); 111        } 112    } 113];

Comparison.

This is a lexicographic comparison and assumes both combinations have the same kind.

120[ COMBINATION_TY_Compare left_comb right_comb delta no_items i cf kind bk; 121    kind = BlkValueRead(left_comb, COMBINATION_KIND_F); 122    no_items = KindBaseArity(kind); 123    for (i=0: i<no_items: i++) { 124        bk = KindBaseTerm(kind, i); 125        cf = KOVComparisonFunction(bk); 126        if (cf == 0 or UnsignedCompare) { 127            delta = BlkValueRead(left_comb, i+COMBINATION_ITEM_BASE) - 128                BlkValueRead(right_comb, i+COMBINATION_ITEM_BASE); 129            if (delta) return delta; 130        } else { 131            delta = cf(BlkValueRead(left_comb, i+COMBINATION_ITEM_BASE), 132                BlkValueRead(right_comb, i+COMBINATION_ITEM_BASE)); 133            if (delta) return delta; 134        } 135    } 136    return 0; 137]; 138 139[ COMBINATION_TY_Distinguish left_comb right_comb; 140    if (COMBINATION_TY_Compare(left_comb, right_comb) == 0) rfalse; 141    rtrue; 142];

Hashing.

147[ COMBINATION_TY_Hash comb kind rv no_items i bk; 148    rv = 0; 149    kind = BlkValueRead(comb, COMBINATION_KIND_F); 150    no_items = KindBaseArity(kind); 151    for (i=0: i<no_items: i++) { 152        bk = KindBaseTerm(kind, i); 153        rv = rv * 33 + GetHashValue(bk, BlkValueRead(comb, i+COMBINATION_ITEM_BASE)); 154    } 155    return rv; 156];

Printing.

161[ COMBINATION_TY_Say comb format no_items v i kind bk; 162    if ((comb==0) || (BlkValueWeakKind(comb) ~= COMBINATION_TY)) return; 163    kind = BlkValueRead(comb, COMBINATION_KIND_F); 164    no_items = KindBaseArity(kind); 165    print "("; 166    for (i=0: i<no_items: i++) { 167        if (i>0) print ", "; 168        bk = KindBaseTerm(kind, i); 169        v = BlkValueRead(comb, i+COMBINATION_ITEM_BASE); 170        if (bk == LIST_OF_TY) LIST_OF_TY_Say(v, 1); 171        else PrintKindValuePair(bk, v); 172    } 173    print ")"; 174];