Show
Ignore:
Timestamp:
06/11/07 04:07:02 (18 months ago)
Author:
krobillard
Message:

Thune - Simplified macros with macro! datatype.

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • branches/thune/thread_safe/tokenize.c

    r390 r408  
    204204 
    205205 
    206 /* 
    207 #if UR_CONFIG_MATH3D 
    208 static int isVec3( const char* cp, int len )  
     206#ifdef UR_CONFIG_MACROS 
     207extern void ur_infuseOpcodes( UThread*, UIndex ); 
     208 
     209//#define MACRO_CONTEXT   1 
     210#ifdef MACRO_CONTEXT 
     211extern UContext ur_global; 
     212 
     213static void _pushMacroContext( UThread* ut ) 
    209214{ 
    210     if( len < 3 ) 
    211         return 0; 
    212     if( *cp == '-' ) 
    213         ++cp; 
    214     if( *cp < '0' || *cp > '9' ) 
    215         return 0; 
    216     return 1; 
    217 } 
    218  
    219  
    220 static void assignVec3( float* vec, const char* start, int len ) 
    221 { 
    222     int ch; 
    223     const char* pos; 
    224     const char* end = start + len; 
    225  
    226     *vec++ = (float) ur_stringToDec( start, end, &pos ); 
    227     while( pos != end ) 
    228     { 
    229         ch = *pos; 
    230         if( ! ur_bitIsSet(charset_white, ch) ) 
    231             break; 
    232         ++pos; 
    233     } 
    234     *vec++ = (float) ur_stringToDec( pos, end, &pos ); 
    235     while( pos != end ) 
    236     { 
    237         ch = *pos; 
    238         if( ! ur_bitIsSet(charset_white, ch) ) 
    239             break; 
    240         ++pos; 
    241     } 
    242     *vec   = (float) ur_stringToDec( pos, end, &pos ); 
     215    UBlock* blk; 
     216    UCell* mc; 
     217    int wrdN; 
     218    
     219    wrdN = ur_internWord( &ur_global, UR_ATOM_READER_MACROS ); 
     220    blk = ur_blockPtr( ur_global.ctx.valBlk ); 
     221    mc = blk->ptr.cells + wrdN; 
     222    if( ! ur_is(mc, UT_CONTEXT) ) 
     223        ur_makeContext( mc, 0 ); 
     224    ur_pushContext( ut, mc ); 
    243225} 
    244226#endif 
    245 */ 
    246  
    247  
    248 #ifdef UR_CONFIG_MACROS 
    249 struct TokenizeCallInfo 
    250 { 
    251     int valueLimit; 
    252     const char* finalInputPos; 
    253 }; 
    254  
    255  
    256 static int _evalMacro( UThread* ut, UBlock* blk, UCell* mval, 
    257                        const char** pin, const char* end ) 
    258 { 
    259     UCell* cell; 
    260  
    261     if( ur_is(mval, UT_FUNCTION) ) 
    262     { 
    263         if( mval->func.localArgs ) 
    264         { 
    265             UIndex tblkN; 
    266             UBlock* callBlk; 
    267             UCell* otos; 
    268             int ok; 
    269             struct TokenizeCallInfo tci; 
    270  
    271             tci.valueLimit    = mval->func.localArgs; 
    272             tci.finalInputPos = 0; 
    273  
    274             tblkN = ur_tokenize( ut, *pin, end, &tci ); 
    275             *pin = tci.finalInputPos; 
    276  
    277             callBlk = ur_blockPtr( tblkN ); 
    278             UR_EXPAND_1( UCell, callBlk, cell ); 
    279             ur_copyCell(cell, *mval); 
    280             otos = UR_TOS; 
    281             ok = ur_eval( ut, tblkN, 0 ); 
    282             if( ok != UR_EVAL_OK ) 
    283                 return 0; 
    284             if( UR_TOS == otos ) 
    285                 return 1; 
    286             mval = ur_result( ut, 1 ); 
    287         } 
    288     } 
    289  
    290     if( ur_is(mval, UT_BLOCK) ) 
    291     { 
    292         // Join blocks (share code with uc_join?). 
    293         UBlock* s2 = ur_block(mval); 
    294         int srcLen = s2->used - mval->series.it; 
    295  
    296         ur_arrayReserve( blk, sizeof(UCell), blk->used + srcLen ); 
    297  
    298         ur_copyCells( s2->ptr.cells + mval->series.it, 
    299                       s2->ptr.cells + s2->used, 
    300                       blk->ptr.cells + blk->used ); 
    301         blk->used += srcLen; 
    302     } 
    303     else 
    304     { 
    305         UR_EXPAND_1( UCell, blk, cell ); 
    306         ur_copyCell( cell, *mval ); 
    307     } 
    308     return 1; 
    309 } 
    310  
    311  
    312 static UCell* _macro( UBlock* macroStack, const char* a, const char* b ) 
    313 { 
    314     int wrdN; 
    315     UCell* top = macroStack->ptr.cells + macroStack->used; 
    316     UAtom atom = ur_intern( a, b - a ); 
    317  
    318     while( top != macroStack->ptr.cells ) 
    319     { 
    320         wrdN = ur_lookup( --top, atom ); 
    321         if( wrdN > -1 ) 
    322         { 
    323             return ur_blockPtr( top->ctx.valBlk )->ptr.cells + wrdN; 
    324         } 
    325     } 
    326  
    327     return 0; 
    328 } 
    329227#endif 
    330228 
     
    341239    ur_throwErr( UR_ERR_SYNTAX, "%s (line %d)", msg, lines + 1 ); \ 
    342240    goto error 
     241 
     242 
     243/* 
     244   Returns zero if end reached. 
     245*/ 
     246static const char* blockComment( const char* it, const char* end, int* lines ) 
     247{ 
     248    int ch, tn, mode; 
     249    int lineCount = 0; 
     250 
     251    mode = 0; 
     252    tn = 0; 
     253 
     254    SCAN_LOOP 
     255        if( ch == '\n' ) 
     256        { 
     257            ++lineCount; 
     258            mode = 0; 
     259        } 
     260        else 
     261        { 
     262            switch( mode ) 
     263            { 
     264                case 0: 
     265                    if( ch == '*' ) 
     266                        mode = 1; 
     267                    else if( ch == '/' ) 
     268                        mode = 2; 
     269                    break; 
     270 
     271                case 1: 
     272                    if( ch == '/' ) 
     273                    { 
     274                        if( tn == 0 ) 
     275                        { 
     276                            *lines += lineCount; 
     277                            return ++it; 
     278                        } 
     279                        --tn; 
     280                    } 
     281                    mode = 0; 
     282                    break; 
     283 
     284                case 2: 
     285                    if( ch == '*' ) 
     286                        ++tn; 
     287                    mode = 0; 
     288                    break; 
     289            } 
     290        } 
     291    SCAN_END 
     292 
     293    *lines += lineCount; 
     294    return 0; 
     295} 
    343296 
    344297 
     
    359312    int lines = 0; 
    360313#ifdef UR_CONFIG_MACROS 
    361 #define TCI     ((struct TokenizeCallInfo*) tci) 
    362     UBlock* macroStack; 
    363     int valueLimit; 
    364  
    365     cell = ur_resolvePath( UR_ATOM_SCRIPT_ENV, 
    366                            UT_WORD, UR_ATOM_READER_MACROS, 
    367                            UT_NONE ); 
    368     macroStack = cell ? ur_block(cell) : 0; 
    369     valueLimit = tci ? TCI->valueLimit : 0; 
    370 #else 
     314    int macroNest = 0; 
     315#endif 
     316 
    371317    (void) tci; 
    372 #endif 
    373318 
    374319 
     
    448393                case '[': 
    449394                case '(': 
     395                case '<': 
    450396                    ur_arrayReserve( &stack, sizeof(UIndex), stack.used+1 ); 
    451397                    STACK[ stack.used ] = ur_makeBlock( 0 ); 
    452398 
    453                     cell = ur_appendCell( BLOCK,  
    454                                           (ch == '[') ? UT_BLOCK : UT_PAREN ); 
     399                    switch( ch ) 
     400                    { 
     401                        case '[': mode = UT_BLOCK; break; 
     402                        case '(': mode = UT_PAREN; break; 
     403                        case '<': mode = UT_MACRO; 
     404#ifdef UR_CONFIG_MACROS 
     405#ifdef MACRO_CONTEXT 
     406                            if( ! macroNest ) 
     407                                _pushMacroContext( ut ); 
     408#endif 
     409                            ++macroNest; 
     410#endif 
     411                            break; 
     412                    } 
     413 
     414                    cell = ur_appendCell( BLOCK, mode ); 
    455415                    ur_setSeries( cell, STACK[ stack.used ], 0 ); 
    456416 
     
    465425                case ']': 
    466426                case ')': 
     427                case '>': 
    467428                    if( stack.used == 1 ) 
    468429                    { 
    469                         syntaxError( "End of block found without '['" ); 
     430                        ur_throwErr( UR_ERR_SYNTAX, 
     431                            "End of block '%c' has no opening match (line %d)", 
     432                                     ch, lines + 1 ); 
     433                        goto error; 
    470434                    } 
    471435                    --stack.used; 
    472436                    if( eol ) 
     437                        eol = 0; 
     438#ifdef UR_CONFIG_MACROS 
     439                    if( ch == '>' && macroNest ) 
    473440                    { 
    474                         /* 
    475                         UBlock* blk = ur_blockPtr( STACK[ stack.used - 1 ] ); 
    476                         cell = blk->ptr.cells + blk->used - 1; 
    477                         cell->id.flags |= UR_FLAG_BLOCK_EOL; 
    478                         */ 
    479                         eol = 0; 
     441                        UCell* otos; 
     442                        UBlock* blk; 
     443 
     444                        otos = UR_TOS; 
     445                        ur_infuseOpcodes( ut, STACK[ stack.used ] ); 
     446                        tn = ur_eval( ut, STACK[ stack.used ], 0 ); 
     447                        if( tn == UR_EVAL_ERROR ) 
     448                        { 
     449                            UR_CALL_OP = OP_THROW; 
     450                            goto error; 
     451                        } 
     452 
     453                        blk = ur_blockPtr( STACK[stack.used - 1] ); 
     454                        --blk->used;    // Remove macro. 
     455 
     456                        if( UR_TOS != otos ) 
     457                        { 
     458                            // Append reduced macro to current block. 
     459                            tn = UR_TOS - otos; 
     460                            UR_TOS = otos; 
     461                            ++otos; 
     462 
     463                            ur_arrayReserve( blk, sizeof(UCell), 
     464                                             blk->used + tn ); 
     465                            ur_copyCells( otos, otos + tn, 
     466                                          blk->ptr.cells + blk->used ); 
     467                            blk->used += tn; 
     468                        } 
     469 
     470#ifdef MACRO_CONTEXT 
     471                        if( macroNest == 1 ) 
     472                            ur_popContext( ut ); 
     473#endif 
     474                        --macroNest; 
    480475                    } 
    481 #ifdef UR_CONFIG_MACROS 
    482                     ++it; 
    483                     goto check_final; 
    484 #else 
     476#endif 
    485477                    break; 
    486 #endif 
    487478                } 
    488479            } 
     
    498489        eol = 0; 
    499490    } 
    500 #ifdef UR_CONFIG_MACROS 
    501 check_final: 
    502     if( valueLimit && (stack.used == 1) ) 
    503     { 
    504         if( --valueLimit == 0 ) 
    505         { 
    506             TCI->finalInputPos = it; 
    507             goto finish; 
    508         } 
    509     } 
    510 #endif 
    511491    goto start; 
    512492 
     
    544524//block_comment 
    545525 
    546     mode = 0; 
    547     tn = 0; 
    548  
    549     SCAN_LOOP 
    550         if( ch == '\n' ) 
    551         { 
    552             ++lines; 
    553             mode = 0; 
    554         } 
    555         else 
    556         { 
    557             switch( mode ) 
    558             { 
    559                 case 0: 
    560                     if( ch == '*' ) 
    561                         mode = 1; 
    562                     else if( ch == '/' ) 
    563                         mode = 2; 
    564                     break; 
    565  
    566                 case 1: 
    567                     if( ch == '/' ) 
    568                     { 
    569                         if( tn == 0 ) 
    570                         { 
    571                             ++it; 
    572                             goto start; 
    573                         } 
    574                         --tn; 
    575                     } 
    576                     mode = 0; 
    577                     break; 
    578  
    579                 case 2: 
    580                     if( ch == '*' ) 
    581                         ++tn; 
    582                     mode = 0; 
    583                     break; 
    584             } 
    585         } 
    586     SCAN_END 
     526    it = blockComment( it, end, &lines ); 
     527    if( it ) 
     528        goto start; 
    587529    goto finish; 
    588530 
     
    707649            } 
    708650word_append: 
    709 #ifdef UR_CONFIG_MACROS 
    710             if( macroStack && mode == UT_WORD ) 
    711             { 
    712                 cell = _macro( macroStack, token, it ); 
    713                 if( cell ) 
    714                 { 
    715                     if( _evalMacro( ut, BLOCK, cell, &it, end ) ) 
    716                         goto start; 
    717                     syntaxError( "Macro evaluation failed" ); 
    718                 } 
    719             } 
    720 #endif 
    721651            if( it == token ) 
    722652                goto word_err; 
     
    909839        else if( *it == '[' ) 
    910840        { 
     841            // TODO: Handle macros in vector!. 
    911842            int inNum = 0; 
    912843            UArray* arr; 
     
    994925                    goto array_white; 
    995926                } 
     927                else if( ch == '/' ) 
     928                { 
     929                    ++it; 
     930                    if( it == end ) 
     931                        goto bad_array; 
     932                    if( *it != '*' ) 
     933                        goto bad_array; 
     934                    it = blockComment( ++it, end, &lines ); 
     935                    if( it ) 
     936                        goto array_white; 
     937                    goto finish; 
     938                } 
    996939                else 
    997940                { 
     
    999942                } 
    1000943            SCAN_END 
    1001  
     944bad_array: 
    1002945            syntaxError( "Invalid array" ); 
    1003946        }