KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > openlaszlo > iv > flash > api > action > ASAssembler


1 /*
2  * ==========================================================================
3  *
4  * The JGenerator Software License, Version 1.0
5  *
6  * Copyright (c) 2000 Dmitry Skavish (skavish@usa.net). All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions are met:
10  *
11  * 1. Redistributions of source code must retain the above copyright
12  * notice, this list of conditions and the following disclaimer.
13  *
14  * 2. Redistributions in binary form must reproduce the above copyright
15  * notice, this list of conditions and the following disclaimer in
16  * the documentation and/or other materials provided with the
17  * distribution.
18  *
19  * 3. The end-user documentation included with the redistribution, if
20  * any, must include the following acknowlegement:
21  * "This product includes software developed by Dmitry Skavish
22  * (skavish@usa.net, http://www.flashgap.com/)."
23  * Alternately, this acknowlegement may appear in the software itself,
24  * if and wherever such third-party acknowlegements normally appear.
25  *
26  * 4. The name "The JGenerator" must not be used to endorse or promote
27  * products derived from this software without prior written permission.
28  * For written permission, please contact skavish@usa.net.
29  *
30  * 5. Products derived from this software may not be called "The JGenerator"
31  * nor may "The JGenerator" appear in their names without prior written
32  * permission of Dmitry Skavish.
33  *
34  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
35  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
36  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
37  * DISCLAIMED. IN NO EVENT SHALL DMITRY SKAVISH OR THE OTHER
38  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
39  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
40  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
41  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
42  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
43  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
44  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
45  * SUCH DAMAGE.
46  *
47  */

48
49 package org.openlaszlo.iv.flash.api.action;
50
51 import java.util.*;
52
53 import org.openlaszlo.iv.flash.util.*;
54 import org.openlaszlo.iv.flash.parser.*;
55 import org.openlaszlo.iv.flash.api.*;
56 import org.openlaszlo.iv.flash.context.Context;
57
58 /**
59  * ActionScript API assembler
60  * <P>
61  * Supports only Flash 5/MX actionscript.
62  *
63  * @author Dmitry Skavish
64  */

65 public class ASAssembler {
66
67     private HashMap pool = new HashMap();
68     private HashMap labels = new HashMap();
69     private IVVector forward_refs = new IVVector();
70     private IVVector delayed_stack = new IVVector();
71     private Program p = new Program();
72     private Stack funcs = new Stack();
73
74     /**
75      * Creates new assembler
76      * <P>
77      * Requires flash version 5+
78      *
79      * @param file flash file.
80      */

81     public ASAssembler( FlashFile file ) {
82         if( file.getVersion() < 5 ) {
83             Log.logRB(Resource.ASASMREQFLASH5);
84         }
85     }
86
87     /**
88      * Creates Program object from this assembler
89      *
90      * @return new Program object
91      */

92     public Program toProgram() {
93         flush_stack();
94         Program prog = new Program();
95         writePool(prog);
96         prog.body().writeFOB(p.body());
97         return prog;
98     }
99
100     /**
101      * Instructs the player to go to the next frame in the current movie.
102      */

103     public void nextFrame() {
104         flush_stack();
105         p.nextFrame();
106     }
107
108     /**
109      * Instructs the player to go to the previous frame in the current movie.
110      */

111     public void prevFrame() {
112         flush_stack();
113         p.prevFrame();
114     }
115
116     /**
117      * Instructs the player to start playing at the current frame.
118      */

119     public void play() {
120         flush_stack();
121         p.play();
122     }
123
124     /**
125      * Instructs the player to stop playing the movie at the current frame.
126      * @since flash 3
127      */

128     public void stop() {
129         flush_stack();
130         p.stop();
131     }
132
133     /**
134      * Toggle the display between high and low quality.
135      */

136     public void toggleQuality() {
137         flush_stack();
138         p.toggleQuality();
139     }
140
141     /**
142      * Instructs the player to stop playing all sounds.
143      */

144     public void stopSounds() {
145         flush_stack();
146         p.stopSounds();
147     }
148
149     public void trace() {
150         flush_stack();
151         p.body().writeByte(Actions.Trace);
152     }
153
154     /**
155      * Adds two values. Can be used for strings as well.
156      * <P>
157      * <OL>
158      * <LI>Pops value A off the stack.
159      * <LI>Pops value B off the stack.
160      * <LI>Pushes the result, A+B, to the stack.
161      * </OL>
162      */

163     public void add() {
164         flush_stack();
165         p.body().writeByte(Actions.Add2);
166     }
167
168     /**
169      * Subtracts two numbers.
170      * <P>
171      * <OL>
172      * <LI>Pops value A off the stack.
173      * <LI>Pops value B off the stack.
174      * <LI>A and B are converted to floating-point; non-numeric values evaluate to 0.
175      * <LI>A is subtracted from B.
176      * <LI>Pushes the result, A-B, to the stack.
177      * </OL>
178      */

179     public void subtract() {
180         flush_stack();
181         p.subtract();
182     }
183
184     /**
185      * Multiplies two numbers.
186      * <P>
187      * <OL>
188      * <LI>Pops value A off the stack.
189      * <LI>Pops value B off the stack.
190      * <LI>A and B are converted to floating-point; non-numeric values evaluate to 0.
191      * <LI>The numbers are multiplied.
192      * <LI>Pushes the result, A*B, to the stack.
193      * </OL>
194      */

195     public void multiply() {
196         flush_stack();
197         p.multiply();
198     }
199
200     /**
201      * Divides two numbers.
202      * <P>
203      * <OL>
204      * <LI>Pops value A off the stack.
205      * <LI>Pops value B off the stack.
206      * <LI>A and B are converted to floating-point; non-numeric values evaluate to 0.
207      * <LI>B is divided by A.
208      * <LI>Pushes the result, B/A, to the stack.
209      * <LI>If A is zero, the result is the string #ERROR#.
210      * </OL>
211      * Note: When playing a Flash 5 .SWF, NaN, Infinity or –Infinity is pushed to the stack instead of #ERROR#.
212      * @since flash 4
213      */

214     public void divide() {
215         flush_stack();
216         p.divide();
217     }
218
219     /**
220      * Tests two values for equality. Can be used for strings as well.
221      * <P>
222      * <OL>
223      * <LI>Pops value A off the stack.
224      * <LI>Pops value B off the stack.
225      * <LI>If the values are equal, a true is pushed to the stack.
226      * <LI>Otherwise, a false is pushed to the stack.
227      * </OL>
228      */

229     public void equal() {
230         flush_stack();
231         p.body().writeByte( Actions.Equals2 );
232     }
233
234     /**
235      * Tests if a value is less than another value. Can be used for strings as well.
236      * <P>
237      * <OL>
238      * <LI>Pops value A off the stack.
239      * <LI>Pops value B off the stack.
240      * <LI>The values are compared for equality.
241      * <LI>If B < A, a true is pushed to the stack; otherwise, a false is pushed to the stack.
242      * </OL>
243      */

244     public void less() {
245         flush_stack();
246         p.body().writeByte( Actions.Less2 );
247     }
248
249     /**
250      * Performs a logical AND of two numbers.
251      * <P>
252      * <OL>
253      * <LI>Pops value A off the stack.
254      * <LI>Pops value B off the stack.
255      * <LI>A and B are converted to floating-point; non-numeric values evaluate to 0.
256      * <LI>If both numbers are nonzero, a 1 is pushed to the stack; otherwise, a 0 is pushed to the stack.
257      * </OL>
258      * Note: When playing a Macromedia Flash 5 .SWF, true is pushed to the stack instead of 1,
259      * and false is pushed to the stack instead of 0.
260      * @since flash 4
261      */

262     public void logicalAnd() {
263         flush_stack();
264         p.logicalAnd();
265     }
266
267     /**
268      * Performs a logical OR of two numbers.
269      * <P>
270      * <OL>
271      * <LI>Pops value A off the stack.
272      * <LI>Pops value B off the stack.
273      * <LI>A and B are converted to floating-point; non-numeric values evaluate to 0.
274      * <LI>If either numbers is nonzero, a 1 is pushed to the stack; otherwise, a 0 is pushed to the stack.
275      * </OL>
276      * Note: When playing a Macromedia Flash 5 .SWF, true is pushed to the stack instead of 1,
277      * and false is pushed to the stack instead of 0.
278      * @since flash 4
279      */

280     public void logicalOr() {
281         flush_stack();
282         p.logicalOr();
283     }
284
285     /**
286      * Performs a logical NOT of a number.
287      * <P>
288      * Note that in Macromedia Flash 5 .SWF files, the ActionNot action
289      * converts its argument to a boolean, and pushes a result of type boolean.
290      * In Macromedia Flash 4 .SWF files, the argument and result are numbers.
291      * <P>
292      * <OL>
293      * <LI>Pops value A off the stack.
294      * <LI>Pops value B off the stack.
295      * <LI>A and B are converted to floating-point; non-numeric values evaluate to 0.
296      * <LI>The numbers are compared for equality.
297      * <LI>If the numbers are equal, a 1 (TRUE) is pushed to the stack.
298      * <LI>Otherwise, a 0 is pushed to the stack.
299      * </OL>
300      * Note: When playing a Macromedia Flash 5 .SWF, true is pushed to the stack instead of 1,
301      * and false is pushed to the stack instead of 0.
302      * @since flash 4
303      */

304     public void logicalNot() {
305         flush_stack();
306         p.logicalNot();
307     }
308
309     /**
310      * Tests two strings for equality.
311      * <P>
312      * <OL>
313      * <LI>Pops value A off the stack.
314      * <LI>Pops value B off the stack.
315      * <LI>A and B are compared as strings. The comparison is case-sensitive.
316      * <LI>If the strings are equal, a 1 (TRUE) is pushed to the stack.
317      * <LI>Otherwise, a 0 is pushed to the stack.
318      * </OL>
319      * Note: When playing a Macromedia Flash 5 .SWF, true is pushed to the stack instead of 1,
320      * and false is pushed to the stack instead of 0.
321      * @since flash 4
322      */

323     public void stringEqual() {
324         flush_stack();
325         p.stringEqual();
326     }
327
328     /**
329      * Computes the length of a string.
330      * <P>
331      * <OL>
332      * <LI>Pops a string off the stack.
333      * <LI>The length of the string is calculated and pushed to the stack.
334      * </OL>
335      * @since flash 4
336      */

337     public void stringLength() {
338         flush_stack();
339         p.stringLength();
340     }
341
342     /**
343      * Tests if a string is less than another string.
344      * <P>
345      * <OL>
346      * <LI>Pops value A off the stack.
347      * <LI>Pops value B off the stack.
348      * <LI>If B < A using a byte-by-byte comparison, a 1 is pushed to the stack;
349      * otherwise, a 0 is pushed to the stack.
350      * </OL>
351      * Note: When playing a Macromedia Flash 5 .SWF, true is pushed to the stack instead of 1,
352      * and false is pushed to the stack instead of 0.
353      * @since flash 4
354      */

355     public void stringLessThan() {
356         flush_stack();
357         p.stringLessThan();
358     }
359
360     /**
361      * Extracts a substring from a string.
362      * <P>
363      * <OL>
364      * <LI>Pops number <B>count</B> off the stack.
365      * <LI>Pops number <B>index</B> off the stack.
366      * <LI>Pops string <B>string</B> off the stack.
367      * <LI>The substring of <B>string</B> starting at the <B>index</B>’th character and
368      * <B>count</B> characters in length is pushed to the stack.
369      * <LI>If either <B>index</B> or <B>count</B> do not evaluate to integers, the result
370      * is the empty string.
371      * </OL>
372      * @since flash 4
373      */

374     public void subString() {
375         flush_stack();
376         p.subString();
377     }
378
379     /**
380      * Concatenates two strings.
381      * <P>
382      * <OL>
383      * <LI>Pops value A off the stack.
384      * <LI>Pops value B off the stack.
385      * <LI>The concatenation BA is pushed to the stack.
386      * </OL>
387      * @since flash 4
388      */

389     public void addString() {
390         flush_stack();
391         p.addString();
392     }
393
394     /**
395      * Computes the length of a string, multi-byte aware.
396      * <P>
397      * <OL>
398      * <LI>Pops a string off the stack.
399      * <LI>The length of the string in characters is calculated and pushed to the stack.
400      * <LI>This is a multi-byte aware version of ActionStringLength.
401      * On systems with double-byte support, a double-byte character is counted as a single character.
402      * </OL>
403      * @since flash 4
404      */

405     public void mbLength() {
406         flush_stack();
407         p.mbLength();
408     }
409
410     /**
411      * Converts ASCII to character code, multi-byte aware.
412      * <P>
413      * <OL>
414      * <LI>Pops value off the stack.
415      * <LI>The value is converted from a number to the corresponding character.
416      * If the character is a 16-bit value (>= 256), a double-byte character
417      * is constructed with the first byte containing the high-order byte,
418      * and the second byte containing the low-order byte.
419      * <LI>The resulting character is pushed to the stack.
420      * </OL>
421      * @since flash 4
422      */

423     public void mbChr() {
424         flush_stack();
425         p.mbChr();
426     }
427
428     /**
429      * Converts character code to ASCII, multi-byte aware.
430      * <P>
431      * <OL>
432      * <LI>Pops value off the stack.
433      * <LI>The first character of value is converted to a numeric character code.
434      * If the first character of value is a double-byte character, a 16-bit value
435      * is constructed with the first byte as the high order byte and the second byte
436      * as the low order byte.
437      * <LI>The resulting character code is pushed to the stack.
438      * </OL>
439      * @since flash 4
440      */

441     public void mbOrd() {
442         flush_stack();
443         p.mbOrd();
444     }
445
446     /**
447      * Extracts a substring from a string, multi-byte aware.
448      * <P>
449      * <OL>
450      * <LI>Pops number <B>count</B> off the stack.
451      * <LI>Pops number <B>index</B> off the stack.
452      * <LI>Pops string <B>string</B> off the stack.
453      * <LI>The substring of <B>string</B> starting at the <B>index</B>’th character and
454      * <B>count</B> characters in length is pushed to the stack.
455      * <LI>If either <B>index</B> or <B>count</B> do not evaluate to integers, the result
456      * is the empty string.
457      * <LI>This is a multi-byte aware version of ActionStringExtract. index and count are
458      * treated as character indices, counting double-byte characters as single characters.
459      * </OL>
460      * @since flash 4
461      */

462     public void mbSubString() {
463         flush_stack();
464         p.mbSubString();
465     }
466
467     /**
468      * Converts to integer.
469      * <P>
470      * <OL>
471      * <LI>Pops a value off the stack.
472      * <LI>The value is converted to a number.
473      * <LI>Next, any digits after the decimal point are discarded, resulting in an integer.
474      * <LI>The resulting integer is pushed to the stack.
475      * </OL>
476      * @since flash 4
477      */

478     public void toInt() {
479         flush_stack();
480         p.toInt();
481     }
482
483     /**
484      * Converts character code to ASCII.
485      * <P>
486      * <OL>
487      * <LI>Pops value off the stack.
488      * <LI>The first character of value is converted to a numeric ASCII character code.
489      * <LI>The resulting character code is pushed to the stack.
490      * </OL>
491      * @since flash 4
492      */

493     public void ord() {
494         flush_stack();
495         p.ord();
496     }
497
498     /**
499      * Converts ASCII to character code.
500      * <P>
501      * <OL>
502      * <LI>Pops value off the stack.
503      * <LI>The value is converted from a number to the corresponding ASCII character..
504      * <LI>The resulting character is pushed to the stack.
505      * </OL>
506      * @since flash 4
507      */

508     public void chr() {
509         flush_stack();
510         p.chr();
511     }
512
513     /**
514      * Gets a movie property
515      * <P>
516      * <OL>
517      * <LI>Pops index off the stack.
518      * <LI>Pops target off the stack.
519      * <LI>Retrieves the value of the property enumerated as index from
520      * the movie clip with target path target and pushes the value to the stack.
521      * </OL>
522      * @since flash 4
523      */

524     public void getProperty() {
525         flush_stack();
526         p.getProperty();
527     }
528
529     /**
530      * Gets a movie property. Leaves property value on the stack.
531      *
532      * @param target movie clip's target path
533      * @param property property index
534      */

535     public void getProperty( String JavaDoc target, int property ) {
536         push(target);
537         push(property);
538         getProperty();
539     }
540
541     /**
542      * Sets a movie property.
543      * <P>
544      * <OL>
545      * <LI>Pops value off the stack.
546      * <LI>Pops index off the stack.
547      * <LI>Pops target off the stack.
548      * <LI>Sets the property enumerated as index in the movie clip
549      * with target path target to the value value.
550      * </OL>
551      * @since flash 4
552      */

553     public void setProperty() {
554         flush_stack();
555         p.setProperty();
556     }
557
558     /**
559      * Sets property on specified movie clip.
560      *
561      * @param target movie clip's target path
562      * @param property property index
563      * @param value property value
564      */

565     public void setProperty( String JavaDoc target, int property, Object JavaDoc value ) {
566         push(target);
567         push(property);
568         push(value);
569         setProperty();
570     }
571
572     /**
573      * Clones a movie clip.
574      * <P>
575      * <OL>
576      * <LI>Pops depth off the stack (has to be added to 16384)
577      * <LI>Pops target off the stack.
578      * <LI>Pops source off the stack.
579      * <LI>Duplicates movie clip source, giving the new instance
580      * the name target, at z-order depth depth.
581      * </OL>
582      * @since flash 4
583      */

584     public void duplicateClip() {
585         flush_stack();
586         p.cloneClip();
587     }
588
589     /**
590      * Clones a movie clip.
591      *
592      * @param source source movie clip path
593      * @param target target name
594      * @param depth depth (z-order)
595      */

596     public void duplicateClip( String JavaDoc source, String JavaDoc target, int depth ) {
597         push(depth+16384);
598         push(target);
599         push(source);
600         duplicateClip();
601     }
602
603     /**
604      * Removes a movie clip.
605      * <P>
606      * <OL>
607      * <LI>Pops target off the stack.
608      * <LI>Removes the clone movie clip identified by target path target.
609      * </OL>
610      * @since flash 4
611      */

612     public void removeClip() {
613         flush_stack();
614         p.removeClip();
615     }
616
617     /**
618      * Removes a movie clip.
619      *
620      * @param target target movie clip path
621      */

622     public void removeClip( String JavaDoc target ) {
623         push(target);
624         removeClip();
625     }
626
627     /**
628      * Starts dragging a movie clip.
629      * <P>
630      * <OL>
631      * <LI>Pops target off the stack. target identifies the movie clip to be dragged.
632      * <LI>Pops lockcenter off the stack. If lockcenter evaluates to a nonzero value,
633      * the center of the dragged movie clip is locked to the mouse position.
634      * Otherwise, the movie clip moves relatively to the mouse position when
635      * the drag started.
636      * <LI>Pops constrain off the stack.
637      * <LI>If constrain evaluates to a nonzero value:
638      * <OL>
639      * <LI>Pops y2 off the stack.
640      * <LI>Pops x2 off the stack.
641      * <LI>Pops y1 off the stack.
642      * <LI>Pops x1 off the stack.
643      * </OL>
644      * </OL>
645      * @since flash 4
646      */

647     public void startDrag() {
648         flush_stack();
649         p.startDrag();
650     }
651
652     /**
653      * Ends drag operation.
654      * <P>
655      * <OL>
656      * <LI>Ends the drag operation in progress, if any.
657      * </OL>
658      * @since flash 4
659      */

660     public void endDrag() {
661         flush_stack();
662         p.endDrag();
663     }
664
665     /**
666      * Calculates a random number.
667      * <P>
668      * <OL>
669      * <LI>Pops maximum off the stack.
670      * <LI>Calculates a random number, an integer in the range 0 ... (maximum-1)
671      * <LI>This random number is pushed to the stack.
672      * </OL>
673      * @since flash 4
674      */

675     public void random() {
676         flush_stack();
677         p.random();
678     }
679
680     /**
681      * Calculates (pushes it to the stack) a random number in the range 0 .. (maximum-1)
682      *
683      * @param maximum maximum
684      */

685     public void random( int maximum ) {
686         push(maximum);
687         random();
688     }
689
690     /**
691      * Reports milliseconds since player started.
692      * <P>
693      * <OL>
694      * <LI>Calculates the number of milliseconds since the Player was started (an integer).
695      * <LI>This number is pushed to the stack.
696      * </OL>
697      * @since flash 4
698      */

699     public void getTimer() {
700         flush_stack();
701         p.getTimer();
702     }
703
704     /**
705      * Instructs the player to go to the specified frame in the current movie.
706      *
707      * @param frame frame number
708      * @since flash 3
709      */

710     public void gotoFrame( int frame ) {
711         flush_stack();
712         p.gotoFrame(frame);
713     }
714
715     /**
716      * Instructs the player to go to the specified frame in the current movie and play
717      *
718      * @param frame frame number
719      */

720     public void gotoFrameAndPlay( int frame ) {
721         p.gotoFrame(frame);
722         play();
723     }
724
725     /**
726      * Instructs the player to go to the specified frame in the current movie and stop
727      *
728      * @param frame frame number
729      */

730     public void gotoFrameAndStop( int frame ) {
731         gotoFrame(frame);
732         stop();
733     }
734
735     /**
736      * Go to frame and play, stack-based.
737      * <P>
738      * <OL>
739      * <LI>Pops <b>frame</b> off the stack.
740      * <LI>If <b>frame</b> is a number, the next frame of the movie to be displayed
741      * will be the <b>frame</b>’th frame in the current movie clip.
742      * <LI>If <b>frame</b> is a string, <b>frame</b> is treated as a frame label.
743      * If the specified label exists in the current movie clip,
744      * the labeled frame will become the current frame. Otherwise, the action is ignored.
745      * <LI>Either a frame or a number may be prefixed by a target path, e.g. /MovieClip:3 or /MovieClip:FrameLabel
746      * </OL>
747      * @since flash 4
748      */

749     public void gotoFrameAndPlay() {
750         flush_stack();
751         p.gotoFrameAndPlay();
752     }
753
754     /**
755      * Go to frame and stop, stack-based.
756      * <P>
757      * <OL>
758      * <LI>Pops <b>frame</b> off the stack.
759      * <LI>If <b>frame</b> is a number, the next frame of the movie to be displayed
760      * will be the <b>frame</b>’th frame in the current movie clip.
761      * <LI>If <b>frame</b> is a string, <b>frame</b> is treated as a frame label.
762      * If the specified label exists in the current movie clip,
763      * the labeled frame will become the current frame. Otherwise, the action is ignored.
764      * <LI>Either a frame or a number may be prefixed by a target path, e.g. /MovieClip:3 or /MovieClip:FrameLabel
765      * </OL>
766      * @since flash 4
767      */

768     public void gotoFrameAndStop() {
769         flush_stack();
770         p.gotoFrameAndStop();
771     }
772
773     /**
774      * Instructs the player to get the URL specified by UrlString.
775      * The URL can be of any type, including an HTML file, an image
776      * or another SWF movie. If the movie is playing in a browser,
777      * the URL will be displayed in the frame specified by TargetString.
778      * The special target names _level0 and _level1 are used to load another
779      * SWF movie into levels 0 and 1 respectively.
780      *
781      * @param url specified url
782      * @param target target
783      * @since flash 3
784      */

785     public void getURL( String JavaDoc url, String JavaDoc target ) {
786         flush_stack();
787         p.getURL(url, target);
788     }
789
790     /**
791      * Get URL, stack-based.
792      * <P>
793      * <OL>
794      * <LI>Pops window off the stack. window specifies the target window,
795      * which may be an empty string to indicate the current window.
796      * <LI>Pops url off the stack. url which specifies the URL to be retrieved.
797      * </OL>
798      *
799      * @param method Method specifies the method to use for the HTTP request. If (method and 0x40) != 0 then target is movie clip target,
800      * NOT browser window target!
801      * <UL>
802      * <LI>A value of 0 indicates that this is not a form request,
803      * so the movie clip’s variables should not be encoded and submitted.
804      * <LI>A value of 1 specifies a HTTP GET request.
805      * <LI>A value of 2 specifies a HTTP POST request.
806      * <LI>If method is 1 (GET) or 2 (POST), the variables in the current
807      * movie clip are submitted to the URL using the standard
808      * x-www-urlencoded encoding and the HTTP request method specified by method.
809      * </UL>
810      */

811     public void getURL( int method ) {
812         flush_stack();
813         p.getURL(method);
814     }
815
816     /**
817      * Loads movie from specified url into specified level
818      *
819      * @param url movie url
820      * @param level level. starts from 0
821      * @param method <UL>
822      * <LI>0 - does not send variables
823      * <LI>1 - send variables using get
824      * <LI>2 - send variables using post
825      * </UL>
826      */

827     public void loadMovieNum( String JavaDoc url, int level, int method ) {
828         push(url);
829         push("_level"+level);
830         getURL(method);
831     }
832
833     /**
834      * Loads movie from specified url into specified level
835      *
836      * @param url movie url
837      * @param level level. starts from 0
838      */

839     public void loadMovieNum( String JavaDoc url, int level ) {
840         loadMovieNum(url, level, 0);
841     }
842
843     /**
844      * Loads movie from specified url into specified target clip
845      *
846      * @param url movie url
847      * @param target target movie clip
848      * @param method <UL>
849      * <LI>0 - does not send variables
850      * <LI>1 - send variables using get
851      * <LI>2 - send variables using post
852      * </UL>
853      */

854     public void loadMovie( String JavaDoc url, String JavaDoc target, int method ) {
855         push(url);
856         push(target);
857         getURL(0x40+method);
858     }
859
860     /**
861      * Loads movie from specified url into specified level
862      *
863      * @param url movie url
864      * @param target target movie clip
865      */

866     public void loadMovie( String JavaDoc url, String JavaDoc target ) {
867         loadMovie(url, target, 0);
868     }
869
870     /**
871      * Unloads movie from specified level
872      *
873      * @param level level to unload the movie from
874      */

875     public void unloadMovieNum( int level ) {
876         loadMovieNum(null, level);
877     }
878
879     /**
880      * Unload movie previously loaded into specified target clip
881      *
882      * @param target target movie clip
883      */

884     public void unloadMovie( String JavaDoc target ) {
885         loadMovie(null, target);
886     }
887
888     /**
889      * Instructs the player to wait until the specified frame,
890      * otherwise skip the specified number of actions.
891      *
892      * @param frame specified frame
893      * @param skip specified number of actions to skip
894      * @since flash 3
895      */

896     public void waitForFrame( int frame, int skip ) {
897         flush_stack();
898         p.waitForFrame(frame, skip);
899     }
900
901     /**
902      * Instructs the player to change the context of subsequent actions,
903      * so they apply to a named object (TargetName) rather than the current movie.
904      * <P>
905      * For example, the SetTarget action can be used to control the timeline of a sprite
906      * object. The following sequence of actions sends a sprite called "spinner" to the
907      * first frame in its timeline:<BR>
908      * <OL>
909      * <LI>SetTarget "spinner"
910      * <LI>GotoFrame zero
911      * <LI>SetTarget "" (empty string)
912      * <LI>End of actions. (Action code = 0)
913      * </OL>
914      * <P>
915      * All actions following SetTarget "spinner" apply to the spinner
916      * object until SetTarget "", which sets the action context back to
917      * the current movie.
918      * For a complete discussion of target names see DefineSprite.
919      *
920      * @param target name of the target
921      * @since flash 3
922      */

923     public void setTarget( String JavaDoc target ) {
924         flush_stack();
925         p.setTarget(target);
926     }
927
928     /**
929      * Instructs the player to go to frame associated with the specified label.
930      * A label can be attached to a frame with the FrameLabel tag.
931      *
932      * @param label specified frame label
933      * @since flash 3
934      */

935     public void gotoFrameLabel( String JavaDoc label ) {
936         flush_stack();
937         p.gotoLabel(label);
938     }
939
940     /**
941      * Pops a value from the stack.
942      * @since flash 4
943      */

944     public void pop() {
945         flush_stack();
946         p.pop();
947     }
948
949     /**
950      * Creates label at current position
951      * <P>
952      * The label can be used for forward and backward jumps
953      * <P>
954      * For example:
955      * <code><PRE>
956      * as.getVar("i");
957      * as.getVar("n");
958      * as.equal();
959      * as.jumpIfTrue("end10");
960      * ......
961      * as.label("end10");
962      * </PRE></CODE>
963      *
964      * @param name name of label
965      */

966     public void label( String JavaDoc name ) {
967         flush_stack();
968         labels.put(name, new ASLabel(name, p.getPos()));
969         for( int i=0; i<forward_refs.size(); i++ ) {
970             ASLabel fref = (ASLabel) forward_refs.elementAt(i);
971             if( fref.name.equals(name) ) {
972                 int offset = fref.offset;
973                 p.body().writeWordAt(p.getPos()-offset-2, offset);
974             }
975         }
976     }
977
978     /**
979      * Jumps to specified label
980      * <P>
981      * Label has to be defined using 'label' method
982      *
983      * @param label_name label name
984      */

985     public void jump( String JavaDoc label_name ) {
986         flush_stack();
987         ASLabel l = (ASLabel) labels.get(label_name);
988         if( l != null ) {
989             int offset = l.offset;
990             p.jump(offset-p.getPos()-5);
991         } else {
992             forward_refs.addElement(new ASLabel(label_name, p.getPos()+3));
993             p.jump(0);
994         }
995     }
996
997     /**
998      * Pops top value off the stack and jumps to specified label if it's true
999      * <P>
1000     * Label has to be defined using 'label' method
1001     *
1002     * @param label_name label name
1003     */

1004    public void jumpIfTrue( String JavaDoc label_name ) {
1005        flush_stack();
1006        ASLabel l = (ASLabel) labels.get(label_name);
1007        if( l != null ) {
1008            int offset = l.offset;
1009            p.jumpIfTrue(offset-p.getPos()-5);
1010        } else {
1011            forward_refs.addElement(new ASLabel(label_name, p.getPos()+3));
1012            p.jumpIfTrue(0);
1013        }
1014    }
1015
1016    /**
1017     * Pushes a string to the stack.
1018     *
1019     * @param data string to push
1020     */

1021    public void push( String JavaDoc data ) {
1022        delayed_stack.addElement(getString(data));
1023    }
1024
1025    /**
1026     * Pushes a float to the stack.
1027     *
1028     * @param data float to push
1029     */

1030    public void push( float data ) {
1031        delayed_stack.addElement(new Float JavaDoc(data));
1032    }
1033
1034    /**
1035     * Pushes an int to the stack.
1036     *
1037     * @param data int to push
1038     */

1039    public void push( int data ) {
1040        delayed_stack.addElement(new Integer JavaDoc(data));
1041    }
1042
1043    /**
1044     * Pushes an double to the stack.
1045     *
1046     * @param data double to push
1047     */

1048    public void push( double data ) {
1049        delayed_stack.addElement(new Double JavaDoc(data));
1050    }
1051
1052    /**
1053     * Pushes an double to the stack.
1054     *
1055     * @param data double to push
1056     */

1057    public void push( boolean data ) {
1058        delayed_stack.addElement(new Boolean JavaDoc(data));
1059    }
1060
1061    /**
1062     * Pushes an double to the stack.
1063     *
1064     * @param data double to push
1065     */

1066    public void push( Object JavaDoc data ) {
1067        if( data instanceof String JavaDoc ) push( (String JavaDoc)data );
1068        else if( data instanceof Expr ) ((Expr)data).eval(this);
1069        else delayed_stack.addElement(data);
1070    }
1071
1072    /**
1073     * Sets a variable.
1074     * <P>
1075     * <OL>
1076     * <LI>Pops value off the stack.
1077     * <LI>Pops name off the stack, which is a string naming the variable to set.
1078     * <LI>Sets the variable name in the current execution context to value.
1079     * </OL>
1080     * A variable in another execution context may be referenced by prefixing the variable name with
1081     * the target path and a colon. For example: /A/B:FOO references variable FOO in movie
1082     * clip with target path /A/B.
1083     */

1084    public void setVar() {
1085        flush_stack();
1086        p.setVar();
1087    }
1088
1089    /**
1090     * Sets value to a variable
1091     *
1092     * @param var1 name of the variable
1093     * @param data new value
1094     */

1095    public void setVar(String JavaDoc var1, Object JavaDoc data) {
1096        push(var1);
1097        push(data);
1098        setVar();
1099    }
1100
1101    /**
1102     * Defines local variable without init data
1103     *
1104     * @param var1 name of the variable
1105     */

1106    public void localVar( String JavaDoc var1 ) {
1107        push(var1);
1108        flush_stack();
1109        p.body().writeByte(Actions.DefineLocal2);
1110    }
1111
1112    /**
1113     * Defines local variable with init value
1114     *
1115     * @param var1 name of the variable
1116     * @param data init value
1117     */

1118    public void localVar( String JavaDoc var1, Object JavaDoc data ) {
1119        push(var1);
1120        push(data);
1121        flush_stack();
1122        p.body().writeByte(Actions.DefineLocal);
1123    }
1124
1125    /**
1126     * Gets a variable’s value.
1127     * <P>
1128     * <OL>
1129     * <LI>Pops name off the stack, which is a string naming the variable to get.
1130     * <LI>Pushes the value of the variable to the stack.
1131     * </OL>
1132     */

1133    public void getVar() {
1134        flush_stack();
1135        p.eval();
1136    }
1137
1138    /**
1139     * Pushes value of specified variable to the stack
1140     *
1141     * @param var1 variable name
1142     */

1143    public void getVar( String JavaDoc var1 ) {
1144        push(var1);
1145        flush_stack();
1146        p.eval();
1147    }
1148
1149    /**
1150     * Pushes values of specified variables to the stack
1151     *
1152     * @param var1 variable name
1153     * @param var2 variable name
1154     */

1155    public void getVars( String JavaDoc var1, String JavaDoc var2 ) {
1156        push(var2);
1157        push(var1);
1158        getVar();
1159        swap();
1160        getVar();
1161    }
1162
1163    /**
1164     * Swaps two topmost elements of the stack
1165     */

1166    public void swap() {
1167        flush_stack();
1168        p.body().writeByte(Actions.StackSwap);
1169    }
1170
1171    /**
1172     * Duplicates top element of the stack
1173     */

1174    public void dup() {
1175        flush_stack();
1176        p.body().writeByte(Actions.PushDuplicate);
1177    }
1178
1179    /**
1180     * Sets member to the specified value
1181     * <P>
1182     * <CODE><PRE>
1183     * // _root.myclip.mysize = 10;
1184     * as.setMember("_root.myclip.mysize", 10);
1185     *
1186     * // _root.myclip.mysize = Math.sin(i);
1187     * as.setMember("_root.myclip.mysize", new ASAssembler.Expr() {
1188     * public void eval( ASAssembler as ) {
1189     * as.callMethod("Math.sin", new ASAssembler.Expr() {
1190     * public void eval( ASAssembler as ) {
1191     * as.getVar("i");
1192     * }
1193     * });
1194     * }
1195     * });
1196     * </PRE></CODE>
1197     *
1198     * @param mem member name
1199     * @param value specified value
1200     */

1201    public void setMember( String JavaDoc mem, Object JavaDoc value ) {
1202        IVVector t = parseMember(mem);
1203        if( t.size() == 1 ) {
1204            setVar(mem, value);
1205        } else {
1206            String JavaDoc iname = (String JavaDoc) t.elementAt(0);
1207            getVar(iname);
1208            int i=1;
1209            for( ; i<t.size()-1; i++ ) {
1210                push(t.elementAt(i));
1211                flush_stack();
1212                p.getMember();
1213            }
1214            push(t.elementAt(i));
1215            push(value);
1216            flush_stack();
1217            p.setMember();
1218        }
1219    }
1220
1221    /**
1222     * Set member.
1223     * Stack state must be [ object, member name, value ]
1224     *
1225     * @since flash 5
1226     */

1227    public void setMember() {
1228        flush_stack();
1229        p.setMember();
1230    }
1231
1232    /**
1233     * Pushes member value on the stack
1234     * <P>
1235     * <CODE><PRE>
1236     * // sz = _root.myclip.mysize;
1237     * as.push("sz");
1238     * as.getMember("_root.myclip.mysize");
1239     * as.setVar();
1240     *
1241     * // var sz = _root.myclip.mysize;
1242     * as.localVar("sz", new ASAssembler.Expr() {
1243     * public void eval( ASAssembler as ) {
1244     * as.getMember("_root.myclip.mysize");
1245     * }
1246     * });
1247     * </PRE></CODE>
1248     *
1249     * @param mem member name
1250     */

1251    public void getMember( String JavaDoc mem ) {
1252        IVVector t = parseMember(mem);
1253        String JavaDoc iname = (String JavaDoc) t.elementAt(0);
1254        getVar(iname);
1255        if( t.size() > 1 ) {
1256            int i=1;
1257            for( ; i<t.size(); i++ ) {
1258                push(t.elementAt(i));
1259                flush_stack();
1260                p.getMember();
1261            }
1262        }
1263    }
1264
1265    /**
1266     * Pushes element of an array into the stack
1267     * <P>
1268     * <CODE><PRE>
1269     * // a = myarray[2];
1270     * as.push("a");
1271     * as.getArrayElement("myarray", 2);
1272     * as.setVar();
1273     * </PRE></CODE>
1274     *
1275     * @param array_name name of array variable
1276     * @param index index
1277     */

1278    public void getArrayElement( String JavaDoc array_name, int index ) {
1279        getVar(array_name);
1280        push(index);
1281        getMember();
1282    }
1283
1284    /**
1285     * Pushes element of an array into the stack
1286     * <P>
1287     * <CODE><PRE>
1288     * // a = myarray[i];
1289     * as.push("a");
1290     * as.getArrayElement("myarray", new ASAssembler.Expr() {
1291     * public void eval( ASAssembler as ) {
1292     * as.getVar("i");
1293     * }
1294     * });
1295     * as.setVar();
1296     * </PRE></CODE>
1297     *
1298     * @param array_name name of array variable
1299     * @param index index expression
1300     */

1301    public void getArrayElement( String JavaDoc array_name, Object JavaDoc index ) {
1302        getVar(array_name);
1303        push(index);
1304        getMember();
1305    }
1306
1307    /**
1308     * Sets element of an array into the specified value
1309     * <P>
1310     * <CODE><PRE>
1311     * // myarray[i] = 10;
1312     * as.setArrayElement("myarray", new ASAssembler.Expr() {
1313     * public void eval( ASAssembler as ) {
1314     * as.getVar("i");
1315     * }
1316     * }, new Integer(10));
1317     * </PRE></CODE>
1318     *
1319     * @param array_name name of array variable
1320     * @param index index expression
1321     */

1322    public void setArrayElement( String JavaDoc array_name, Object JavaDoc index, Object JavaDoc value ) {
1323        getVar(array_name);
1324        push(index);
1325        push(value);
1326        getMember();
1327    }
1328
1329    /**
1330     * New Object
1331     */

1332    public void newObject() {
1333        flush_stack();
1334        p.newObject();
1335    }
1336
1337    /**
1338     * Creates new object
1339     * <P>
1340     * <CODE><PRE>
1341     * // ok = new Boolean(true);
1342     * as.push("ok");
1343     * as.newObject("Boolean", new Object[] {new Boolean(true)});
1344     * as.setVar();
1345     * </PRE></CODE>
1346     *
1347     * @param class_name class name
1348     * @param args arguments
1349     */

1350    public void newObject( String JavaDoc class_name, Object JavaDoc[] args ) {
1351        if( args == null || args.length == 0 ) {
1352            push(0);
1353        } else {
1354            for( int i=0; i<args.length; i++ ) {
1355                push(args[i]);
1356            }
1357            push(args.length);
1358        }
1359        newObject();
1360    }
1361
1362    public void newObject( String JavaDoc class_name, Object JavaDoc arg ) {
1363        newObject(class_name, new Object JavaDoc[] {arg});
1364    }
1365
1366    public void newObject( String JavaDoc class_name, int arg ) {
1367        newObject(class_name, new Integer JavaDoc(arg));
1368    }
1369
1370    public void newObject( String JavaDoc class_name, double arg ) {
1371        newObject(class_name, new Double JavaDoc(arg));
1372    }
1373
1374    public void newObject( String JavaDoc class_name, boolean arg ) {
1375        newObject(class_name, new Boolean JavaDoc(arg));
1376    }
1377
1378    /**
1379     * Initialize object
1380     * <P>
1381     * <CODE><PRE>
1382     * // a = {radius:5, angle:pi/2};
1383     * as.push("a");
1384     * as.initObject(
1385     * new String[] {"radius", "angle"},
1386     * new Object[] {
1387     * new Integer(5),
1388     * new ASAssembler.Expr() {
1389     * public void eval(ASAssembler as) {
1390     * as.getVar("pi");
1391     * as.push(2);
1392     * as.divide();
1393     * }
1394     * }
1395     * }
1396     * );
1397     * as.setVar();
1398     * </PRE></CODE>
1399     *
1400     * @param props array of properties
1401     * @param values array of values
1402     */

1403    public void initObject( String JavaDoc[] props, Object JavaDoc[] values ) {
1404        for( int i=0; i<props.length; i++ ) {
1405            push(props[i]);
1406            push(values[i]);
1407        }
1408        push(props.length);
1409        flush_stack();
1410        p.body().writeByte(Actions.InitObject);
1411    }
1412
1413    /**
1414     * Calls method with parameters
1415     * <P>
1416     * <CODE><PRE>
1417     * // sn = Math.sin(10);
1418     * as.push("sn");
1419     * as.callMember("Math.sin", new Object[] {new Integer(10)});
1420     * as.setVar();
1421     *
1422     * // _root.myclip.play();
1423     * as.callMember("_root.myclip.play", null);
1424     * as.pop(); // remove resultat
1425     * </PRE></CODE>
1426     *
1427     * @param method method name
1428     * @param args array of parameters
1429     */

1430    public void callMethod( String JavaDoc method, Object JavaDoc[] args ) {
1431        IVVector t = parseMember(method);
1432        if( t.size() == 1 ) {
1433            callFunction(method, args);
1434        } else {
1435            if( args == null || args.length == 0 ) {
1436                push(0);
1437            } else {
1438                for( int i=0; i<args.length; i++ ) {
1439                    push(args[i]);
1440                }
1441                push(args.length);
1442            }
1443            String JavaDoc iname = (String JavaDoc) t.elementAt(0);
1444            getVar(iname);
1445            int i=1;
1446            for( ; i<t.size()-1; i++ ) {
1447                push(t.elementAt(i));
1448                flush_stack();
1449                p.getMember();
1450            }
1451            push(t.elementAt(i));
1452            callMethod();
1453        }
1454    }
1455
1456    public void callMethod( String JavaDoc method, Object JavaDoc arg ) {
1457        callMethod(method, new Object JavaDoc[] {arg});
1458    }
1459
1460    public void callMethod( String JavaDoc method, int arg ) {
1461        callMethod(method, new Integer JavaDoc(arg));
1462    }
1463
1464    public void callMethod( String JavaDoc method, double arg ) {
1465        callMethod(method, new Double JavaDoc(arg));
1466    }
1467
1468    public void callMethod( String JavaDoc method, boolean arg ) {
1469        callMethod(method, new Boolean JavaDoc(arg));
1470    }
1471
1472    /**
1473     * Calls a method of an object.
1474     * Stack state must be [ arguments, argCount, object, methodName ]
1475     *
1476     * @since flash 5
1477     */

1478    public void callMethod() {
1479        flush_stack();
1480        p.callMethod();
1481    }
1482
1483    /**
1484     * Get member.
1485     * Stack state must be [ object, member name ]
1486     *
1487     * @since flash 5
1488     */

1489    public void getMember() {
1490        flush_stack();
1491        p.getMember();
1492    }
1493
1494    /**
1495     * Calls function with parameters
1496     * <P>
1497     * <CODE><PRE>
1498     * // sn = myfunc(10);
1499     * as.push("sn");
1500     * as.callFunction("myfunc", new Object[] {new Integer(10)});
1501     * as.setVar();
1502     * </PRE></CODE>
1503     *
1504     * @param func_name function name
1505     * @param args array of parameters
1506     */

1507    public void callFunction( String JavaDoc func_name, Object JavaDoc[] args ) {
1508        if( args == null || args.length == 0 ) {
1509            push(0);
1510        } else {
1511            for( int i=0; i<args.length; i++ ) {
1512                push(args[i]);
1513            }
1514            push(args.length);
1515        }
1516        push(func_name);
1517        flush_stack();
1518        p.callFunction();
1519    }
1520
1521    public void callFunction( String JavaDoc func_name, Object JavaDoc arg ) {
1522        callFunction(func_name, new Object JavaDoc[] {arg});
1523    }
1524
1525    public void callFunction( String JavaDoc func_name, int arg ) {
1526        callFunction(func_name, new Integer JavaDoc(arg));
1527    }
1528
1529    public void callFunction( String JavaDoc func_name, double arg ) {
1530        callFunction(func_name, new Double JavaDoc(arg));
1531    }
1532
1533    public void callFunction( String JavaDoc func_name, boolean arg ) {
1534        callFunction(func_name, new Boolean JavaDoc(arg));
1535    }
1536
1537    /**
1538     * Defines new function
1539     * <P>
1540     * <CODE><PRE>
1541     * // function printmsg(msg, name) {
1542     * // trace(msg+", "+name);
1543     * // }
1544     * as.defineFunction("printmsg", new String[] {"msg", "name"});
1545     * as.getVar("name");
1546     * as.push(" = ");
1547     * as.getVar("msg");
1548     * as.add();
1549     * as.add();
1550     * as.trace();
1551     * as.endFunction();
1552     * </PRE></CODE>
1553     *
1554     * @param func_name function name
1555     * @param parms parameter names
1556     */

1557    public void defineFunction( String JavaDoc func_name, String JavaDoc[] parms ) {
1558        flush_stack();
1559        FlashBuffer fob = p.body();
1560        fob.writeByte(Actions.DefineFunction|0x80); // 0x80 - with length
1561
int pos = fob.getPos();
1562        fob.writeWord(0); // size - will be stored later
1563
fob.writeStringZ(func_name);
1564        int num = parms==null? 0: parms.length;
1565        fob.writeWord(num);
1566        for( int i=0; i<num; i++ ) fob.writeStringZ(parms[i]);
1567        fob.writeWordAt(fob.getSize()-pos, pos);
1568        funcs.push(p);
1569        p = new Program();
1570    }
1571
1572    /**
1573     * End of function definition
1574     *
1575     * @see defineFunction
1576     */

1577    public void endFunction() {
1578        flush_stack();
1579
1580        Program prev_p = (Program) funcs.pop();
1581        prev_p.body().writeWord(p.body().getSize());
1582        prev_p.body().writeFOB(p.body());
1583
1584        p = prev_p;
1585    }
1586
1587    /**
1588     * Function/method return statement
1589     */

1590    public void funcReturn() {
1591        flush_stack();
1592        p.body().writeByte(Actions.Return);
1593    }
1594
1595    /**
1596     * Nested expression
1597     * <P>
1598     * Usage:
1599     * <P>
1600     * <CODE><PRE>
1601     * // _root.myclip.mysize = i*10;
1602     * as.setMember("_root.myclip.mysize", new ASAssembler.Expr() {
1603     * public void eval( ASAssembler as ) {
1604     * as.push(10);
1605     * as.getVar("i");
1606     * as.multiply();
1607     * }
1608     * });
1609     *
1610     * // var d = f*108;
1611     * as.localVar("d", new ASAssembler.Expr() {
1612     * public void eval( ASAssembler as ) {
1613     * as.push(108);
1614     * as.getVar("f");
1615     * as.multiply();
1616     * }
1617     * });
1618     * </PRE></CODE>
1619     */

1620    public abstract static class Expr {
1621        public abstract void eval( ASAssembler as );
1622    }
1623
1624    ///////////////////////////////////////////////////////////////////////////////////////////
1625

1626    private IVVector t = new IVVector();
1627
1628    private IVVector parseMember( String JavaDoc m ) {
1629        t.reset();
1630        int idx = 0;
1631        for(;;) {
1632            int idx2 = m.indexOf('.', idx);
1633            if( idx2 < 0 ) {
1634                if( idx == 0 ) t.addElement(m);
1635                else t.addElement(m.substring(idx));
1636                break;
1637            }
1638            t.addElement(m.substring(idx, idx2));
1639            idx = ++idx2;
1640        }
1641        return t;
1642    }
1643
1644    /**
1645     * Returns index of specified string in contant pool
1646     *
1647     * @param s specified string
1648     * @return index of specified string wrapped in Short
1649     */

1650    private Short JavaDoc getString( String JavaDoc s ) {
1651        Short JavaDoc i = (Short JavaDoc) pool.get(s);
1652        if( i == null ) {
1653            i = new Short JavaDoc((short) pool.size());
1654            pool.put(s, i);
1655        }
1656        return i;
1657    }
1658
1659    /**
1660     * Writes constant pool
1661     *
1662     * @param p program to write contant pool
1663     */

1664    private void writePool( Program p ) {
1665        if( pool.size() == 0 ) return;
1666        String JavaDoc[] ss = new String JavaDoc[pool.size()];
1667        Set set = pool.entrySet();
1668        for( Iterator it = set.iterator(); it.hasNext(); ) {
1669            Map.Entry entry = (Map.Entry) it.next();
1670            String JavaDoc s = (String JavaDoc) entry.getKey();
1671            int idx = ((Short JavaDoc)entry.getValue()).intValue();
1672            ss[idx] = s;
1673        }
1674        p.addConstantPool(ss);
1675    }
1676
1677    /**
1678     * Flushes push stack
1679     */

1680    private void flush_stack() {
1681        int n = delayed_stack.size();
1682        if( n == 0 ) return;
1683        if( n == 1 ) {
1684            p.push(delayed_stack.elementAt(0));
1685        } else {
1686            Object JavaDoc[] data = new Object JavaDoc[n];
1687            delayed_stack.copyInto(data);
1688            p.push(data);
1689        }
1690        delayed_stack.reset();
1691    }
1692
1693    private static class ASLabel {
1694        String JavaDoc name;
1695        int offset;
1696        ASLabel( String JavaDoc name, int offset ) {
1697            this.name = name;
1698            this.offset = offset;
1699        }
1700    }
1701
1702}
1703
1704
Popular Tags