Beispiel #1
0
def quote(obj, depth=1):
    assert depth > 0

    if isDoc(obj, rootops.quote):
        depth += 1

    elif isDoc(obj, rootops.escape):
        escapelevel = 1 + len(obj.get('extra', []))
        if escapelevel > depth:
            raise CompileError("more quote escapes than quotes")
        
        elif escapelevel == depth:
            if obj.hasProperty('splice'):
                raise CompileError("Can't splice here")

            elif obj.hasProperty("localmodule"):
                return topy(localModuleQuote())
            
            else:
                assertResult(obj[0], "insert into quote")
                return topy(obj[0])

    if isinstance(obj, Doc):
        return quotedDoc(obj, depth)

    elif isinstance(obj, Symbol):
        return compileSymbol(obj)

    else:
        return topy(obj)
Beispiel #2
0
def interactiveCompile(expr, env, filename, mode):
    modname = env['__name__']
    if data.isDoc(expr, rootops.setlang):
        newlang = language.tmpLanguage(language.eval(expr, env), modname)
        env['__currentlang__']  = newlang
        env[newlang.__impl__.name] = newlang
        return compile("None", "", "eval")

    if data.isDoc(expr, (rootops.defop, rootops.getops)):
        expr['lang'] = '__currentlang__'
        language.eval(expr, env)
        return compile("None", "", "eval")
    else:
        return logixcompiler.compile([expr], filename, mode, module=modname)
Beispiel #3
0
def interactiveCompile(expr, env, filename, mode):
    modname = env['__name__']
    if data.isDoc(expr, rootops.setlang):
        newlang = language.tmpLanguage(language.eval(expr, env), modname)
        env['__currentlang__'] = newlang
        env[newlang.__impl__.name] = newlang
        return compile("None", "", "eval")

    if data.isDoc(expr, (rootops.defop, rootops.getops)):
        expr['lang'] = '__currentlang__'
        language.eval(expr, env)
        return compile("None", "", "eval")
    else:
        return logixcompiler.compile([expr], filename, mode, module=modname)
Beispiel #4
0
 def assign(self, place, val):
     "="
     if isDoc(val, self.symbol):
         # chained assign (a = b = blah)
         res = topy(val)
         res.nodes.append(compilePlace(place))
         return res
     else:
         assertResult(val, "assign from")
         res = ast.Assign([compilePlace(place)], topy(val))
         if lineno:
             res.lineno = lineno
         return res
Beispiel #5
0
def quotedDoc(doc, depth):
    """
    Generate code to build a Doc like `doc` with quote-escapes
    replaced by runtime values.
    """

    # Each element of contentParts is either:
    #  an AST - meaning a spliced value - the resulting content
    #           should be `extend`ed by that value
    #  a list of ASTs - a list of regular elements, the resulting
    #                   content should be `extend`ed by an ast.List
    #                   with these elements
    # {{{ contentParts = 
    contentParts = [[]]

    for x in doc.content():
        if isDoc(x, rootops.escape):
            escapelevel = 1 + len(x.get('extra', []))
            if escapelevel > depth:
                raise CompileError("more quote escapes than quotes")
            escape = escapelevel == depth
        else:
            escape = False
            
        if escape:
            if x.hasProperty("splice"):
                assertResult(x[0], "insert into quote")
                contentParts.append(topy(x[0]))
                contentParts.append([])
            elif x.hasProperty("localmodule"):
                contentParts[-1].append(topy(localModuleQuote()))
            else:
                assertResult(x[0], "insert into quote")
                contentParts[-1].append(topy(x[0]))
            
        else:
            contentParts[-1].append(quote(x, depth))
    # }}}

    # These properties are added to the result doc *after*
    # any spliced in docs, so they overwrite any spliced properties
    for v in doc.propertyValues():
        assertResult(v, "use as operand")
    properties = ast.Dict([(compileSymbol(n), quote(v, depth))
                           for n, v in doc.properties()])
        
    # assert isinstance(contentParts[0], list)

    if contentParts == [[]]:
        return ast.CallFunc(logixglobal("Doc"),
                            [compileSymbol(doc.tag),
                             properties])
    else:
        if len(contentParts[0]) > 0:
            docArg = ast.List(contentParts[0])
            rest = contentParts[1:]
        elif len(contentParts) > 0:
            docArg = contentParts[1]
            rest = contentParts[2:]
        
        if len(rest) == 0:
            return ast.CallFunc(logixglobal("Doc"),
                                [compileSymbol(doc.tag),
                                 docArg,
                                 properties])
        else:
            val = macros.gensym("val")
            stmts = [ast.Assign([compilePlace(val)],
                                ast.CallFunc(logixglobal("Doc"),
                                             [compileSymbol(doc.tag),
                                              docArg]))]
            for part in rest:
                if isinstance(part, list):
                    if len(part) == 0:
                        continue
                    ext = ast.List(part)
                else:
                    ext = part
                stmts.append(ast.Discard(ast.CallFunc(ast.Getattr(topy(val),
                                                                  "extend"),
                                                      [ext])))
        
            stmts.append(ast.Discard(ast.CallFunc(ast.Getattr(topy(val),
                                                              "extend"),
                                                  [properties])))
            stmts.append(topy(val))
            return ast.Stmt(stmts)
Beispiel #6
0
def compilePlace(place, opname='OP_ASSIGN'):

    # {{{ def compileSubscriptPlace(objx, keyxs):
    def compileSubscriptPlace(objx, keyxs):
         assertResult(objx, "subscript")

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

         return ast.Subscript(topy(objx), opname, map(topy, keyxs))
    # }}}

    # {{{ def compileSlicePlace(objx, fromx, tox, stepx):
    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)))])
    # }}}
    
    if isinstance(place, Symbol):
        if place.namespace != "":
            raise CompileError, "cannot assign to symbol with namespace: %s" % place
        return ast.AssName(place.name, opname)

    elif isDoc(place, rootops.sliceOp):
        return compileSlicePlace(place[0], place[1], place[2], place[3])

    elif isDoc(place, rootops.subscriptOp):
        return compileSubscriptPlace(place[0], place[1:])

    elif isPyOp(place):
        token = place.tag.name

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

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

            # expr = the continuationOp not including the last part
            if len(place) == 2:
                expr = place[0]
            else:
                expr = Doc(Symbol(rootops.base_ns, ""),
                           place[:-1])
            
            kind = last[-1]
            if kind == 'subscript':
                return compileSubscriptPlace(expr, last[:-1])

            elif kind ==  "slice":
                start,end,step = last[:-1]
                return compileSlicePlace(expr, 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])

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

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

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