/*! * dictionary-type → [type:type] * array-type → [type] */ TypeNodePtr Parser::parseCollectionType() { Token token; expect(L"[", token); TypeNodePtr type = this->parseType(); if(match(L":")) { //it's a dictionary type TypeNodePtr valueType = parseType(); expect(L"]"); DictionaryTypePtr ret = nodeFactory->createDictionaryType(token.state); ret->setKeyType(type); ret->setValueType(valueType); return ret; } else { //it's an array type expect(L"]"); ArrayTypePtr ret = nodeFactory->createArrayType(token.state); ret->setInnerType(type); return ret; } }
TypeNodePtr Parser::parseType() { Token token; TypeNodePtr ret = NULL; expect_next(token); restore(token); if(token == TokenType::OpenParen) { ret = parseTupleType(); } else if(token.type == TokenType::Identifier && token.identifier.keyword == Keyword::_) { ret = parseTypeIdentifier(); } else if(token.type == TokenType::Identifier && token.identifier.keyword == Keyword::SelfType) { ret = parseTypeIdentifier(); } else if(token.getKeyword() == Keyword::Protocol) { ret = parseProtocolComposition(); } else if(token == TokenType::OpenBracket) { ret = parseCollectionType(); } else { unexpected(token); } do { if(!next(token)) break; //type chaining if(token == L"->") { //function-type → type->type TupleTypePtr argType = std::dynamic_pointer_cast<TupleType>(ret); if(!argType) { //wrap ret as a tuple type argType = nodeFactory->createTupleType(*ret->getSourceInfo()); argType->add(false, L"", ret); } TypeNodePtr retType = parseType(); FunctionTypePtr func = nodeFactory->createFunctionType(token.state); func->setArgumentsType(argType); func->setReturnType(retType); ret = func; continue; } if(token == TokenType::OpenBracket) { expect(L"]"); ArrayTypePtr array = nodeFactory->createArrayType(token.state); array->setInnerType(ret); ret = array; continue; } if(token == L"?") { //optional-type → type? OptionalTypePtr type = nodeFactory->createOptionalType(token.state); type->setInnerType(ret); ret = type; continue; } if(token == L"!") { //implicitly-unwrapped-optional-type → type! ImplicitlyUnwrappedOptionalPtr type = nodeFactory->createImplicitlyUnwrappedOptional(token.state); type->setInnerType(ret); ret = type; continue; } // metatype-type → type.Type type.Protocol //TODO meta type is not supported restore(token); break; }while(true); return ret; }