Changeset 387 for branches/thune/thread_safe/eval.c
- Timestamp:
- 05/17/07 16:25:27 (18 months ago)
- Files:
-
- 1 modified
-
branches/thune/thread_safe/eval.c (modified) (49 diffs)
Legend:
- Unmodified
- Added
- Removed
-
branches/thune/thread_safe/eval.c
r385 r387 19 19 20 20 21 #include "os.h" 22 #include "urlan.h" 21 #include "internal.h" 23 22 #include "urlan_atoms.h" 24 #include "internal.h"25 23 #include "bignum.h" 26 24 27 25 26 extern UContext ur_global; 27 extern UContext ur_envGlobal; 28 28 29 extern void uc_console_out( UThread*, UCell* ); 29 30 30 31 31 32 #ifdef DEBUG 32 void ur_dumpBlock( U Index blkN )33 void ur_dumpBlock( UThread* ut, UIndex blkN ) 33 34 { 34 35 UCell* cell; … … 58 59 59 60 60 static void _infuseOpcodes( UThread* thr, UIndex blkN )61 static void _infuseOpcodes( UThread* ut, UIndex blkN ) 61 62 { 62 63 UBlock* blk; 63 U Block* gblk;64 UContext* global; 64 65 const UCell* ctx; 65 66 int wrdN; 66 67 67 blk = ur_bind( blkN, &ur_global ); 68 69 wrdN = ur_lookup( &ur_global, UR_ATOM_KERNEL_OPS ); 70 //assert( wrdN > -1 ); 71 if( wrdN > -1 ) 72 { 73 gblk = ur_blockPtr( GLOBAL_VAL_BLKN ); 74 ctx = gblk->ptr.cells + wrdN; 75 76 assert( ctx->id.type == UT_CONTEXT ); 77 78 ur_infuse( thr, blk, ctx ); 68 global = (ut->env->blocks.arr.used) ? &ur_envGlobal : &ur_global; 69 70 wrdN = ur_lookup( global, UR_ATOM_KERNEL_OPS ); 71 assert( wrdN > -1 ); 72 //if( wrdN > -1 ) 73 { 74 blk = ur_blockPtr( global->ctx.valBlk ); 75 ctx = blk->ptr.cells + wrdN; 76 77 assert( ur_is(ctx, UT_CONTEXT) ); 78 79 blk = ur_blockPtr( blkN ); 80 ur_infuse( ut, blk, ctx ); 79 81 } 80 82 } … … 86 88 returned. 87 89 */ 88 static int ur_itLen( U Cell* cell )90 static int ur_itLen( UThread* ut, UCell* cell ) 89 91 { 90 92 int len = ur_seriesLen( cell ); … … 101 103 Res may be the same as sel. 102 104 */ 103 int ur_getSelector( UThread* u r_thread, const UCell* sel, UCell* res )105 int ur_getSelector( UThread* ut, const UCell* sel, UCell* res ) 104 106 { 105 107 #define ATOM_OFF(val,atm) (((unsigned int) val) - atm) … … 107 109 UCell* val; 108 110 109 val = ur_wordCell( u r_thread, sel );111 val = ur_wordCell( ut, sel ); 110 112 if( ! val ) 111 113 return 0; … … 157 159 if( ur_type(val) >= UT_BI_COUNT ) 158 160 { 159 UDatatypeSelFunc func = u r_thread->env->customDT161 UDatatypeSelFunc func = ut->env->customDT 160 162 [ ur_type(val) - UT_BI_COUNT ].selectAtom; 161 163 if( func ) 162 return func( u r_thread, val, sel, res );164 return func( ut, val, sel, res ); 163 165 } 164 166 goto set_none; … … 167 169 else 168 170 { 169 if( ur_pick( val, ur_sel(sel) - 1, res ) )171 if( ur_pick( ut, val, ur_sel(sel) - 1, res ) ) 170 172 return 1; 171 173 } 172 174 173 ur_throwErr( ur_thread, UR_EX_SCRIPT, "Invalid select!" );175 ur_throwErr( UR_ERR_SCRIPT, "Invalid select!" ); 174 176 return 0; 175 177 … … 184 186 Returns non-zero if successful. 185 187 */ 186 int ur_setSelector( UThread* u r_thread, const UCell* sel, const UCell* nval )188 int ur_setSelector( UThread* ut, const UCell* sel, const UCell* nval ) 187 189 { 188 190 UBlock* blk; 189 191 UCell* val; 190 192 191 val = ur_wordCell( u r_thread, sel );193 val = ur_wordCell( ut, sel ); 192 194 if( ! val ) 193 195 return 0; … … 242 244 if( ! ur_selIsAtom(sel) ) 243 245 { 244 if( ur_poke( val, ur_sel(sel) - 1, nval ) )245 return 1; 246 } 247 break; 248 } 249 250 ur_throwErr( ur_thread, UR_EX_SCRIPT, "Invalid select!" );246 if( ur_poke( ut, val, ur_sel(sel) - 1, nval ) ) 247 return 1; 248 } 249 break; 250 } 251 252 ur_throwErr( UR_ERR_SCRIPT, "Invalid select!" ); 251 253 return 0; 252 254 } … … 283 285 { 284 286 UCell* val; 285 val = ur_wordCell( u r_thread, tos );287 val = ur_wordCell( ut, tos ); 286 288 if( val ) 287 289 { … … 317 319 318 320 319 static void _appendTraceBlk( U CellError* err, int n, int it )321 static void _appendTraceBlk( UThread* ut, UCellError* err, int n, int it ) 320 322 { 321 323 if( err->traceBlk ) … … 334 336 #define _throwUnbound(th,cell) _throwUnsetF(th,cell,"unbound") 335 337 336 static void _throwUnsetF( UThread* ur_thread, const UCell* wcell, 337 const char* umsg ) 338 static void _throwUnsetF( UThread* ut, const UCell* wcell, const char* umsg ) 338 339 { 339 340 UString* str; 340 str = ur_ binPtr( ur_thread->callTempBinN);341 str = ur_threadTmp( ut ); 341 342 str->used = 0; 342 343 ur_atomStr( ur_atom(wcell), str ); 343 344 ur_termCStr( str ); 344 ur_throwErr( ur_thread, UR_EX_SCRIPT, 345 "word '%s is %s", str->ptr.c, umsg ); 346 } 347 348 349 /* 345 ur_throwErr( UR_ERR_SCRIPT, "word '%s is %s", str->ptr.c, umsg ); 346 } 347 348 349 /** 350 350 Returns cell pointer or zero if word does not reference a valid cell. 351 351 */ 352 UCell* ur_wordCell( UThread* ur_thread, const UCell* pc ) 353 { 354 UCell* val; 355 int i; 356 357 i = pc->word.valBlk; 358 if( i < 0 ) 359 { 360 // Find function local frame i. 361 362 LocalFrame* it; 363 LocalFrame* end; 364 365 it = UR_LF_BEG; 366 end = UR_LF_END; 367 while( it != end ) 368 { 369 if( it->localFrame.n == i ) 370 { 371 val = it->localFrame.cell; 372 goto val_set; 373 } 374 ++it; 375 } 376 377 _throwUnsetF( ur_thread, pc, "out-of-scope local" ); 352 UCell* ur_wordCell( UThread* ut, const UCell* pc ) 353 { 354 UBlock* blk; 355 int wrdN; 356 357 wrdN = pc->word.index; 358 if( wrdN < 0 ) 359 { 360 _throwUnbound( ut, pc); // UR_UNBOUND 378 361 return 0; 379 362 } 380 else 381 { 382 val = ur_blockPtr( i )->ptr.cells; 383 } 384 385 val_set: 386 387 i = pc->word.index; 388 if( i < 0 ) 389 { 390 _throwUnbound(ur_thread, pc); 391 return 0; 392 } 393 394 return val + i; 395 } 396 397 398 int ur_evalCStr( UThread* ur_thread, const char* cmd, int len ) 363 364 switch( pc->word.flags & UR_FLAG_BIND_MASK ) 365 { 366 case UR_BIND_THREAD: 367 // ur_blockPtr( pc->word.valBlk ) 368 blk = (((UBlock*) ut->blocks.arr.ptr.v) + pc->word.valBlk); 369 return blk->ptr.cells + wrdN; 370 371 case UR_BIND_GLOBAL: 372 // ur_blockPtr( pc->word.valBlk ) 373 blk = (((UBlock*) ut->env->blocks.arr.ptr.v) - pc->word.valBlk); 374 return blk->ptr.cells + wrdN; 375 376 case UR_BIND_LOCAL: 377 #if 1 378 { 379 LocalFrame* it = UR_LF_BEG; 380 LocalFrame* end = UR_LF_END; 381 while( it != end ) 382 { 383 if( it->n == pc->word.wordBlk ) 384 return it->cell + wrdN; 385 ++it; 386 } 387 _throwUnsetF( ut, pc, "out-of-scope local" ); 388 return 0; 389 } 390 #else 391 if( pc->word.wordBlk != ut->localWordBlk ) 392 { 393 _throwUnsetF( ut, pc, "out-of-scope local" ); 394 return 0; 395 } 396 #if 0 397 blk = ((UBlock*) ut->blocks.arr.ptr.v) + BLK_DSTACK; 398 return blk->ptr.cells + wrdN + ut->localIdx; 399 #else 400 return ut->localPos + wrdN; 401 #endif 402 #endif 403 } 404 405 return 0; 406 } 407 408 409 int ur_evalCStr( UThread* ut, const char* cmd, int len ) 399 410 { 400 411 const char* end; … … 417 428 if( end != cmd ) 418 429 { 419 blkN = ur_tokenize( u r_thread, cmd, end, 0 );430 blkN = ur_tokenize( ut, cmd, end, 0 ); 420 431 if( blkN ) 421 432 { 422 _infuseOpcodes( u r_thread, blkN );423 return ur_eval( u r_thread, blkN, 0 );433 _infuseOpcodes( ut, blkN ); 434 return ur_eval( ut, blkN, 0 ); 424 435 } 425 436 return UR_EVAL_ERROR; … … 437 448 Returns 1 if equivalent or zero if not. 438 449 */ 439 int ur_equal( const UCell* a, const UCell* b )450 int ur_equal( UThread* ut, const UCell* a, const UCell* b ) 440 451 { 441 452 switch( ur_type(a) ) … … 581 592 int len; 582 593 583 if( ur_blockSlice( a, &cpA1, &cpA2 ) )584 { 585 if( ur_blockSlice( b, &cpB1, &cpB2 ) )594 if( ur_blockSlice( ut, a, &cpA1, &cpA2 ) ) 595 { 596 if( ur_blockSlice( ut, b, &cpB1, &cpB2 ) ) 586 597 { 587 598 len = cpB2 - cpB1; … … 592 603 while( cpA1 != cpA2 ) 593 604 { 594 if( ! ur_equal( cpA1++, cpB1++ ) )605 if( ! ur_equal( ut, cpA1++, cpB1++ ) ) 595 606 return 0; 596 607 } … … 610 621 int len; 611 622 612 if( ur_stringSlice( a, &cpA1, &cpA2 ) )613 { 614 if( ur_stringSlice( b, &cpB1, &cpB2 ) )623 if( ur_stringSlice( ut, a, &cpA1, &cpA2 ) ) 624 { 625 if( ur_stringSlice( ut, b, &cpB1, &cpB2 ) ) 615 626 { 616 627 // TODO: Handle different encodings. … … 628 639 } 629 640 } 630 else if( ur_binarySlice( a, &cpA1, &cpA2 ) )631 { 632 if( ur_binarySlice( b, &cpB1, &cpB2 ) )641 else if( ur_binarySlice( ut, a, &cpA1, &cpA2 ) ) 642 { 643 if( ur_binarySlice( ut, b, &cpB1, &cpB2 ) ) 633 644 goto eq_bin_slice; 634 645 } … … 643 654 Returns 1 if cells are of the same type and value or zero if not. 644 655 */ 645 int ur_same( const UCell* a, const UCell* b ) 646 { 656 int ur_same( UThread* ut, const UCell* a, const UCell* b ) 657 { 658 (void) ut; 659 647 660 if( ur_type(a) != ur_type(b) ) 648 661 return 0; … … 700 713 { 701 714 UR_S_DROP; 702 ur_logic(UR_TOS) = ur_equal( UR_TOS, tos );715 ur_logic(UR_TOS) = ur_equal( ut, UR_TOS, tos ); 703 716 ur_initType( UR_TOS, UT_LOGIC ); 704 717 } … … 713 726 UR_S_DROP; 714 727 715 same = ur_same( res, tos );728 same = ur_same( ut, res, tos ); 716 729 ur_initType( res, UT_LOGIC ); 717 730 ur_logic(res) = same; … … 761 774 ur_initType(tos, UT_WORD); 762 775 tos->word.wordBlk = 0; 763 tos->word.valBlk = GLOBAL_VAL_BLKN;776 tos->word.valBlk = BLK_GLOBAL_VAL; 764 777 tos->word.index = t; 765 778 tos->word.atom = t; … … 772 785 #if 1 773 786 UString* str; 774 str = ur_ binPtr( ur_thread->callTempBinN);787 str = ur_threadTmp( ut ); 775 788 str->used = 0; 776 789 ur_toStr( tos, str, 0 ); … … 781 794 tos = UR_TOS; 782 795 ur_initType( tos, UT_STRING ); 783 ur_setSeries( tos, ur_thread->callTempBinN, 0 );784 uc_console_out( u r_thread, tos );796 ur_setSeries( tos, BIN_THREAD_TMP, 0 ); 797 uc_console_out( ut, tos ); 785 798 #else 786 799 UString str; … … 805 818 UR_CALL( uc_showTOS ) 806 819 { 807 _probe( u r_thread, tos );820 _probe( ut, tos ); 808 821 UR_S_SAFE_DROP; 809 822 } … … 815 828 { 816 829 UCell* it = tos; 817 UCell* end = u r_thread->dstack;830 UCell* end = ut->dstack; 818 831 819 832 if( it >= (end + UR_DSTACK_SIZE) ) … … 825 838 while( it != end ) 826 839 { 827 _probe( u r_thread, it );840 _probe( ut, it ); 828 841 --it; 829 842 } … … 857 870 if( ur_wordIsUnbound(tos) ) 858 871 { 859 if( tos->word.valBlk == GLOBAL_VAL_BLKN)872 if( tos->word.valBlk == BLK_GLOBAL_VAL ) 860 873 { 861 874 tos->word.index = ur_internWord( &ur_global, ur_atom(tos) ); … … 863 876 else 864 877 { 865 _throwUnbound( u r_thread, tos );878 _throwUnbound( ut, tos ); 866 879 return; 867 880 } 868 881 } 869 882 870 cell = ur_wordCell( u r_thread, tos );883 cell = ur_wordCell( ut, tos ); 871 884 if( ! cell ) 872 885 return; … … 888 901 if( ur_isAWord(it) ) 889 902 { 890 cell = ur_wordCell( u r_thread, it );903 cell = ur_wordCell( ut, it ); 891 904 if( ! cell ) 892 905 return; 893 ur_pick( val, n++, cell );906 ur_pick( ut, val, n++, cell ); 894 907 } 895 908 ++it; … … 902 915 if( ur_isAWord(it) ) 903 916 { 904 cell = ur_wordCell( u r_thread, it );917 cell = ur_wordCell( ut, it ); 905 918 if( ! cell ) 906 919 return; … … 945 958 if( ur_isAWord(tos) ) 946 959 { 947 val = ur_wordCell( u r_thread, tos );960 val = ur_wordCell( ut, tos ); 948 961 if( val ) 949 962 { … … 968 981 /* 969 982 if( ur_is(ctx, UT_UNSET) ) 970 _throwUnset( u r_thread, ctx );983 _throwUnset( ut, ctx ); 971 984 */ 972 985 } … … 981 994 } 982 995 983 ur_throwErr( ur_thread, UR_EX_DATATYPE, "get expected word!" );996 ur_throwErr( UR_ERR_DATATYPE, "get expected word!" ); 984 997 } 985 998 … … 1013 1026 char* spA; 1014 1027 char* spB; 1015 if( ur_stringSlice( val, &spA, &spB) && spA )1028 if( ur_stringSlice(ut, val, &spA, &spB) && spA ) 1016 1029 { 1017 1030 ur_initType(val, UT_WORD); 1018 ur_setUnbound( val, UR_INTERN( spA, spB - spA ) );1031 ur_setUnbound( val, ur_intern( spA, spB - spA ) ); 1019 1032 } 1020 1033 } … … 1076 1089 // Must copy so UArray->used will be accurate. 1077 1090 UIndex binN; 1078 binN = ur_makeBinaryFrom( val );1091 binN = ur_makeBinaryFrom( ut, val ); 1079 1092 ur_setSeries(val, binN, 0); 1080 1093 } … … 1161 1174 if( ur_is(val, UT_STRING) ) 1162 1175 { 1163 ur_clone( val, UR_COPY_ALL, 0 );1176 ur_clone( ut, val, UR_COPY_ALL, 0 ); 1164 1177 UR_S_DROP; 1165 1178 return; … … 1168 1181 } 1169 1182 1170 uc_as( u r_thread, tos );1183 uc_as( ut, tos ); 1171 1184 } 1172 1185 … … 1191 1204 } 1192 1205 1193 ur_throwErr( ur_thread, UR_EX_DATATYPE, "Invalid bind values" );1206 ur_throwErr( UR_ERR_DATATYPE, "Invalid bind values" ); 1194 1207 } 1195 1208 1196 1209 1197 1210 // Find function local frame for N. 1198 static UCell* _localCells( UThread* ur_thread, int n ) 1199 { 1200 LocalFrame* it; 1201 LocalFrame* end; 1202 it = UR_LF_BEG; 1203 end = UR_LF_END; 1211 static UCell* _localCells( UThread* ut, UIndex wordBlk ) 1212 { 1213 #if 0 1214 assert( ut->localWordBlk == wordBlk ); 1215 return ut->localPos; 1216 #else 1217 LocalFrame* it = UR_LF_BEG; 1218 LocalFrame* end = UR_LF_END; 1204 1219 while( it != end ) 1205 1220 { 1206 if( it-> localFrame.n == n)1207 return it-> localFrame.cell;1221 if( it->n == wordBlk ) 1222 return it->cell; 1208 1223 ++it; 1209 1224 } 1210 1225 assert( 0 ); 1211 1226 return 0; 1227 #endif 1212 1228 } 1213 1229 … … 1217 1233 the context. 1218 1234 */ 1219 void ur_infuse( UThread* thr, UBlock* blk, const UContext* cc )1235 void ur_infuse( UThread* ut, UBlock* blk, const UContext* cc ) 1220 1236 { 1221 1237 UCell* it = blk->ptr.cells; … … 1224 1240 int flags; 1225 1241 1226 if( cc->ctx.valBlk < 0)1227 { 1228 values = _localCells( thr, cc->ctx.valBlk );1242 if( ur_bindType(cc) == UR_BIND_LOCAL ) 1243 { 1244 values = _localCells( ut, cc->ctx.wordBlk ); 1229 1245 } 1230 1246 else … … 1251 1267 else if( ur_is(it, UT_BLOCK) || ur_is(it, UT_PAREN) ) 1252 1268 { 1253 ur_infuse( thr, ur_blockPtr( it->series.n ), cc );1269 ur_infuse( ut, ur_blockPtr( it->series.n ), cc ); 1254 1270 } 1255 1271 else if( ur_is(it, UT_SELECT) ) … … 1295 1311 { 1296 1312 if( ur_is(bc, UT_BLOCK) ) 1297 ur_infuse( u r_thread, ur_block(bc), tos );1313 ur_infuse( ut, ur_block(bc), tos ); 1298 1314 } 1299 1315 UR_S_DROP; … … 1308 1324 static 1309 1325 #endif 1310 UIndex _funcSignature( const UCell* scell, int* pArgc, int* pVarc )1326 UIndex _funcSignature( UThread* ut, const UCell* scell, int* pArgc, int* pVarc ) 1311 1327 { 1312 1328 UIndex sigN; … … 1421 1437 1422 1438 // Scan signature 1423 sigN = _funcSignature( res, &argc, &varc );1424 1425 lctx.ctx.wordBlk = sigN;1426 lctx.ctx.valBlk = -sigN; // Negative valBlk denotes stack storage.1427 1428 ur_bind ( bodN, &lctx);1439 sigN = _funcSignature( ut, res, &argc, &varc ); 1440 1441 lctx.ctx.wordBlk = sigN; 1442 lctx.ctx.valBlk = 0; //BLK_DSTACK; 1443 1444 ur_bindT( ut, bodN, &lctx, UR_BIND_LOCAL ); 1429 1445 1430 1446 ur_initType( res, UT_FUNCTION ); … … 1502 1518 { 1503 1519 UIndex strN = ur_makeBinary( 0 ); 1504 ur_toStrNatural( tos, ur_binPtr(strN), 0 );1520 ur_toStrNatural( ut, tos, ur_binPtr(strN), 0 ); 1505 1521 ur_initString(tos, strN, 0); 1506 1522 } … … 1517 1533 if( ur_isAWord(tos) ) 1518 1534 { 1519 hash = ur_atomHash( u r_thread->env, ur_atom(tos) );1520 } 1521 else if( ur_stringSlice( tos, &cpA, &cpB) )1535 hash = ur_atomHash( ut->env, ur_atom(tos) ); 1536 } 1537 else if( ur_stringSlice(ut, tos, &cpA, &cpB) ) 1522 1538 { 1523 1539 hash = ur_hash( cpA, cpB ); … … 1539 1555 { 1540 1556 UR_CALL_UNUSED_TOS 1541 ur_recycle( u r_thread->env);1557 ur_recycle( ut ); 1542 1558 } 1543 1559 …
