Exemplo n.º 1
0
def addpairs(plst,x,alst,dLst):
    try:
        if alst.kind==-4:
            return alst
    except:
        a=2
    obj= SExp.SExp(3)
    obj.left=car(plst)
    if x.kind in [1,2]:
        obj.right = x
    else:    
        obj.right=car(x)
    alst=[j for j in alst]
    alst.append(obj)
    if cdr(plst).getString()!='NIL' and cdr(x).getString()!='NIL':
        alst=[j for j in addpairs(cdr(plst),cdr(x),alst,dLst)]
    else:
        if cdr(plst).getString()!='NIL' and cdr(x).getString()=='NIL':
            errorObj = SExp.SExp(-4)
            errorObj.string = 'parameter count less'
            return errorObj
        if cdr(plst).getString()=='NIL' and (x.kind==3 and cdr(x).getString()!='NIL'):
            errorObj = SExp.SExp(-4)
            errorObj.string = 'parameter count more'
            return errorObj     
    return alst
Exemplo n.º 2
0
def evlis (lst, alst,dLst):
    if lst.kind==-4:
        return lst
    if isNull(lst) == 'T':
        return dLst['NIL']
    else:
        return cons(evaluate(car(lst),alst,dLst),evlis(cdr(lst),alst,dLst))
Exemplo n.º 3
0
def evconHelper(be,alst,dLst):
    while(be.getString()!='NIL'):
            lexp,rexpr = evcon(car(be),alst,dLst)
            if lexp == 'T':
                return rexpr
            else:
                be = cdr(be)
                if be.getString() == 'NIL':
                    errorObj = SExp.SExp(-4)
                    errorObj.string = 'Invalid EVCON Expression:Catch all missing'
                    return errorObj       
Exemplo n.º 4
0
def chkParams(lst,buff):
    if lst.kind == -4:
        return lst
    if lst.getString() == 'NIL':
        return 'T'
    obj = car(lst)
   
    if(obj.getString() not in buff and not isPrimitive(obj.getString())):
        buff.append(obj.getString())
        return chkParams(cdr(lst), buff)
    else:
        return -4
Exemplo n.º 5
0
def evcon(be,alst,dLst):
    
    if be.kind == -4:
        print be.getValidString()
    if isNull(be) == 'T':
        print dLst['NIL'].getValidString()
    else:
        lExp = evaluate(car(be),alst,dLst).getString()
        
        if lExp not in ['T','NIL']:
            errorObj = SExp.SExp(-4)
            errorObj.string = 'Invalid EVCON Expression'
            return lExp,errorObj
        if lExp == 'T':
            if cdr(cdr(be)).getString()!='NIL':
                errorObj = SExp.SExp(-4)
                errorObj.string = 'Invalid EVCON Expression:more than one expression to eval'
                return lExp,errorObj    
            rExp = evaluate(car(cdr(be)),alst,dLst)
            return lExp,rExp
        else:    
            return lExp,''
Exemplo n.º 6
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 
Exemplo n.º 7
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