Changeset 166

Show
Ignore:
Timestamp:
06/04/06 03:43:03 (3 years ago)
Author:
krobillard
Message:

Thune - Can now make (and extend) context from an existing context.

Location:
trunk/thune
Files:
2 added
3 modified

Legend:

Unmodified
Added
Removed
  • trunk/thune/make.c

    r164 r166  
    161161 
    162162 
     163/** 
     164   Make context with wordCount reserved (used set to zero). 
     165*/ 
    163166void ur_makeContext( UContext* ctx, int wordCount ) 
    164167{ 
     
    206209    ctx->ctx.valBlk      = ur_blockN( ptrB ); 
    207210    ctx->ctx.protoValBlk = ctx->ctx.valBlk; 
     211} 
     212 
     213 
     214extern void ur_copyCells( UCell* src, UCell* srcEnd, UCell* dest ); 
     215 
     216 
     217/* 
     218   Create context from initializer block. 
     219   protoCtx may be zero. 
     220   Caller must hold init and protoCtx (if non-zero) from GC. 
     221*/ 
     222static void _makeContextProto( UContext* res, const UCell* init, 
     223                               const UCell* protoCtx ) 
     224{ 
     225    if( init && ur_is(init, UT_BLOCK) ) 
     226    { 
     227        int size = 0; 
     228        UBlock* blk; 
     229        UCell* it; 
     230        UCell* start; 
     231        UCell* end; 
     232 
     233        blk = ur_blockPtr( init->series.n ); 
     234        UR_ITER_BLOCK( start, end, blk, init ) 
     235 
     236        it = start; 
     237 
     238        if( protoCtx ) 
     239        { 
     240            // Check if prototype must be extended with new words. 
     241 
     242            while( it != end ) 
     243            { 
     244                if( ur_is(it, UT_SETWORD) ) 
     245                { 
     246                    if( ur_lookup(protoCtx, ur_atom(it)) < 0 ) 
     247                        ++size; 
     248                } 
     249                ++it; 
     250            } 
     251 
     252            if( size ) 
     253            { 
     254                UIndex pwN; 
     255                UIndex pvN; 
     256                UCell* rend; 
     257                UBlock* rblk; 
     258 
     259                // Keep indices in case protoCtx == res 
     260                pwN = protoCtx->ctx.wordBlk; 
     261                pvN = protoCtx->ctx.valBlk; 
     262 
     263                blk  = ur_blockPtr( pvN ); 
     264                size += blk->used; 
     265 
     266                ur_makeContext( res, size ); 
     267 
     268                // Copy value block. 
     269 
     270                blk  = ur_blockPtr( pvN );      // re-acquire 
     271                rblk = ur_blockPtr( res->ctx.valBlk ); 
     272                rblk->used = size; 
     273                ur_copyCells( blk->ptr.cells, 
     274                              blk->ptr.cells + blk->used, 
     275                              rblk->ptr.cells ); 
     276 
     277                // Init new words to none. 
     278 
     279                it   = rblk->ptr.cells + blk->used; 
     280                rend = rblk->ptr.cells + size; 
     281                while( it != rend ) 
     282                { 
     283                    ur_setType( it, UT_NONE ); 
     284                    ++it; 
     285                } 
     286 
     287                // Copy word block. 
     288 
     289                blk  = ur_blockPtr( pwN ); 
     290                rblk = ur_blockPtr( res->ctx.wordBlk ); 
     291                rblk->used = blk->used; 
     292                ur_copyCells( blk->ptr.cells, 
     293                              blk->ptr.cells + blk->used, 
     294                              rblk->ptr.cells ); 
     295            } 
     296            else 
     297            { 
     298                // No new words in init block; clone to share word block. 
     299 
     300                if( res != protoCtx ) 
     301                { 
     302                    ur_copyCell( res, *protoCtx ); 
     303                } 
     304                ur_clone( res, size, 1 ); 
     305                return; 
     306            } 
     307        } 
     308        else 
     309        { 
     310            while( it != end ) 
     311            { 
     312                if( ur_is(it, UT_SETWORD) ) 
     313                    ++size; 
     314                ++it; 
     315            } 
     316 
     317            ur_makeContext( res, size ); 
     318        } 
     319 
     320        it = start; 
     321        while( it != end ) 
     322        { 
     323            if( ur_is(it, UT_SETWORD) ) 
     324                ur_internWord( res, it->word.atom ); 
     325            ++it; 
     326        } 
     327    } 
    208328} 
    209329 
     
    543663 
    544664 
    545 static void _makeContextProto( UContext* ctx, const UCell* proto ) 
    546 { 
    547     if( proto && ur_is(proto, UT_BLOCK) ) 
    548     { 
    549         int size = 0; 
    550         UBlock* blk; 
    551         UCell* it; 
    552         UCell* start; 
    553         UCell* end; 
    554  
    555         blk = ur_blockPtr( proto->series.n ); 
    556         UR_ITER_BLOCK( start, end, blk, proto ) 
    557  
    558         it = start; 
    559         while( it != end ) 
    560         { 
    561             if( ur_is(it, UT_SETWORD) ) 
    562                 ++size; 
    563             ++it; 
    564         } 
    565  
    566         ur_makeContext( ctx, size ); 
    567  
    568         it = start; 
    569         while( it != end ) 
    570         { 
    571             if( ur_is(it, UT_SETWORD) ) 
    572                 ur_internWord( ctx, it->word.atom ); 
    573             ++it; 
    574         } 
    575     } 
    576 } 
    577  
    578  
    579665typedef  void (*call_t)(void*,void*); 
    580666 
     
    660746  (opcode! code word -- value) 
    661747  (binary! int bytes -- value) 
     748  (context block -- value) 
    662749*/ 
    663750UR_CALL_PUB( uc_make ) 
     
    678765            return; 
    679766        } 
     767    } 
     768    else if( ur_is(res, UT_CONTEXT) ) 
     769    { 
     770        if( ! ur_is(tos, UT_BLOCK) ) 
     771            goto error; 
     772 
     773        UR_S_PUSH( *res );      // Hold original context. 
     774        _makeContextProto( res, tos, UR_TOS ); 
     775        ur_bind( tos->series.n, res ); 
     776        UR_S_DROP; 
     777 
     778        UR_CALL_OP = OP_DO; 
     779        return; 
    680780    } 
    681781    else 
     
    9121012            if( ur_is(tos, UT_BLOCK) ) 
    9131013            { 
    914                 _makeContextProto( res, tos ); 
     1014                _makeContextProto( res, tos, 0 ); 
    9151015                ur_bind( tos->series.n, res ); 
    9161016 
     
    9231023            { 
    9241024                ur_copyCell( res, *tos ); 
    925                 ur_clone( res, UR_COPY_ALL, 1 ); 
     1025                ur_clone( res, 0, 0 ); 
    9261026            } 
    9271027            break; 
  • trunk/thune/parse.c

    r162 r166  
    372372                } 
    373373 
    374                 /* Re-aquire pointer & check if input modified. */ 
     374                /* Re-acquire pointer & check if input modified. */ 
    375375                istr = pe->str = ur_binPtr( pe->input.n ); 
    376376                if( istr->used < pe->input.end ) 
     
    852852                } 
    853853 
    854                 /* Re-aquire pointer & check if input modified. */ 
     854                /* Re-acquire pointer & check if input modified. */ 
    855855                iblk = pe->blk = ur_blockPtr( pe->input.n ); 
    856856                if( iblk->used < pe->input.end ) 
  • trunk/thune/series.c

    r164 r166  
    446446 
    447447 
    448 static void copyV( UCell* src, UCell* srcEnd, UCell* dest ) 
     448void ur_copyCells( UCell* src, UCell* srcEnd, UCell* dest ) 
    449449{ 
    450450#if __WORDSIZE == 64 
     
    604604                } 
    605605 
    606                 copyV( s2->ptr.cells + tos->series.it, 
    607                        s2->ptr.cells + s2->used, 
    608                        ipos ); 
     606                ur_copyCells( s2->ptr.cells + tos->series.it, 
     607                              s2->ptr.cells + s2->used, 
     608                              ipos ); 
    609609 
    610610                s1->used += srcLen; 
     
    914914                ur_arrayReserve( s1, sizeof(UCell), used + srcLen ); 
    915915 
    916                 copyV( s2->ptr.cells + tos->series.it, 
    917                        s2->ptr.cells + s2->used, 
    918                        s1->ptr.cells + s1->used ); 
     916                ur_copyCells( s2->ptr.cells + tos->series.it, 
     917                              s2->ptr.cells + s2->used, 
     918                              s1->ptr.cells + s1->used ); 
    919919                s1->used += srcLen; 
    920920            }