Ejemplo n.º 1
0
def topy(obj):
    """The main compiler function - convert a source object to an ast node"""

    # {{{ ln = line number from metadata (also set global \lineno)
    ln = getmeta(obj, 'lineno')
    if ln:
        global lineno
        lineno = ln
    # }}}

    customcompile = getattr(obj, 'pycompile', None)
    if customcompile:
        node = customcompile(*opargs(obj), **opfields(obj))

    elif isinstance(type(obj), OperatorType):
        node = compileOperator(obj)
    else:
        typ = type(obj).__name__
        method = (getattr(objtopy, typ, None) or
                  getattr(objtopy, "_" + typ, None))
        compilefunc = method and method.im_func

        if compilefunc:
            node = compilefunc(obj)
        else:
            raise CompileError("Cannot compile %s (of type %s)" % (obj, typ))

    if ln:
        node.lineno = ln

    return node
Ejemplo n.º 2
0
def compileDeflang(self, name, parentx, body):
    assert isinstance(name, Symbol)

    if parentx:
        assertResult(parentx, "derive language from")
        parent = topy(parentx)
    else:
        parent = logixglobal('langlang')

    funcname = "#lang:%s" % name

    body = len(body) > 0 and block(body, False).nodes or []

    funcbody = ast.Stmt(
        body
        + [ast.CallFunc(ast.Getattr(ast.Getattr(ast.Name(str(name)),
                                                '__impl__'),
                                    'addDeflangLocals'),
                        [ast.CallFunc(ast.Name('locals'), [])])])
    
    res = ast.Stmt([
        ast.Assign([compilePlace(Symbol(name))],
                   ast.CallFunc(logixglobal('defLanguage'),
                                [ast.Const(str(name)),
                                 parent,
                                 ast.CallFunc(GlobalName("globals"), [])])),
        astFunction(funcname, tuple(), tuple(), 0, None, funcbody),
        ast.CallFunc(ast.Name(funcname), []),
        ast.AssName(funcname, 'OP_DELETE')])
    
    lineno = getmeta(self, 'lineno')
    for n in res.nodes:
        n.lineno = lineno
    res.lineno = lineno
    return res
Ejemplo n.º 3
0
 def stm(x):
     if hasResult(x):
         dis = ast.Discard(topy(x))
         dis.lineno = getmeta(x, 'lineno')
         return dis
     else:
         return topy(x)
Ejemplo n.º 4
0
def block(lst, withResult, prepend=None):
    if len(lst) == 0:
        if withResult:
            return ast.Const(None)
        else:
            return ast.Pass()

    def stm(x):
        if hasResult(x):
            dis = ast.Discard(topy(x))
            dis.lineno = getmeta(x, 'lineno')
            return dis
        else:
            return topy(x)

    if withResult:
        stms = [stm(s) for s in lst[:-1]]
        last = lst[-1]
        lastpy = topy(last)

        if hasResult(last):
            # Insert a pass so pycodegen emits a SET_LINENO
            p = ast.Pass()
            p.lineno = getmeta(last, 'lineno')
        
            statements = stms + [p, lastpy]
        else:
            statements = stms + [lastpy, ast.Const(None)]
    else:
        statements = [stm(s) for s in lst]

    if prepend:
        return ast.Stmt(prepend + statements)
    else:
        return ast.Stmt(statements)
Ejemplo n.º 5
0
def compileSetlang(self, langx, temp=False):
    assertResult(langx, "set language to")
    if temp:
        # a top-level setlang - set to a temporary language
        res = ast.CallFunc(logixglobal('tmpLanguage'),
                           [topy(langx), GlobalName('__name__'),
                            ast.CallFunc(GlobalName("globals"), [], None, None)])
    else:
        res = topy(langx)
    res.lineno = getmeta(self, 'lineno')
    return res
Ejemplo n.º 6
0
    def _if(self, test, body, elifs=None, _else=None):
        assertResult(test, "use as if test")

        if elifs:
            for el in elifs:
                assertResult(el['test'], "use as elif test")
            tests = [(test, body)] + [(el['test'], el['body']) for el in elifs]
        else:
            tests = [(test, body)]

        pytests = []
        for t,b in tests:
            pyt = topy(t)
            pyt.lineno = getmeta(t, 'lineno')
            pytests.append( (pyt, block(b, True)) )

        # HACK: For line numbers. Workaround for a test with no metadata
        # (e.g. just a symbol), but this doesn't work for elifs
        if pytests[0][0].lineno is None:
            pytests[0][0].lineno =  getmeta(self, 'lineno')

        if _else: _else = block(_else, True)

        return ast.If(pytests, _else or ast.Const(None))
Ejemplo n.º 7
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
Ejemplo n.º 8
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