Changeset 278 for trunk/thune/rune
- Timestamp:
- 09/20/06 03:07:59 (2 years ago)
- Location:
- trunk/thune/rune
- Files:
-
- 3 modified
-
rune.c (modified) (23 diffs)
-
tests/eval.good (modified) (2 diffs)
-
tests/eval.t (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/thune/rune/rune.c
r276 r278 34 34 #define OR_BOC ur_thread->cstack 35 35 36 #define ur_callFetch(cell) cell->call.sigN37 36 #define ur_funcFetch(cell) cell->func.closureN 38 37 #define ur_argc(cell) cell->func.localArgs 39 38 #define ur_varc(cell) cell->func.localVars 40 39 #define ur_evalLocal(cell) cell->series.encoding 41 #define ur_evalFetch(cell) cell->coord.elem[5]42 40 43 41 #define CC_SETWORD CC_END+1 … … 55 53 start = blk->ptr.cells; \ 56 54 pc = start + it; \ 57 end = start + blk->used; \ 58 fetch = 0 55 end = start + blk->used; 59 56 60 57 … … 71 68 ur_initType(OR_TOC, UT_BLOCK); \ 72 69 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); 75 71 76 72 #define PUSHC_EVAL(blkn,pos) \ 77 73 UR_C_GROW; \ 78 74 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 82 85 83 86 #define PUSHC_CELL(val) \ … … 85 88 *OR_TOC = *val 86 89 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 102 90 103 91 enum eRuneOpcode 104 92 { 105 93 ROP_NOP = 0, 94 ROP_REDUCE, 106 95 ROP_ADD, 107 96 ROP_SUB, … … 110 99 }; 111 100 101 102 #define INFIX_CALL(op) ((UCell*) (_infixOperator + ((op) - ROP_ADD))) 103 112 104 UCellCall _infixOperator[] = 113 105 { 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} 118 110 }; 119 111 … … 164 156 165 157 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 166 166 int rune_eval( UThread* ur_thread, UIndex blkN, UIndex si ) 167 167 { … … 171 171 UCell* end; 172 172 UCell* val; 173 int fetch; // Controls if pc values are pushed onto the stack.173 UCell* cval; 174 174 175 175 … … 179 179 pc = start + si; 180 180 end = start + blk->used; 181 fetch = 0; 181 182 ur_initType(UR_TOS, UT_UNSET); 183 val = UR_TOS; 182 184 183 185 PUSHC_END; … … 190 192 // End of block reached. 191 193 192 //if( fetch )193 // goto op_throw;194 194 switch( ur_type(OR_TOC) ) 195 195 { 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 196 224 case UT_BLOCK: 197 225 if( ur_evalLocal(OR_TOC) ) … … 216 244 else 217 245 { 218 fetch_pc_infix:219 246 val = pc; 220 247 } … … 225 252 case UT_SETWORD: 226 253 assert( val->word.index > -1 ); 227 ++fetch; 228 PUSHC_SETWORD(val); 254 PUSHC_CELL( val ); 229 255 goto fetch_pc; 230 256 … … 234 260 case ROP_NOP: 235 261 #ifdef DEBUG 236 val = 0;262 cval = val; 237 263 #endif 238 264 goto fetch_pc; … … 242 268 case ROP_MUL: 243 269 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; 249 273 250 274 case UT_CALL: 251 275 if( ur_argc(val) == 0 ) 252 276 goto call; 253 fetch += ur_argc(val); 254 PUSHC_CALL(val); 277 PUSHC_CELL( val ); 255 278 goto fetch_pc; 256 279 … … 258 281 if( ur_argc(val) == 0 ) 259 282 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; 271 286 } 272 287 273 288 control: 274 275 if( (pc < end) && ur_is(pc, UT_OPCODE) && (ur_opcode(pc) >= ROP_ADD) )276 goto fetch_pc_infix;277 278 289 control_end: 290 291 // Here val points to current value (most often contents at pc). 279 292 280 293 switch( ur_type(OR_TOC) ) … … 283 296 goto finish; 284 297 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 285 308 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 ) 289 312 { 290 313 goto op_throw; 291 314 } 292 ur_copyCell( val, *UR_TOS ); 293 315 ur_copyCell( cval, *val /*UR_TOS*/ ); 294 316 UR_C_DEC; 295 317 goto control_end; 296 318 297 319 case UT_BLOCK: 298 break; 320 LOOK_AHEAD_FOR_INFIX 321 goto fetch_pc; 299 322 300 323 case UT_PAREN: … … 304 327 305 328 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 ) 308 333 { 309 334 val = OR_TOC; … … 311 336 goto call; 312 337 } 313 break;338 goto fetch_pc; 314 339 315 340 case UT_FUNCTION: 316 --fetch; 341 LOOK_AHEAD_FOR_INFIX 342 PUSH_VAL 317 343 if( --ur_funcFetch(OR_TOC) == 0 ) 318 344 { … … 326 352 goto call_func; 327 353 } 328 break; 329 330 default: 331 goto bad_control; 332 } 354 goto fetch_pc; 355 } 356 goto bad_control; 357 358 push_infix: 359 360 PUSHC_CELL( pc ); 361 ++pc; 362 PUSH_VAL 333 363 goto fetch_pc; 334 364 … … 357 387 UR_CALL_OP = 0; 358 388 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; 360 399 goto control; 361 400 … … 398 437 399 438 ur_initType(UR_TOS, UT_UNSET); 439 val = UR_TOS; 400 440 goto fetch_pc; 401 441 … … 424 464 finish: 425 465 466 PUSH_VAL 426 467 return UR_EVAL_OK; 468 469 unexpected_infix: 470 471 ur_throwErr( UR_ERR_SCRIPT, "infix opcode missing first value" ); 472 goto trace_error; 473 474 invalid_opcode: 475 476 ur_throwErr( UR_ERR_SCRIPT, "invalid opcode" ); 477 goto trace_error; 427 478 428 479 unexpected_end: … … 481 532 if( ur_is(val, UT_CALL) ) 482 533 { 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 ); 484 536 ur_argc(val) = argc; 485 537 ur_varc(val) = 0; //varc 538 val->call.fetch = argc; 486 539 } 487 540 else … … 588 641 "[\n" 589 642 " 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" 594 648 "] make-opcodes :rune-ops\n" 595 649 "[block! verify/1 rune-ops infuse code! swap 'rune make] proc :runec\n" 596 650 "[runec do] proc :rune\n" 597 651 "[\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" 602 660 "] define-natives\n" 603 661 "\n" -
trunk/thune/rune/tests/eval.good
r260 r278 1 1 --- Empty --- 2 'orig 2 unset 3 --- Inert --- 4 3 3 5 --- Call 1 --- 4 6 8 … … 10 12 7 11 13 3 14 --- Infix 3 --- 15 7 16 9 17 9 18 --- Print --- 19 hi 20 unset 12 21 --- Func 1 --- 13 22 16 -
trunk/thune/rune/tests/eval.t
r260 r278 5 5 6 6 7 7 8 /* 9 "--- Reduce 1 ---" 10 [reduce [1 + 2 * 3]] test 8 11 */ 9 'orig 12 13 ;'orig 10 14 "--- Empty ---" 11 15 [] test 16 17 "--- Inert ---" 18 [1 2 3] test 12 19 13 20 "--- Call 1 ---" … … 23 30 x . 24 31 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 25 42 "--- Func 1 ---" 26 43 [p2: func [x] [x * x] nop p2 4] test … … 28 45 "--- Func 2 ---" 29 46 [p2: func [] [] p2] test 30 /* 31 */ 47
