Back to index

supertuxkart  0.5+dfsg1
lisp.hpp
Go to the documentation of this file.
00001 //  $Id: lisp.hpp 2111 2008-05-31 07:04:30Z cosmosninja $
00002 //
00003 //  TuxKart - a fun racing game with go-kart
00004 //  Copyright (C) 2004 Matthias Braun <matze@braunis.de>
00005 //  code in this file based on lispreader from Mark Probst
00006 //
00007 //  This program is free software; you can redistribute it and/or
00008 //  modify it under the terms of the GNU General Public License
00009 //  as published by the Free Software Foundation; either version 2
00010 //  of the License, or (at your option) any later version.
00011 //
00012 //  This program is distributed in the hope that it will be useful,
00013 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 //  GNU General Public License for more details.
00016 //
00017 //  You should have received a copy of the GNU General Public License
00018 //  along with this program; if not, write to the Free Software
00019 //  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00020 #ifndef __LISPREADER_H__
00021 #define __LISPREADER_H__
00022 
00023 #include <string>
00024 #include <vector>
00025 #include <plib/sg.h>
00026 
00027 namespace lisp
00028 {
00029 
00030     class Lisp
00031     {
00032     public:
00033         ~Lisp();
00034 
00035         enum LispType
00036         {
00037             TYPE_CONS,
00038             TYPE_SYMBOL,
00039             TYPE_INTEGER,
00040             TYPE_STRING,
00041             TYPE_REAL,
00042             TYPE_BOOLEAN
00043         };
00044 
00045         LispType getType() const
00046             { return m_type; }
00047 
00048         const Lisp* getCar() const
00049             { return m_v.m_cons.m_car; }
00050         const Lisp* getCdr() const
00051             { return m_v.m_cons.m_cdr; }
00052         bool get(std::string& val) const
00053             {
00054                 if(m_type != TYPE_STRING && m_type != TYPE_SYMBOL)
00055                     return false;
00056                 val = m_v.m_string;
00057                 return true;
00058             }
00059         bool get(int& val) const
00060             {
00061                 if(m_type != TYPE_INTEGER)
00062                     return false;
00063                 val = m_v.m_integer;
00064                 return true;
00065             }
00066         bool get(float& val) const
00067             {
00068                 if(m_type != TYPE_REAL && m_type != TYPE_INTEGER)
00069                     return false;
00070                 val = m_type==TYPE_REAL ? m_v.m_real : m_v.m_integer;
00071                 return true;
00072             }
00073         bool get(bool& val) const
00074             {
00075                 if(m_type != TYPE_BOOLEAN)
00076                     return false;
00077                 val = m_v.m_boolean;
00078                 return true;
00079             }
00080 
00081         /* conveniance functions which traverse the list until a child with a
00082          * specified name is found. The value part is then interpreted in a specific
00083          * way. The functions return true, if a child was found and could be
00084          * interpreted correctly, otherwise false is returned and the variable value
00085          * is not changed.
00086          * (Please note that searching the lisp structure is O(n) so these functions
00087          *  are no good idea for performance critical areas)
00088          */
00089         template<class T>
00090         bool get(const char* name, T& val) const
00091             {
00092                 const Lisp* lisp = getLisp(name);
00093                 if(!lisp)
00094                     return false;
00095 
00096                 lisp = lisp->getCdr();
00097                 if(!lisp)
00098                     return false;
00099                 lisp = lisp->getCar();
00100                 if(!lisp)
00101                     return false;
00102                 return lisp->get(val);
00103             }
00104         bool get(const char* name, sgVec4& val) const
00105             {
00106                 const Lisp* lisp = getLisp(name);
00107                 if(!lisp)
00108                     return false;
00109 
00110                 lisp = lisp->getCdr();
00111                 if(!lisp)
00112                     return false;
00113                 for(int i = 0; i < 4 && lisp; ++i)
00114                 {
00115                     const Lisp* m_car = lisp->getCar();
00116                     if(!m_car)
00117                         return false;
00118                     m_car->get(val[i]);
00119                     lisp = lisp->getCdr();
00120                 }
00121                 return true;
00122             }
00123         bool get(const char* name, sgVec3& val) const
00124             {
00125                 const Lisp* lisp = getLisp(name);
00126                 if(!lisp)
00127                     return false;
00128 
00129                 lisp = lisp->getCdr();
00130                 if(!lisp)
00131                     return false;
00132                 for(int i = 0; i < 3 && lisp; ++i)
00133                 {
00134                     const Lisp* m_car = lisp->getCar();
00135                     if(!m_car)
00136                         return false;
00137                     m_car->get(val[i]);
00138                     lisp = lisp->getCdr();
00139                 }
00140                 return true;
00141             }
00142 
00143         template<class T>
00144         bool getVector(const char* name, std::vector<T>& vec) const
00145         {
00146             const Lisp* child = getLisp(name);
00147             if(!child)
00148                 return false;
00149 
00150             for(child = child->getCdr(); child != 0; child = child->getCdr())
00151             {
00152                 T val;
00153                 if(!child->getCar())
00154                     continue;
00155                 if(child->getCar()->get(val))
00156                 {
00157                     vec.insert(vec.begin(),val);
00158                 }
00159             }
00160 
00161             return true;
00162         }
00163 
00164         const Lisp* getLisp(const char* name) const;
00165         const Lisp* getLisp(const std::string& name) const
00166             { return getLisp(name.c_str()); }
00167 
00168         // for debugging
00169         void print(int indent = 0) const;
00170 
00171     private:
00172         friend class Parser;
00173         Lisp(LispType newtype);
00174 
00175         LispType m_type;
00176         union
00177         {
00178             struct
00179             {
00180                 Lisp* m_car;
00181                 Lisp* m_cdr;
00182             }
00183             m_cons;
00184 
00185             char* m_string;
00186             int m_integer;
00187             bool m_boolean;
00188             float m_real;
00189         }
00190         m_v;
00191     };
00192 
00193 } // end of namespace lisp
00194 
00195 #endif
00196