Changeset 408 for branches/thune/thread_safe/tokenize.c
- Timestamp:
- 06/11/07 04:07:02 (18 months ago)
- Files:
-
- 1 modified
-
branches/thune/thread_safe/tokenize.c (modified) (11 diffs)
Legend:
- Unmodified
- Added
- Removed
-
branches/thune/thread_safe/tokenize.c
r390 r408 204 204 205 205 206 /* 207 #if UR_CONFIG_MATH3D 208 static int isVec3( const char* cp, int len ) 206 #ifdef UR_CONFIG_MACROS 207 extern void ur_infuseOpcodes( UThread*, UIndex ); 208 209 //#define MACRO_CONTEXT 1 210 #ifdef MACRO_CONTEXT 211 extern UContext ur_global; 212 213 static void _pushMacroContext( UThread* ut ) 209 214 { 210 if( len < 3 ) 211 return 0; 212 if( *cp == '-' ) 213 ++cp; 214 if( *cp < '0' || *cp > '9' ) 215 return 0; 216 return 1; 217 } 218 219 220 static void assignVec3( float* vec, const char* start, int len ) 221 { 222 int ch; 223 const char* pos; 224 const char* end = start + len; 225 226 *vec++ = (float) ur_stringToDec( start, end, &pos ); 227 while( pos != end ) 228 { 229 ch = *pos; 230 if( ! ur_bitIsSet(charset_white, ch) ) 231 break; 232 ++pos; 233 } 234 *vec++ = (float) ur_stringToDec( pos, end, &pos ); 235 while( pos != end ) 236 { 237 ch = *pos; 238 if( ! ur_bitIsSet(charset_white, ch) ) 239 break; 240 ++pos; 241 } 242 *vec = (float) ur_stringToDec( pos, end, &pos ); 215 UBlock* blk; 216 UCell* mc; 217 int wrdN; 218 219 wrdN = ur_internWord( &ur_global, UR_ATOM_READER_MACROS ); 220 blk = ur_blockPtr( ur_global.ctx.valBlk ); 221 mc = blk->ptr.cells + wrdN; 222 if( ! ur_is(mc, UT_CONTEXT) ) 223 ur_makeContext( mc, 0 ); 224 ur_pushContext( ut, mc ); 243 225 } 244 226 #endif 245 */246 247 248 #ifdef UR_CONFIG_MACROS249 struct TokenizeCallInfo250 {251 int valueLimit;252 const char* finalInputPos;253 };254 255 256 static int _evalMacro( UThread* ut, UBlock* blk, UCell* mval,257 const char** pin, const char* end )258 {259 UCell* cell;260 261 if( ur_is(mval, UT_FUNCTION) )262 {263 if( mval->func.localArgs )264 {265 UIndex tblkN;266 UBlock* callBlk;267 UCell* otos;268 int ok;269 struct TokenizeCallInfo tci;270 271 tci.valueLimit = mval->func.localArgs;272 tci.finalInputPos = 0;273 274 tblkN = ur_tokenize( ut, *pin, end, &tci );275 *pin = tci.finalInputPos;276 277 callBlk = ur_blockPtr( tblkN );278 UR_EXPAND_1( UCell, callBlk, cell );279 ur_copyCell(cell, *mval);280 otos = UR_TOS;281 ok = ur_eval( ut, tblkN, 0 );282 if( ok != UR_EVAL_OK )283 return 0;284 if( UR_TOS == otos )285 return 1;286 mval = ur_result( ut, 1 );287 }288 }289 290 if( ur_is(mval, UT_BLOCK) )291 {292 // Join blocks (share code with uc_join?).293 UBlock* s2 = ur_block(mval);294 int srcLen = s2->used - mval->series.it;295 296 ur_arrayReserve( blk, sizeof(UCell), blk->used + srcLen );297 298 ur_copyCells( s2->ptr.cells + mval->series.it,299 s2->ptr.cells + s2->used,300 blk->ptr.cells + blk->used );301 blk->used += srcLen;302 }303 else304 {305 UR_EXPAND_1( UCell, blk, cell );306 ur_copyCell( cell, *mval );307 }308 return 1;309 }310 311 312 static UCell* _macro( UBlock* macroStack, const char* a, const char* b )313 {314 int wrdN;315 UCell* top = macroStack->ptr.cells + macroStack->used;316 UAtom atom = ur_intern( a, b - a );317 318 while( top != macroStack->ptr.cells )319 {320 wrdN = ur_lookup( --top, atom );321 if( wrdN > -1 )322 {323 return ur_blockPtr( top->ctx.valBlk )->ptr.cells + wrdN;324 }325 }326 327 return 0;328 }329 227 #endif 330 228 … … 341 239 ur_throwErr( UR_ERR_SYNTAX, "%s (line %d)", msg, lines + 1 ); \ 342 240 goto error 241 242 243 /* 244 Returns zero if end reached. 245 */ 246 static const char* blockComment( const char* it, const char* end, int* lines ) 247 { 248 int ch, tn, mode; 249 int lineCount = 0; 250 251 mode = 0; 252 tn = 0; 253 254 SCAN_LOOP 255 if( ch == '\n' ) 256 { 257 ++lineCount; 258 mode = 0; 259 } 260 else 261 { 262 switch( mode ) 263 { 264 case 0: 265 if( ch == '*' ) 266 mode = 1; 267 else if( ch == '/' ) 268 mode = 2; 269 break; 270 271 case 1: 272 if( ch == '/' ) 273 { 274 if( tn == 0 ) 275 { 276 *lines += lineCount; 277 return ++it; 278 } 279 --tn; 280 } 281 mode = 0; 282 break; 283 284 case 2: 285 if( ch == '*' ) 286 ++tn; 287 mode = 0; 288 break; 289 } 290 } 291 SCAN_END 292 293 *lines += lineCount; 294 return 0; 295 } 343 296 344 297 … … 359 312 int lines = 0; 360 313 #ifdef UR_CONFIG_MACROS 361 #define TCI ((struct TokenizeCallInfo*) tci) 362 UBlock* macroStack; 363 int valueLimit; 364 365 cell = ur_resolvePath( UR_ATOM_SCRIPT_ENV, 366 UT_WORD, UR_ATOM_READER_MACROS, 367 UT_NONE ); 368 macroStack = cell ? ur_block(cell) : 0; 369 valueLimit = tci ? TCI->valueLimit : 0; 370 #else 314 int macroNest = 0; 315 #endif 316 371 317 (void) tci; 372 #endif373 318 374 319 … … 448 393 case '[': 449 394 case '(': 395 case '<': 450 396 ur_arrayReserve( &stack, sizeof(UIndex), stack.used+1 ); 451 397 STACK[ stack.used ] = ur_makeBlock( 0 ); 452 398 453 cell = ur_appendCell( BLOCK, 454 (ch == '[') ? UT_BLOCK : UT_PAREN ); 399 switch( ch ) 400 { 401 case '[': mode = UT_BLOCK; break; 402 case '(': mode = UT_PAREN; break; 403 case '<': mode = UT_MACRO; 404 #ifdef UR_CONFIG_MACROS 405 #ifdef MACRO_CONTEXT 406 if( ! macroNest ) 407 _pushMacroContext( ut ); 408 #endif 409 ++macroNest; 410 #endif 411 break; 412 } 413 414 cell = ur_appendCell( BLOCK, mode ); 455 415 ur_setSeries( cell, STACK[ stack.used ], 0 ); 456 416 … … 465 425 case ']': 466 426 case ')': 427 case '>': 467 428 if( stack.used == 1 ) 468 429 { 469 syntaxError( "End of block found without '['" ); 430 ur_throwErr( UR_ERR_SYNTAX, 431 "End of block '%c' has no opening match (line %d)", 432 ch, lines + 1 ); 433 goto error; 470 434 } 471 435 --stack.used; 472 436 if( eol ) 437 eol = 0; 438 #ifdef UR_CONFIG_MACROS 439 if( ch == '>' && macroNest ) 473 440 { 474 /* 475 UBlock* blk = ur_blockPtr( STACK[ stack.used - 1 ] ); 476 cell = blk->ptr.cells + blk->used - 1; 477 cell->id.flags |= UR_FLAG_BLOCK_EOL; 478 */ 479 eol = 0; 441 UCell* otos; 442 UBlock* blk; 443 444 otos = UR_TOS; 445 ur_infuseOpcodes( ut, STACK[ stack.used ] ); 446 tn = ur_eval( ut, STACK[ stack.used ], 0 ); 447 if( tn == UR_EVAL_ERROR ) 448 { 449 UR_CALL_OP = OP_THROW; 450 goto error; 451 } 452 453 blk = ur_blockPtr( STACK[stack.used - 1] ); 454 --blk->used; // Remove macro. 455 456 if( UR_TOS != otos ) 457 { 458 // Append reduced macro to current block. 459 tn = UR_TOS - otos; 460 UR_TOS = otos; 461 ++otos; 462 463 ur_arrayReserve( blk, sizeof(UCell), 464 blk->used + tn ); 465 ur_copyCells( otos, otos + tn, 466 blk->ptr.cells + blk->used ); 467 blk->used += tn; 468 } 469 470 #ifdef MACRO_CONTEXT 471 if( macroNest == 1 ) 472 ur_popContext( ut ); 473 #endif 474 --macroNest; 480 475 } 481 #ifdef UR_CONFIG_MACROS 482 ++it; 483 goto check_final; 484 #else 476 #endif 485 477 break; 486 #endif487 478 } 488 479 } … … 498 489 eol = 0; 499 490 } 500 #ifdef UR_CONFIG_MACROS501 check_final:502 if( valueLimit && (stack.used == 1) )503 {504 if( --valueLimit == 0 )505 {506 TCI->finalInputPos = it;507 goto finish;508 }509 }510 #endif511 491 goto start; 512 492 … … 544 524 //block_comment 545 525 546 mode = 0; 547 tn = 0; 548 549 SCAN_LOOP 550 if( ch == '\n' ) 551 { 552 ++lines; 553 mode = 0; 554 } 555 else 556 { 557 switch( mode ) 558 { 559 case 0: 560 if( ch == '*' ) 561 mode = 1; 562 else if( ch == '/' ) 563 mode = 2; 564 break; 565 566 case 1: 567 if( ch == '/' ) 568 { 569 if( tn == 0 ) 570 { 571 ++it; 572 goto start; 573 } 574 --tn; 575 } 576 mode = 0; 577 break; 578 579 case 2: 580 if( ch == '*' ) 581 ++tn; 582 mode = 0; 583 break; 584 } 585 } 586 SCAN_END 526 it = blockComment( it, end, &lines ); 527 if( it ) 528 goto start; 587 529 goto finish; 588 530 … … 707 649 } 708 650 word_append: 709 #ifdef UR_CONFIG_MACROS710 if( macroStack && mode == UT_WORD )711 {712 cell = _macro( macroStack, token, it );713 if( cell )714 {715 if( _evalMacro( ut, BLOCK, cell, &it, end ) )716 goto start;717 syntaxError( "Macro evaluation failed" );718 }719 }720 #endif721 651 if( it == token ) 722 652 goto word_err; … … 909 839 else if( *it == '[' ) 910 840 { 841 // TODO: Handle macros in vector!. 911 842 int inNum = 0; 912 843 UArray* arr; … … 994 925 goto array_white; 995 926 } 927 else if( ch == '/' ) 928 { 929 ++it; 930 if( it == end ) 931 goto bad_array; 932 if( *it != '*' ) 933 goto bad_array; 934 it = blockComment( ++it, end, &lines ); 935 if( it ) 936 goto array_white; 937 goto finish; 938 } 996 939 else 997 940 { … … 999 942 } 1000 943 SCAN_END 1001 944 bad_array: 1002 945 syntaxError( "Invalid array" ); 1003 946 }
