Changeset 184 for trunk/thune/context.c

Show
Ignore:
Timestamp:
06/12/06 01:58:22 (3 years ago)
Author:
krobillard
Message:

Thune -

Word lookup now uses an ordered binary search.
Renamed ur_setType as ur_initType.
Some error reporting improvements in eval.

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • trunk/thune/context.c

    r164 r184  
    4848            rec->nameLen ); 
    4949    str->used += rec->nameLen; 
     50} 
     51 
     52 
     53const char* ur_atomCStr( UAtom atom ) 
     54{ 
     55    UBinary* names; 
     56    AtomRec* rec; 
     57 
     58    rec = ((AtomRec*) ur_env->atoms.ptr.v) + atom; 
     59    names = ur_binPtr( BIN_ATOM_NAMES ); 
     60    return names->ptr.c + rec->nameIndex; 
    5061} 
    5162 
     
    124135 
    125136    ur_arrayReserve( names, sizeof(char), names->used + len ); 
    126     memCpy( names->ptr.c + names->used, buf, len ); 
    127     names->used += len; 
     137    cp = names->ptr.c + names->used; 
     138    memCpy( cp, buf, len ); 
     139    cp[len] = '\0'; 
     140    names->used += len + 1; 
    128141 
    129142done: 
     
    131144    return rec - ((AtomRec*) atoms->ptr.v); 
    132145} 
     146 
     147 
     148static int _binarySearch( UCell* words, int count, UAtom atom ); 
    133149 
    134150 
     
    151167 
    152168    wblk = ur_blockPtr( ctx->ctx.wordBlk ); 
    153     it  = wblk->ptr.cells; 
    154     end = it + wblk->used; 
    155  
    156     while( it != end ) 
    157     { 
    158         if( it->word.atom == atom ) 
    159             return it - wblk->ptr.cells; 
    160         ++it; 
     169    it = wblk->ptr.cells; 
     170 
     171    if( (wblk->used < 6) || (it->word.sel == UR_CTX_UNORDERED) ) 
     172    { 
     173        end = it + wblk->used; 
     174        while( it != end ) 
     175        { 
     176            if( it->word.atom == atom ) 
     177                return it - wblk->ptr.cells; 
     178            ++it; 
     179        } 
     180    } 
     181    else 
     182    { 
     183        wrdN = _binarySearch( it, wblk->used, atom ); 
     184        if( wrdN > -1 ) 
     185            return wrdN; 
    161186    } 
    162187 
     
    167192    UR_EXPAND_1( UCell, wblk, it ); 
    168193 
    169     ur_setType( it, UT_WORD ); 
    170     it->word.wordBlk = 0;       //ctx->ctx.wordBlk; 
     194    ur_initType( it, UT_WORD ); 
     195    it->word.atom    = atom; 
     196    it->word.wordBlk = 0; 
    171197    it->word.valBlk  = ctx->ctx.valBlk; 
    172     it->word.index   = wrdN; 
    173     it->word.atom    = atom; 
    174  
     198    it->word.index   = 0; 
     199    it->word.sel     = 0; 
     200 
     201    wblk->ptr.cells->word.sel = UR_CTX_UNORDERED; 
    175202 
    176203    vblk = ur_blockPtr( ctx->ctx.valBlk ); 
     
    181208 
    182209        it = vblk->ptr.cells + wrdN; 
    183         ur_setType( it, UT_UNSET ); 
     210        ur_initType( it, UT_UNSET ); 
    184211    } 
    185212 
    186213    return wrdN; 
     214} 
     215 
     216 
     217#define QS_VAL(a)   cells[a].word.sel 
     218 
     219// Using series.end to swap word.index & word.sel together. 
     220#define QS_SWAP(a,b) \ 
     221    stmp = cells[a].series.end; \ 
     222    cells[a].series.end = cells[b].series.end; \ 
     223    cells[b].series.end = stmp 
     224 
     225static void _quickSort( UCell* cells, int low, int high ) 
     226{ 
     227    int i, j; 
     228    UAtom val; 
     229    UIndex stmp; 
     230 
     231    if( low >= high ) 
     232        return; 
     233 
     234    val = QS_VAL(low); 
     235    i = low; 
     236    j = high+1; 
     237    for(;;) 
     238    { 
     239        do i++; while( i <= high && QS_VAL(i) < val ); 
     240        do j--; while( QS_VAL(j) > val ); 
     241        if( i > j ) 
     242            break; 
     243        QS_SWAP( i, j ); 
     244    } 
     245    QS_SWAP( low, j ); 
     246    _quickSort( cells, low, j-1 ); 
     247    _quickSort( cells, j+1, high ); 
     248} 
     249 
     250 
     251static void _orderWords( UCell* words, int count ) 
     252{ 
     253    UCell* it; 
     254    UCell* end; 
     255    int index = 0; 
     256 
     257    it  = words; 
     258    end = words + count; 
     259 
     260    while( it != end ) 
     261    { 
     262        it->word.index = index++; 
     263        it->word.sel   = ur_atom(it); 
     264        ++it; 
     265    } 
     266 
     267    _quickSort( words, 0, count - 1 ); 
     268} 
     269 
     270 
     271/* 
     272   Returns index of atom in word block or -1 if not found. 
     273*/ 
     274static int _binarySearch( UCell* words, int count, UAtom atom ) 
     275{ 
     276    int sAtom; 
     277    int mid; 
     278    int low = 0; 
     279    int high = count - 1; 
     280 
     281    while( low <= high ) 
     282    { 
     283        mid = ((unsigned int) (low + high)) >> 1; 
     284        sAtom = words[ mid ].word.sel; 
     285 
     286        if( sAtom < atom ) 
     287            low = mid + 1; 
     288        else if( sAtom > atom ) 
     289            high = mid - 1; 
     290        else 
     291            return words[ mid ].word.index; 
     292    } 
     293 
     294    // Atom not found. 
     295    return -1; 
    187296} 
    188297 
     
    198307    UCell* end; 
    199308 
    200     /* There is unused space in wblk->ptr.cells which could be used to speed 
    201        up word search.  Some ideas: 
    202         - Min/max atom to fail early. 
    203         - Hash. 
    204         - Also store atoms in order and use binary search. 
    205      */ 
    206  
    207309    wblk = ur_blockPtr( ctx->ctx.wordBlk ); 
    208     it  = wblk->ptr.cells; 
    209     end = it + wblk->used; 
    210  
    211     while( it != end ) 
    212     { 
    213         if( it->word.atom == atom ) 
    214             return it - wblk->ptr.cells; 
    215         ++it; 
    216     } 
    217     return -1; 
     310    it = wblk->ptr.cells; 
     311 
     312    if( wblk->used < 6 ) 
     313    { 
     314        end = it + wblk->used; 
     315        while( it != end ) 
     316        { 
     317            if( it->word.atom == atom ) 
     318                return it - wblk->ptr.cells; 
     319            ++it; 
     320        } 
     321        return -1; 
     322    } 
     323    else 
     324    { 
     325        if( it->word.sel == UR_CTX_UNORDERED ) 
     326        { 
     327            _orderWords( it, wblk->used ); 
     328        } 
     329        return _binarySearch( it, wblk->used, atom ); 
     330    } 
    218331} 
    219332 
     
    270383 
    271384 
    272 #if 0 
    273 /* 
    274    Returns true if block contains does or func. 
    275 */ 
    276 int orClosureRequired( OIndex blkN ) 
    277 { 
    278     OBlock* blk = orBlockPtr( blkN ); 
    279     UCell* it  = blk->values; 
    280     UCell* end = it + blk->used; 
    281  
    282     while( it != end ) 
    283     { 
    284         if( (it->type == OT_WORD) || 
    285             (it->type == OT_SETWORD) || 
    286             (it->type == OT_GETWORD) ) 
    287         { 
    288             if( (it->word.atom == orEnv->atom_func) || 
    289                 (it->word.atom == orEnv->atom_does) ) 
    290                 return 1; 
    291         } 
    292         else if( (it->type == OT_BLOCK) || (it->type == OT_PAREN) ) 
    293         { 
    294             if( orClosureRequired( it->index ) ) 
    295                 return 1; 
    296         } 
    297  
    298         ++it; 
    299     } 
    300     return 0; 
    301 } 
    302  
    303  
    304 void orRebind( OIndex blkN, OIndex from, OIndex to ) 
    305 { 
    306     OBlock* blk = orBlockPtr( blkN ); 
    307     UCell* it  = blk->values; 
    308     UCell* end = it + blk->used; 
    309  
    310     while( it != end ) 
    311     { 
    312         if( (it->type == OT_WORD) || 
    313             (it->type == OT_SETWORD) || 
    314             (it->type == OT_GETWORD) ) 
    315         { 
    316             if( it->word.context == from ) 
    317                 it->word.context = to; 
    318         } 
    319 #if 0 
    320         else if( (it->type == OT_PATH) || (it->type == OT_SETPATH) ) 
    321         { 
    322             UCell* path1 = orBLOCK( it )->values; 
    323             if( (path1->type == OT_WORD) || 
    324                 (path1->type == OT_SETWORD) || 
    325                 (path1->type == OT_GETWORD) ) 
    326             { 
    327                 if( path1->word.context == from ) 
    328                     path1->word.context = to; 
    329             } 
    330         } 
    331 #endif 
    332         else if( (it->type == OT_BLOCK) || (it->type == OT_PAREN) ) 
    333         { 
    334             orRebind( it->index, from, to ); 
    335         } 
    336  
    337         ++it; 
    338     } 
    339 } 
    340 #endif 
    341  
    342  
    343 /* 
    344    (block context -- block) 
    345 */ 
    346 UR_CALL_PUB( uc_bind ) 
    347 { 
    348     UCell* bc; 
    349  
    350     UR_S_DROP; 
    351     bc = UR_TOS; 
    352  
    353     if( ur_is(tos, UT_LITWORD) || ur_is(tos, UT_CONTEXT) ) 
    354     { 
    355         if( ur_is(bc, UT_BLOCK) ) 
    356         { 
    357             ur_bind( bc->series.n, tos ); 
    358             return; 
    359         } 
    360     } 
    361  
    362     ur_throwErr( ur_thread, UR_EX_DATATYPE, "Invalid bind values" ); 
    363 } 
    364  
    365  
    366 #if 0 
    367 void orProtectNative( UCell* a1 ) 
    368 { 
    369     OBlock* vblk; 
    370     OContext ctx; 
    371     int wrdN; 
    372  
    373     orGlobalCtx( ctx ); 
    374     vblk = orBlockPtr( ctx.wblkN ); 
    375  
    376     if( a1->type == OT_WORD ) 
    377     { 
    378         wrdN = orLookup( &ctx, a1->word.atom ); 
    379         if( wrdN > -1 ) 
    380         { 
    381             vblk->values[ wrdN ].flags |= OR_WORD_PROT; 
    382         } 
    383     } 
    384     else if( a1->type == OT_BLOCK ) 
    385     { 
    386         OBlock* blk = orBLOCK( a1 ); 
    387         UCell* it  = blk->values; 
    388         UCell* end = it + blk->used; 
    389         while( it != end ) 
    390         { 
    391             if( it->type == OT_WORD ) 
    392             { 
    393                 wrdN = orLookup( &ctx, a1->word.atom ); 
    394                 if( wrdN > -1 ) 
    395                 { 
    396                     vblk->values[ wrdN ].flags |= OR_WORD_PROT; 
    397                 } 
    398             } 
    399             ++it; 
    400         } 
    401     } 
    402     orResultUNSET; 
    403 } 
    404  
    405  
    406 /* 
    407    object [object!] 
    408    word   [word!] 
    409 */ 
    410 void orInNative( UCell* a1 ) 
    411 { 
    412     UCell* a2 = a1 + 1; 
    413     OIndex wrdN; 
    414  
    415     wrdN = orLookup( &a1->ctx, a2->word.atom ); 
    416     if( wrdN < 0 ) 
    417     { 
    418         orResultNONE; 
    419     } 
    420     else 
    421     { 
    422         orSetTF( a1, OT_WORD ); 
    423         // a1->context remains unchanged. 
    424         a1->word.index = wrdN; 
    425         a1->word.atom  = a2->word.atom; 
    426     } 
    427 } 
    428  
    429  
    430 /* 
    431    words [block! word!] 
    432    body  [block!] 
    433 */ 
    434 void orUseNative( UCell* a1 ) 
    435 { 
    436     OContext ctx; 
    437     OBlock* blk; 
    438     UCell* it; 
    439     UCell* end; 
    440     UCell* a2 = a1 + 1; 
    441  
    442  
    443     orRefPush( OT_BLOCK, a2->index ); 
    444  
    445     if( a1->type == OT_WORD ) 
    446     { 
    447         orMakeContext( &ctx, 1 ); 
    448         orInternA( orBlockPtr( ctx.wblkN ), a1->word.atom ); 
    449     } 
    450     else 
    451     { 
    452         orRefPush( OT_BLOCK, a1->index ); 
    453  
    454         blk = orBLOCK( a1 ); 
    455         it  = blk->values + a1->series.index; 
    456         end = blk->values + blk->used; 
    457  
    458         orMakeContext( &ctx, end - it ); 
    459         blk = orBlockPtr( ctx.wblkN ); 
    460  
    461         while( it != end ) 
    462         { 
    463             if( it->type == OT_WORD ) 
    464                 orInternA( blk, it->word.atom ); 
    465             ++it; 
    466         } 
    467  
    468         orRefPop( 1 ); 
    469     } 
    470  
    471     blk = orBlockPtr( ctx.vblkN ); 
    472     it  = blk->values; 
    473     end = it + blk->used; 
    474     while( it != end ) 
    475     { 
    476         orSetTF( it, OT_UNSET ); 
    477         ++it; 
    478     } 
    479  
    480     orBind( orBlockPtr( a2->index ), &ctx ); 
    481  
    482     orRefPop( 1 ); 
    483  
    484     orEvalBlock( orBlockPtr( a2->index ), a2->series.index ); 
    485 } 
    486 #endif 
    487  
    488  
    489385/*EOF*/