示例#1
0
	def _coerceOperands(self, arg1, arg2):
		if arg1.esType.isEquivalentTo(arg2.esType, False):
			return

		if estypesystem.canImplicitlyCast(arg1.esType, arg2.esType):
			self._insertImplicitCastNode(arg1, arg2.esType)
		elif estypesystem.canImplicitlyCast(arg2.esType, arg1.esType):
			self._insertImplicitCastNode(arg2, arg1.esType)
		else:
			s1 = 'operands can not be coerced'
			s2 = 'lhs: %s; rhs: %s' % (arg1.esType, arg2.esType)
			self._raiseException(RecoverableCompileError, tree=arg1, inlineText=s1, postText=s2)
示例#2
0
	def _onAssert(self, ast, expression):
		self._dispatch(expression)

		esType = expression.esType
		if not esType.isEquivalentTo(self._findSymbol(name=u'bool', type_=ESType), False):
			if not estypesystem.canImplicitlyCast(esType, self._findSymbol(name=u'bool', type_=ESType)):
				self._raiseException(RecoverableCompileError, tree=expression, inlineText='expression is of incompatible type. expected bool')

			self._insertImplicitCastNode(expression, u'bool')
示例#3
0
	def _onWhile(self, ast, expression, block):
		self._dispatch(expression)

		esType = expression.esType
		bool = self._findSymbol(name=u'bool', type_=ESType)
		if not esType.isEquivalentTo(bool, False):
			# types did not match, try implicit cast
			if not estypesystem.canImplicitlyCast(esType, bool):
				self._raiseException(RecoverableCompileError, tree=expression, inlineText='incompatible type, expected bool')

			# TODO add cast node


		self._dispatch(block)
示例#4
0
	def _onIf(self, ast, expressions, blocks, elseBlock):
		for x in expressions:
			self._dispatch(x)

		for i in range(len(expressions)):
			esType = expressions[i].esType

			if not esType.isEquivalentTo(self._findSymbol(name=u'bool', type_=ESType), False):
				if not estypesystem.canImplicitlyCast(esType, self._findSymbol(name=u'bool', type_=ESType)):
					self._raiseException(RecoverableCompileError, tree=expressions[i], inlineText='expression is of incompatible type. expected bool')

				self._insertImplicitCastNode(expressions[i], u'bool')

		for x in blocks:
			self._dispatch(x)

		if elseBlock:
			self._dispatch(elseBlock)
示例#5
0
		def getMatchingFunctions(functions, paramTypes):
			nParams = len(paramTypes)

			# get all functions with matching argument count
			good = []
			for f in esFunctions:
				if len(f.esType.getFunctionParameterTypes()) == len(expressions):
					good.append(f)

			if not good:
				# TODO provide a better error message
				self._raiseException(RecoverableCompileError, tree=calleeName, inlineText='no function with the right number of arguments found')


			# try to find perfect match --> no implicit conversions needed
			perfectMatch = None
			for f in good:
				bad = False
				ptypes = f.esType.getFunctionParameterTypes()
				for i, t in enumerate(ptypes):
					if not t.isEquivalentTo(expressions[i].esType, False):
						bad = True
						break

				if not bad:
					return [f]

			# sort out functions which are definitely wrong --> at least one parameter does not fit and there's no implicit cast
			tmp = good
			good = []
			for f in tmp:
				ptypes = f.esType.getFunctionParameterTypes()
				bad = False
				for i, t in enumerate(ptypes):
					if not estypesystem.canImplicitlyCast(expressions[i].esType, t):
						bad = True
						break
				if not bad:
					good.append(f)

			# find best match(es)


			return good
示例#6
0
	def _insertImplicitCastNode(self, exprNode, to):
		if isinstance(to, ESType):
			targetT = to
			toTypeName = u'%s' % to # TODO a real typename would be better...
		else:
			targetT = self._findSymbol(name=to, type_=ESType)
			toTypeName = to


		if not estypesystem.canImplicitlyCast(exprNode.esType, targetT):
			bad = False
			if exprNode.type == TreeType.INTEGER_CONSTANT:
				# an int32 can be cast implicitly to an int8 or even uint8 etc. if it was a constant in the target range
				if exprNode.signed:
					if targetT.isEquivalentTo(self._findSymbol(name=u'int8', type_=ESType), False) and exprNode.minBits <= 8:
						pass
					elif targetT.isEquivalentTo(self._findSymbol(name=u'int16', type_=ESType), False) and exprNode.minBits <= 16:
						pass
					else:
						bad = True
				else:
					raise NotImplementedError('TODO')
			else:
				bad = True

			if bad:
				self._raiseException(RecoverableCompileError, tree=exprNode, inlineText='no implicit cast to %s available' % toTypeName)

		newExprNode = exprNode.copy(True)
		typeNameNode = exprNode.copy(False)

		typeNameNode.type = TreeType.NAME # FIXME this should be later a typename node
		typeNameNode.text = toTypeName

		exprNode.type = TreeType.IMPLICITCAST
		exprNode.text = u'IMPLICITCAST'
		exprNode.children = [newExprNode, typeNameNode]
		exprNode.esType = targetT