コード例 #1
0
ファイル: json.py プロジェクト: pombredanne/pyllisp
def decode(stream):
    stream.skipspace()
    if stream.shift(u'{'):
        dct = space.Dict()
        if stream.shift(u'}'):
            return dct
        decode_pair(stream, dct)
        while stream.shift(u','):
            decode_pair(stream, dct)
            stream.skipspace()
        stream.skipspace()
        stream.expect(u'}')
        return dct
    if stream.shift(u'['):
        lst = []
        if stream.shift(u']'):
            return space.List(lst)
        lst.append(decode(stream))
        while stream.shift(u','):
            lst.append(decode(stream))
            stream.skipspace()
        stream.skipspace()
        stream.expect(u']')
        return space.List(lst)
    if stream.get() == u'"':
        return decode_string(stream)
    if stream.shift(u'f'):
        stream.expect(u'a')
        stream.expect(u'l')
        stream.expect(u's')
        stream.expect(u'e')
        return space.false
    if stream.shift(u't'):
        stream.expect(u'r')
        stream.expect(u'u')
        stream.expect(u'e')
        return space.true
    if stream.shift(u'n'):
        stream.expect(u'u')
        stream.expect(u'l')
        stream.expect(u'l')
        return space.null
    if stream.shift(u'-'):
        sign = -1
    else:
        sign = +1
    num = digits(stream)
    if stream.shift(u'.'):
        num += u'.' + digits(stream)
        if stream.get() in u'eE':
            raise space.Error(u"XXX")
        return space.Float(float(num.encode('utf-8')))
    else:
        if stream.get() in u'eE':
            raise space.Error(u"XXX")
        return space.Integer(sign * int(num.encode('utf-8')))
    raise space.Error(u"JSON decode error at %s" % stream.get())
コード例 #2
0
ファイル: __init__.py プロジェクト: pombredanne/pyllisp
def from_macro(env, exp):
    if len(exp.exps) == 2:
        exp.exps.extend(env.capture(exp))
    if len(exp.exps) <= 2:
        raise space.Error(u"%s: format: from expr symbol..." %
                          exp.start.repr())
    val = translate(env, exp.exps[1])
    for attr in exp.exps[2:]:
        if isinstance(attr, reader.Literal) and attr.name == u'symbol':
            var = env.add(GetAttr(val, attr.value))
            env.add(SetLocal(attr.value, var, False))
        else:
            raise space.Error(u"%s: expected symbol" % attr.start.repr())
    return val
コード例 #3
0
ファイル: __init__.py プロジェクト: pombredanne/pyllisp
 def call(self, argv):
     if len(argv) != 1:
         raise space.Error(u"program expects module as an argument")
     module = argv[0]
     assert isinstance(module, space.Module)
     frame = ActivationRecord(module, None)
     return interpret(self.body, frame)
コード例 #4
0
ファイル: __init__.py プロジェクト: pombredanne/pyllisp
 def call(self, argv):
     argc = len(self.func.args)
     if len(argv) < argc:
         raise space.Error(u"closure requires %d arguments" % argc)
     frame = ActivationRecord(self.frame.module, self.frame)
     for i in range(argc):
         frame.var[self.func.args[i]] = argv[i]
     return interpret(self.func.body, frame)
コード例 #5
0
ファイル: __init__.py プロジェクト: pombredanne/pyllisp
def yield_macro(env, exp):
    if len(exp.exps) != 2:
        raise space.Error(u"%s: format: yield expr" % exp.start.repr())
    env.is_generator = True
    val = translate(env, exp.exps[1])
    yield_ = env.add(Yield(val, env.new_block()))
    env.block = yield_.block
    return yield_
コード例 #6
0
 def call(self, argv):
     if len(argv) != 1:
         raise space.Error(u"program expects module as an argument")
     module = argv[0]
     assert isinstance(module, space.Module)
     entry = self.unit.functions[0]
     frame = Frame(entry, module, None)
     regv = new_register_array(entry.regc)
     return interpret(0, entry.block, regv, frame)
コード例 #7
0
 def call(self, argv):
     argc = self.function.argc
     if len(argv) < argc:
         raise space.Error(u"closure requires %d arguments" % argc)
     frame = Frame(self.function, self.frame.module, self.frame)
     for i in range(argc):
         frame.local[i] = argv[i]
     regv = new_register_array(self.function.regc)
     return interpret(0, self.function.block, regv, frame)
コード例 #8
0
ファイル: __init__.py プロジェクト: pombredanne/pyllisp
def translate_chain(env, chain):
    chain_above = env.chain
    exp = chain.pop(0)
    env.chain = chain
    val = translate(env, exp)
    if len(env.chain) > 0:
        raise space.Error(u"%s: chain without receiver" % exp.start.repr())
    env.chain = chain_above
    return val
コード例 #9
0
ファイル: __init__.py プロジェクト: pombredanne/pyllisp
def or_macro(env, exp):
    if len(exp.exps) != 3:
        raise space.Error(u"no translation for %s with length != 3" % exp.name)
    val = translate(env, exp.exps[1])
    cond = env.add(Cond(val))
    cond.exit = env.block = env.new_block()
    cond.then = env.new_block()
    env.add(Merge(val, translate(env, exp.exps[2])))
    env.add(Jump(cond.then))
    env.block = cond.then
    return val
コード例 #10
0
ファイル: __init__.py プロジェクト: pombredanne/pyllisp
def func_macro(env, exp):
    argv = []
    for i in range(1, len(exp.exps)):
        arg = exp.exps[i]
        if isinstance(arg, reader.Literal) and arg.name == u'symbol':
            argv.append(arg.value)
        else:
            raise space.Error(u"%s: expected symbol inside func" %
                              arg.start.repr())
    body = env.capture(exp)
    return env.new_function(argv, body)
コード例 #11
0
ファイル: __init__.py プロジェクト: pombredanne/pyllisp
def for_macro(env, exp):
    if len(exp.exps) != 3:
        raise space.Error(u"no translation for %s with length != 2" % exp.name)
    var = exp.exps[1]
    if not isinstance(var, reader.Literal):
        raise space.Error(u"%s: format: for variable exp" % exp.start.repr())
    it = env.add(Iter(translate(env, exp.exps[2])))

    current_loop = (loop, exit, _) = (env.new_block(), env.new_block(), True)
    env.loop_stack.append(current_loop)
    cond = env.add(SetBreak(exit))

    env.add(Jump(loop))
    env.block = loop
    env.add(SetLocal(var.value, env.add(Next(it)), False))
    val = translate_flow(env, env.capture(exp))
    env.add(Merge(cond, val))
    env.add(Jump(loop))
    env.block = exit

    loop_exit(env)
    return cond
コード例 #12
0
ファイル: __init__.py プロジェクト: pombredanne/pyllisp
def if_macro(env, exp):
    if len(exp.exps) != 2:
        raise space.Error(u"no translation for %s with length != 2" % exp.name)
    chain = env.pull_chain()
    cond = Cond(translate(env, exp.exps[1]))
    env.add(cond)
    cond.then = env.block = env.new_block()
    cond.exit = exit = env.new_block()
    val = translate_flow(env, env.capture(exp))
    env.add(Merge(cond, val))
    env.add(Jump(exit))
    if len(chain) > 0:
        first = chain[0]
        if len(chain) > 1 and macro_name(first.exps[0]) != u'else' and len(
                first.exps) != 1:
            raise space.Error(u"%s: non-else longer chains not supported" %
                              exp.start.repr())
        env.block, exit = exit, env.new_block()
        val = translate_flow(env, first.capture)
        env.add(Merge(cond, val))
        env.add(Jump(exit))
    env.block = exit
    return cond
コード例 #13
0
ファイル: __init__.py プロジェクト: pombredanne/pyllisp
def while_macro(env, exp):
    if len(exp.exps) != 2:
        raise space.Error(u"no translation for %s with length != 2" % exp.name)
    current_loop = (loop, exit, _) = (env.new_label(), env.new_block(), False)
    env.loop_stack.append(current_loop)

    loop = env.new_label()
    cond = env.add(Cond(translate(env, exp.exps[1])))
    cond.then = env.block = env.new_block()
    cond.exit = env.new_block()
    val = translate_flow(env, env.capture(exp))
    env.add(Merge(cond, val))
    env.add(Jump(loop))
    env.block = cond.exit
    loop_exit(env)
    return cond
コード例 #14
0
ファイル: __init__.py プロジェクト: pombredanne/pyllisp
def store_value(env, lhs, value, upscope):
    if isinstance(lhs, reader.Literal) and lhs.name == u'symbol':
        return env.add(SetLocal(lhs.value, value, upscope))
    elif isinstance(lhs, reader.Expr) and lhs.name == u'attr' and len(
            lhs.exps) == 2:
        obj, name = lhs.exps
        obj = translate(env, obj)
        assert isinstance(name, reader.Literal)
        return env.add(SetAttr(obj, name.value, value))
    elif isinstance(lhs, reader.Expr) and lhs.name == u'index' and len(
            lhs.exps) == 2:
        obj, index = lhs.exps
        obj = translate(env, obj)
        index = translate(env, index)
        return env.add(SetItem(obj, index, value))
    else:
        raise space.Error(u"no translation for " + lhs.name)
コード例 #15
0
ファイル: json.py プロジェクト: pombredanne/pyllisp
def escape_ch(ch):
    if ch == u'"':
        return u'"'
    if ch == u'\\':
        return u'\\'
    if ch == u'\/':
        return u'/'
    if ch == u'b':
        return u'\b'
    if ch == u'f':
        return u'\f'
    if ch == u'n':
        return u'\n'
    if ch == u'r':
        return u'\r'
    if ch == u't':
        return u'\t'
    raise space.Error(u"JSON decode error")
コード例 #16
0
ファイル: __init__.py プロジェクト: pombredanne/pyllisp
def syntax_chain(env, exp):
    if len(exp.exps) < 3:
        raise space.Error(u"no translation for %s with length < 3" % exp.name)
    and_ = Variable(u'and')
    if len(exp.exps) > 3:
        env.add(and_)
    lhs = translate(env, exp.exps[0])
    op = translate(env, exp.exps[1])
    rhs = translate(env, exp.exps[2])
    res = env.add(Call(op, [lhs, rhs]))
    i = 3
    while i < len(exp.exps):
        lhs = rhs
        op = translate(env, exp.exps[i])
        rhs = translate(env, exp.exps[i + 1])
        res = env.add(Call(and_, [res, env.add(Call(op, [lhs, rhs]))]))
        i += 2
    return res
コード例 #17
0
ファイル: __init__.py プロジェクト: pombredanne/pyllisp
def store_aug_value(env, aug, lhs, value):
    aug = env.add(Variable(aug.value))
    if isinstance(lhs, reader.Literal) and lhs.name == u'symbol':
        name = lhs.value
        value = env.add(Call(aug, [env.add(Variable(name)), value]))
        return env.add(SetLocal(name, value, True))
    elif isinstance(lhs, reader.Expr) and lhs.name == u'attr' and len(
            lhs.exps) == 2:
        obj, name = lhs.exps
        assert isinstance(name, reader.Literal)
        obj = translate(env, obj)
        value = env.add(Call(aug, [env.add(GetAttr(obj, name.value)), value]))
        return env.add(SetAttr(obj, name.value, value))
    elif isinstance(lhs, reader.Expr) and lhs.name == u'index' and len(
            lhs.exps) == 2:
        obj, index = lhs.exps
        obj = translate(env, obj)
        index = translate(env, index)
        value = env.add(Call(aug, [env.add(GetItem(obj, index)), value]))
        return env.add(SetItem(obj, index, value))
    else:
        raise space.Error(u"no translation for " + lhs.name)
コード例 #18
0
ファイル: __init__.py プロジェクト: pombredanne/pyllisp
def interpret_body(block, t, cl_frame, loop_break):
    frame = Frame(t)
    pc = 0
    module = jit.promote(cl_frame.module)
    try:
        while pc < len(block):
            try:
                jitdriver.jit_merge_point(pc=pc,
                                          block=block,
                                          loop_break=loop_break,
                                          module=module,
                                          cl_frame=cl_frame,
                                          frame=frame)
                op = block[pc]
                pc += 1
                if isinstance(op, Call):
                    do_call(frame, op)
                elif isinstance(op, Assert):
                    if space.is_false(frame.load(op.value.i)):
                        raise space.Error(u"Assertion error")
                elif isinstance(op, Cond):
                    pc = 0
                    if space.is_false(frame.load(op.cond.i)):
                        block = op.exit
                    else:
                        block = op.then
                elif isinstance(op, Jump):
                    pc = 0
                    block = op.exit
                elif isinstance(op, Next):
                    frame.store(op.i,
                                frame.load(op.it.i).callattr(u'next', []))
                elif isinstance(op, Yield):
                    raise YieldIteration(op.block, loop_break, op.i,
                                         frame.load(op.value.i))
                elif isinstance(op, SetBreak):
                    loop_break = op.block
                elif isinstance(op, Iter):
                    frame.store(op.i, frame.load(op.value.i).iter())
                elif isinstance(op, Constant):
                    frame.store(op.i, op.value)
                elif isinstance(op, Variable):
                    frame.store(op.i, lookup(module, cl_frame, op.name))
                elif isinstance(op, Merge):
                    frame.store(op.dst.i, frame.load(op.src.i))
                elif isinstance(op, Function):
                    frame.store(op.i, Closure(cl_frame, op))
                elif isinstance(op, MakeList):
                    contents = []
                    for val in op.values:
                        contents.append(frame.load(val.i))
                    frame.store(op.i, space.List(contents))
                elif isinstance(op, GetAttr):
                    frame.store(op.i, frame.load(op.value.i).getattr(op.name))
                elif isinstance(op, GetItem):
                    frame.store(
                        op.i,
                        frame.load(op.value.i).getitem(frame.load(op.index.i)))
                elif isinstance(op, SetAttr):
                    frame.store(
                        op.i,
                        frame.load(op.obj.i).setattr(op.name,
                                                     frame.load(op.value.i)))
                elif isinstance(op, SetItem):
                    frame.store(
                        op.i,
                        frame.load(op.obj.i).setitem(frame.load(op.index.i),
                                                     frame.load(op.value.i)))
                elif isinstance(op, SetLocal):
                    frame.store(
                        op.i,
                        set_local(module, cl_frame, op.name,
                                  frame.load(op.value.i), op.upscope))
                elif isinstance(op, Return):
                    return frame.load(op.ref.i)
                else:
                    raise space.Error(u"spaced out")
            except StopIteration as stopiter:
                if loop_break is not None:
                    block = loop_break
                    loop_break = None
                    continue
                op = block[pc - 1]
                error = space.Error(u"stop iteration")
                error.stacktrace.append((cl_frame, op.start, op.stop))
                raise error
        raise space.Error(u"crappy compiler")
    except space.Error as e:
        op = block[pc - 1]
        e.stacktrace.append((cl_frame, op.start, op.stop))
        raise e
コード例 #19
0
def interpret(pc, block, regv, frame, iterstop=LARGE_PC):
    module = jit.promote(frame.module)
    unit   = jit.promote(frame.unit)
    try:
        while pc < len(block):
            jitdriver.jit_merge_point(
                pc=pc, block=block, module=module, unit=unit, iterstop=iterstop,
                regv=regv, frame=frame)
            opcode = rffi.r_ulong(block[pc])>>8
            ix = pc+1
            pc = ix+(rffi.r_ulong(block[pc])&255)
            if opcode == opcode_of('assert'):
                if space.is_false(regv.load(block[ix+0])):
                    raise space.Error(u"Assertion error")
            elif opcode == opcode_of('constant'):
                regv.store(block[ix+0], unit.constants[block[ix+1]])
            elif opcode == opcode_of('list'):
                contents = []
                for i in range(ix+1, pc):
                    contents.append(regv.load(block[i]))
                regv.store(block[ix], space.List(contents))
            elif opcode == opcode_of('move'):
                regv.store(block[ix+0], regv.load(block[ix+1]))
            elif opcode == opcode_of('call'):
                op_call(regv, block, ix, pc)
            elif opcode == opcode_of('return'):
                return regv.load(block[ix+0])
            elif opcode == opcode_of('jump'):
                pc = rffi.r_ulong(block[ix+0])
            elif opcode == opcode_of('cond'):
                if space.is_false(regv.load(block[ix+0])):
                    pc = rffi.r_ulong(block[ix+2])
                else:
                    pc = rffi.r_ulong(block[ix+1])
            elif opcode == opcode_of('func'):
                regv.store(block[ix+0],
                    Closure(frame, unit.functions[block[ix+1]]))
            elif opcode == opcode_of('iter'):
                regv.store(block[ix+0], regv.load(block[ix+1]).iter())
            elif opcode == opcode_of('iterstop'):
                iterstop = rffi.r_ulong(block[ix+0])
            elif opcode == opcode_of('next'):
                regv.store(block[ix+0], regv.load(block[ix+1]).callattr(u'next', []))
            # this is missing.
            #elif isinstance(op, Yield):
            #    raise YieldIteration(op.block, loop_break, op.i, regv.load(op.value.i))
            elif opcode == opcode_of('getattr'):
                name = get_string(unit, block, ix+2)
                obj = regv.load(block[ix+1])
                regv.store(block[ix+0], obj.getattr(name))
            elif opcode == opcode_of('setattr'):
                value = regv.load(block[ix+3])
                name = get_string(unit, block, ix+2)
                obj = regv.load(block[ix+1])
                regv.store(block[ix+0], obj.setattr(name, value))
            elif opcode == opcode_of('getitem'):
                index = regv.load(block[ix+2])
                obj = regv.load(block[ix+1])
                regv.store(block[ix+0], obj.getitem(index))
            elif opcode == opcode_of('setitem'):
                item = regv.load(block[ix+3])
                index = regv.load(block[ix+2])
                obj = regv.load(block[ix+1])
                regv.store(block[ix+0], obj.setitem(index, item))
            elif opcode == opcode_of('getloc'):
                regv.store(block[ix+0], frame.local[block[ix+1]])
            elif opcode == opcode_of('setloc'):
                value = regv.load(block[ix+2])
                frame.local[block[ix+1]] = value
                regv.store(block[ix+0], value)
            elif opcode == opcode_of('getupv'):
                value = get_upframe(frame, block[ix+1]).local[block[ix+2]]
                regv.store(block[ix+0], value)
            elif opcode == opcode_of('setupv'):
                value = regv.load(block[ix+3])
                get_upframe(frame, block[ix+1]).local[block[ix+2]] = value
                regv.store(block[ix+0], value)
            elif opcode == opcode_of('getglob'):
                regv.store(block[ix+0],
                    module.getattr(get_string(unit, block, ix+1)))
            elif opcode == opcode_of('setglob'):
                regv.store(block[ix+0],
                    module.setattr(
                        get_string(unit, block, ix+1),
                        regv.load(block[ix+2])))
            else:
                raise space.Error(u"unexpected instruction: " + optable.names.get(opcode, str(opcode)).decode('utf-8'))
    except StopIteration as stop:
        if iterstop != LARGE_PC:
            return interpret(iterstop, block, regv, frame)
        else:
            raise space.Error(u"StopIteration")

    return space.null
コード例 #20
0
ファイル: __init__.py プロジェクト: pombredanne/pyllisp
def translate_(env, exp):
    if isinstance(exp, reader.Literal):
        if exp.name == u'string':
            return env.add(Constant(space.from_ustring(exp.value)))
        elif exp.name == u'int':
            return env.add(
                Constant(space.Integer(int(exp.value.encode('utf-8')))))
        elif exp.name == u'hex':
            return env.add(
                Constant(space.Integer(int(exp.value[2:].encode('utf-8'),
                                           16))))
        elif exp.name == u'float':
            return env.add(
                Constant(space.Float(float(exp.value.encode('utf-8')))))
        elif exp.name == u'symbol':
            return env.add(Variable(exp.value))
        raise space.Error(u"no translation for " + exp.name)
    assert isinstance(exp, reader.Expr), exp.__class__.__name__
    if exp.name == u'form' and len(exp.exps) > 0:
        if macro_name(exp) in macros:
            cc = env.capture_catch
            if len(exp.capture) > 0:
                env.capture_catch = exp.capture
            res = macros[macro_name(exp)](env, exp)
            if len(exp.capture) > 0 and len(env.capture_catch) > 0:
                raise space.Error(u"%s: capture without receiver" %
                                  exp.start.repr())
            env.capture_catch = cc
            return res
        # callattr goes here, if it'll be needed
        args = translate_map(env, exp.exps)
        callee = args.pop(0)
        args.extend(translate_map(env, exp.capture))
        return env.add(Call(callee, args))
    elif exp.name == u'list':
        return env.add(MakeList(translate_map(env, exp.exps)))
    elif exp.name == u'attr' and len(exp.exps) == 2:
        lhs, name = exp.exps
        lhs = translate(env, lhs)
        if not isinstance(name, reader.Literal):
            raise space.Error(u"%s: bad attribute expr" % exp.repr())
        return env.add(GetAttr(lhs, name.value))
        sym.value
    elif exp.name == u'index' and len(exp.exps) == 2:
        lhs, rhs = exp.exps
        lhs = translate(env, lhs)
        rhs = translate(env, rhs)
        return env.add(GetItem(lhs, rhs))
    elif exp.name == u'let' or exp.name == u'set':
        lhs, rhs = exp.exps
        rhs = translate(env, rhs)
        return store_value(env, lhs, rhs, exp.name == u'set')
    elif exp.name == u'aug' and len(exp.exps) == 3:
        aug, lhs, rhs = exp.exps
        if not isinstance(aug, reader.Literal):
            raise space.Error(u"%s: bad augmented expr" % exp.repr())
        rhs = translate(env, rhs)
        return store_aug_value(env, aug, lhs, rhs)
    elif exp.name == u'chain':
        return syntax_chain(env, exp)
    raise space.Error(u"no translation for " + exp.name)
コード例 #21
0
ファイル: __init__.py プロジェクト: pombredanne/pyllisp
def continue_macro(env, exp):
    if len(exp.exps) != 1:
        raise space.Error(u"%s: format: continue" % exp.start.repr())
    if len(env.loop_stack) == 0:
        raise space.Error(u"%s: not inside a loop" % exp.start.repr())
    return env.add(Jump(env.loop_stack[-1][0]))
コード例 #22
0
ファイル: __init__.py プロジェクト: pombredanne/pyllisp
 def capture(self, exp):
     if len(self.capture_catch) == 0:
         raise space.Error(u"%s: expecting capture" % exp.start.repr())
     cap = self.capture_catch
     self.capture_catch = []
     return cap
コード例 #23
0
ファイル: json.py プロジェクト: pombredanne/pyllisp
 def expect(self, ch):
     if not self.shift(ch):
         raise space.Error(u"JSON decode expected '%s', got '%s'" %
                           (ch, self.get()))
コード例 #24
0
ファイル: __init__.py プロジェクト: pombredanne/pyllisp
def return_macro(env, exp):
    if len(exp.exps) != 2:
        raise space.Error(u"no translation for %s with length != 2" % exp.name)
    return env.add(Return(translate(env, exp.exps[1])))
コード例 #25
0
ファイル: __init__.py プロジェクト: pombredanne/pyllisp
def assert_macro(env, exp):
    if len(exp.exps) != 2:
        raise space.Error(u"no translation for %s with length != 2" % exp.name)
    val = translate(env, exp.exps[1])
    env.add(Assert(val))
    return val