OSDN Git Service

first commit
[soopy/alpha1.git] / src / NameSpace.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: NameSpace.cpp,v 1.69 2004/03/27 05:08:14 randy Exp $
12  */
13
14 #include "soopy.h"
15
16 //
17 // Soopy NameSpace Class
18 //
19
20 #ifndef USE_PTHREAD
21 vector<SpValue> Frame;
22 #endif
23
24 SpNameSpace::SpNameSpace(NSMap& m, SpValue& p)
25 {
26     aMap = m;
27     parentNS = p;
28 }
29
30 SpNameSpace::SpNameSpace(SpNameSpace* ns1, SpNameSpace* ns2, SpValue& p)
31 {
32     aMap = ns1->aMap;
33     NSMap::iterator found;
34     NSMap::iterator it = ns2->aMap.begin();
35     for(; it != ns2->aMap.end(); it++){
36         found = aMap.find(it->first);
37         if(found != aMap.end()){
38             aMap.erase(found);
39         }
40         aMap[it->first] = it->second;
41     }
42     parentNS = p;
43 }
44
45 SpNameSpace::SpNameSpace(SpValue& p)
46 {
47     parentNS = p;
48 }
49
50 SpNameSpace::~SpNameSpace()
51 {
52 #ifdef TEST
53     *spout << ":destroy NameSpace:" << "\n";
54 #endif
55 //    NSMap::iterator it;
56 //    for(it = aMap.begin(); it != aMap.end(); it++){
57 //        delete it->first;
58 //    }
59 }
60
61 SpValue& SpNameSpace::toString()
62 {
63     SpString* str;
64     bool isPublic=true;
65
66     str = new SpString();
67     *str = "{\n";
68     NSMap::iterator it;
69     for(it = aMap.begin(); it != aMap.end(); it++){
70         SpValue temp = it->first;
71         NSKey* key = temp.asNSKey();
72         if(key->isPublic != isPublic){
73             isPublic = ! isPublic;
74             if(isPublic){
75                 *str += "public\n";
76             }else{
77                 *str += "private\n";
78             }
79         }
80         *str += "  ";
81         *str += key->toString();
82         *str += ": ";
83         *str += it->second.toString();
84         *str += ";\n";
85     }
86     *str += "}";
87
88     //    static SpValue s;
89     //    s.setNewObject(str);
90     //    return s;
91     return SpObjectResult(str);
92 }
93
94 bool SpNameSpace::operator==(SpObject& obj)
95 {
96     if(SpNameSpace* p2 = dynamic_cast<SpNameSpace*>(&obj)){
97         if(size() != p2->size()){
98             return false;
99         }
100
101         NSMap::iterator it;
102         for(it = aMap.begin(); it != aMap.end(); it++){
103             NSMap::iterator find;
104
105             find = p2->aMap.find(it->first);
106             if(find == p2->aMap.end()){ // not found
107                 return false;
108             }
109             if(it->second != find->second){
110                 return false;
111             }
112         }
113         return true;
114     }
115     return false;
116 }
117
118 bool SpNameSpace::operator<(SpObject& obj)
119 {
120     if(SpNameSpace* p2 = dynamic_cast<SpNameSpace*>(&obj)){
121         int size1 = size();
122         int size2 = p2->size();
123         if(size1 != size2){
124             return size1 < size2;
125         }
126
127         // \82·\82×\82Ä\82Ì\83L\81[\82ª\93¯\82\82©\82Ç\82¤\82©\83`\83F\83b\83N
128         bool all_match = true;
129         NSMap::iterator it;
130         for(it = aMap.begin(); it != aMap.end(); it++){
131             NSMap::iterator find;
132             find = p2->aMap.find(it->first);
133             if(find == p2->aMap.end()){ // not found
134                 all_match = false;
135                 break;
136             }
137         }
138
139         if(all_match){
140             // \82·\82×\82Ä\82Ì\83L\81[\82ª\93¯\82\82Æ\82«\81A\92l\82ð\8f\87\94Ô\82É\94ä\8ar\82·\82é\81B
141             NSMap::iterator it;
142             for(it = aMap.begin(); it != aMap.end(); it++){
143                 if(it->second != p2->aMap[it->first]){
144                     return it->second < p2->aMap[it->first];
145                 }
146             }
147             return false;
148         }else{
149             // \83L\81[\82ª\95Ê\82Ì\82Æ\82«\81A\83L\81[\82Ì\91å\82«\82³\82ð\94ä\8ar\82·\82é\81B
150             //   \83L\81[\82Ì\8f\87\94Ô\82É\82Í\88Ó\96¡\82ª\82È\82¢\82Ì\82Å\81A\82±\82ê\82Å\82Í\81A\96{\93\96\82Í\95s\8f\\95ª\81B
151             //   \82æ\82Á\82Ä\81A\92P\8f\83\82È\83l\81[\83\80\83X\83y\81[\83X\88È\8aO\82ð\81A\83l\81[\83\80\83X\83y\81[\83X\82Ì\83L\81[\82Æ\82µ\82Ä\8eg\82¤\82×\82«\82Å\82Í\82È\82¢\81B
152             NSMap::iterator it;
153             NSMap::iterator it2;
154             for(it = aMap.begin(), it2 = p2->aMap.begin();
155                 it != aMap.end();
156                 it++, it2++)
157             {
158                 SpValue temp;
159                 temp = it->first;
160                 NSKey* key1 = temp.asNSKey();
161                 temp = it2->first;
162                 NSKey* key2 = temp.asNSKey();
163                 SpValue v1 = key1->val;
164                 SpValue v2 = key2->val;
165                 if(v1 != v2){
166                     return v1 < v2;
167                 }
168             }
169         }
170     }
171     return SpObject::operator<(obj);
172 }
173
174 SpNameSpace& SpNameSpace::operator+=(SpNameSpace& ns)
175 {
176     NSMap::iterator it;
177     for(it=ns.begin(); it != ns.end(); it++){
178         this->setValue((SpValue&)it->first, it->second, (SpNameSpace*)this);
179     }
180     return *this;
181 }
182
183 bool SpNameSpace::reachable(SpNameSpace* ns)
184 {
185   if(ns == NULL) return false;
186   if(this == ns){
187     return true;
188   }
189   if(!parentNS.isNil()){
190     SpNameSpace* p = parentNS.asNameSpace();
191     return p->reachable(ns);
192   }
193   return false;
194 }
195
196 SpValue& SpNameSpace::lookup(SpValue& v, SpNameSpace* searcher)
197 {
198     NSVar* key = new NSVar(v);
199     try{
200         return getValue(key, searcher, NULL, true);
201     //}catch(SpAccessException& e){
202     //    throw;
203     //}catch(SpException& e){
204     }catch(SpKeyException& e){
205         return NilObject;
206     }
207 }
208
209 // search 1 level only
210 SpValue& SpNameSpace::lookup1(SpValue& v, SpNameSpace* searcher)
211 {
212     NSVar* key = new NSVar(v);
213     try{
214         return getValue(key, searcher, NULL, false);
215     //}catch(SpAccessException& e){
216     //    throw;
217     //}catch(SpException& e){
218     }catch(SpKeyException& e){
219         return NilObject;
220     }
221 }
222
223 SpValue& SpNameSpace::getValue(NSKey* k, SpNameSpace* searcher, SpNameSpace* cur_ns, bool search_parent)
224 {
225 //cout << "getValue key:'" << *k << "'" << endl;
226     if(cur_ns == NULL){
227         cur_ns = this;
228     }
229     NSKey* ptr;
230     //    SpValue key(k);
231     SpValue key;
232     key.setObject(k);
233     NSMap::iterator it;
234     it = aMap.find(key);
235     if(it != aMap.end()){
236         SpValue temp = it->first;
237         ptr = temp.asNSKey();
238         // check permission
239         if(!ptr->isPublic){
240             if(searcher == NULL){
241                 throw SpAccessException("can't access private feature.");
242             }
243             if(!searcher->reachable(this)){
244                 throw SpAccessException("can't access private feature.");
245             }
246         }
247         if(ptr->isNSProperty()){
248             NSProperty* pro = (NSProperty*)ptr;
249             NSVar* var = new NSVar(pro->getter);
250             SpValue key2(var);
251             it = aMap.find(key2);
252             if(it == aMap.end()){ throw SpException("no getter in property"); }
253             temp = it->first;
254             NSKey* ptr2 = dynamic_cast<NSKey*>(temp.getObject());
255             if(ptr2->isNSFunc()){
256                 SpFunc* func = it->second.asFunc();
257                 //static SpValue v;
258                 SpValue v;
259                 // push this to currentNS
260                 SpValue ns(cur_ns);
261                 pushCurrentNS(ns);
262                 try{
263                     v = (*func)(NilObject);
264                 }catch(...){
265                     popCurrentNS();
266                     throw;
267                 }
268                 popCurrentNS();
269                 //                return v;
270                 return SpValueResult(v);
271             }else{
272                 return it->second;
273             }
274         }else if(ptr->isNSPrimProperty()){
275             NSPrimProperty* pro = (NSPrimProperty*)ptr;
276             if(pro->getter.isFunc()){
277                 SpFunc* func = pro->getter.asFunc();
278                 //                static SpValue v;
279                 SpValue v;
280                 // push this to currentNS
281                 SpValue ns(cur_ns);
282                 pushCurrentNS(ns);
283                 try{
284                     v = (*func)(NilObject);
285                 }catch(...){
286                     popCurrentNS();
287                     throw;
288                 }
289                 popCurrentNS();
290                 //                return v;
291                 return SpValueResult(v);
292             }else{
293                 return it->second;
294             }
295         }else if(ptr->isNSFunc()){
296             //SpValue ns(this);
297             SpValue ns(cur_ns);
298             SpClosure* clos = new SpClosure(it->second, ns);
299             //            static SpValue result;
300             //            result.setNewObject(clos);
301             //            return result;
302             return SpObjectResult(clos);
303         }else{
304             return it->second;
305         }
306     }
307     // not found
308     if(search_parent && !parentNS.isNil()){
309         SpNameSpace* ns = dynamic_cast<SpNameSpace*>(parentNS.getObject());
310         return ns->getValue(k, searcher, cur_ns);
311     }
312
313     throw SpKeyException("no such a key", k->toCStringWithEncoder());
314 }
315
316 void SpNameSpace::setValue(SpValue& key, SpValue& val, SpNameSpace* searcher, SpNameSpace* cur_ns)
317 {
318     SpValue old_value;
319     if(cur_ns == NULL){
320         cur_ns = this;
321     }
322     NSMap::iterator it;
323     it = aMap.find(key);
324     if(it != aMap.end()){
325         old_value = it->second;
326         SpValue temp = it->first;
327         NSKey* ptr = temp.asNSKey();
328         // check permission
329         if(!ptr->isPublic){
330             if(searcher == NULL){
331                 throw SpAccessException("can't access private feature.");
332             }
333             if(!searcher->reachable(this)){
334                 throw SpAccessException("can't access private feature.");
335             }
336         }
337         if(ptr->isNSProperty()){
338             NSProperty* pro = (NSProperty*)ptr;
339             NSVar* var = new NSVar(pro->setter);
340             SpValue key2(var);
341             it = aMap.find(key2);
342             if(it == aMap.end()){ throw SpException("no setter in property"); }
343             temp = it->first;
344             NSKey* ptr2 = dynamic_cast<NSKey*>(temp.getObject());
345             if(ptr2->isNSFunc()){
346                 SpFunc* func = it->second.asFunc();
347                 // push this to currentNS
348                 //SpValue ns(this);
349                 SpValue ns(cur_ns);
350                 pushCurrentNS(ns);
351                 try{
352                     (*func)(val);
353                 }catch(...){
354                     popCurrentNS();
355                     throw;
356                 }
357                 popCurrentNS();
358             }else if(ptr2->isNSConst()){
359                 throw SpException("setter is constant or function");
360             }else{
361                 //aMap[pro->setter] = val;
362                 aMap[key2] = val;
363             }
364         }else if(ptr->isNSPrimProperty()){
365             NSPrimProperty* pro = (NSPrimProperty*)ptr;
366             if(pro->setter.isFunc()){
367                 SpFunc* func = pro->setter.asFunc();
368                 //                static SpValue v;
369                 // push this to currentNS
370                 SpValue ns(cur_ns);
371                 pushCurrentNS(ns);
372                 try{
373                     (*func)(val);
374                 }catch(...){
375                     popCurrentNS();
376                     throw;
377                 }
378                 popCurrentNS();
379             }else{
380                 //throw SpException("system error");
381                 throw SpSystemError(__FILE__, __LINE__);
382             }
383         }else{
384             if(ptr->isNSConst()){
385                 throw SpException("can't change constant or function");
386             }
387             aMap.erase(it);
388             aMap[key] = val;
389         }
390     }else{
391         if(!parentNS.isNil()){
392             SpNameSpace* ns = dynamic_cast<SpNameSpace*>(parentNS.getObject());
393             ns->setValue(key, val, searcher);
394         }else if(this == PMainNameSpace){
395             aMap[key] = val;
396         }else{
397             throw SpException("can't set undefined feature");
398         }
399     }
400 }
401
402 void SpNameSpace::intern(SpValue& key, SpValue& val)
403 {
404     NSMap::iterator it = aMap.find(key);
405     if(it != aMap.end()){
406         aMap.erase(it);
407     }
408     aMap[key] = val;
409 }
410
411 /*
412  * NSVar
413  */
414
415 SpValue& NSVar::toString()
416 {
417     SpString* s = new SpString("var ");
418     *s += val.toString();
419     //    static SpValue v;
420     //    v.setNewObject(s);
421     //    return v;
422     return SpObjectResult(s);
423 }
424
425
426 /*
427  * NSCont
428  */
429
430 SpValue& NSConst::toString()
431 {
432     SpString* s1 = new SpString("const ");
433     SpValue taker(s1);
434     SpValue v2 = val.toString();
435     SpString* s2 = dynamic_cast<SpString*>(v2.getObject());
436     *s1 += *s2;
437     SpString* s = new SpString(s1->toCStringWithEncoder());
438     //    static SpValue v;
439     //    v.setNewObject(s);
440     //    return v;
441     return SpObjectResult(s);
442 }
443
444
445 /*
446  * NSProperty
447  */
448
449 SpValue& NSProperty::toString()
450 {
451     bool print_getter=false;
452     SpString* s = new SpString("property ");
453     SpValue taker(s);
454     SpValue v0 = NSKey::toString();
455     SpValue v1 = getter.toString();
456     SpValue v2 = setter.toString();
457     SpString* s1 = dynamic_cast<SpString*>(v1.getObject());
458     SpString* s2 = dynamic_cast<SpString*>(v2.getObject());
459     *s += v0;
460     *s += " {";
461     if(getter != NilObject){
462         *s += "get: ";
463         *s += *s1;
464         print_getter = true;
465     }
466     if(setter != NilObject){
467         if(print_getter){
468             *s += ", ";
469         }
470         *s += "set: ";
471         *s += *s2;
472     }
473     *s += "}";
474     SpString* s3 = new SpString(s->toCStringWithEncoder());
475     //    static SpValue v;
476     //    v.setNewObject(s3);
477     //    return v;
478     return SpObjectResult(s3);
479 }
480
481
482 /*
483  * NSPrimProperty
484  */
485
486 SpValue& NSPrimProperty::toString()
487 {
488     bool print_getter=false;
489     SpString* s = new SpString("property ");
490     SpValue taker(s);
491     SpValue v0 = NSKey::toString();
492     SpValue v1 = getter.toString();
493     SpValue v2 = setter.toString();
494     SpString* s1 = dynamic_cast<SpString*>(v1.getObject());
495     SpString* s2 = dynamic_cast<SpString*>(v2.getObject());
496     *s += v0;
497     *s += " {";
498     if(getter != NilObject){
499         *s += "get: ";
500         *s += *s1;
501         print_getter = true;
502     }
503     if(setter != NilObject){
504         if(print_getter){
505             *s += ", ";
506         }
507         *s += "set: ";
508         *s += *s2;
509     }
510     *s += "}";
511     SpString* s3 = new SpString(s->toCStringWithEncoder());
512     //    static SpValue v;
513     //    v.setNewObject(s3);
514     //    return v;
515     return SpObjectResult(s3);
516 }
517
518
519 /*
520  * Message Handler
521  */
522
523 SpValue& SpNameSpace::onMessage(SpValue& rec, SpValue& msg)
524 {
525     NSVar* key = new NSVar(msg);
526     try{
527         SpValue temp = getCurrentNS();
528         SpNameSpace* ns = temp.asNameSpace();
529         return getValue(key, ns);
530         //        return lookup(msg);
531     }catch(SpAccessException& e){
532         throw;
533     }catch(SpException& e){
534         try{
535             return NameSpaceMsgHandler(rec, msg);
536         }catch(SpNoMethodException& e){
537             return NilObject;
538         }
539     }
540 }
541
542 /*
543  * primitives
544  */
545
546 SpValue& SpNameSpace::rename(SpValue& self, SpValue& renames)
547 {
548     if(!renames.isNameSpace()){
549         throw SpException("arg is not namespace.(ns.rename)");
550     }
551     SpNameSpace* ns1 = self.asNameSpace();
552     SpNameSpace* ns2 = renames.asNameSpace();
553
554     NSMap assoc = ns1->aMap;
555     NSMap::iterator it = ns2->aMap.begin();
556     for(; it != ns2->aMap.end(); it++){
557         NSMap::iterator found;
558         found = assoc.find(it->first);
559         if(found != assoc.end()){
560             SpValue val = found->second;
561             //NSKey* key = ((SpValue&)found->first).asNSKey();
562             SpValue temp = found->first;
563             NSKey* key = temp.asNSKey();
564             if(key->isNSProperty()){
565                 NSProperty* p = (NSProperty*)key;
566                 key = new NSProperty(it->second, p->getter, p->setter, p->isPublic);
567             }else if(key->isNSPrimProperty()){
568                 NSPrimProperty* p = (NSPrimProperty*)key;
569                 key = new NSProperty(it->second, p->getter, p->setter, p->isPublic);
570             }else if(key->isNSFunc()){
571                 key = new NSFunc(it->second);
572             }else if(key->isNSDataType()){
573                 key = new NSDataType(it->second);
574             }else if(key->isNSConst()){
575                 key = new NSConst(it->second);
576             }else{
577                 key = new NSVar(it->second);
578             }
579             assoc.erase(found);
580             assoc[key] = val;
581         }
582     }
583
584     //    static SpValue result;
585     //    result.setNewObject(new SpNameSpace(assoc, ns1->parentNS));
586     //    return result;
587     return SpObjectResult(new SpNameSpace(assoc, ns1->parentNS));
588 }
589
590
591 SpValue& SpNameSpace::make_func(SpValue& self)
592 {
593     SpNameSpace* ns = self.asNameSpace();
594     SpValue f(SpUsrFunc::fromNameSpace(ns));
595     //    static SpValue result;
596     //    result.setNewObject(new SpClosure(f, self));
597     //    return result;
598     return SpObjectResult(new SpClosure(f, self));
599 }
600
601 static SpValue PrimAppend;
602
603 SpValue& SpNameSpace::prim_append(SpValue& self, SpValue& key, SpValue& val)
604 {
605     SpNameSpace* ns = self.asNameSpace();
606     SpValue v1 = key.eval();
607     SpValue v2 = val.eval();
608     ns->internVar(v1, v2);
609
610     //    static SpValue result;
611     //    result.setNewObject(new SpClosureP3_1(PrimAppend, self, getCurrentNS()));
612     //    return result;
613     return SpObjectResult(new SpClosureP3_1(PrimAppend, self, getCurrentNS()));
614 }
615
616 SpValue& SpNameSpace::prim_keys(SpValue& self)
617 {
618     //    static SpValue result;
619     SpValue result;
620     result = NilObject;
621     SpNameSpace* ns = self.asNameSpace();
622
623     NSMap::iterator it = ns->aMap.begin();
624     for(; it != ns->aMap.end(); it++){
625         NSKey* key;
626         key = ((SpValue)it->first).asNSKey();
627         result.setNewObject(new SpCons(key->val, result));
628     }
629
630     //    return result;
631     return SpValueResult(result);
632 }
633
634 SpValue& SpNameSpace::prim_delete(SpValue& self, SpValue& key)
635 {
636     SpNameSpace* ns = self.asNameSpace();
637     NSVar var(key);
638     SpValue k;
639     k.setObject(&var);
640     NSMap::iterator found = ns->aMap.find(k);
641     if(found != ns->aMap.end()){
642         ns->aMap.erase(found);
643         return TrueObject;
644     }
645     return FalseObject;
646 }
647
648 SpValue& SpNameSpace::prim_lookup(SpValue& self, SpValue& key)
649 {
650     SpNameSpace* ns = self.asNameSpace();
651     SpValue v = key.eval();
652     //    static SpValue result;
653     //    result = ns->lookup(v);
654     //    return result;
655     return SpValueResult(ns->lookup(v));
656 }
657
658 /*
659  * init NameSpace
660  */
661
662 SpNameSpace* PMainNameSpace;
663 SpValue MainNS;
664 SpNameSpace* PSoopyNameSpace;
665 SpValue SoopyNS;
666 SpNameSpace* PEnvNameSpace;
667 SpValue EnvNS;
668
669 void SpNameSpace::init()
670 {
671     PMainNameSpace = new SpNameSpace();
672     MainNS.setNewObject(PMainNameSpace);
673     pushCurrentNS(MainNS);
674
675     PSoopyNameSpace = new SpNameSpace();
676     SoopyNS.setNewObject(PSoopyNameSpace);
677     PMainNameSpace->internConst(SymSoopy, SoopyNS);
678
679     PEnvNameSpace = new SpNameSpace();
680     EnvNS.setNewObject(PEnvNameSpace);
681     PMainNameSpace->internConst(SymEnv, EnvNS);
682
683     SpValue PrimRename(new SpPrim2(rename));
684     NameSpaceMsgHandler.append(SymRename, PrimRename);
685
686     SpValue SymEval(new SpSymbol("eval"));
687     SpValue PrimEval(new SpPrim1(make_func));
688     NameSpaceMsgHandler.append(SymEval, PrimEval);
689
690     PrimAppend.setNewObject(new SpPrim3(prim_append));
691     NameSpaceMsgHandler.append(SymAppend, PrimAppend);
692
693     SpValue PrimKeys(new SpPrim1(prim_keys));
694     NameSpaceMsgHandler.append(SymKeys, PrimKeys);
695
696     SpValue PrimDelete(new SpPrim2(prim_delete));
697     NameSpaceMsgHandler.append(SymDelete, PrimDelete);
698
699     SpValue SymLookup(new SpSymbol("lookup"));
700     SpValue PrimLookup(new SpPrim2(prim_lookup));
701     NameSpaceMsgHandler.append(SymLookup, PrimLookup);
702 }
703
704 /*
705  * operator +
706  */
707
708 SpValue& SpNameSpace::plus(SpValue& e1, SpValue& e2)
709 {
710     SpNameSpace* ns1;
711     SpNameSpace* ns2;
712     SpNameSpace* ns3;
713
714     if(!e2.isNameSpace()){
715         throw SpException("type mismatch in +(NameSpace, ...)");
716     }
717     ns1 = dynamic_cast<SpNameSpace*>(e1.getObject());
718     ns2 = dynamic_cast<SpNameSpace*>(e2.getObject());
719     ns3 = new SpNameSpace(ns1, ns2, getCurrentNS());
720     //    static SpValue v;
721     //    v.setNewObject(ns3);
722     //    return v;
723     return SpObjectResult(ns3);
724 }
725
726
727 /*
728  * class MakeNameSpace
729  */
730
731 SpValue& MakeNameSpace::eval()
732 {
733     SpNameSpace* src = dynamic_cast<SpNameSpace*>(ns.getObject());
734     SpNameSpace* assoc = new SpNameSpace(getCurrentNS());
735     NSMap::iterator it = src->aMap.begin();
736     for(; it != src->aMap.end(); it++){
737         SpValue temp = it->first;
738         if(temp.isNSKey() && temp.asNSKey()->isNSDataType()){
739             SpDataType* dt = it->second.asDataType();
740             dt->mapping2ns(it->second, assoc);
741         }else{
742             SpValue v = it->second.eval();
743             temp = it->first;
744             assoc->intern(temp, v);
745         }
746     }
747     //    static SpValue result;
748     //    result.setNewObject(assoc);
749     //    return result;
750     return SpObjectResult(assoc);
751 }
752
753 SpValue& MakeNameSpace::toString()
754 {
755     SpString* str;
756
757     str = new SpString();
758     *str = "MakeNameSpace(";
759     *str += ns.toString();
760     *str += ")";
761     //    static SpValue s;
762     //    s.setNewObject(str);
763     //    return s;
764     return SpObjectResult(str);
765 }