Ejemplo n.º 1
0
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)
Ejemplo n.º 2
0
    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)
Ejemplo n.º 3
0
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)
Ejemplo n.º 4
0
def maybe_oop_invoke(form):
    head = rt.first(form)
    if isinstance(rt.first(form), symbol.Symbol) and rt.name(head).startswith(".-"):
        postfix = rt.next(form)
        affirm(rt.count(postfix) == 1, u" Attribute lookups must only have one argument")
        subject = rt.first(postfix)
        kw = keyword(rt.name(head)[2:])
        fn = symbol.symbol(u"pixie.stdlib/-get-attr")
        return create_from_list([fn, subject, kw])

    elif isinstance(rt.first(form), symbol.Symbol) and rt.name(head).startswith("."):
        subject = rt.first(rt.next(form))
        postfix = rt.next(rt.next(form))
        form = cons(keyword(rt.name(head)[1:]), postfix)
        form = cons(subject, form)
        form = cons(symbol.symbol(u"pixie.stdlib/-call-method"), form)
        return form

    else:
        return form
Ejemplo n.º 5
0
def maybe_oop_invoke(form):
    head = rt.first(form)
    if isinstance(rt.first(form),
                  symbol.Symbol) and rt.name(head).startswith(".-"):
        postfix = rt.next(form)
        affirm(
            rt.count(postfix) == 1,
            u" Attribute lookups must only have one argument")
        subject = rt.first(postfix)
        kw = keyword(rt.name(head)[2:])
        fn = symbol.symbol(u"pixie.stdlib/-get-attr")
        return create_from_list([fn, subject, kw])

    elif isinstance(rt.first(form),
                    symbol.Symbol) and rt.name(head).startswith("."):
        subject = rt.first(rt.next(form))
        postfix = rt.next(rt.next(form))
        form = cons(keyword(rt.name(head)[1:]), postfix)
        form = cons(subject, form)
        form = cons(symbol.symbol(u"pixie.stdlib/-call-method"), form)
        return form

    else:
        return form
Ejemplo n.º 6
0
def read_symbol(rdr, ch):
    acc = [ch]
    try:
        while True:
            ch = rdr.read()
            if is_whitespace(ch) or is_terminating_macro(ch):
                rdr.unread(ch)
                break
            acc.append(ch)
    except EOFError:
        pass

    sym_str = u"".join(acc)
    if sym_str == u"true":
        return true
    if sym_str == u"false":
        return false
    if sym_str == u"nil":
        return nil
    return symbol(sym_str)
Ejemplo n.º 7
0
def read_symbol(rdr, ch):
    acc = [ch]
    try:
        while True:
            ch = rdr.read()
            if is_whitespace(ch) or is_terminating_macro(ch):
                rdr.unread()
                break
            acc.append(ch)
    except EOFError:
        pass

    sym_str = u"".join(acc)
    if sym_str == u"true":
        return true
    if sym_str == u"false":
        return false
    if sym_str == u"nil":
        return nil
    return symbol(sym_str)
Ejemplo n.º 8
0
def read_obj(rdr):
    tag = read_tag(rdr)

    if tag == INT:
        return Integer(intmask(read_raw_integer(rdr)))
    elif tag == BIGINT:
        return BigInteger(read_raw_bigint(rdr))
    elif tag == CODE:
        return read_code(rdr)
    elif tag == NIL:
        return nil
    elif tag == VAR:
        return read_var(rdr)
    elif tag == STRING:
        return String(read_raw_string(rdr))
    elif tag == KEYWORD:
        return keyword(read_raw_string(rdr))
    elif tag == SYMBOL:
        return symbol(read_raw_string(rdr))
    elif tag == LINE_PROMISE:
        lp = LinePromise()
        lp._chrs = None
        lp._str = read_raw_string(rdr)
        return lp
    elif tag == MAP:
        return read_map(rdr)
    elif tag == TRUE:
        return true
    elif tag == FALSE:
        return false
    elif tag == NIL:
        return nil
    elif tag == VECTOR:
        return read_vector(rdr)
    elif tag == SEQ:
        return read_seq(rdr)
    elif tag == FLOAT:
        return read_float(rdr)
    elif tag == NAMESPACE:
        return read_namespace(rdr)
    elif tag == INT_STRING:
        return Integer(int(read_raw_string(rdr)))
    elif tag == BIGINT_STRING:
        return BigInteger(rbigint.fromstr(str(read_raw_string(rdr))))

    elif tag == NEW_CACHED_OBJ:
        return rdr.read_and_cache()
    elif tag == CACHED_OBJ:
        return rdr.read_cached_obj()

    elif tag == EOF:
        from pixie.vm.reader import eof

        return eof

    elif tag == CODE_INFO:
        return read_interpreter_code_info(rdr)

    elif tag == TAGGED:
        tp_name = read_raw_string(rdr)
        tp = get_type_by_name(tp_name)
        handler = read_handlers.get(tp, None)
        if handler is None:
            runtime_error(u"No type handler for " + tp_name)

        obj = read_obj(rdr)
        return handler.invoke([obj])
    else:
        runtime_error(u"No dispatch for bytecode: " + unicode(tag_name[tag]))

    return nil
Ejemplo n.º 9
0
 def invoke(self, rdr, ch):
     return rt.cons(symbol(u"-deref"), rt.cons(read(rdr, True), nil))
Ejemplo n.º 10
0
 def invoke(self, rdr, ch):
     itm = read(rdr, True)
     return cons(symbol(u"quote"), cons(itm))
Ejemplo n.º 11
0
            l = len(token) - 1
            if l > 3:
                throw_syntax_error_with_data(rdr, u"Invalid octal escape sequence: \\" + token)
            c = read_unicode_char(rdr, token, 1, l, 8)
            if c > 0377:
                throw_syntax_error_with_data(rdr, u"Octal escape sequences must be in range [0, 377]")
            return Character(c)
        else:
            throw_syntax_error_with_data(rdr, u"Unsupported character: \\" + token)

class DerefReader(ReaderHandler):
    def invoke(self, rdr, ch):
        return rt.cons(symbol(u"-deref"), rt.cons(read(rdr, True), nil))


QUOTE = symbol(u"quote")
UNQUOTE = symbol(u"unquote")
UNQUOTE_SPLICING = symbol(u"unquote-splicing")
APPLY = symbol(u"apply")
CONCAT = symbol(u"concat")
SEQ = symbol(u"seq")
LIST = symbol(u"list")

def is_unquote(form):
    return True if rt.satisfies_QMARK_(rt.ISeq.deref(), form) \
                   and rt.eq(rt.first(form), UNQUOTE) \
           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) \
Ejemplo n.º 12
0
        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)


LOOP = symbol.symbol(u"loop")


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))
Ejemplo n.º 13
0
 def invoke(self, rdr, ch):
     itm = read_inner(rdr, True)
     return cons(symbol(u"quote"), cons(itm))
Ejemplo n.º 14
0
 def invoke(self, rdr, ch):
     return rt.cons(symbol(u"-deref"), rt.cons(read_inner(rdr, True), nil))
Ejemplo n.º 15
0
def read_obj(rdr):
    tag = read_tag(rdr)

    if tag == INT:
        return Integer(intmask(read_raw_integer(rdr)))
    elif tag == CODE:
        return read_code(rdr)
    elif tag == NIL:
        return nil
    elif tag == VAR:
        return read_var(rdr)
    elif tag == STRING:
        return String(read_raw_string(rdr))
    elif tag == KEYWORD:
        return keyword(read_raw_string(rdr))
    elif tag == SYMBOL:
        return symbol(read_raw_string(rdr))
    elif tag == LINE_PROMISE:
        lp = LinePromise()
        lp._str = read_raw_string(rdr)
        return lp
    elif tag == MAP:
        return read_map(rdr)
    elif tag == TRUE:
        return true
    elif tag == FALSE:
        return false
    elif tag == NIL:
        return nil
    elif tag == VECTOR:
        return read_vector(rdr)
    elif tag == SEQ:
        return read_seq(rdr)
    elif tag == FLOAT:
        return read_float(rdr)
    elif tag == NAMESPACE:
        return read_namespace(rdr)
    elif tag == INT_STRING:
        return Integer(int(read_raw_string(rdr)))

    elif tag == NEW_CACHED_OBJ:
        return rdr.read_and_cache()
    elif tag == CACHED_OBJ:
        return rdr.read_cached_obj()

    elif tag == EOF:
        from pixie.vm.reader import eof
        return eof

    elif tag == CODE_INFO:
        return read_interpreter_code_info(rdr)

    elif tag == TAGGED:
        tp_name = read_raw_string(rdr)
        tp = get_type_by_name(tp_name)
        handler = read_handlers.get(tp, None)
        if handler is None:
            runtime_error(u"No type handler for " + tp_name)

        obj = read_obj(rdr)
        return handler.invoke([obj])
    else:
        runtime_error(u"No dispatch for bytecode: " + unicode(tag_name[tag]))

    return nil
Ejemplo n.º 16
0
from rpython.rlib.rsre import rsre_re as re

READING_FORM_VAR = code.intern_var(u"pixie.stdlib", u"*reading-form*")
READING_FORM_VAR.set_dynamic()
READING_FORM_VAR.set_root(false)

LINE_NUMBER_KW = keyword(u"line-number")
COLUMN_NUMBER_KW = keyword(u"column-number")
LINE_KW = keyword(u"line")
FILE_KW = keyword(u"file")

GEN_SYM_ENV = code.intern_var(u"pixie.stdlib.reader", u"*gen-sym-env*")
GEN_SYM_ENV.set_dynamic()
GEN_SYM_ENV.set_root(EMPTY_MAP)

ARG_AMP = symbol(u"&")
ARG_MAX = keyword(u"max-arg")
ARG_ENV = code.intern_var(u"pixie.stdlib.reader", u"*arg-env*")
ARG_ENV.set_dynamic()
ARG_ENV.set_root(nil)

class PlatformReader(object.Object):
    _type = object.Type(u"PlatformReader")

    def type(self):
        return PlatformReader._type

    def read(self):
        assert False

    def unread(self):
Ejemplo n.º 17
0
from pixie.vm.reader import read, StringReader
from pixie.vm.object import Object
from pixie.vm.cons import Cons
from pixie.vm.numbers import Integer
from pixie.vm.symbol import symbol, Symbol
from pixie.vm.persistent_vector import PersistentVector
import pixie.vm.rt as rt
import unittest


data = {u"(1 2)": (1, 2,),
        u"(foo)": (symbol(u"foo"),),
        u"foo": symbol(u"foo"),
        u"1": 1,
        u"2": 2,
        u"((42))": ((42,),),
        u"(platform+ 1 2)": (symbol(u"platform+"), 1, 2),
        u"[42 43 44]": [42, 43, 44]}

class TestReader(unittest.TestCase):
    def _compare(self, frm, to):
        if isinstance(to, tuple):
            assert isinstance(frm, Cons)

            for x in to:
                self._compare(frm.first(), x)
                frm = frm.next()
        elif isinstance(to, int):
            assert isinstance(frm, Integer)
            assert frm._int_val == to
Ejemplo n.º 18
0
        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)

LOOP = symbol.symbol(u"loop")

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

    affirm(isinstance(name, symbol.Symbol), u"Function names must be symbols")

    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)))
Ejemplo n.º 19
0
        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)


LOOP = symbol.symbol(u"loop*")


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)

    affirm(isinstance(name, symbol.Symbol), u"Function names must be symbols")

    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)))
Ejemplo n.º 20
0
        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)

LOOP = symbol.symbol(u"loop*")

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)

    affirm(isinstance(name, symbol.Symbol), u"Function names must be symbols")

    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)))
Ejemplo n.º 21
0
from pixie.vm.reader import read, StringReader
from pixie.vm.object import Object
from pixie.vm.cons import Cons
from pixie.vm.numbers import Integer
from pixie.vm.symbol import symbol, Symbol
from pixie.vm.persistent_vector import PersistentVector
import pixie.vm.rt as rt
import unittest

data = {
    u"(1 2)": (
        1,
        2,
    ),
    u"(foo)": (symbol(u"foo"), ),
    u"foo": symbol(u"foo"),
    u"1": 1,
    u"2": 2,
    u"((42))": ((42, ), ),
    u"(platform+ 1 2)": (symbol(u"platform+"), 1, 2),
    u"[42 43 44]": [42, 43, 44],
    u"(1 2 ; 7 8 9\n3)": (
        1,
        2,
        3,
    ),
    u"(1 2 ; 7 8 9\r\n3)": (
        1,
        2,
        3,
    )