Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: com/memoire/foo/FooList.java


1   /**
2    * @modification $Date: 2002/12/16 18:56:26 $
3    * @statut       unstable
4    * @file         FooList.java
5    * @version      0.08
6    * @author       Guillaume Desnoix
7    * @email        guillaume@desnoix.com
8    * @license      GNU General Public License 2 (GPL2)
9    * @copyright    1999-2001 Guillaume Desnoix
10   */
11  
12  package com.memoire.foo;
13  import com.memoire.foo.*;
14  
15  import java.lang.reflect.*;
16  import java.util.*;
17  
18  public class FooList
19         implements FooEval
20  {
21    private static FooCategory pkg_=null;
22  
23    public static final FooCategory init()
24    {
25      if(pkg_==null)
26      {
27        pkg_=FooCategory.create(FooList.class);
28        pkg_.alias("&list");
29  
30        pkg_.setMessage("#"  ,FooList.class,"length");
31        pkg_.setMessage("+"  ,FooList.class,"append");
32        pkg_.setMessage("[]" ,FooList.class,"extractII");
33        pkg_.setMessage("[[" ,FooList.class,"extractIX");
34        pkg_.setMessage("]]" ,FooList.class,"extractXI");
35        pkg_.setMessage("][" ,FooList.class,"extractXX");
36        //pkg_.setMessage("]" ,FooList.class,"brkMsg2");
37        pkg_.setMessage("="  ,FooList.class,"setValue");
38        pkg_.setMessage(":"  ,FooList.class,"local",false);
39        pkg_.setMessage("each",FooList.class,"each",false); 
40        //pkg_.setMessage("==" ,FooList.class,"equals");
41      }
42  
43      return pkg_;
44    }
45  
46    private Vector vector_;
47    String origin_;
48    int    lineno_;
49  
50    public FooList()
51    {
52      vector_=new Vector(0);
53    }
54  
55    /*
56      public FooList(Object[] _array)
57      {
58    vector_=new Vector(_array.length,1);
59    for(int i=0;i<_array.length;i++)
60        add(_array[i]);
61      }
62    */
63  
64    // not public
65    void add(Object _o)
66    {
67      if(_o!=FooVoid.VOID)
68      {
69        if(_o==null) _o=FooNull.NULL;
70        vector_.addElement(_o);
71      }
72    }
73  
74    public Object at(int _i)
75    {
76      Object r=null;
77      if((_i>=0)&&(_i<vector_.size()))
78        r=vector_.elementAt(_i);
79      if(r==FooNull.NULL) r=null;
80      return r;
81    }
82  
83    public int length()
84    {
85      return vector_.size();
86    }
87  
88    public boolean empty()
89    {
90      return (vector_.size()==0);
91    }
92    
93    public boolean contains(Object _o)
94    {
95      return vector_.contains(_o);
96    }
97  
98    public int hashCode()
99    {
100     return toString().hashCode();
101   }
102 
103   public boolean equals(Object _o)
104   {
105     if(_o==this) return true;
106     if(_o==null) return false;
107 
108     //System.err.println("LIST-EQUALS:"+this+"=="+_o);
109     boolean r=(_o instanceof FooList);
110 
111     if(r)
112     {
113       FooList o=(FooList)_o;
114       int     l=length();
115 
116       r=(l==o.length());
117 
118       if(r)
119       {
120   for(int i=0;i<l;i++)
121   {
122     Object a=at(i);
123     Object b=o.at(i);
124     /*
125     FooList call=new FooList();
126     call.add(a);
127     call.add(FooSymbol.create("=="));
128     call.add(b);
129     r=FooLib.booleanValue(call.eval());
130     System.err.println("CALL="+call);
131     */
132     r=FooObject.eqMsg(a,b).booleanValue();
133     if(!r) break;
134   }
135       }
136     }
137 
138     return r;
139   }
140   
141   public Object[] array()
142   {
143     // return vector_.toArray();
144 
145     int      l=length();
146     Object[] r=new Object[l];
147     
148     for(int i=0;i<l;i++) r[i]=at(i);
149     return r;
150   }
151 
152   public Object convert(Class _c)
153   {
154     int    l=length();
155     Object r=Array.newInstance(_c,l);
156 
157     for(int i=0;i<l;i++)
158       Array.set(r,i,at(i));
159 
160     return r;
161   }
162 
163   public Object eval()
164   {
165     if(empty()) return this;
166     
167     Object r=null;
168 
169     Object old_call3 =FooSymbol.get_local("[call-3]");
170     Object old_call2 =FooSymbol.get_local("[call-2]");
171     Object old_call1 =FooSymbol.get_local("[call-1]");
172     Object old_caller=FooSymbol.get_local("[caller]");
173     Object old_agent =FooSymbol.get_local("[agent]" );
174 
175     FooSymbol.create_local("[call-3]",old_call2);
176     FooSymbol.create_local("[call-2]",old_call1);
177     FooSymbol.create_local("[call-1]",this);
178 
179     Object c=FooNull.NULL;
180     Object a=null;
181 
182     if(  (old_call1 instanceof FooList)
183        &&!((FooList)old_call1).empty())
184       c=((FooList)old_call1).at(0);
185 
186     if(  (c!=null)
187        &&(FooCategory.create(c.getClass()).getMessage("[send]")!=null))
188       a=c;
189       
190     FooSymbol.create_local("[caller]",c);
191     if(a!=null) FooSymbol.create_local("[agent]",a);
192 
193     r=eval1();
194 
195     FooSymbol.forget_local("[call-3]",old_call3);
196     FooSymbol.forget_local("[call-2]",old_call2);
197     FooSymbol.forget_local("[call-1]",old_call1);
198     FooSymbol.forget_local("[caller]",old_caller);
199     if(a!=null) FooSymbol.forget_local("[agent]" ,old_agent);
200 
201     return r;
202   }
203 
204   private Object eval1()
205   {
206     if(empty())
207       throw new RuntimeException
208   ("empty list:"+FooLib.toString(this));
209     
210     Object o=FooLib.eval(at(0));
211 
212     if(o==null) o=FooNull.NULL;
213     /*
214     if(o==null)
215       throw new RuntimeException
216   ("object is null:"+FooLib.toString(at(0)));
217   */
218     
219     if(length()==1)
220       throw new RuntimeException
221   ("no message to eval:"+FooLib.toString(this));
222 
223     Object z=at(1);
224     if(z instanceof FooComma)
225   z=((FooComma)z).eval();
226 
227     String  s=z.toString();
228     Object  r=null;
229     Object  e=this;
230 
231     Object a=FooSymbol.get_local("[agent]" );
232     Object c=FooSymbol.get_local("[caller]");
233 
234     /*
235     System.err.println("$$$ call2="+FooLib.toSource(FooSymbol.get_local("[call-2]")));
236     System.err.println("$$$ call1="+FooLib.toSource(FooSymbol.get_local("[call-1]")));
237     System.err.println("$$$ this ="+FooLib.toSource(this));
238     System.err.println("$$$ a    ="+FooLib.toSource(a));
239     System.err.println("$$$ c    ="+FooLib.toSource(c));
240     System.err.println("$$$ o    ="+FooLib.toSource(o));
241     */
242 
243     Object old_meta_send=FooSymbol.get_local("[meta-send]");
244     Object old_meta_recv=FooSymbol.get_local("[meta-recv]");
245     
246     if(  !Boolean.TRUE.equals(old_meta_send)
247        &&!Boolean.TRUE.equals(old_meta_recv)
248        &&(a!=null)
249        &&(a!=o))
250     {
251       FooList l=new FooList();
252       l.add(a);
253       l.add(FooSymbol.create("[send]"));
254       l.add(this);
255       FooSymbol.create_local("[meta-send]",Boolean.TRUE);
256       e=l.eval();
257       FooSymbol.forget_local("[meta-send]",old_meta_send);
258     }
259 
260     if(  !Boolean.TRUE.equals(old_meta_send)
261        &&(c!=o)
262        &&(FooCategory.create(o.getClass()).getMessage("[receive]")!=null)
263        &&!"[receive]".equals(s))
264     {
265       FooList l=new FooList();
266       l.add(o);
267       l.add(FooSymbol.create("[receive]"));
268       l.add(this);
269       FooSymbol.create_local("[meta-recv]",Boolean.TRUE);
270       e=l.eval();
271       FooSymbol.forget_local("[meta-recv]",old_meta_recv);
272     }
273 
274     /*
275     System.err.println("T="+this);
276     System.err.println("E="+e);
277     System.err.println("=="+equals(e));
278     */
279 
280     if(equals(e)) r=eval0(o,s);
281     else          r=FooLib.eval(e);
282 
283     return r;
284   }
285 
286   private Object eval0(Object _o,String _s)
287   {
288     Object   r=null;
289     Object   o=_o;
290     String   s=_s;
291     int      l=length();
292 
293     Object[] p=new Object[l-2];
294     for(int i=2;i<l;i++)
295       p[i-2]=at(i);
296 
297     Method m=null;
298     Class  c=o.getClass();
299 
300     boolean isClass =false;
301     boolean evalArgs=true;
302 
303     //System.err.println("Object : "+o);
304     //System.err.println("Message: "+s);
305     //System.err.println("Params#: "+p.length);
306 
307     Class d=c;
308     while(d!=null)
309     {
310       FooCategory fd=FooCategory.create(d);
311       //System.err.println("   - "+d+" "+fd);
312       if(fd!=null)
313       {
314   FooMessage msg=fd.getMessage(s);
315   if(msg!=null)
316   {
317     Object obj=msg.getObject();
318     if(obj instanceof Method)
319     {
320       m=(Method)obj;
321       evalArgs=msg.shouldEvalArgs();
322       break;
323     }
324     if(obj instanceof Field)
325     {
326       if(msg.shouldEvalArgs())
327         for(int i=0;i<p.length;i++)
328     p[i]=FooLib.eval(p[i]);
329       return FooLib.invokeField(o,(Field)obj,p);
330     }
331     if(obj instanceof Object[])
332     {
333       if(msg.shouldEvalArgs())
334         for(int i=0;i<p.length;i++)
335     p[i]=FooLib.eval(p[i]);
336       return FooLib.invokeBlock(o,(Object[])obj,p,msg.getArgNames());
337     }
338     if(obj instanceof String)
339     {
340       d=c;
341       s=(String)obj;
342       if(msg.shouldEvalArgs())
343         for(int i=0;i<p.length;i++)
344     p[i]=FooLib.eval(p[i]);
345       continue;
346     }
347   }
348       }
349       d=FooLib.getSuperclass(d);
350     }
351   
352     if((m==null)&&(o instanceof Class))
353     {
354       Constructor n=FooLib.getConstructor((Class)o,s,p.length);
355       if(n!=null)
356       {
357   if(evalArgs)
358     for(int i=0;i<p.length;i++)
359       p[i]=FooLib.eval(p[i]);
360   return FooLib.invokeConstructor(n,p);
361       }
362     }
363 
364     if(m==null)
365     {
366       m=FooLib.getMethod(c,s,p.length);
367       if((m==null)&&(o instanceof Class))
368       {
369   m=FooLib.getMethod((Class)o,s,p.length);
370   isClass=(m!=null);
371       }
372     }
373 
374     if(m==null)
375     {
376       Field f=FooLib.getField(c,s);
377       if((f==null)&&(o instanceof Class))
378   f=FooLib.getField((Class)o,s);
379       
380       // System.out.println("Field: "+f);
381       if(f!=null)
382       {
383   if(evalArgs)
384     for(int i=0;i<p.length;i++)
385       p[i]=FooLib.eval(p[i]);
386   return FooLib.invokeField(o,f,p);
387       }
388     }
389 
390     if(m==null)
391       throw new RuntimeException
392   ("message "+s+" can not be found for "+
393    FooLib.getClassName(o.getClass()));
394     
395     if(evalArgs)
396       for(int i=0;i<p.length;i++)
397   p[i]=FooLib.eval(p[i]);
398     
399     //System.out.println(""+m);
400   
401     if(!isClass)
402     {
403       boolean isStatic = ((m.getModifiers() & Modifier.STATIC) != 0);
404       if(isStatic)
405       {
406   Object[] q=new Object[p.length+1];
407   for(int i=0;i<p.length;i++) q[i+1]=p[i];
408   q[0]=o;
409   o=null;
410   p=q;
411       }
412     }
413 
414     r=FooLib.invokeMethod(o,m,p);
415     //System.out.println("--> "+r);
416     return r;
417   }
418 
419   public String toString()
420   {
421     StringBuffer r=new StringBuffer();
422     r.append('(');
423     for(int i=0;i<length();i++)
424     {
425       if(i>0) r.append(' ');
426       Object o=at(i);
427            if(o==null)                r.append(o);
428       else if(o.getClass().isArray()) r.append(FooLib.stringValue(o));
429       else                            r.append(o);
430     }
431     r.append(')');
432     return r.toString();
433   }
434 
435   public String toSource()
436   {
437     StringBuffer r=new StringBuffer();
438     r.append('(');
439     for(int i=0;i<length();i++)
440     {
441       if(i>0) r.append(' ');
442       r.append(FooLib.toSource(at(i)));
443     }
444     r.append(')');
445     return r.toString();
446   }
447 
448   public Object car()
449   {
450     return at(0);
451   }
452 
453   public FooList cdr()
454   {
455     FooList r=new FooList();
456     for(int i=1;i<length();i++) r.add(at(i));
457     return r;
458   }
459 
460   public FooList append(Object[] _n)
461   {
462     FooList r=new FooList();
463     for(int i=0;i<length() ;i++) r.add(at(i));
464     for(int i=0;i<_n.length;i++) r.add(_n[i]);
465     return r;
466   }
467 
468   /*
469   public FooList map(Object _msg)
470   {
471     FooList r=new FooList();
472     for(int i=0;i<length();i++)
473     {
474       Object o=at(i);
475       FooList call=new FooList().append(new Object[] { o,_msg });
476       r.add(call.eval());
477     }
478     return r;
479   }
480   */
481 
482   public FooList map(Object[] _o)
483   {
484     FooList r=new FooList();
485     for(int i=0;i<length();i++)
486     {
487       Object o=at(i);
488       FooList call=new FooList();
489       call=call.append(new Object[] { new FooQuote(o) });
490       call=call.append(_o);
491       r.add(call.eval());
492     }
493     return r;
494   }
495 
496   public FooList filter(Object[] _o)
497   {
498     FooList r=new FooList();
499     for(int i=0;i<length();i++)
500     {
501       Object o=at(i);
502       FooList call=new FooList();
503       call=call.append(new Object[] { o });
504       call=call.append(_o);
505       Object b=call.eval();
506       if(FooLib.booleanValue(b)) r.add(o);
507     }
508     return r;
509   }
510 
511   public FooList each(Object[] _o)
512   {
513     FooLib.checkClassArgument(FooSymbol.class,_o[0],1);
514 
515     FooList r   =new FooList();
516     String  name=((FooSymbol)_o[0]).getName();
517 
518     for(int i=0;i<length();i++)
519     {
520       Object  old=FooSymbol.get_local(name);
521       FooSymbol.create_local(name,at(i));
522       r.add(FooLib.evalBlock(_o,1));
523       FooSymbol.forget_local(name,old);
524     }
525 
526     return r;
527   }
528 
529   public FooList slice(int _begin, int _end)
530   {
531     FooList r=new FooList();
532     for(int i=Math.max(0,_begin);
533   i<Math.min(length(),_end);i++)
534       r.add(at(i));
535     return r;
536   }
537 
538     public Object extractII(Object[] _o)
539     {
540       Object r=null;
541 
542       switch(_o.length)
543       {
544       case 1:
545   FooLib.checkClassArgument(Number.class,_o[0],1);
546   r=at(((Number)_o[0]).intValue());  
547   break;
548       case 2:
549   FooLib.checkClassArgument(Number.class,_o[0],1);
550   FooLib.checkClassArgument(Number.class,_o[1],2);
551   r=slice(((Number)_o[0]).intValue()+0,
552     ((Number)_o[1]).intValue()+1);
553   break;
554       default:
555   FooLib.checkNumberArgument(1,_o.length);
556   break;
557       }
558       
559       return r;
560     }
561 
562     public Object extractIX(Object[] _o)
563     {
564       Object r=null;
565 
566       switch(_o.length)
567       {
568       case 2:
569   FooLib.checkClassArgument(Number.class,_o[0],1);
570   FooLib.checkClassArgument(Number.class,_o[1],2);
571   r=slice(((Number)_o[0]).intValue()+0,
572     ((Number)_o[1]).intValue()+0);
573   break;
574       default:
575   FooLib.checkNumberArgument(2,_o.length);
576   break;
577       }
578       
579       return r;
580     }
581 
582     public Object extractXI(Object[] _o)
583     {
584       Object r=null;
585 
586       switch(_o.length)
587       {
588       case 2:
589   FooLib.checkClassArgument(Number.class,_o[0],1);
590   FooLib.checkClassArgument(Number.class,_o[1],2);
591   r=slice(((Number)_o[0]).intValue()+1,
592     ((Number)_o[1]).intValue()+1);
593   break;
594       default:
595   FooLib.checkNumberArgument(2,_o.length);
596   break;
597       }
598       
599       return r;
600     }
601 
602     public Object extractXX(Object[] _o)
603     {
604       Object r=null;
605 
606       switch(_o.length)
607       {
608       case 2:
609   FooLib.checkClassArgument(Number.class,_o[0],1);
610   FooLib.checkClassArgument(Number.class,_o[1],2);
611   r=slice(((Number)_o[0]).intValue()+1,
612     ((Number)_o[1]).intValue()+0);
613   break;
614       default:
615   FooLib.checkNumberArgument(2,_o.length);
616   break;
617       }
618       
619       return r;
620     }
621 
622     /*
623     public Object brkMsg(Object[] _o)
624     {
625   Object r=null;
626 
627   switch(_o.length)
628   {
629   case 0:
630   case 1:
631       FooLib.checkNumberArgument(2,_o.length);
632       break;
633   case 2:
634       FooLib.checkClassArgument(Number.class,_o[0],1);
635       FooLib.checkValueArgument("]",_o[1],2);
636       r=at(((Number)_o[0]).intValue());  
637       break;
638   case 3:
639       FooLib.checkClassArgument(Number.class,_o[0],1);
640       FooLib.checkClassArgument(Number.class,_o[1],2);
641       FooLib.checkBracket(_o[2],3);
642       r=slice(((Number)_o[0]).intValue(),
643         ((Number)_o[1]).intValue()+
644         ("]".equals(_o[2]) ? 1 : 0));
645       break;
646   default:
647       FooLib.checkNumberArgument(4,_o.length);
648       break;
649   }
650 
651   return r;
652     }
653     */
654 
655     /*
656     public Object brkMsg2(Object[] _o)
657     {
658   Object r=null;
659 
660   switch(_o.length)
661   {
662   case 3:
663       FooLib.checkClassArgument(Number.class,_o[0],1);
664       FooLib.checkClassArgument(Number.class,_o[1],2);
665       FooLib.checkBracket(_o[2],3);
666       r=slice(((Number)_o[0]).intValue()+1,
667         ((Number)_o[1]).intValue()+
668         ("]".equals(_o[2]) ? 1 : 0));
669       break;
670   default:
671       FooLib.checkNumberArgument(4,_o.length);
672       break;
673   }
674 
675   return r;
676     }
677     */
678 
679     public void setValue(FooList _list)
680     {
681       int      l=_list.length();
682       Object[] r=new Object[l];
683       for(int i=0;i<l;i++)
684   r[i]=FooLib.eval(_list.at(i));
685 
686       int n=length();
687       for(int i=0;i<n;i++)
688       {
689   Object s=at(i);
690   if(s==null) continue;
691   if(!(s instanceof FooSymbol))
692     throw new RuntimeException
693       ("not a symbol:"+FooLib.toString(s));
694   ((FooSymbol)s).setValue
695     ((i<r.length) ? r[i] : null);
696       }
697     }
698 
699     public Object local(Object[] _body)
700     {
701   Object   r=null;
702   Object[] names=array();
703   int      l=names.length;
704   Object[] old_vars=new Object[l];
705 
706   for(int i=0;i<l;i++)
707   {
708       Object s=names[i];
709       if(!(s instanceof FooSymbol))
710     throw new RuntimeException
711         ("not a symbol:"+FooLib.toString(s));
712       String n=s.toString();
713       old_vars[i]=FooSymbol.get_local(n);
714       FooSymbol.create_local(n,null);
715   }
716 
717   r=FooLib.evalBlock(_body,0);
718 
719   for(int i=0;i<l;i++)
720   {
721       Object s=names[i];
722       String n=s.toString();
723       FooSymbol.forget_local(n,old_vars[i]);
724   }
725 
726   return r;
727     }
728 
729   // BROKEN???
730   public FooList order()
731   {
732     Hashtable t=new Hashtable();
733     int       l=length();
734     int       i;
735 
736     for(i=0;i<l;i++)
737     {
738       Object  o=at(i);
739       Integer j=(Integer)t.get(o);
740       if(j==null) j=new Integer(1);
741       else        j=new Integer(j.intValue()+1);
742       t.put(o,j);
743     }
744 
745     l=t.size();
746     int[]    n=new int[l];
747     Object[] v=new Object[l];
748     Enumeration e=t.keys();
749     i=0;
750     while(e.hasMoreElements())
751     {
752       Object o=e.nextElement();
753       v[i]=o;
754       n[i]=((Integer)t.get(o)).intValue();
755       i++;
756     }
757 
758     for(i=1;i<l;i++)
759     {
760       if(n[i-1]<n[i])
761       {
762   int    m=n[i-1]; n[i-1]=n[i]; n[i]=m;
763   Object w=v[i-1]; v[i-1]=v[i]; v[i]=w;
764   i--;
765   if(i>=0) i--;
766       }
767     }
768 
769     return new FooList().append(v);
770   }
771 }