Changeset 181036c
- Timestamp:
- Aug 13, 2022, 1:30:37 PM (3 years ago)
- Branches:
- ADT, ast-experimental, master, pthread-emulation
- Children:
- 3f1059e
- Parents:
- 62c5a55 (diff), 082af5b (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - Files:
-
- 16 edited
Legend:
- Unmodified
- Added
- Removed
-
doc/bibliography/pl.bib
r62c5a55 r181036c 7837 7837 } 7838 7838 7839 @misc{Tokio, 7840 contributer = {pabuhr@plg}, 7841 key = {Tokio}, 7842 title = {{T}okio Asynchronous Runtime for {R}ust}, 7843 author = {Tokio}, 7844 howpublished= {\href{https://tokio.rs}{https://\-tokio.rs}}, 7845 } 7846 7839 7847 @misc{Bumbulis90, 7840 7848 keywords = {parameter inference, ForceN}, … … 8152 8160 doi = {10.1145/3379483}, 8153 8161 journal = {Proc. ACM Meas. Anal. Comput. Syst.}, 8154 month = mar,8162 month = jun, 8155 8163 numpages = {30}, 8156 8164 } -
src/Common/Eval.cc
r62c5a55 r181036c 10 10 // Created On : Mon May 18 07:44:20 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Jul 1 08:41:03202213 // Update Count : 11 712 // Last Modified On : Sat Aug 6 12:11:59 2022 13 // Update Count : 119 14 14 // 15 15 … … 217 217 value = arg1.first * arg2.first; 218 218 } else if (fname == "?/?") { 219 value = arg1.first / arg2.first;219 if ( arg2.first ) value = arg1.first / arg2.first; 220 220 } else if (fname == "?%?") { 221 value = arg1.first % arg2.first;221 if ( arg2.first ) value = arg1.first % arg2.first; 222 222 } else if (fname == "?<<?") { 223 223 value = arg1.first << arg2.first; -
src/Common/ScopedMap.h
r62c5a55 r181036c 10 10 // Created On : Wed Dec 2 11:37:00 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Mon May 21 15:22:40 201813 // Update Count : 312 // Last Modified On : Tue Feb 15 08:41:28 2022 13 // Update Count : 5 14 14 // 15 15 … … 36 36 37 37 template<typename N> 38 Scope(N && n) : map(), note(std::forward<N>(n)) {}38 Scope(N && n) : map(), note(std::forward<N>(n)) {} 39 39 40 40 Scope() = default; 41 Scope(const Scope &) = default;42 Scope(Scope &&) = default;43 Scope & operator= (const Scope&) = default;44 Scope & operator= (Scope&&) = default;41 Scope(const Scope &) = default; 42 Scope(Scope &&) = default; 43 Scope & operator= (const Scope &) = default; 44 Scope & operator= (Scope &&) = default; 45 45 }; 46 46 typedef std::vector< Scope > ScopeList; … … 58 58 typedef typename MapType::const_pointer const_pointer; 59 59 60 class iterator : public std::iterator< std::bidirectional_iterator_tag, 61 value_type > { 60 class iterator : public std::iterator< std::bidirectional_iterator_tag, value_type > { 62 61 friend class ScopedMap; 63 62 friend class const_iterator; … … 72 71 73 72 /// Increments on invalid 74 iterator & next_valid() {73 iterator & next_valid() { 75 74 if ( ! is_valid() ) { ++(*this); } 76 75 return *this; … … 78 77 79 78 /// Decrements on invalid 80 iterator & prev_valid() {79 iterator & prev_valid() { 81 80 if ( ! is_valid() ) { --(*this); } 82 81 return *this; 83 82 } 84 83 85 iterator(scope_list & _scopes, const wrapped_iterator &_it, size_type inLevel)84 iterator(scope_list & _scopes, const wrapped_iterator & _it, size_type inLevel) 86 85 : scopes(&_scopes), it(_it), level(inLevel) {} 87 86 public: 88 iterator(const iterator & that) : scopes(that.scopes), it(that.it), level(that.level) {}89 iterator & operator= (const iterator &that) {87 iterator(const iterator & that) : scopes(that.scopes), it(that.it), level(that.level) {} 88 iterator & operator= (const iterator & that) { 90 89 scopes = that.scopes; level = that.level; it = that.it; 91 90 return *this; … … 95 94 pointer operator-> () const { return it.operator->(); } 96 95 97 iterator & operator++ () {96 iterator & operator++ () { 98 97 if ( it == (*scopes)[level].map.end() ) { 99 98 if ( level == 0 ) return *this; … … 107 106 iterator operator++ (int) { iterator tmp = *this; ++(*this); return tmp; } 108 107 109 iterator & operator-- () {108 iterator & operator-- () { 110 109 // may fail if this is the begin iterator; allowed by STL spec 111 110 if ( it == (*scopes)[level].map.begin() ) { … … 118 117 iterator operator-- (int) { iterator tmp = *this; --(*this); return tmp; } 119 118 120 bool operator== (const iterator & that) const {119 bool operator== (const iterator & that) const { 121 120 return scopes == that.scopes && level == that.level && it == that.it; 122 121 } 123 bool operator!= (const iterator & that) const { return !( *this == that ); }122 bool operator!= (const iterator & that) const { return !( *this == that ); } 124 123 125 124 size_type get_level() const { return level; } 126 125 127 Note & get_note() { return (*scopes)[level].note; }128 const Note & get_note() const { return (*scopes)[level].note; }126 Note & get_note() { return (*scopes)[level].note; } 127 const Note & get_note() const { return (*scopes)[level].note; } 129 128 130 129 private: … … 148 147 149 148 /// Increments on invalid 150 const_iterator & next_valid() {149 const_iterator & next_valid() { 151 150 if ( ! is_valid() ) { ++(*this); } 152 151 return *this; … … 154 153 155 154 /// Decrements on invalid 156 const_iterator & prev_valid() {155 const_iterator & prev_valid() { 157 156 if ( ! is_valid() ) { --(*this); } 158 157 return *this; 159 158 } 160 159 161 const_iterator(scope_list const & _scopes, const wrapped_const_iterator &_it, size_type inLevel)160 const_iterator(scope_list const & _scopes, const wrapped_const_iterator & _it, size_type inLevel) 162 161 : scopes(&_scopes), it(_it), level(inLevel) {} 163 162 public: 164 const_iterator(const iterator & that) : scopes(that.scopes), it(that.it), level(that.level) {}165 const_iterator(const const_iterator & that) : scopes(that.scopes), it(that.it), level(that.level) {}166 const_iterator & operator= (const iterator &that) {163 const_iterator(const iterator & that) : scopes(that.scopes), it(that.it), level(that.level) {} 164 const_iterator(const const_iterator & that) : scopes(that.scopes), it(that.it), level(that.level) {} 165 const_iterator & operator= (const iterator & that) { 167 166 scopes = that.scopes; level = that.level; it = that.it; 168 167 return *this; 169 168 } 170 const_iterator & operator= (const const_iterator &that) {169 const_iterator & operator= (const const_iterator & that) { 171 170 scopes = that.scopes; level = that.level; it = that.it; 172 171 return *this; … … 176 175 const_pointer operator-> () { return it.operator->(); } 177 176 178 const_iterator & operator++ () {177 const_iterator & operator++ () { 179 178 if ( it == (*scopes)[level].map.end() ) { 180 179 if ( level == 0 ) return *this; … … 188 187 const_iterator operator++ (int) { const_iterator tmp = *this; ++(*this); return tmp; } 189 188 190 const_iterator & operator-- () {189 const_iterator & operator-- () { 191 190 // may fail if this is the begin iterator; allowed by STL spec 192 191 if ( it == (*scopes)[level].map.begin() ) { … … 199 198 const_iterator operator-- (int) { const_iterator tmp = *this; --(*this); return tmp; } 200 199 201 bool operator== (const const_iterator & that) const {200 bool operator== (const const_iterator & that) const { 202 201 return scopes == that.scopes && level == that.level && it == that.it; 203 202 } 204 bool operator!= (const const_iterator & that) const { return !( *this == that ); }203 bool operator!= (const const_iterator & that) const { return !( *this == that ); } 205 204 206 205 size_type get_level() const { return level; } 207 206 208 const Note & get_note() const { return (*scopes)[level].note; }207 const Note & get_note() const { return (*scopes)[level].note; } 209 208 210 209 private: … … 221 220 // Starts a new scope with the given note 222 221 template<typename N> 223 void beginScope( N && n ) {222 void beginScope( N && n ) { 224 223 scopes.emplace_back( std::forward<N>(n) ); 225 224 } … … 236 235 /// Constructs with a given note on the outermost scope 237 236 template<typename N> 238 ScopedMap( N && n ) : scopes() { beginScope(std::forward<N>(n)); }237 ScopedMap( N && n ) : scopes() { beginScope(std::forward<N>(n)); } 239 238 240 239 iterator begin() { return iterator(scopes, scopes.back().map.begin(), currentScope()).next_valid(); } … … 249 248 250 249 /// Gets the note at the given scope 251 Note & getNote() { return scopes.back().note; }252 const Note & getNote() const { return scopes.back().note; }253 Note & getNote( size_type i ) { return scopes[i].note; }254 const Note & getNote( size_type i ) const { return scopes[i].note; }250 Note & getNote() { return scopes.back().note; } 251 const Note & getNote() const { return scopes.back().note; } 252 Note & getNote( size_type i ) { return scopes[i].note; } 253 const Note & getNote( size_type i ) const { return scopes[i].note; } 255 254 256 255 /// Finds the given key in the outermost scope it occurs; returns end() for none such 257 iterator find( const Key & key ) {256 iterator find( const Key & key ) { 258 257 for ( size_type i = scopes.size() - 1; ; --i ) { 259 258 typename MapType::iterator val = scopes[i].map.find( key ); … … 263 262 return end(); 264 263 } 265 const_iterator find( const Key & key ) const {264 const_iterator find( const Key & key ) const { 266 265 return const_iterator( const_cast< ScopedMap< Key, Value, Note >* >(this)->find( key ) ); 267 266 } 268 267 269 268 /// Finds the given key in the provided scope; returns end() for none such 270 iterator findAt( size_type scope, const Key & key ) {269 iterator findAt( size_type scope, const Key & key ) { 271 270 typename MapType::iterator val = scopes[scope].map.find( key ); 272 271 if ( val != scopes[scope].map.end() ) return iterator( scopes, val, scope ); 273 272 return end(); 274 273 } 275 const_iterator findAt( size_type scope, const Key & key ) const {274 const_iterator findAt( size_type scope, const Key & key ) const { 276 275 return const_iterator( const_cast< ScopedMap< Key, Value, Note >* >(this)->findAt( scope, key ) ); 277 276 } 278 277 279 278 /// Finds the given key in the outermost scope inside the given scope where it occurs 280 iterator findNext( const_iterator & it, const Key &key ) {279 iterator findNext( const_iterator & it, const Key & key ) { 281 280 if ( it.level == 0 ) return end(); 282 281 for ( size_type i = it.level - 1; ; --i ) { … … 287 286 return end(); 288 287 } 289 const_iterator findNext( const_iterator & it, const Key &key ) const {288 const_iterator findNext( const_iterator & it, const Key & key ) const { 290 289 return const_iterator( const_cast< ScopedMap< Key, Value, Note >* >(this)->findNext( it, key ) ); 291 290 } … … 293 292 /// Inserts the given key-value pair into the outermost scope 294 293 template< typename value_type_t > 295 std::pair< iterator, bool > insert( value_type_t && value ) {294 std::pair< iterator, bool > insert( value_type_t && value ) { 296 295 std::pair< typename MapType::iterator, bool > res = scopes.back().map.insert( std::forward<value_type_t>( value ) ); 297 296 return std::make_pair( iterator(scopes, std::move( res.first ), scopes.size()-1), std::move( res.second ) ); … … 299 298 300 299 template< typename value_type_t > 301 std::pair< iterator, bool > insert( iterator at, value_type_t && value ) {302 MapType & scope = (*at.scopes)[ at.level ].map;300 std::pair< iterator, bool > insert( iterator at, value_type_t && value ) { 301 MapType & scope = (*at.scopes)[ at.level ].map; 303 302 std::pair< typename MapType::iterator, bool > res = scope.insert( std::forward<value_type_t>( value ) ); 304 303 return std::make_pair( iterator(scopes, std::move( res.first ), at.level), std::move( res.second ) ); … … 306 305 307 306 template< typename value_t > 308 std::pair< iterator, bool > insert( const Key & key, value_t&& value ) { return insert( std::make_pair( key, std::forward<value_t>( value ) ) ); }307 std::pair< iterator, bool > insert( const Key & key, value_t && value ) { return insert( std::make_pair( key, std::forward<value_t>( value ) ) ); } 309 308 310 309 template< typename value_type_t > 311 std::pair< iterator, bool > insertAt( size_type scope, value_type_t && value ) {310 std::pair< iterator, bool > insertAt( size_type scope, value_type_t && value ) { 312 311 std::pair< typename MapType::iterator, bool > res = scopes.at(scope).map.insert( std::forward<value_type_t>( value ) ); 313 312 return std::make_pair( iterator(scopes, std::move( res.first ), scope), std::move( res.second ) ); … … 315 314 316 315 template< typename value_t > 317 std::pair< iterator, bool > insertAt( size_type scope, const Key & key, value_t&& value ) {316 std::pair< iterator, bool > insertAt( size_type scope, const Key & key, value_t && value ) { 318 317 return insertAt( scope, std::make_pair( key, std::forward<value_t>( value ) ) ); 319 318 } 320 319 321 Value & operator[] ( const Key &key ) {320 Value & operator[] ( const Key & key ) { 322 321 iterator slot = find( key ); 323 322 if ( slot != end() ) return slot->second; … … 326 325 327 326 iterator erase( iterator pos ) { 328 MapType & scope = (*pos.scopes)[ pos.level ].map;329 const typename iterator::wrapped_iterator & new_it = scope.erase( pos.it );327 MapType & scope = (*pos.scopes)[ pos.level ].map; 328 const typename iterator::wrapped_iterator & new_it = scope.erase( pos.it ); 330 329 iterator it( *pos.scopes, new_it, pos.level ); 331 330 return it.next_valid(); 332 331 } 333 332 334 size_type count( const Key & key ) const {333 size_type count( const Key & key ) const { 335 334 size_type c = 0; 336 335 auto it = find( key ); … … 344 343 return c; 345 344 } 346 347 345 }; 348 346 -
src/Parser/DeclarationNode.cc
r62c5a55 r181036c 10 10 // Created On : Sat May 16 12:34:05 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed Jul 14 17:36:57 202113 // Update Count : 11 5412 // Last Modified On : Mon Aug 8 17:07:00 2022 13 // Update Count : 1185 14 14 // 15 15 … … 128 128 if ( name ) { 129 129 os << *name << ": "; 130 } else {131 os << "unnamed: ";132 130 } // if 133 131 … … 154 152 initializer->printOneLine( os ); 155 153 os << " maybe constructed? " << initializer->get_maybeConstructed(); 156 157 } // if 154 } // if 155 156 for ( Attribute * attr: reverseIterate( attributes ) ) { 157 os << string( indent + 2, ' ' ) << "attr " << attr->name.c_str(); 158 } // for 158 159 159 160 os << endl; … … 243 244 newnode->type = new TypeData( TypeData::Aggregate ); 244 245 newnode->type->aggregate.kind = kind; 245 newnode->type->aggregate.name = 246 newnode->type->aggregate.name = name == nullptr ? new string( DeclarationNode::anonymous.newName() ) : name; 246 247 newnode->type->aggregate.actuals = actuals; 247 248 newnode->type->aggregate.fields = fields; … … 518 519 storageClasses |= q->storageClasses; 519 520 520 for ( Attribute * attr: reverseIterate( q->attributes ) ) {521 for ( Attribute * attr: reverseIterate( q->attributes ) ) { 521 522 attributes.push_front( attr->clone() ); 522 523 } // for … … 683 684 } // if 684 685 delete o; 686 685 687 return this; 686 688 } -
src/Parser/TypeData.cc
r62c5a55 r181036c 9 9 // Author : Rodolfo G. Esteves 10 10 // Created On : Sat May 16 15:12:51 2015 11 // Last Modified By : Henry Xue12 // Last Modified On : Tue Jul 20 04:10:50 202113 // Update Count : 67 311 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Tue May 10 22:36:52 2022 13 // Update Count : 677 14 14 // 15 15 … … 283 283 if ( signedness != DeclarationNode::NoSignedness ) os << DeclarationNode::signednessNames[ signedness ] << " "; 284 284 if ( length != DeclarationNode::NoLength ) os << DeclarationNode::lengthNames[ length ] << " "; 285 if ( complextype == DeclarationNode::NoComplexType ) { // basic type 286 assert( basictype != DeclarationNode::NoBasicType ); 287 os << DeclarationNode::basicTypeNames[ basictype ] << " "; 288 } else { // complex type 289 // handle double _Complex 290 if ( basictype != DeclarationNode::NoBasicType ) os << DeclarationNode::basicTypeNames[ basictype ] << " "; 291 os << DeclarationNode::complexTypeNames[ complextype ] << " "; 292 } // if 285 if ( complextype != DeclarationNode::NoComplexType ) os << DeclarationNode::complexTypeNames[ complextype ] << " "; 286 if ( basictype != DeclarationNode::NoBasicType ) os << DeclarationNode::basicTypeNames[ basictype ] << " "; 293 287 break; 294 288 case Pointer: … … 437 431 __attribute__((fallthrough)); 438 432 #endif 433 // FALL THROUGH 439 434 case Typeof: 440 435 os << "type-of expression "; … … 442 437 typeexpr->print( os, indent + 2 ); 443 438 } // if 439 break; 440 case Vtable: 441 os << "vtable"; 444 442 break; 445 443 case Builtin: -
src/Parser/TypeData.h
r62c5a55 r181036c 10 10 // Created On : Sat May 16 15:18:36 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed Jul 14 17:44:05 202113 // Update Count : 20 212 // Last Modified On : Tue May 10 22:18:49 2022 13 // Update Count : 203 14 14 // 15 15 … … 27 27 struct TypeData { 28 28 enum Kind { Basic, Pointer, Reference, Array, Function, Aggregate, AggregateInst, Enum, EnumConstant, Symbolic, 29 SymbolicInst, Tuple, Typeof, Basetypeof, Vtable, Builtin, GlobalScope, Qualified, Unknown };29 SymbolicInst, Tuple, Basetypeof, Typeof, Vtable, Builtin, GlobalScope, Qualified, Unknown }; 30 30 31 31 struct Aggregate_t { -
src/Parser/TypedefTable.cc
r62c5a55 r181036c 10 10 // Created On : Sat May 16 15:20:13 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed May 19 08:30:14 202113 // Update Count : 2 6212 // Last Modified On : Tue Feb 15 08:27:24 2022 13 // Update Count : 275 14 14 // 15 15 … … 18 18 #include <cassert> // for assert 19 19 #include <iostream> 20 using namespace std; 20 21 21 22 #if 0 … … 28 29 29 30 debugPrint( 30 static const char *kindName( int kind ) {31 switch ( kind ) {32 case IDENTIFIER: return "identifier";33 case TYPEDIMname: return "typedim";34 case TYPEDEFname: return "typedef";35 case TYPEGENname: return "typegen";36 default:37 cerr << "Error: cfa-cpp internal error, invalid kind of identifier" << endl;38 abort();39 } // switch40 } // kindName41 ) 31 static const char *kindName( int kind ) { 32 switch ( kind ) { 33 case IDENTIFIER: return "identifier"; 34 case TYPEDIMname: return "typedim"; 35 case TYPEDEFname: return "typedef"; 36 case TYPEGENname: return "typegen"; 37 default: 38 cerr << "Error: cfa-cpp internal error, invalid kind of identifier" << endl; 39 abort(); 40 } // switch 41 } // kindName 42 ); 42 43 43 44 TypedefTable::~TypedefTable() { … … 80 81 81 82 void TypedefTable::addToScope( const string & identifier, int kind, const char * locn __attribute__((unused)) ) { 82 autoscope = kindTable.currentScope();83 KindTable::size_type scope = kindTable.currentScope(); 83 84 debugPrint( cerr << "Adding current at " << locn << " " << identifier << " as " << kindName( kind ) << " scope " << scope << endl ); 84 85 kindTable.insertAt( scope, identifier, kind ); … … 86 87 87 88 void TypedefTable::addToEnclosingScope( const string & identifier, int kind, const char * locn __attribute__((unused)) ) { 88 autoscope = kindTable.currentScope() - 1 - kindTable.getNote( kindTable.currentScope() - 1 ).level;89 // autoscope = level - kindTable.getNote( kindTable.currentScope() - 1 ).level;89 KindTable::size_type scope = kindTable.currentScope() - 1 - kindTable.getNote( kindTable.currentScope() - 1 ).level; 90 // size_type scope = level - kindTable.getNote( kindTable.currentScope() - 1 ).level; 90 91 debugPrint( cerr << "Adding enclosing at " << locn << " " << identifier << " as " << kindName( kind ) << " scope " << scope << " level " << level << " note " << kindTable.getNote( kindTable.currentScope() - 1 ).level << endl ); 91 autoret = kindTable.insertAt( scope, identifier, kind );92 pair< KindTable::iterator, bool > ret = kindTable.insertAt( scope, identifier, kind ); 92 93 if ( ! ret.second ) ret.first->second = kind; // exists => update 93 94 } // TypedefTable::addToEnclosingScope -
src/Parser/parser.yy
r62c5a55 r181036c 10 10 // Created On : Sat Sep 1 20:22:55 2001 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Jul 1 15:35:08 202213 // Update Count : 5 40512 // Last Modified On : Fri Aug 12 07:59:58 2022 13 // Update Count : 5649 14 14 // 15 15 … … 58 58 59 59 // lex uses __null in a boolean context, it's fine. 60 #pragma GCC diagnostic ignored "-Wparentheses-equality"60 //#pragma GCC diagnostic ignored "-Wparentheses-equality" 61 61 62 62 extern DeclarationNode * parseTree; … … 197 197 } // fieldDecl 198 198 199 #define NEW_ZERO new ExpressionNode( build_constantInteger( *new string( "0" ) ) ) 200 #define NEW_ONE new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) 201 #define UPDOWN( compop, left, right ) (compop == OperKinds::LThan || compop == OperKinds::LEThan ? left : right) 202 203 ForCtrl * forCtrl( DeclarationNode * index, ExpressionNode * start, enum OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) { 204 if ( index->initializer ) { 205 SemanticError( yylloc, "Direct initialization disallowed. Use instead: type var; initialization ~ comparison ~ increment." ); 206 } // if 207 if ( index->next ) { 208 SemanticError( yylloc, "Multiple loop indexes disallowed in for-loop declaration." ); 209 } // if 210 return new ForCtrl( index->addInitializer( new InitializerNode( start ) ), 211 // NULL comp/inc => leave blank 212 comp ? new ExpressionNode( build_binary_val( compop, new ExpressionNode( build_varref( new string( *index->name ) ) ), comp ) ) : nullptr, 213 inc ? new ExpressionNode( build_binary_val( compop == OperKinds::LThan || compop == OperKinds::LEThan ? // choose += or -= for upto/downto 214 OperKinds::PlusAssn : OperKinds::MinusAssn, new ExpressionNode( build_varref( new string( *index->name ) ) ), inc ) ) : nullptr ); 215 } // forCtrl 216 199 217 ForCtrl * forCtrl( ExpressionNode * type, string * index, ExpressionNode * start, enum OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) { 200 218 ConstantExpr * constant = dynamic_cast<ConstantExpr *>(type->expr.get()); … … 206 224 distAttr( DeclarationNode::newTypeof( type, true ), DeclarationNode::newName( index )->addInitializer( new InitializerNode( start ) ) ), 207 225 // NULL comp/inc => leave blank 208 comp ? new ExpressionNode( build_binary_val( compop, new ExpressionNode( build_varref( new string( *index ) ) ), comp ) ) : 0,226 comp ? new ExpressionNode( build_binary_val( compop, new ExpressionNode( build_varref( new string( *index ) ) ), comp ) ) : nullptr, 209 227 inc ? new ExpressionNode( build_binary_val( compop == OperKinds::LThan || compop == OperKinds::LEThan ? // choose += or -= for upto/downto 210 OperKinds::PlusAssn : OperKinds::MinusAssn, new ExpressionNode( build_varref( new string( *index ) ) ), inc ) ) : 0);228 OperKinds::PlusAssn : OperKinds::MinusAssn, new ExpressionNode( build_varref( new string( *index ) ) ), inc ) ) : nullptr ); 211 229 } // forCtrl 212 230 … … 346 364 %type<ifctl> conditional_declaration 347 365 %type<fctl> for_control_expression for_control_expression_list 348 %type<compop> inclexcl366 %type<compop> updown updowneq downupdowneq 349 367 %type<en> subrange 350 368 %type<decl> asm_name_opt … … 1239 1257 iteration_statement: 1240 1258 WHILE '(' ')' statement %prec THEN // CFA => while ( 1 ) 1241 { $$ = new StatementNode( build_while( new CondCtl( nullptr, new ExpressionNode( build_constantInteger( *new string( "1" ) ) )), maybe_build_compound( $4 ) ) ); }1259 { $$ = new StatementNode( build_while( new CondCtl( nullptr, NEW_ONE ), maybe_build_compound( $4 ) ) ); } 1242 1260 | WHILE '(' ')' statement ELSE statement // CFA 1243 1261 { 1244 $$ = new StatementNode( build_while( new CondCtl( nullptr, new ExpressionNode( build_constantInteger( *new string( "1" ) ) )), maybe_build_compound( $4 ) ) );1262 $$ = new StatementNode( build_while( new CondCtl( nullptr, NEW_ONE ), maybe_build_compound( $4 ) ) ); 1245 1263 SemanticWarning( yylloc, Warning::SuperfluousElse, "" ); 1246 1264 } … … 1250 1268 { $$ = new StatementNode( build_while( $3, maybe_build_compound( $5 ), $7 ) ); } 1251 1269 | DO statement WHILE '(' ')' ';' // CFA => do while( 1 ) 1252 { $$ = new StatementNode( build_do_while( new ExpressionNode( build_constantInteger( *new string( "1" ) ) ), maybe_build_compound( $2 ) ) ); }1270 { $$ = new StatementNode( build_do_while( NEW_ONE, maybe_build_compound( $2 ) ) ); } 1253 1271 | DO statement WHILE '(' ')' ELSE statement // CFA 1254 1272 { 1255 $$ = new StatementNode( build_do_while( new ExpressionNode( build_constantInteger( *new string( "1" ) ) ), maybe_build_compound( $2 ) ) );1273 $$ = new StatementNode( build_do_while( NEW_ONE, maybe_build_compound( $2 ) ) ); 1256 1274 SemanticWarning( yylloc, Warning::SuperfluousElse, "" ); 1257 1275 } … … 1305 1323 1306 1324 | comma_expression // CFA 1307 { $$ = forCtrl( $1, new string( DeclarationNode::anonymous.newName() ), new ExpressionNode( build_constantInteger( *new string( "0" ) ) ), 1308 OperKinds::LThan, $1->clone(), new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ); } 1309 | '=' comma_expression // CFA 1310 { $$ = forCtrl( $2, new string( DeclarationNode::anonymous.newName() ), new ExpressionNode( build_constantInteger( *new string( "0" ) ) ), 1311 OperKinds::LEThan, $2->clone(), new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ); } 1312 | comma_expression inclexcl comma_expression // CFA 1313 { $$ = forCtrl( $1, new string( DeclarationNode::anonymous.newName() ), $1->clone(), $2, $3, new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ); } 1314 | comma_expression inclexcl comma_expression '~' comma_expression // CFA 1315 { $$ = forCtrl( $1, new string( DeclarationNode::anonymous.newName() ), $1->clone(), $2, $3, $5 ); } 1316 | comma_expression ';' // CFA 1317 { $$ = forCtrl( new ExpressionNode( build_constantInteger( *new string( "0u" ) ) ), $1, nullptr, OperKinds::LThan, nullptr, nullptr ); } 1325 { $$ = forCtrl( $1, new string( DeclarationNode::anonymous.newName() ), NEW_ZERO, OperKinds::LThan, $1->clone(), NEW_ONE ); } 1326 | downupdowneq comma_expression // CFA 1327 { $$ = forCtrl( $2, new string( DeclarationNode::anonymous.newName() ), UPDOWN( $1, NEW_ZERO, $2->clone() ), $1, UPDOWN( $1, $2->clone(), NEW_ZERO ), NEW_ONE ); } 1328 1329 | comma_expression updowneq comma_expression // CFA 1330 { $$ = forCtrl( $1, new string( DeclarationNode::anonymous.newName() ), UPDOWN( $2, $1->clone(), $3 ), $2, UPDOWN( $2, $3->clone(), $1->clone() ), NEW_ONE ); } 1331 | '@' updowneq comma_expression // CFA 1332 { 1333 if ( $2 == OperKinds::LThan || $2 == OperKinds::LEThan ) { SemanticError( yylloc, "Missing start value so cannot compare." ); $$ = nullptr; } 1334 else $$ = forCtrl( $3, new string( DeclarationNode::anonymous.newName() ), $3->clone(), $2, nullptr, NEW_ONE ); 1335 } 1336 | comma_expression updowneq '@' // CFA 1337 { 1338 if ( $2 == OperKinds::LThan || $2 == OperKinds::LEThan ) { SemanticError( yylloc, "Missing comparison ('@') with an anonymous loop index is meaningless." ); $$ = nullptr; } 1339 else { SemanticError( yylloc, "Missing start value so cannot compare." ); $$ = nullptr; } 1340 } 1341 | comma_expression updowneq comma_expression '~' comma_expression // CFA 1342 { $$ = forCtrl( $1, new string( DeclarationNode::anonymous.newName() ), UPDOWN( $2, $1->clone(), $3 ), $2, UPDOWN( $2, $3->clone(), $1->clone() ), $5 ); } 1343 | '@' updowneq comma_expression '~' comma_expression // CFA 1344 { 1345 if ( $2 == OperKinds::LThan || $2 == OperKinds::LEThan ) { SemanticError( yylloc, "Missing start value so cannot compare." ); $$ = nullptr; } 1346 else $$ = forCtrl( $3, new string( DeclarationNode::anonymous.newName() ), $3->clone(), $2, nullptr, $5 ); 1347 } 1348 | comma_expression updowneq '@' '~' comma_expression // CFA 1349 { 1350 if ( $2 == OperKinds::LThan || $2 == OperKinds::LEThan ) { SemanticError( yylloc, "Missing comparison ('@') with an anonymous loop index is meaningless." ); $$ = nullptr; } 1351 else { SemanticError( yylloc, "Missing start value so cannot compare." ); $$ = nullptr; } 1352 } 1353 | comma_expression updowneq comma_expression '~' '@' // CFA, error 1354 { SemanticError( yylloc, "Missing increment ('@') with an anonymous loop index is meaningless." ); $$ = nullptr; } 1355 | '@' updowneq comma_expression '~' '@' // CFA, error 1356 { SemanticError( yylloc, "Missing loop fields ('@') with an anonymous loop index is meaningless." ); $$ = nullptr; } 1357 | comma_expression updowneq '@' '~' '@' // CFA, error 1358 { SemanticError( yylloc, "Missing loop fields ('@') with an anonymous loop index is meaningless." ); $$ = nullptr; } 1359 | '@' updowneq '@' '~' '@' // CFA, error 1360 { SemanticError( yylloc, "Missing loop fields ('@') with an anonymous loop index is meaningless." ); $$ = nullptr; } 1361 1318 1362 | comma_expression ';' comma_expression // CFA 1319 { $$ = forCtrl( $3, $1, new ExpressionNode( build_constantInteger( *new string( "0" ) ) ), 1320 OperKinds::LThan, $3->clone(), new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ); } 1321 | comma_expression ';' '=' comma_expression // CFA 1322 { $$ = forCtrl( $4, $1, new ExpressionNode( build_constantInteger( *new string( "0" ) ) ), 1323 OperKinds::LEThan, $4->clone(), new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ); } 1324 | comma_expression ';' comma_expression inclexcl comma_expression // CFA 1325 { $$ = forCtrl( $3, $1, $3->clone(), $4, $5, new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ); } 1326 | comma_expression ';' comma_expression inclexcl comma_expression '~' comma_expression // CFA 1327 { $$ = forCtrl( $3, $1, $3->clone(), $4, $5, $7 ); } 1363 { $$ = forCtrl( $3, $1, NEW_ZERO, OperKinds::LThan, $3->clone(), NEW_ONE ); } 1364 | comma_expression ';' downupdowneq comma_expression // CFA 1365 { $$ = forCtrl( $4, $1, UPDOWN( $3, NEW_ZERO, $4->clone() ), $3, UPDOWN( $3, $4->clone(), NEW_ZERO ), NEW_ONE ); } 1366 1367 | comma_expression ';' comma_expression updowneq comma_expression // CFA 1368 { $$ = forCtrl( $3, $1, UPDOWN( $4, $3->clone(), $5 ), $4, UPDOWN( $4, $5->clone(), $3->clone() ), NEW_ONE ); } 1369 | comma_expression ';' '@' updowneq comma_expression // CFA 1370 { 1371 if ( $4 == OperKinds::LThan || $4 == OperKinds::LEThan ) { SemanticError( yylloc, "Missing start value so cannot compare." ); $$ = nullptr; } 1372 else $$ = forCtrl( $5, $1, $5->clone(), $4, nullptr, NEW_ONE ); 1373 } 1374 | comma_expression ';' comma_expression updowneq '@' // CFA 1375 { 1376 if ( $4 == OperKinds::GThan || $4 == OperKinds::GEThan ) { SemanticError( yylloc, "Missing start value so cannot compare." ); $$ = nullptr; } 1377 else if ( $4 == OperKinds::LEThan ) { SemanticError( yylloc, "Equality with missing comparison is meaningless. Use \"~\"." ); $$ = nullptr; } 1378 else $$ = forCtrl( $3, $1, $3->clone(), $4, nullptr, NEW_ONE ); 1379 } 1380 | comma_expression ';' '@' updowneq '@' // CFA, error 1381 { SemanticError( yylloc, "Missing start value so cannot compare." ); $$ = nullptr; } 1382 1383 | comma_expression ';' comma_expression updowneq comma_expression '~' comma_expression // CFA 1384 { $$ = forCtrl( $3, $1, UPDOWN( $4, $3->clone(), $5 ), $4, UPDOWN( $4, $5->clone(), $3->clone() ), $7 ); } 1385 | comma_expression ';' '@' updowneq comma_expression '~' comma_expression // CFA, error 1386 { 1387 if ( $4 == OperKinds::LThan || $4 == OperKinds::LEThan ) { SemanticError( yylloc, "Missing start value so cannot compare." ); $$ = nullptr; } 1388 else $$ = forCtrl( $5, $1, $5->clone(), $4, nullptr, $7 ); 1389 } 1390 | comma_expression ';' comma_expression updowneq '@' '~' comma_expression // CFA 1391 { 1392 if ( $4 == OperKinds::GThan || $4 == OperKinds::GEThan ) { SemanticError( yylloc, "Missing start value so cannot compare." ); $$ = nullptr; } 1393 else if ( $4 == OperKinds::LEThan ) { SemanticError( yylloc, "Equality with missing comparison is meaningless. Use \"~\"." ); $$ = nullptr; } 1394 else $$ = forCtrl( $3, $1, $3->clone(), $4, nullptr, $7 ); 1395 } 1396 | comma_expression ';' comma_expression updowneq comma_expression '~' '@' // CFA 1397 { $$ = forCtrl( $3, $1, UPDOWN( $4, $3->clone(), $5 ), $4, UPDOWN( $4, $5->clone(), $3->clone() ), nullptr ); } 1398 | comma_expression ';' '@' updowneq comma_expression '~' '@' // CFA, error 1399 { 1400 if ( $4 == OperKinds::LThan || $4 == OperKinds::LEThan ) { SemanticError( yylloc, "Missing start value so cannot compare." ); $$ = nullptr; } 1401 else $$ = forCtrl( $5, $1, $5->clone(), $4, nullptr, nullptr ); 1402 } 1403 | comma_expression ';' comma_expression updowneq '@' '~' '@' // CFA 1404 { 1405 if ( $4 == OperKinds::GThan || $4 == OperKinds::GEThan ) { SemanticError( yylloc, "Missing start value so cannot compare." ); $$ = nullptr; } 1406 else if ( $4 == OperKinds::LEThan ) { SemanticError( yylloc, "Equality with missing comparison is meaningless. Use \"~\"." ); $$ = nullptr; } 1407 else $$ = forCtrl( $3, $1, $3->clone(), $4, nullptr, nullptr ); 1408 } 1409 | comma_expression ';' '@' updowneq '@' '~' '@' // CFA 1410 { SemanticError( yylloc, "Missing start value so cannot compare." ); $$ = nullptr; } 1411 1412 | declaration comma_expression // CFA 1413 { $$ = forCtrl( $1, NEW_ZERO, OperKinds::LThan, $2, NEW_ONE ); } 1414 | declaration downupdowneq comma_expression // CFA 1415 { $$ = forCtrl( $1, UPDOWN( $2, NEW_ZERO, $3 ), $2, UPDOWN( $2, $3->clone(), NEW_ZERO ), NEW_ONE ); } 1416 1417 | declaration comma_expression updowneq comma_expression // CFA 1418 { $$ = forCtrl( $1, UPDOWN( $3, $2->clone(), $4 ), $3, UPDOWN( $3, $4->clone(), $2->clone() ), NEW_ONE ); } 1419 | declaration '@' updowneq comma_expression // CFA 1420 { 1421 if ( $3 == OperKinds::LThan || $3 == OperKinds::LEThan ) { SemanticError( yylloc, "Missing start value so cannot compare." ); $$ = nullptr; } 1422 else $$ = forCtrl( $1, $4, $3, nullptr, NEW_ONE ); 1423 } 1424 | declaration comma_expression updowneq '@' // CFA 1425 { 1426 if ( $3 == OperKinds::GThan || $3 == OperKinds::GEThan ) { SemanticError( yylloc, "Missing start value so cannot compare." ); $$ = nullptr; } 1427 else if ( $3 == OperKinds::LEThan ) { SemanticError( yylloc, "Equality with missing comparison is meaningless. Use \"~\"." ); $$ = nullptr; } 1428 else $$ = forCtrl( $1, $2, $3, nullptr, NEW_ONE ); 1429 } 1430 1431 | declaration comma_expression updowneq comma_expression '~' comma_expression // CFA 1432 { $$ = forCtrl( $1, UPDOWN( $3, $2, $4 ), $3, UPDOWN( $3, $4->clone(), $2->clone() ), $6 ); } 1433 | declaration '@' updowneq comma_expression '~' comma_expression // CFA 1434 { 1435 if ( $3 == OperKinds::LThan || $3 == OperKinds::LEThan ) { SemanticError( yylloc, "Missing start value so cannot compare." ); $$ = nullptr; } 1436 else $$ = forCtrl( $1, $4, $3, nullptr, $6 ); 1437 } 1438 | declaration comma_expression updowneq '@' '~' comma_expression // CFA 1439 { 1440 if ( $3 == OperKinds::GThan || $3 == OperKinds::GEThan ) { SemanticError( yylloc, "Missing start value so cannot compare." ); $$ = nullptr; } 1441 else if ( $3 == OperKinds::LEThan ) { SemanticError( yylloc, "Equality with missing comparison is meaningless. Use \"~\"." ); $$ = nullptr; } 1442 else $$ = forCtrl( $1, $2, $3, nullptr, $6 ); 1443 } 1444 | declaration comma_expression updowneq comma_expression '~' '@' // CFA 1445 { $$ = forCtrl( $1, UPDOWN( $3, $2, $4 ), $3, UPDOWN( $3, $4->clone(), $2->clone() ), nullptr ); } 1446 | declaration '@' updowneq comma_expression '~' '@' // CFA 1447 { 1448 if ( $3 == OperKinds::LThan || $3 == OperKinds::LEThan ) { SemanticError( yylloc, "Missing start value so cannot compare." ); $$ = nullptr; } 1449 else $$ = forCtrl( $1, $4, $3, nullptr, nullptr ); 1450 } 1451 | declaration comma_expression updowneq '@' '~' '@' // CFA 1452 { 1453 if ( $3 == OperKinds::GThan || $3 == OperKinds::GEThan ) { SemanticError( yylloc, "Missing start value so cannot compare." ); $$ = nullptr; } 1454 else if ( $3 == OperKinds::LEThan ) { SemanticError( yylloc, "Equality with missing comparison is meaningless. Use \"~\"." ); $$ = nullptr; } 1455 else $$ = forCtrl( $1, $2, $3, nullptr, nullptr ); 1456 } 1457 | declaration '@' updowneq '@' '~' '@' // CFA, error 1458 { SemanticError( yylloc, "Missing start value so cannot compare." ); $$ = nullptr; } 1328 1459 1329 1460 | comma_expression ';' TYPEDEFname // CFA, array type 1330 1461 { 1331 SemanticError( yylloc, "Array interator is currently unimplemented." ); $$ = nullptr; 1332 $$ = forCtrl( new ExpressionNode( build_varref( $3 ) ), $1, nullptr, OperKinds::Range, nullptr, nullptr ); 1333 } 1334 1335 // There is a S/R conflicit if ~ and -~ are factored out. 1336 | comma_expression ';' comma_expression '~' '@' // CFA 1337 { $$ = forCtrl( $3, $1, $3->clone(), OperKinds::LThan, nullptr, new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ); } 1338 | comma_expression ';' comma_expression ErangeDown '@' // CFA 1339 { $$ = forCtrl( $3, $1, $3->clone(), OperKinds::GThan, nullptr, new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ); } 1340 | comma_expression ';' comma_expression '~' '@' '~' comma_expression // CFA 1341 { $$ = forCtrl( $3, $1, $3->clone(), OperKinds::LThan, nullptr, $7 ); } 1342 | comma_expression ';' comma_expression ErangeDown '@' '~' comma_expression // CFA 1343 { $$ = forCtrl( $3, $1, $3->clone(), OperKinds::GThan, nullptr, $7 ); } 1344 | comma_expression ';' comma_expression '~' '@' '~' '@' // CFA 1345 { $$ = forCtrl( $3, $1, $3->clone(), OperKinds::LThan, nullptr, nullptr ); } 1462 SemanticError( yylloc, "Type iterator is currently unimplemented." ); $$ = nullptr; 1463 //$$ = forCtrl( new ExpressionNode( build_varref( $3 ) ), $1, nullptr, OperKinds::Range, nullptr, nullptr ); 1464 } 1465 | comma_expression ';' downupdowneq TYPEDEFname // CFA, array type 1466 { 1467 if ( $3 == OperKinds::LEThan || $3 == OperKinds::GEThan ) { SemanticError( yylloc, "All enumation ranges are equal (all values). Remove \"=~\"." ); $$ = nullptr; } 1468 SemanticError( yylloc, "Type iterator is currently unimplemented." ); $$ = nullptr; 1469 } 1346 1470 ; 1347 1471 1348 inclexcl: 1472 downupdowneq: 1473 ErangeDown 1474 { $$ = OperKinds::GThan; } 1475 | ErangeUpEq 1476 { $$ = OperKinds::LEThan; } 1477 | ErangeDownEq 1478 { $$ = OperKinds::GEThan; } 1479 ; 1480 1481 updown: 1349 1482 '~' 1350 1483 { $$ = OperKinds::LThan; } 1484 | ErangeDown 1485 { $$ = OperKinds::GThan; } 1486 ; 1487 1488 updowneq: 1489 updown 1351 1490 | ErangeUpEq 1352 1491 { $$ = OperKinds::LEThan; } 1353 | ErangeDown1354 { $$ = OperKinds::GThan; }1355 1492 | ErangeDownEq 1356 1493 { $$ = OperKinds::GEThan; } … … 2395 2532 '{' enumerator_list comma_opt '}' 2396 2533 { $$ = DeclarationNode::newEnum( $3->name, $5, true )->addQualifiers( $2 ); } 2534 | ENUM '(' ')' attribute_list_opt '{' enumerator_list comma_opt '}' 2535 { SemanticError( yylloc, "Unvalued enumerated type is currently unimplemented." ); $$ = nullptr; } 2397 2536 | ENUM '(' cfa_abstract_parameter_declaration ')' attribute_list_opt '{' enumerator_list comma_opt '}' 2398 2537 { -
src/Virtual/ExpandCasts.cc
r62c5a55 r181036c 10 10 // Created On : Mon Jul 24 13:59:00 2017 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Fri Jul 31 10:29:00 202013 // Update Count : 412 // Last Modified On : Thu Aug 11 12:06:00 2022 13 // Update Count : 5 14 14 // 15 15 … … 20 20 #include <string> // for string, allocator, operator==, ope... 21 21 22 #include "AST/Decl.hpp" 23 #include "AST/Expr.hpp" 24 #include "AST/Pass.hpp" 22 25 #include "Common/PassVisitor.h" // for PassVisitor 23 26 #include "Common/ScopedMap.h" // for ScopedMap … … 32 35 namespace Virtual { 33 36 34 static bool is_prefix( const std::string & prefix, const std::string& entire ) { 37 namespace { 38 39 bool is_prefix( const std::string & prefix, const std::string& entire ) { 35 40 size_t const p_size = prefix.size(); 36 41 return (p_size < entire.size() && prefix == entire.substr(0, p_size)); 37 42 } 38 43 39 staticbool is_type_id_object( const ObjectDecl * objectDecl ) {44 bool is_type_id_object( const ObjectDecl * objectDecl ) { 40 45 const std::string & objectName = objectDecl->name; 41 46 return is_prefix( "__cfatid_", objectName ); 47 } 48 49 bool is_type_id_object( const ast::ObjectDecl * decl ) { 50 return is_prefix( "__cfatid_", decl->name ); 42 51 } 43 52 … … 124 133 } 125 134 } 126 127 namespace {128 135 129 136 /// Better error locations for generated casts. … … 229 236 } 230 237 231 } // namespace232 233 238 Expression * VirtualCastCore::postmutate( VirtualCastExpr * castExpr ) { 234 239 assertf( castExpr->result, "Virtual Cast target not found before expansion." ); … … 265 270 } 266 271 267 void expandCasts( std::list< Declaration * > & translationUnit ) { 268 PassVisitor<VirtualCastCore> translator; 269 mutateAll( translationUnit, translator ); 270 } 271 } 272 /// Better error locations for generated casts. 273 // TODO: Does the improved distribution of code locations make this unneeded? 274 CodeLocation castLocation( const ast::VirtualCastExpr * castExpr ) { 275 if ( castExpr->location.isSet() ) { 276 return castExpr->location; 277 } else if ( castExpr->arg->location.isSet() ) { 278 return castExpr->arg->location; 279 } else { 280 return CodeLocation(); 281 } 282 } 283 284 [[noreturn]] void castError( ast::VirtualCastExpr const * castExpr, std::string const & message ) { 285 SemanticError( castLocation( castExpr ), message ); 286 } 287 288 class TypeIdTable final { 289 ScopedMap<std::string, ast::ObjectDecl const *> instances; 290 public: 291 void enterScope() { instances.beginScope(); } 292 void leaveScope() { instances.endScope(); } 293 294 // Attempt to insert an instance into the map. If there is a conflict, 295 // returns the previous declaration for error messages. 296 ast::ObjectDecl const * insert( ast::ObjectDecl const * typeIdDecl ) { 297 std::string const & mangledName = 298 Mangle::mangle( typeIdDecl->type, Mangle::typeMode() ); 299 ast::ObjectDecl const *& value = instances[ mangledName ]; 300 if ( value ) { 301 if ( typeIdDecl->storage.is_extern ) { 302 return nullptr; 303 } else if ( !value->storage.is_extern ) { 304 return value; 305 } 306 } 307 value = typeIdDecl; 308 return nullptr; 309 } 310 311 ast::ObjectDecl const * lookup( ast::Type const * typeIdType ) { 312 std::string const & mangledName = 313 Mangle::mangle( typeIdType, Mangle::typeMode() ); 314 auto const it = instances.find( mangledName ); 315 return ( instances.end() == it ) ? nullptr : it->second; 316 } 317 }; 318 319 struct ExpandCastsCore { 320 void previsit( ast::FunctionDecl const * decl ); 321 void previsit( ast::StructDecl const * decl ); 322 void previsit( ast::ObjectDecl const * decl ); 323 ast::Expr const * postvisit( ast::VirtualCastExpr const * expr ); 324 325 ast::CastExpr const * cast_to_type_id( 326 ast::Expr const * expr, unsigned int level_of_indirection ); 327 328 ast::FunctionDecl const * vcast_decl = nullptr; 329 ast::StructDecl const * info_decl = nullptr; 330 331 TypeIdTable symtab; 332 }; 333 334 void ExpandCastsCore::previsit( ast::FunctionDecl const * decl ) { 335 if ( !vcast_decl && "__cfavir_virtual_cast" == decl->name ) { 336 vcast_decl = decl; 337 } 338 } 339 340 void ExpandCastsCore::previsit( ast::StructDecl const * decl ) { 341 if ( !info_decl && decl->body && "__cfavir_type_info" == decl->name ) { 342 info_decl = decl; 343 } 344 } 345 346 void ExpandCastsCore::previsit( ast::ObjectDecl const * decl ) { 347 if ( is_type_id_object( decl ) ) { 348 // Multiple definitions should be fine because of linkonce. 349 symtab.insert( decl ); 350 } 351 } 352 353 /// Get the base type from a pointer or reference. 354 ast::Type const * getBaseType( ast::ptr<ast::Type> const & type ) { 355 if ( auto target = type.as<ast::PointerType>() ) { 356 return target->base.get(); 357 } else if ( auto target = type.as<ast::ReferenceType>() ) { 358 return target->base.get(); 359 } else { 360 return nullptr; 361 } 362 } 363 364 ast::StructInstType * polyCopy( 365 ast::StructInstType const * oldType, 366 ast::StructInstType const * newType ) { 367 assert( oldType->params.size() == newType->params.size() ); 368 ast::StructInstType * retType = ast::deepCopy( newType ); 369 if ( ! oldType->params.empty() ) { 370 retType->params.clear(); 371 for ( auto oldParams : oldType->params ) { 372 retType->params.push_back( ast::deepCopy( oldParams ) ); 373 } 374 } 375 return retType; 376 } 377 378 /// Follow the "head" field of the structure to get the type that is pointed 379 /// to by that field. 380 ast::StructInstType const * followHeadPointerType( 381 CodeLocation const & errorLocation, 382 ast::StructInstType const * oldType, 383 std::string const & fieldName ) { 384 ast::StructDecl const * oldDecl = oldType->base; 385 assert( oldDecl ); 386 387 // Helper function for throwing semantic errors. 388 auto throwError = [&fieldName, &errorLocation, &oldDecl]( 389 std::string const & message ) { 390 std::string const & context = "While following head pointer of " + 391 oldDecl->name + " named '" + fieldName + "': "; 392 SemanticError( errorLocation, context + message ); 393 }; 394 395 if ( oldDecl->members.empty() ) { 396 throwError( "Type has no fields." ); 397 } 398 ast::ptr<ast::Decl> const & memberDecl = oldDecl->members.front(); 399 assert( memberDecl ); 400 ast::ObjectDecl const * fieldDecl = memberDecl.as<ast::ObjectDecl>(); 401 assert( fieldDecl ); 402 if ( fieldName != fieldDecl->name ) { 403 throwError( "Head field did not have expected name." ); 404 } 405 406 ast::ptr<ast::Type> const & fieldType = fieldDecl->type; 407 if ( nullptr == fieldType ) { 408 throwError( "Could not get head field." ); 409 } 410 auto ptrType = fieldType.as<ast::PointerType>(); 411 if ( nullptr == ptrType ) { 412 throwError( "First field is not a pointer type." ); 413 } 414 assert( ptrType->base ); 415 auto newType = ptrType->base.as<ast::StructInstType>(); 416 if ( nullptr == newType ) { 417 throwError( "First field does not point to a structure type." ); 418 } 419 420 return polyCopy( oldType, newType ); 421 } 422 423 /// Get the type-id type from a virtual type. 424 ast::StructInstType const * getTypeIdType( 425 CodeLocation const & errorLocation, 426 ast::Type const * type ) { 427 auto typeInst = dynamic_cast<ast::StructInstType const *>( type ); 428 if ( nullptr == typeInst ) { 429 return nullptr; 430 } 431 ast::ptr<ast::StructInstType> tableInst = 432 followHeadPointerType( errorLocation, typeInst, "virtual_table" ); 433 if ( nullptr == tableInst ) { 434 return nullptr; 435 } 436 ast::StructInstType const * typeIdInst = 437 followHeadPointerType( errorLocation, tableInst, "__cfavir_typeid" ); 438 return typeIdInst; 439 } 440 441 ast::Expr const * ExpandCastsCore::postvisit( 442 ast::VirtualCastExpr const * expr ) { 443 assertf( expr->result, "Virtual cast target not found before expansion." ); 444 445 assert( vcast_decl ); 446 assert( info_decl ); 447 448 ast::Type const * base_type = getBaseType( expr->result ); 449 if ( nullptr == base_type ) { 450 castError( expr, "Virtual cast target must be a pointer or reference type." ); 451 } 452 ast::StructInstType const * type_id_type = 453 getTypeIdType( castLocation( expr ), base_type ); 454 if ( nullptr == type_id_type ) { 455 castError( expr, "Ill formed virtual cast target type." ); 456 } 457 ast::ObjectDecl const * type_id = symtab.lookup( type_id_type ); 458 if ( nullptr == type_id ) { 459 // I'm trying to give a different error for polymorpic types as 460 // different things can go wrong there. 461 if ( type_id_type->params.empty() ) { 462 castError( expr, "Virtual cast does not target a virtual type." ); 463 } else { 464 castError( expr, "Virtual cast does not target a type with a " 465 "type id (possible missing virtual table)." ); 466 } 467 } 468 469 return new ast::CastExpr( expr->location, 470 new ast::ApplicationExpr( expr->location, 471 ast::VariableExpr::functionPointer( expr->location, vcast_decl ), 472 { 473 cast_to_type_id( 474 new ast::AddressExpr( expr->location, 475 new ast::VariableExpr( expr->location, type_id ) ), 476 1 ), 477 cast_to_type_id( expr->arg, 2 ), 478 } 479 ), 480 ast::deepCopy( expr->result ) 481 ); 482 } 483 484 ast::CastExpr const * ExpandCastsCore::cast_to_type_id( 485 ast::Expr const * expr, unsigned int level_of_indirection ) { 486 assert( info_decl ); 487 ast::Type * type = new ast::StructInstType( info_decl, ast::CV::Const ); 488 for ( unsigned int i = 0 ; i < level_of_indirection ; ++i ) { 489 type = new ast::PointerType( type ); 490 } 491 return new ast::CastExpr( expr->location, expr, type ); 492 } 493 494 } // namespace 495 496 void expandCasts( std::list< Declaration * > & translationUnit ) { 497 PassVisitor<VirtualCastCore> translator; 498 mutateAll( translationUnit, translator ); 499 } 500 501 void expandCasts( ast::TranslationUnit & translationUnit ) { 502 ast::Pass<ExpandCastsCore>::run( translationUnit ); 503 } 504 505 } // namespace Virtual -
src/Virtual/ExpandCasts.h
r62c5a55 r181036c 10 10 // Created On : Mon Jul 24 13:54:00 2017 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Tus Jul 25 14:51:00 201713 // Update Count : 012 // Last Modified On : Fri Jul 29 14:40:00 2022 13 // Update Count : 1 14 14 // 15 15 … … 19 19 20 20 class Declaration; 21 namespace ast { 22 class TranslationUnit; 23 } 21 24 22 25 namespace Virtual { 23 void expandCasts( std::list< Declaration * > & translationUnit ); 24 // Breaks all virtual cast nodes up into translatable nodes. 26 void expandCasts( std::list< Declaration * > & translationUnit ); 27 void expandCasts( ast::TranslationUnit & translationUnit ); 28 // Breaks all virtual cast nodes up into translatable nodes. 25 29 26 30 // Later this might just set some information so it can happen at CodeGen. 27 31 28 32 } -
src/main.cc
r62c5a55 r181036c 10 10 // Created On : Fri May 15 23:12:02 2015 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Mon Jul 18 11:08:00 202213 // Update Count : 67 612 // Last Modified On : Thu 11 12:18:00 2022 13 // Update Count : 677 14 14 // 15 15 … … 445 445 PASS( "Expand Tuples", Tuples::expandTuples( transUnit ) ); 446 446 447 if ( tuplep ) { 448 dump( move( transUnit ) ); 449 return EXIT_SUCCESS; 450 } // if 451 452 // Must come after Translate Tries. 453 PASS( "Virtual Expand Casts", Virtual::expandCasts( transUnit ) ); 454 447 455 translationUnit = convert( move( transUnit ) ); 448 456 } else { … … 520 528 PASS( "Convert Specializations", GenPoly::convertSpecializations( translationUnit ) ); // needs to happen before tuple types are expanded 521 529 PASS( "Expand Tuples", Tuples::expandTuples( translationUnit ) ); // xxx - is this the right place for this? 530 531 if ( tuplep ) { 532 dump( translationUnit ); 533 return EXIT_SUCCESS; 534 } // if 535 536 PASS( "Virtual Expand Casts", Virtual::expandCasts( translationUnit ) ); // Must come after translateEHM 522 537 } 523 524 if ( tuplep ) {525 dump( translationUnit );526 return EXIT_SUCCESS;527 } // if528 529 PASS( "Virtual Expand Casts", Virtual::expandCasts( translationUnit ) ); // Must come after translateEHM530 538 531 539 PASS( "Instantiate Generics", GenPoly::instantiateGeneric( translationUnit ) ); -
tests/.expect/loop_else.txt
r62c5a55 r181036c 33 33 0 1 2 3 4 5 6 7 8 9 else 34 34 0 1 2 3 4 5 6 7 8 9 10 else 35 10 9 8 7 6 5 4 3 2 1 else35 10 9 8 7 6 5 4 3 2 1 0 else 36 36 37 37 3 6 9 else 38 39 (0 0)(1 1)(2 2)(3 3)(4 4)(5 5)(6 6)(7 7)(8 8)(9 9)else40 (0 0)(1 1)(2 2)(3 3)(4 4)(5 5)(6 6)(7 7)(8 8)(9 9)else41 42 (0 0)(1 1)(2 2)(3 3)(4 4)(5 5)(6 6)(7 7)(8 8)(9 9)else43 (0 0)(1 1)(2 2)(3 3)(4 4)(5 5)(6 6)(7 7)(8 8)(9 9)else44 (0 0)(1 1)(2 2)(3 3)(4 4)(5 5)(6 6)(7 7)(8 8)(9 9)(10 10)else45 (0 0)(1 1)(2 2)(3 3)(4 4)(5 5)(6 6)(7 7)(8 8)(9 9)(10 10)else46 47 (10 10)(9 9)(8 8)(7 7)(6 6)(5 5)(4 4)(3 3)(2 2)(1 1)else48 (10 10)(9 9)(8 8)(7 7)(6 6)(5 5)(4 4)(3 3)(2 2)(1 1)else49 (10 10)(9 9)(8 8)(7 7)(6 6)(5 5)(4 4)(3 3)(2 2)(1 1)(0 0)else50 (10 10)(9 9)(8 8)(7 7)(6 6)(5 5)(4 4)(3 3)(2 2)(1 1)(0 0)else51 38 52 39 0 -5 1 -4 2 -3 3 -2 4 -1 5 0 6 1 7 2 8 3 9 4 else … … 63 50 0 -5 1.5 1 -7 2.5 2 -9 3.5 3 -11 4.5 4 -13 5.5 5 -15 6.5 6 -17 7.5 7 -19 8.5 8 -21 9.5 9 -23 10.5 else 64 51 0 -5 1.5 1 -7 2.5 2 -9 3.5 3 -11 4.5 4 -13 5.5 5 -15 6.5 6 -17 7.5 7 -19 8.5 8 -21 9.5 9 -23 10.5 else 52 (0 0)(1 1)(2 2)(3 3)(4 4)(5 5)(6 6)(7 7)(8 8)(9 9)else 53 (0 0)(1 1)(2 2)(3 3)(4 4)(5 5)(6 6)(7 7)(8 8)(9 9)else 54 55 (0 0)(1 1)(2 2)(3 3)(4 4)(5 5)(6 6)(7 7)(8 8)(9 9)else 56 (0 0)(1 1)(2 2)(3 3)(4 4)(5 5)(6 6)(7 7)(8 8)(9 9)else 57 (0 0)(1 1)(2 2)(3 3)(4 4)(5 5)(6 6)(7 7)(8 8)(9 9)(10 10)else 58 (0 0)(1 1)(2 2)(3 3)(4 4)(5 5)(6 6)(7 7)(8 8)(9 9)(10 10)else 59 60 (10 10)(9 9)(8 8)(7 7)(6 6)(5 5)(4 4)(3 3)(2 2)(1 1)else 61 (10 10)(9 9)(8 8)(7 7)(6 6)(5 5)(4 4)(3 3)(2 2)(1 1)else 62 (10 10)(9 9)(8 8)(7 7)(6 6)(5 5)(4 4)(3 3)(2 2)(1 1)(0 0)else 63 (10 10)(9 9)(8 8)(7 7)(6 6)(5 5)(4 4)(3 3)(2 2)(1 1)(0 0)else 64 -
tests/.expect/loopctrl.txt
r62c5a55 r181036c 31 31 0 1 2 3 4 5 6 7 8 9 32 32 0 1 2 3 4 5 6 7 8 9 10 33 10 9 8 7 6 5 4 3 2 1 33 10 9 8 7 6 5 4 3 2 1 0 34 34 35 35 3 6 9 36 37 (0 0)(1 1)(2 2)(3 3)(4 4)(5 5)(6 6)(7 7)(8 8)(9 9)38 (0 0)(1 1)(2 2)(3 3)(4 4)(5 5)(6 6)(7 7)(8 8)(9 9)39 40 (0 0)(1 1)(2 2)(3 3)(4 4)(5 5)(6 6)(7 7)(8 8)(9 9)41 (0 0)(1 1)(2 2)(3 3)(4 4)(5 5)(6 6)(7 7)(8 8)(9 9)42 (0 0)(1 1)(2 2)(3 3)(4 4)(5 5)(6 6)(7 7)(8 8)(9 9)(10 10)43 (0 0)(1 1)(2 2)(3 3)(4 4)(5 5)(6 6)(7 7)(8 8)(9 9)(10 10)44 45 (10 10)(9 9)(8 8)(7 7)(6 6)(5 5)(4 4)(3 3)(2 2)(1 1)46 (10 10)(9 9)(8 8)(7 7)(6 6)(5 5)(4 4)(3 3)(2 2)(1 1)47 (10 10)(9 9)(8 8)(7 7)(6 6)(5 5)(4 4)(3 3)(2 2)(1 1)(0 0)48 (10 10)(9 9)(8 8)(7 7)(6 6)(5 5)(4 4)(3 3)(2 2)(1 1)(0 0)49 36 50 37 0 -5 1 -4 2 -3 3 -2 4 -1 5 0 6 1 7 2 8 3 9 4 … … 61 48 0 -5 1.5 1 -7 2.5 2 -9 3.5 3 -11 4.5 4 -13 5.5 5 -15 6.5 6 -17 7.5 7 -19 8.5 8 -21 9.5 9 -23 10.5 62 49 0 -5 1.5 1 -7 2.5 2 -9 3.5 3 -11 4.5 4 -13 5.5 5 -15 6.5 6 -17 7.5 7 -19 8.5 8 -21 9.5 9 -23 10.5 50 (0 0)(1 1)(2 2)(3 3)(4 4)(5 5)(6 6)(7 7)(8 8)(9 9) 51 (0 0)(1 1)(2 2)(3 3)(4 4)(5 5)(6 6)(7 7)(8 8)(9 9) 52 53 (0 0)(1 1)(2 2)(3 3)(4 4)(5 5)(6 6)(7 7)(8 8)(9 9) 54 (0 0)(1 1)(2 2)(3 3)(4 4)(5 5)(6 6)(7 7)(8 8)(9 9) 55 (0 0)(1 1)(2 2)(3 3)(4 4)(5 5)(6 6)(7 7)(8 8)(9 9)(10 10) 56 (0 0)(1 1)(2 2)(3 3)(4 4)(5 5)(6 6)(7 7)(8 8)(9 9)(10 10) 57 58 (10 10)(9 9)(8 8)(7 7)(6 6)(5 5)(4 4)(3 3)(2 2)(1 1) 59 (10 10)(9 9)(8 8)(7 7)(6 6)(5 5)(4 4)(3 3)(2 2)(1 1) 60 (10 10)(9 9)(8 8)(7 7)(6 6)(5 5)(4 4)(3 3)(2 2)(1 1)(0 0) 61 (10 10)(9 9)(8 8)(7 7)(6 6)(5 5)(4 4)(3 3)(2 2)(1 1)(0 0) 62 63 A A A A A A A A A A 64 B B B B B B B B B B B 65 C C C C C C C C C C 66 D D D D D D D D D D D 67 A A A A A A A A A A 68 B B B B B B B B B B B 69 C C C C C C C C C C 70 D D D D D D D D D D D 71 A A A A A 72 B B B B B B 73 C C C C C 74 D D D D D D 75 0 1 2 3 4 5 6 7 8 9 76 0 1 2 3 4 5 6 7 8 9 10 77 10 9 8 7 6 5 4 3 2 1 78 10 9 8 7 6 5 4 3 2 1 0 79 0 1 2 3 4 5 6 7 8 9 80 0 1 2 3 4 5 6 7 8 9 10 81 10 9 8 7 6 5 4 3 2 1 82 10 9 8 7 6 5 4 3 2 1 0 83 0 2 4 6 8 84 0 2 4 6 8 10 85 10 8 6 4 2 86 10 8 6 4 2 0 87 0 1 2 3 4 5 6 7 8 9 88 0 1 2 3 4 5 6 7 8 9 89 0 1 2 3 4 5 6 7 8 9 10 90 10 9 8 7 6 5 4 3 2 1 91 10 9 8 7 6 5 4 3 2 1 0 92 0 1 2 3 4 5 6 7 8 9 93 0 1 2 3 4 5 6 7 8 9 10 94 10 9 8 7 6 5 4 3 2 1 95 10 9 8 7 6 5 4 3 2 1 0 96 0 2 4 6 8 97 0 2 4 6 8 10 98 10 8 6 4 2 99 10 8 6 4 2 0 100 0 1 2 3 4 5 6 7 8 9 101 0 -1 -2 -3 -4 -5 -6 -7 -8 -9 102 0 2 4 6 8 103 0 -2 -4 -6 -8 104 0 1 2 3 4 5 6 7 8 9 105 0 2 4 6 8 106 0 -2 -4 -6 -8 107 0 2 4 6 8 108 0 -2 -4 -6 -8 109 0 1 2 3 4 5 6 7 8 9 -
tests/heap.cfa
r62c5a55 r181036c 10 10 // Created On : Tue Nov 6 17:54:56 2018 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Tue Dec 15 12:11:51 202013 // Update Count : 7912 // Last Modified On : Wed Aug 10 09:57:01 2022 13 // Update Count : 86 14 14 // 15 15 … … 26 26 // return __CFA_DEFAULT_PREEMPTION__; 27 27 // } 28 29 size_t default_heap_expansion() {30 return 10 * 1024 * 1024;31 } // default_heap_expansion32 33 size_t default_mmap_start() {34 return 512 * 1024 + 1;35 } // default_mmap_start36 28 37 29 thread Worker { … … 66 58 for ( k; i ) locns[i][k] = '\345'; 67 59 } // for 68 for ( i; NoOfAllocs - 1 -~= 0) {60 for ( i; -~= NoOfAllocs - 1 ) { 69 61 //sout | (void *)locns[i]; 70 62 for ( k; i ) if ( locns[i][k] != '\345' ) abort( "new/delete corrupt storage2" ); … … 99 91 100 92 for ( i; NoOfMmaps ) { 101 size_t s = i + default_mmap_start(); // cross over point93 size_t s = i + malloc_mmap_start(); // cross over point 102 94 char * area = (char *)malloc( s ); 103 95 area[0] = '\345'; area[s - 1] = '\345'; // fill first/last … … 107 99 108 100 for ( i; NoOfMmaps ) { 109 size_t s = i + default_mmap_start(); // cross over point101 size_t s = i + malloc_mmap_start(); // cross over point 110 102 locns[i] = (char *)malloc( s ); 111 103 locns[i][0] = '\345'; locns[i][s - 1] = '\345'; // fill first/last … … 113 105 } // for 114 106 for ( i; NoOfMmaps ) { 115 size_t s = i + default_mmap_start(); // cross over point107 size_t s = i + malloc_mmap_start(); // cross over point 116 108 if ( locns[i][0] != '\345' || locns[i][s - 1] != '\345' || 117 109 locns[i][malloc_usable_size( locns[i] ) - 1] != '\345' ) abort( "malloc/free corrupt storage" ); … … 151 143 152 144 for ( i; NoOfMmaps ) { 153 size_t s = i + default_mmap_start(); // cross over point145 size_t s = i + malloc_mmap_start(); // cross over point 154 146 char * area = (char *)calloc( 1, s ); 155 147 if ( area[0] != '\0' || area[s - 1] != '\0' ) abort( "calloc/free corrupt storage4.1" ); … … 162 154 163 155 for ( i; NoOfMmaps ) { 164 size_t s = i + default_mmap_start(); // cross over point156 size_t s = i + malloc_mmap_start(); // cross over point 165 157 locns[i] = (char *)calloc( 1, s ); 166 158 if ( locns[i][0] != '\0' || locns[i][s - 1] != '\0' || … … 171 163 } // for 172 164 for ( i; NoOfMmaps ) { 173 size_t s = i + default_mmap_start(); // cross over point165 size_t s = i + malloc_mmap_start(); // cross over point 174 166 if ( locns[i][0] != '\345' || locns[i][s - 1] != '\345' || 175 167 locns[i][malloc_usable_size( locns[i] ) - 1] != '\345' ) abort( "calloc/free corrupt storage6" ); … … 198 190 //sout | alignments[a]; 199 191 for ( i; 1 ~ NoOfMmaps ) { 200 size_t s = i + default_mmap_start(); // cross over point192 size_t s = i + malloc_mmap_start(); // cross over point 201 193 char * area = (char *)memalign( a, s ); 202 194 //sout | i | area; … … 232 224 for ( i; 2 ~ NoOfAllocs ~ 12 ) { 233 225 // initial N byte allocation 234 size_t s = i + default_mmap_start(); // cross over point226 size_t s = i + malloc_mmap_start(); // cross over point 235 227 char * area = (char *)malloc( s ); 236 228 area[0] = '\345'; area[s - 1] = '\345'; // fill first/penultimate byte … … 269 261 for ( i; 2 ~ NoOfAllocs ~ 12 ) { 270 262 // initial N byte allocation 271 size_t s = i + default_mmap_start(); // cross over point263 size_t s = i + malloc_mmap_start(); // cross over point 272 264 char * area = (char *)malloc( s ); 273 265 area[0] = '\345'; area[s - 1] = '\345'; // fill first/penultimate byte … … 307 299 for ( i; 1 ~ 10_000 ~ 12 ) { 308 300 // initial N byte allocation 309 size_t s = i + default_mmap_start(); // cross over point301 size_t s = i + malloc_mmap_start(); // cross over point 310 302 char * area = (char *)calloc( 1, s ); 311 303 if ( area[0] != '\0' || area[s - 1] != '\0' || … … 481 473 482 474 int main() { 483 const unsigned int NoOfWorkers = 4;475 enum { NoOfWorkers = 4 }; 484 476 { 485 477 processor processors[NoOfWorkers - 1] __attribute__(( unused )); // more than one processor -
tests/loop_else.cfa
r62c5a55 r181036c 20 20 21 21 int main() { 22 sout | nlOff; // turn off auto newline 23 while () { sout | "empty"; break; } else { sout | "else"; } sout | nl; 24 do { sout | "empty"; break; } while () else { sout | "else"; } sout | nl; 25 for () { sout | "empty"; break; } else { sout | "else"; } sout | nl | nl; 22 // Test some loop options. 26 23 27 do { sout | "false"; } while (false) else { sout | "else"; } sout | nl | nl; 24 sout | nlOff; // turn off auto newline 25 while () { sout | "empty"; break; } else { sout | "else"; } sout | nl; 26 do { sout | "empty"; break; } while () else { sout | "else"; } sout | nl; 27 for () { sout | "empty"; break; } else { sout | "else"; } sout | nl | nl; 28 28 29 for ( 0 ) { sout | "A"; } else { sout | "else"; } sout | "zero" | nl; 29 do { sout | "false"; } while (false) else { sout | "else"; } sout | nl | nl; 30 31 for ( 0 ) { sout | "A"; } else { sout | "else"; } sout | "zero" | nl; 30 32 for ( 1 ) { sout | "A"; } else { sout | "else"; } sout | nl; 31 for ( 10 ) { sout | "A"; } else { sout | "else"; } 32 for ( = 10 ) { sout | "A"; } else { sout | "else"; } sout | nl;33 for ( 10 ) { sout | "A"; } else { sout | "else"; } sout | nl; 34 for ( ~= 10 ) { sout | "A"; } else { sout | "else"; } sout | nl; 33 35 for ( 1 ~= 10 ~ 2 ) { sout | "B"; } else { sout | "else"; } sout | nl; 34 for ( 1 0 -~= 1~ 2 ) { sout | "C"; } else { sout | "else"; } sout | nl;36 for ( 1 -~= 10 ~ 2 ) { sout | "C"; } else { sout | "else"; } sout | nl; 35 37 for ( 0.5 ~ 5.5 ) { sout | "D"; } else { sout | "else"; } sout | nl; 36 for ( 5.5 -~ 0.5 ) { sout | "E"; } else { sout | "else"; } sout | nl | nl;38 for ( 0.5 -~ 5.5 ) { sout | "E"; } else { sout | "else"; } sout | nl | nl; 37 39 38 40 for ( i; 10 ) { sout | i; } else { sout | "else"; } sout | nl; 39 for ( i; = 10 ) { sout | i; } else { sout | "else"; } sout | nl;41 for ( i; ~= 10 ) { sout | i; } else { sout | "else"; } sout | nl; 40 42 for ( i; 1 ~= 10 ~ 2 ) { sout | i; } else { sout | "else"; } sout | nl; 41 for ( i; 1 0 -~= 1~ 2 ) { sout | i; } else { sout | "else"; } sout | nl;43 for ( i; 1 -~= 10 ~ 2 ) { sout | i; } else { sout | "else"; } sout | nl; 42 44 for ( i; 0.5 ~ 5.5 ) { sout | i; } else { sout | "else"; } sout | nl; 43 for ( i; 5.5 -~ 0.5 ) { sout | i; } else { sout | "else"; } sout | nl;45 for ( i; 0.5 -~ 5.5 ) { sout | i; } else { sout | "else"; } sout | nl; 44 46 for ( ui; 2u ~= 10u ~ 2u ) { sout | ui; } else { sout | "else"; } sout | nl; 45 for ( ui; 10u -~= 2u ~ 2u ) { sout | ui; } else { sout | "else"; } sout | nl | nl;47 for ( ui; 2u -~= 10u ~ 2u ) { sout | ui; } else { sout | "else"; } sout | nl | nl; 46 48 47 49 // @ means do nothing … … 50 52 sout | i; 51 53 } else { sout | "else"; } sout | nl; 52 for ( i; 10 -~ @) {54 for ( i; @ -~ 10 ) { 53 55 if ( i < 0 ) break; 54 56 sout | i; … … 63 65 i += 1.7; 64 66 } else { sout | "else"; } sout | nl; 65 for ( i; 10 -~ @~ 2 ) {67 for ( i; @ -~ 10 ~ 2 ) { 66 68 if ( i < 0 ) break; 67 69 sout | i; … … 76 78 for ( N ) { sout | "N"; } else { sout | "else"; } sout | nl; 77 79 for ( i; N ) { sout | i; } else { sout | "else"; } sout | nl; 78 for ( i; = N ) { sout | i; } else { sout | "else"; } sout | nl;79 for ( i; N -~ 0) { sout | i; } else { sout | "else"; } sout | nl | nl;80 for ( i; ~= N ) { sout | i; } else { sout | "else"; } sout | nl; 81 for ( i; -~= N ) { sout | i; } else { sout | "else"; } sout | nl | nl; 80 82 81 83 const int start = 3, comp = 10, inc = 2; 82 84 for ( i; start ~ comp ~ inc + 1 ) { sout | i; } else { sout | "else"; } sout | nl | nl; 85 86 for ( i; 10 : j; -5 ~ @ ) { sout | i | j; } else { sout | "else"; } sout | nl; 87 for ( i; 10 : j; @ -~ -5 ) { sout | i | j; } else { sout | "else"; } sout | nl; 88 for ( i; 10 : j; -5 ~ @ ~ 2 ) { sout | i | j; } else { sout | "else"; } sout | nl; 89 for ( i; 10 : j; @ -~ -5 ~ 2 ) { sout | i | j; } else { sout | "else"; } sout | nl | nl; 90 91 for ( j; -5 ~ @ : i; 10 ) { sout | i | j; } else { sout | "else"; } sout | nl; 92 for ( j; @ -~ -5 : i; 10 ) { sout | i | j; } else { sout | "else"; } sout | nl; 93 for ( j; -5 ~ @ ~ 2 : i; 10 ) { sout | i | j; } else { sout | "else"; } sout | nl; 94 for ( j; @ -~ -5 ~ 2 : i; 10 ) { sout | i | j; } else { sout | "else"; } sout | nl | nl; 95 96 for ( j; @ -~ -5 ~ 2 : i; 10 : k; 1.5 ~ @ ) { sout | i | j | k; } else { sout | "else"; } sout | nl; 97 for ( j; @ -~ -5 ~ 2 : k; 1.5 ~ @ : i; 10 ) { sout | i | j | k; } else { sout | "else"; } sout | nl; 98 for ( k; 1.5 ~ @ : j; @ -~ -5 ~ 2 : i; 10 ) { sout | i | j | k; } else { sout | "else"; } sout | nl; 83 99 84 100 for ( S s = (S){0}; s < (S){10,10}; s += (S){1} ) { sout | s; } else { sout | "else"; } sout | nl; … … 90 106 for ( s; (S){0} ~= (S){10,10} ~ (S){1} ) { sout | s; } else { sout | "else"; } sout | nl; 91 107 sout | nl; 92 for ( s; (S){10,10} -~ (S){0} ) { sout | s; } else { sout | "else"; } sout | nl; 93 for ( s; (S){10,10} -~ (S){0} ~ (S){1} ) { sout | s; } else { sout | "else"; } sout | nl; 94 for ( s; (S){10,10} -~= (S){0} ) { sout | s; } else { sout | "else"; } sout | nl; 95 for ( s; (S){10,10} -~= (S){0} ~ (S){1} ) { sout | s; } else { sout | "else"; } sout | nl | nl; 96 97 for ( i; 10 : j; -5 ~ @ ) { sout | i | j; } else { sout | "else"; } sout | nl; 98 for ( i; 10 : j; -5 -~ @ ) { sout | i | j; } else { sout | "else"; } sout | nl; 99 for ( i; 10 : j; -5 ~ @ ~ 2 ) { sout | i | j; } else { sout | "else"; } sout | nl; 100 for ( i; 10 : j; -5 -~ @ ~ 2 ) { sout | i | j; } else { sout | "else"; } sout | nl | nl; 101 102 for ( j; -5 ~ @ : i; 10 ) { sout | i | j; } else { sout | "else"; } sout | nl; 103 for ( j; -5 -~ @ : i; 10 ) { sout | i | j; } else { sout | "else"; } sout | nl; 104 for ( j; -5 ~ @ ~ 2 : i; 10 ) { sout | i | j; } else { sout | "else"; } sout | nl; 105 for ( j; -5 -~ @ ~ 2 : i; 10 ) { sout | i | j; } else { sout | "else"; } sout | nl | nl; 106 107 for ( j; -5 -~ @ ~ 2 : i; 10 : k; 1.5 ~ @ ) { sout | i | j | k; } else { sout | "else"; } sout | nl; 108 for ( j; -5 -~ @ ~ 2 : k; 1.5 ~ @ : i; 10 ) { sout | i | j | k; } else { sout | "else"; } sout | nl; 109 for ( k; 1.5 ~ @ : j; -5 -~ @ ~ 2 : i; 10 ) { sout | i | j | k; } else { sout | "else"; } sout | nl; 108 for ( s; (S){0} -~ (S){10,10} ) { sout | s; } else { sout | "else"; } sout | nl; 109 for ( s; (S){0} -~ (S){10,10} ~ (S){1} ) { sout | s; } else { sout | "else"; } sout | nl; 110 for ( s; (S){0} -~= (S){10,10} ) { sout | s; } else { sout | "else"; } sout | nl; 111 for ( s; (S){0} -~= (S){10,10} ~ (S){1} ) { sout | s; } else { sout | "else"; } sout | nl | nl; 110 112 } -
tests/loopctrl.cfa
r62c5a55 r181036c 10 10 // Created On : Wed Aug 8 18:32:59 2018 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu Dec 12 17:55:26 201913 // Update Count : 1 0812 // Last Modified On : Thu Aug 11 23:04:35 2022 13 // Update Count : 160 14 14 // 15 15 16 16 #include <fstream.hfa> 17 18 void fred() { 19 // Test all possible loop syntax. 20 21 int s = 0, c = 10, i = 2; 22 23 for ( c ) { sout | "A"; } sout | nl; 24 for ( ~= c ) { sout | "B"; } sout | nl; 25 for ( -~ c ) { sout | "C"; } sout | nl; 26 for ( -~= c ) { sout | "D"; } sout | nl; 27 28 for ( s ~ c ) { sout | "A"; } sout | nl; 29 for ( s ~= c ) { sout | "B"; } sout | nl; 30 for ( s -~ c ) { sout | "C"; } sout | nl; 31 for ( s -~= c ) { sout | "D"; } sout | nl; 32 33 for ( s ~ c ~ i ) { sout | "A"; } sout | nl; 34 for ( s ~= c ~ i ) { sout | "B"; } sout | nl; 35 for ( s -~ c ~ i ) { sout | "C"; } sout | nl; 36 for ( s -~= c ~ i ) { sout | "D"; } sout | nl; 37 38 for ( j; c ) { sout | j; } sout | nl; 39 for ( j; ~= c ) { sout | j; } sout | nl; 40 for ( j; -~ c ) { sout | j; } sout | nl; 41 for ( j; -~= c ) { sout | j; } sout | nl; 42 43 for ( j; s ~ c ) { sout | j; } sout | nl; 44 for ( j; s ~= c ) { sout | j; } sout | nl; 45 for ( j; s -~ c ) { sout | j; } sout | nl; 46 for ( j; s -~= c ) { sout | j; } sout | nl; 47 48 for ( j; s ~ c ~ i ) { sout | j; } sout | nl; 49 for ( j; s ~= c ~ i ) { sout | j; } sout | nl; 50 for ( j; s -~ c ~ i ) { sout | j; } sout | nl; 51 for ( j; s -~= c ~ i ) { sout | j; } sout | nl; 52 53 // CANNOT DIRECTLY INITIALIZE INDEX VARIABLE, ONLY SINGLE LOOP INDEX VARIABLE IN DECLARATION 54 55 for ( j; c ) { sout | j; } sout | nl; 56 for ( int j; c ) { sout | j; } sout | nl; 57 for ( int j; ~= c ) { sout | j; } sout | nl; 58 for ( int j; -~ c ) { sout | j; } sout | nl; 59 for ( int j; -~= c ) { sout | j; } sout | nl; 60 61 for ( int j; s ~ c ) { sout | j; } sout | nl; 62 for ( int j; s ~= c ) { sout | j; } sout | nl; 63 for ( int j; s -~ c ) { sout | j; } sout | nl; 64 for ( int j; s -~= c ) { sout | j; } sout | nl; 65 66 for ( int j; s ~ c ~ i ) { sout | j; } sout | nl; 67 for ( int j; s ~= c ~ i ) { sout | j; } sout | nl; 68 for ( int j; s -~ c ~ i ) { sout | j; } sout | nl; 69 for ( int j; s -~= c ~ i ) { sout | j; } sout | nl; 70 71 for ( j; s ~ @ ) { if ( j == 10 ) break; sout | j; } sout | nl; 72 for ( j; @ -~ s ) { if ( j == -10 ) break; sout | j; } sout | nl; 73 for ( j; s ~ @ ~ i ) { if ( j == 10 ) break; sout | j; } sout | nl; 74 for ( j; @ -~ s ~ i ) { if ( j == -10 ) break; sout | j; } sout | nl; 75 for ( j; s ~ @ ~ @ ) { if ( j == 10 ) break; sout | j; j += 1; } sout | nl; 76 77 for ( int j; s ~ @ ) { if ( j == 10 ) break; sout | j; j += 1; } sout | nl; 78 for ( int j; @ -~ s ) { if ( j == -10 ) break; sout | j; j -= 1; } sout | nl; 79 for ( int j; s ~ @ ~ i ) { if ( j == 10 ) break; sout | j; } sout | nl; 80 for ( int j; @ -~ s ~ i ) { if ( j == -10 ) break; sout | j; } sout | nl; 81 for ( int j; s ~ @ ~ @ ) { if ( j == 10 ) break; sout | j; j += 1; } sout | nl; 82 83 // enum E { A, B, C, D }; 84 // for ( e; A ~= C ) { sout | j; } 85 // for ( e; A ~= D ) { sout | j; } 86 // for ( e; A -~= D ~ 2 ) { sout | j; } 87 // for ( e; E ) { sout | j; } 88 // for ( e; -~ E ) { sout | j; } 89 } 17 90 18 91 struct S { int i, j; }; … … 35 108 36 109 int main() { 110 // Test some loop options. 111 37 112 sout | nlOff; // turn off auto newline 38 113 while () { sout | "empty"; break; } sout | nl; … … 43 118 for ( 1 ) { sout | "A"; } sout | nl; 44 119 for ( 10 ) { sout | "A"; } sout | nl; 45 for ( = 10 ) { sout | "A"; } sout | nl;120 for ( ~= 10 ) { sout | "A"; } sout | nl; 46 121 for ( 1 ~= 10 ~ 2 ) { sout | "B"; } sout | nl; 47 for ( 1 0 -~= 1~ 2 ) { sout | "C"; } sout | nl;122 for ( 1 -~= 10 ~ 2 ) { sout | "C"; } sout | nl; 48 123 for ( 0.5 ~ 5.5 ) { sout | "D"; } sout | nl; 49 for ( 5.5 -~ 0.5 ) { sout | "E"; } sout | nl | nl;124 for ( 0.5 -~ 5.5 ) { sout | "E"; } sout | nl | nl; 50 125 51 126 for ( i; 10 ) { sout | i; } sout | nl; 52 for ( i; = 10 ) { sout | i; } sout | nl;127 for ( i; ~= 10 ) { sout | i; } sout | nl; 53 128 for ( i; 1 ~= 10 ~ 2 ) { sout | i; } sout | nl; 54 for ( i; 1 0 -~= 1~ 2 ) { sout | i; } sout | nl;129 for ( i; 1 -~= 10 ~ 2 ) { sout | i; } sout | nl; 55 130 for ( i; 0.5 ~ 5.5 ) { sout | i; } sout | nl; 56 for ( i; 5.5 -~ 0.5 ) { sout | i; } sout | nl;131 for ( i; 0.5 -~ 5.5 ) { sout | i; } sout | nl; 57 132 for ( ui; 2u ~= 10u ~ 2u ) { sout | ui; } sout | nl; 58 for ( ui; 10u -~= 2u ~ 2u ) { sout | ui; } sout | nl | nl;133 for ( ui; 2u -~= 10u ~ 2u ) { sout | ui; } sout | nl | nl; 59 134 60 135 // @ means do nothing … … 63 138 sout | i; 64 139 } sout | nl; 65 for ( i; 10 -~ @) {140 for ( i; @ -~ 10 ) { 66 141 if ( i < 0 ) break; 67 142 sout | i; … … 76 151 i += 1.7; 77 152 } sout | nl; 78 for ( i; 10 -~ @~ 2 ) {153 for ( i; @ -~ 10 ~ 2 ) { 79 154 if ( i < 0 ) break; 80 155 sout | i; … … 89 164 for ( N ) { sout | "N"; } sout | nl; 90 165 for ( i; N ) { sout | i; } sout | nl; 91 for ( i; = N ) { sout | i; } sout | nl;92 for ( i; N -~ 0) { sout | i; } sout | nl | nl;166 for ( i; ~= N ) { sout | i; } sout | nl; 167 for ( i; -~= N ) { sout | i; } sout | nl | nl; 93 168 94 169 const int start = 3, comp = 10, inc = 2; 95 170 for ( i; start ~ comp ~ inc + 1 ) { sout | i; } sout | nl | nl; 171 172 for ( i; 10 : j; -5 ~ @ ) { sout | i | j; } sout | nl; 173 for ( i; 10 : j; @ -~ -5 ) { sout | i | j; } sout | nl; 174 for ( i; 10 : j; -5 ~ @ ~ 2 ) { sout | i | j; } sout | nl; 175 for ( i; 10 : j; @ -~ -5 ~ 2 ) { sout | i | j; } sout | nl | nl; 176 177 for ( j; -5 ~ @ : i; 10 ) { sout | i | j; } sout | nl; 178 for ( j; @ -~ -5 : i; 10 ) { sout | i | j; } sout | nl; 179 for ( j; -5 ~ @ ~ 2 : i; 10 ) { sout | i | j; } sout | nl; 180 for ( j; @ -~ -5 ~ 2 : i; 10 ) { sout | i | j; } sout | nl | nl; 181 182 for ( j; @ -~ -5 ~ 2 : i; 10 : k; 1.5 ~ @ ) { sout | i | j | k; } sout | nl; 183 for ( j; @ -~ -5 ~ 2 : k; 1.5 ~ @ : i; 10 ) { sout | i | j | k; } sout | nl; 184 for ( k; 1.5 ~ @ : j; @ -~ -5 ~ 2 : i; 10 ) { sout | i | j | k; } sout | nl; 96 185 97 186 for ( S s = (S){0}; s < (S){10,10}; s += (S){1} ) { sout | s; } sout | nl; … … 103 192 for ( s; (S){0} ~= (S){10,10} ~ (S){1} ) { sout | s; } sout | nl; 104 193 sout | nl; 105 for ( s; (S){10,10} -~ (S){0} ) { sout | s; } sout | nl; 106 for ( s; (S){10,10} -~ (S){0} ~ (S){1} ) { sout | s; } sout | nl; 107 for ( s; (S){10,10} -~= (S){0} ) { sout | s; } sout | nl; 108 for ( s; (S){10,10} -~= (S){0} ~ (S){1} ) { sout | s; } sout | nl | nl; 109 110 for ( i; 10 : j; -5 ~ @ ) { sout | i | j; } sout | nl; 111 for ( i; 10 : j; -5 -~ @ ) { sout | i | j; } sout | nl; 112 for ( i; 10 : j; -5 ~ @ ~ 2 ) { sout | i | j; } sout | nl; 113 for ( i; 10 : j; -5 -~ @ ~ 2 ) { sout | i | j; } sout | nl | nl; 114 115 for ( j; -5 ~ @ : i; 10 ) { sout | i | j; } sout | nl; 116 for ( j; -5 -~ @ : i; 10 ) { sout | i | j; } sout | nl; 117 for ( j; -5 ~ @ ~ 2 : i; 10 ) { sout | i | j; } sout | nl; 118 for ( j; -5 -~ @ ~ 2 : i; 10 ) { sout | i | j; } sout | nl | nl; 119 120 for ( j; -5 -~ @ ~ 2 : i; 10 : k; 1.5 ~ @ ) { sout | i | j | k; } sout | nl; 121 for ( j; -5 -~ @ ~ 2 : k; 1.5 ~ @ : i; 10 ) { sout | i | j | k; } sout | nl; 122 for ( k; 1.5 ~ @ : j; -5 -~ @ ~ 2 : i; 10 ) { sout | i | j | k; } sout | nl; 194 for ( s; (S){0} -~ (S){10,10} ) { sout | s; } sout | nl; 195 for ( s; (S){0} -~ (S){10,10} ~ (S){1} ) { sout | s; } sout | nl; 196 for ( s; (S){0} -~= (S){10,10} ) { sout | s; } sout | nl; 197 for ( s; (S){0} -~= (S){10,10} ~ (S){1} ) { sout | s; } sout | nl | nl; 198 199 fred(); 123 200 } 124 201
Note: See TracChangeset
for help on using the changeset viewer.