def register_next_arg(n): arg_env = ARG_ENV.deref() max_arg = rt.get(arg_env, ARG_MAX) if n > max_arg.int_val(): arg_env = rt.assoc(arg_env, ARG_MAX, rt.wrap(n)) arg = rt.get(arg_env, rt.wrap(n), nil) if arg is nil: arg = ArgReader.gen_arg(n) arg_env = rt.assoc(arg_env, rt.wrap(n), arg) ARG_ENV.set_value(arg_env) return arg
def syntax_quote(form): if isinstance(form, Symbol) and compiler.is_compiler_special(form): ret = rt.list(QUOTE, form) elif isinstance(form, Symbol): if rt.namespace(form) is None and rt.name(form).endswith("#"): gmap = rt.deref(GEN_SYM_ENV) affirm(gmap is not nil, u"Gensym literal used outside a syntax quote") gs = rt.get(gmap, form) if gs is nil: gs = rt.symbol(rt.str(form, rt.wrap(u"__"), rt.gensym())) GEN_SYM_ENV.set_value(rt.assoc(gmap, form, gs)) form = gs else: var = rt.resolve_in(compiler.NS_VAR.deref(), form) if var is nil: form = rt.symbol(rt.str(rt.wrap(rt.name(rt.deref(compiler.NS_VAR))), rt.wrap(u"/"), form)) else: form = rt.symbol(rt.str(rt.wrap(rt.namespace(var)), rt.wrap(u"/"), rt.str(rt.wrap(rt.name(var))))) ret = rt.list(QUOTE, form) elif is_unquote(form): ret = rt.first(rt.next(form)) elif is_unquote_splicing(form): raise Exception("Unquote splicing not used inside list") elif rt.vector_QMARK_(form) is true: ret = rt.list(APPLY, CONCAT, SyntaxQuoteReader.expand_list(form)) elif rt.seq_QMARK_(form) is true: ret = rt.list(APPLY, LIST, rt.cons(CONCAT, SyntaxQuoteReader.expand_list(rt.seq(form)))) else: ret = rt.list(QUOTE, form) return ret
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 syntax_quote(form): if isinstance(form, Symbol) and compiler.is_compiler_special(form): ret = rt.list(QUOTE, form) elif isinstance(form, Symbol): if rt.namespace(form) is None and rt.name(form).endswith("#"): gmap = rt.deref(GEN_SYM_ENV) affirm(gmap is not nil, u"Gensym literal used outside a syntax quote") gs = rt.get(gmap, form) if gs is nil: gs = rt.symbol(rt.str(form, rt.wrap(u"__"), rt.gensym())) GEN_SYM_ENV.set_value(rt.assoc(gmap, form, gs)) form = gs else: var = rt.resolve_in(compiler.NS_VAR.deref(), form) if var is nil: form = rt.symbol(rt.str(rt.wrap(rt.name(rt.deref(compiler.NS_VAR))), rt.wrap(u"/"), form)) else: form = rt.symbol(rt.str(rt.wrap(rt.namespace(var)), rt.wrap(u"/"), rt.str(rt.wrap(rt.name(var))))) ret = rt.list(QUOTE, form) elif is_unquote(form): ret = rt.first(rt.next(form)) elif is_unquote_splicing(form): return runtime_error(u"Unquote splicing not used inside list") elif rt.vector_QMARK_(form) is true: ret = rt.list(APPLY, CONCAT, SyntaxQuoteReader.expand_list(form)) elif rt.map_QMARK_(form) is true: mes = SyntaxQuoteReader.flatten_map(form) ret = rt.list(APPLY, HASHMAP, rt.list(APPLY, CONCAT, SyntaxQuoteReader.expand_list(mes))) elif form is not nil and rt.seq_QMARK_(form) is true: ret = rt.list(APPLY, LIST, rt.cons(CONCAT, SyntaxQuoteReader.expand_list(rt.seq(form)))) else: ret = rt.list(QUOTE, form) return ret
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 ns_map(ns): from pixie.vm.symbol import Symbol affirm(isinstance(ns, code.Namespace) or isinstance(ns, Symbol), u"ns must be a symbol or a namespace") if isinstance(ns, Symbol): ns = rt.the_ns(ns) if ns is nil: return nil m = rt.hashmap() for name in ns._registry: var = ns._registry.get(name, nil) m = rt.assoc(m, rt.symbol(rt.wrap(name)), var) return m
def ns_aliases(ns): from pixie.vm.symbol import Symbol affirm(isinstance(ns, Namespace) or isinstance(ns, Symbol), u"ns must be a symbol or a namespace") if isinstance(ns, Symbol): ns = rt.the_ns(ns) if ns is nil: return nil if isinstance(ns, Namespace): m = rt.hashmap() for alias in ns._refers: refered_ns = ns._refers[alias]._namespace m = rt.assoc(m, rt.symbol(rt.wrap(alias)), refered_ns) return m return nil
def ns_aliases(ns): from pixie.vm.symbol import Symbol affirm( isinstance(ns, Namespace) or isinstance(ns, Symbol), u"ns must be a symbol or a namespace") if isinstance(ns, Symbol): ns = rt.the_ns(ns) if ns is nil: return nil if isinstance(ns, Namespace): m = rt.hashmap() for alias in ns._refers: refered_ns = ns._refers[alias]._namespace m = rt.assoc(m, rt.symbol(rt.wrap(alias)), refered_ns) return m return nil
def ns_map(ns): from pixie.vm.symbol import Symbol affirm( isinstance(ns, Namespace) or isinstance(ns, Symbol), u"ns must be a symbol or a namespace") if isinstance(ns, Symbol): ns = rt.the_ns(ns) if ns is nil: return nil if isinstance(ns, Namespace): m = rt.hashmap() for name in ns._registry: var = ns._registry.get(name, nil) m = rt.assoc(m, rt.symbol(rt.wrap(name)), var) return m return nil