def _throw(ex): from pixie.vm.keyword import keyword if isinstance(ex, RuntimeException): raise WrappedException(ex) if rt._satisfies_QMARK_(IVector, ex): data = rt.nth(ex, rt.wrap(0)) msg = rt.nth(ex, rt.wrap(1)) elif rt._satisfies_QMARK_(ILookup, ex): data = rt._val_at(ex, keyword(u"data"), nil) msg = rt._val_at(ex, keyword(u"msg"), nil) else: affirm(False, u"Can only throw vectors, maps and exceptions") return nil raise WrappedException(RuntimeException(msg, data))
def compile_fn(form, ctx): form = rt.next(form) if isinstance(rt.first(form), symbol.Symbol): name = rt.first(form) form = rt.next(form) else: name = symbol.symbol(default_fn_name) if rt._satisfies_QMARK_(rt.ISeq.deref(), rt.first(form)): arities = [] while form is not nil: required_arity, argc = compile_fn_body(name, rt.first(rt.first(form)), rt.next(rt.first(form)), ctx) arities.append(argc if required_arity == -1 else required_arity | 256) form = rt.next(form) ctx.bytecode.append(code.MAKE_MULTI_ARITY) ctx.bytecode.append(r_uint(len(arities))) arities.reverse() for x in arities: ctx.bytecode.append(r_uint(x)) ctx.add_sp(1) # result ctx.sub_sp(len(arities)) else: res = compile_fn_body(name, rt.first(form), rt.next(form), ctx) if rt.meta(name) is not nil: compile_meta(rt.meta(name), ctx)
def write_object(obj, wtr): wtr.flush() if isinstance(obj, String): write_string(rt.name(obj), wtr) elif isinstance(obj, Integer): write_int(obj.int_val(), wtr) elif isinstance(obj, BigInteger): #TODO test write_bigint(obj.bigint_val(), wtr) elif isinstance(obj, Float): write_float(obj.float_val(), wtr) elif isinstance(obj, Code): write_code(obj, wtr) elif obj is nil: wtr.write(chr(NIL)) elif isinstance(obj, Var): #wtr.write_cached_obj(obj, write_var) write_var(obj, wtr) elif rt._satisfies_QMARK_(rt.IMap.deref(), obj): write_map(obj, wtr) elif rt._satisfies_QMARK_(rt.IVector.deref(), obj): write_vector(obj, wtr) elif rt._satisfies_QMARK_(rt.ISeq.deref(), obj): write_seq(obj, wtr) elif isinstance(obj, Keyword): wtr.write_cached_obj(obj, write_keyword) elif isinstance(obj, LinePromise): wtr.write_cached_obj(obj, write_line_promise) elif obj is true: write_tag(TRUE, wtr) elif obj is false: write_tag(FALSE, wtr) elif isinstance(obj, Symbol): write_symbol(obj, wtr) elif isinstance(obj, Namespace): wtr.write_cached_obj(obj, write_namespace) elif isinstance(obj, InterpreterCodeInfo): wtr.write_cached_obj(obj, write_interpreter_code_info) else: from pixie.vm.libs.pxic.util import write_handlers handler = write_handlers.get(obj.type(), None) if handler is None: runtime_error(u"Object is not supported by pxic writer: " + rt.name(rt.str(obj.type()))) else: write_tag(TAGGED, wtr) write_string_raw(obj.type().name(), wtr) write_object(handler.invoke([obj]), wtr)
def invoke(self, rdr, ch): meta = read_inner(rdr, True) obj = read_inner(rdr, True) if isinstance(meta, Keyword): meta = rt.hashmap(meta, true) if isinstance(meta, Symbol): meta = rt.hashmap(keyword(u"tag"), meta) if rt._satisfies_QMARK_(rt.IMeta.deref(), obj): return rt.with_meta(obj, rt.merge(meta, rt.meta(obj))) return obj
def _eq(self, obj): assert isinstance(self, PersistentVector) if self is obj: return true elif isinstance(obj, PersistentVector): if self._cnt != obj._cnt: return false for i in range(0, intmask(self._cnt)): if not rt.eq(self.nth(i), obj.nth(i)): return false return true else: if obj is nil or not rt._satisfies_QMARK_(proto.ISeqable, obj): return false seq = rt.seq(obj) for i in range(0, intmask(self._cnt)): if seq is nil or not rt.eq(self.nth(i), rt.first(seq)): return false seq = rt.next(seq) if seq is not nil: return false return true
def vector_QMARK_(a): return true if rt._satisfies_QMARK_(rt.IVector.deref(), a) else false
def map_QMARK_(a): return true if rt._satisfies_QMARK_(rt.IMap.deref(), a) else false
def is_unquote_splicing(form): return True if rt._satisfies_QMARK_(rt.ISeq.deref(), form) \ and rt.eq(rt.first(form), UNQUOTE_SPLICING) \ else False
def is_unquote(form): return True if rt._satisfies_QMARK_(rt.ISeq.deref(), form) \ and rt.eq(rt.first(form), UNQUOTE) \ else False
def compile_form(form, ctx): if form is nil: ctx.push_const(nil) return if rt._satisfies_QMARK_(rt.ISeq.deref(), form) and form is not nil: form = macroexpand(form) return compile_cons(form, ctx) if isinstance(form, numbers.Integer): ctx.push_const(form) return if isinstance(form, numbers.BigInteger): ctx.push_const(form) return if isinstance(form, numbers.Float): ctx.push_const(form) return if isinstance(form, numbers.Ratio): ctx.push_const(form) return if isinstance(form, symbol.Symbol): name = rt.name(form) ns = rt.namespace(form) loc = resolve_local(ctx, name) var = resolve_var(ctx, form) if var is None and loc: loc.emit(ctx) return if var and loc and ns is None: loc.emit(ctx) return if var is None: name = rt.name(form) var = NS_VAR.deref().intern_or_make(name) ctx.push_const(var) meta = rt.meta(form) if meta is not nil: ctx.debug_points[len(ctx.bytecode)] = rt.interpreter_code_info(meta) ctx.bytecode.append(code.DEREF_VAR) return if isinstance(form, Bool) or form is nil: ctx.push_const(form) return if isinstance(form, Keyword): ctx.push_const(form) return if isinstance(form, PersistentVector): vector_var = rt.vector() size = rt.count(form) #assert rt.count(form).int_val() == 0 ctx.push_const(code.intern_var(u"pixie.stdlib", u"vector")) for x in range(size): compile_form(rt.nth(form, rt.wrap(x)), ctx) ctx.bytecode.append(code.INVOKE) ctx.bytecode.append(r_uint(size + 1)) ctx.sub_sp(size) compile_meta(rt.meta(form), ctx) return if isinstance(form, PersistentHashSet): compile_set_literal(form, ctx) return if rt._satisfies_QMARK_(rt.IMap.deref(), form): compile_map_literal(form, ctx) return if isinstance(form, String): ctx.push_const(form) return if isinstance(form, Character): ctx.push_const(form) return raise Exception("Can't compile ")
def compile_form(form, ctx): if form is nil: ctx.push_const(nil) return if rt._satisfies_QMARK_(rt.ISeq.deref(), form) and form is not nil: form = maybe_oop_invoke(form) return compile_cons(form, ctx) if isinstance(form, numbers.Integer): ctx.push_const(form) return if isinstance(form, numbers.BigInteger): ctx.push_const(form) return if isinstance(form, numbers.Float): ctx.push_const(form) return if isinstance(form, numbers.Ratio): ctx.push_const(form) return if isinstance(form, symbol.Symbol): name = rt.name(form) ns = rt.namespace(form) loc = resolve_local(ctx, name) var = resolve_var(form) if var is None and loc: loc.emit(ctx) return if var and loc and ns is None: loc.emit(ctx) return if var is None: name = rt.name(form) var = NS_VAR.deref().intern_or_make(name) ctx.push_const(var) meta = rt.meta(form) if meta is not nil: ctx.debug_points[len( ctx.bytecode)] = rt.interpreter_code_info(meta) ctx.bytecode.append(code.DEREF_VAR) return if isinstance(form, Bool) or form is nil: ctx.push_const(form) return if isinstance(form, Keyword): ctx.push_const(form) return if isinstance(form, PersistentVector): size = rt.count(form) #assert rt.count(form).int_val() == 0 ctx.push_const(code.intern_var(u"pixie.stdlib", u"vector")) for x in range(size): compile_form(rt.nth(form, rt.wrap(x)), ctx) ctx.bytecode.append(code.INVOKE) ctx.bytecode.append(r_uint(size + 1)) ctx.sub_sp(size) compile_meta(rt.meta(form), ctx) return if isinstance(form, PersistentHashSet): compile_set_literal(form, ctx) return if rt._satisfies_QMARK_(rt.IMap.deref(), form): compile_map_literal(form, ctx) return if isinstance(form, String): ctx.push_const(form) return if isinstance(form, Character): ctx.push_const(form) return raise Exception("Can't compile ")