- Timestamp:
- Jul 17, 2024, 11:37:18 AM (5 months ago)
- Branches:
- master
- Children:
- a758169
- Parents:
- 97f9619
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/enum.cfa
r97f9619 r0097d08 6 6 7 7 forall( E | Serial( E ) ) { 8 9 10 11 8 E fromInt( unsigned i ) { 9 E upper = upperBound(); 10 E lower = lowerBound(); 11 // It is okay to overflow as overflow will be theoretically caught by the other bound 12 12 if ( i < fromInstance( lower ) || i > fromInstance( upper ) ) 13 13 abort( "call to fromInt has index %d outside enumeration range %d-%d", 14 14 i, fromInstance( lower ), fromInstance( upper ) ); 15 16 15 return fromInt_unsafe( i ); 16 } 17 17 18 19 18 E succ( E e ) { 19 E upper = upperBound(); 20 20 if ( fromInstance( e ) >= fromInstance( upper ) ) 21 21 abort( "call to succ() exceeds enumeration upper bound of %d", fromInstance( upper ) ); 22 23 22 return succ_unsafe(e); 23 } 24 24 25 26 25 E pred( E e ) { 26 E lower = lowerBound(); 27 27 if ( fromInstance(e) <= fromInstance(lower ) ) 28 28 abort( "call to pred() exceeds enumeration lower bound of %d", fromInstance( lower ) ); 29 30 29 return pred_unsafe(e); 30 } 31 31 32 33 34 32 int Countof( __attribute__((unused)) E e ) { 33 E upper = upperBound(); 34 E lower = lowerBound(); 35 35 return fromInstance( upper ) + fromInstance( lower ) + 1; 36 36 } 37 37 } 38 38 39 forall( istype & | istream( istype ), E | CfaEnum( E ) | Serial(E) )39 forall( istype & | istream( istype ), E | CfaEnum( E ) | Serial( E ) ) 40 40 istype & ?|?( istype & is, E & e ) { 41 41 // fprintf( stderr, "here0\n" ); … … 44 44 // Match longest input enumerator string to enumerator labels, where enumerator names are unique. 45 45 46 int N = Countof( e), lnths[N], max = 0;46 int N = countof( E ), lnths[N], max = 0; 47 47 // printf( "N %d\n", N ); 48 // for ( s; E : i; 0~@ ) { 49 int i = 0; 50 for ( s; E ) { 51 lnths[ i] = strlen( label( s ) );52 if ( lnths[ i] > max ) max = lnths[i];53 // fprintf( stderr, "%s %d %d\n", label( s ), lnths[ i], max );54 i+= 1;48 int r = 0; 49 // for ( s; E : r; 0~@ ) { 50 for ( s; E ) { // scan string rows gathering lengths 51 lnths[r] = strlen( label( s ) ); 52 if ( lnths[r] > max ) max = lnths[r]; 53 // fprintf( stderr, "%s %d %d\n", label( s ), lnths[r], max ); 54 r += 1; 55 55 } // for 56 56 57 int win = -1;57 int mcol = -1; // last match column 58 58 char ch, curr = '\0', prev = '\0'; 59 59 60 60 fmt( is, " " ); // skip optional whitespace 61 for ( c; max ) { 61 for ( c; max ) { // scan columns of the label matix (some columns missing) 62 62 int args = fmt( is, "%c", &ch ); // read character 63 63 if ( eof( is ) ) { … … 68 68 break; 69 69 } // if 70 if ( args != 1 ) throwResume ExceptionInst( missing_data );70 if ( args != 1 ) throwResume ExceptionInst( missing_data ); // may be unnecessary since reading single character 71 71 72 72 // printf( "read '%c'\n", ch ); 73 for ( i; N ) { // scan enumeration strings for winner74 // printf( "%d %d %d\n", c, i, lnths[i] );75 if ( c < lnths[ i] ) { // eligible for this checking round?76 char match = label( fromInt( i) )[c]; // optimization73 for ( r; N ) { // scan enumeration strings for matching character in current column 74 // printf( "%d %d %d\n", c, r, lnths[r] ); 75 if ( c < lnths[r] ) { // string long enough for this column check ? 76 char match = label( fromInt( r ) )[c]; // optimization 77 77 // printf( "%c '%c'\n", match, ch ); 78 78 // Stop on first match, could be other matches. 79 if ( (match == ch) && (c == 0 || curr == label( fromInt( i) )[c - 1]) ) {80 // printf( "match %d %d %d '%c' '%c' '%c' '%c' 'c'\n", c, i, lnths[i], match, ch, prev, label( fromInt( i) )[c - 1] );81 win = c;82 prev = curr; 83 curr = ch; 79 if ( (match == ch) && (c == 0 || curr == label( fromInt( r ) )[c - 1]) ) { 80 // printf( "match %d %d %d '%c' '%c' '%c' '%c' 'c'\n", c, r, lnths[r], match, ch, prev, label( fromInt( r ) )[c - 1] ); 81 mcol = c; // matching column 82 prev = curr; // last matching character 83 curr = ch; // current matching character 84 84 break; 85 85 } // if 86 86 } // if 87 87 } else { 88 // fprintf( stderr, "finished win: %d ch: '%c' curr: '%c' prev: '%c'\n", win, ch, curr, prev );89 ungetc( ch, is ); 90 if ( win == -1 ) throwResume ExceptionInst( missing_data );91 goto W; // break does not work88 // fprintf( stderr, "finished mcol: %d ch: '%c' curr: '%c' prev: '%c'\n", mcol, ch, curr, prev ); 89 ungetc( ch, is ); // push back last unmatching character 90 if ( mcol == -1 ) throwResume ExceptionInst( missing_data ); // no matching character in first column 91 break; 92 92 } // for 93 93 // printf( "\n" ); 94 94 // } else { 95 // fprintf( stderr, "finished2 %d\n", win);95 // fprintf( stderr, "finished2 %d\n", mcol ); 96 96 } // for 97 W: ; 98 for ( i; N ) { // scan enumeration strings for winner99 if ( win == lnths[i] - 1 ) {100 char match = label( fromInt( i ) )[win]; // optimization101 // printf( "finished1 win: %d i: %d lnth: %d match: '%c' curr: '%c' prev: '%c'\n", win, i, lnths[i], match, curr, prev );102 if ( (match == curr) && ( win == 0 || prev == label( fromInt( i ) )[win- 1]) ) {103 e = fromInt( i);97 98 for ( c; N ) { // scan enumeration strings of length "mcol" for match 99 if ( mcol == lnths[c] - 1 ) { 100 char match = label( fromInt( c ) )[mcol]; // optimization 101 // printf( "finished1 mcol: %d c: %d lnth: %d match: '%c' curr: '%c' prev: '%c'\n", mcol, c, lnths[c], match, curr, prev ); 102 if ( (match == curr) && (mcol == 0 || prev == label( fromInt( c ) )[mcol - 1]) ) { 103 e = fromInt( c ); 104 104 break; 105 105 } // if 106 106 } // if 107 107 } else { 108 // fprintf( stderr, "finished3 %d\n", win);109 throwResume ExceptionInst( missing_data ); 108 // fprintf( stderr, "finished3 %d\n", mcol ); 109 throwResume ExceptionInst( missing_data ); // no match in this column 110 110 } // for 111 111 return is;
Note: See TracChangeset
for help on using the changeset viewer.