OSDN Git Service

first commit
[soopy/alpha1.git] / src / Array.cpp
1 /*
2  * Programming Language SOOPY
3  *   (Simple Object Oriented Programming sYstem)
4  * 
5  * Copyright (C) 2002 SUZUKI Jun
6  * 
7  * URL: http://sourceforge.jp/projects/soopy/
8  * License: GPL(GNU General Public License)
9  * 
10  * 
11  * $Id: Array.cpp,v 1.13 2004/03/24 11:53:44 randy Exp $
12  */
13
14 #include <stdio.h>
15
16 #include "soopy.h"
17
18 /*
19  * class SpArray
20  */
21
22 SpBaseArray::SpBaseArray(uintvec& v)
23   : dimension(v)
24 {
25     depth = dimension.size();
26 }
27
28 // primitives
29 SpValue& SpBaseArray::getDepth(SpValue& self)
30 {
31     SpArray* array = self.asArray();
32     //    static SpValue result;
33     //    result.setInt(array->depth);
34     //    return result;
35     return SpIntResult(array->depth);
36 }
37
38 SpValue& SpBaseArray::getDimension(SpValue& self)
39 {
40     SpValue temp;
41     SpArray* array = self.asArray();
42     uintvec::iterator it;
43     it = array->dimension.begin();
44     temp.setInt(*it);
45     SpCons* head = new SpCons(temp);
46     SpCons* ptr = head;
47     it++;
48     for(; it != array->dimension.end(); it++){
49         temp.setInt(*it);
50         ptr->append(temp);
51         SpValue v;
52         v = ptr->nextList();
53         ptr = (SpCons*)v.asList();
54     }
55     //    static SpValue result;
56     //    result.setNewObject(head);
57     //    return result;
58     return SpObjectResult(head);
59 }
60
61 // init Message Handler
62 void SpBaseArray::init()
63 {
64     SpValue SymDepth(new SpSymbol("depth"));
65     SpValue PrimDepth(new SpPrim1(getDepth));
66     ArrayMsgHandler.append(SymDepth, PrimDepth);
67
68     SpValue SymDimension(new SpSymbol("dimension"));
69     SpValue PrimDimension(new SpPrim1(getDimension));
70     ArrayMsgHandler.append(SymDimension, PrimDimension);
71 }
72
73
74 /*
75  * class SpObjectArray
76  */
77
78 SpObjectArray::SpObjectArray(SpValue& t, uintvec& v)
79   : SpArray(v), typ(t)
80 {
81 //    depth = dimension.size();
82     int allsize = 1;
83     uintvec::iterator it;
84     it = dimension.begin();
85     for(; it != dimension.end(); it++){
86         allsize *= *it;
87     }
88     pvec = new SpValueVector(allsize);
89 }
90
91 SpValue& SpObjectArray::toString()
92 {
93     SpString* str;
94     char buf[128];
95
96     str = new SpString();
97     *str = "Array:";
98     if(!typ.isNil()){
99         *str += typ;
100     }
101     *str += " (";
102
103     uintvec::iterator it;
104     it = dimension.begin();
105 #ifdef HAVE_ITOA
106     *str += itoa(*it, buf, 10);
107 #else
108     sprintf(buf, "%d", *it);
109     *str += buf;
110 #endif
111     it++;
112     for(; it != dimension.end(); it++){
113         *str += ",";
114 #ifdef HAVE_ITOA
115         *str += itoa(*it, buf, 10);
116 #else
117     sprintf(buf, "%d", *it);
118     *str += buf;
119 #endif
120     }
121
122     *str += ")";
123     //    static SpValue s;
124     //    s.setNewObject(str);
125     //    return s;
126     return SpObjectResult(str);
127 }
128
129 SpValue& SpObjectArray::operator[](SpValue& tuple)
130 {
131     if(tuple.isTuple()){
132         SpTuple* t = dynamic_cast<SpTuple*>(tuple.getObject());
133         if((SpInt)depth != t->length()){
134             throw SpException("array depth mismatch");
135         }
136         uintvec::iterator uit;
137         SpValueVector::iterator tit;
138         uit = dimension.begin();
139         tit = t->begin();
140         unsigned int offset = 0;
141         unsigned int times = 1;
142         for(; uit != dimension.end(); uit++, tit++){
143             SpValue v = tit->eval();
144             if(!v.isInt()){
145                 throw SpException("not int (access array)");
146             }
147             unsigned int index = v.getInt();
148             if((*uit - 1) < index){
149                 throw SpException("too large index (access array)");
150             }
151             offset += times * index;
152             times *= *uit;
153         }
154         return (*pvec)[offset];
155
156     }else{ // not tuple
157         SpValue v = tuple.eval();
158         if(!v.isInt()){
159             throw SpException("not int (access array)");
160         }
161         if(depth != 1){
162             throw SpException("depth not match (access array)");
163         }
164         unsigned int index = v.getInt();
165         if((dimension[0] - 1) < index){
166             throw SpException("over range (access array)");
167         }
168         return (*pvec)[index];
169     }
170 }
171
172 void SpObjectArray::set(SpValue& tuple, SpValue& value)
173 {
174     (*this)[tuple] = value;
175 }
176
177 SpValue& SpObjectArray::onMessage(SpValue& rec, SpValue& msg)
178 {
179     if(ArrayMsgHandler.hasMessage(msg)){
180         return ArrayMsgHandler(rec, msg);
181     }
182     SpValue val = msg.eval();
183     if(val.isInt()){
184         return operator[](val);
185     }
186     if(val.isTuple()){
187         return operator[](val);
188     }
189
190     // Error
191     static char buf[256];
192     strncpy(buf, rec.toCStringWithEncoder(), 255);
193     buf[255] = '\0';
194     static char buf2[256];
195     strncpy(buf2, msg.toCStringWithEncoder(), 255);
196     buf2[255] = '\0';
197     throw SpNoMethodException("no such a feature", buf, buf2);
198 }
199
200
201 /*
202  * class SpByteArray
203  */
204
205 SpByteArray::SpByteArray(uintvec& v)
206   : SpBaseArray(v)
207 {
208     int allsize = 1;
209     uintvec::iterator it;
210     it = dimension.begin();
211     for(; it != dimension.end(); it++){
212         allsize *= *it;
213     }
214 //    buf = new char(allsize);
215     buf = (unsigned char*)malloc(allsize);
216     if(buf == NULL){
217         throw SpException("out of memory");
218     }
219 }
220
221 SpValue& SpByteArray::toString()
222 {
223     SpString* str;
224     char buf[128];
225
226     str = new SpString();
227     *str = "Array:byte (";
228
229     uintvec::iterator it;
230     it = dimension.begin();
231 #ifdef HAVE_ITOA
232     *str += itoa(*it, buf, 10);
233 #else
234     sprintf(buf, "%d", *it);
235     *str += buf;
236 #endif
237     it++;
238     for(; it != dimension.end(); it++){
239         *str += ",";
240 #ifdef HAVE_ITOA
241         *str += itoa(*it, buf, 10);
242 #else
243     sprintf(buf, "%d", *it);
244     *str += buf;
245 #endif
246     }
247
248     *str += ")";
249     //    static SpValue s;
250     //    s.setNewObject(str);
251     //    return s;
252     return SpObjectResult(str);
253 }
254
255 unsigned char& SpByteArray::operator[](SpValue& tuple)
256 {
257     if(tuple.isTuple()){
258         SpTuple* t = dynamic_cast<SpTuple*>(tuple.getObject());
259         if((SpInt)depth != t->length()){
260             throw SpException("array depth mismatch");
261         }
262         uintvec::iterator uit;
263         SpValueVector::iterator tit;
264         uit = dimension.begin();
265         tit = t->begin();
266         unsigned int offset = 0;
267         unsigned int times = 1;
268         for(; uit != dimension.end(); uit++, tit++){
269             SpValue v = tit->eval();
270             if(!v.isInt()){
271                 throw SpException("not int (access array)");
272             }
273             unsigned int index = v.getInt();
274             if((*uit - 1) < index){
275                 throw SpException("too large index (access array)");
276             }
277             offset += times * index;
278             times *= *uit;
279         }
280         return buf[offset];
281
282     }else{ // not tuple
283         SpValue v = tuple.eval();
284         if(!v.isInt()){
285             throw SpException("not int (access array)");
286         }
287         if(depth != 1){
288             throw SpException("depth not match (access array)");
289         }
290         unsigned int index = v.getInt();
291         if((dimension[0] - 1) < index){
292             throw SpException("over range (access array)");
293         }
294         return buf[index];
295     }
296 }
297
298 SpValue& SpByteArray::getFeatureType()
299 {
300     return SymByte;
301 }
302
303 SpValue& SpByteArray::onMessage(SpValue& rec, SpValue& msg)
304 {
305   //    static SpValue result;
306
307     if(ArrayMsgHandler.hasMessage(msg)){
308         return ArrayMsgHandler(rec, msg);
309     }
310     SpValue val = msg.eval();
311     if(val.isInt()){
312       //        result.setInt(operator[](val));
313       //        return result;
314       return SpIntResult(operator[](val));
315     }
316     if(val.isTuple()){
317       //        result.setInt(operator[](val));
318       //        return result;
319       return SpIntResult(operator[](val));
320     }
321
322     // Error
323     static char buf[256];
324     strncpy(buf, rec.toCStringWithEncoder(), 255);
325     buf[255] = '\0';
326     static char buf2[256];
327     strncpy(buf2, msg.toCStringWithEncoder(), 255);
328     buf2[255] = '\0';
329     throw SpNoMethodException("no such a feature", buf, buf2);
330 }
331
332
333 /*
334  * class MakeArray
335  */
336
337 SpValue& MakeArray::eval()
338 {
339     uintvec intVec; // int vector
340     SpTuple* tuple = vec.asTuple();
341     SpValueVector::iterator it;
342     it = tuple->begin();
343     for(; it != tuple->end(); it++){
344         SpValue v = it->eval();;
345         if(!v.isInt()){ throw SpException("not int (make array)"); }
346         intVec.push_back(v.getInt());
347     }
348
349     //    static SpValue result;
350     if(typ == SymByte){
351       //        result.setNewObject(new SpByteArray(intVec));
352       return SpObjectResult(new SpByteArray(intVec));
353     }else{
354       //        result.setNewObject(new SpObjectArray(typ, intVec));
355       return SpObjectResult(new SpObjectArray(typ, intVec));
356     }
357     //    return result;
358 }
359
360 SpValue& MakeArray::toString()
361 {
362     SpString* str;
363     //char buf[128];
364
365     str = new SpString();
366     *str = "MakeArray:";
367     if(!typ.isNil()){
368         *str += typ;
369     }
370     *str += " (";
371
372     SpTuple* tuple = vec.asTuple();
373     SpValueVector::iterator it;
374     it = tuple->begin();
375     *str += *it;
376     it++;
377     for(; it != tuple->end(); it++){
378         *str += ",";
379         *str += *it;
380     }
381
382     *str += ")";
383     //    static SpValue s;
384     //    s.setNewObject(str);
385     //    return s;
386     return SpObjectResult(str);
387 }
388