()
| 781 | |
| 782 | // t = int|i8|i16|i32|i64|u8|u16|u32|u64|byte|bool | flt|f32|f64 | val | var | struct[?] |
| 783 | private Type type() { |
| 784 | int old1 = pos(); |
| 785 | // Only type with a leading `{` is a function pointer... |
| 786 | if( peek('{') ) return typeFunPtr(); |
| 787 | |
| 788 | // Otherwise you get a type name |
| 789 | String tname = _lexer.matchId(); |
| 790 | if( tname==null ) return null; |
| 791 | |
| 792 | // Convert the type name to a type. |
| 793 | Type t0 = TYPES.get(tname); |
| 794 | // No new types as keywords |
| 795 | if( t0 == null && KEYWORDS.contains(tname) ) |
| 796 | return posT(old1); |
| 797 | if( t0 == Type.BOTTOM || t0 == Type.TOP ) return t0; // var/val type inference |
| 798 | Type t1 = t0 == null ? TypeMemPtr.make(TypeStruct.makeFRef(tname)) :t0; // Null: assume a forward ref type |
| 799 | // Nest arrays and '?' as needed |
| 800 | Type t2 = t1; |
| 801 | while( true ) { |
| 802 | if( match("?") ) { |
| 803 | if( !(t2 instanceof TypeMemPtr tmp) ) |
| 804 | throw error("Type "+t0+" cannot be null"); |
| 805 | if( tmp.nullable() ) throw error("Type "+t2+" already allows null"); |
| 806 | t2 = tmp.makeNullable(); |
| 807 | } else if( match("[]") ) { |
| 808 | t2 = typeAry(t2); |
| 809 | } else |
| 810 | break; |
| 811 | } |
| 812 | |
| 813 | // Check no forward ref |
| 814 | if( t0 != null ) return t2; |
| 815 | // Check valid forward ref, after parsing all the type extra bits. |
| 816 | // Cannot check earlier, because cannot find required 'id' until after "[]?" syntax |
| 817 | int old2 = pos(); |
| 818 | match("!"); |
| 819 | String id = _lexer.matchId(); |
| 820 | if( !(peek(',') || peek(';') || match("->")) ) |
| 821 | return posT(old1); |
| 822 | pos(old2); // Reset lexer to reparse |
| 823 | if( id==null ) |
| 824 | return posT(old1); // Reset lexer to reparse |
| 825 | // Yes a forward ref, so declare it |
| 826 | TYPES.put(tname,t1); |
| 827 | return t2; |
| 828 | } |
| 829 | |
| 830 | // Make an array type of t |
| 831 | private TypeMemPtr typeAry( Type t ) { |
no test coverage detected