def substring(w_string, w_start, w_end): """ (substring str start [end]) -> string? str : string? start : exact-nonnegative-integer? end : exact-nonnegative-integer? = (string-length str) """ lenstring = w_string.length() start = w_start.value if start > lenstring or start < 0: raise SchemeException("substring: end index out of bounds") if w_end is not None: end = w_end.value if end > lenstring or end < 0: raise SchemeException("substring: end index out of bounds") else: end = lenstring if end < start: raise SchemeException( "substring: ending index is smaller than starting index") return w_string.getslice(start, end)
def string_copy_bang(w_dest, w_dest_start, w_src, w_src_start, w_src_end): from pycket.interpreter import return_value # FIXME: custom ports if w_dest.immutable(): raise SchemeException("string-copy!: given immutable string") dest_start = w_dest_start.value dest_len = w_dest.length() dest_max = (dest_len - dest_start) src_len = w_src.length() src_start = w_src_start.value src_end = w_src.length() if w_src_end is None else w_src_end.value if src_start >= src_len: raise SchemeException("string-copy!: source start too large") if src_end > src_len: raise SchemeException("string-copy!: source end too large") if src_end < src_start: raise SchemeException("string-copy!: source end before start") if dest_start >= dest_len: raise SchemeException("string-copy!: destination start too large") if src_end - src_start > dest_max: raise SchemeException("string-copy!: not enough room in target string") w_dest.setslice(dest_start, w_src, src_start, src_end) return values.w_void
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 if isinstance(input, values_string.W_String): bytestring = ['\0'] * (end - start) matched = input.getslice(start, end) for i in range(end - start): bytestring[i] = chr(ord(matched.getitem(i)) % 256) elif isinstance(input, values.W_Bytes): bytestring = input.getslice(start, end) else: raise SchemeException( "regexp-match-positions/end: unsupported input type") bytes = values.W_Bytes.from_charlist(bytestring, immutable=False) result = values.Values._make2(acc, bytes) return return_multi_vals(result, env, cont)
def from_list(w_curr, unroll_to=0): result = [] n = 0 while isinstance(w_curr, W_Cons): if from_list_unroll_pred(w_curr, n, unroll_to=unroll_to): return result + from_list_elidable(w_curr) result.append(w_curr.car()) w_curr = w_curr.cdr() n += 1 if w_curr is w_null: return result[:] # copy to make result non-resizable else: raise SchemeException("Expected list, but got something else")
def format(form, vals, name): fmt = form.as_str_utf8() # XXX for now i = 0 j = 0 result = [] len_fmt = len(fmt) while True: start = i while i < len_fmt: if fmt[i] == '~': break i += 1 else: # not left via break, so we're done result.append(fmt[start:len_fmt]) break result.append(fmt[start:i]) if i + 1 == len_fmt: raise SchemeException(name + ": bad format string") s = fmt[i + 1] if (s == 'a' or # turns into switch s == 'A' or s == 's' or s == 'S' or s == 'v' or s == 'V' or s == 'e' or s == 'E' or s == '.'): if j >= len(vals): raise SchemeException( name + ": not enough arguments for format string") result.append(vals[j].tostring()) j += 1 elif s == 'n' or s == '%': result.append("\n") # newline elif s == '~': result.append("~") else: raise SchemeException("%s: undexpected format character '%s'" % (name, s)) i += 2 if j != len(vals): raise SchemeException(name + ": not all values used") return "".join(result)
def _compiler_sizeof(ctype): if ctype.is_proper_list(): acc = 0 for type in values.from_list_iter(ctype): if not isinstance(type, values.W_Symbol): break size = _compiler_sizeof(type) acc = max(size, acc) else: return acc if not isinstance(ctype, values.W_Symbol): msg = ( "compiler-sizeof: expected (or/c symbol? (listof symbol?)) in argument 0 got %s" % ctype.tostring()) raise SchemeException(msg) for sym, size in COMPILER_SIZEOF: if ctype is sym: return size raise SchemeException("compiler-sizeof: %s is not a valid C type" % ctype.tostring())
def call(self, args, env, cont): from pycket.interpreter import return_value if len(args) == 0: return self.parameter.call(args, env, call_cont(self.wrap, env, cont)) elif len(args) == 1: if self.guard: return self.guard.call(args, env, call_cont(self.parameter, env, cont)) return self.parameter.call(args, env, cont) else: raise SchemeException("wrong number of arguments to parameter")
def build_path(args): # XXX Does not check that we are joining absolute paths # Sorry again Windows if not args: raise SchemeException("build-path: expected at least 1 argument") result = [None] * len(args) for i, s in enumerate(args): if s is UP: part = ".." elif s is SAME: part = "." else: part = extract_path(s) if not part: raise SchemeException("build-path: path element is empty") if part == os.path.sep: part = "" result[i] = part path = os.path.sep.join(result) if not path: return ROOT return values.W_Path(path)
def error(args): if len(args) == 1: sym = args[0] raise SchemeException("error: %s" % sym.tostring()) else: first_arg = args[0] if isinstance(first_arg, values_string.W_String): from rpython.rlib.rstring import StringBuilder msg = StringBuilder() msg.append(first_arg.tostring()) v = args[1:] for item in v: msg.append(" %s" % item.tostring()) raise SchemeException(msg.build()) else: src = first_arg form = args[1] v = args[2:] assert isinstance(src, values.W_Symbol) assert isinstance(form, values_string.W_String) raise SchemeException("%s: %s" % ( src.tostring(), input_output.format(form, v, "error")))
def match(w_re, w_str): w_re = promote_to_regexp(w_re) if isinstance(w_str, values_string.W_String): s = w_str.as_str_ascii() # XXX for now result = w_re.match_string(s) return result if isinstance(w_str, values.W_Bytes): result = w_re.match_string(w_str.as_str()) return result if isinstance(w_str, values.W_InputPort): result = w_re.match_port(w_str) return result raise SchemeException("regexp-match: can't deal with this type")
def bytes(args): if len(args) == 0: return values.W_MutableBytes([]) assert len(args) > 0 builder = StringBuilder() for char in args: if not (isinstance(char, values.W_Fixnum) and 0 <= char.value <= 255): raise SchemeException("string: expected a character int") builder.append(chr(char.value)) return values.W_Bytes.from_string(builder.build(), immutable=False)
def func_arg_unwrap(*allargs): from pycket import values args = allargs[0] rest = allargs[1:] typed_args = () lenargs = len(args) if lenargs != num_args: raise SchemeException(errormsg_arity + str(lenargs)) if num_args == 1: return func_direct_unwrap(args[0], *rest) else: assert num_args == 2 return func_direct_unwrap(args[0], args[1], *rest)
def integer_bytes_to_integer(bstr, signed): # XXX Currently does not make use of the signed parameter bytes = bstr.as_bytes_list() if len(bytes) not in (4, 8): raise SchemeException( "floating-point-bytes->real: byte string must have length 2, 4, or 8" ) val = rarithmetic.r_int64(0) for i, v in enumerate(bytes): val += rarithmetic.r_int64(ord(v)) << (i * 8) return values.W_Flonum(longlong2float.longlong2float(val))
def regexp_replace(pattern, input, insert, prefix): matches = match_positions(pattern, input) if not matches: return input if isinstance(input, values_string.W_String): str = input.as_unicode() elif isinstance(input, values.W_Bytes): str = input.as_str().decode("utf-8") else: raise SchemeException("regexp-replace*: expected string or bytes input") if isinstance(insert, values_string.W_String): ins = insert.as_unicode() elif isinstance(insert, values.W_Bytes): ins = insert.as_str().decode("utf-8") else: raise SchemeException("regexp-replace*: expected string or bytes insert string") formatter = values_regex.parse_insert_string(ins) subs = values_regex.do_input_substitution(formatter, str, matches) start, end = matches[0] assert start >= 0 and end >= 0 result = u"".join([str[0:start], subs, str[end:]]) return values_string.W_String.fromunicode(result)
def func_direct_unwrap(arg1, arg2, *rest): typed_arg1 = unwrapper1(arg1) if typed_arg1 is not None: typed_arg2 = unwrapper2(arg2) if typed_arg2 is not None: return func(typed_arg1, typed_arg2, *rest) else: type_errormsg = type_errormsg2 arg = arg2 else: type_errormsg = type_errormsg1 arg = arg1 raise SchemeException(type_errormsg + arg.tostring())
def match_positions(w_re, w_str, start=0, end=sys.maxint): w_re = promote_to_regexp(w_re) if isinstance(w_str, values_string.W_String): s = w_str.as_unicode() # XXX for now result = w_re.match_string_positions(s, start, end) return result if isinstance(w_str, values.W_Bytes): result = w_re.match_string_positions(w_str.as_str(), start, end) return result if isinstance(w_str, values.W_InputPort): result = w_re.match_port_positions(w_str) return result raise SchemeException("regexp-match-positions: can't deal with this type")
def build_path(args): # this is terrible r = "" for a in args: if isinstance(a, values.W_Bytes): r = r + str(a.value) elif isinstance(a, values_string.W_String): r = r + a.as_str_utf8() elif isinstance(a, values.W_Path): r = r + a.path else: raise SchemeException("bad input to build-path: %s" % a) return values.W_Path(r)
def subbytes(w_bytes, w_start, w_end): """ (subbytes bstr start [end]) → bytes? bstr : bytes? start : exact-nonnegative-integer? end : exact-nonnegative-integer? = (bytes-length str) """ start = w_start.value length = w_bytes.length() if start > length or start < 0: raise SchemeException("subbytes: end index out of bounds") if w_end is not None: end = w_end.value if end > length or end < 0: raise SchemeException("subbytes: end index out of bounds") else: end = length if end < start: raise SchemeException( "subbytes: ending index is smaller than starting index") slice = w_bytes.getslice(start, end) return values.W_Bytes.from_charlist(slice, immutable=False)
def read_stream(stream): next_token = read_token(stream) if isinstance(next_token, SpecialToken): v = read_stream(stream) return next_token.finish(v) if isinstance(next_token, DelimToken): if not isinstance(next_token, LParenToken): raise SchemeException("read: unexpected %s" % next_token.str) v = read_list(stream, next_token.str) return v else: assert isinstance(next_token, values.W_Object) return next_token
def make_string(k, char): if char is None: char = u'\0' else: char = char.value c = ord(char) if k.value < 0: raise SchemeException("make-string: around negative") if c < 128: char = chr(c) return W_String.fromascii(char * k.value) else: char = unichr(c) return W_String.fromunicode(char * k.value)
def rmp(pat, input, inp_start, inp_end, output_port, prefix): 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: 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 values.w_false lst, _ = make_match_list(matches) return lst
def match_all_positions(who, w_re, w_str, start=0, end=sys.maxint): w_re = promote_to_regexp(w_re) if isinstance(w_str, values_string.W_String): s = w_str.as_unicode() # XXX for now result = w_re.match_all_string_positions(s, start, end) return result if isinstance(w_str, values.W_Bytes): result = w_re.match_all_string_positions(w_str.as_str(), start, end) return result if isinstance(w_str, values.W_InputPort): assert False, "not yet supported" # result = w_re.match_port_positions(w_str) # return result raise SchemeException("%s: can't deal with this type" % who)
def deserialize_exports(w_exports): r_exports, exports_len = to_rpython_list(w_exports) exports = {} for i, exp in enumerate(r_exports): if looks_like_an_export(exp): k = exp.cdr().car() gen_int_id = exp.cdr().cdr().car() ext_id = exp.cdr().cdr().cdr().car() exports[k] = Export(gen_int_id, ext_id) else: raise SchemeException( "looks like an invalid serialization of export : %s" % exp.tostring()) return exports
def do_write_string(w_str, port, start_pos, end_pos, env, cont): from pycket.interpreter import return_value start = start_pos.value assert start >= 0 if end_pos: end_pos = end_pos.value if end_pos < 0 or end_pos > w_str.length(): raise SchemeException("write-string: ending index out of range") else: end_pos = w_str.length() if port is None: port = current_out_param.get(cont) port.write(w_str.getslice(start, end_pos).as_str_utf8()) return return_value(values.W_Fixnum(end_pos - start), env, cont)
def get_arity(self): if self.iscallable(): typ = self.struct_type() proc = typ.prop_procedure if isinstance(proc, values.W_Fixnum): offset = typ.get_offset(typ.procedure_source) proc = self._ref(proc.value + offset) return proc.get_arity() else: # -1 for the self argument arity = proc.get_arity() return arity.shift_arity(-1) else: raise SchemeException("%s does not have arity" % self.tostring())
def instantiate_def_cont(forms, form, index, return_val, target, env, cont, _vals): values = _vals.get_all_values() len_values = len(values) if len(form.names) != len_values: raise SchemeException("%s -- expected %s values but got %s" % (form.tostring(), str(len(form.names)), str(len_values))) for i in range(len_values): name = form.names[i] value = values[i] env.toplevel_env().toplevel_set(name, value) return return_value(w_void, env, instantiate_val_cont(forms, index + 1, return_val, target, env, cont))
def instantiate_linklet(linkl, import_instances, target_instance, use_prompt, env, cont): from pycket.util import console_log console_log("instantiating linklet : %s" % linkl.name.tostring(), 4) prompt = False if use_prompt is not w_false: # use-prompt? : any/c = #t - what happens when it is 3 ? prompt = True im_list, im_length = to_rpython_list(import_instances) expected = len(linkl.importss) if expected != im_length: raise SchemeException("The number of instances in import-instances must match the number of import sets in linklet. Expected %s but got %s" % (expected, im_length)) if target_instance is w_false: target = None elif isinstance(target_instance, W_LinkletInstance): target = target_instance else: raise SchemeException("Expected #f or instance? as target-instance, got : %s" % target_instance) with PerfRegionCPS("instantiate-linklet"): cont_ = finish_perf_region_cont("instantiate-linklet", env, cont) return linkl.instantiate(im_list, env.toplevel_env()._pycketconfig, prompt, target, env, cont_)
def arith_quotient_same(self, other): assert isinstance(other, values.W_Fixnum) x = self.value y = other.value if y: try: res = int_floordiv_ovf( x, y) # misnomer, should be int_truncdiv or so except OverflowError: return self.arith_quotient( values.W_Bignum(rbigint.fromint(other.value))) else: raise SchemeException("zero_divisor") return values.W_Fixnum(res)
def do_make_struct_type(name, super_type, w_init_field_cnt, w_auto_field_cnt, auto_v, props, inspector, proc_spec, w_immutables, guard, constr_name, env, cont): if inspector is None: inspector = values_struct.current_inspector_param.get(cont) if constr_name is not values.w_false and not isinstance(constr_name, values.W_Symbol): raise SchemeException("make-struct-type: constructor name mustbe be symbol? or #f") if not isinstance(super_type, values_struct.W_StructType) and super_type is not values.w_false: raise SchemeException("make-struct-type: expected a struct-type? or #f for the super type , but got %s : %s" % (super_type, super_type.tostring())) init_field_cnt = w_init_field_cnt.value auto_field_cnt = w_auto_field_cnt.value immutables = [] for i in values.from_list_iter(w_immutables): if not isinstance(i, values.W_Fixnum) or i.value < 0: raise SchemeException("make-struct-type: expected list of positive integers for immutable fields") immutables.append(i.value) return values_struct.W_StructType.make(name, super_type, init_field_cnt, auto_field_cnt, auto_v, props, inspector, proc_spec, immutables, guard, constr_name, 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")