Пример #1
0
def apply_function(f,x,alst,dLst):
    if x.kind==3 and (x.left.getString()=='NIL' and x.right.getString()=='NIL'):
        x=dLst['NIL'] 
    if f.kind==-4:
        return f
    if x.kind == -4:
        return x
    if atom(f) == 'T' :
        if eq(f,dLst['CAR']) == 'T' :
            return car(car(x))
        elif eq(f,dLst['CDR']) == 'T' :
            return cdr(car(x))
        elif eq(f,dLst['CONS']) == 'T' :
            if(cdr(cdr(x)).getString()!='NIL'):
                errorObj = SExp.SExp(-4)
                errorObj.string = 'CONS takes only two atomic arguments'
                return errorObj
            return cons(car(x),car(cdr(x)))
        elif eq(f,dLst['ATOM']) == 'T' :
            if(cdr(x).getString()=='NIL'):
                return dLst[atom(car(x))]
            return dLst[atom(x)]
        elif eq(f,dLst['INT']) == 'T' :
            if(cdr(x).getString()=='NIL'):
                return dLst[isInt(car(x))]
            return dLst[atom(x)]
        elif eq(f,dLst['NULL']) == 'T' :
            return dLst[isNull(x)]
        elif eq(f,dLst['PLUS']) == 'T' :
            if(cdr(cdr(x)).getString()!='NIL' or car(x).kind!=1 or car(cdr(x)).kind!=1):
                errorObj = SExp.SExp(-4)
                errorObj.string = 'PLUS takes only two integer arguments'
                return errorObj
            obj=plus(car(x),car(cdr(x)))
            if(obj.kind==-4):
                return obj
            if(obj.value not in dLst.keys()):
                dLst[obj.value]=obj
                setDict(dLst)
            return obj
        
        elif eq(f,dLst['MINUS']) == 'T' :
            if(cdr(cdr(x)).getString()!='NIL' or car(x).kind!=1 or car(cdr(x)).kind!=1):
                errorObj = SExp.SExp(-4)
                errorObj.string = 'MINUS takes only two integer arguments'
                return errorObj
            obj=minus(car(x),car(cdr(x)))
            if(obj.value not in dLst.keys()):
                dLst[obj.value]=obj
                setDict(dLst)
            return obj
        elif eq(f,dLst['TIMES']) == 'T' :
            if(cdr(cdr(x)).getString()!='NIL' or car(x).kind!=1 or car(cdr(x)).kind!=1):
                errorObj = SExp.SExp(-4)
                errorObj.string = 'TIMES takes only two integer arguments'
                return errorObj
            obj=times(car(x),car(cdr(x)))
            if(obj.value not in dLst.keys()):
                dLst[obj.value]=obj
                setDict(dLst)
            return obj
        elif eq(f,dLst['QUOTIENT']) == 'T' :
            if(cdr(cdr(x)).getString()!='NIL' or car(x).kind!=1 or car(cdr(x)).kind!=1):
                errorObj = SExp.SExp(-4)
                errorObj.string = 'QUOTIENT takes only two integer arguments'
                return errorObj
            obj=divide(car(x),car(cdr(x)))
            if(obj.value not in dLst.keys()):
                dLst[obj.value]=obj
                setDict(dLst)
            return obj
        elif eq(f,dLst['REMAINDER']) == 'T' :
            if(cdr(cdr(x)).getString()!='NIL' or car(x).kind!=1 or car(cdr(x)).kind!=1):
                errorObj = SExp.SExp(-4)
                errorObj.string = 'REMAINDER takes only two integer arguments'
                return errorObj
            obj=mod(car(x),car(cdr(x)))
            if(obj.value not in dLst.keys()):
                dLst[obj.value]=obj
                setDict(dLst)
            return obj
        elif eq(f,dLst['LESS']) == 'T' :
            if(cdr(cdr(x)).getString()!='NIL' or car(x).kind!=1 or car(cdr(x)).kind!=1):
                errorObj = SExp.SExp(-4)
                errorObj.string = 'LESS takes only two integer arguments'
                return errorObj
            return dLst[lt(car(x),car(cdr(x)))]
        elif eq(f,dLst['GREATER']) == 'T' :
            if(cdr(cdr(x)).getString()!='NIL' or car(x).kind!=1 or car(cdr(x)).kind!=1):
                errorObj = SExp.SExp(-4)
                errorObj.string = 'GREATER takes only two integer arguments'
                return errorObj
            return dLst[gt(car(x),car(cdr(x)))]
        elif eq(f,dLst['EQ']) == 'T' :
            if(cdr(cdr(x)).getString()!='NIL'):
                errorObj = SExp.SExp(-4)
                errorObj.string = 'EQ takes only two atomic arguments'
                return errorObj
            res=eq(car(x),car(cdr(x))) 
            if res == 'T' or res=='NIL':
                return dLst[res]
            else:
                return res
        else:
            try:
                tlst = getDefLst()
                if f.getString() not in tlst.keys():
                    errorObj = SExp.SExp(-4)
                    errorObj.string = 'Undefined function:'+f.getString()
                    return errorObj
                fundef = tlst[f.getString()]
                setDefun(True)
                return evaluate(car(cdr(fundef)),addpairs(car(fundef),x,alst,dLst),dLst)
            except:
                errorObj = SExp.SExp(-4)
                errorObj.string = 'Improper input for function or function execution did not complete'
                return errorObj 
Пример #2
0
def evaluate(exp, alst,dLst):
    if(exp.kind==-4):
        return exp
    if atom(exp) == 'T':
        if isInt(exp) == 'T':
            return exp
        elif eq(exp,dLst['T']) == 'T':
            return dLst['T']
        elif eq(exp,dLst['NIL']) == 'T':
            return dLst['NIL']
        elif getMapping(exp.getString(),alst,False).kind!=-4:
            return getMapping(exp.getString(),alst,True)
        else:
            errorObj = SExp.SExp(-4)
            errorObj.string = 'Unbound Variable'
            return errorObj  
    elif atom(car(exp))=='T':
        if eq(car(exp),dLst['QUOTE']) == 'T':
            if cdr(exp).right.getString() == 'NIL':
                return car(cdr(exp))
            else:
                errorObj = SExp.SExp(-4)
                errorObj.string = 'Too Many Args for QUOTE'
                return errorObj
        elif eq(car(exp),dLst['COND']) == 'T':
            return evconHelper(cdr(exp),alst,dLst)
        elif eq(car(exp),dLst['DEFUN']) == 'T':
            key = car(cdr(exp))
            if cdr(cdr(cdr(cdr(exp)))).getString()!='NIL':
                errorObj = SExp.SExp(-4)
                errorObj.string = 'Invalid Defun syntax'
                return errorObj
            if isPrimitive(key.getString()) :
                errorObj = SExp.SExp(-4)
                errorObj.string = 'Cannot replace primitives'
                return errorObj
                
            temp = cdr(exp)
            val=cdr(temp)
            res = chkParams(car(val),[])
            if res == 'T':
                tlst =  getDefLst()
                splt = val.getString().replace('(', ' ( ').replace(')',' ) ').replace('.',' . ').split()
                if 'DEFUN' in splt:
                    errorObj = SExp.SExp(-4)
                    errorObj.string = 'Cannot Define function inside a UDF'
                    return errorObj
                tlst[key.getString()]=val
                setDefLst(tlst)
                return key
            else:
                if res == -4:
                    errorObj = SExp.SExp(-4)
                    errorObj.string = 'Parameter Names Should Be Unique and non primitives'
                    return errorObj
                return res           
            
        else:
            return apply_function(car(exp),evlis(cdr(exp),alst,dLst),alst,dLst)    
    else:
        errorObj = SExp.SExp(-4)
        errorObj.string = 'Invalid Eval Expression'
        return errorObj