Changeset 426
- Timestamp:
- 07/05/07 04:03:51 (14 months ago)
- Location:
- branches/thune/thread_safe
- Files:
-
- 16 modified
-
config.t (modified) (1 diff)
-
context.c (modified) (1 diff)
-
doc/UserManual (modified) (8 diffs)
-
eval.c (modified) (9 diffs)
-
gc.c (modified) (1 diff)
-
gl/project.r (modified) (1 diff)
-
internal.h (modified) (1 diff)
-
make.c (modified) (4 diffs)
-
print.c (modified) (7 diffs)
-
read_config.r (modified) (1 diff)
-
tests/working/bytecode.good (modified) (1 diff)
-
tests/working/bytecode.t (modified) (1 diff)
-
thune.c (modified) (2 diffs)
-
tokenize.c (modified) (4 diffs)
-
urlan.c (modified) (1 diff)
-
urlan.h (modified) (5 diffs)
Legend:
- Unmodified
- Added
- Removed
-
branches/thune/thread_safe/config.t
r408 r426 6 6 enable trig 7 7 [x] macros "Reader macros" 8 [x] net "UDP socket port" 9 [x] dataflow "Component! datatype for dataflow programming" 10 8 11 [ ] dt-code "Include 'code datatype" 9 10 [x] net "UDP socket port"11 12 12 [ ] uds "Library with datatype & gc system only - no eval" 13 13 disable [bzip2 trig math3d dt-code] -
branches/thune/thread_safe/context.c
r387 r426 489 489 case UT_SELECT: 490 490 case UT_SETSELECT: 491 case UT_LITSELECT: 491 492 case UT_OPCODE: 492 493 _bindWord( it ); -
branches/thune/thread_safe/doc/UserManual
r415 r426 88 88 select! obj/x my-block/2 89 89 set-select! :obj/x :my-block/2 90 lit-select! 'obj/x 'my-block/2 90 91 slice! 91 92 time! 10:02 -0:0:32.08 92 93 context! 94 component! 93 95 =========== ========== 94 96 … … 102 104 103 105 Macros can be used wherever a constant is needed to improve evaluation 104 speed. 106 speed. They are also useful for conditional code generation. 105 107 106 108 Example:: … … 110 112 box-width <border> add 111 113 114 Conditional Example:: 115 116 <script-env/os [ 117 linux ["Linux"] 118 solaris ["Solaris"] 119 ["Unsupported OS" error] 120 ] case> 121 print 112 122 113 123 Currently, macro! values cannot be created by the user. … … 243 253 .. The Evaluator 244 254 Contexts & Binding 255 256 257 Components 258 ---------- 259 260 Components are similar to functions, but they operate via a dataflow model. 261 They have inputs, outputs which are connected to the inputs of other 262 components, and a body which is evaluated when all inputs are set. 263 264 Components must have at least one input, but they don't require any outputs. 265 266 Here is an example of how to create and connect components:: 267 268 [a b -- out] [a b mul :out] component :c1 269 [val] [val .] component :probe 270 'c1/out 'probe/val connect 271 272 Now, when the inputs to *c1* are set, *probe* will automatically be invoked:: 273 274 3 :c1/a 275 5 :c1/b 276 15 277 278 Further changes to the inputs will continue to invoke the *probe* component:: 279 280 5 :c1/a 281 25 282 283 *Connect* also accepts components as arguments. This is short-hand for 284 refering to the first input or output. 285 The following call makes the same connection as the example above:: 286 287 c1 probe connect 245 288 246 289 … … 533 576 :: 534 577 535 (logic -- )578 (logic -- ) 536 579 537 580 Evaluate next value if TOS is true. To evaluate more than one value use … … 558 601 :: 559 602 560 (ser new [part int!] -- ser)603 (ser new [part int!] -- ser) 561 604 562 605 Change series at current position. … … 568 611 :: 569 612 570 (ser pat -- end series!/none!)613 (ser pat -- end series!/none!) 571 614 572 615 Move position to end of matching pattern. … … 584 627 585 628 629 Extending The System 630 ==================== 631 632 Adding C Functions 633 ------------------ 634 635 C functions are defined with the *UR_CALL* macro. 636 637 The function is responsible for checking that arguments are of the correct 638 type and for reporting any errors. If type checking were built into the 639 evaluator there would be redundant checks for the typical case where the 640 function accepts multiple types for a given argument or pattern of 641 arguments. 642 643 Always access and check stack arguments starting with *tos* and work down. 644 Since the bottom of the stack contains *UT_UNSET*, checking in this order 645 avoids an extra check to make sure that the stack holds at least the number 646 of expected arguments. 647 648 -
branches/thune/thread_safe/eval.c
r417 r426 120 120 case UT_CONTEXT: 121 121 case UT_PORT: 122 #ifdef UR_CONFIG_DATAFLOW 123 case UT_COMPONENT: 124 #endif 122 125 { 123 126 int wrdN = ur_lookup( val, ur_sel(sel) ); … … 184 187 185 188 189 #ifdef UR_CONFIG_DATAFLOW 190 void ur_setPlug( UThread*, UBlock* cblk, UIndex wrdN, const UCell* nval ); 191 #endif 192 193 186 194 /** 187 195 Returns non-zero if successful. … … 242 250 break; 243 251 252 #ifdef UR_CONFIG_DATAFLOW 253 case UT_COMPONENT: 254 if( ur_selIsAtom(sel) ) 255 { 256 int wrdN; 257 wrdN = ur_lookup( val, ur_sel(sel) ); 258 ur_setPlug( ut, tBlockPtr(val->ctx.valBlk), wrdN, nval ); 259 return 1; 260 } 261 break; 262 #endif 263 244 264 default: 245 265 if( ! ur_selIsAtom(sel) ) … … 295 315 { 296 316 ur_type(tos) = UT_WORD; 317 } 318 else if( ur_is(tos, UT_LITSELECT) ) 319 { 320 ur_type(tos) = UT_SELECT; 297 321 } 298 322 // else leave tos unchanged... … … 366 390 { 367 391 case UR_BIND_THREAD: 392 #ifdef UR_CONFIG_DATAFLOW 393 case UR_BIND_PLUG: // Each component has its own body for now. 394 #endif 368 395 // ur_blockPtr( pc->word.valBlk ) 369 396 blk = (((UBlock*) ut->blocks.arr.ptr.v) + pc->word.valBlk); … … 404 431 } 405 432 433 _throwUnsetF( ut, pc, "Invalid bind mask" ); 406 434 return 0; 435 } 436 437 438 static int ur_setWord( UThread* ut, const UCell* pc, const UCell* val ) 439 { 440 UBlock* blk; 441 UCell* dest; 442 int wrdN; 443 444 wrdN = pc->word.index; 445 if( wrdN < 0 ) 446 { 447 _throwUnbound( ut, pc); // UR_UNBOUND 448 return 0; 449 } 450 451 switch( pc->word.flags & UR_FLAG_BIND_MASK ) 452 { 453 case UR_BIND_THREAD: 454 // ur_blockPtr( pc->word.valBlk ) 455 blk = (((UBlock*) ut->blocks.arr.ptr.v) + pc->word.valBlk); 456 dest = blk->ptr.cells + wrdN; 457 break; 458 459 case UR_BIND_GLOBAL: 460 // ur_blockPtr( pc->word.valBlk ) 461 blk = (((UBlock*) ut->env->blocks.arr.ptr.v) - pc->word.valBlk); 462 dest = blk->ptr.cells + wrdN; 463 break; 464 465 case UR_BIND_LOCAL: 466 { 467 LocalFrame* it = UR_LF_BEG; 468 LocalFrame* end = UR_LF_END; 469 while( it != end ) 470 { 471 if( it->n == pc->word.wordBlk ) 472 { 473 dest = it->cell + wrdN; 474 goto set_word; 475 } 476 ++it; 477 } 478 _throwUnsetF( ut, pc, "out-of-scope local" ); 479 return 0; 480 } 481 482 #ifdef UR_CONFIG_DATAFLOW 483 case UR_BIND_PLUG: 484 // Assuming there are no global components. 485 ur_setPlug( ut, tBlockPtr(pc->word.valBlk), wrdN, val ); 486 return 1; 487 #endif 488 489 default: 490 _throwUnsetF( ut, pc, "Invalid bind mask" ); 491 return 0; 492 } 493 494 set_word: 495 496 ur_copyCell(dest, *val); 497 return 1; 407 498 } 408 499 … … 1378 1469 argc = varc = 0; 1379 1470 1380 sigN = scell->series.n;1381 1471 blk = ur_block( scell ); 1382 1472 it = blk->ptr.cells; … … 1633 1723 #ifdef UR_CONFIG_NET 1634 1724 extern void uc_net_addr( UThread*, UCell* ); 1725 #endif 1726 #ifdef UR_CONFIG_DATAFLOW 1727 #include "component.c" 1635 1728 #endif 1636 1729 … … 1667 1760 #endif 1668 1761 #ifdef LANG_THUNE 1762 #ifdef UR_CONFIG_DATAFLOW 1763 { uc_component, "component" }, 1764 { uc_connect, "connect" }, 1765 #endif 1669 1766 #ifdef UR_CONFIG_THREADS 1670 1767 { uc_thread, "thread" }, -
branches/thune/thread_safe/gc.c
r418 r426 285 285 case UT_CONTEXT: 286 286 case UT_PORT: 287 case UT_COMPONENT: 287 288 idx = it->ctx.wordBlk; 288 289 if( ur_isLocal(idx) ) -
branches/thune/thread_safe/gl/project.r
r423 r426 39 39 40 40 libs [%freetype %bz2 %png] 41 libs [%vorbis %vorbisfile] 41 42 ] 42 43 linux [ -
branches/thune/thread_safe/internal.h
r408 r426 17 17 //#define BLK_DSTACK 4 18 18 19 enum ComponentContextValues 20 { 21 COMPONENT_SELF = 0, 22 COMPONENT_COUNTS, 23 COMPONENT_BODY, 24 COMPONENT_CELLS 25 }; 19 26 20 27 #define initGCArray(af) \ 21 28 (af)->freeCount = 0; \ 22 29 (af)->freeList = -2 30 31 32 /* Get block ptr from thread storage */ 33 #define tBlockPtr(n) (((UBlock*) ut->blocks.arr.ptr.v) + (n)) 34 #define tBlock(bc) tBlockPtr( bc->series.n ) 23 35 24 36 -
branches/thune/thread_safe/make.c
r417 r426 111 111 Size is the number of cells to reserve. Used is set to 0. 112 112 */ 113 UIndex ur_makeBlockT( UThread* ut, int size )113 UIndex ur_makeBlockT( UThread* ut, int size, UBlock** blkPtr ) 114 114 { 115 115 UBlock* ptr; … … 144 144 145 145 ur_arrayInit( ptr, sizeof(UCell), size ); 146 if( blkPtr ) 147 *blkPtr = ptr; 146 148 return ur_blockN( ptr ); 147 149 } … … 1342 1344 1343 1345 /*--------------------------------------------------------------------------*/ 1346 1347 1348 #ifdef UR_CONFG_DATAFLOW 1349 extern void ur_cloneComponent( UThread*, UCell* result, UCell* proto ); 1350 #endif 1344 1351 1345 1352 … … 1869 1876 #endif 1870 1877 1878 #ifdef UR_CONFG_DATAFLOW 1879 case UT_COMPONENT: 1880 if( ! ur_is(tos, UT_COMPONENT) ) 1881 goto error; 1882 ur_cloneComponent( ut, res, tos ); 1883 break; 1884 #endif 1871 1885 default: 1872 1886 if( ur_datatype(res) < UT_BI_COUNT ) -
branches/thune/thread_safe/print.c
r408 r426 291 291 else if( braceType == UT_PAREN ) 292 292 append1( '(', out ); 293 #ifdef UR_CONFIG_MARCOS 294 else if( braceType == UT_MACRO ) 295 append1( '<', out ); 296 #endif 293 297 294 298 if( it != end ) … … 322 326 else if( braceType == UT_PAREN ) 323 327 append1( ')', out ); 328 #ifdef UR_CONFIG_MARCOS 329 else if( braceType == UT_MACRO ) 330 append1( '>', out ); 331 #endif 324 332 } 325 333 … … 699 707 case UT_SELECT: 700 708 case UT_SETSELECT: 709 case UT_LITSELECT: 701 710 case UT_INT: 702 711 case UT_DECIMAL: … … 817 826 818 827 828 /* 829 Print words only - no ticks or colons. 830 */ 819 831 static void _selectToStr( UThread* ut, const UCell* val, UString* out ) 820 832 { … … 928 940 #endif 929 941 942 case UT_LITSELECT: 943 append1('\'', out); 944 // Fall through to UT_SELECT... 945 930 946 case UT_SELECT: 931 947 _selectToStr( ut, val, out ); … … 1160 1176 case UT_CONTEXT: 1161 1177 case UT_PORT: 1178 #ifdef UR_CONFIG_DATAFLOW 1179 case UT_COMPONENT: 1180 #endif 1162 1181 if( val->id.flags & UR_FLAG_CTX_RECURSION ) 1163 1182 { 1164 append( out, "?context?", 8);1183 append( out, "?context?", 9 ); 1165 1184 } 1166 1185 else … … 1284 1303 #endif 1285 1304 1305 #if 0 1306 #ifdef UR_CONFIG_DATAFLOW 1307 case UT_COMPONENT: 1308 { 1309 UBlock* wblk = ur_blockPtr( val->ctx.wordBlk ); 1310 UBlock* vblk = ur_blockPtr( val->ctx.valBlk ); 1311 UCell* it = wblk->ptr.cells + 2; 1312 UCell* end = it + wblk->used; 1313 UCell* vit = vblk->ptr.cells; 1314 1315 /* 1316 while( it != end ) 1317 { 1318 ++it; 1319 ++vit; 1320 } 1321 */ 1322 1323 ur_blockToStr( ut, out, 1324 vblk->ptr.cells + val->series.it, 1325 vblk->ptr.cells + blk->used, 1326 UT_BLOCK, depth ); 1327 append( out, " component", 10 ); 1328 } 1329 break; 1330 #endif 1331 #endif 1332 1286 1333 default: 1287 1334 if( ur_type(val) < UT_BI_COUNT ) -
branches/thune/thread_safe/read_config.r
r350 r426 12 12 trig: 13 13 math3d: 14 dataflow: 14 15 dt-code: 15 16 net: -
branches/thune/thread_safe/tests/working/bytecode.good
r365 r426 1 1 "nonecathello" 2 #{0400000400041 300070D000000190E3F800000030103000C61}2 #{0400000400041400070E000000190F3F800000030103000D61} -
branches/thune/thread_safe/tests/working/bytecode.t
r408 r426 29 29 nop ; 8 - select 30 30 nop ; 9 - set-select 31 nop ;10 - opcode 32 nop ;11 - hash-id 33 [val int! as emit8] ;12 - char 34 [val emit32] ;13 - int 35 [val emitf] ;14 - decimal 36 nop ;15 - bignum 37 nop ;16 - coord 38 nop ;17 - vec3 39 nop ;18 - binary 40 [val add-word emit16] ;19 - string 41 [val add-word emit16] ;20 - block 42 nop ;21 - paren 43 nop ;23 - macro 44 nop ;23 - path 45 nop ;24 - setpath 46 nop ;25 - slice 47 nop ;26 - array 48 nop ;27 - bitset 49 nop ;28 - list 50 nop ;29 - context 51 nop ;30 - function 52 nop ;31 - call 53 nop ;32 - date 54 nop ;33 - time 55 nop ;34 - bitset 56 nop ;35 - error 57 nop ;36 - code 58 nop ;37 - port 59 nop ;38 - struct 31 nop ;10 - lit-select 32 nop ;11 - opcode 33 nop ;12 - hash-id 34 [val int! as emit8] ;13 - char 35 [val emit32] ;14 - int 36 [val emitf] ;15 - decimal 37 nop ;16 - bignum 38 nop ;17 - coord 39 nop ;18 - vec3 40 nop ;19 - binary 41 [val add-word emit16] ;20 - string 42 [val add-word emit16] ;21 - block 43 nop ;22 - paren 44 nop ;24 - macro 45 nop ;24 - path 46 nop ;25 - setpath 47 nop ;26 - slice 48 nop ;27 - array 49 nop ;28 - bitset 50 nop ;29 - list 51 nop ;30 - context 52 nop ;31 - function 53 nop ;32 - call 54 nop ;33 - date 55 nop ;34 - time 56 nop ;35 - bitset 57 nop ;36 - error 58 nop ;37 - code 59 nop ;38 - port 60 nop ;39 - struct 60 61 ] :type-convert 61 62 -
branches/thune/thread_safe/thune.c
r415 r426 379 379 UR_S_PUSH( *val ); 380 380 ur_type( UR_TOS ) = UT_WORD; 381 break; 382 383 case UT_LITSELECT: 384 if( UR_TOS >= ut->eos ) 385 goto stack_overflow; 386 UR_S_PUSH( *val ); 387 ur_type( UR_TOS ) = UT_SELECT; 381 388 break; 382 389 … … 822 829 823 830 case UT_SETWORD: 824 val = ur_wordCell( ut, val ); 825 if( ! val ) 831 if( ! ur_setWord( ut, val, UR_TOS ) ) 826 832 goto throw_cc; 827 ur_copyCell(val, *UR_TOS);828 833 UR_S_DROP; 829 834 break; -
branches/thune/thread_safe/tokenize.c
r408 r426 539 539 } 540 540 541 mode = UT_LITWORD; 542 541 543 SCAN_LOOP 542 if( ur_bitIsSet( charset_delimiters, ch ) ) // '[' 'word[] 544 if( ch == '/' ) 545 { 546 mode = UT_LITSELECT; 547 } 548 else if( ur_bitIsSet( charset_delimiters, ch ) ) // '[' 'word[] 549 { 543 550 break; 551 } 544 552 SCAN_END 545 553 … … 549 557 if( it == token ) 550 558 goto quote_err; 551 cell = ur_appendWord( BLOCK, UT_LITWORD, token, it - token ); 559 if( mode == UT_LITWORD ) 560 { 561 cell = ur_appendWord( BLOCK, UT_LITWORD, token, it - token ); 562 } 563 else 564 { 565 cell = ur_appendCell( BLOCK, UT_UNSET ); 566 if( ! ur_makeSelector( ut, cell, token, it ) ) 567 { 568 syntaxError( "Invalid lit-select" ); 569 } 570 ur_type(cell) = UT_LITSELECT;
