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 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 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 macroexpand(form): sym = rt.first(form) if isinstance(sym, symbol.Symbol): s = rt.name(sym) if s.startswith(".") and s != u".": if rt.count(form) < 2: raise Exception("malformed dot expression, expecting (.member obj ...)") method = rt.keyword(rt.wrap(rt.name(sym)[1:])) obj = rt.first(rt.next(form)) dot = rt.symbol(rt.wrap(u".")) call = rt.cons(dot, rt.cons(obj, rt.cons(method, rt.next(rt.next(form))))) return call return form
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 macroexpand(form): sym = rt.first(form) if isinstance(sym, symbol.Symbol): s = rt.name(sym) if s.startswith(".") and s != u".": if rt.count(form) < 2: raise Exception( "malformed dot expression, expecting (.member obj ...)") method = rt.keyword(rt.wrap(rt.name(sym)[1:])) obj = rt.first(rt.next(form)) dot = rt.symbol(rt.wrap(u".")) call = rt.cons( dot, rt.cons(obj, rt.cons(method, rt.next(rt.next(form))))) return call return form
def syntax_quote(form): if isinstance(form, Symbol): 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, args): return rt.cons(args[1], args[0])
def invoke(self, rdr, ch): return rt.cons(symbol(u"-deref"), rt.cons(read(rdr, True), nil))
def __init__(self): self._vars = rt.cons(rt.hashmap(), nil)
def invoke(self, rdr, ch): return rt.cons(symbol(u"-deref"), rt.cons(read_inner(rdr, True), nil))
def compile_set_literal(form, ctx): vals = rt.reduce(ConsReduce(), nil, form) vector_call = rt.cons(rt.symbol(rt.wrap(u"vector")), vals) set_call = rt.cons(rt.symbol(rt.wrap(u"set")), rt.cons(vector_call, nil)) compile_cons(set_call, ctx)
def push_binding_frame(self): self._vars = rt.cons(rt.first(self._vars), self._vars)
def set_var_value(self, var, val): cur_frame = self.current_frame() self.pop_binding_frame() self._vars = rt.cons(rt._assoc(cur_frame, var, val), self._vars)