def rmpe(pat, input, inp_start, inp_end, output_port, prefix, count, env, cont): from pycket.interpreter import return_multi_vals start = inp_start.value if inp_end is values.w_false: end = sys.maxint elif isinstance(inp_end, values.W_Fixnum): end = inp_end.value else: raise SchemeException( "regexp-match-positions/end: expected fixnum or #f for argument 3") assert output_port is values.w_false, "output port not supported yet" matches = match_positions(pat, input, start, end) if matches is None: return return_multi_vals(NO_MATCH, env, cont) acc, end = make_match_list(matches) length = count.value start = max(0, end - length) assert start >= 0 and end >= 0 matched = input.getslice(start, end) bytestring = ['\0'] * (end - start) for i in range(end - start): bytestring[i] = chr(ord(matched.getitem(i)) % 256) bytes = values.W_Bytes(bytestring) result = values.Values._make2(acc, bytes) return return_multi_vals(result, env, cont)
def rmpe(pat, input, inp_start, inp_end, output_port, prefix, count, env, cont): from pycket.interpreter import return_multi_vals start = inp_start.value if inp_end is values.w_false: end = sys.maxint elif isinstance(inp_end, values.W_Fixnum): end = inp_end.value else: raise SchemeException("regexp-match-positions/end: expected fixnum or #f for argument 3") assert output_port is values.w_false, "output port not supported yet" matches = match_positions(pat, input, start, end) if matches is None: return return_multi_vals(NO_MATCH, env, cont) acc, end = make_match_list(matches) length = count.value input_str = input.as_str_ascii() start = max(0, end - length) assert start >= 0 and end >= 0 bytes = values.W_Bytes.from_string(input_str[start:end], immutable=False) result = values.Values.make([acc, bytes]) return return_multi_vals(result, env, cont)
def rmpe(pat, input, inp_start, inp_end, output_port, prefix, count, env, cont): from pycket.interpreter import return_multi_vals start = inp_start.value if inp_end is values.w_false: end = sys.maxint elif isinstance(inp_end, values.W_Fixnum): end = inp_end.value else: raise SchemeException("regexp-match-positions/end: expected fixnum or #f for argument 3") assert output_port is values.w_false, "output port not supported yet" matches = match_positions(pat, input, start, end) if matches is None: return return_multi_vals(NO_MATCH, env, cont) acc, end = make_match_list(matches) length = count.value start = max(0, end - length) assert start >= 0 and end >= 0 matched = input.getslice(start, end) bytestring = ['\0'] * (end - start) for i in range(end - start): bytestring[i] = chr(ord(matched.getitem(i)) % 256) bytes = values.W_Bytes(bytestring) result = values.Values._make2(acc, bytes) return return_multi_vals(result, env, cont)
def do_struct_info(v, env, cont): from pycket.interpreter import return_multi_vals if (isinstance(v, values_struct.W_RootStruct) and values_struct.current_inspector.has_control(v.struct_type())): return v.get_struct_info(env, cont) return return_multi_vals( values.Values.make([values.w_false, values.w_true]), env, cont)
def make_imp_prop(sym, env, cont): from pycket.interpreter import return_multi_vals name = sym.utf8value prop = imp.W_ImpPropertyDescriptor(name) pred = imp.W_ImpPropertyPredicate(prop) accs = imp.W_ImpPropertyAccessor(prop) return return_multi_vals(values.Values.make([prop, pred, accs]), env, cont)
def make_imp_prop(sym, env, cont): from pycket.interpreter import return_multi_vals name = sym.utf8value prop = imp.W_ImpPropertyDescriptor(name) pred = imp.W_ImpPropertyPredicate(prop) accs = imp.W_ImpPropertyAccessor(prop) return return_multi_vals(values.Values.make([prop, pred, accs]), env, cont)
def attach_prop(self, props, idx, is_checked, env, cont): from pycket.interpreter import return_multi_vals if idx < len(props): (prop, prop_val, sub_prop) = props[idx] if sub_prop is not None: for p in props: if p[0] is sub_prop: return prop_val.call([p[1]], env, self.save_prop_value(props, idx, False, env, cont)) assert isinstance(prop, W_StructProperty) if not is_checked and prop.guard.iscallable(): return prop.guard.call([prop_val, values.to_list(self.struct_type_info())], env, self.save_prop_value(props, idx, True, env, cont)) if prop.isinstance(w_prop_procedure): self.prop_procedure = prop_val self.props.append((prop, prop_val)) return self.attach_prop(props, idx + 1, False, env, cont) # at this point all properties are saved, next step is to copy # propertyes from super types struct_type = self.super while isinstance(struct_type, W_StructType): self.props = self.props + struct_type.props if not self.prop_procedure and struct_type.prop_procedure: self.prop_procedure = struct_type.prop_procedure self.procedure_source = struct_type.procedure_source struct_type = struct_type.super struct_tuple = self.make_struct_tuple() return return_multi_vals(values.Values.make(struct_tuple), env, cont)
def constr_proc_wrapper_cont(self, field_values, struct_type_name, issuper, app, env, cont, _vals): from pycket.interpreter import return_multi_vals, jump guard_values = _vals.get_all_values() type = jit.promote(self.type) if guard_values: field_values = guard_values super_type = jit.promote(type.super) if isinstance(super_type, W_StructType): split_position = len(field_values) - type.init_field_cnt super_auto = super_type.constr.type.auto_values assert split_position >= 0 field_values = self._splice(field_values, len(field_values),\ split_position, super_auto, len(super_auto)) if issuper: return super_type.constr.code(field_values[:split_position], struct_type_name, True, env, cont, app) else: return super_type.constr.code(field_values[:split_position], struct_type_name, True, env, self.constr_proc_cont(field_values, env, cont), app) else: if issuper: return return_multi_vals(values.Values.make(field_values), env, cont) else: return jump(env, self.constr_proc_cont(field_values, env, cont))
def split_path(w_path, env, cont): from pycket.interpreter import return_multi_vals path = extract_path(w_path) base, name, must_be_dir = _split_path(path) result = values.Values.make([base, name, must_be_dir]) return return_multi_vals(result, env, cont)
def attach_prop(self, props, idx, is_checked, env, cont): from pycket.interpreter import return_multi_vals if idx < len(props): (prop, prop_val, sub_prop) = props[idx] if sub_prop is not None: for p in props: if p[0] is sub_prop: return prop_val.call([p[1]], env, self.save_prop_value( props, idx, False, env, cont)) assert isinstance(prop, W_StructProperty) if not is_checked and prop.guard.iscallable(): return prop.guard.call( [prop_val, values.to_list(self.struct_type_info(cont))], env, self.save_prop_value(props, idx, True, env, cont)) if prop.isinstance(w_prop_procedure): self.prop_procedure = prop_val self.props.append((prop, prop_val)) return self.attach_prop(props, idx + 1, False, env, cont) # at this point all properties are saved, next step is to copy # propertyes from super types struct_type = self.super while isinstance(struct_type, W_StructType): self.props = self.props + struct_type.props if not self.prop_procedure and struct_type.prop_procedure: self.prop_procedure = struct_type.prop_procedure self.procedure_source = struct_type.procedure_source struct_type = struct_type.super struct_tuple = self.make_struct_tuple() return return_multi_vals(values.Values.make(struct_tuple), env, cont)
def time_apply_cont(initial, env, cont, vals): from pycket.interpreter import return_multi_vals final = time.clock() ms = values.W_Fixnum(int((final - initial) * 1000)) vals_w = vals.get_all_values() results = values.Values.make([values.to_list(vals_w), ms, ms, values.W_Fixnum.ZERO]) return return_multi_vals(results, env, cont)
def imp_hash_table_post_ref_cont(post, ht, old, env, cont, _vals): from pycket.interpreter import check_one_val, return_multi_vals val = check_one_val(_vals) if val is None: # XXX this looks wrong, check_one_val raises if there are multiple # values return return_multi_vals(_vals, env, cont) return post.call([ht, old, val], env, cont)
def do_struct_info(v, env, cont): from pycket.interpreter import return_multi_vals current_inspector = values_struct.current_inspector_param.get(cont) if (isinstance(v, values_struct.W_RootStruct) and current_inspector.has_control(v.struct_type())): return v.get_struct_info(env, cont) return return_multi_vals( values.Values.make([values.w_false, values.w_true]), env, cont)
def imp_hash_table_post_ref_cont(post, ht, old, env, cont, _vals): from pycket.interpreter import check_one_val, return_multi_vals val = check_one_val(_vals) if val is None: # XXX this looks wrong, check_one_val raises if there are multiple # values return return_multi_vals(_vals, env, cont) return post.call([ht, old, val], env, cont)
def vec2val_cont(vals, vec, n, s, l, env, cont, new_vals): from pycket.interpreter import return_multi_vals, check_one_val new = check_one_val(new_vals) vals[n] = new if s+n+1 == l: return return_multi_vals(values.Values.make(vals), env, cont) else: return vec.vector_ref(values.W_Fixnum.make(s+n+1), env, vec2val_cont(vals, vec, n+1, s, l, env, cont))
def time_apply_cont(initial, env, cont, vals): from pycket.interpreter import return_multi_vals final = time.clock() ms = values.W_Fixnum(int((final - initial) * 1000)) vals_l = vals._get_full_list() results = values.Values.make([values.to_list(vals_l), ms, ms, values.W_Fixnum(0)]) return return_multi_vals(results, env, cont)
def vec2val_cont(vals, vec, n, s, l, env, cont, new_vals): from pycket.interpreter import return_multi_vals, check_one_val new = check_one_val(new_vals) vals[n] = new if s+n+1 == l: return return_multi_vals(values.Values.make(vals), env, cont) else: return vec.vector_ref(s+n+1, env, vec2val_cont(vals, vec, n+1, s, l, env, cont))
def vector_to_values(v, start, end, env, cont): from pycket.interpreter import return_multi_vals l = end.value if end else v.length() s = start.value if s == l: return return_multi_vals(values.Values.make([]), env, cont) else: vals = [None] * (l - s) return v.vector_ref(values.W_Fixnum.make(s), env, vec2val_cont(vals, v, 0, s, l, env, cont))
def vector_to_values(v, start, end, env, cont): from pycket.interpreter import return_multi_vals l = end.value if end else v.length() s = start.value if s == l: return return_multi_vals(values.Values.make([]), env, cont) else: vals = [None] * (l - s) return v.vector_ref(s, env, vec2val_cont(vals, v, 0, s, l, env, cont))
def check_chaperone_results_loop(vals, args, idx, env, cont): from pycket.interpreter import return_multi_vals from pycket.prims.equal import equal_func, EqualInfo while idx < len(args) and vals._get_list(idx) is None and args[idx] is None: idx += 1 if idx >= len(args): return return_multi_vals(vals, env, cont) info = EqualInfo.CHAPERONE_SINGLETON return equal_func(vals._get_list(idx), args[idx], info, env, catch_equal_cont(vals, args, idx, env, cont))
def install_continuation_fast_path(current_cont, args, has_handlers, env, cont): from pycket.interpreter import return_multi_vals, return_void if not has_handlers: args = values.Values.make(args) return return_multi_vals(args, env, cont) unwind = find_handlers(current_cont, cont) cont = return_args_cont(args, env, cont) unwind = [x for x in reversed(unwind)] cont = do_unwind_cont(unwind, env, cont) return return_void(env, cont)
def install_continuation_fast_path(current_cont, args, has_handlers, env, cont): from pycket.interpreter import return_multi_vals, return_void if not has_handlers: args = values.Values.make(args) return return_multi_vals(args, env, cont) unwind = find_handlers(current_cont, cont) cont = return_args_cont(args, env, cont) unwind = [x for x in reversed(unwind)] cont = do_unwind_cont(unwind, env, cont) return return_void(env, cont)
def check_chaperone_results_loop(vals, args, idx, env, cont): from pycket.interpreter import return_multi_vals from pycket.prims.equal import equal_func_unroll_n, EqualInfo while idx < len(args) and vals.get_value(idx) is None and args[idx] is None: idx += 1 if idx >= len(args): return return_multi_vals(vals, env, cont) info = EqualInfo.CHAPERONE_SINGLETON # XXX it would be best to store the parameter on the toplevel env and make # it changeable via a cmdline parameter to pycket-c unroll_n_times = 2 # XXX needs tuning return equal_func_unroll_n(vals.get_value(idx), args[idx], info, env, catch_equal_cont(vals, args, idx, env, cont), unroll_n_times)
def check_chaperone_results_loop(vals, args, idx, env, cont): from pycket.interpreter import return_multi_vals from pycket.prims.equal import equal_func_unroll_n, EqualInfo while idx < len(args) and vals.get_value(idx) is None and args[idx] is None: idx += 1 if idx >= len(args): return return_multi_vals(vals, env, cont) info = EqualInfo.CHAPERONE_SINGLETON # XXX it would be best to store the parameter on the toplevel env and make # it changeable via a cmdline parameter to pycket-c unroll_n_times = 2 # XXX needs tuning return equal_func_unroll_n(vals.get_value(idx), args[idx], info, env, catch_equal_cont(vals, args, idx, env, cont), unroll_n_times)
def func_result_handling(*args): from pycket.interpreter import (return_multi_vals, return_value_direct) from pycket import values env = args[-2] cont = args[-1] args = args[:-2] result = func_arg_unwrap(*args) if result is None: result = values.w_void if isinstance(result, values.Values): return return_multi_vals(result, env, cont) else: return return_value_direct(result, env, cont)
def install_continuation(cont, prompt_tag, args, env, current_cont, extend=False, escape=False): from pycket.interpreter import return_multi_vals, return_void # Find the common merge point for two continuations # The extend option controls whether or not we remove frames from the # existing continuation, or simply stack the new continuation on top. # This is what differentiates call-with-current-continuation from # call-with-composable-continuation. if extend: _, rewind = find_continuation_prompt(prompt_tag, cont, direction='rewind') base, unwind = current_cont, None stop = None else: head1, handlers = scan_continuation(current_cont, prompt_tag, look_for=cont, escape=escape) if head1 is None: return install_continuation_fast_path(current_cont, args, handlers, env, cont) head2, _ = scan_continuation(cont, prompt_tag) base, stop, unwind, rewind = find_merge_point(head1, head2) # Append the continuations at the appropriate prompt if base is not None: cont = cont.append(base, stop=stop, upto=prompt_tag) # Fast path if no unwinding is required (avoids continuation allocation) if not unwind and not rewind: args = values.Values.make(args) return return_multi_vals(args, env, cont) # NOTE: All the continuations pushed here expect no arguments # They simply wrap functions which we could call directly, but using # continuations to perform the desired sequencing is easier. cont = return_args_cont(args, env, cont) if rewind: cont = do_rewind_cont(rewind, env, cont) if unwind: unwind = [x for x in reversed(unwind)] cont = do_unwind_cont(unwind, env, cont) return return_void(env, cont)
def func_result_handling(*args): from pycket.interpreter import (return_multi_vals, return_value_direct) from pycket import values env = args[-2] cont = args[-1] args = args[:-2] result = func_arg_unwrap(*args) if result is None: result = values.w_void if isinstance(result, values.Values): return return_multi_vals(result, env, cont) else: return return_value_direct(result, 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 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 split_path(w_path, env, cont): from pycket.interpreter import return_multi_vals path = extract_path(w_path) dirname = _dirname(path) basename = _basename(path) name = _explode_element(basename) if dirname == os.path.sep: base = values.w_false must_be_dir = values.w_false elif name is UP or name is SAME: base = RELATIVE must_be_dir = values.w_true else: base = values.W_Path(dirname + os.path.sep) must_be_dir = values.w_false result = values.Values.make([base, name, must_be_dir]) return return_multi_vals(result, env, cont)
def split_path(w_path, env, cont): from pycket.interpreter import return_multi_vals path = extract_path(w_path) dirname = _dirname(path) basename = _basename(path) name = _explode_element(basename) if dirname == os.path.sep: base = values.w_false must_be_dir = values.w_false elif name is UP or name is SAME: base = RELATIVE must_be_dir = values.w_true else: base = values.W_Path(dirname + os.path.sep) must_be_dir = values.w_false result = values.Values.make([base, name, must_be_dir]) return return_multi_vals(result, env, cont)
def _make_result_handling_func(func_arg_unwrap, simple): if simple: def func_result_handling(*args): from pycket.interpreter import return_multi_vals, return_value_direct from pycket.prims.control import convert_runtime_exception from pycket import values env = args[-2] cont = args[-1] args = args[:-2] try: result = func_arg_unwrap(*args) except SchemeException, exn: return convert_runtime_exception(exn, env, cont) if result is None: result = values.w_void if isinstance(result, values.Values): return return_multi_vals(result, env, cont) else: return return_value_direct(result, env, cont) return func_result_handling
def _make_result_handling_func(func_arg_unwrap, simple): if simple: def func_result_handling(*args): from pycket.interpreter import return_multi_vals, return_value_direct from pycket.prims.control import convert_runtime_exception, convert_os_error from pycket import values env = args[-2] cont = args[-1] args = args[:-2] try: result = func_arg_unwrap(*args) except SchemeException, exn: return convert_runtime_exception(exn, env, cont) except OSError, exn: return convert_os_error(exn, env, cont) if result is None: result = values.w_void if isinstance(result, values.Values): return return_multi_vals(result, env, cont) else: return return_value_direct(result, env, cont)
def install_continuation(cont, prompt_tag, args, env, current_cont, extend=False, escape=False): from pycket.interpreter import return_multi_vals, return_void # Find the common merge point for two continuations # The extend option controls whether or not we remove frames from the # existing continuation, or simply stack the new continuation on top. # This is what differentiates call-with-current-continuation from # call-with-composable-continuation. if extend: _ , rewind = find_continuation_prompt(prompt_tag, cont, direction='rewind') base, unwind = current_cont, None stop = None else: head1, handlers = scan_continuation( current_cont, prompt_tag, look_for=cont, escape=escape) if head1 is None: return install_continuation_fast_path(current_cont, args, handlers, env, cont) head2, _ = scan_continuation(cont, prompt_tag) base, stop, unwind, rewind = find_merge_point(head1, head2) # Append the continuations at the appropriate prompt if base is not None: cont = cont.append(base, stop=stop, upto=prompt_tag) # Fast path if no unwinding is required (avoids continuation allocation) if not unwind and not rewind: args = values.Values.make(args) return return_multi_vals(args, env, cont) # NOTE: All the continuations pushed here expect no arguments # They simply wrap functions which we could call directly, but using # continuations to perform the desired sequencing is easier. cont = return_args_cont(args, env, cont) if rewind: cont = do_rewind_cont(rewind, env, cont) if unwind: unwind = [x for x in reversed(unwind)] cont = do_unwind_cont(unwind, env, cont) return return_void(env, cont)
def call_with_escape_continuation_cont(env, cont, _vals): # Does not do anything currently. Solely to ensure call/ec does not invoke # its procedure in tail position from pycket.interpreter import return_multi_vals return return_multi_vals(_vals, env, cont)
def dynamic_wind_post_cont(val, env, cont, _vals): from pycket.interpreter import return_multi_vals return return_multi_vals(val, env, cont)
def return_args_cont(args, env, cont, _vals): from pycket.interpreter import return_multi_vals args = values.Values.make(args) return return_multi_vals(args, env, cont)
def call(self, args, env, cont): from pycket.interpreter import return_multi_vals return return_multi_vals(Values.make(args), env, self.cont)
def call_with_escape_continuation_cont(env, cont, _vals): # Does not do anything currently. Solely to ensure call/ec does not invoke # its procedure in tail position from pycket.interpreter import return_multi_vals return return_multi_vals(_vals, env, cont)
def port_next_loc(p, env, cont): from pycket.interpreter import return_multi_vals return return_multi_vals(values.Values.make([values.w_false] * 3), env, cont)
def return_args_cont(args, env, cont, _vals): from pycket.interpreter import return_multi_vals args = values.Values.make(args) return return_multi_vals(args, env, cont)
def imp_hash_table_post_ref_cont(post, ht, old, env, cont, _vals): from pycket.interpreter import check_one_val, return_multi_vals val = check_one_val(_vals) if val is None: return return_multi_vals(_vals, env, cont) return post.call([ht, old, val], env, cont)
def get_struct_info(self, env, cont): from pycket.interpreter import return_multi_vals return return_multi_vals( values.Values.make([self.struct_type(), values.w_false]), env, cont)
def port_next_loc(p, env, cont): from pycket.interpreter import return_multi_vals return return_multi_vals(values.Values.make([values.w_false] * 3), env, cont)
def close_cont(port, env, cont, vals): from pycket.interpreter import return_multi_vals port.close() return return_multi_vals(vals, env, cont)
def procedure_result_arity(proc, env, cont): from pycket.interpreter import return_multi_vals arity = proc.get_result_arity() if arity is None: return return_multi_vals(values.w_false, env, cont) return arity_to_value(arity, env, cont)
def sem_post_cont(sem, env, cont, vals): sem.post() from pycket.interpreter import return_multi_vals return return_multi_vals(vals, env, cont)
def call(self, args, env, cont): from pycket.interpreter import return_multi_vals return return_multi_vals(Values.make(args), env, self.cont)
def dynamic_wind_post_cont(val, env, cont, _vals): from pycket.interpreter import return_multi_vals return return_multi_vals(val, env, cont)
def split_path(w_path, env, cont): from pycket.interpreter import return_multi_vals path = extract_path(w_path) base, name, must_be_dir = _split_path(path) result = values.Values.make([base, name, must_be_dir]) return return_multi_vals(result, env, cont)
def get_struct_info(self, env, cont): from pycket.interpreter import return_multi_vals vals = values.Values._make2(self.struct_type(), values.w_false) return return_multi_vals(vals, env, cont)
def get_struct_info(self, env, cont): from pycket.interpreter import return_multi_vals vals = values.Values._make2(self.struct_type(), values.w_false) return return_multi_vals(vals, env, cont)
def sem_post_cont(sem, env, cont, vals): sem.post() from pycket.interpreter import return_multi_vals return return_multi_vals(vals, env, cont)
def close_cont(port, env, cont, vals): from pycket.interpreter import return_multi_vals port.close() return return_multi_vals(vals, env, cont)