Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members

value.cpp

Go to the documentation of this file.
00001 // value.cpp
00002 //
00003 // Copyright (C) 2002, Chris Laurel <claurel@shatters.net>
00004 //
00005 // This program is free software; you can redistribute it and/or
00006 // modify it under the terms of the GNU General Public License
00007 // as published by the Free Software Foundation; either version 2
00008 // of the License, or (at your option) any later version.
00009 
00010 #include <cassert>
00011 #include <cstdio>
00012 #include <celscript/value.h>
00013 #include <celscript/function.h>
00014 
00015 using namespace std;
00016 using namespace celx;
00017 
00018 
00019 Value::Value() :
00020     type(NilType)
00021 {
00022 }
00023 
00024 
00025 Value::~Value()
00026 {
00027     if (type == StringType)
00028     {
00029         delete val.strVal;
00030     }
00031     else if (type == FunctionType)
00032     {
00033         delete val.funcVal;
00034     }
00035 }
00036 
00037 
00038 Value::Value(double x) :
00039     type(NumberType)
00040 {
00041     val.numVal = x;
00042 }
00043 
00044 
00045 Value::Value(const string& x) :
00046     type(StringType)
00047 {
00048     val.strVal = new string(x);
00049 }
00050 
00051 
00052 Value::Value(bool x) :
00053     type(BooleanType)
00054 {
00055     val.boolVal = x;
00056 }
00057 
00058 
00059 Value::Value(Function* f) :
00060     type(FunctionType)
00061 {
00062     val.funcVal = new Function(*f);
00063 }
00064 
00065 
00066 // Copy constructor
00067 Value::Value(const Value& v) :
00068     type(NilType)
00069 {
00070     *this = v;
00071 }
00072 
00073 
00074 Value& Value::operator=(const Value& v)
00075 {
00076     if (this != &v)
00077     {
00078         // Clean up the current contents first
00079         switch (type)
00080         {
00081         case StringType:
00082             delete val.strVal;
00083             break;
00084         case FunctionType:
00085             delete val.funcVal;
00086             break;
00087         default:
00088             break;
00089         }
00090 
00091         type = v.type;
00092         switch (type)
00093         {
00094         case NumberType:
00095             val.numVal = v.val.numVal;
00096             break;
00097         case StringType:
00098             val.strVal = new string(*v.val.strVal);
00099             break;
00100         case BooleanType:
00101             val.boolVal = v.val.boolVal;
00102             break;
00103         case NilType:
00104             break;
00105         case FunctionType:
00106             val.funcVal = new Function(*v.val.funcVal);
00107             break;
00108         default:
00109             assert(0);
00110             break;
00111         }
00112     }
00113 
00114     return *this;
00115 }
00116 
00117 
00118 bool Value::operator==(const Value& v) const
00119 {
00120     if (v.type != type)
00121         return false;
00122 
00123     switch (type)
00124     {
00125     case BooleanType:
00126         return v.val.boolVal == val.boolVal;
00127     case NumberType:
00128         return v.val.numVal == val.numVal;
00129     case StringType:
00130         return *v.val.strVal == *val.strVal;
00131     case FunctionType:
00132         return v.val.funcVal == val.funcVal;
00133     case NilType:
00134         return true;
00135     default:
00136         return false;
00137     }
00138 }
00139 
00140 
00141 bool Value::operator!=(const Value& v) const
00142 {
00143     return !(*this == v);
00144 }
00145 
00146 
00147 bool Value::toBoolean() const
00148 {
00149     switch (type)
00150     {
00151     case BooleanType:
00152         return val.boolVal;
00153     case NumberType:
00154         return val.numVal != 0.0;
00155     case StringType:
00156         return !val.strVal->empty();
00157     default:
00158         return false;
00159     }
00160 }
00161 
00162 
00163 double Value::toNumber() const
00164 {
00165     switch (type)
00166     {
00167     case BooleanType:
00168         return val.boolVal ? 1.0 : 0.0;
00169     case NumberType:
00170         return val.numVal;
00171     case StringType:
00172         return 0.0; // TODO: attempt conversion to number
00173     default:
00174         return 0.0;
00175     }
00176 }
00177 
00178 
00179 string Value::toString() const
00180 {
00181     switch (type)
00182     {
00183     case BooleanType:
00184         if (val.boolVal)
00185             return string("true");
00186         else
00187             return string("false");
00188     case NumberType:
00189         {
00190             char buf[256];
00191             sprintf(buf, "%f", val.numVal);
00192             return string(buf);
00193         }
00194 
00195     case StringType:
00196         return *val.strVal;
00197 
00198     case NilType:
00199         return string("null");
00200 
00201     default:
00202         return string("");
00203     }
00204 }
00205 
00206 
00207 void Value::output(ostream& out) const
00208 {
00209     switch (type)
00210     {
00211     case NilType:
00212         out << "null";
00213         break;
00214     case BooleanType:
00215         if (val.boolVal)
00216             out << "true";
00217         else
00218             out << "false";
00219         break;
00220     case NumberType:
00221         out << val.numVal;
00222         break;
00223     case StringType:
00224         out << '"' << *val.strVal << '"';
00225         break;
00226     case FunctionType:
00227         out << "[function]";
00228         break;
00229     default:
00230         out << "#unknown";
00231         break;
00232     }
00233 }
00234 
00235 
00236 ostream& operator<<(ostream& out, const celx::Value& v)
00237 {
00238     v.output(out);
00239     return out;
00240 }

Generated on Sat Jan 14 22:30:32 2006 for Celestia by  doxygen 1.4.1