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 _mutate_index_dim(self, gid, ctype, node, axis=0): info = cast.CName('cly_%s_info' % gid, ast.Load(), ctype.array_info) right = cast.CAttribute(info, 's%s' % hex(axis + 4)[2:], ast.Load(), derefrence(ctype.array_info)) index = cast.CBinOp(node, ast.Mult(), right, node.ctype) #FIXME: cast type return index
def visitCCall(self, node): if isinstance(node.func, FuncPlaceHolder): if node.func.name == '<lambda>': name = 'lambda_id%i' % id(node.func) else: name = node.func.name node.func = cast.CName(name, ast.Load(), node.func.key[0])
def visitarguments(self, node): # for i in range(len(node.args)): i = 0 while i < len(node.args): arg = node.args[i] if isinstance(arg.ctype, contextual_memory): new_id = 'cly_%s_info' % arg.id if (i + 1) < len(node.args) and node.args[i + 1].id == new_id: i += 1 continue if arg.ctype.ndim > 0 or arg.ctype.flat: new_arg = cast.CName(new_id, ast.Param(), arg.ctype.array_info) node.args.insert(i + 1, new_arg) i += 1 i += 1
def mutatePrint(self, node): str_formats = [] for val in node.values: if val.ctype == str: str_formats.append('%s') else: cfmt = type_format(val.ctype) fmt = STR_FORMAT_MAP[cfmt] str_formats.append(fmt) if node.nl: str_formats.append('\\n') cstr = cast.CStr(" ".join(str_formats), str) arg = cast.CTypeCast(cstr, 'const char*') vlaue = cast.CCall(cast.CName('printf', ast.Load(), None), [arg] + node.values, [], None) return ast.Expr(vlaue)
def visitCCall(self, node): i = 0 while i < len(node.args): arg = node.args[i] if isinstance(arg.ctype, contextual_memory): new_id = 'cly_%s_info' % arg.id if (i + 1) < len(node.args) and isinstance( node.args[i + 1], cast.CName) and node.args[i + 1].id == new_id: i += 1 continue if arg.ctype.ndim > 0 or arg.ctype.flat: new_arg = cast.CName(new_id, ast.Load(), arg.ctype.array_info) node.args.insert(i + 1, new_arg) i += 1 i += 1 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 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)