def write_bytes_avail(w_bstr, w_port, w_start, w_end, env, cont): # FIXME: discern the available from the non-available form from pycket.interpreter import return_value # FIXME: custom ports if w_port is None: w_port = current_out_param.get(cont) start = w_start.value stop = len(w_bstr.value) if w_end is None else w_end.value if start == stop: w_port.flush() return return_value(values.W_Fixnum(0), env, cont) if start == 0 and stop == len(w_bstr.value): to_write = w_bstr.value else: slice_stop = stop - 1 assert start >= 0 and slice_stop < len(w_bstr.value) assert slice_stop >= 0 to_write = w_bstr.value[start:slice_stop] # FIXME: we fake here w_port.write("".join(to_write)) return return_value(values.W_Fixnum(stop - start), env, cont)
def do_read_one(w_port, as_bytes, peek, env, cont): from pycket.interpreter import return_value if peek: c = w_port.peek() else: c = w_port.read(1) if len(c) == 0: return return_value(values.eof_object, env, cont) i = ord(c[0]) if as_bytes: return return_value(values.W_Fixnum(i), env, cont) else: # hmpf, poking around in internals needed = runicode.utf8_code_length[i] if peek: old = w_port.tell() c = w_port.read(needed) w_port.seek(old) elif needed > 1: c += w_port.read(needed - 1) c = c.decode("utf-8") assert len(c) == 1 return return_value(values.W_Character(c[0]), env, cont)
def read_bytes_avail_bang(w_bstr, w_port, w_start, w_end, env, cont): # FIXME: discern the available from the non-available form from pycket.interpreter import return_value # FIXME: custom ports if w_bstr.immutable(): raise SchemeException("read-bytes-avail!: given immutable byte string") if w_port is None: w_port = current_in_param.get(cont) start = w_start.value stop = len(w_bstr.value) if w_end is None else w_end.value if stop == start: return return_value(values.W_Fixnum(0), env, cont) # FIXME: assert something on indices assert start >= 0 and stop <= len(w_bstr.value) n = stop - start res = w_port.read(n) reslen = len(res) # shortcut without allocation when complete replace if start == 0 and stop == len(w_bstr.value) and reslen == n: w_bstr.value = list(res) return return_value(values.W_Fixnum(reslen), env, cont) if reslen == 0: return return_value(values.eof_object, env, cont) for i in range(0, reslen): w_bstr.value[start + i] = res[i] return return_value(values.W_Fixnum(reslen), env, cont)
def proc_arity_cont(arity, env, cont, _vals): from pycket.interpreter import check_one_val, return_value val = check_one_val(_vals) if not arity.arity_list: return return_value(val, env, cont) result = make_arity_list(arity, val) return return_value(result, env, cont)
def datum_to_correlated(ignored, datum, _srcloc, env, cont): if isinstance(datum, W_Correlated): return return_value(datum, env, cont) else: from pycket.prims.general import srcloc srcloc_const = srcloc.constructor if isinstance(_srcloc, W_Vector): #unerase = _srcloc.get_strategy().unerase #vector_contents = unerase(_srcloc.storage) v_ref = _srcloc.get_strategy().ref return srcloc_const.call([ v_ref(_srcloc, 0), v_ref(_srcloc, 1), v_ref(_srcloc, 2), v_ref(_srcloc, 3), v_ref(_srcloc, 4) ], env, datum_to_corr_cont(datum, env, cont)) elif isinstance(_srcloc, W_List): return srcloc_const.call([ _srcloc.car(), _srcloc.cdr().car(), _srcloc.cdr().cdr().car(), _srcloc.cdr().cdr().cdr().car(), _srcloc.cdr().cdr().cdr().cdr().car() ], env, datum_to_corr_cont(datum, env, cont)) elif isinstance(_srcloc, W_Correlated): raise Exception("FIXME NYI datum->syntax _srcloc is a correlated") else: if _srcloc is not w_false: raise Exception("FIXME, unhandled srcloc type %s" % _srcloc.tostring()) srcloc = _srcloc return return_value(W_Correlated(datum, srcloc, {}), env, cont)
def datum_to_correlated(ignored, datum, _srcloc, env, cont): if isinstance(datum, W_Correlated): return return_value(datum, env, cont) else: from pycket.prims.general import srcloc srcloc_const = srcloc.constructor if isinstance(_srcloc, W_Vector): #unerase = _srcloc.get_strategy().unerase #vector_contents = unerase(_srcloc.storage) v_ref = _srcloc.get_strategy().ref return srcloc_const.call([v_ref(_srcloc, 0), v_ref(_srcloc, 1), v_ref(_srcloc, 2), v_ref(_srcloc, 3), v_ref(_srcloc, 4)], env, datum_to_corr_cont(datum, env, cont)) elif isinstance(_srcloc, W_List): return srcloc_const.call([_srcloc.car(), _srcloc.cdr().car(), _srcloc.cdr().cdr().car(), _srcloc.cdr().cdr().cdr().car(), _srcloc.cdr().cdr().cdr().cdr().car()], env, datum_to_corr_cont(datum, env, cont)) elif isinstance(_srcloc, W_Correlated): raise Exception("FIXME NYI datum->syntax _srcloc is a correlated") else: if _srcloc is not w_false: raise Exception("FIXME, unhandled srcloc type %s" % _srcloc.tostring()) srcloc = _srcloc return return_value(W_Correlated(datum, srcloc, {}), env, cont)
def do_is_struct(v, env, cont): from pycket.interpreter import return_value current_inspector = values_struct.current_inspector_param.get(cont) if isinstance(v, values_struct.W_RootStruct): if current_inspector.has_control(v.struct_type()): return return_value(values.w_true, env, cont) return return_value(values.w_false, env, cont)
def hash_copy(src, env, cont): from pycket.interpreter import return_value new = src.make_empty() if isinstance(src, W_ImmutableHashTable): return return_value(new, env, cont) if src.length() == 0: return return_value(new, env, cont) return hash_copy_loop(src.hash_items(), 0, src, new, env, cont)
def hash_ref_cont(default, env, cont, _vals): from pycket.interpreter import return_value, check_one_val val = check_one_val(_vals) if val is not w_missing: return return_value(val, env, cont) if default is None: raise SchemeException("key not found") if default.iscallable(): return default.call([], env, cont) return return_value(default, env, cont)
def hash_ref_cont(default, k, env, cont, _vals): from pycket.interpreter import return_value, check_one_val val = check_one_val(_vals) if val is not w_missing: return return_value(val, env, cont) if default is None: raise SchemeException("key %s not found"%k.tostring()) if default.iscallable(): return default.call([], env, cont) return return_value(default, env, cont)
def arity_to_value(arity, env, cont): from pycket.interpreter import return_value if arity.at_least != -1: val = [values.W_Fixnum(arity.at_least)] constructor = arity_at_least.constructor return constructor.call(val, env, proc_arity_cont(arity, env, cont)) if len(arity.arity_list) == 1: item = values.W_Fixnum(arity.arity_list[0]) return return_value(item, env, cont) result = make_arity_list(arity) return return_value(result, env, cont)
def hash_for_each_cont(f, ht, index, env, cont, _vals): from pycket.interpreter import return_value nextindex = index + 1 try: w_key, w_value = ht.get_item(index) except KeyError: return return_value(values.w_void, env, hash_for_each_cont(f, ht, nextindex, env, cont)) except IndexError: return return_value(values.w_void, env, cont) after = hash_for_each_cont(f, ht, nextindex, env, cont) return f.call([w_key, w_value], env, after)
def do_procedure_arity(proc, env, cont): from pycket.interpreter import return_value result = [] arity = proc.get_arity() for item in arity.arity_list: result.append(values.W_Fixnum(item)) if arity.at_least != -1: val = [values.W_Fixnum(arity.at_least)] return arity_at_least.constr.call(val, env, proc_arity_cont(result, env, cont)) if len(result) == 1: return return_value(result[0], env, cont) return return_value(values.to_list(result[:]), env, cont)
def ormap_cont(f, ls, env, cont, vals): # XXX this is currently not properly jitted from pycket.interpreter import return_value, check_one_val val = check_one_val(vals) if val is values.w_true: return return_value(val, env, cont) for l in ls: if l is values.w_null: return return_value(values.w_false, env, cont) cars = [l.car() for l in ls] cdrs = [l.cdr() for l in ls] return f.call(cars, env, ormap_cont(f, cdrs, env, cont))
def do_extract_struct_info(v, env, cont): assert is_struct_info(v) from pycket.interpreter import return_value if isinstance(v, values.W_Cons): return return_value(v, env, cont) elif isinstance(v, values.W_Prim): return v.call([], env, cont) else: # TODO: it can be also: # 1. a structure with the prop:struct-info property # 2. a structure type derived from struct:struct-info or # with prop:struct-info and wrapped with make-set!-transformer return return_value(values.w_void, env, cont)
def call(self, args, env, cont): from pycket.interpreter import return_value if len(args) == 0: return return_value(self.get(cont), env, cont) elif len(args) == 1: cell = find_param_cell(cont, self) assert isinstance(cell, values.W_ThreadCell) if self.guard: return self.guard.call([args[0]], env, param_set_cont(cell, env, cont)) else: cell.set(args[0]) return return_value(values.w_void, env, cont) else: raise SchemeException("wrong number of arguments to parameter")
def call_with_extra_info(self, arg, fail, env, cont, app): from pycket.interpreter import return_value if isinstance(arg, W_StructType): w_val = arg.read_prop_precise(self.property) if w_val is not None: return return_value(w_val, env, cont) elif arg.struct_type() is not None: return arg.get_prop(self.property, env, cont) elif fail is not None: if fail.iscallable(): return fail.call_with_extra_info([], env, cont, app) return return_value(fail, env, cont) raise SchemeException("%s-accessor: expected %s? but got %s" % (self.property.name, self.property.name, arg.tostring()))
def hash_map_cont(f, ht, index, w_acc, env, cont, vals): from pycket.interpreter import return_value, check_one_val w_val = check_one_val(vals) if w_val is not w_missing: w_acc = values.W_Cons.make(w_val, w_acc) nextindex = index + 1 try: w_key, w_value = ht.get_item(index) except KeyError: return return_value(w_missing, env, hash_map_cont(f, ht, nextindex, w_acc, env, cont)) except IndexError: return return_value(w_acc, env, cont) after = hash_map_cont(f, ht, nextindex, w_acc, env, cont) return f.call([w_key, w_value], env, after)
def do_read_one(port, as_bytes, env, cont): from pycket.interpreter import return_value if port is None: port = current_in_param.get(cont) assert isinstance(port, values.W_InputPort) # FIXME: UTF-8 c = port.read(1) if len(c) == 0: return return_value(values.eof_object, env, cont) i = ord(c[0]) if as_bytes: return return_value(values.W_Fixnum(i), env, cont) else: return return_value(values.W_Character(unichr(i)), env, cont)
def hash_iter_ref(ht, n, env, cont, returns=_KEY_AND_VALUE): from pycket.interpreter import return_value, return_multi_vals try: w_key, w_val = ht.get_item(n) if returns == _KEY: return return_value(w_key, env, cont) if returns == _VALUE: return return_value(w_val, env, cont) if returns == _KEY_AND_VALUE: vals = values.Values._make2(w_key, w_val) return return_multi_vals(vals, env, cont) except KeyError: raise SchemeException("hash-iterate-key: invalid position") except IndexError: raise SchemeException("hash-iterate-key: invalid position")
def call_with_extra_info(self, arg, fail, env, cont, app): from pycket.interpreter import return_value if isinstance(arg, W_StructType): w_val = arg.read_prop_precise(self.property) if w_val is not None: return return_value(w_val, env, cont) elif isinstance(arg, W_RootStruct): return arg.get_prop(self.property, env, cont) elif fail is not None: if fail.iscallable(): return fail.call_with_extra_info([], env, cont, app) return return_value(fail, env, cont) raise SchemeException( "%s-accessor: expected %s? but got %s" % (self.property.name, self.property.name, arg.tostring()))
def get_prop(self, property, env, cont): from pycket.interpreter import return_value val = self.struct_type().read_prop_precise(property) if val is not None: return return_value(val, env, cont) raise SchemeException("%s-accessor: expected %s? but got %s" % (property.name, property.name, self.tostring()))
def equal_vec_done_cont(a, b, idx, info, env, cont, _vals): from pycket.interpreter import check_one_val, return_value eq = check_one_val(_vals) if eq is values.w_false: return return_value(values.w_false, env, cont) inc = idx + 1 return equal_vec_func(a, b, inc, info, env, cont)
def do_struct_type_make_predicate(struct_type, env, cont): from pycket.interpreter import return_value current_inspector = values_struct.current_inspector_param.get(cont) if not current_inspector.has_control(struct_type): # TODO: we should raise exn:fail:contract raise SchemeException("fail_contract") return return_value(struct_type.predicate, env, cont)
def do_make_sibling_instpector(inspector, env, cont): from pycket.interpreter import return_value if inspector is None: inspector = values_struct.current_inspector_param.get(cont) new_inspector = values_struct.W_StructInspector.make(inspector, issibling=True) return return_value(new_inspector, env, cont)
def set(self, w_dict, w_key, w_val, env, cont): from pycket.interpreter import return_value if self.is_correct_type(w_key): self.unerase(w_dict.hstorage)[self.unwrap(w_key)] = w_val return return_value(values.w_void, env, cont) self.switch_to_object_strategy(w_dict) return w_dict.hash_set(w_key, w_val, env, cont)
def cont_prompt_avail(tag, continuation, env, cont): from pycket.interpreter import return_value if continuation is not None: cont = continuation.cont prompt = find_continuation_prompt(tag, cont) available = values.W_Bool.make(prompt is not None) return return_value(available, env, cont)
def unsafe_vector_set(v, i, new, env, cont): from pycket.interpreter import return_value if isinstance(v, imp.W_ImpVector) or isinstance(v, imp.W_ChpVector): return v.vector_set(i, new, env, cont) else: assert type(v) is values_vector.W_Vector return return_value(v.unsafe_set(i.value, new), env, cont)
def catch_set_is_equal_cont(data, idx, key, val, env, cont, _vals): from pycket.interpreter import check_one_val, return_value cmp = check_one_val(_vals) if cmp is not values.w_false: data[idx] = (key, val) return return_value(values.w_void, env, cont) return equal_hash_set_loop(data, idx + 1, key, val, env, cont)
def vector_copy(dest, _dest_start, src, _src_start, _src_end, env, cont): from pycket.interpreter import return_value if dest.immutable(): raise SchemeException("vector-copy!: given an immutable destination") src_start = _src_start.value if _src_start is not None else 0 src_end = _src_end.value if _src_end is not None else src.length() dest_start = _dest_start.value src_range = src_end - src_start dest_range = dest.length() - dest_start if src_range == 0: return return_value(values.w_void, env, cont) if not (0 <= dest_start < dest.length()): raise SchemeException("vector-copy!: destination start out of bounds") if not (0 <= src_start <= src.length()) or not (0 <= src_start <= src.length()): raise SchemeException("vector-copy!: source start/end out of bounds") if dest_range < src_range: raise SchemeException("vector-copy!: not enough room in target vector") return vector_copy_loop(src, src_start, src_end, dest, dest_start, 0, env, cont)
def do_read_line(mode, as_bytes, env, cont, _vals): # FIXME: respect mode from pycket.interpreter import return_value, check_one_val port = check_one_val(_vals) line = port.readline() stop = len(line) - 1 if stop >= 0: # chomp if line[stop] == "\n": line = line[:stop] if as_bytes: return return_value(values.W_Bytes.from_string(line), env, cont) else: return return_value(values_string.W_String.fromstr_utf8(line), env, cont) else: return return_value(values.eof_object, env, cont)
def get_port_cont(prop, typ, env, cont, _vals): from pycket.interpreter import return_value, check_one_val val = check_one_val(_vals) if isinstance(val, values_struct.W_RootStruct): return get_port(val, prop, typ, env, cont) else: return return_value(val, env, cont)
def _get_port(port, prop, typ, env, cont): from pycket.interpreter import return_value if isinstance(port, values_struct.W_RootStruct): cont = get_port_from_property(port, env, cont) return port.get_prop(prop, env, cont) else: return return_value(port, env, cont)
def get_input_port(port, env, cont): from pycket.interpreter import return_value if port is None: port = current_in_param.get(cont) return return_value(port, env, cont) else: return get_port(port, values_struct.w_prop_input_port, values.W_InputPort, env, cont)
def hash_clear_proc(self, env, cont): from pycket.interpreter import return_value if self.clear_proc is values.w_false or not self.clear_proc.iscallable( ): return return_value(values.w_void, env, cont) else: return self.clear_proc.call([self.inner], env, cont)
def hash_keys_subset_huh_loop(keys_vals, hash_2, idx, env, cont): from pycket.interpreter import return_value if idx >= len(keys_vals): return return_value(values.w_true, env, cont) else: return hash_ref([hash_2, keys_vals[idx][0], values.w_false], env, hash_keys_subset_huh_cont(keys_vals, hash_2, idx, env, cont))
def hash_clear_loop(ht, env, cont): from pycket.interpreter import return_value if ht.length() == 0: return return_value(values.w_void, env, cont) w_k, w_v = ht.get_item(0) return ht.hash_remove_inplace(w_k, env, hash_clear_cont(ht, env, cont))
def find_sys_path(sym, env, cont): from pycket.interpreter import return_value v = env.toplevel_env().globalconfig.lookup(sym.utf8value) if v: return return_value(values.W_Path(v), env, cont) else: raise SchemeException("unknown system path %s" % sym.utf8value)
def hash_keys_subset_huh_cont(keys_vals, hash_2, idx, env, cont, _vals): from pycket.interpreter import return_value, check_one_val val = check_one_val(_vals) if val is values.w_false: return return_value(values.w_false, env, cont) else: return hash_keys_subset_huh_loop(keys_vals, hash_2, idx + 1, env, cont)