def mkfn(ctx, w_args, body_w): args = [] rest_args_id = -1 arg_vec_w = unwrap(cast(w_args, W_Seq)) idx = 0 st = ctx.st() while idx < len(arg_vec_w): w_arg = cast(arg_vec_w[idx], W_Sym) if w_arg.val == '&': assert idx == len(arg_vec_w) - 2 w_last = cast(arg_vec_w[idx + 1], W_Sym) rest_args_id = st.add_sym(w_last.val) break else: args.append(w_arg.val) idx += 1 ids = [] for arg in args: id = st.add_sym(arg) ids.append(id) if len(ids) > 0 or rest_args_id >= 0: recur_bindings = (ids, rest_args_id) else: recur_bindings = empty_recur_bindings code = [] for w_elem in body_w: code += emit(ctx, w_elem, recur_bindings) return st.add_fn(W_Fun(code, ids, rest_args_id))
def setitem(self, index, value): index = space.cast(index, numbers.Integer, u"index not an integer") if not 0 <= index.value < self.length: raise space.unwind(space.LKeyError(self, index)) value = space.cast(value, numbers.Integer, u"value not an integer") self.uint8data[index.value] = rffi.r_uchar(value.value) return value
def instantiate(obj): res = Exnihilo() if obj is not None: obj = space.cast(obj, space.Dict, u"object instantiation") for key, value in obj.data.items(): key = space.cast(key, space.String, u"setattr") res.setattr(key.string, value) return res
def setitem(self, index, value): index = space.cast(index, space.List, u"Multimethod.setitem") vec = [ space.cast(item, space.Interface, u"Multimethod expects interface list") for item in index.contents] self.multimethod_table[vec] = value return value
def setitem(self, index, value): index = space.cast(index, space.List, u"Multimethod.setitem") vec = [ space.cast(item, space.Interface, u"Multimethod expects interface list").weakref for item in index.contents ] if vec in self.multimethod_table: raise space.unwind( space.LError(u"Multimethod table is not overwritable.")) record = MultimethodRecord(self, vec, value) self.register_record(record) return value
def invoke(self, args, ctx): w_str = space.cast(args[0], space.W_String) from parser import parse parsed = parse(w_str.val) if len(parsed) == 0: raise space.ParsingException("EOF") return eval.read(ctx, parsed[0])
def setitem(self, index, value): # TODO: Add slice support to this side. index = space.cast(index, Integer, u"index not an integer") if not 0 <= index.value < len(self.contents): raise space.unwind(space.LKeyError(self, index)) self.contents[index.value] = value return value
def hash(self): custom_interface = jit.promote(self.custom_interface) method = custom_interface.lookup_method(u"+hash") if method is None: return Object.hash(self) else: result = method.call([self]) return int(space.cast(result, space.Integer, u"+hash cast").value)
def repr(self): custom_interface = jit.promote(self.custom_interface) method = custom_interface.lookup_method(u"+repr") if method is None: return Object.repr(self) else: result = method.call([self]) return space.cast(result, space.String, u"+repr cast").string
def getitem(self, index): index = space.cast(index, space.List, u"Multimethod.getitem") try: vec = [cls.interface.weakref for cls in index.contents] item = self.multimethod_table[vec]() if item is not None: return item except KeyError as _: pass raise space.unwind(space.LKeyError(self, index))
def getitem(self, index): if isinstance(index, space.Slice): start, stop, step = index.clamped(0, len(self.contents) - 1) result = [] for i in range(start, stop, step): result.append(self.contents[i]) return List(result) index = space.cast(index, Integer, u"index not an integer") if not 0 <= index.value < len(self.contents): raise space.unwind(space.LKeyError(self, index)) return self.contents[index.value]
def getitem(self, index): if isinstance(index, space.Slice): result = [] start, stop, step = index.clamped(0, len(self.string)-1) for i in range(start, stop, step): result.append(self.string[i]) return String(u"".join(result)) index = space.cast(index, Integer, u"index not an integer") if not 0 <= index.value < len(self.string): raise space.unwind(space.LKeyError(self, index)) return String(self.string[index.value])
def getitem(self, index): if isinstance(index, space.Slice): result = [] start, stop, step = index.clamped(0, len(self.string)) for i in range(start, stop, step): result.append(self.string[i]) return String(u"".join(result)) index = space.cast(index, numbers.Integer, u"index not an integer") if not 0 <= index.value < len(self.string): raise space.unwind(space.LKeyError(self, index)) return String(self.string[index.value])
def getitem(self, index): if isinstance(index, space.Slice): start, stop, step = index.clamped(0, len(self.contents)) result = [] for i in range(start, stop, step): result.append(self.contents[i]) return List(result) index = space.cast(index, Integer, u"index not an integer") if not 0 <= index.value < len(self.contents): raise space.unwind(space.LKeyError(self, index)) return self.contents[index.value]
def doclink_traverse(obj, doc, parent): listing = obj.listattr() for name in listing: name = space.cast(name, space.String, u"importer poststage") field = obj.getattr(name.string) try: if field.getattr(u"doc") == null: docref = DocRef(doc, name, parent) field.setattr(u"doc", docref) doclink_traverse(field, doc, docref) except space.Unwinder as unwind: pass # TODO: pass only LAttributeError
def invoke(self, args, ctx): from parser import parse from compiler import emit w_str = space.cast(args[0], space.W_String) f = open(w_str.val) try: input = f.read() parsed = parse(input) for sexp in parsed: code = emit(ctx, eval.read(ctx, sexp)) ctx.run(code) finally: f.close()
def fancy_frame(argv): args = () L = len(argv) if L < argc or (L > topc and not variadic): raise space.unwind(space.LCallError(argc, topc, variadic, L)) for i in argi: arg = argv[i] if isinstance(arg, argtypes[i]): args += (arg, ) else: args += (space.cast(arg, argtypes[i], u"arg:%d" % i), ) for j in argj: if j < L: arg = argv[j] if arg is null: arg = None elif not isinstance(arg, argtypes[j]): arg = space.cast(arg, argtypes[j], u"arg:%d" % j) else: arg = None args += (arg, ) if variadic: args += (argv[min(topc, L):], ) return func(*args)
def fancy_frame(argv): args = () L = len(argv) if L < argc or (L > topc and not variadic): raise space.unwind(space.LCallError(argc, topc, variadic, L)) for i in argi: arg = argv[i] if isinstance(arg, argtypes[i]): args += (arg,) else: args += (space.cast(arg, argtypes[i], u"arg:%d"%i),) for j in argj: if j < L: arg = argv[j] if arg is null: arg = None elif not isinstance(arg, argtypes[j]): arg = space.cast(arg, argtypes[j], u"arg:%d"%j) else: arg = None args += (arg,) if variadic: args += (argv[min(topc, L):],) return func(*args)
def getitem(self, index): if isinstance(index, space.Slice): start, stop, step = index.clamped(0, self.length - 1) if step != 1: result = [] # TODO: keep it as Uint8Array? for i in range(start, stop, step): result.append( numbers.Integer(rffi.r_long(self.uint8data[i]))) return space.List(result) parent = self.parent if isinstance(self, Uint8Slice) else self return Uint8Slice(rffi.ptradd(self.uint8data, start), stop - start, parent) index = space.cast(index, numbers.Integer, u"index not an integer") if not 0 <= index.value < self.length: raise space.unwind(space.LKeyError(self, index)) return numbers.Integer(rffi.r_long(self.uint8data[index.value]))
def last_chance_logging(self): loggers, self.loggers = self.loggers, [] # last chance logging # at this point it is best-effort. try: if len(loggers) > 0: for item in loggers[0].items: which = item.getattr(u"type") value = item.getattr(u"value") which = space.cast(which, space.String, u"last_chance_logging") if which.string != u"exception": continue self.exception(value) except space.Unwinder as unwinder: self.exception(unwinder.exception)
def invoke_fn(w_fn, args_w, ctx): w_fn = space.cast(w_fn, space.W_Fun) argc = len(args_w) arg_ids_len = len(w_fn.arg_ids) rest_args = space.w_empty_list if argc > arg_ids_len and w_fn.got_rest_args(): rest_args = [args_w.pop() for _ in range(argc - arg_ids_len)] rest_args.reverse() rest_args = space.wrap(rest_args) args = [args_w.pop() for _ in range(arg_ids_len)] idx = 0 env = Env([], w_fn.env) for arg_id in reversed(w_fn.arg_ids): env.set(arg_id, args[idx]) idx += 1 if w_fn.got_rest_args(): env.set(w_fn.rest_args_id, rest_args) return eval(ctx, env, w_fn.code)
def String_init_is_cast(obj): return space.cast(obj, String, u"str()")
def invoke(self, args, ctx): w_arg = space.cast(args[0], space.W_Sym) return ctx.bindings().get_var(w_arg.val)
def invoke(self, args, ctx): w_var = space.cast(args[0], space.W_Var) w_fn = space.cast(args[1], space.W_Fun) w_new = eval.invoke_fn(w_fn, [w_var.w_val], ctx) ctx.bindings().alter_var(w_var, w_new) return w_new
def getitem(self, index): pc = space.cast(index, space.Integer, u"[index]").value if pc < len(self.closure.function.block): return space.Integer(rffi.r_long(self.closure.function.block[pc])) raise space.OldError(u"pc out of range")
def defmacro(ctx, list_w): _, w_name, w_args = list_w[0:3] fn_id = mkfn(ctx, w_args, list_w[3:]) ctx.st().add_macro(cast(w_name, W_Sym).val, fn_id) return []
def emit_list(ctx, node, recur_bindings): st = ctx.st() list_w = unwrap(node) if len(list_w) == 0: return [ops.SYM, st.add_sym("list"), ops.INVOKE, 0] w_head = list_w[0] args_w = list_w[1:] if isinstance(w_head, W_Sym): head = w_head.val if head == "if": cond_code = emit(ctx, list_w[1]) true_code = emit(ctx, list_w[2], recur_bindings) false_code = emit(ctx, list_w[3], recur_bindings) jmp_code = [ops.RELJMP, len(false_code)] code = (cond_code + [ops.IF, len(true_code) + len(jmp_code)] + true_code + jmp_code + false_code) return code elif head == "let*": sym = cast(list_w[1], W_Sym) binding_code = emit(ctx, list_w[2]) id = st.add_sym(sym.val) inner_code = emit(ctx, list_w[3], recur_bindings) code = binding_code + [ops.PUSH_ENV, id] + inner_code + [ops.POP_ENV] return code elif head == "do": body_code = [] for step in list_w[1:]: body_code += emit(ctx, step, recur_bindings) return body_code elif head == "quote": return emit_quote(ctx, list_w[1]) elif head == "qquote*": return emit_quasiquote(ctx, list_w[1]) elif head == "fn*": return fn(ctx, list_w) elif head == "defmacro*": return defmacro(ctx, list_w) elif head == "def*": var_sym = cast(list_w[1], W_Sym) id = st.add_sym(var_sym.val) val_code = emit(ctx, list_w[2]) return val_code + [ops.DEF, id] elif head == "try*": return try_block(ctx, list_w) elif head == "recur": args = list_w[1:] args_code = [] (ids, rest_id) = recur_bindings if len(args) < len(ids): msg = "Invalid number of recur arguments: %s given, %s expected" raise CompilationException(msg % (len(args), len(ids))) for arg in args: c = emit(ctx, arg) args_code += c + [ops.PUSH] if recur_bindings == no_recur_bindings: raise CompilationException("Not a recur point :o") bindings_ids = [x for x in reversed(ids)] + \ [rest_id if rest_id >= 0 else -1] return args_code + [ops.RECUR, len(args)] + bindings_ids elif st.has_macro(head): return expand_macro(ctx, st.get_macro(head), list_w[1:], recur_bindings) elif head == "apply": args_code = [] for arg in args_w: c = emit(ctx, arg) args_code += c + [ops.PUSH] return args_code + [ops.APPLY, len(args_w)] args_code = [] for arg in args_w: c = emit(ctx, arg) args_code += c + [ops.PUSH] fn_code = emit(ctx, w_head) return args_code + fn_code + [ops.INVOKE, len(args_w)]
def invoke(self, args, *_): w_obj = space.cast(args[0], space.W_String) raise space.SpaceException(w_obj.val)
def getitem(self, index): index = space.cast(index, numbers.Integer, u"index not an integer") if not 0 <= index.value < self.length: raise space.unwind(space.LKeyError(self, index)) return numbers.Integer(rffi.r_long(self.uint8data[index.value]))
def _(cfunc, callback): if isinstance(cfunc, Pointer): cfunc = cfunc.to cfunc = space.cast(cfunc, CFunc, u"callback") return Callback(cfunc, callback)
def invoke(self, args, ctx): w_obj = space.cast(args[0], space.W_Sym) ctx.bindings().set_ns(w_obj.val)
def f(self, args, *_): a = space.cast(args[0], space.W_Int) b = space.cast(args[1], space.W_Int) return space.W_Int(op(a.val, b.val))
def invoke(self, args, ctx): w_var = space.cast(args[0], space.W_Var) w_fn = space.cast(args[1], space.W_Fun) w_meta = eval.invoke_fn(w_fn, [w_var.meta()], ctx) w_var.set_meta(w_meta)
def invoke(self, args, *_): a = space.cast(args[0], space.W_Int) b = space.cast(args[1], space.W_Int) return space.wrap(a.val < b.val)
def invoke(self, args, ctx): w_fn = space.cast(args[0], space.W_Fun) pr = LazySeq.Promise(w_fn, ctx) return space.W_LazySeq(pr)
def invoke(self, args, ctx): w_atom = space.cast(args[0], space.W_Atom) w_fn = space.cast(args[1], space.W_Fun) w_new = eval.invoke_fn(w_fn, [w_atom.deref()], ctx) w_atom.reset(w_new) return w_new
def getitem(self, index): index = space.cast(index, space.List, u"Multimethod.getitem") try: return self.multimethod_table[index.contents] except KeyError as _: raise space.unwind(space.LKeyError(self, index))