source: cpp/gdk/extvalue.cpp @ 57

Last change on this file since 57 was 5, checked in by sz, 16 years ago

added the GDK (Genotype Development Kit)

File size: 5.3 KB
RevLine 
[5]1// This file is a part of Framsticks GDK library.
2// Copyright (C) 2002-2006  Szymon Ulatowski.  See LICENSE.txt for details.
3// Refer to http://www.frams.alife.pl/ for further information.
4
5#include "extvalue.h"
6#include "param.h"
7#include <math.h>
8
9SString ExtObject::toString()
10{
11if (isEmpty()) return SString("<empty object>");
12ParamInterface *p=getParamInterface();
13int tostr=p->findId("toString");
14if (tostr>=0)
15        {
16        return SString(p->getString(tostr));
17        }
18else
19        {
20        SString tmp("<");
21        tmp+=p->getName();
22        sprintf(tmp.directAppend(30)," object at %p>",object);
23        tmp.endAppend();
24        return tmp;
25        }
26}
27
28///////////////////////////////////////
29
30void ExtValue::set(const ExtValue& src)
31{
32switch(src.type)
33        {
34        case TString: sets(src.sdata()); break;
35        case TInt: seti(src.idata()); break;
36        case TDouble: setd(src.ddata()); break;
37        case TObj: seto(src.odata()); break;
38        }
39}
40
41void ExtValue::setEmpty()
42{
43switch(type)
44        {
45#ifdef EXTVALUEUNION
46        case TString: sdata().~SString(); break;
47        case TObj: odata().~ExtObject(); break;
48#else
49        case TString: delete s; break;
50        case TObj: delete o; break;
51#endif
52        }
53type=TUnknown;
54}
55
56static long longsign(long x)
57{
58if (x<0) return -1;
59if (x>0) return 1;
60return 0;
61}
62
63long ExtValue::compare(const ExtValue& src) const
64{
65if (type==TUnknown)
66        {
67        if (src.type==TDouble)
68                return (src.getDouble()!=0.0);
69        if (src.type==TString)
70                return 1;
71        return src.getInt()?1:0;
72        }
73else if (src.type==TUnknown)
74        {
75        if (type==TDouble)
76                return (getDouble()!=0.0);
77        if (type==TString)
78                return 1;
79        return getInt()?1:0;
80        }
81switch(type)
82        {
83        case TInt:
84        {
85        long t=src.getInt();
86        if (idata()>0)
87                {if (t>0) return longsign(idata()-t); else return +1;}
88        else
89                {if (t<=0) return longsign(idata()-t); else return -1;}
90        }
91        case TDouble:
92                {
93                double t=ddata()-src.getDouble();
94                if (t<0) return -1;
95                else if (t>0) return 1;
96                return 0;
97                }
98        case TString:
99        {
100        SString t=src.getString();
101        SString& t2=sdata();
102        const char* s1=(const char*)t2;
103        const char* s2=(const char*)t;
104        return longsign(strcmp(s1,s2));
105        }
106        case TObj:
107        {
108        if (src.type==TObj)
109                return !(odata()==src.odata());
110        return 1;
111        }
112        }
113return 1;
114}
115
116int ExtValue::operator==(const ExtValue& src) const
117{
118if (type!=src.type) return 0;
119switch(type)
120        {
121        case TInt: return idata()==src.idata();
122        case TDouble: return ddata()==src.ddata();
123        case TString: return sdata()==src.sdata();
124        case TObj: return odata()==src.odata();
125        }
126return 1;
127}
128
129void ExtValue::operator+=(const ExtValue& src)
130{
131switch(type)
132        {
133        case TInt: idata()+=src.getInt(); break;
134        case TDouble: ddata()+=src.getDouble(); break;
135        case TString: sdata()+=src.getString(); break;
136        }
137}
138
139void ExtValue::operator-=(const ExtValue& src)
140{
141switch(type)
142        {
143        case TInt: idata()-=src.getInt(); break;
144        case TDouble: ddata()-=src.getDouble(); break;
145        }
146}
147
148void ExtValue::operator*=(const ExtValue& src)
149{
150switch(type)
151        {
152        case TInt: idata()*=src.getInt(); break;
153        case TDouble: ddata()*=src.getDouble(); break;
154        }
155}
156
157#include "framsg.h"
158/*#include "fpu_control.h"
159#include <signal.h>
160
161static int fpuexception;
162void mathhandler(int sig)
163{
164printf("fpu exception!\n");
165fpuexception=1;
166signal(SIGFPE,SIG_IGN);
167} */
168
169void ExtValue::operator/=(const ExtValue& src)
170{
171switch(type)
172        {
173        case TInt:
174        { int a=src.getInt();
175//              idata()/=src.getInt();
176        if (a) idata()/=a;
177        else FMprintf("ExtValue","divide",FMLV_ERROR,"%s/0",(const char*)getString());
178        }
179                break;
180
181        case TDouble:
182// ugly ;-(
183#ifdef FPU_THROWS_EXCEPTIONS
184                try
185                        {
186                        ddata()/=src.getDouble();
187                        }
188                catch(...)
189                        {
190                        FMprintf("ExtValue","divide",FMLV_ERROR,"%s/0.0",(const char*)getString());
191                        }
192#else
193                {
194                double d=ddata();
195                d/=src.getDouble();
196                if (finite(d))
197                        ddata()=d;
198                else
199                        FMprintf("ExtValue","divide",FMLV_ERROR,"%s/0.0",(const char*)getString());
200                }
201#endif
202                break;
203        }
204}
205
206void ExtValue::operator%=(const ExtValue& src)
207{
208switch(type)
209        {
210        case TInt: idata()=idata()%src.getInt(); break;
211        case TDouble: ddata()=fmod(ddata(),src.getDouble()); break;
212        }
213}
214
215long ExtValue::getInt() const
216{
217switch(type)
218        {
219        case TInt: return idata();
220        case TDouble: return (int)ddata();
221        case TString:
222        {
223        const char* s=(const char*)sdata();
224        if ((s[0]=='0')&&(s[1]=='x'))
225                {
226                long val;
227                sscanf(s+2,"%lx",&val);
228                return val;
229                }
230        else
231                {
232                if (strchr(s,'e')||(strchr(s,'E')))
233                        return atof(s);
234                else
235                        return atol(s);
236                }
237        }
238        case TObj: return (long)odata().param;
239        }
240return 0;
241}
242double ExtValue::getDouble() const
243{
244switch(type)
245        {
246        case TDouble: return ddata();
247        case TInt: return (double)idata();
248        case TString:
249        {
250        const char* s=(const char*)sdata();
251        if ((s[0]=='0')&&(s[1]=='x'))
252                {
253                long val;
254                sscanf(s+2,"%lx",&val);
255                return val;
256                }
257        else
258                return atof(s);
259        }
260        case TObj: return (double)(long)odata().param;
261        }
262return 0.0;
263}
264SString ExtValue::getString() const
265{
266switch(type)
267        {
268        case TString: return sdata();
269        case TInt:
270                {
271                SString tmp;
272                sprintf(tmp.directAppend(20),"%d",idata());
273                tmp.endAppend();
274                return tmp;
275                }
276        case TDouble:
277                {
278                SString tmp;
279                sprintf(tmp.directAppend(20),"%g",ddata());
280                tmp.endAppend();
281                if ((!strchr(tmp,'.'))&&(!strchr(tmp,'e'))) tmp+=".0";
282                return tmp;
283                }
284        case TObj:
285                return odata().toString();
286        default:
287                return SString("null");
288        }
289}
290
291ExtObject ExtValue::getObject() const
292{
293if (type==TObj) return odata();
294return ExtObject();
295}
296
297ExtValue ExtValue::getExtType()
298{
299if (getType()!=TObj) return ExtValue((long)getType());
300ExtObject& o=odata();
301return ExtValue(SString(o.isEmpty()?"":o.getParamInterface()->getName()));
302}
Note: See TracBrowser for help on using the repository browser.