Example #1
0
void UnaryOpExpressionAST::typeCheck(TypeChecker& checker) {
	mOperand->typeCheck(checker);

	auto opType = mOperand->expressionType(checker);

	if (mOp == Operator('!') && opType != checker.findType("Bool")) {
		checker.typeError("The '!' operator can only be applied to values/variables of type 'Bool'.");
	} else if (mOp == Operator('-') && opType != checker.findType("Int") && opType != checker.findType("Float")) {
		checker.typeError("The '-' operator can only be applied to values/variables of type 'Int' or 'Float'.");
	}
}
Example #2
0
void MemberAccessAST::typeCheck(TypeChecker& checker) {
	mAccessExpression->typeCheck(checker);

	if (auto varRef = std::dynamic_pointer_cast<VariableReferenceExpressionAST>(mAccessExpression)) {
		auto varSymbol = std::dynamic_pointer_cast<VariableSymbol>(mSymbolTable->find(varRef->name()));
		auto varRefType = checker.findType(varSymbol->variableType());

		std::string memberName = getMemberName();
		std::string objName = varRefType->name();

		if (std::dynamic_pointer_cast<ArrayType>(varRefType)) {
			objName = "Array";
		}

		if (!checker.objectExists(objName)) {
			checker.typeError(varRefType->name() + " is not an object type.");
		}

		auto& object = checker.getObject(objName);

		if (!object.fieldExists(memberName)) {
			checker.typeError("There exists no field '" + memberName + "' in the type '" + varRefType->name() + "'.");
		}

		if (auto arrayMember = std::dynamic_pointer_cast<ArrayAccessAST>(mMemberExpression)) {
			arrayMember->accessExpression()->typeCheck(checker);
		}
	}
}
Example #3
0
void MemberCallExpressionAST::typeCheck(TypeChecker& checker) {
	mAccessExpression->typeCheck(checker);

	if (auto varRef = std::dynamic_pointer_cast<VariableReferenceExpressionAST>(mAccessExpression)) {
		auto varSymbol = std::dynamic_pointer_cast<VariableSymbol>(mSymbolTable->find(varRef->name()));
		auto varRefType = checker.findType(varSymbol->variableType());

		std::string objName = varRefType->name();

		if (!checker.objectExists(objName)) {
			checker.typeError(varRefType->name() + " is not an object type.");
		}

		auto classSymbol = std::dynamic_pointer_cast<ClassSymbol>(Helpers::findSymbolInNamespace(mSymbolTable, objName));
		mMemberCallExpression->setCallTable(classSymbol->symbolTable());
		mMemberCallExpression->generateSymbols(checker.binder(), mSymbolTable);
		mMemberCallExpression->typeCheck(checker);
	} else {
		auto varRefType = mAccessExpression->expressionType(checker);

		std::string objName = varRefType->name();

		if (!checker.objectExists(objName)) {
			checker.typeError(varRefType->name() + " is not an object type.");
		}

		auto classSymbol = std::dynamic_pointer_cast<ClassSymbol>(Helpers::findSymbolInNamespace(mSymbolTable, objName));
		mMemberCallExpression->setCallTable(classSymbol->symbolTable());
		mMemberCallExpression->generateSymbols(checker.binder(), mSymbolTable);
		mMemberCallExpression->typeCheck(checker);
	}
}
Example #4
0
std::shared_ptr<Type> BinaryOpExpressionAST::expressionType(const TypeChecker& checker) const {
	auto& boolTypes = checker.operators().binaryOpReturnTypes();

	if (boolTypes.count(mOp) > 0) {
		return boolTypes.at(mOp);
	} else {
		if (mOp == Operator('=')) {
			return checker.findType("Void");
		} else {
			return mLeftHandSide->expressionType(checker);
		}
	}
}
Example #5
0
void ArrayDeclarationAST::typeCheck(TypeChecker& checker) {
	mLengthExpression->typeCheck(checker);

	//Check length
	checker.assertSameType(
		*checker.makeType("Int"),
		*mLengthExpression->expressionType(checker),
		"Expected the length to be of type 'Int'.");

	//Check if the element type exists
	checker.assertTypeExists(elementType(), false);
	checker.assertNotVoid(*checker.findType(elementType()), "Arrays of type 'Void' is not allowed.");

	//Create the array type if not created
	checker.makeType(elementType() + "[]");
}
Example #6
0
void SetFieldValueAST::typeCheck(TypeChecker& checker) {
	mObjectRefExpression->typeCheck(checker);

	std::shared_ptr<Type> objRefType;

	if (auto varRef = std::dynamic_pointer_cast<VariableReferenceExpressionAST>(mObjectRefExpression)) {
		auto varSymbol = std::dynamic_pointer_cast<VariableSymbol>(mSymbolTable->find(varRef->name()));
		objRefType = checker.findType(varSymbol->variableType());
	} else if (auto arrayRef = std::dynamic_pointer_cast<ArrayAccessAST>(mObjectRefExpression)) {
		objRefType = arrayRef->expressionType(checker);
	} else {
		checker.typeError("Not implemented");
	}

	auto memberName = getMemberName();
	std::string objName = objRefType->name();

	if (!checker.objectExists(objName)) {
		checker.typeError(objRefType->name() + " is not an object type.");
	}

	auto& object = checker.getObject(objName);

	if (!object.fieldExists(memberName)) {
		checker.typeError("There exists no field '" + memberName + "' in the type '" + objRefType->name() + "'.");
	}

	mRightHandSide->typeCheck(checker);

	//Check rhs
	std::shared_ptr<Type> fieldType;

	if (std::dynamic_pointer_cast<ArrayAccessAST>(mMemberExpression)) {
		fieldType = std::dynamic_pointer_cast<ArrayType>(object.getField(memberName).type())->elementType();
	} else {
		fieldType = object.getField(memberName).type();
	}

	checker.assertSameType(
		*fieldType,
		*mRightHandSide->expressionType(checker),
		asString());
}
Example #7
0
void MultiDimArrayDeclarationAST::typeCheck(TypeChecker& checker) {
	for (auto lengthExpr : mLengthExpressions) {
		lengthExpr->typeCheck(checker);
	}

	//Check lengths
	int dim = 0;
	for (auto lengthExpr : mLengthExpressions) {
		checker.assertSameType(
			*checker.makeType("Int"),
			*lengthExpr->expressionType(checker),
			"Expected the length of dimension " + std::to_string(dim) + " to be of type 'Int'.");
		dim++;
	}

	//Check if the element type exists
	checker.assertTypeExists(elementType(), false);
	checker.assertNotVoid(*checker.findType(elementType()), "Arrays of type 'Void' is not allowed.");

	//Create all array types
	for (int i = 0; i < mLengthExpressions.size(); i++) {
		checker.makeType(typeString(i));
	}
}
Example #8
0
std::shared_ptr<Type> ExpressionAST::expressionType(const TypeChecker& checker) const {
	return checker.findType("Void");
}
Example #9
0
std::shared_ptr<Type> ArrayDeclarationAST::expressionType(const TypeChecker& checker) const {
	return checker.findType(elementType() + "[]");
}
Example #10
0
std::shared_ptr<Type> ArraySetElementAST::expressionType(const TypeChecker& checker) const {
	return checker.findType("Void");
}
Example #11
0
std::shared_ptr<Type> MultiDimArrayDeclarationAST::expressionType(const TypeChecker& checker) const {
	return checker.findType(typeString());
}