Example #1
0
 def bind(self, expr, name):
     """
     Generates code for binding a name to a value in the rule's locals dict.
     """
     return ast.Stmt([
              ast.Assign([ast.Subscript(ast.Name('__locals'),
                                        'OP_ASSIGN',
                                        [ast.Const(name)])],
                         expr),
              ast.Subscript(ast.Name('__locals'),
                            'OP_APPLY', [ast.Const(name)])])
Example #2
0
def compileSlice(doc):
    assertResult(doc[0], "slice")
    assertResult(doc[1], "slice from")
    assertResult(doc[2], "slice to")
    assertResult(doc[3], "slice with step")
    return ast.Subscript(topy(doc[0]), 'OP_APPLY',
                         [ast.Sliceobj([topy(x) for x in doc[1:4]])])
Example #3
0
    def compileSubscriptPlace(objx, keyxs):
         assertResult(objx, "subscript")

         for key in keyxs:
             assertResult(key, "subscript with")

         return ast.Subscript(topy(objx), opname, map(topy, keyxs))
Example #4
0
def compileGetOp(op):
    lang = op.__language__
    opmodname = op.__language__.__module__

    if opmodname == modulename:
        langexpr = GlobalName(lang.__impl__.name)
    else:
        langexpr = ast.Getattr(ast.Subscript(logixglobal('lmodules'),
                                             'OP_APPLY',
                                             [ast.Const(opmodname)]),
                               lang.__impl__.name)

    return ast.Subscript(
        ast.Getattr(ast.Getattr(langexpr, '__impl__'), 'operators'),
        'OP_APPLY',
        [ast.Const(op.__syntax__.token)])
Example #5
0
 def compileSlicePlace(objx, fromx, tox, stepx):
      assertResult(objx, "slice")
      
      assertResult(fromx, "slice from ")
      assertResult(tox, "slice to")
      assertResult(stepx, "slice with step")
      
      return ast.Subscript(topy(objx), opname,
                           [ast.Sliceobj(map(topy, (fromx, tox, stepx)))])
Example #6
0
 def _do_IndexExpression(self, node, context):
     expr = self.transform(node.Target)
     index = node.Index
     if isinstance(index, SliceExpression) and index.SliceStep is None:
         lower = self.transform(index.SliceStart)
         upper = self.transform(index.SliceStop)
         return ast.Slice(expr, context, lower, upper)
     sub = self.transform(index)
     return ast.Subscript(expr, context, [sub])
Example #7
0
    def continuationOp(self, expr, parts):
        "__continue__"
        assertResult(expr, "call or subscript")

        res = topy(expr)

        for part in parts:
            kind = part[-1]
            args = part[:-1]
            if kind == 'call':
                funcArgs = []
                funcKws = {}
                for a in args:
                    if isinstance(a, rootops.PyOp) and a.__syntax__.token == '=':
                        if isinstance(a[0], Symbol):
                            funcKws[str(a[0])] = a[1]
                        else:
                            raise CompileError("invalid keyword arg %r" % a[0])
                    else:
                        funcArgs.append(a)

                star = part.get('star', None)
                dstar = part.get('dstar', None)
                
                res = compileFunctionCall(res, funcArgs, funcKws, star, dstar)

            elif kind == 'subscript':
                for key in args:
                    assertResult(key, "subscript with")
                res = ast.Subscript(res, 'OP_APPLY', map(topy, args))

            elif kind == 'slice':
                start, end, step = args
                assertResult(start, "slice from")
                assertResult(end, "slice to")
                assertResult(step, "slice with step")

                res = ast.Subscript(res, 'OP_APPLY',
                                    [ast.Sliceobj(map(topy, (start, end, step)))])

        return res
Example #8
0
    def continuationOp(self, expr, *parts):
        "" # The language knows it as the blank operator
        assertResult(expr, "call or subscript")

        res = topy(expr)

        for part in parts:
            kind = part[-1]
            args = part[:-1]
            if kind == 'call':
                funcArgs = []
                funcKws = {}
                for a in args:
                    if isPyOp(a, "="):
                        if isinstance(a[0], Symbol) and a[0].namespace == "":
                            funcKws[a[0].name] = a[1]
                        else:
                            raise CompileError("invalid keyword arg %r" % a[0])
                    else:
                        funcArgs.append(a)

                star = part.get('star')
                dstar = part.get('dstar')
                
                res = compileFunctionCall(res, funcArgs, funcKws, star, dstar)

            elif kind == 'subscript':
                for key in args:
                    assertResult(key, "subscript with")
                res = ast.Subscript(res, 'OP_APPLY', map(topy, args))

            elif kind == 'slice':
                start, end, step = args
                assertResult(start, "slice from")
                assertResult(end, "slice to")
                assertResult(step, "slice with step")

                res = ast.Subscript(res, 'OP_APPLY',
                                    [ast.Sliceobj(map(topy, (start, end, step)))])

        return res
Example #9
0
def compileGetOp(symbol):
    lang = language.getLanguage(symbol.namespace)

    if lang is None:
        debug()
        raise CompileError, "not an operator symbol: %s" % symbol
        
    opmodname = lang.__module__

    if opmodname == modulename:
        langexpr = GlobalName(lang.__impl__.name)
    else:
        langexpr = ast.Getattr(ast.Subscript(logixglobal('lmodules'),
                                             'OP_APPLY',
                                             [ast.Const(opmodname)]),
                               lang.__impl__.name)

    return ast.Subscript(
        ast.Getattr(ast.Getattr(langexpr, '__impl__'), 'operators'),
        'OP_APPLY',
        [ast.Const(symbol.name)])
Example #10
0
 def visitAugAssign(self, node):
     if isinstance(node.node, ast.Name) and (
             not self.locals or node.node.name not in flatten(self.locals)):
         name = node.node.name
         node.node = ast.Subscript(ast.Name('data'), 'OP_APPLY',
                                   [ast.Const(name)])
         node.expr = self.visit(node.expr)
         return ast.If(
             [(ast.Compare(ast.Const(name),
                           [('in', ast.Name('data'))]), ast.Stmt([node]))],
             ast.Stmt([
                 ast.Raise(
                     ast.CallFunc(ast.Name('UndefinedError'),
                                  [ast.Const(name)]), None, None)
             ]))
     else:
         return ASTTransformer.visitAugAssign(self, node)
Example #11
0
def compileGetops(self, fromlang, *ops, **kw):
    targetlang = kw.get("lang")
    if targetlang is None:
        raise CompileError("No target language for getops"
                           "(getops in non-exec parse?)")

    assertResult(fromlang, "get operators from")

    lineno = getmeta(self, 'lineno')

    lastdot = targetlang.rfind('.')
    if lastdot == -1:
        targetlangexpr = GlobalName(targetlang)
    else:
        assert 0, ("PROBE: Why are we getting ops into an imported language?")
        langname = targetlang[lastdot+1:]
        langmod = targetlang[:lastdot]
        targetlangexpr = ast.Getattr(ast.Subscript(logixglobal('lmodules'),
                                                   'OP_APPLY',
                                                   [ast.Const(langmod)]),
                               langname)

    if len(ops) == 0:
        # get all operators
        res = ast.CallFunc(ast.Getattr(ast.Getattr(targetlangexpr, '__impl__'),
                                       'addAllOperators'),
                           [topy(fromlang)])
        
    else:
        stmts = [ast.CallFunc(ast.Getattr(ast.Getattr(targetlangexpr, '__impl__'),
                                          'addOp'),
                              [compileGetOp(op)])
                 for op in ops]

        for s in stmts: s.lineno = lineno
        res = ast.Stmt(stmts)

    res.lineno = lineno
    return res
Example #12
0
    def function(self, name, expr):
        """
        Create a function of one argument with the given name returning the
        given expr.

        @param name: The function name.
        @param expr: The AST to insert into the function.
        """

        fexpr = ast.Stmt([ast.Assign([ast.AssName('__locals', 'OP_ASSIGN')],
                                     ast.Dict([(ast.Const('self'),
                                                ast.Name('self'))])),
                          ast.Assign([ast.Subscript(ast.Getattr(
                                                  ast.Name('self'), 'locals'),
                                                    'OP_ASSIGN',
                                                    [ast.Const(
                                                     name.split('_',1)[1])])],
                                     ast.Name('__locals')),
                          expr])
        f = ast.Lambda(['self'], [], 0, fexpr)
        f.filename = self.name
        return f
Example #13
0
def compileDefop(doc):
    binding = doc['binding']
    ruledef = doc['ruledef']
    smartspace = doc.get('smartspace')
    assoc = doc.get('assoc', 'left')
    imp = doc.get('imp')
    lang = doc.get('lang')

    if lang is None:
        raise CompileError("invalid defop")

    assertResult(ruledef, "use in defop")
    assertResult(binding, "use in defop")

    lineno = getattr(doc, "lineno", None)

    # {{{ token = extract from ruledef
    def islit(x): return x[0][0] == 'LiteralRule'

    if islit(ruledef):
        token = ruledef[1]
    elif ruledef[0][0] == 'SequenceRule':
        rules = ruledef[1:]
        if len(rules) > 1 and islit(rules[0]):
            token = rules[0][1]
        elif len(rules) > 1 and islit(rules[1]):
            token = rules[1][1]
        else:
            raise CompileError("invalid ruledef")
    else:
        raise CompileError("invalid ruledef")

    # }}}

    if imp:
        if imp['kind'] == 'm':
            impkind = 'macro'
            
        elif imp['kind'] == 'f':
            impkind = 'func'

        else:
            assert 0, "invalid implementation kind: %s" % imp.kind

        impfuncname = 'operator[%s]' % token

        # {{{ impfunc = 
        argflags, argnames, argdefaults = funcArgs(imp.get('args'))
        impfunc = astFunction(impfuncname,
                              argnames,
                              argdefaults,
                              argflags,
                              None, #docstring
                              ast.Return(block(imp['body'], True)))
        impfunc.lineno = lineno
        # }}}

        impArgs = [ast.Const(impkind), ast.Name(impfuncname)]
    else:
        impArgs = []

    lastdot = lang.rfind('.')
    if lastdot == -1:
        langexpr = GlobalName(lang)
    else:
        assert 0, "PROBE: Why are we adding an op to an imported language?"
        langname = lang[lastdot+1:]
        langmod = lang[:lastdot]
        langexpr = ast.Getattr(ast.Subscript(logixglobal('lmodules'),
                                             'OP_APPLY',
                                             [ast.Const(langmod)]),
                               langname)

    # If unmarshallable objects get into the code-object, you get a
    # blanket error message, so check these before they go in.
    assert isinstance(token, str)
    assert isinstance(smartspace, str) or smartspace == None
    assert isinstance(assoc, str)

    newOpCall = ast.CallFunc(
        ast.Getattr(ast.Getattr(langexpr, '__impl__'), 'newOp'),
        [ast.Const(token),
         topy(binding),
         topy(ruledef),
         ast.Const(smartspace),
         ast.Const(assoc)]
        + impArgs)

    if impArgs != []:
        return ast.Stmt([impfunc, newOpCall])
    else:
        return newOpCall
Example #14
0
def compileDefop(self, binding, ruledef, smartspace=None, assoc='left',
                 imp=None, lang=None):

    if lang is None:
        raise CompileError("invalid defop")

    assertResult(ruledef, "use in defop")
    assertResult(binding, "use in defop")

    lineno = getmeta(self, 'lineno')

    # {{{ token = extract from ruledef
    def islit(x): return x[0][0] == 'LiteralRule'

    if islit(ruledef):
        token = ruledef[1]
    elif ruledef[0][0] == 'SequenceRule':
        rules = ruledef[1:]
        if len(rules) > 1 and islit(rules[0]):
            token = rules[0][1]
        elif len(rules) > 1 and islit(rules[1]):
            token = rules[1][1]
        else:
            raise CompileError("invalid ruledef")
    else:
        raise CompileError("invalid ruledef")
    # }}}

    if imp:
        if imp['kind'] == 'm':
            funcname = 'macro'
            
        elif imp['kind'] == 'f':
            funcname = 'func'

        else:
            assert 0, "invalid implementation kind: %s" % imp.kind

        impfuncname = 'operator[%s]' % token

        # {{{ impfunc = 
        argflags, argnames, argdefaults = funcArgs(imp.get('args'))
        impfunc = astFunction(impfuncname,
                              argnames,
                              argdefaults,
                              argflags,
                              None, #docstring
                              ast.Return(block(imp['body'], True)))
        impfunc.lineno = lineno
        # }}}
    else:
        funcname = None
        impfuncname = "None"
        impfunc = None

    lastdot = lang.rfind('.')
    if lastdot == -1:
        langexpr = GlobalName(lang)
    else:
        assert 0, "PROBE: Why are we adding an op to an imported language?"
        langname = lang[lastdot+1:]
        langmod = lang[:lastdot]
        langexpr = ast.Getattr(ast.Subscript(logixglobal('lmodules'),
                                             'OP_APPLY',
                                             [ast.Const(langmod)]),
                               langname)

    newOpCall = ast.CallFunc(
        ast.Getattr(ast.Getattr(langexpr, '__impl__'), 'newOp'),
        [ast.Const(token),
         topy(binding),
         topy(ruledef),
         ast.Const(smartspace),
         ast.Const(assoc),
         ast.Const(funcname),
         ast.Name(impfuncname)
         ])

    if impfunc:
        return ast.Stmt([impfunc, newOpCall])
    else:
        return newOpCall
Example #15
0
def compileGetlmodule(doc):
    return ast.Subscript(logixglobal("lmodules"),'OP_APPLY',
                         [topy(doc[0])])
Example #16
0
def compilePlace(place, opname='OP_ASSIGN'):
    if isinstance(place, Symbol):
        return ast.AssName(str(place), opname)

    elif isinstance(place, rootops.PyOp):
        token = place.__syntax__.token

        if token == ".":
            # {{{ assign to field
            expr = topy(place[0])
            field = place[1]
            if isinstance(field, Symbol):
                return ast.AssAttr(expr, str(field), opname)
            else:
                raise CompileError("Cannot assign to %s" % place)
            # }}}

        elif token == "__continue__":
            # {{{ assign to slice or subscript
            last = place[1][-1]

            # expr = the continuationOp not including the last part
            if len(place[1]) == 1:
                expr = place[0]
            else:
                expr = basel.getContinuationOp()(place[0], place[1][:-1])
            
            kind = last[-1]
            if kind == 'subscript':
                # {{{ assign to subscript
                assertResult(expr, "subscript")

                keys = last[:-1]
                for key in keys:
                    assertResult(key, "subscript with")

                return ast.Subscript(topy(expr), opname, map(topy, keys))
                # }}}

            elif kind ==  "slice":
                # {{{ assign to slice
                assertResult(expr, "slice")

                start,end,step = last[:-1]
                assertResult(start, "slice from ")
                assertResult(end, "slice to")
                assertResult(step, "slice with step")

                return ast.Subscript(topy(expr), opname,
                                     [ast.Sliceobj(map(topy, (start,end,step)))])
                # }}}
                
            else:
                raise CompileError("Cannot asign to %s " % place)
            # }}}

        elif token == ",":
            return ast.AssTuple([compilePlace(p, opname) for p in list(place)])

        elif token == "[" and place[1] == 'list':
            return ast.AssList([compilePlace(p, opname) for p in place.elems])

        elif token == "(":
            return compilePlace(place[1], opname)

        else:
            raise CompileError("Cannot asign to %s " % place)

    else:
        raise CompileError("Cannot assign to %s" % place)
Example #17
0
def compileSubscript(doc):
    assertResult(doc[0], "subscript")
    for x in doc[1:]:
        assertResult(x, "subscript with")
    return ast.Subscript(topy(doc[0]), 'OP_APPLY', [topy(x) for x in doc[1:]])
Example #18
0
 def BINARY_SUBSCR(decompiler):
     oper2 = decompiler.stack.pop()
     oper1 = decompiler.stack.pop()
     if isinstance(oper2, ast.Tuple): return ast.Subscript(oper1, 'OP_APPLY', list(oper2.nodes))
     else: return ast.Subscript(oper1, 'OP_APPLY', [ oper2 ])
Example #19
0
 def visitSlice(self, node):
     n = ast.Subscript(node.expr, compiler.consts.OP_APPLY, [ast.Sliceobj(node.asList()[2:])])
     self.visit(n)
Example #20
0
 def targetlangexpr():
     return ast.Getattr(ast.Subscript(logixglobal('lmodules'),
                                      'OP_APPLY',
                                      [ast.Const(langmod)]),
                        langname)