source: libcfa/src/enum.cfa@ 88bc876

Last change on this file since 88bc876 was d796be70, checked in by Peter A. Buhr <pabuhr@…>, 17 months ago

commenting

  • Property mode set to 100644
File size: 3.9 KB
RevLine 
[c333ed2]1#include "enum.hfa"
[85855b0]2#include "fstream.hfa"
[6d2b3dc]3#include <string.h>
[c333ed2]4
[03ac869]5#pragma GCC visibility push(default)
6
[0c327ce]7forall( E | Serial( E ) ) {
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
[2e6b2a0]12 if ( i < fromInstance( lower ) || i > fromInstance( upper ) )
13 abort( "call to fromInt has index %d outside enumeration range %d-%d",
14 i, fromInstance( lower ), fromInstance( upper ) );
[0c327ce]15 return fromInt_unsafe( i );
16 }
17
18 E succ( E e ) {
19 E upper = upperBound();
[2e6b2a0]20 if ( fromInstance( e ) >= fromInstance( upper ) )
21 abort( "call to succ() exceeds enumeration upper bound of %d", fromInstance( upper ) );
[0c327ce]22 return succ_unsafe(e);
23 }
24
25 E pred( E e ) {
26 E lower = lowerBound();
[2e6b2a0]27 if ( fromInstance(e) <= fromInstance(lower ) )
28 abort( "call to pred() exceeds enumeration lower bound of %d", fromInstance( lower ) );
[0c327ce]29 return pred_unsafe(e);
30 }
31
32 int Countof( __attribute__((unused)) E e ) {
33 E upper = upperBound();
34 E lower = lowerBound();
35 return fromInstance( upper ) + fromInstance( lower ) + 1;
36 }
37}
38
[236f133]39forall( istype & | istream( istype ), E | CfaEnum( E ) )
[64eeb06]40istype & ?|?( istype & is, E & e ) {
[2e6b2a0]41// fprintf( stderr, "here0\n" );
[64eeb06]42 if ( eof( is ) ) throwResume ExceptionInst( missing_data );
[d287f3e]43
[d796be70]44 // Match longest input enumerator string to enumerator labels, where enumerator names are unique.
45
[2e6b2a0]46 int N = Countof( e ), lnths[N], max = 0;
47// printf( "N %d\n", N );
48// for ( s; E : i; 0~@ ) {
[d287f3e]49 int i = 0;
50 for ( s; E ) {
[2e6b2a0]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 );
[d287f3e]54 i += 1;
[6d2b3dc]55 } // for
[d287f3e]56
[2e6b2a0]57 int win = -1;
58 char ch, curr = '\0', prev = '\0';
59
60 fmt( is, " " ); // skip optional whitespace
61 for ( c; max ) {
62 int args = fmt( is, "%c", &ch ); // read character
[d796be70]63 if ( eof( is ) ) {
[2e6b2a0]64// fprintf( stderr, "Eof1\n" );
65 if ( c == 0 ) return is; // no characters read ?
[d796be70]66 clear( is ); // => read something => reset EOF => detect again on next read
[2e6b2a0]67// fprintf( stderr, "Eof2\n" );
[d796be70]68 break;
69 } // if
[2e6b2a0]70 if ( args != 1 ) throwResume ExceptionInst( missing_data );
[d796be70]71
[2e6b2a0]72// printf( "read '%c'\n", ch );
[d796be70]73 for ( i; N ) { // scan enumeration strings for winner
[2e6b2a0]74// 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]; // optimization
77// printf( "%c '%c'\n", match, ch );
[d796be70]78 // Stop on first match, could be other matches.
[2e6b2a0]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;
84 break;
85 } // if
86 } // if
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 work
92 } // for
93// printf( "\n" );
94// } else {
95// fprintf( stderr, "finished2 %d\n", win );
96 } // for
[d796be70]97 W: ;
98 for ( i; N ) { // scan enumeration strings for winner
[2e6b2a0]99 if ( win == lnths[i] - 1 ) {
100 char match = label( fromInt( i ) )[win]; // optimization
101// 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 );
104 break;
[d796be70]105 } // if
[2e6b2a0]106 } // if
107 } else {
108// fprintf( stderr, "finished3 %d\n", win );
109 throwResume ExceptionInst( missing_data );
110 } // for
[64eeb06]111 return is;
112}
113
[236f133]114forall( ostype & | ostream( ostype ), E | CfaEnum( E ) ) {
[64eeb06]115 ostype & ?|?( ostype & os, E e ) {
116 return os | label( e );
117 }
118 OSTYPE_VOID_IMPL( E )
[259012e]119}
Note: See TracBrowser for help on using the repository browser.