source: libcfa/src/enum.cfa @ 0c327ce

Last change on this file since 0c327ce was 0c327ce, checked in by JiadaL <j82liang@…>, 3 months ago
  1. Add bound check to Serial function: now compiler generates the unchecked functions in ImplementEnumFunc?, and enum.hfa implements the bound check on top. Todo: Wrapped the checked version into a trait; 2. countof is now works on any type that implement Countof(). Because Countof() is implemented in enum.hfa for all CfaEnum?, we can call countof on { T | CfaEnum?(T) }
  • Property mode set to 100644
File size: 3.2 KB
Line 
1#include "enum.hfa"
2#include "fstream.hfa"
3#include <stdlib.h>                                                                             // qsort
4#include <string.h>
5
6#pragma GCC visibility push(default)
7
8forall( E | Serial( E ) ) {
9    E fromInt( unsigned i ) {
10        E upper = upperBound();
11        E lower = lowerBound();
12        // It is okay to overflow as overflow will be theoretically caught by the other bound
13        assert( i <= fromInstance(upper) && i >= fromInstance(lower)
14            &&  "Not a valid value");
15        return fromInt_unsafe( i );
16    }
17
18    E succ( E e ) {
19        E upper = upperBound();
20        assert( (fromInstance(e) < fromInstance(upper))
21            && "Calling succ() on the last" );
22        return succ_unsafe(e);
23    }
24
25    E pred( E e ) {
26        E lower = lowerBound();
27        assert( (fromInstance(e) > fromInstance(lower))
28            && "Calling pred() on the first" );
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
39int scmp( const void * str1, const void * str2 ) {
40    return -strcmp( *(char **)str1, *(char **)str2 );   // dscending order
41} // scmp
42
43forall( istype & | istream( istype ), E | CfaEnum( E ) )
44istype & ?|?( istype & is, E & e ) {
45//      printf( "here0\n" );
46        if ( eof( is ) ) throwResume ExceptionInst( missing_data );
47
48        // Match input enumerator string to enumerator labels.
49        int len = -1;
50        const char * cpy[ 20 /*countof( E )*/ ];
51        int i = 0;
52        for ( s; E ) {
53                cpy[i] = label( s );
54                printf( "%s\n", cpy[i] );
55                i += 1;
56        }
57        printf( "%d\n", i );
58        qsort( cpy, i, sizeof(char*), scmp );
59        i = 0;
60        for ( s; E ) {
61                printf( "%s\n", cpy[i] );
62                i += 1;
63        }
64        int j = 0;
65  X : for ( s; E ) {
66                len = strlen( cpy[j] );
67                printf( "%s %d\n", cpy[j], len );
68                char fmtstr[len + 16];
69                fmtstr[0] = ' ';                                                                // optional leadig whitespace
70                strcpy( &fmtstr[1], cpy[j] );                                   // copy format and add %n
71                strcpy( &fmtstr[len + 1], "%n" );
72                printf( "%s\n", fmtstr );
73                len = -1;
74                // scanf cursor does not move if no match
75                fmt( is, fmtstr, &len );
76                printf( "%s %d %d\n", fmtstr, len, j );
77          if ( eof( is ) ) { break; }
78          if ( len != -1 ) {
79                  for ( s; E ) {
80                          if ( strcmp( label( s ), cpy[j] ) == 0 ) { e = s; break X; }
81                  }
82          }
83                j += 1;
84        } else {
85                //ExceptionInst( missing_data );
86        } // for
87        printf( "X %s %d\n", label( e ), len );
88        if ( ! eof( is ) && len == -1 ) throwResume ExceptionInst( missing_data );
89
90        // if ( eof( is ) ) throwResume ExceptionInst( missing_data );
91        // char val[256];
92        // int args = fmt( is, "%255s", val );
93        // if ( ! eof( is ) && args != 1 ) throwResume ExceptionInst( missing_data );
94        // for ( s; E ) {
95        //      if ( strcmp(val, label( s )) == 0 ) { e = s; break; }
96        // } else {
97        //      fprintf( stderr, "invalid enumeration constant\n" );
98        //      abort();                                                                        // cannot use abort stream
99        // } // for
100        return is;
101}
102
103// forall( ostype & | ostream( ostype ), E | CfaEnum( E, quasi_void ) ) {
104//      ostype & ?|?( ostype & os, E e ) {
105//              return os | label( e );
106//      }
107//      OSTYPE_VOID_IMPL( E )
108// }
109
110forall( ostype & | ostream( ostype ), E | CfaEnum( E ) ) {
111        ostype & ?|?( ostype & os, E e ) {
112                return os | label( e );
113        }
114        OSTYPE_VOID_IMPL( E )
115}
116
117//
Note: See TracBrowser for help on using the repository browser.