def invoke(self, rdr, ch): if ARG_ENV.deref() is not nil: throw_syntax_error_with_data(rdr, u"Nested #()s are not allowed") try: ARG_ENV.set_value(rt.assoc(EMPTY_MAP, ARG_MAX, rt.wrap(-1))) rdr.unread() form = read_inner(rdr, True) args = EMPTY_VECTOR percent_args = ARG_ENV.deref() max_arg = rt.get(percent_args, ARG_MAX) for i in range(1, max_arg.int_val() + 1): arg = rt.get(percent_args, rt.wrap(i)) if arg is nil: arg = ArgReader.gen_arg(i) args = rt.conj(args, arg) rest_arg = rt.get(percent_args, rt.wrap(-1)) if rest_arg is not nil: args = rt.conj(args, ARG_AMP) args = rt.conj(args, rest_arg) return rt.cons(symbol(u"fn*"), rt.cons(args, rt.cons(form, nil))) finally: ARG_ENV.set_value(nil)
def expand_list_rfn(ret, item): if is_unquote(item): ret = rt.conj(ret, rt.vector(rt.first(rt.next(item)))) elif is_unquote_splicing(item): ret = rt.conj(ret, rt.first(rt.next(item))) else: ret = rt.conj(ret, rt.vector(SyntaxQuoteReader.syntax_quote(item))) return ret
def compile_fn_body(name, args, body, ctx): new_ctx = Context(rt.name(name), rt.count(args), ctx) required_args = add_args(rt.name(name), args, new_ctx) bc = 0 if name is not None: affirm(isinstance(name, symbol.Symbol), u"Function names must be symbols") #new_ctx.add_local(name._str, Self()) arg_syms = EMPTY for x in range(rt.count(args)): sym = rt.nth(args, rt.wrap(x)) if not rt.name(sym) == u"&": arg_syms = rt.conj(rt.conj(arg_syms, sym), sym) body = rt.list(rt.cons(LOOP, rt.cons(arg_syms, body))) #new_ctx.push_recur_point(FunctionRecurPoint()) new_ctx.disable_tail_call() if body is nil: compile_form(body, new_ctx) else: while body is not nil: if rt.next(body) is nil: new_ctx.enable_tail_call() compile_form(rt.first(body), new_ctx) body = rt.next(body) if body is not nil: new_ctx.pop() new_ctx.bytecode.append(code.RETURN) closed_overs = new_ctx.closed_overs if len(closed_overs) == 0: ctx.push_const(new_ctx.to_code(required_args)) else: ctx.push_const(new_ctx.to_code(required_args)) for x in closed_overs: x.emit(ctx) ctx.bytecode.append(code.MAKE_CLOSURE) ctx.bytecode.append(r_uint(len(closed_overs))) ctx.sub_sp(len(closed_overs)) if required_args >= 0: ctx.bytecode.append(code.MAKE_VARIADIC) ctx.bytecode.append(r_uint(required_args)) return required_args, intmask(rt.count(args))
def inner_invoke(self, args): import pixie.vm.rt as rt import pixie.vm.persistent_vector as vector with with_ns(u"user"): NS_VAR.deref().include_stdlib() acc = vector.EMPTY for x in self._argv: acc = rt.conj(acc, rt.wrap(x)) PROGRAM_ARGUMENTS.set_root(acc) with with_ns(u"user"): try: f = None if self._file == '-': f, _, _ = create_stdio() else: if not path.isfile(self._file): print "Error: Cannot open '" + self._file + "'" os._exit(1) f = open(self._file) data = f.read() f.close() if data.startswith("#!"): newline_pos = data.find("\n") if newline_pos > 0: data = data[newline_pos:] rt.load_reader(StringReader(unicode_from_utf8(data))) except WrappedException as ex: print "Error: ", ex._ex.__repr__() os._exit(1)
def add_env_to_load_path(): pp = os.environ.get("PIXIE_PATH") if pp is not None: LP = rt.deref(LOAD_PATHS.deref()) for path in pp.split(":"): LP = rt.conj(LP, rt.wrap(path)) LOAD_PATHS.set_root(Atom(LP))
def inner_invoke(self, args): from pixie.vm.keyword import keyword import pixie.vm.rt as rt from pixie.vm.string import String import pixie.vm.persistent_vector as vector with with_ns(u"user"): NS_VAR.deref().include_stdlib() acc = vector.EMPTY for x in self._argv: acc = rt.conj(acc, rt.wrap(x)) PROGRAM_ARGUMENTS.set_root(acc) rdr = MetaDataReader(PromptReader()) with with_ns(u"user"): while True: try: val = read(rdr, False) if val is eof: break val = interpret(compile(val)) except WrappedException as ex: print "Error: ", ex._ex.__repr__() rdr.reset_line() continue if val is keyword(u"exit-repl"): break val = rt.str(val) assert isinstance(val, String), "str should always return a string" print val._str
def invoke(self, rdr, ch): acc = EMPTY_VECTOR while True: eat_whitespace(rdr) ch = rdr.read() if ch == u"]": return acc rdr.unread(ch) acc = rt.conj(acc, read(rdr, True))
def _seq(self): import pixie.vm.persistent_vector as vector import pixie.vm.persistent_hash_map as hmap from pixie.vm.keyword import keyword assert isinstance(self, RuntimeException) trace = vector.EMPTY trace_element = rt.hashmap(keyword(u"type"), keyword(u"runtime")) trace_element = rt.assoc(trace_element, keyword(u"data"), rt.wrap(self._data)) trace = rt.conj(trace, trace_element) for x in self._trace: tmap = x.trace_map() trace_element = hmap.EMPTY for key in tmap: val = tmap[key] trace_element = rt.assoc(trace_element, key, val) trace = rt.conj(trace, trace_element) return rt._seq(trace)
def invoke(self, rdr, ch): acc = EMPTY_VECTOR while True: try: eat_whitespace(rdr) except EOFError: rdr throw_syntax_error_with_data(rdr, u"Unmatched vector open '['") ch = rdr.read() if ch == u"]": return acc rdr.unread() itm = read_inner(rdr, True, always_return_form=False) if itm != rdr: acc = rt.conj(acc, itm)
def inner_invoke(self, args): import pixie.vm.rt as rt import pixie.vm.persistent_vector as vector with with_ns(u"user"): NS_VAR.deref().include_stdlib() acc = vector.EMPTY for x in self._argv: acc = rt.conj(acc, rt.wrap(x)) PROGRAM_ARGUMENTS.set_root(acc) with with_ns(u"user"): if self._file == '-': stdin, _, _ = create_stdio() code = stdin.read() interpret(compile(read(StringReader(unicode(code)), True))) else: rt.load_file(rt.wrap(self._file))
def inner_invoke(self, args): from pixie.vm.keyword import keyword import pixie.vm.rt as rt from pixie.vm.string import String import pixie.vm.persistent_vector as vector print "Pixie 0.1 - Interactive REPL" print "(" + platform.name + ", " + platform.cc + ")" print ":exit-repl or Ctrl-D to quit" print "----------------------------" with with_ns(u"user"): NS_VAR.deref().include_stdlib() acc = vector.EMPTY for x in self._argv: acc = rt.conj(acc, rt.wrap(x)) PROGRAM_ARGUMENTS.set_root(acc) rdr = MetaDataReader(PromptReader()) with with_ns(u"user"): while True: try: val = read(rdr, False) if val is eof: break val = interpret(compile(val)) self.set_recent_vars(val) except WrappedException as ex: print "Error: ", ex._ex.__repr__() rdr.reset_line() self.set_error_var(ex._ex) continue if val is keyword(u"exit-repl"): break val = rt._repr(val) assert isinstance(val, String), "str should always return a string" print unicode_to_utf8(val._str)
def add_to_load_paths(path): rt.reset_BANG_(LOAD_PATHS.deref(), rt.conj(rt.deref(LOAD_PATHS.deref()), rt.wrap(path)))
def split(a, b): affirm(rt.count(b) > 0, u"separator can't be empty") v = rt.vector() for s in rstring.split(rt.name(a), rt.name(b)): v = rt.conj(v, rt.wrap(s)) return v
def list_dir(self): assert isinstance(self, Path) result = rt.vector() for item in os.listdir(str(self._path)): result = rt.conj(result, rt.wrap(str(self._path) + "/" + str(item))) return result
def flatten_map_rfn(ret, item): return rt.conj(rt.conj(ret, rt.first(item)), rt.first(rt.next(item)))