source: libcfa/src/enum.cfa @ b2ca052

Last change on this file since b2ca052 was 2e6b2a0, checked in by Peter A. Buhr <pabuhr@…>, 4 months ago

change assert to abort, second attempt to read enumerators

  • Property mode set to 100644
File size: 3.7 KB
Line 
1#include "enum.hfa"
2#include "fstream.hfa"
3#include <string.h>
4
5#pragma GCC visibility push(default)
6
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
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 ) );
15        return fromInt_unsafe( i );
16    }
17
18    E succ( E e ) {
19        E upper = upperBound();
20                if ( fromInstance( e ) >= fromInstance( upper ) )
21                        abort( "call to succ() exceeds enumeration upper bound of %d", fromInstance( upper ) );
22        return succ_unsafe(e);
23    }
24
25    E pred( E e ) {
26        E lower = lowerBound();
27                if ( fromInstance(e) <= fromInstance(lower ) )
28                        abort( "call to pred() exceeds enumeration lower bound of %d", fromInstance( lower ) );
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
39forall( istype & | istream( istype ), E | CfaEnum( E ) )
40istype & ?|?( istype & is, E & e ) {
41//      fprintf( stderr, "here0\n" );
42        if ( eof( is ) ) throwResume ExceptionInst( missing_data );
43
44        // Match input enumerator string to enumerator labels.
45        int N = Countof( e ), lnths[N], max = 0;
46//      printf( "N %d\n", N );
47//      for ( s; E : i; 0~@ ) {
48        int i = 0;
49        for ( s; E ) {
50                lnths[i] = strlen( label( s ) );
51                if ( lnths[i] > max ) max = lnths[i];
52//              fprintf( stderr, "%s %d %d\n", label( s ), lnths[i], max );
53                i += 1;
54        } // for
55
56        int win = -1;
57        char ch, curr = '\0', prev = '\0';
58
59        fmt( is, " " );                                                                         // skip optional whitespace
60        for ( c; max ) {
61                int args = fmt( is, "%c", &ch );                                // read character
62                if ( eof( is ) ) {
63//                      fprintf( stderr, "Eof1\n" );
64                        if ( c == 0 ) return is;                                        // no characters read ?
65                        clear( is );                                                            // => reset EOF => detect again on next read
66//                      fprintf( stderr, "Eof2\n" );
67                        goto W;
68                }
69                if ( args != 1 ) throwResume ExceptionInst( missing_data );
70//              printf( "read '%c'\n", ch );
71                for ( i; N ) {
72//                      printf( "%d %d %d\n", c, i, lnths[i] );
73                        if ( c < lnths[i] ) {                                           // eligible for this checking round ?
74                                char match = label( fromInt( i ) )[c];  // optimization
75//                              printf( "%c '%c'\n", match, ch );
76                                if ( (match == ch) && (c == 0 || curr == label( fromInt( i ) )[c - 1]) ) {
77//                                      printf( "match %d %d %d '%c' '%c' '%c' '%c' 'c'\n", c, i, lnths[i], match, ch, prev, label( fromInt( i ) )[c - 1] );
78                                        win = c;
79                                        prev = curr;
80                                        curr = ch;
81                                        break;
82                                } // if
83                        } // if
84                } else {
85//                      fprintf( stderr, "finished win: %d ch: '%c' curr: '%c' prev: '%c'\n", win, ch, curr, prev );
86                        ungetc( ch, is );
87                        if ( win == -1 ) throwResume ExceptionInst( missing_data );
88                        goto W;                                                                         // break does not work
89                } // for
90//              printf( "\n" );
91//      } else {
92//              fprintf( stderr, "finished2 %d\n", win );
93        } // for
94  W :;
95        for ( i; N ) {                                                                          // scan for winner, must succeed
96                if ( win == lnths[i] - 1 ) {
97                        char match = label( fromInt( i ) )[win];        // optimization
98//                      printf( "finished1 win: %d i: %d lnth: %d match: '%c' curr: '%c' prev: '%c'\n", win, i, lnths[i], match, curr, prev );
99                        if ( (match == curr) && (win == 0 || prev == label( fromInt( i ) )[win - 1]) ) {
100                                e = fromInt( i );
101                                break;
102                        }
103                } // if
104        } else {
105//              fprintf( stderr, "finished3 %d\n", win );
106                throwResume ExceptionInst( missing_data );
107        } // for
108        return is;
109}
110
111forall( ostype & | ostream( ostype ), E | CfaEnum( E ) ) {
112        ostype & ?|?( ostype & os, E e ) {
113                return os | label( e );
114        }
115        OSTYPE_VOID_IMPL( E )
116}
Note: See TracBrowser for help on using the repository browser.