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)
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')
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)
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)
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
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