コード例 #1
0
ファイル: Name.cpp プロジェクト: PuerkitoBio/locic
	Name Name::makeAbsolute(const Name& name) const{
		assert(isAbsolute());
		assert(!name.empty());
		if(name.isAbsolute()) {
			return name.copy();
		} else {
			return concat(name);
		}
	}
コード例 #2
0
		SEM::TypeInstance* AddTypeInstance(Context& context, const AST::Node<AST::TypeInstance>& astTypeInstanceNode, const SEM::ModuleScope& moduleScope) {
			const auto parentNamespace = context.scopeStack().back().nameSpace();
			
			const auto& typeInstanceName = astTypeInstanceNode->name;
			
			const Name fullTypeName = parentNamespace->name() + typeInstanceName;
			
			// Check if there's anything with the same name.
			const auto iterator = parentNamespace->items().find(typeInstanceName);
			if (iterator != parentNamespace->items().end()) {
				const auto& existingTypeInstance = iterator->second.typeInstance();
				const auto& debugInfo = *(existingTypeInstance.debugInfo());
				throw ErrorException(makeString("Type instance name '%s', at position %s, clashes with existing name, at position %s.",
					fullTypeName.toString().c_str(), astTypeInstanceNode.location().toString().c_str(),
					debugInfo.location.toString().c_str()));
			}
			
			const auto typeInstanceKind = ConvertTypeInstanceKind(astTypeInstanceNode->kind);
			
			// Create a placeholder type instance.
			std::unique_ptr<SEM::TypeInstance> semTypeInstance(new SEM::TypeInstance(context.semContext(), fullTypeName.copy(), typeInstanceKind, moduleScope.copy()));
			
			if (semTypeInstance->isPrimitive()) {
				semTypeInstance->setPrimitiveID(context.sharedMaps().primitiveIDMap().getPrimitiveID(typeInstanceName));
			}
			
			switch (moduleScope.kind()) {
				case SEM::ModuleScope::INTERNAL: {
					if (semTypeInstance->isClassDecl()) {
						throw ErrorException(makeString("Definition required for internal class '%s', at location %s.",
							fullTypeName.toString().c_str(), astTypeInstanceNode.location().toString().c_str()));
					}
					break;
				}
				case SEM::ModuleScope::IMPORT: {
					if (semTypeInstance->isClassDef()) {
						throw ErrorException(makeString("Implementation not allowed of imported class '%s', at location %s.",
							fullTypeName.toString().c_str(), astTypeInstanceNode.location().toString().c_str()));
					}
					break;
				}
				case SEM::ModuleScope::EXPORT: {
					if (semTypeInstance->isClassDecl()) {
						throw ErrorException(makeString("Definition required for exported class '%s', at location %s.",
							fullTypeName.toString().c_str(), astTypeInstanceNode.location().toString().c_str()));
					}
					break;
				}
			}
			
			semTypeInstance->setDebugInfo(Debug::TypeInstanceInfo(astTypeInstanceNode.location()));
			
			// Add template variables.
			size_t templateVarIndex = 0;
			for (const auto& astTemplateVarNode: *(astTypeInstanceNode->templateVariables)) {
				const auto& templateVarName = astTemplateVarNode->name;
				// TODO!
				const bool isVirtual = (typeInstanceName == "__ref");
				const auto semTemplateVar =
					new SEM::TemplateVar(context.semContext(),
						fullTypeName + templateVarName,
						templateVarIndex++, isVirtual);
				
				const auto templateVarIterator = semTypeInstance->namedTemplateVariables().find(templateVarName);
				if (templateVarIterator != semTypeInstance->namedTemplateVariables().end()) {
					throw ErrorException(makeString("More than one template variable shares name '%s' in type '%s', at location %s.",
						templateVarName.c_str(), fullTypeName.toString().c_str(),
						astTemplateVarNode.location().toString().c_str()));
				}
				
				semTemplateVar->setDebugInfo(makeTemplateVarInfo(astTemplateVarNode));
				
				semTypeInstance->templateVariables().push_back(semTemplateVar);
				semTypeInstance->namedTemplateVariables().insert(std::make_pair(templateVarName, semTemplateVar));
			}
			
			if (semTypeInstance->isUnionDatatype()) {
				for (auto& astVariantNode: *(astTypeInstanceNode->variants)) {
					const auto variantTypeInstance = AddTypeInstance(context, astVariantNode, moduleScope);
					variantTypeInstance->setParent(semTypeInstance.get());
					variantTypeInstance->templateVariables() = semTypeInstance->templateVariables().copy();
					variantTypeInstance->namedTemplateVariables() = semTypeInstance->namedTemplateVariables().copy();
					semTypeInstance->variants().push_back(variantTypeInstance);
				}
			}
			
			if (!astTypeInstanceNode->noTagSet.isNull()) {
				SEM::TemplateVarArray noTagSet;
				
				for (const auto& astNoTagName: *(astTypeInstanceNode->noTagSet)) {
					const auto templateVarIterator = semTypeInstance->namedTemplateVariables().find(astNoTagName);
					if (templateVarIterator == semTypeInstance->namedTemplateVariables().end()) {
						throw ErrorException(makeString("Can't find template variable '%s' in notag() set in type '%s', at location %s.",
										astNoTagName.c_str(), fullTypeName.toString().c_str(),
										astTypeInstanceNode->noTagSet.location().toString().c_str()));
					}
					
					noTagSet.push_back(templateVarIterator->second);
				}
				
				semTypeInstance->setNoTagSet(std::move(noTagSet));
			}
			
			const auto typeInstancePtr = semTypeInstance.get();
			
			parentNamespace->items().insert(std::make_pair(typeInstanceName, SEM::NamespaceItem::TypeInstance(std::move(semTypeInstance))));
			
			return typeInstancePtr;
		}