def make_unary_arith(name, methname, flversion=False, fxversion=False, unwrap_type=values.W_Number): def do(a): return getattr(a, methname)() do.__name__ = methname expose(name, [unwrap_type], simple=True)(do) if flversion: @expose("fl" + name, [values.W_Flonum], simple=True) def dofl(a): return getattr(a, methname)() dofl.__name__ = methname if fxversion: @expose("fx" + name, [values.W_Fixnum], simple=True) def dofx(a): return getattr(a, methname)() dofx.__name__ = methname
def make_fixedtype_cmps(name, methname): methname = "arith_%s_same" % methname @jit.unroll_safe def do(args): idx = 2 truth = True while idx <= len(args): start = idx - 2 assert start >= 0 w_a, w_b = args[start], args[start + 1] nan_a = not isinstance(w_a, values.W_Number) nan_b = not isinstance(w_b, values.W_Number) if nan_a or nan_b: pf = ["st", "nd", "rd"][idx - 1] if idx <= 3 else "th" w = w_a if nan_a else w_b raise SchemeException( "%s expected number as %s%s argument, got : %s" % (name, idx, pf, w.tostring())) idx += 1 truth = truth and getattr(w_a, methname)(w_b) return values.W_Bool.make(truth) do.__name__ = "fl_" + methname expose("fl" + name, simple=True, arity=Arity.geq(2))(do) expose("unsafe-fl" + name, simple=True, arity=Arity.geq(2))(do) # FIXME: get rid of this code duplication @jit.unroll_safe def do(args): idx = 2 truth = True while idx <= len(args): start = idx - 2 assert start >= 0 w_a, w_b = args[start], args[start + 1] nan_a = not isinstance(w_a, values.W_Number) nan_b = not isinstance(w_b, values.W_Number) if nan_a or nan_b: pf = ["st", "nd", "rd"][idx - 1] if idx <= 3 else "th" w = w_a if nan_a else w_b raise SchemeException( "%s expected number as %s%s argument, got : %s" % (name, idx, pf, w.tostring())) idx += 1 truth = truth and getattr(w_a, methname)(w_b) return values.W_Bool.make(truth) do.__name__ = "fx_" + methname expose("fx" + name, simple=True, arity=Arity.geq(2))(do) expose("unsafe-fx" + name, simple=True, arity=Arity.geq(2))(do)
def make_fixedtype_cmps(name, methname): methname = "arith_%s_same" % methname def do(a, b): return values.W_Bool.make(getattr(a, methname)(b)) do.__name__ = "fl_" + methname expose("fl" + name, [values.W_Flonum] * 2, simple=True)(do) expose("unsafe-fl" + name, [unsafe(values.W_Flonum)] * 2, simple=True)(do) def do(a, b): return values.W_Bool.make(getattr(a, methname)(b)) do.__name__ = "fx_" + methname expose("fx" + name, [values.W_Fixnum] * 2, simple=True)(do) expose("unsafe-fx" + name, [unsafe(values.W_Fixnum)] * 2, simple=True)(do)
cont = prompt.get_previous_continuation() assert cont is not None if handler is None: if not args: raise SchemeException( "abort-current-continuation: expected thunk as argument 1") cont = Prompt(tag, None, env, cont) handler = args[0] args = [] if frames: cont = call_handler_cont(handler, args, env, cont) return unwind_frames(frames, env, cont) return handler.call(args, env, cont) expose("abort-current-continuation", simple=False)(abort_current_continuation) @expose("force-exit", [values.W_Object]) def force_exit(v): return _force_exit(v) def _force_exit(v): from pycket.error import ExitException if isinstance(v, values.W_Fixnum) and (0 <= v.value <= 255): raise ExitException(v) else: raise ExitException(values.W_Fixnum(0))
@continuation def hash_copy_set_cont(keys, idx, src, new, env, cont, _vals): return hash_copy_loop(keys, idx + 1, src, new, env, cont) @loop_label def hash_copy_loop(keys, idx, src, new, env, cont): from pycket.interpreter import return_value if idx >= len(keys): return return_value(new, env, cont) return src.hash_ref(keys[idx][0], env, hash_copy_ref_cont(keys, idx, src, new, env, cont)) def hash_copy(src, env, cont): from pycket.interpreter import return_value if isinstance(src, W_ImmutableHashTable): return return_value(src.make_copy(), env, cont) new = src.make_empty() return hash_copy_loop(src.hash_items(), 0, src, new, env, cont) expose("hash-copy", [W_HashTable], simple=False)(hash_copy) # FIXME: not implemented @expose("equal-hash-code", [values.W_Object]) def equal_hash_code(v): return values.W_Fixnum(0) @expose("equal-secondary-hash-code", [values.W_Object]) def equal_secondary_hash_code(v): return values.W_Fixnum(0)
raise SchemeException("abort-current-continuation: no such prompt exists") handler = prompt.handler cont = prompt.get_previous_continuation() assert cont is not None if handler is None: if not args: raise SchemeException("abort-current-continuation: expected thunk as argument 1") cont = Prompt(tag, None, env, cont) handler = args[0] args = [] if frames: cont = call_handler_cont(handler, args, env, cont) return unwind_frames(frames, env, cont) return handler.call(args, env, cont) expose("abort-current-continuation", simple=False)(abort_current_continuation) @make_procedure("default-error-escape-handler", [], simple=False) def default_error_escape_handler(env, cont): from pycket.prims.general import do_void args = [values.w_default_continuation_prompt_tag, do_void.w_prim] return abort_current_continuation(args, env, cont) expose_val("error-escape-handler", values_parameter.W_Parameter(default_error_escape_handler)) @make_procedure("default-continuation-prompt-handler", [procedure], simple=False) def default_continuation_prompt_handler(proc, env, cont): return proc.call([], env, cont) @expose("call-with-continuation-prompt", simple=False, arity=Arity.geq(1)) def call_with_continuation_prompt(args, env, cont):
return w_n.arith_negativep() v = w_n.arith_and(arith_shift(values.W_Fixnum.ONE, w_m)) if isinstance(v, values.W_Fixnum) and 0 == v.value: return values.w_false else: return values.w_true def arith_shift(w_a, w_b): # XXX support biginteger as second argument (returning 0 and out of memory) b = w_b.value if b >= 0: return w_a.arith_shl(w_b) else: return w_a.arith_shr(values.W_Fixnum(-b)) # don't use the decorator to make the function usable in this file expose("arithmetic-shift", [values.W_Integer, values.W_Fixnum])(arith_shift) @expose("fxlshift", [values.W_Fixnum, values.W_Fixnum]) def fxlshift(w_a, w_b): b = w_b.value if 0 <= b <= 64: try: res = rarithmetic.ovfcheck(w_a.value << b) except OverflowError: raise SchemeException( "fxlshift: result is not a fixnum") return values.W_Fixnum(res) else: raise SchemeException( "fxlshift: expected integer >= 0 and <= 64, got %s" % w_b.tostring())
return values.w_false else: return values.w_true def arith_shift(w_a, w_b): # XXX support biginteger as second argument (returning 0 and out of memory) b = w_b.value if b >= 0: return w_a.arith_shl(w_b) else: return w_a.arith_shr(values.W_Fixnum(-b)) # don't use the decorator to make the function usable in this file expose("arithmetic-shift", [values.W_Integer, values.W_Fixnum])(arith_shift) @expose("fxlshift", [values.W_Fixnum, values.W_Fixnum]) def fxlshift(w_a, w_b): b = w_b.value if 0 <= b <= 64: try: res = rarithmetic.ovfcheck(w_a.value << b) except OverflowError: raise SchemeException("fxlshift: result is not a fixnum") return values.W_Fixnum(res) else: raise SchemeException( "fxlshift: expected integer >= 0 and <= 64, got %s" % w_b.tostring())
if idx >= len(keys): return return_value(new, env, cont) return src.hash_ref(keys[idx][0], env, hash_copy_ref_cont(keys, idx, src, new, env, cont)) def hash_copy(src, env, cont): from pycket.interpreter import return_value if isinstance(src, W_ImmutableHashTable): new = src.make_copy() return return_value(new, env, cont) new = src.make_empty() if src.length() == 0: return return_value(new, env, cont) return hash_copy_loop(src.hash_items(), 0, src, new, env, cont) expose("hash-copy", [W_HashTable], simple=False)(hash_copy) # FIXME: not implemented @expose("equal-hash-code", [values.W_Object]) def equal_hash_code(v): # only for improper path cache entries if isinstance(v, values.W_Cons): if v.is_proper_list(): return values.W_Fixnum.ZERO nm = v.car() p = v.cdr() if isinstance(nm, values_string.W_String) and \ isinstance(p, values.W_Path) and \ isinstance(p.path, str):