KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > caucho > quercus > env > Value


1 /*
2  * Copyright (c) 1998-2006 Caucho Technology -- all rights reserved
3  *
4  * This file is part of Resin(R) Open Source
5  *
6  * Each copy or derived work must preserve the copyright notice and this
7  * notice unmodified.
8  *
9  * Resin Open Source is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * Resin Open Source is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
17  * of NON-INFRINGEMENT. See the GNU General Public License for more
18  * details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with Resin Open Source; if not, write to the
22  *
23  * Free Software Foundation, Inc.
24  * 59 Temple Place, Suite 330
25  * Boston, MA 02111-1307 USA
26  *
27  * @author Scott Ferguson
28  */

29
30 package com.caucho.quercus.env;
31
32 import com.caucho.quercus.QuercusException;
33 import com.caucho.quercus.QuercusRuntimeException;
34 import com.caucho.quercus.expr.Expr;
35 import com.caucho.quercus.program.AbstractFunction;
36 import com.caucho.util.L10N;
37 import com.caucho.vfs.WriteStream;
38
39 import java.io.IOException JavaDoc;
40 import java.io.InputStream JavaDoc;
41 import java.io.PrintWriter JavaDoc;
42 import java.net.MalformedURLException JavaDoc;
43 import java.net.URL JavaDoc;
44 import java.util.Calendar JavaDoc;
45 import java.util.Collection JavaDoc;
46 import java.util.Date JavaDoc;
47 import java.util.IdentityHashMap JavaDoc;
48 import java.util.List JavaDoc;
49 import java.util.Map JavaDoc;
50
51 /**
52  * Represents a PHP expression value.
53  */

54 abstract public class Value {
55   protected static final L10N L = new L10N(Value.class);
56
57   public static final StringValue SCALAR_V = new StringValueImpl("scalar");
58
59   public static final Value []NULL_VALUE_ARRAY = new Value[0];
60   public static final Value []NULL_ARGS = new Value[0];
61
62   //
63
// Properties
64
//
65

66   public QuercusClass getQuercusClass()
67   {
68     return null;
69   }
70
71   /**
72    * Returns the value's class name.
73    */

74   public String JavaDoc getClassName()
75   {
76     QuercusClass qClass = getQuercusClass();
77
78     if (qClass != null)
79       return qClass.getName();
80
81     return getType();
82   }
83
84   //
85
// Predicates and Relations
86
//
87

88   /**
89    * Returns true for an implementation of a class
90    */

91   public boolean isA(String JavaDoc name)
92   {
93     return false;
94   }
95
96   /**
97    * Returns true for an array.
98    */

99   public boolean isArray()
100   {
101     return false;
102   }
103
104   /**
105    * Returns true for a double-value.
106    */

107   public boolean isDoubleConvertible()
108   {
109     return false;
110   }
111
112   /**
113    * Returns true for a long-value.
114    */

115   public boolean isLongConvertible()
116   {
117     return false;
118   }
119
120   /**
121    * Returns true for a null.
122    */

123   public boolean isNull()
124   {
125     return false;
126   }
127
128   /**
129    * Returns true for a number.
130    */

131   public boolean isNumberConvertible()
132   {
133     return isLongConvertible() || isDoubleConvertible();
134   }
135
136   /**
137    * Matches is_numeric
138    */

139   public boolean isNumeric()
140   {
141     return false;
142   }
143
144   /**
145    * Returns true for an object.
146    */

147   public boolean isObject()
148   {
149     return false;
150   }
151
152   /**
153    * Returns true for a set type.
154    */

155   public boolean isset()
156   {
157     return true;
158   }
159
160   /**
161    * Returns true for a StringValue.
162    */

163   public boolean isString()
164   {
165     return false;
166   }
167
168   /**
169    * Returns true for a BinaryValue.
170    */

171   public boolean isBinary()
172   {
173     return false;
174   }
175
176   /**
177    * Returns true for a UnicodeValue.
178    */

179   public boolean isUnicode()
180   {
181     return false;
182   }
183
184   /**
185    * Returns true if there are more elements.
186    */

187   public boolean hasCurrent()
188   {
189     return false;
190   }
191
192   /**
193    * Returns true for equality
194    */

195   public Value eqValue(Value rValue)
196   {
197     return eq(rValue) ? BooleanValue.TRUE : BooleanValue.FALSE;
198   }
199
200   /**
201    * Returns true for equality
202    */

203   public boolean eq(Value rValue)
204   {
205     if (rValue instanceof BooleanValue)
206       return toBoolean() == rValue.toBoolean();
207     else if (isLongConvertible() && rValue.isLongConvertible())
208       return toLong() == rValue.toLong();
209     else if (isNumberConvertible() || rValue.isNumberConvertible())
210       return toDouble() == rValue.toDouble();
211     else
212       return toString().equals(rValue.toString());
213   }
214
215   /**
216    * Returns true for equality
217    */

218   public boolean eql(Value rValue)
219   {
220     return this == rValue.toValue();
221   }
222
223   /**
224    * Returns a negative/positive integer if this Value is
225    * lessthan/greaterthan rValue.
226    */

227   public int cmp(Value rValue)
228   {
229     // This is tricky: implemented according to Table 15-5 of
230
// http://us2.php.net/manual/en/language.operators.comparison.php
231

232     Value lVal = toValue();
233     Value rVal = rValue.toValue();
234
235     if (lVal instanceof StringValue && rVal instanceof NullValue)
236       return ((StringValue)lVal).cmpString(StringValue.EMPTY);
237     if (lVal instanceof NullValue && rVal instanceof StringValue)
238       return StringValue.EMPTY.cmpString((StringValue)rVal);
239     if (lVal instanceof StringValue && rVal instanceof StringValue)
240       return ((StringValue)lVal).cmpString((StringValue)rVal);
241
242     if (lVal instanceof NullValue || lVal instanceof BooleanValue ||
243     rVal instanceof NullValue || rVal instanceof BooleanValue) {
244       boolean thisBool = toBoolean();
245       boolean rBool = rValue.toBoolean();
246       if (!thisBool && rBool) return -1;
247       if (thisBool && !rBool) return 1;
248       return 0;
249     }
250
251     // XXX: check if values belong to same class; if not, incomparable
252
if (lVal instanceof ObjectValue && rVal instanceof ObjectValue)
253       return ((ObjectValue)lVal).cmpObject((ObjectValue)rVal);
254
255     if ((lVal instanceof StringValue || lVal instanceof NumberValue ||
256      lVal instanceof ResourceValue) &&
257     (rVal instanceof StringValue || rVal instanceof NumberValue ||
258      rVal instanceof ResourceValue))
259       return NumberValue.compareNum(lVal, rVal);
260
261     if (lVal instanceof ArrayValue && rVal instanceof ArrayValue)
262       ((ArrayValue)lVal).compareArray((ArrayValue)rVal);
263
264     if (lVal instanceof ArrayValue) return 1;
265     if (rVal instanceof ArrayValue) return -1;
266     if (lVal instanceof ObjectValue) return 1;
267     if (rVal instanceof ObjectValue) return -1;
268
269     // XXX: proper default case?
270
throw new RuntimeException JavaDoc("values are incomparable: " +
271                    lVal + " <=> " + rVal);
272   }
273
274   /**
275    * Returns true for less than
276    */

277   public final boolean lt(Value rValue)
278   {
279     return cmp(rValue)<0;
280   }
281
282   /**
283    * Returns true for less than or equal to
284    */

285   public final boolean leq(Value rValue)
286   {
287     return cmp(rValue)<=0;
288   }
289
290   /**
291    * Returns true for greater than
292    */

293   public final boolean gt(Value rValue)
294   {
295     return cmp(rValue)>0;
296   }
297
298   /**
299    * Returns true for greater than or equal to
300    */

301   public final boolean geq(Value rValue)
302   {
303     return cmp(rValue)>=0;
304   }
305
306   //
307
// Conversions
308
//
309

310   /**
311    * Converts to a boolean.
312    */

313   public boolean toBoolean()
314   {
315     return true;
316   }
317
318   /**
319    * Converts to a long.
320    */

321   public long toLong()
322   {
323     return toBoolean() ? 1 : 0;
324   }
325
326   /**
327    * Converts to an int
328    */

329   public int toInt()
330   {
331     return (int) toLong();
332   }
333
334   /**
335    * Converts to a double.
336    */

337   public double toDouble()
338   {
339     return 0;
340   }
341
342   /**
343    * Converts to a char
344    */

345   public char toChar()
346   {
347     String JavaDoc s = toString();
348
349     if (s == null || s.length() < 1)
350       return 0;
351     else
352       return s.charAt(0);
353   }
354
355   /**
356    * Converts to a string.
357    *
358    * @param env
359    */

360   public StringValue toString(Env env)
361   {
362     return toStringValue();
363   }
364
365   /**
366    * Converts to an array.
367    */

368   public Value toArray()
369   {
370     return new ArrayValueImpl().append(this);
371   }
372
373   /**
374    * Converts to an array if null.
375    */

376   public Value toAutoArray()
377   {
378     return this;
379   }
380
381   /**
382    * Casts to an array.
383    */

384   public ArrayValue toArrayValue(Env env)
385   {
386     env.warning(L.l("'{0}' ({1}) is not assignable to ArrayValue",
387           this, getType()));
388
389     return null;
390   }
391
392   /**
393    * Converts to an object if null.
394    */

395   public Value toAutoObject(Env env)
396   {
397     return this;
398   }
399
400   /**
401    * Converts to an object.
402    */

403   public Value toObject(Env env)
404   {
405     return env.createObject();
406   }
407
408   public CompiledObjectValue toObjectValue()
409   {
410     return null;
411   }
412
413   /**
414    * Converts to a java object.
415    */

416   public Object JavaDoc toJavaObject()
417   {
418     return null;
419   }
420
421   /**
422    * Converts to a java object.
423    */

424   public Object JavaDoc toJavaObject(Env env, Class JavaDoc type)
425   {
426     env.warning(L.l("Can't convert {0} to Java {1}",
427             getClass().getName(), type.getName()));
428     
429     return null;
430   }
431
432   /**
433    * Converts to a java object.
434    */

435   public Object JavaDoc toJavaObjectNotNull(Env env, Class JavaDoc type)
436   {
437     env.warning(L.l("Can't convert {0} to Java {1}",
438             getClass().getName(), type.getName()));
439     
440     return null;
441   }
442
443   /**
444    * Converts to a java boolean object.
445    */

446   public Boolean JavaDoc toJavaBoolean()
447   {
448     return toBoolean() ? Boolean.FALSE : Boolean.TRUE;
449   }
450
451   /**
452    * Converts to a java byte object.
453    */

454   public Byte JavaDoc toJavaByte()
455   {
456     return new Byte JavaDoc((byte) toLong());
457   }
458
459   /**
460    * Converts to a java short object.
461    */

462   public Short JavaDoc toJavaShort()
463   {
464     return new Short JavaDoc((short) toLong());
465   }
466
467   /**
468    * Converts to a java Integer object.
469    */

470   public Integer JavaDoc toJavaInteger()
471   {
472     return new Integer JavaDoc((int) toLong());
473   }
474
475   /**
476    * Converts to a java Long object.
477    */

478   public Long JavaDoc toJavaLong()
479   {
480     return new Long JavaDoc((int) toLong());
481   }
482
483   /**
484    * Converts to a java Float object.
485    */

486   public Float JavaDoc toJavaFloat()
487   {
488     return new Float JavaDoc((float) toDouble());
489   }
490
491   /**
492    * Converts to a java Double object.
493    */

494   public Double JavaDoc toJavaDouble()
495   {
496     return new Double JavaDoc(toDouble());
497   }
498
499   /**
500    * Converts to a java Character object.
501    */

502   public Character JavaDoc toJavaCharacter()
503   {
504     return new Character JavaDoc(toChar());
505   }
506
507   /**
508    * Converts to a java String object.
509    */

510   public String JavaDoc toJavaString()
511   {
512     return toString();
513   }
514
515   /**
516    * Converts to a java Collection object.
517    */

518   public Collection JavaDoc toJavaCollection(Env env, Class JavaDoc type)
519   {
520     env.warning(L.l("Can't convert {0} to Java {1}",
521             getClass().getName(), type.getName()));
522     
523     return null;
524   }
525   
526   /**
527    * Converts to a java List object.
528    */

529   public List JavaDoc toJavaList(Env env, Class JavaDoc type)
530   {
531     env.warning(L.l("Can't convert {0} to Java {1}",
532             getClass().getName(), type.getName()));
533     
534     return null;
535   }
536   
537   /**
538    * Converts to a java Map object.
539    */

540   public Map JavaDoc toJavaMap(Env env, Class JavaDoc type)
541   {
542     env.warning(L.l("Can't convert {0} to Java {1}",
543             getClass().getName(), type.getName()));
544     
545     return null;
546   }
547
548   /**
549    * Converts to a Java Calendar.
550    */

551   public Calendar JavaDoc toJavaCalendar()
552   {
553     Calendar JavaDoc cal = Calendar.getInstance();
554     
555     cal.setTimeInMillis(toLong());
556     
557     return cal;
558   }
559   
560   /**
561    * Converts to a Java Date.
562    */

563   public Date JavaDoc toJavaDate()
564   {
565     return new Date JavaDoc(toLong());
566   }
567   
568   /**
569    * Converts to a Java URL.
570    */

571   public URL JavaDoc toJavaURL(Env env)
572   {
573     try {
574       return new URL JavaDoc(toString());
575     }
576     catch (MalformedURLException JavaDoc e) {
577       env.warning(L.l(e.getMessage()));
578       return null;
579     }
580   }
581
582   /**
583    * Converts to an exception.
584    */

585   public QuercusException toException(Env env, String JavaDoc file, int line)
586   {
587     putField(env, "file", new StringValueImpl(file));
588     putField(env, "line", LongValue.create(line));
589     
590     return new QuercusLanguageException(this);
591   }
592
593   /**
594    * Converts to a raw value.
595    */

596   public Value toValue()
597   {
598     return this;
599   }
600
601   /**
602    * Converts to a key.
603    */

604   public Value toKey()
605   {
606     throw new QuercusRuntimeException(L.l("{0} is not a valid key", this));
607   }
608
609   /**
610    * Convert to a ref.
611    */

612   public Value toRef()
613   {
614     return this;
615   }
616
617   /**
618    * Convert to a function argument value, e.g. for
619    *
620    * function foo($a)
621    *
622    * where $a is never assigned or modified
623    */

624   public Value toArgValueReadOnly()
625   {
626     return this;
627   }
628
629   /**
630    * Convert to a function argument value, e.g. for
631    *
632    * function foo($a)
633    *
634    * where $a is never assigned, but might be modified, e.g. $a[3] = 9
635    */

636   public Value toArgValue()
637   {
638     return this;
639   }
640
641   /**
642    * Convert to a function argument reference value, e.g. for
643    *
644    * function foo(&$a)
645    *
646    * where $a is never assigned in the function
647    */

648   public Value toRefValue()
649   {
650     return this;
651   }
652
653   /**
654    * Convert to a function argument value, e.g. for
655    *
656    * function foo($a)
657    *
658    * where $a is used as a variable in the function
659    */

660   public Var toVar()
661   {
662     return new Var(toArgValue());
663   }
664
665   /**
666    * Convert to a function argument reference value, e.g. for
667    *
668    * function foo(&$a)
669    *
670    * where $a is used as a variable in the function
671    */

672   public Var toRefVar()
673   {
674     return new Var(this);
675   }
676
677   /**
678    * Converts to a StringValue.
679    */

680   public StringValue toStringValue()
681   {
682     return new StringValueImpl(toString());
683   }
684
685   /**
686    * Converts to a UnicodeValue.
687    */

688   public UnicodeValue toUnicodeValue(Env env)
689   {
690     return new StringValueImpl(toString());
691   }
692
693   /**
694    * Converts to a BinaryValue.
695    */

696   public BinaryValue toBinaryValue(Env env)
697   {
698     try {
699       InputStream JavaDoc is = toInputStream();
700
701       BinaryBuilderValue bb = new BinaryBuilderValue();
702
703       int length = 0;
704       while (true) {
705         bb.prepareReadBuffer();
706
707         int sublen = is.read(bb.getBuffer(),
708                              bb.getOffset(),
709                              bb.getLength() - bb.getOffset());
710
711         if (sublen <= 0)
712           return bb;
713         else {
714           length += sublen;
715           bb.setOffset(length);
716         }
717       }
718     } catch (IOException JavaDoc e) {
719       throw new QuercusException(e);
720     }
721   }
722
723   /**
724    * Returns a byteArrayInputStream for the value.
725    * See TempBufferStringValue for how this can be overriden
726    *
727    * @return InputStream
728    */

729   public InputStream JavaDoc toInputStream()
730   {
731     return new StringInputStream(toString());
732   }
733
734   /**
735    * Converts to a string builder
736    */

737   public StringValue toStringBuilder()
738   {
739     return new StringBuilderValue(toString(), 32);
740   }
741
742   /**
743    * Converts to a long vaule
744    */

745   public Value toLongValue()
746   {
747     return new LongValue(toLong());
748   }
749
750   /**
751    * Converts to a double vaule
752    */

753   public Value toDoubleValue()
754   {
755     return new DoubleValue(toDouble());
756   }
757
758   //
759
// Operations
760
//
761

762   /**
763    * Append to a string builder.
764    */

765   public void appendTo(StringBuilderValue sb)
766   {
767     //System.out.println("APPEND: " + toString());
768
sb.append(toString());
769   }
770
771   /**
772    * Append to a binary builder.
773    */

774   public void appendTo(BinaryBuilderValue sb)
775   {
776     sb.appendBytes(toString());
777   }
778
779   /**
780    * Copy for assignment.
781    */

782   public Value copy()
783   {
784     return this;
785   }
786
787   /**
788    * Copy as an array item
789    */

790   public Value copyArrayItem()
791   {
792     return copy();
793   }
794
795   /**
796    * Copy as a return value
797    */

798   public Value copyReturn()
799   {
800     // php/3a5d
801

802     return this;
803   }
804
805   /**
806    * Copy for serialization
807    */

808   public final Value copy(Env env)
809   {
810     return copy(env, new IdentityHashMap JavaDoc<Value,Value>());
811   }
812
813   /**
814    * Copy for serialization
815    */

816   public Value copy(Env env, IdentityHashMap JavaDoc<Value,Value> map)
817   {
818     return this;
819   }
820
821   /**
822    * Clone for the clone keyword
823    */

824   public Value clone()
825   {
826     return this;
827   }
828
829   /**
830    * Returns the type.
831    */

832   public String JavaDoc getType()
833   {
834     return "value";
835   }
836
837   /**
838    * Returns the current key
839    */

840   public Value key()
841   {
842     return NullValue.NULL;
843   }
844
845   /**
846    * Returns the current value
847    */

848   public Value current()
849   {
850     return NullValue.NULL;
851   }
852
853   /**
854    * Returns the current value
855    */

856   public Value next()
857   {
858     return BooleanValue.FALSE;
859   }
860
861   /**
862    * Finds the method name.
863    */

864   public AbstractFunction findFunction(String JavaDoc methodName)
865   {
866     return null;
867   }
868
869   /**
870    * Evaluates a method.
871    */

872   public Value callMethod(Env env, String JavaDoc methodName, Expr []args)
873   {
874     Value []value = new Value[args.length];
875
876     for (int i = 0; i < args.length; i++) {
877       value[i] = args[i].eval(env);
878     }
879
880     return callMethod(env, methodName, value);
881   }
882
883   /**
884    * Evaluates a method.
885    */

886   public Value callMethod(Env env, String JavaDoc methodName, Value []args)
887   {
888     switch (args.length) {
889     case 0:
890       return callMethod(env, methodName);
891
892     case 1:
893       return callMethod(env, methodName, args[0]);
894
895     case 2:
896       return callMethod(env, methodName, args[0], args[1]);
897
898     case 3:
899       return callMethod(env, methodName, args[0], args[1], args[2]);
900
901     case 4:
902       return callMethod(env, methodName, args[0], args[1], args[2],
903             args[3]);
904
905     case 5:
906       return callMethod(env, methodName, args[0], args[1], args[2],
907             args[3], args[4]);
908
909     default:
910       return errorNoMethod(env, methodName);
911     }
912   }
913
914   /**
915    * Evaluates a method with 0 args.
916    */

917   public Value callMethod(Env env, String JavaDoc methodName)
918   {
919     return errorNoMethod(env, methodName);
920   }
921
922   /**
923    * Evaluates a method with 1 arg.
924    */

925   public Value callMethod(Env env, String JavaDoc methodName, Value a0)
926   {
927     return errorNoMethod(env, methodName);
928   }
929
930   /**
931    * Evaluates a method with 1 arg.
932    */

933   public Value callMethod(Env env, String JavaDoc methodName, Value a0, Value a1)
934   {
935     return errorNoMethod(env, methodName);
936   }
937
938   /**
939    * Evaluates a method with 3 args.
940    */

941   public Value callMethod(Env env, String JavaDoc methodName,
942               Value a0, Value a1, Value a2)
943   {
944     return errorNoMethod(env, methodName);
945   }
946
947   /**
948    * Evaluates a method with 4 args.
949    */

950   public Value callMethod(Env env, String JavaDoc methodName,
951               Value a0, Value a1, Value a2, Value a3)
952   {
953     return errorNoMethod(env, methodName);
954   }
955
956   /**
957    * Evaluates a method with 5 args.
958    */

959   public Value callMethod(Env env, String JavaDoc methodName,
960               Value a0, Value a1, Value a2, Value a3, Value a5)
961   {
962     return errorNoMethod(env, methodName);
963   }
964
965   private Value errorNoMethod(Env env, String JavaDoc methodName)
966   {
967     return env.error(L.l("{0}: '{1}' is an unknown method.",
968              toDebugString(), methodName));
969   }
970
971   /**
972    * Evaluates a method.
973    */

974   public Value callMethodRef(Env env, String JavaDoc methodName, Expr []args)
975   {
976     Value []value = new Value[args.length];
977
978     for (int i = 0; i < args.length; i++) {
979       value[i] = args[i].eval(env);
980     }
981
982     return callMethodRef(env, methodName, value);
983   }
984
985   /**
986    * Evaluates a method.
987    */

988   public Value callMethodRef(Env env, String JavaDoc methodName, Value []args)
989   {
990     switch (args.length) {
991     case 0:
992       return callMethodRef(env, methodName);
993
994     case 1:
995       return callMethodRef(env, methodName, args[0]);
996
997     case 2:
998       return callMethodRef(env, methodName, args[0], args[1]);
999
1000    case 3:
1001      return callMethodRef(env, methodName, args[0], args[1], args[2]);
1002
1003    case 4:
1004      return callMethodRef(env, methodName, args[0], args[1], args[2],
1005            args[3]);
1006
1007    case 5:
1008      return callMethodRef(env, methodName, args[0], args[1], args[2],
1009            args[3], args[4]);
1010
1011    default:
1012      return env.error(L.l("{0}: '{1}' is an unknown method.",
1013               toString(), methodName));
1014    }
1015  }
1016
1017  /**
1018   * Evaluates a method with 0 args.
1019   */

1020  public Value callMethodRef(Env env, String JavaDoc methodName)
1021  {
1022    return env.error(L.l("{0}: '{1}' is an unknown method.",
1023             toString(), methodName));
1024  }
1025
1026  /**
1027   * Evaluates a method with 1 arg.
1028   */

1029  public Value callMethodRef(Env env, String JavaDoc methodName, Value a0)
1030  {
1031    return env.error(L.l("{0}: '{1}' is an unknown method.",
1032             toString(), methodName));
1033  }
1034
1035  /**
1036   * Evaluates a method with 1 arg.
1037   */

1038  public Value callMethodRef(Env env, String JavaDoc methodName, Value a0, Value a1)
1039  {
1040    return env.error(L.l("{0}: '{1}' is an unknown method.",
1041             toString(), methodName));
1042  }
1043
1044  /**
1045   * Evaluates a method with 3 args.
1046   */

1047  public Value callMethodRef(Env env, String JavaDoc methodName,
1048              Value a0, Value a1, Value a2)
1049  {
1050    return env.error(L.l("{0}: '{1}' is an unknown method.",
1051             toString(), methodName));
1052  }
1053
1054  /**
1055   * Evaluates a method with 4 args.
1056   */

1057  public Value callMethodRef(Env env, String JavaDoc methodName,
1058              Value a0, Value a1, Value a2, Value a3)
1059  {
1060    return env.error(L.l("{0}: '{1}' is an unknown method.",
1061             toString(), methodName));
1062  }
1063
1064  /**
1065   * Evaluates a method with 5 args.
1066   */

1067  public Value callMethodRef(Env env, String JavaDoc methodName,
1068              Value a0, Value a1, Value a2, Value a3, Value a5)
1069  {
1070    return env.error(L.l("{0}: '{1}' is an unknown method.",
1071             toString(), methodName));
1072  }
1073
1074  /**
1075   * Evaluates a method.
1076   */

1077  public Value callClassMethod(Env env, AbstractFunction fun, Value []args)
1078  {
1079    return NullValue.NULL;
1080  }
1081
1082  //
1083
// Arithmetic operations
1084
//
1085

1086  /**
1087   * Negates the value.
1088   */

1089  public Value neg()
1090  {
1091    return new LongValue(- toLong());
1092  }
1093
1094  /**
1095   * Negates the value.
1096   */

1097  public Value pos()
1098  {
1099    return new LongValue(toLong());
1100  }
1101
1102  /**
1103   * Adds to the following value.
1104   */

1105  public Value add(Value rValue)
1106  {
1107    if (isLongConvertible() && rValue.isLongConvertible())
1108      return LongValue.create(toLong() + rValue.toLong());
1109    
1110    return DoubleValue.create(toDouble() + rValue.toDouble());
1111  }
1112
1113  /**
1114   * Multiplies to the following value.
1115   */

1116  public Value add(long lLong)
1117  {
1118    return new DoubleValue(lLong + toDouble());
1119  }
1120
1121  /**
1122   * Pre-increment the following value.
1123   */

1124  public Value preincr(int incr)
1125  {
1126    long lValue = toLong();
1127
1128    return new LongValue(lValue + incr);
1129  }
1130
1131  /**
1132   * Post-increment the following value.
1133   */

1134  public Value postincr(int incr)
1135  {
1136    long lValue = toLong();
1137
1138    return new LongValue(lValue + incr);
1139  }
1140
1141  /**
1142   * Subtracts to the following value.
1143   */

1144  public Value sub(Value rValue)
1145  {
1146    if (isLongConvertible() && rValue.isLongConvertible())
1147      return LongValue.create(toLong() - rValue.toLong());
1148    return DoubleValue.create(toDouble() - rValue.toDouble());
1149  }
1150
1151  /**
1152   * Subtracts
1153   */

1154  public Value sub(long rLong)
1155  {
1156    return new DoubleValue(toDouble() - rLong);
1157  }
1158
1159
1160  /**
1161   * Substracts from the previous value.
1162   */

1163  public Value sub_rev(long lLong)
1164  {
1165    return new DoubleValue(lLong - toDouble());
1166  }
1167
1168  /**
1169   * Multiplies to the following value.
1170   */

1171  public Value mul(Value rValue)
1172  {
1173    return new DoubleValue(toDouble() * rValue.toDouble());
1174  }
1175
1176  /**
1177   * Multiplies to the following value.
1178   */

1179  public Value mul(long lLong)
1180  {
1181    return new DoubleValue(toDouble() * lLong);
1182  }
1183
1184  /**
1185   * Divides the following value.
1186   */

1187  public Value div(Value rValue)
1188  {
1189    double lDouble = toDouble();
1190    double rDouble = rValue.toDouble();
1191
1192    return new DoubleValue(lDouble / rDouble);
1193  }
1194
1195  /**
1196   * modulo the following value.
1197   */

1198  public Value mod(Value rValue)
1199  {
1200    double lDouble = toDouble();
1201    double rDouble = rValue.toDouble();
1202
1203    return LongValue.create((long) lDouble % rDouble);
1204  }
1205
1206  /**
1207   * Shifts left by the value.
1208   */

1209  public Value lshift(Value rValue)
1210  {
1211    long lLong = toLong();
1212    long rLong = rValue.toLong();
1213
1214    return new LongValue(lLong << rLong);
1215  }
1216
1217  /**
1218   * Shifts right by the value.
1219   */

1220  public Value rshift(Value rValue)
1221  {
1222    long lLong = toLong();
1223    long rLong = rValue.toLong();
1224
1225    return new LongValue(lLong >> rLong);
1226  }
1227
1228  //
1229
// string functions
1230
//
1231

1232  /**
1233   * Returns the length as a string.
1234   */

1235  public int length()
1236  {
1237    return toString().length();
1238  }
1239
1240  //
1241
// Array functions
1242
//
1243

1244  /**
1245   * Returns the array size.
1246   */

1247  public int getSize()
1248  {
1249    return 1;
1250  }
1251
1252  /**
1253   * Returns the field values.
1254   */

1255  public Collection JavaDoc<Value> getIndices()
1256  {
1257    return new java.util.ArrayList JavaDoc<Value>();
1258  }
1259
1260  /**
1261   * Returns the field keys.
1262   */

1263  public Value []getKeyArray()
1264  {
1265    return NULL_VALUE_ARRAY;
1266  }
1267
1268  /**
1269   * Returns the field values.
1270   */

1271  public Value []getValueArray(Env env)
1272  {
1273    return NULL_VALUE_ARRAY;
1274  }
1275
1276  /**
1277   * Returns the array ref.
1278   */

1279  public Value get(Value index)
1280  {
1281    return NullValue.NULL;
1282  }
1283
1284  /**
1285   * Returns a reference to the array value.
1286   */

1287  public Value getRef(Value index)
1288  {
1289    return NullValue.NULL;
1290  }
1291
1292  /**
1293   * Returns the array ref as a function argument.
1294   */

1295  public Value getArg(Value index)
1296  {
1297    return NullValue.NULL;
1298  }
1299
1300  /**
1301   * Returns the array value, copying on write if necessary.
1302   */

1303  public Value getDirty(Value index)
1304  {
1305    return NullValue.NULL;
1306  }
1307
1308  /**
1309   * Returns the array ref for an argument.
1310   */

1311  public Value getArgRef(Value index)
1312  {
1313    return getRef(index);
1314  }
1315
1316  /**
1317   * Returns the value for a field, creating an array if the field
1318   * is unset.
1319   */

1320  public Value getArray()
1321  {
1322    return this;
1323  }
1324
1325  /**
1326   * Returns the value for a field, creating an array if the field
1327   * is unset.
1328   */

1329  public Value getArray(Value index)
1330  {
1331    return NullValue.NULL;
1332  }
1333
1334  //
1335
// Object operations
1336
//
1337

1338  /**
1339   * Returns the field ref.
1340   */

1341  public Value getField(Env env, String JavaDoc index)
1342  {
1343    return NullValue.NULL;
1344  }
1345
1346  /**
1347   * Returns the field ref.
1348   */

1349  public Value getFieldRef(Env env, String JavaDoc index)
1350  {
1351    return getField(env, index);
1352  }
1353
1354  /**
1355   * Returns the field ref.
1356   */

1357  public Value getFieldArg(Env env, String JavaDoc index)
1358  {
1359    return getFieldRef(env, index);
1360  }
1361
1362  /**
1363   * Returns the field ref for an argument.
1364   */

1365  public Value getFieldArgRef(Env env, String JavaDoc index)
1366  {
1367    return getFieldRef(env, index);
1368  }
1369
1370  /**
1371   * Returns the value for a field, creating an object if the field
1372   * is unset.
1373   */

1374  public Value getFieldObject(Env env, String JavaDoc index)
1375  {
1376    Value v = getField(env, index);
1377
1378    if (! v.isset()) {
1379      v = env.createObject();
1380
1381      putField(env, index, v);
1382    }
1383
1384    return v;
1385  }
1386
1387  /**
1388   * Returns the value for a field, creating an object if the field
1389   * is unset.
1390   */

1391  public Value getFieldArray(Env env, String JavaDoc index)
1392  {
1393    Value v = getField(env, index);
1394
1395    Value array = v.toAutoArray();
1396
1397    if (v == array)
1398      return v;
1399    else {
1400      putField(env, index, array);
1401
1402      return array;
1403    }
1404  }
1405
1406  /**
1407   * Returns the field ref.
1408   */

1409  public Value putField(Env env, String JavaDoc index, Value object)
1410  {
1411    return NullValue.NULL;
1412  }
1413
1414  /**
1415   * Removes the field ref.
1416   */

1417  public void removeField(String JavaDoc index)
1418  {
1419  }
1420
1421  /**
1422   * Returns the value for the variable, creating an object if the var
1423   * is unset.
1424   */

1425  public Value getObject(Env env)
1426  {
1427    return NullValue.NULL;
1428  }
1429
1430  /**
1431   * Returns the value for a field, creating an object if the field
1432   * is unset.
1433   */

1434  public Value getObject(Env env, Value index)
1435  {
1436    return NullValue.NULL;
1437  }
1438
1439  /**
1440   * Sets the value ref.
1441   */

1442  public Value set(Value value)
1443  {
1444    return value;
1445  }
1446
1447  /**
1448   * Sets the array ref.
1449   */

1450  public Value put(Value index, Value value)
1451  {
1452    return value;
1453  }
1454
1455  /**
1456   * Sets the array ref.
1457   */

1458  public Value put(Value value)
1459  {
1460    return value;
1461  }
1462
1463  /**
1464   * Sets the array ref.
1465   */

1466  public Value putRef()
1467  {
1468    return NullValue.NULL;
1469  }
1470
1471  /**
1472   * Appends the array
1473   */

1474  public Value putArray()
1475  {
1476    ArrayValue value = new ArrayValueImpl();
1477
1478    put(value);
1479
1480    return value;
1481  }
1482
1483  /**
1484   * Appends a new object
1485   */

1486  public Value putObject(Env env)
1487  {
1488    Value value = env.createObject();
1489
1490    put(value);
1491
1492    return value;
1493  }
1494
1495  /**
1496   * Return unset the value.
1497   */

1498  public Value remove(Value index)
1499  {
1500    return UnsetValue.UNSET;
1501  }
1502  
1503  /**
1504   * Takes the values of this array, unmarshalls them to objects of type
1505   * <i>elementType</i>, and puts them in a java array.
1506   */

1507  public Object JavaDoc valuesToArray(Env env, Class JavaDoc elementType)
1508  {
1509    env.error(L.l("Can't assign {0} with type {1} to {2}[]", this, this.getClass(), elementType));
1510    return null;
1511  }
1512
1513  /**
1514   * Returns the character at the named index.
1515   */

1516  public Value charValueAt(long index)
1517  {
1518    return NullValue.NULL;
1519  }
1520
1521  /**
1522   * Sets the character at the named index.
1523   */

1524  public Value setCharValueAt(long index, String JavaDoc value)
1525  {
1526    return NullValue.NULL;
1527  }
1528
1529  /**
1530   * Prints the value.
1531   * @param env
1532   */

1533  public void print(Env env)
1534  {
1535    env.print(toString(env));
1536  }
1537
1538  /**
1539   * Serializes the value.
1540   */

1541  public void serialize(StringBuilder JavaDoc sb)
1542  {
1543    throw new UnsupportedOperationException JavaDoc(getClass().getName());
1544  }
1545
1546  /**
1547   * Exports the value.
1548   */

1549  public void varExport(StringBuilder JavaDoc sb)
1550  {
1551    throw new UnsupportedOperationException JavaDoc(getClass().getName());
1552  }
1553
1554  //
1555
// Java generator code
1556
//
1557

1558  /**
1559   * Generates code to recreate the expression.
1560   *
1561   * @param out the writer to the Java source code.
1562   */

1563  public void generate(PrintWriter JavaDoc out)
1564    throws IOException JavaDoc
1565  {
1566  }
1567
1568  protected void printJavaString(PrintWriter JavaDoc out, String JavaDoc s)
1569  {
1570    if (s == null) {
1571      out.print("");
1572      return;
1573    }
1574
1575    int len = s.length();
1576    for (int i = 0; i < len; i++) {
1577      char ch = s.charAt(i);
1578
1579      switch (ch) {
1580      case '\r':
1581    out.print("\\r");
1582    break;
1583      case '\n':
1584    out.print("\\n");
1585    break;
1586      case '\"':
1587    out.print("\\\"");
1588    break;
1589      case '\'':
1590    out.print("\\\'");
1591    break;
1592      case '\\':
1593    out.print("\\\\");
1594    break;
1595      default:
1596    out.print(ch);
1597    break;
1598      }
1599    }
1600  }
1601
1602  public String JavaDoc toInternString()
1603  {
1604    return toString().intern();
1605  }
1606
1607  public String JavaDoc toDebugString()
1608  {
1609    return toString();
1610  }
1611
1612  final public void varDump(Env env,
1613                            WriteStream out,
1614                            int depth,
1615                            IdentityHashMap JavaDoc<Value, String JavaDoc> valueSet)
1616    throws IOException JavaDoc
1617  {
1618    if (valueSet.get(this) != null) {
1619       out.print("#recursion#");
1620       return;
1621     }
1622
1623    valueSet.put(this, "printing");
1624
1625    try {
1626      varDumpImpl(env, out, depth, valueSet);
1627    }
1628    finally {
1629      valueSet.remove(this);
1630    }
1631  }
1632
1633  protected void varDumpImpl(Env env,
1634                             WriteStream out,
1635                             int depth,
1636                             IdentityHashMap JavaDoc<Value, String JavaDoc> valueSet)
1637    throws IOException JavaDoc
1638  {
1639    out.print(toString());
1640  }
1641
1642  final public void printR(Env env,
1643                           WriteStream out,
1644                           int depth,
1645                           IdentityHashMap JavaDoc<Value, String JavaDoc> valueSet)
1646    throws IOException JavaDoc
1647  {
1648    if (valueSet.get(this) != null) {
1649      out.print("#recursion#");
1650      return;
1651    }
1652
1653    valueSet.put(this, "printing");
1654
1655    try {
1656      printRImpl(env, out, depth, valueSet);
1657    }
1658    finally {
1659      valueSet.remove(this);
1660    }
1661  }
1662
1663  protected void printRImpl(Env env,
1664                            WriteStream out,
1665                            int depth,
1666                            IdentityHashMap JavaDoc<Value, String JavaDoc> valueSet)
1667    throws IOException JavaDoc
1668  {
1669    out.print(toString());
1670  }
1671
1672  protected void printDepth(WriteStream out, int depth)
1673    throws IOException JavaDoc
1674  {
1675    for (int i = 0; i < depth; i++)
1676      out.print(' ');
1677  }
1678}
1679
1680
Popular Tags