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