Changeset 300 for trunk/thune/rune

Show
Ignore:
Timestamp:
10/18/06 23:51:02 (2 years ago)
Author:
krobillard
Message:

Rune - Implemented 'each.

Location:
trunk/thune/rune
Files:
2 added
3 modified

Legend:

Unmodified
Added
Removed
  • trunk/thune/rune/project.r

    r282 r300  
    55default [ 
    66    warn 
    7     ;debug 
    8     release 
     7    debug 
     8    ;release 
    99 
    1010    cflags {-DLANG_RUNE} 
  • trunk/thune/rune/rune.c

    r284 r300  
    4141 
    4242 
    43 #define OR_TOC      ur_thread->toc 
    44 #define OR_BOC      ur_thread->cstack 
     43#define OR_TOC          ur_thread->toc 
     44#define OR_BOC          ur_thread->cstack 
    4545 
    4646#define ur_funcFetch(cell)  cell->func.closureN 
     
    4949#define ur_varc(cell)       cell->func.localVars 
    5050#define ur_evalLocal(cell)  cell->series.encoding 
     51#define opForeverBlkN(cell) cell->word.valBlk 
    5152 
    5253#if 0 
     
    115116    ROP_IF_ELSE, 
    116117    ROP_FOREVER, 
     118    ROP_EACH, 
     119    ROP_EACH_LOOP, 
    117120    ROP_BREAK, 
    118121    ROP_RETURN, 
     
    139142 
    140143 
     144#ifdef DEBUG 
     145void dumpControl() 
     146{ 
     147    UString str; 
     148    UString* sp = &str; 
     149    UCell* it  = ur_env->threads->cstack; 
     150    UCell* end = ur_env->threads->toc + 1; 
     151 
     152    ur_arrayInit( sp, 1, 0 ); 
     153 
     154    while( it != end ) 
     155    { 
     156        str.used = 0; 
     157        ur_toStr( it++, sp, 0 ); 
     158        ur_termCStr( sp ); 
     159 
     160        dprint( str.ptr.c ); 
     161        dprint( "\n" ); 
     162    } 
     163 
     164    ur_arrayFree( sp ); 
     165} 
     166#endif 
     167 
     168 
    141169static void _appendTraceBlk( UCellError* err, int n, int it ) 
    142170{ 
     
    181209    } 
    182210    return 1; 
     211} 
     212 
     213 
     214/* 
     215   Returns length of series from current iterator position. 
     216   If cell is not a series or beyond the tail then a negative number is 
     217   returned. 
     218*/ 
     219static int ur_itLen( UCell* cell ) 
     220{ 
     221    int len = ur_seriesLen( cell ); 
     222    if( len > -1 ) 
     223        len -= cell->series.it; 
     224    return len; 
    183225} 
    184226 
     
    329371 
    330372                case ROP_FOREVER: 
     373                    PUSHC_EVAL( blkN, 0 ); 
    331374                    PUSHC_CELL( val ); 
    332                     OR_TOC->word.valBlk = 0; 
     375                    opForeverBlkN(OR_TOC) = 0; 
    333376                    goto fetch_pc; 
     377 
     378                case ROP_EACH: 
     379                    PUSHC_EVAL( blkN, 0 ); 
     380                    PUSHC_CELL( val ); 
     381                    ur_opFetch( OR_TOC ) = 0; 
     382                    if( pc >= end ) 
     383                        goto unexpected_end; 
     384                    if( ur_is(pc, UT_WORD) ) 
     385                    { 
     386                        UR_S_PUSH( *pc ); 
     387                        ++pc; 
     388                        goto fetch_pc; 
     389                    } 
     390                    cval = val; 
     391                    val = pc; 
     392                    goto bad_opcode_type; 
    334393 
    335394                case ROP_BREAK: 
     
    465524 
    466525                case ROP_FOREVER: 
    467                     if( OR_TOC->word.valBlk == 0 ) 
     526                    if( opForeverBlkN(cval) == 0 ) 
    468527                    { 
     528                        // Evaluate loop for the first time. 
    469529                        if( ur_is(val, UT_BLOCK) || ur_is(val, UT_PAREN) ) 
    470530                        { 
    471                             OR_TOC->word.valBlk = val->series.n; 
     531                            opForeverBlkN(cval) = val->series.n; 
     532                            // Set resume block pc for any 'break. 
     533                            cval[-1].series.it = pc - start; 
    472534                            goto do_block; 
    473535                        } 
     536                        goto bad_opcode_type; 
    474537                    } 
    475538                    val = ur_s_next(UR_TOS); 
    476539                    ur_initType( val, UT_BLOCK ); 
    477                     ur_setSeries( val, OR_TOC->word.valBlk, 0 ); 
     540                    ur_setSeries( val, opForeverBlkN(cval), 0 ); 
    478541                    goto do_block; 
     542 
     543                case ROP_EACH: 
     544                    PUSH_VAL 
     545                    if( ur_opFetch( cval ) == 0 ) 
     546                    { 
     547                        ur_opFetch( cval ) += 1; 
     548                        if( ! ur_isASeries(val) ) 
     549                            goto bad_opcode_type; 
     550                        goto fetch_pc; 
     551                    } 
     552                    else 
     553                    { 
     554                        if( ! ur_is(val, UT_BLOCK) ) 
     555                            goto bad_opcode_type; 
     556                        ur_opcode(cval) = ROP_EACH_LOOP; 
     557                        // Set resume block pc. 
     558                        cval[-1].series.it = pc - start; 
     559                    } 
     560                    // Drop through to ROP_EACH_LOOP. 
     561 
     562                case ROP_EACH_LOOP: 
     563                    val = ur_s_prev(UR_TOS); 
     564                    if( ur_itLen( val ) > 0 ) 
     565                    { 
     566                        cval = ur_wordCell( ur_thread, ur_s_prev(val) ); 
     567                        if( ! cval ) 
     568                            goto op_throw; 
     569                        ur_pick( val, 0, cval ); 
     570                        val->series.it++; 
     571                        val = UR_TOS; 
     572                        goto do_block; 
     573                    } 
     574                    UR_C_DEC; 
     575                    UR_S_DROPN(3); 
     576                    val = UR_TOS; 
     577                    goto control; 
    479578 
    480579                case ROP_RETURN: 
     
    677776                        if( ur_evalLocal(cval) ) 
    678777                            UR_LF_POP; 
    679                         break; 
    680778                    } 
    681                     OR_TOC = cval; 
    682                     goto func_return; 
     779                    else 
     780                    { 
     781                        OR_TOC = cval; 
     782                        goto func_return; 
     783                    } 
    683784                } 
     785                break; 
    684786        } 
    685787        --cval;     // UR_C_DEC 
     
    687789 
    688790op_break: 
     791 
     792    cval = OR_TOC; 
     793    while( 1 ) 
     794    { 
     795        switch( ur_type(cval) ) 
     796        { 
     797            case UT_UNSET: 
     798bad_break: 
     799                ur_throwErr( UR_ERR_SCRIPT, "break used outside of loop" ); 
     800                goto trace_error; 
     801 
     802            case UT_OPCODE: 
     803                switch( ur_opcode(cval) ) 
     804                { 
     805                    case ROP_EACH_LOOP: 
     806                        UR_S_DROPN(3); 
     807                        // Drop through. 
     808 
     809                    case ROP_FOREVER: 
     810                        OR_TOC = cval - 1; 
     811                        val = UR_TOS; 
     812                        ur_initType( val, UT_UNSET ); 
     813                        goto control; 
     814                } 
     815                break; 
     816 
     817            case UT_BLOCK: 
     818                if( cval->id.flags & FLAG_FUNC_BLOCK ) 
     819                    goto bad_break; 
     820                break; 
     821        } 
     822        --cval;     // UR_C_DEC 
     823    } 
     824 
    689825op_throw: 
    690826 
     
    700836 
    701837            case UT_OPCODE: 
    702                 if( ur_opcode(cval) == ROP_FOREVER ) 
    703                 { 
    704                     ur_copyCell( cval, cval[1] ); 
    705                     goto control; 
    706                 } 
    707838                break; 
    708839 
     
    9751106  "  5 'if.else\n" 
    9761107  "  6 'forever\n" 
    977   "  7 'break\n" 
    978   "  8 'return\n" 
    979   "  9 +\n" 
    980   "  10 -\n" 
    981   "  11 *\n" 
    982   "  12 /\n" 
    983   "  13 >\n" 
    984   "  14 <\n" 
     1108  "  7 'each\n" 
     1109  "  8 'each-loop\n" 
     1110  "  9 'break\n" 
     1111  "  10 'return\n" 
     1112  "  11 +\n" 
     1113  "  12 -\n" 
     1114  "  13 *\n" 
     1115  "  14 /\n" 
     1116  "  15 >\n" 
     1117  "  16 <\n" 
    9851118  "] make-opcodes :rune-ops\n" 
    9861119  "[\n" 
     
    10051138  "  probe  [val]\n" 
    10061139  "  type?  [val]\n" 
     1140  "  eq?    [a b]\n" 
     1141  "  same?  [a b]\n" 
    10071142  "  zero?  [val]\n" 
    10081143  "  to-text [val]\n" 
  • trunk/thune/rune/tests/mandel.ru

    r282 r300  
    2828 
    2929;prin zi2 prin ' ' print zr2 
    30         if zi2 + zr2 > BAILOUT [return nop false] 
     30        if zi2 + zr2 > BAILOUT [return false] 
    3131    ] 
    3232    true