Dynamic Tables

version 5/140515 by Jesse McGrew

  • Home page
  • Beginning
  • Previous



  • Chapter 2 - Library replacements
    Section 1 - Using the dynamic blank bits
    [We need to change the parts of Tables.i6t that directly use TB_Blanks to call DT_FindBlankBits instead.]
    Include (-
    [ CheckTableEntryIsBlank tab col row i at oldv flags;
        if (col >= 100) col = TableFindCol(tab, col);
        if (col == 0) rtrue;
        if ((tab-->col)-->(row+COL_HSIZE) ~= TABLE_NOVALUE) {
            print "*** CTEIB on nonblank value ", tab, " ", col, " ", row, " ***^";
        }
        if (((tab-->col)-->1) & TB_COLUMN_NOBLANKBITS) rtrue;
        row--;
        at = DT_FindBlankBits(tab, col) + (row/8);
        if ((at->0) & (CheckTableEntryIsBlank_LU->(row%8))) rtrue;
        rfalse;
    ];
    -) instead of "Testing Blankness" in "Tables.i6t".
    Include (-
    [ ForceTableEntryBlank tab col row i at oldv flags;
        if (col >= 100) col = TableFindCol(tab, col);
        if (col == 0) rtrue;
        flags = (tab-->col)-->1;
        oldv = (tab-->col)-->(row+COL_HSIZE);
        if ((flags & TB_COLUMN_ALLOCATED) && (oldv ~= 0 or TABLE_NOVALUE))
            FlexFree(oldv);
        (tab-->col)-->(row+COL_HSIZE) = TABLE_NOVALUE;
        if (flags & TB_COLUMN_NOBLANKBITS) return;
        row--;
        at = DT_FindBlankBits(tab, col) + (row/8);
        (at->0) = (at->0) | (CheckTableEntryIsBlank_LU->(row%8));
    ];
    -) instead of "Force Entry Blank" in "Tables.i6t".
    Include (-
    [ ForceTableEntryNonBlank tab col row i at oldv flags tc kov j;
        if (col >= 100) col=TableFindCol(tab, col);
        if (col == 0) rtrue;
        if (((tab-->col)-->1) & TB_COLUMN_NOBLANKBITS) return;
        flags = (tab-->col)-->1;
        oldv = (tab-->col)-->(row+COL_HSIZE);
        if ((flags & TB_COLUMN_ALLOCATED) &&
            (oldv == 0 or TABLE_NOVALUE)) {
            kov = UNKNOWN_TY;
            tc = ((tab-->col)-->1) & TB_COLUMN_NUMBER;
            kov = TC_KOV(tc);
            if (kov ~= UNKNOWN_TY) {
                if (KindBaseArity(kov) > 0) i = KindAtomic(kov); else i = 0;
                (tab-->col)-->(row+COL_HSIZE) = BlkValueCreate(kov, 0, i);
            }
        }
        row--;
        at = DT_FindBlankBits(tab, col) + (row/8);
        (at->0) = (at->0) & (CheckTableEntryIsNonBlank_LU->(row%8));
    ];
    -) instead of "Force Entry Non-Blank" in "Tables.i6t".
    Include (-
    [ TableSwapBlankBits tab row1 row2 col at1 at2 bit1 bit2;
        if (col >= 100) col=TableFindCol(tab, col);
        if (col == 0) rtrue;
        if (((tab-->col)-->1) & TB_COLUMN_NOBLANKBITS) return;
        row1--;
        at1 = DT_FindBlankBits(tab, col) + (row1/8);
        row2--;
        at2 = DT_FindBlankBits(tab, col) + (row2/8);
        bit1 = ((at1->0) & (CheckTableEntryIsBlank_LU->(row1%8)));
        bit2 = ((at2->0) & (CheckTableEntryIsBlank_LU->(row2%8)));
        if (bit1) bit1 = true;
        if (bit2) bit2 = true;
        if (bit1 == bit2) return;
        if (bit1) {
            (at1->0)
                = (at1->0) & (CheckTableEntryIsNonBlank_LU->(row1%8));
            (at2->0)
                = (at2->0) | (CheckTableEntryIsBlank_LU->(row2%8));
        } else {
            (at1->0)
                = (at1->0) | (CheckTableEntryIsBlank_LU->(row1%8));
            (at2->0)
                = (at2->0) & (CheckTableEntryIsNonBlank_LU->(row2%8));
        }
    ];
    -) instead of "Swapping Blank Bits" in "Tables.i6t".
    Include (-
    [ TableMoveBlankBitsDown tab row1 row2 col at atp1 bit rx bba;
        if (col >= 100) col=TableFindCol(tab, col);
        if (col == 0) rtrue;
        if (((tab-->col)-->1) & TB_COLUMN_NOBLANKBITS) return;
        row1--; row2--;
        ! Read blank bit for row1:
        bba = DT_FindBlankBits(tab, col);
        at = bba + (row1/8);
        bit = ((at->0) & (CheckTableEntryIsBlank_LU->(row1%8)));
        if (bit) bit = true;
        ! Loop through, setting each blank bit to the next:
        for (rx=row1:rx<row2:rx++) {
            atp1 = bba + ((rx+1)/8);
            at = bba + (rx/8);
            if ((atp1->0) & (CheckTableEntryIsBlank_LU->((rx+1)%8))) {
                (at->0)
                    = (at->0) | (CheckTableEntryIsBlank_LU->(rx%8));
            } else {
                (at->0)
                    = (at->0) & (CheckTableEntryIsNonBlank_LU->(rx%8));
            }
        }
        ! Write bit to blank bit for row2:
        at = bba + (row2/8);
        if (bit) {
            (at->0)
                = (at->0) | (CheckTableEntryIsBlank_LU->(row2%8));
        } else {
            (at->0)
                = (at->0) & (CheckTableEntryIsNonBlank_LU->(row2%8));
        }
    ];
    -) instead of "Moving Blank Bits Down" in "Tables.i6t".
    [And here we replace PrintTableName to show something sensible for fully dynamic tables.]
    Include (-
    [ PrintTableName T;
        switch(T) {
    {-call:Data::Tables::compile_print_table_names}
            default:
                if (DT_IsFullyDynamic(T))
                    print "** Dynamically created table **";
                else
                    print "** No such table **";
        }
    ];
    -) instead of "Print Table Name" in "Tables.i6t".
    Dynamic Tables ends here.