Esempio n. 1
0
TypePtr Parser::maybeType(bool se)
{
	if(token == TIdent)
	{
		TypePtr t = resolveIdentType(tokenStr);
		if(t)
			next(se);
		return t;
	}
	else if(token == TTypeIdent)
	{
		IntrusiveRefCntPtr<TypeDataNamed> named(
			new TypeDataNamed(nextIdent(se)));

		if(test(TLParen))
		{
			do
			{
				named->typeAssignment.push_back(typeName(false));
			}
			while(test(TComma));

			expect(TRParen);
		}

		return TypePtr(named);
	}

	parseError();
	return TypePtr();
}
Esempio n. 2
0
TypePtr getRepeatedType(const TypePtr& cur) {
	assert_true(isVariableSized(cur)) << "Only variable sized types contain repeated types.";

	NodeType type = cur->getNodeType();
	switch(type) {
	case NT_ArrayType: return cur.as<ArrayTypePtr>()->getElementType();
	case NT_StructType: {
		StructTypePtr structType = cur.as<StructTypePtr>();
		return getRepeatedType(structType.back()->getType());
	}
	case NT_TupleType: {
		TupleTypePtr tupleType = cur.as<TupleTypePtr>();
		return getRepeatedType(tupleType.back());
	}
	case NT_UnionType: {
		UnionTypePtr unionType = cur.as<UnionTypePtr>();
		for(auto cur : unionType) {
			if (isVariableSized(cur->getType())) return getRepeatedType(cur->getType());
		}
		break;
	}
	default: break;
	}

	assert_fail() << "Invalid classification as a variable sized type!";
	return TypePtr();
}
Esempio n. 3
0
TypePtr TypeData::fresh()
{
/*
	if(kind == TyVar)
	{
		IntrusiveRefCntPtr<TypeData> data(
			new TypeDataVar(*static_cast<TypeDataVar*>(data.getPtr())));
		return TypeRef(TyVar, data);
	}
	else if(kind == TyNamed)
	{
		vector<TypeRef> newAssignment;
		auto& def = *static_cast<TypeDataDef*>(data.getPtr());

		bool different = false;

		for(auto& t : def.typeAssignment)
		{
			TypeRef newT = t.fresh();
			newAssignment.push_back(newT);

			different = different || !newT.isSame(t);
		}

		if(different)
		{
			
		}
	}
	
	assert(kind != TyDef);
*/
	return TypePtr(this);
}
Esempio n. 4
0
TypePtr TypeData::commonWith(TypePtr const& other)
{
	if(this != other.getPtr()) // TODO: TypeData may not be interned
		return tyUnit;
			
	return TypePtr(this);
}
Esempio n. 5
0
TypePtr Parser::parseType()
{
    if (match(TokenType::Array)) {
        if (!match(TokenType::LBracket)) {
            reportError(ErrorCodes::ExpectedLBracket);

            panic(typeFollow, typeFollowSize);
            return TypePtr();
        }

        NumberPtr from = parseNumber();
        if (m_errorCode > ErrorCodes::NoError) {
            panic(typeFollow, typeFollowSize);
            return TypePtr();
        }

        if (!match(TokenType::Range)) {
            reportError(ErrorCodes::ExpectedRange);

            panic(typeFollow, typeFollowSize);
            return TypePtr();
        }

        NumberPtr to = parseNumber();
        if (m_errorCode > ErrorCodes::NoError) {
            panic(typeFollow, typeFollowSize);
            return TypePtr();
        }

        if (!match(TokenType::RBracket)) {
            reportError(ErrorCodes::ExpectedRBracket);

            panic(typeFollow, typeFollowSize);
            return TypePtr();
        }

        if (!match(TokenType::Of)) {
            reportError(ErrorCodes::ExpectedOf);

            panic(typeFollow, typeFollowSize);
            return TypePtr();
        }

        TypePtr type = parseStandardType();
        if (m_errorCode > ErrorCodes::NoError) {
            panic(typeFollow, typeFollowSize);
            return TypePtr();
        }

        TypePtr arrayType(new Type);
        arrayType->isArray = true;
        arrayType->startsAt = from;
        arrayType->endsAt = to;
        arrayType->standardType = type->standardType;

        return arrayType;
    }

    return parseStandardType();
}
Esempio n. 6
0
Value *TacBuilder::createNot(Value *value)
{
    TacValuePtr result = m_insertBlock->owner->createTemporary(TypePtr());

    TacValue *valueValue = (TacValue *)value;
    m_insertBlock->code << "\t\t" << "NOT" << "\t" << valueValue->value() << "\t" << valueValue->value() << "\t" << result->value() << std::endl;

    return result.get();
}
Esempio n. 7
0
Value *TacBuilder::createSub(Value *lhs, Value *rhs)
{
    TacValuePtr result = m_insertBlock->owner->createTemporary(TypePtr());

    TacValue *lhsValue = (TacValue *)lhs;
    TacValue *rhsValue = (TacValue *)rhs;
    m_insertBlock->code << "\t\t" << "SUB" << "\t" << lhsValue->value() << "\t" << rhsValue->value() << "\t" << result->value() << std::endl;

    return result.get();
}
Esempio n. 8
0
TacBuilder::TacBuilder()
    : m_programFunction(new TacFunction("", DeclarationsPtr(), TypePtr()))
    , m_insertBlock()
{
    TacValuePtr writelnPtr(new TacValue);

    IdentifierPtr writelnIdPtr(new Identifier);
    writelnIdPtr->id = Token("writeln", -1, -1);

    writelnPtr->id = writelnIdPtr;
    writelnPtr->isConstant = true;
    writelnPtr->isFunction = true;

    m_programFunction->symbols.push_back(writelnPtr);
}
Esempio n. 9
0
TypePtr deduceReturnType(const FunctionTypePtr& funType, const TypeList& argumentTypes, bool unitOnFail) {
	try {

		// try deducing the return type ...
		return tryDeduceReturnType(funType, argumentTypes);

	} catch (const ReturnTypeDeductionException&) {

		// didn't work => print a warning
		LOG(DEBUG) << "Unable to deduce return type for call to function of type "
				<< toString(*funType) << " using arguments " << join(", ", argumentTypes, print<deref<TypePtr>>());
	}
	// return null ptr
	return unitOnFail ? funType->getNodeManager().getLangBasic().getUnit() : TypePtr();
}
Esempio n. 10
0
Value *TacBuilder::createCmpNe(Value *lhs, Value *rhs)
{
    TacValuePtr result = m_insertBlock->owner->createTemporary(TypePtr());
    std::string trueLabel = createLabel();
    std::string doneLabel = createLabel();

    TacValue *lhsValue = (TacValue *)lhs;
    TacValue *rhsValue = (TacValue *)rhs;
    m_insertBlock->code << "\t\t" << "NE" << "\t" << lhsValue->value() << "\t" << rhsValue->value() << "\t" << trueLabel << std::endl;
    m_insertBlock->code << "\t\t" << "ASSIGN" << "\t" << "0" << "\t" << result->value() << std::endl;
    m_insertBlock->code << "\t\t" << "GOTO" << "\t" << doneLabel << std::endl;
    m_insertBlock->code << trueLabel << ":";
    m_insertBlock->code << "\t\t" << "ASSIGN" << "\t" << "1" << "\t" << result->value() << std::endl;
    m_insertBlock->code << doneLabel << ":";

    return result.get();
}
Esempio n. 11
0
TypePtr TypeDataDef::apply(vector<TypePtr> const& params)
{
	assert(!params.empty());
		
	IntrusiveRefCntPtr<TypeDataDef> newData(new TypeDataDef(*this));

	newData->typeAssignment.insert(
		newData->typeAssignment.end(),
		params.begin(),
		params.end());

	// Check "over-application"
	if(newData->typeAssignment.size() > def->typeParams.size())
		throw CompileError(CEGeneralError, -1);

	return TypePtr(newData);
}
Esempio n. 12
0
TypePtr Parser::parseStandardType()
{
    TypePtr type(new Type);

    if (m_curToken.tokenType() == TokenType::Integer) {
        match(TokenType::Integer);

        type->standardType = NumberType::Integer;

        return type;
    } else if (m_curToken.tokenType() == TokenType::Real) {
        match(TokenType::Real);

        type->standardType = NumberType::Real;

        return type;
    }

    reportError(ErrorCodes::ExpectedStandardType);
    return TypePtr();
}
Esempio n. 13
0
IntrusiveRefCntPtr<PatternExpr> Parser::pattern(bool se)
{
	// TODO: Proper pattern syntax
	if(token == TTypeIdent)
	{
		string const& ctorName = nextIdent(se);

		IntrusiveRefCntPtr<PatternNamedCtorExpr> pt(
			new PatternNamedCtorExpr());
		pt->name = ctorName;

		if(test(TLParen))
		{
			do
			{
				pt->subPatterns.push_back(pattern(false));
			}
			while(test(TComma));

			expect(TRParen);
		}

		return IntrusiveRefCntPtr<PatternExpr>(pt.getPtr());
	}
	else if(token == TIdent)
	{
		string const& bindingName = nextIdent(se);

		auto varDecl = declVar(bindingName, TypePtr());

		IntrusiveRefCntPtr<PatternBindingExpr> pt(
			new PatternBindingExpr());
		pt->var = varDecl;

		return IntrusiveRefCntPtr<PatternExpr>(pt.getPtr());
	}

	parseError();
	return IntrusiveRefCntPtr<PatternExpr>();
}
Esempio n. 14
0
TypePtr UserAttribute::inferTypes(AnalysisResultPtr ar, TypePtr type,
                                  bool coerce) {
  assert(false);
  return TypePtr();
}
	void TypeInference::inferTypes(
		ValueDef& valueDef,
		StaticContextPtr& pMemberCtx,
		const LogPtr& pLog)
	{
		switch (valueDef.getValueType())
		{
		case OBJECT_INIT:
			{
				const ObjectInitValueDef& objectInitDef = static_cast<const ObjectInitValueDef&>(valueDef);

				TypePtr pType = TypePtr(
					new ReferenceType(OBJECT_REF_TYPE, objectInitDef.getClassName()));

				valueDef.setInferredType(pType);

				const map<const wstring, ActualParamDefPtr>& actualParamsMap = objectInitDef.getActualParamsMap();

				map<const wstring, ActualParamDefPtr>::const_iterator it;

				for (it = actualParamsMap.begin(); it != actualParamsMap.end(); it++)
				{
					const ActualParamDefPtr& pActualParamDef = (*it).second;
					const ValueDefPtr& pParamValueDef = pActualParamDef->getValue();

					inferTypes(*pParamValueDef, pMemberCtx, pLog);
				}
			}
			break;
		case ARRAY_INIT:
			{
				const ArrayInitValueDef& arrayInitDef = static_cast<const ArrayInitValueDef&>(valueDef);

				valueDef.setInferredType(arrayInitDef.getDeclaredType());

				const list<ValueDefPtr>& arrayValues = arrayInitDef.getValues();

				list<ValueDefPtr>::const_iterator it;

				for (it = arrayValues.begin(); it != arrayValues.end(); it++)
				{
					const ValueDefPtr& pArrayValue = *it;

					inferTypes(*pArrayValue, pMemberCtx, pLog);
				}
			}
			break;
		case LITERAL:
			{
				const LiteralValueDef& literalDef = static_cast<const LiteralValueDef&>(valueDef);

				switch (literalDef.getLiteralType())
				{
				case INTEGER_LITERAL:
					valueDef.setInferredType(P_INTEGER_TYPE);
					break;
				case FLOAT_LITERAL:
					valueDef.setInferredType(P_FLOAT_TYPE);
					break;
				case STRING_LITERAL:
					valueDef.setInferredType(P_STRING_TYPE);
					break;
				default:
					assert(false);
					break;
				}
			}
			break;
		case REFERENCE_PATH:
			{
				const ReferencePathValueDef& referencePathDef = static_cast<const ReferencePathValueDef&>(valueDef);

				const list<const wstring>& path = referencePathDef.getReferencePath();

				StaticContextEntryPtr pEntry;

				TypePtr pCurrentType;

				list<const wstring>::const_iterator it;

				wstring parentPath(L"");

				for (it = path.begin(); it != path.end(); it++)
				{
					const wstring& pathElement = *it;

					if (it == path.begin())
					{
						CStaticContextEntryPtr pEntry;

						if (!pMemberCtx->lookup(pathElement, pEntry))
						{
							boost::wformat f(L"Unable to resolve name %1%");
							f % pathElement;
							pLog->log(referencePathDef, msg::ErrAnaTypeInfer_NameNotInContext, f.str());
							return;
						}
						else
						{
							switch (pEntry->getStaticEntryType())
							{
							case CLASS_DEF_CTX_ENTRY:
								{
									TypePtr pType(new ReferenceType(CLASS_REF_TYPE, pEntry->getName()));
									pCurrentType = pType;
								}
								break;
							case INTERFACE_DEF_CTX_ENTRY:
								{
									TypePtr pType(new ReferenceType(CLASS_REF_TYPE, pEntry->getName()));
									pCurrentType = pType;
								}
								break;
							case VARIABLE_DEF_CTX_ENTRY:
								{
									VariableDeclDefPtr pVariableDef;
									pEntry->getVariable(pVariableDef);

									if (pMemberCtx->isStatic() && !pVariableDef->isStatic())
									{
										boost::wformat f(L"Cannot refer to a non static variable from an static context: %1%");
										f % pathElement;
										pLog->log(referencePathDef, msg::ErrAnaTypeInfer_NonStaticVarRef, f.str());
										return;
									}
									else
									{
										pCurrentType = pVariableDef->getDeclaredType();
									}
								}
								break;
							case FORMAL_PARAM_DEF_CTX_ENTRY:
								{
									if (pMemberCtx->isStatic())
									{
										boost::wformat f(L"Cannot refer to a class parameter from an static context: %1%");
										f % pathElement;
										pLog->log(referencePathDef, msg::ErrAnaTypeInfer_NonStaticParamRef, f.str());
										return;
									}

									FormalParamDefPtr pFormalParamDef;
									pEntry->getFormalParam(pFormalParamDef);
									pCurrentType = pFormalParamDef->getType();
								}
								break;
							default:
								assert(false);
								return;
							}
						}
					}
					else
					{
						assert(pCurrentType.get() != NULL);

						StaticContextPtr pRootCtx;
						pMemberCtx->getRootContext(pRootCtx);

						if (!followPathElement(
								*pCurrentType,
								*pRootCtx,
								pathElement,
								pCurrentType))
						{
							boost::wformat f(L"%1% is not a member of %2%");
							f % pathElement % parentPath;
							pLog->log(referencePathDef, msg::ErrAnaTypeInfer_NotAMember, f.str());
							return;
						}
					}

					if (parentPath.size())
					{
						parentPath.append(L".");
					}

					parentPath.append(pathElement);
				}

				assert(pCurrentType.get() != NULL);

				valueDef.setInferredType(pCurrentType);
			}
			break;
		default:
			assert(false);
			break;
		}
	}
Esempio n. 16
0
TypePtr TypeDataDef::doResolve(ModuleBuilder& /*modBuilder*/)
{
	def->doResolve(*modBuilder);
	TypeDataComposite::doResolve();
	return TypePtr(this);
}
Esempio n. 17
0
	TypePtr PointerType::create(const TypePtr& elementType, bool _const, bool _volatile) {
		assert_true(elementType);
		return PointerType(elementType, _const, _volatile).operator TypePtr();
	}
Esempio n. 18
0
TypePtr Parser::resolveIdentType(string const& name)
{
	if (!currentTypeScope) return TypePtr();
	return currentTypeScope->resolveIdent(name);
}