      - Parameter environment: A set of named functions or the default environment
      - Returns: the resulting SExpression after evaluation
      */
-    public func eval() -> SExpr?{
+    public func eval(with locals: [SExpr]? = nil, for values: [SExpr]? = nil) -> SExpr?{
         var node = self
         
         switch node {
         case .Atom:
-            return node
+            return evaluateVariable(node, with:locals, for:values)
         case var .List(elements):
             var skip = false
             

        
        let lambda = parameters[3]
        
        let f: (SExpr)->SExpr = { params in
            guard case var .List(p) = params else {return .List([])}
            p = Array(p.dropFirst(1))
            
            // Replace parameters in the lambda with values
            if let result = lambda.replace(this:vars, with:p).eval(){
                return result
            }else{
                return .List([])

        }
    }
    
    private func evaluateVariable(_ v: SExpr, with locals: [SExpr]?, for values: [SExpr]?) -> SExpr {
        guard let locals = locals, let values = values else {return v}
        
        if locals.contains(v) {
            return values[locals.index(of: v)!]
        }else{
            return v
        }
    }
    
