()
| 903 | |
| 904 | // t = int|i8|i16|i32|i64|u8|u16|u32|u64|byte|bool | flt|f32|f64 | val | var | struct[?] |
| 905 | private Type type() { |
| 906 | int old1 = pos(); |
| 907 | // Only type with a leading `{` is a function pointer... |
| 908 | if( peek('{') ) return typeFunPtr(); |
| 909 | |
| 910 | // Otherwise you get a type name |
| 911 | String tname = _lexer.matchId(); |
| 912 | if( tname==null ) return null; |
| 913 | |
| 914 | // Convert the type name to a type. |
| 915 | Type t0 = TYPES.get(tname); |
| 916 | // No new types as keywords |
| 917 | if( t0 == null && KEYWORDS.contains(tname) ) |
| 918 | return posT(old1); |
| 919 | if( t0 == Type.BOTTOM || t0 == Type.TOP ) return t0; // var/val type inference |
| 920 | |
| 921 | // Check for subtype. |
| 922 | while( true ) { |
| 923 | int old2 = pos(); |
| 924 | if( !match(".") ) break; |
| 925 | String sname = _lexer.matchId(); |
| 926 | if( sname==null ) { pos(old2); break; } |
| 927 | String tsname = tname+"."+sname; |
| 928 | t0 = TYPES.get(tsname); |
| 929 | if( t0==null ) { pos(old2); t0 = TYPES.get(tname); break; } |
| 930 | tname = tsname; |
| 931 | } |
| 932 | |
| 933 | // Still no type found? Assume forward reference |
| 934 | Type t1 = t0 == null ? TypeMemPtr.make(TypeStruct.open(tname)) :t0; // Null: assume a forward ref type |
| 935 | // Nest arrays and '?' as needed |
| 936 | Type t2 = t1; |
| 937 | while( true ) { |
| 938 | if( match("?") ) { |
| 939 | if( !(t2 instanceof TypeMemPtr tmp) ) |
| 940 | throw error("Type "+t0+" cannot be null"); |
| 941 | if( tmp.nullable() ) throw error("Type "+t2+" already allows null"); |
| 942 | t2 = tmp.makeNullable(); |
| 943 | } else if( match("[~]") ) { |
| 944 | t2 = typeAry(t2,true); |
| 945 | } else if( match("[]") ) { |
| 946 | t2 = typeAry(t2,false); |
| 947 | } else |
| 948 | break; |
| 949 | } |
| 950 | |
| 951 | // Check no forward ref |
| 952 | if( t0 != null ) return t2; |
| 953 | // Check valid forward ref, after parsing all the type extra bits. |
| 954 | // Cannot check earlier, because cannot find required 'id' until after "[]?" syntax |
| 955 | int old2 = pos(); |
| 956 | match("!"); |
| 957 | String id = _lexer.matchId(); |
| 958 | if( !(peek(',') || peek(';') || match("->")) || id==null ) |
| 959 | return posT(old1); // Reset lexer to reparse |
| 960 | pos(old2); // Reset lexer to reparse |
| 961 | // Yes a forward ref, so declare it |
| 962 | TYPES.put(tname,t1); |
no test coverage detected