def visitExec(self, node): # ('body', 'globals', 'locals') if node.globals is not None: raise cast.CError(node, NotImplementedError, ("exec globals is not allowed in openCL")) if node.locals is not None: raise cast.CError(node, NotImplementedError, "exec locals is not allowed in openCL") body = self.visit(node.body) return ast.Exec(body, None, None)
def visitName(self, node, ctype=None): if isinstance(node.ctx, ast.Param): if node.id not in self.argtypes: raise CTypeError( node.id, 'function %s() requires argument %r' % (self.func_name, node.id)) ctype = self.argtypes[node.id] return cast.CName(node.id, ast.Param(), ctype, **n(node)) elif isinstance(node.ctx, ast.Load): try: ctype = self.scope(node.id) except NameError as err: raise cast.CError(node, NameError, err.args[0]) return cast.CName(node.id, ast.Load(), ctype, **n(node)) elif isinstance(node.ctx, ast.Store): assert type is not None if node.id in self.locls: ectype = self.locls[node.id] try: greatest_common_type(ctype, ectype) except: # Raise a custom exception if the types are not compatible raise ctype = ectype self.locls[node.id] = ctype return cast.CName(node.id, ast.Store(), ctype, **n(node)) else: assert False
def visitWhile(self, node): #('test', 'body', 'orelse') if node.orelse: raise cast.CError(node, NotImplementedError, "while ... else is not yet allowed in openCL") test = self.visit(node.test) body = list(self.visit_list(node.body)) return ast.While(test, body, None)
def visitPrint(self, node): #('dest', 'values', 'nl') if node.dest is not None: raise cast.CError(node, NotImplementedError, ("print '>>' operator is not allowed in openCL")) values = list(self.visit_list(node.values)) return ast.Print(None, values, node.nl)
def visitarguments(self, node): #'args', 'vararg', 'kwarg', 'defaults' if node.kwarg or node.vararg: raise cast.CError(node, NotImplementedError, 'star args or kwargs') args = list(self.visit_list(node.args)) defaults = list(self.visit_list(node.defaults)) return ast.arguments(args, None, None, defaults)
def visitCSubscript(self, node): if isinstance(node.value.ctype, contextual_memory): if isinstance(node.slice, ast.Index): if not node.value.ctype.flat: node.slice = self._mutate_index(node.value.id, node.value.ctype, node.slice) else: raise cast.CError(node, NotImplementedError, "I will get to slicing later") self.visitDefault(node)
def _mutate_index(self, gid, ctype, node): info = cast.CName('cly_%s_info' % gid, ast.Load(), ctype.array_info) left = cast.CAttribute(info, 's7', ast.Load(), derefrence(ctype.array_info)) if isinstance(node.value, cast.CList): if len(node.value.elts) > ctype.ndim: raise cast.CError( node, IndexError, "invalid index. Array is an %i dimentional array (got %i indices)" % (ctype.ndim, len(node.value.elts))) elif len(node.value.elts) < ctype.ndim: raise cast.CError( node, NotImplementedError, "Slicing not supported yet. Array is an %i dimentional array (got %i indices)" % (ctype.ndim, len(node.value.elts))) for axis, elt in enumerate(node.value.elts): index = self._mutate_index_dim(gid, ctype, elt, axis) left = cast.CBinOp(left, ast.Add(), index, node.value.ctype) #FIXME: cast type else: if ctype.ndim not in [1, None]: if ctype.ndim is None: raise cast.CError(node, NotImplementedError, "Can not slice a flat array") raise cast.CError( node, NotImplementedError, "Slicing not supported yet. Array is an %i dimentional array (got 1 index)" % (ctype.ndim, )) index = self._mutate_index_dim(gid, ctype, node.value, 0) left = cast.CBinOp(left, ast.Add(), index, node.value.ctype) #FIXME: cast type return left
def visitAttribute(self, node, ctype=None): value = self.visit(node.value) try: attr_type = getattrtype(value.ctype, node.attr) except CLAttributeError as err: raise cast.CError(node, CLAttributeError, err.args[0]) if isinstance(node.ctx, ast.Store): pass if isinstance(value.ctype, cl.contextual_memory) and value.ctype.ndim == 0: attr = cast.CPointerAttribute(value, node.attr, node.ctx, attr_type) else: attr = cast.CAttribute(value, node.attr, node.ctx, attr_type) return attr
def call_python_function(self, node, func, args, keywords): func_ast = decompile_func(func) argtypes = {} for keyword in keywords: argtypes[keyword.arg] = keyword.ctype for param, arg in zip(func_ast.args.args, args): argtypes[param.id] = arg.ctype func_dict = self.function_calls.setdefault(func, {}) hsh = dict2hashable(argtypes) if hsh not in func_dict: try: typed_ast = Typify(func.func_name, argtypes, func.func_globals).make_cfunction(func_ast) except CTypeError as err: argid = err.args[0] ids = [arg.id for arg in func_ast.args.args] if argid in ids: pos = ids.index(argid) else: pos = '?' raise cast.CError(node, TypeError, err.args[1] + ' at position %s' % (pos)) key = (func, hsh) plchldr = FuncPlaceHolder(func.func_name, key, typed_ast) typed_ast.name = plchldr func_dict[hsh] = typed_ast else: typed_ast = func_dict[hsh] plchldr = typed_ast.name return cast.CCall(plchldr, args, keywords, typed_ast.return_type)
def visitCall(self, node): #('func', 'args', 'keywords', 'starargs', 'kwargs') if node.starargs or node.kwargs: raise cast.CError(node, NotImplementedError, '* and ** args ar not supported yet') expr = ast.Expression(node.func, lineno=node.func.lineno, col_offset=node.func.col_offset) code = compile(expr, '<nofile>', 'eval') try: func = eval(code, self.globls, self.locls) except AttributeError as err: raise cast.CError(node, AttributeError, err.args[0]) args = list(self.visit_list(node.args)) keywords = list(self.visit_list(node.keywords)) if func in builtin_map: cl_func = builtin_map[func] if isinstance(cl_func, RuntimeFunction): argtypes = [arg.ctype for arg in args] try: return_type = cl_func.return_type(argtypes) except TypeError as exc: raise cast.CError(node, type(exc), exc.args[0]) func_name = cast.CName(cl_func.name, ast.Load(), cl_func) return cast.CCall(func_name, args, keywords, return_type) else: func = self.visit(node.func) return cast.CCall(func, args, keywords, cl_func) elif isfunction(func): return self.call_python_function(node, func, args, keywords) elif ismethod(func): value = self.visit(node.func.value) return self.call_python_function(node, func.im_func, [value] + args, keywords) else: func_name = self.visit(node.func) if isinstance(func_name.ctype, RuntimeFunction): rt = func_name.ctype argtypes = [arg.ctype for arg in args] try: func = rt.return_type(argtypes) except TypeError as exc: raise cast.CError(node, type(exc), exc.args[0]) func_name = cast.CName(rt.name, ast.Load(), rt) elif is_type(func): # possibly a type cast pass else: msg = ( 'This function is not one that CLyther understands. ' 'A function may be a) A native python function. ' 'A python built-in function registered with clyther.pybuiltins ' 'or a ctype (got %r)' % (func)) raise cast.CError(node, TypeError, msg) return cast.CCall(func_name, args, keywords, func)
def visitDefault(self, node): raise cast.CError( node, NotImplementedError, 'python ast node %r is not yet supported by clyther' % type(node).__name__)