| 545 | // types (which ARE valid here) from local vars in an (optional) forward |
| 546 | // ref type position. |
| 547 | private Type type() { |
| 548 | int old1 = _lexer._position; |
| 549 | String tname = _lexer.matchId(); |
| 550 | if( tname==null ) return null; |
| 551 | // Convert the type name to a type. |
| 552 | Type t0 = TYPES.get(tname); |
| 553 | Type t1 = t0 == null ? TypeMemPtr.make(TypeStruct.make(tname)) : t0; // Null: assume a forward ref type |
| 554 | // Nest arrays and '?' as needed |
| 555 | while( true ) { |
| 556 | assert !(t1 instanceof TypeStruct); |
| 557 | if( match("?") ) { |
| 558 | if( !(t1 instanceof TypeMemPtr tmp) ) |
| 559 | throw error("Type "+t0+" cannot be null"); |
| 560 | if( tmp._nil ) throw error("Type "+t1+" already allows null"); |
| 561 | t1 = TypeMemPtr.make(tmp._obj,true); |
| 562 | continue; |
| 563 | } |
| 564 | if( match("[]") ) { |
| 565 | t1 = typeAry(t1); |
| 566 | continue; |
| 567 | } |
| 568 | break; |
| 569 | } |
| 570 | |
| 571 | // Check no forward ref |
| 572 | if( t0 != null ) return t1; |
| 573 | // Check valid forward ref, after parsing all the type extra bits. |
| 574 | // Cannot check earlier, because cannot find required 'id' until after "[]?" syntax |
| 575 | int old2 = _lexer._position; |
| 576 | String id = _lexer.matchId(); |
| 577 | _lexer._position = old2; // Reset lexer to reparse |
| 578 | if( id==null ) { |
| 579 | _lexer._position = old1; // Reset lexer to reparse |
| 580 | return null; // Not a type |
| 581 | } |
| 582 | // Yes a forward ref, so declare it |
| 583 | TYPES.put(tname,t1); |
| 584 | return t1; |
| 585 | } |
| 586 | |
| 587 | // Make an array type of t |
| 588 | private TypeMemPtr typeAry( Type t ) { |