source: libcfa/src/enum.cfa@ b24cbaf

Last change on this file since b24cbaf was 3ac5fd8, checked in by Peter A. Buhr <pabuhr@…>, 13 months ago

first attempt changing end-of-file to an exception

  • Property mode set to 100644
File size: 4.3 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( int 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 of 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( 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 ) | Serial( E ) )
40istype & ?|?( istype & is, E & e ) {
41// fprintf( stderr, "here0\n" );
42 if ( eof( is ) ) throwResume ExceptionInst( end_of_file );
43
44 // Match longest input enumerator string to enumerator labels, where enumerator names are unique.
45
46 int N = countof( E ), lnths[N], max = 0;
47// printf( "N %d\n", N );
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 } // for
56
57 int mcol = -1; // last match column
58 char ch, curr = '\0', prev = '\0';
59
60 fmt( is, " " ); // skip optional whitespace
61 if ( eof( is ) ) throwResume ExceptionInst( end_of_file );
62
63 for ( c; max ) { // scan columns of the label matix (some columns missing)
64 int args = fmt( is, "%c", &ch ); // read character
65// fprintf( stderr, "fmt args: %d eof: %d\n", args, eof(is) );
66 if ( eof( is ) ) {
67// fprintf( stderr, "Eof1\n" );
68 if ( c == 0 ) return is; // no characters read ?
69 clear( is ); // => read something => reset EOF => detect again on next read
70// fprintf( stderr, "Eof2\n" );
71 break;
72 } // if
73 if ( args != 1 ) throwResume ExceptionInst( missing_data ); // may be unnecessary since reading single character
74
75// printf( "read '%c'\n", ch );
76 for ( r; N ) { // scan enumeration strings for matching character in current column
77// printf( "%d %d %d\n", c, r, lnths[r] );
78 if ( c < lnths[r] ) { // string long enough for this column check ?
79 char match = label( fromInt( r ) )[c]; // optimization
80// printf( "%c '%c'\n", match, ch );
81 // Stop on first match, could be other matches.
82 if ( (match == ch) && (c == 0 || curr == label( fromInt( r ) )[c - 1]) ) {
83// printf( "match %d %d %d '%c' '%c' '%c' '%c' 'c'\n", c, r, lnths[r], match, ch, prev, label( fromInt( r ) )[c - 1] );
84 mcol = c; // matching column
85 prev = curr; // last matching character
86 curr = ch; // current matching character
87 break;
88 } // if
89 } // if
90 } else {
91// fprintf( stderr, "finished mcol: %d ch: '%c' curr: '%c' prev: '%c'\n", mcol, ch, curr, prev );
92 ungetc( ch, is ); // push back last unmatching character
93 if ( mcol == -1 ) throwResume ExceptionInst( missing_data ); // no matching character in first column
94 break;
95 } // for
96// printf( "\n" );
97// } else {
98// fprintf( stderr, "finished2 %d\n", mcol );
99 } // for
100
101 for ( c; N ) { // scan enumeration strings of length "mcol" for match
102 if ( mcol == lnths[c] - 1 ) {
103 char match = label( fromInt( c ) )[mcol]; // optimization
104// printf( "finished1 mcol: %d c: %d lnth: %d match: '%c' curr: '%c' prev: '%c'\n", mcol, c, lnths[c], match, curr, prev );
105 if ( (match == curr) && (mcol == 0 || prev == label( fromInt( c ) )[mcol - 1]) ) {
106 e = fromInt( c );
107 break;
108 } // if
109 } // if
110 } else {
111// fprintf( stderr, "finished3 %d\n", mcol );
112 throwResume ExceptionInst( missing_data ); // no match in this column
113 } // for
114 return is;
115}
116
117forall( ostype & | ostream( ostype ), E | CfaEnum( E ) ) {
118 ostype & ?|?( ostype & os, E e ) {
119 return os | label( e );
120 }
121 OSTYPE_VOID_IMPL( os, E )
122}
Note: See TracBrowser for help on using the repository browser.