Changeset 278 for trunk/thune/rune

Show
Ignore:
Timestamp:
09/20/06 03:07:59 (2 years ago)
Author:
krobillard
Message:

Reworked Rune eval.

Location:
trunk/thune/rune
Files:
3 modified

Legend:

Unmodified
Added
Removed
  • trunk/thune/rune/rune.c

    r276 r278  
    3434#define OR_BOC      ur_thread->cstack 
    3535 
    36 #define ur_callFetch(cell)  cell->call.sigN 
    3736#define ur_funcFetch(cell)  cell->func.closureN 
    3837#define ur_argc(cell)       cell->func.localArgs 
    3938#define ur_varc(cell)       cell->func.localVars 
    4039#define ur_evalLocal(cell)  cell->series.encoding 
    41 #define ur_evalFetch(cell)  cell->coord.elem[5] 
    4240 
    4341#define CC_SETWORD      CC_END+1 
     
    5553    start = blk->ptr.cells; \ 
    5654    pc    = start + it; \ 
    57     end   = start + blk->used; \ 
    58     fetch = 0 
     55    end   = start + blk->used; 
    5956 
    6057 
     
    7168    ur_initType(OR_TOC, UT_BLOCK); \ 
    7269    ur_evalLocal(OR_TOC) = locals; \ 
    73     ur_setSeries(OR_TOC, blkn, 0); \ 
    74     ur_evalFetch(OR_TOC) = fetch 
     70    ur_setSeries(OR_TOC, blkn, 0); 
    7571 
    7672#define PUSHC_EVAL(blkn,pos) \ 
    7773    UR_C_GROW; \ 
    7874    ur_initType(OR_TOC, UT_PAREN); \ 
    79     ur_setSeries(OR_TOC, blkn, pos); \ 
    80     ur_evalFetch(OR_TOC) = fetch; \ 
    81     fetch = 0 
     75    ur_setSeries(OR_TOC, blkn, pos); 
     76 
     77#define PUSHC_REDUCE(blkn) \ 
     78    UR_C_GROW; \ 
     79    ur_initType(OR_TOC, UT_WORD); \ 
     80    OR_TOC->word.wordBlk = 0; \ 
     81    OR_TOC->word.valBlk  = blkn; \ 
     82    OR_TOC->word.sel     = UR_TOS - UR_BOS 
     83 
     84    //ur_opcode(OR_TOC) = ROP_REDUCE 
    8285 
    8386#define PUSHC_CELL(val) \ 
     
    8588    *OR_TOC = *val 
    8689 
    87 #define PUSHC_SETWORD(val) \ 
    88     PUSHC_CELL( val ) 
    89  
    90 #define PUSHC_CALL(val) \ 
    91     PUSHC_CELL( val ); \ 
    92     ur_callFetch(OR_TOC) = ur_argc(val) 
    93  
    94 #define PUSHC_INFIX(n) \ 
    95     UR_C_GROW; \ 
    96     *OR_TOC = *((UCell*) (_infixOperator + n)) 
    97  
    98 #define PUSHC_FUNC(val) \ 
    99     PUSHC_CELL( val ); \ 
    100     ur_funcFetch(OR_TOC) = ur_argc(val) 
    101  
    10290 
    10391enum eRuneOpcode 
    10492{ 
    10593    ROP_NOP = 0, 
     94    ROP_REDUCE, 
    10695    ROP_ADD, 
    10796    ROP_SUB, 
     
    11099}; 
    111100 
     101 
     102#define INFIX_CALL(op)  ((UCell*) (_infixOperator + ((op) - ROP_ADD))) 
     103 
    112104UCellCall _infixOperator[] = 
    113105{ 
    114     {UT_CALL, 0, 2, 0, 1, uc_add}, 
    115     {UT_CALL, 0, 2, 0, 1, uc_sub}, 
    116     {UT_CALL, 0, 2, 0, 1, uc_mul}, 
    117     {UT_CALL, 0, 2, 0, 1, uc_div} 
     106    {UT_CALL, 0, 2,0, 1,0, 0, uc_add}, 
     107    {UT_CALL, 0, 2,0, 1,0, 0, uc_sub}, 
     108    {UT_CALL, 0, 2,0, 1,0, 0, uc_mul}, 
     109    {UT_CALL, 0, 2,0, 1,0, 0, uc_div} 
    118110}; 
    119111 
     
    164156 
    165157 
     158#define PUSH_VAL    if(val != UR_TOS) { UR_S_PUSH( *val ); } 
     159 
     160// Look ahead for infix operator. 
     161#define LOOK_AHEAD_FOR_INFIX \ 
     162    if((pc < end) && ur_is(pc, UT_OPCODE) && (ur_opcode(pc) >= ROP_ADD)) \ 
     163        goto push_infix; 
     164 
     165 
    166166int rune_eval( UThread* ur_thread, UIndex blkN, UIndex si ) 
    167167{ 
     
    171171    UCell* end; 
    172172    UCell* val; 
    173     int fetch;      // Controls if pc values are pushed onto the stack. 
     173    UCell* cval; 
    174174 
    175175 
     
    179179    pc    = start + si; 
    180180    end   = start + blk->used; 
    181     fetch = 0; 
     181 
     182    ur_initType(UR_TOS, UT_UNSET); 
     183    val = UR_TOS; 
    182184 
    183185    PUSHC_END; 
     
    190192        // End of block reached. 
    191193 
    192         //if( fetch ) 
    193         //    goto op_throw; 
    194194        switch( ur_type(OR_TOC) ) 
    195195        { 
     196#if 1 
     197            case UT_WORD:   // Reduce 
     198            { 
     199                int size; 
     200                UIndex rblkN; 
     201                UBlock* rblk; 
     202                UCell* ntos; 
     203 
     204                //ntos = UR_TOC->reduce.cell; 
     205                ntos = ur_s_aheadN( UR_BOS, OR_TOC->word.sel ); 
     206                size = (UR_TOS - ntos) + 1; 
     207                //if( size < 0 ) 
     208                //    goto stack_eaten; 
     209                rblkN = ur_makeBlock( size ); 
     210                if( size ) 
     211                { 
     212                    rblk = ur_blockPtr( rblkN ); 
     213                    rblk->used = size; 
     214                    ur_copyCells( ntos, ntos + size, rblk->ptr.cells ); 
     215                    UR_TOS = ntos; 
     216                } 
     217                ur_initType(ntos, UT_BLOCK); 
     218                ur_setSeries(ntos, rblkN, 0); 
     219            } 
     220                UR_C_DEC; 
     221                goto control_end; 
     222#endif 
     223 
    196224            case UT_BLOCK: 
    197225                if( ur_evalLocal(OR_TOC) ) 
     
    216244    else 
    217245    { 
    218 fetch_pc_infix: 
    219246        val = pc; 
    220247    } 
     
    225252        case UT_SETWORD: 
    226253            assert( val->word.index > -1 ); 
    227             ++fetch; 
    228             PUSHC_SETWORD(val); 
     254            PUSHC_CELL( val ); 
    229255            goto fetch_pc; 
    230256 
     
    234260                case ROP_NOP: 
    235261#ifdef DEBUG 
    236                     val = 0; 
     262                    cval = val; 
    237263#endif 
    238264                    goto fetch_pc; 
     
    242268                case ROP_MUL: 
    243269                case ROP_DIV: 
    244                     ++fetch; 
    245                     PUSHC_INFIX( ur_opcode(val) - ROP_ADD ); 
    246                     goto fetch_pc; 
    247             } 
    248             break; 
     270                    goto unexpected_infix; 
     271            } 
     272            goto invalid_opcode; 
    249273 
    250274        case UT_CALL: 
    251275            if( ur_argc(val) == 0 ) 
    252276                goto call; 
    253             fetch += ur_argc(val); 
    254             PUSHC_CALL(val); 
     277            PUSHC_CELL( val ); 
    255278            goto fetch_pc; 
    256279 
     
    258281            if( ur_argc(val) == 0 ) 
    259282                goto call_func; 
    260             fetch += ur_argc(val); 
    261             PUSHC_FUNC(val); 
    262             goto fetch_pc; 
    263  
    264         default: 
    265             if( fetch ) 
    266             { 
    267                 UR_S_GROW; 
    268             } 
    269             ur_copyCell( UR_TOS, *val ); 
    270             break; 
     283            PUSHC_CELL( val ); 
     284            ur_funcFetch(OR_TOC) = ur_argc(val); 
     285            goto fetch_pc; 
    271286    } 
    272287 
    273288control: 
    274  
    275     if( (pc < end) && ur_is(pc, UT_OPCODE) && (ur_opcode(pc) >= ROP_ADD) ) 
    276         goto fetch_pc_infix; 
    277  
    278289control_end: 
     290 
     291    // Here val points to current value (most often contents at pc). 
    279292 
    280293    switch( ur_type(OR_TOC) ) 
     
    283296            goto finish; 
    284297 
     298        case UT_WORD:       // Reduce 
     299            //UR_S_GROW; 
     300            goto fetch_pc; 
     301 
     302        case UT_OPCODE:     // Assume Infix. 
     303            PUSH_VAL 
     304            val = INFIX_CALL( ur_opcode(OR_TOC) ); 
     305            UR_C_DEC; 
     306            goto call; 
     307 
    285308        case UT_SETWORD: 
    286             --fetch; 
    287             val = ur_wordCell( ur_thread, OR_TOC ); 
    288             if( ! val ) 
     309            LOOK_AHEAD_FOR_INFIX 
     310            cval = ur_wordCell( ur_thread, OR_TOC ); 
     311            if( ! cval ) 
    289312            { 
    290313                goto op_throw; 
    291314            } 
    292             ur_copyCell( val, *UR_TOS ); 
    293  
     315            ur_copyCell( cval, *val /*UR_TOS*/ ); 
    294316            UR_C_DEC; 
    295317            goto control_end; 
    296318 
    297319        case UT_BLOCK: 
    298             break; 
     320            LOOK_AHEAD_FOR_INFIX 
     321            goto fetch_pc; 
    299322 
    300323        case UT_PAREN: 
     
    304327 
    305328        case UT_CALL: 
    306             --fetch; 
    307             if( --ur_callFetch(OR_TOC) == 0 ) 
     329            LOOK_AHEAD_FOR_INFIX 
     330            PUSH_VAL 
     331            //printf( "KR f %d\n", OR_TOC->call.fetch ); 
     332            if( --OR_TOC->call.fetch == 0 ) 
    308333            { 
    309334                val = OR_TOC; 
     
    311336                goto call; 
    312337            } 
    313             break; 
     338            goto fetch_pc; 
    314339 
    315340        case UT_FUNCTION: 
    316             --fetch; 
     341            LOOK_AHEAD_FOR_INFIX 
     342            PUSH_VAL 
    317343            if( --ur_funcFetch(OR_TOC) == 0 ) 
    318344            { 
     
    326352                goto call_func; 
    327353            } 
    328             break; 
    329  
    330         default: 
    331             goto bad_control; 
    332     } 
     354            goto fetch_pc; 
     355    } 
     356    goto bad_control; 
     357 
     358push_infix: 
     359 
     360    PUSHC_CELL( pc ); 
     361    ++pc; 
     362    PUSH_VAL 
    333363    goto fetch_pc; 
    334364 
     
    357387            UR_CALL_OP = 0; 
    358388            goto quit; 
    359     } 
     389 
     390        case OP_REDUCE: 
     391            UR_CALL_OP = 0; 
     392            PUSHC_EVAL( blkN, pc - start ); 
     393            SET_BLK_PC( UR_TOS->series.n, UR_TOS->series.it ); 
     394            PUSHC_REDUCE( UR_TOS->series.n ); 
     395            UR_S_DROP; 
     396            goto fetch_pc; 
     397    } 
     398    val = UR_TOS; 
    360399    goto control; 
    361400 
     
    398437 
    399438    ur_initType(UR_TOS, UT_UNSET); 
     439    val = UR_TOS; 
    400440    goto fetch_pc; 
    401441 
     
    424464finish: 
    425465 
     466    PUSH_VAL 
    426467    return UR_EVAL_OK; 
     468 
     469unexpected_infix: 
     470 
     471    ur_throwErr( UR_ERR_SCRIPT, "infix opcode missing first value" ); 
     472    goto trace_error; 
     473 
     474invalid_opcode: 
     475 
     476    ur_throwErr( UR_ERR_SCRIPT, "invalid opcode" ); 
     477    goto trace_error; 
    427478 
    428479unexpected_end: 
     
    481532            if( ur_is(val, UT_CALL) ) 
    482533            { 
    483                 val->call.sigN = _funcSignature( it, &argc, &varc ); 
     534                /* LIMIT: All Rune call sigN blocks must be in first 65k. */ 
     535                val->call.sigN  = _funcSignature( it, &argc, &varc ); 
    484536                ur_argc(val)   = argc; 
    485537                ur_varc(val)   = 0; //varc 
     538                val->call.fetch = argc; 
    486539            } 
    487540            else 
     
    588641  "[\n" 
    589642  "  0 'nop\n" 
    590   "  1 +\n" 
    591   "  2 -\n" 
    592   "  3 *\n" 
    593   "  4 /\n" 
     643  "  1 reduce\n" 
     644  "  2 +\n" 
     645  "  3 -\n" 
     646  "  4 *\n" 
     647  "  5 /\n" 
    594648  "] make-opcodes :rune-ops\n" 
    595649  "[block! verify/1 rune-ops infuse code! swap 'rune make] proc :runec\n" 
    596650  "[runec do] proc :rune\n" 
    597651  "[\n" 
    598   "  add   [a int!/decimal! b int!/decimal!]\n" 
    599   "  sub   [a int!/decimal! b int!/decimal!]\n" 
    600   "  func  [sig block! body block!]\n" 
    601   "  type? [val]\n" 
     652  "  add    [a int!/decimal! b int!/decimal!]\n" 
     653  "  sub    [a int!/decimal! b int!/decimal!]\n" 
     654  "  mul    [a int!/decimal! b int!/decimal!]\n" 
     655  "  div    [a int!/decimal! b int!/decimal!]\n" 
     656  "  console.out [val]\n" 
     657  "  func   [sig block! body block!]\n" 
     658  "  type?  [val]\n" 
     659  "  reduce [val]\n" 
    602660  "] define-natives\n" 
    603661  "\n" 
  • trunk/thune/rune/tests/eval.good

    r260 r278  
    11--- Empty --- 
    2 'orig 
     2unset 
     3--- Inert --- 
     43 
    35--- Call 1 --- 
    468 
     
    10127 
    11133 
     14--- Infix 3 --- 
     157 
     169 
     179 
     18--- Print --- 
     19hi 
     20unset 
    1221--- Func 1 --- 
    132216 
  • trunk/thune/rune/tests/eval.t

    r260 r278  
    55 
    66 
     7 
    78/* 
     9"--- Reduce 1 ---" 
     10[reduce [1 + 2 * 3]] test 
    811*/ 
    9 'orig 
     12 
     13;'orig 
    1014"--- Empty ---" 
    1115[] test 
     16 
     17"--- Inert ---" 
     18[1 2 3] test 
    1219 
    1320"--- Call 1 ---" 
     
    2330x . 
    2431 
     32"--- Infix 3 ---" 
     33[add 1 2 * 3] test      ;= 7 
     34[1 + 2 * 3] rune .        ;= 9 
     35[mul add 1 2 3] rune .    ;= 9 
     36;[+ 1 * 2 3] test        ;= 5 (Rune expects first value) 
     37;[1 + * 2 3] test        ;= 7 (Rune expects first value) 
     38 
     39"--- Print ---" 
     40[console.out "hi^/"] test 
     41 
    2542"--- Func 1 ---" 
    2643[p2: func [x] [x * x]  nop p2 4] test 
     
    2845"--- Func 2 ---" 
    2946[p2: func [] [] p2] test 
    30 /* 
    31 */ 
     47