| 486 | // types (which ARE valid here) from local vars in an (optional) forward |
| 487 | // ref type position. |
| 488 | private Type type() { |
| 489 | int old1 = _lexer._position; |
| 490 | String tname = _lexer.matchId(); |
| 491 | if( tname==null ) return null; |
| 492 | // Convert the type name to a type. |
| 493 | Type t0 = TYPES.get(tname); |
| 494 | Type t1 = t0 == null ? TypeMemPtr.make(TypeStruct.make(tname)) : t0; // Null: assume a forward ref type |
| 495 | // Nest arrays and '?' as needed |
| 496 | while( true ) { |
| 497 | assert !(t1 instanceof TypeStruct); |
| 498 | if( match("?") ) { |
| 499 | if( !(t1 instanceof TypeMemPtr tmp) ) |
| 500 | throw error("Type "+t0+" cannot be null"); |
| 501 | if( tmp._nil ) throw error("Type "+t1+" already allows null"); |
| 502 | t1 = TypeMemPtr.make(tmp._obj,true); |
| 503 | continue; |
| 504 | } |
| 505 | if( match("[]") ) { |
| 506 | t1 = typeAry(t1); |
| 507 | continue; |
| 508 | } |
| 509 | break; |
| 510 | } |
| 511 | |
| 512 | // Check no forward ref |
| 513 | if( t0 != null ) return t1; |
| 514 | // Check valid forward ref, after parsing all the type extra bits. |
| 515 | // Cannot check earlier, because cannot find required 'id' until after "[]?" syntax |
| 516 | int old2 = _lexer._position; |
| 517 | String id = _lexer.matchId(); |
| 518 | _lexer._position = old2; // Reset lexer to reparse |
| 519 | if( id==null ) { |
| 520 | _lexer._position = old1; // Reset lexer to reparse |
| 521 | return null; // Not a type |
| 522 | } |
| 523 | // Yes a forward ref, so declare it |
| 524 | TYPES.put(tname,t1); |
| 525 | return t1; |
| 526 | } |
| 527 | |
| 528 | // Make an array type of t |
| 529 | private TypeMemPtr typeAry( Type t ) { |