Beispiel #1
0
def const(expr):
    if type(expr) == tuple:
        expr = expr[0]
    if literable(expr):
        return (True, expr)
    if type(expr) == list and expr and type(expr[0]) == S:
        if expr[0] in const.knownFuncs:
            args = []
            for arg in expr[1:]:
                (argConstP, argValue) = const(arg)
                if not argConstP:
                    return (False, None)
                args.append(argValue)
            try:
                return (True, const.knownFuncs[arg[0]](*args))
            except Exception:
                return (False, None)
        if expr[0] is S("quote"):
            assert len(expr) == 2
            return (True, expr[1])
    return (False, None)
Beispiel #2
0
    def __call__(self,parsedExpr,scope,globalDict,localDict,*,asFunc=False):
        try:
            (expr,line)=parsedExpr
        except ValueError as ve:
            print(ve,parsedExpr)
            raise
        if type(expr)==list and expr:
            if type(expr[0][0])==S:
                (f,_,_)=self(expr[0],scope,globalDict,localDict,asFunc=True)
                if isinstance(f,S):
                    required=scope.requiredScope(f)
                    if required is Scope.root:
                        m=self.methodFor(f)
                        if hasattr(self,m):
                            return getattr(self,m)(expr,line,scope,
                                                   globalDict,localDict)
                    if required[f].macroExpander:
                        xArgs=stripLines((expr[1:],expr[1][1]))
                        xCall=[required[f].macroExpander]+list(map(q,xArgs))
                        expanded=adder.runtime.eval(xCall,scope,
                                                    globalDict,localDict)
                        return self(addLines(expanded,line),
                                    scope,globalDict,localDict)
            scoped=[self(expr[0],scope,globalDict,localDict,asFunc=True)]
            for e in expr[1:]:
                scoped.append(self(e,scope,globalDict,localDict))
            return (scoped,line,scope)
        if type(expr)==S:
            if expr.isKeyword():
                return (expr,line,Scope.root)
            else:
                symbolName=str(expr)
                if symbolName=='current-scope':
                    adder.runtime.getScopeById.scopes[scope.id]=scope
                    return self(([(S('getScopeById'),line),
                                  (scope.id,line)],line),scope,
                                globalDict,localDict)

                if ((symbolName!='.')
                    and ('.' in symbolName)
                    and not (asFunc and scope.isMacro(expr))
                    ):
                    op='..' if symbolName[0]=='.' else '.'
                    expanded=[op]+list(filter(None,symbolName.split('.')))
                    expanded=list(map(lambda s: (S(s),line),expanded))
                    return self((expanded,line),
                                scope,globalDict,localDict,asFunc=asFunc)

                required=scope.requiredScope(expr)

                exprPy=expr.toPython()
                if (required is Scope.root
                    and exprPy in globalDict
                    and literable(globalDict[exprPy])):
                    return (globalDict[exprPy],line,required)
                if (required is scope
                    and exprPy in localDict
                    and literable(localDict[exprPy])):
                    return (localDict[exprPy],line,required)

                entry=required[expr]

                if entry.isBuiltinFunc and not asFunc:
                    return self(self.wrapForApply(expr,line,scope,entry),
                                scope,globalDict,localDict)

                if (entry.asConst
                    and entry.constValueValid
                    and (type(entry.constValue)==int
                         or type(entry.constValue)==float
                         or type(entry.constValue)==str
                         or type(entry.constValue)==bool
                         )
                    ):
                    expr=entry.constValue
                return (expr,line,required)
        return (expr,line,scope)
Beispiel #3
0
def stripLines(parsedExpr):
    (expr,line)=parsedExpr
    if literable(expr) or type(expr)==S:
        return expr
    #assert type(expr)==list
    return list(map(stripLines,expr))
Beispiel #4
0
def addLines(expr,defLine):
    if literable(expr) or type(expr)==S:
        return (expr,defLine)
    #assert type(expr)==list
    return (list(map(lambda e: addLines(e,defLine),expr)),defLine)
Beispiel #5
0
def build(pyle):
    #collapseCallScratches(pyle)
    def buildPair(varAndVal):
        (var,val)=varAndVal
        return (build(var),build(val))
    if isinstance(pyle,S):
        return Var(pyle)
    if not isinstance(pyle,list):
        assert(literable(pyle))
        return Literal(pyle)
    assert pyle
    f=pyle[0]
    if f is S(':='):
        assert len(pyle)==3
        return Assign(build(pyle[1]),build(pyle[2]))
    if f is S('return'):
        assert len(pyle) in [1,2]
        if len(pyle)==1:
            return Return()
        else:
            return Return(build(pyle[1]))
    if f is S('yield'):
        assert len(pyle)==2
        return Yield(build(pyle[1]))
    if f is S('mk-list'):
        return MkList(list(map(build,pyle[1:])))
    if f is S('mk-tuple'):
        return MkTuple(list(map(build,pyle[1:])))
    if f is S('mk-set'):
        return MkSet(list(map(build,pyle[1:])))
    if f is S('mk-dict'):
        return MkDict(list(map(buildPair,pyle[1:])))
    if f is S('try'):
        klassClauses=[]
        finallyClause=None
        assert len(pyle)>=2
        sawFinally=False
        finallyBody=None
        for clause in pyle[2:]:
            assert not sawFinally
            assert len(clause) in [2,3]
            if len(clause)==2:
                assert clause[0] is S(':finally')
                sawFinally=True
                finallyBody=build(clause[1])
            else:
                assert isinstance(clause[0],S)
                assert isinstance(clause[1],S)
                assert str(clause[0])[0]==':'
                klassClauses.append((Var(S(str(clause[0])[1:])),
                                     Var(clause[1]),
                                     build(clause[2])))
        return Try(build(pyle[1]),klassClauses,finallyBody)
    if f is S('raise'):
        assert len(pyle)==2
        return Raise(build(pyle[1]))
    if f is S('reraise'):
        assert len(pyle)==1
        return Reraise()
    if f is S('binop'):
        assert len(pyle)==4
        return Binop(build(pyle[1]),
                     build(pyle[2]),
                     build(pyle[3]))
    if f is S('quote'):
        assert len(pyle)==2
        def q(r):
            if isinstance(r,list):
                return List(list(map(q,r)))
            else:
                return Literal(r)
        return Quote(q(pyle[1]))
    if f is S('if'):
        assert len(pyle) in [3,4]
        cond=build(pyle[1])
        thenClause=build(pyle[2])
        elseClause=build(pyle[3]) if len(pyle)==4 else None
        return If(cond,thenClause,elseClause)
    if f is S('while'):
        assert len(pyle)==3
        cond=build(pyle[1])
        body=build(pyle[2])
        return While(cond,body)
    if f is S('def'):
        assert len(pyle)==4
        name=build(pyle[1])
        body=build(pyle[3])

        posArgs=[]
        nonlocals=[]
        optionalArgs=[]
        kwArgs=[]
        restArgs=[]
        globals=[]

        states={'&optional': optionalArgs,
                '&key': kwArgs,
                '&rest': restArgs,
                '&global': globals,
                '&nonlocal': nonlocals}
        cur=posArgs
        for arg in pyle[2]:
            isS=isinstance(arg,S)
            assert isS or (cur is optionalArgs
                           and isinstance(arg,list)
                           and len(arg)==2
                           and isinstance(arg[0],S))
            if isS and arg[0]=='&':
                cur=states[str(arg)]
            else:
                if cur is optionalArgs:
                    if isinstance(arg,list):
                        (arg,default)=arg
                    else:
                        default=None
                    cur.append((build(arg),build(default)))
                else:
                    cur.append(build(arg))

        return Def(name,posArgs,optionalArgs,kwArgs,restArgs,
                   globals,nonlocals,body)
    if f is S('class'):
        assert len(pyle)>=3
        name=build(pyle[1])
        bases=list(map(build,pyle[2]))
        body=list(map(build,pyle[3:]))

        return Class(name,bases,body)
    if f is S('break'):
        assert len(pyle)==1
        return Break()
    if f is S('continue'):
        assert len(pyle)==1
        return Continue()
    if f is S('pass'):
        assert len(pyle)==1
        return Pass()
    if f is S('nop'):
        return Pass()
    if f is S('begin'):
        return Begin(list(map(build,pyle[1:])))
    if f is S('import'):
        assert len(pyle)==2
        return Import(build(pyle[1]))
    if f is S('import'):
        assert len(pyle)==2
        return Import(build(pyle[1]))
    if f is S('.'):
        assert len(pyle)>2
        return Dot(build(pyle[1]),
                   list(map(build,pyle[2:])))
    if f is S('[]'):
        assert len(pyle)==3
        return Subscript(build(pyle[1]),build(pyle[2]))

    if f is S('slice'):
        assert len(pyle)==4
        return Slice(build(pyle[1]),build(pyle[2]),build(pyle[3]))

    if f is S('call'):
        assert len(pyle)==4

        if isinstance(pyle[2],list):
            posArgs=list(map(build,pyle[2]))
        else:
            posArgs=build(pyle[2])

        if isinstance(pyle[3],list):
            kwArgs=list(map(buildPair,pyle[3]))
        else:
            kwArgs=build(pyle[3])

        return Call(build(pyle[1]),posArgs,kwArgs)

    print(pyle)
    pdb.set_trace()
    assert False