2 * Copyright 2001-2006 Adrian Thurston <thurston@cs.queensu.ca>
5 /* This file is part of Ragel.
7 * Ragel is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * Ragel is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with Ragel; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
29 typedef unsigned long long Size
;
37 friend inline Key
operator+(const Key key1
, const Key key2
);
38 friend inline Key
operator-(const Key key1
, const Key key2
);
39 friend inline Key
operator/(const Key key1
, const Key key2
);
40 friend inline long operator&(const Key key1
, const Key key2
);
42 friend inline bool operator<( const Key key1
, const Key key2
);
43 friend inline bool operator<=( const Key key1
, const Key key2
);
44 friend inline bool operator>( const Key key1
, const Key key2
);
45 friend inline bool operator>=( const Key key1
, const Key key2
);
46 friend inline bool operator==( const Key key1
, const Key key2
);
47 friend inline bool operator!=( const Key key1
, const Key key2
);
52 Key( const Key
&key
) : key(key
.key
) {}
53 Key( long key
) : key(key
) {}
55 /* Returns the value used to represent the key. This value must be
56 * interpreted based on signedness. */
57 long getVal() const { return key
; };
59 /* Returns the key casted to a long long. This form of the key does not
60 * require any signedness interpretation. */
61 long long getLongLong() const;
63 /* Returns the distance from the key value to the maximum value that the
64 * key implementation can hold. */
65 Size
availableSpace() const;
67 bool isUpper() const { return ( 'A' <= key
&& key
<= 'Z' ); }
68 bool isLower() const { return ( 'a' <= key
&& key
<= 'z' ); }
69 bool isPrintable() const
71 return ( 7 <= key
&& key
<= 13 ) || ( 32 <= key
&& key
< 127 );
75 { return Key( 'A' + ( key
- 'a' ) ); }
77 { return Key( 'a' + ( key
- 'A' ) ); }
79 void operator+=( const Key other
)
81 /* FIXME: must be made aware of isSigned. */
85 void operator-=( const Key other
)
87 /* FIXME: must be made aware of isSigned. */
91 void operator|=( const Key other
)
93 /* FIXME: must be made aware of isSigned. */
97 /* Decrement. Needed only for ranges. */
98 inline void decrement();
99 inline void increment();
106 const char *internalName
;
115 /* Target language. */
118 C
, D
, Java
, Ruby
, CSharp
124 HostType
*defaultAlphType
;
125 bool explicitUnsigned
;
128 extern HostLang
*hostLang
;
130 extern HostLang hostLangC
;
131 extern HostLang hostLangD
;
132 extern HostLang hostLangJava
;
133 extern HostLang hostLangRuby
;
134 extern HostLang hostLangCSharp
;
136 HostType
*findAlphType( char *s1
);
137 HostType
*findAlphType( char *s1
, char *s2
);
138 HostType
*findAlphTypeInternal( char *s1
);
140 /* An abstraction of the key operators that manages key operations such as
141 * comparison and increment according the signedness of the key. */
144 /* Default to signed alphabet. */
150 /* Default to signed alphabet. */
151 KeyOps( bool isSigned
)
152 :isSigned(isSigned
) {}
158 void setAlphType( HostType
*alphType
)
160 this->alphType
= alphType
;
161 isSigned
= alphType
->isSigned
;
163 minKey
= (long) alphType
->minVal
;
164 maxKey
= (long) alphType
->maxVal
;
167 minKey
= (long) (unsigned long) alphType
->minVal
;
168 maxKey
= (long) (unsigned long) alphType
->maxVal
;
172 /* Compute the distance between two keys. */
173 Size
span( Key key1
, Key key2
)
176 (unsigned long long)(
177 (long long)key2
.key
-
178 (long long)key1
.key
+ 1) :
179 (unsigned long long)(
180 (unsigned long)key2
.key
) -
181 (unsigned long long)((unsigned long)key1
.key
) + 1;
185 { return span( minKey
, maxKey
); }
187 HostType
*typeSubsumes( long long maxVal
)
189 for ( int i
= 0; i
< hostLang
->numHostTypes
; i
++ ) {
190 if ( maxVal
<= hostLang
->hostTypes
[i
].maxVal
)
191 return hostLang
->hostTypes
+ i
;
196 HostType
*typeSubsumes( bool isSigned
, long long maxVal
)
198 for ( int i
= 0; i
< hostLang
->numHostTypes
; i
++ ) {
199 if ( ( ( isSigned
&& hostLang
->hostTypes
[i
].isSigned
) || !isSigned
) &&
200 maxVal
<= hostLang
->hostTypes
[i
].maxVal
)
201 return hostLang
->hostTypes
+ i
;
207 extern KeyOps
*keyOps
;
209 inline bool operator<( const Key key1
, const Key key2
)
211 return keyOps
->isSigned
? key1
.key
< key2
.key
:
212 (unsigned long)key1
.key
< (unsigned long)key2
.key
;
215 inline bool operator<=( const Key key1
, const Key key2
)
217 return keyOps
->isSigned
? key1
.key
<= key2
.key
:
218 (unsigned long)key1
.key
<= (unsigned long)key2
.key
;
221 inline bool operator>( const Key key1
, const Key key2
)
223 return keyOps
->isSigned
? key1
.key
> key2
.key
:
224 (unsigned long)key1
.key
> (unsigned long)key2
.key
;
227 inline bool operator>=( const Key key1
, const Key key2
)
229 return keyOps
->isSigned
? key1
.key
>= key2
.key
:
230 (unsigned long)key1
.key
>= (unsigned long)key2
.key
;
233 inline bool operator==( const Key key1
, const Key key2
)
235 return key1
.key
== key2
.key
;
238 inline bool operator!=( const Key key1
, const Key key2
)
240 return key1
.key
!= key2
.key
;
243 /* Decrement. Needed only for ranges. */
244 inline void Key::decrement()
246 key
= keyOps
->isSigned
? key
- 1 : ((unsigned long)key
)-1;
249 /* Increment. Needed only for ranges. */
250 inline void Key::increment()
252 key
= keyOps
->isSigned
? key
+1 : ((unsigned long)key
)+1;
255 inline long long Key::getLongLong() const
257 return keyOps
->isSigned
? (long long)key
: (long long)(unsigned long)key
;
260 inline Size
Key::availableSpace() const
262 if ( keyOps
->isSigned
)
263 return (long long)LONG_MAX
- (long long)key
;
265 return (unsigned long long)ULONG_MAX
- (unsigned long long)(unsigned long)key
;
268 inline Key
operator+(const Key key1
, const Key key2
)
270 /* FIXME: must be made aware of isSigned. */
271 return Key( key1
.key
+ key2
.key
);
274 inline Key
operator-(const Key key1
, const Key key2
)
276 /* FIXME: must be made aware of isSigned. */
277 return Key( key1
.key
- key2
.key
);
280 inline long operator&(const Key key1
, const Key key2
)
282 /* FIXME: must be made aware of isSigned. */
283 return key1
.key
& key2
.key
;
286 inline Key
operator/(const Key key1
, const Key key2
)
288 /* FIXME: must be made aware of isSigned. */
289 return key1
.key
/ key2
.key
;
292 /* Filter on the output stream that keeps track of the number of lines
294 class output_filter
: public std::filebuf
297 output_filter( char *fileName
) : fileName(fileName
), line(1) { }
300 virtual std::streamsize
xsputn(const char* s
, std::streamsize n
);
306 class cfilebuf
: public std::streambuf
309 cfilebuf( char *fileName
, FILE* file
) : fileName(fileName
), file(file
) { }
319 int overflow( int c
)
326 std::streamsize
xsputn( const char* s
, std::streamsize n
)
328 std::streamsize written
= fwrite( s
, 1, n
, file
);
333 class costream
: public std::ostream
336 costream( cfilebuf
*b
) :
337 std::ostream(b
), b(b
) {}
343 { ::fclose( b
->file
); }
349 char *findFileExtension( char *stemFile
);
350 char *fileNameFromStem( char *stemFile
, const char *suffix
);
354 Export( const char *name
, Key key
)
355 : name(name
), key(key
) {}
363 typedef DList
<Export
> ExportList
;
365 struct exit_object
{ };
366 extern exit_object endp
;
367 void operator<<( std::ostream
&out
, exit_object
& );
369 #endif /* _COMMON_H */