source: libcfa/src/enum.cfa@ 76b507d

Last change on this file since 76b507d was 0c327ce, checked in by JiadaL <j82liang@…>, 15 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
RevLine 
[c333ed2]1#include "enum.hfa"
[85855b0]2#include "fstream.hfa"
[d287f3e]3#include <stdlib.h> // qsort
[6d2b3dc]4#include <string.h>
[c333ed2]5
[03ac869]6#pragma GCC visibility push(default)
7
[0c327ce]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
[d287f3e]39int scmp( const void * str1, const void * str2 ) {
40 return -strcmp( *(char **)str1, *(char **)str2 ); // dscending order
41} // scmp
42
[236f133]43forall( istype & | istream( istype ), E | CfaEnum( E ) )
[64eeb06]44istype & ?|?( istype & is, E & e ) {
[d287f3e]45// printf( "here0\n" );
[64eeb06]46 if ( eof( is ) ) throwResume ExceptionInst( missing_data );
[d287f3e]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;
[6d2b3dc]60 for ( s; E ) {
[d287f3e]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;
[6d2b3dc]84 } else {
[d287f3e]85 //ExceptionInst( missing_data );
[6d2b3dc]86 } // for
[d287f3e]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
[64eeb06]100 return is;
101}
102
[236f133]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// }
[c333ed2]109
[236f133]110forall( ostype & | ostream( ostype ), E | CfaEnum( E ) ) {
[64eeb06]111 ostype & ?|?( ostype & os, E e ) {
112 return os | label( e );
113 }
114 OSTYPE_VOID_IMPL( E )
[259012e]115}
[236f133]116
117//
Note: See TracBrowser for help on using the repository browser.