0001: /*
0002: * ==========================================================================
0003: *
0004: * The JGenerator Software License, Version 1.0
0005: *
0006: * Copyright (c) 2000 Dmitry Skavish (skavish@usa.net). All rights reserved.
0007: *
0008: * Redistribution and use in source and binary forms, with or without
0009: * modification, are permitted provided that the following conditions are met:
0010: *
0011: * 1. Redistributions of source code must retain the above copyright
0012: * notice, this list of conditions and the following disclaimer.
0013: *
0014: * 2. Redistributions in binary form must reproduce the above copyright
0015: * notice, this list of conditions and the following disclaimer in
0016: * the documentation and/or other materials provided with the
0017: * distribution.
0018: *
0019: * 3. The end-user documentation included with the redistribution, if
0020: * any, must include the following acknowlegement:
0021: * "This product includes software developed by Dmitry Skavish
0022: * (skavish@usa.net, http://www.flashgap.com/)."
0023: * Alternately, this acknowlegement may appear in the software itself,
0024: * if and wherever such third-party acknowlegements normally appear.
0025: *
0026: * 4. The name "The JGenerator" must not be used to endorse or promote
0027: * products derived from this software without prior written permission.
0028: * For written permission, please contact skavish@usa.net.
0029: *
0030: * 5. Products derived from this software may not be called "The JGenerator"
0031: * nor may "The JGenerator" appear in their names without prior written
0032: * permission of Dmitry Skavish.
0033: *
0034: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
0035: * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
0036: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
0037: * DISCLAIMED. IN NO EVENT SHALL DMITRY SKAVISH OR THE OTHER
0038: * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
0039: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
0040: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
0041: * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
0042: * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
0043: * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
0044: * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
0045: * SUCH DAMAGE.
0046: *
0047: */
0048:
0049: package org.openlaszlo.iv.flash.api.action;
0050:
0051: import java.util.*;
0052:
0053: import org.openlaszlo.iv.flash.util.*;
0054: import org.openlaszlo.iv.flash.parser.*;
0055: import org.openlaszlo.iv.flash.api.*;
0056: import org.openlaszlo.iv.flash.context.Context;
0057:
0058: /**
0059: * ActionScript API assembler
0060: * <P>
0061: * Supports only Flash 5/MX actionscript.
0062: *
0063: * @author Dmitry Skavish
0064: */
0065: public class ASAssembler {
0066:
0067: private HashMap pool = new HashMap();
0068: private HashMap labels = new HashMap();
0069: private IVVector forward_refs = new IVVector();
0070: private IVVector delayed_stack = new IVVector();
0071: private Program p = new Program();
0072: private Stack funcs = new Stack();
0073:
0074: /**
0075: * Creates new assembler
0076: * <P>
0077: * Requires flash version 5+
0078: *
0079: * @param file flash file.
0080: */
0081: public ASAssembler(FlashFile file) {
0082: if (file.getVersion() < 5) {
0083: Log.logRB(Resource.ASASMREQFLASH5);
0084: }
0085: }
0086:
0087: /**
0088: * Creates Program object from this assembler
0089: *
0090: * @return new Program object
0091: */
0092: public Program toProgram() {
0093: flush_stack();
0094: Program prog = new Program();
0095: writePool(prog);
0096: prog.body().writeFOB(p.body());
0097: return prog;
0098: }
0099:
0100: /**
0101: * Instructs the player to go to the next frame in the current movie.
0102: */
0103: public void nextFrame() {
0104: flush_stack();
0105: p.nextFrame();
0106: }
0107:
0108: /**
0109: * Instructs the player to go to the previous frame in the current movie.
0110: */
0111: public void prevFrame() {
0112: flush_stack();
0113: p.prevFrame();
0114: }
0115:
0116: /**
0117: * Instructs the player to start playing at the current frame.
0118: */
0119: public void play() {
0120: flush_stack();
0121: p.play();
0122: }
0123:
0124: /**
0125: * Instructs the player to stop playing the movie at the current frame.
0126: * @since flash 3
0127: */
0128: public void stop() {
0129: flush_stack();
0130: p.stop();
0131: }
0132:
0133: /**
0134: * Toggle the display between high and low quality.
0135: */
0136: public void toggleQuality() {
0137: flush_stack();
0138: p.toggleQuality();
0139: }
0140:
0141: /**
0142: * Instructs the player to stop playing all sounds.
0143: */
0144: public void stopSounds() {
0145: flush_stack();
0146: p.stopSounds();
0147: }
0148:
0149: public void trace() {
0150: flush_stack();
0151: p.body().writeByte(Actions.Trace);
0152: }
0153:
0154: /**
0155: * Adds two values. Can be used for strings as well.
0156: * <P>
0157: * <OL>
0158: * <LI>Pops value A off the stack.
0159: * <LI>Pops value B off the stack.
0160: * <LI>Pushes the result, A+B, to the stack.
0161: * </OL>
0162: */
0163: public void add() {
0164: flush_stack();
0165: p.body().writeByte(Actions.Add2);
0166: }
0167:
0168: /**
0169: * Subtracts two numbers.
0170: * <P>
0171: * <OL>
0172: * <LI>Pops value A off the stack.
0173: * <LI>Pops value B off the stack.
0174: * <LI>A and B are converted to floating-point; non-numeric values evaluate to 0.
0175: * <LI>A is subtracted from B.
0176: * <LI>Pushes the result, A-B, to the stack.
0177: * </OL>
0178: */
0179: public void subtract() {
0180: flush_stack();
0181: p.subtract();
0182: }
0183:
0184: /**
0185: * Multiplies two numbers.
0186: * <P>
0187: * <OL>
0188: * <LI>Pops value A off the stack.
0189: * <LI>Pops value B off the stack.
0190: * <LI>A and B are converted to floating-point; non-numeric values evaluate to 0.
0191: * <LI>The numbers are multiplied.
0192: * <LI>Pushes the result, A*B, to the stack.
0193: * </OL>
0194: */
0195: public void multiply() {
0196: flush_stack();
0197: p.multiply();
0198: }
0199:
0200: /**
0201: * Divides two numbers.
0202: * <P>
0203: * <OL>
0204: * <LI>Pops value A off the stack.
0205: * <LI>Pops value B off the stack.
0206: * <LI>A and B are converted to floating-point; non-numeric values evaluate to 0.
0207: * <LI>B is divided by A.
0208: * <LI>Pushes the result, B/A, to the stack.
0209: * <LI>If A is zero, the result is the string #ERROR#.
0210: * </OL>
0211: * Note: When playing a Flash 5 .SWF, NaN, Infinity or –Infinity is pushed to the stack instead of #ERROR#.
0212: * @since flash 4
0213: */
0214: public void divide() {
0215: flush_stack();
0216: p.divide();
0217: }
0218:
0219: /**
0220: * Tests two values for equality. Can be used for strings as well.
0221: * <P>
0222: * <OL>
0223: * <LI>Pops value A off the stack.
0224: * <LI>Pops value B off the stack.
0225: * <LI>If the values are equal, a true is pushed to the stack.
0226: * <LI>Otherwise, a false is pushed to the stack.
0227: * </OL>
0228: */
0229: public void equal() {
0230: flush_stack();
0231: p.body().writeByte(Actions.Equals2);
0232: }
0233:
0234: /**
0235: * Tests if a value is less than another value. Can be used for strings as well.
0236: * <P>
0237: * <OL>
0238: * <LI>Pops value A off the stack.
0239: * <LI>Pops value B off the stack.
0240: * <LI>The values are compared for equality.
0241: * <LI>If B < A, a true is pushed to the stack; otherwise, a false is pushed to the stack.
0242: * </OL>
0243: */
0244: public void less() {
0245: flush_stack();
0246: p.body().writeByte(Actions.Less2);
0247: }
0248:
0249: /**
0250: * Performs a logical AND of two numbers.
0251: * <P>
0252: * <OL>
0253: * <LI>Pops value A off the stack.
0254: * <LI>Pops value B off the stack.
0255: * <LI>A and B are converted to floating-point; non-numeric values evaluate to 0.
0256: * <LI>If both numbers are nonzero, a 1 is pushed to the stack; otherwise, a 0 is pushed to the stack.
0257: * </OL>
0258: * Note: When playing a Macromedia Flash 5 .SWF, true is pushed to the stack instead of 1,
0259: * and false is pushed to the stack instead of 0.
0260: * @since flash 4
0261: */
0262: public void logicalAnd() {
0263: flush_stack();
0264: p.logicalAnd();
0265: }
0266:
0267: /**
0268: * Performs a logical OR of two numbers.
0269: * <P>
0270: * <OL>
0271: * <LI>Pops value A off the stack.
0272: * <LI>Pops value B off the stack.
0273: * <LI>A and B are converted to floating-point; non-numeric values evaluate to 0.
0274: * <LI>If either numbers is nonzero, a 1 is pushed to the stack; otherwise, a 0 is pushed to the stack.
0275: * </OL>
0276: * Note: When playing a Macromedia Flash 5 .SWF, true is pushed to the stack instead of 1,
0277: * and false is pushed to the stack instead of 0.
0278: * @since flash 4
0279: */
0280: public void logicalOr() {
0281: flush_stack();
0282: p.logicalOr();
0283: }
0284:
0285: /**
0286: * Performs a logical NOT of a number.
0287: * <P>
0288: * Note that in Macromedia Flash 5 .SWF files, the ActionNot action
0289: * converts its argument to a boolean, and pushes a result of type boolean.
0290: * In Macromedia Flash 4 .SWF files, the argument and result are numbers.
0291: * <P>
0292: * <OL>
0293: * <LI>Pops value A off the stack.
0294: * <LI>Pops value B off the stack.
0295: * <LI>A and B are converted to floating-point; non-numeric values evaluate to 0.
0296: * <LI>The numbers are compared for equality.
0297: * <LI>If the numbers are equal, a 1 (TRUE) is pushed to the stack.
0298: * <LI>Otherwise, a 0 is pushed to the stack.
0299: * </OL>
0300: * Note: When playing a Macromedia Flash 5 .SWF, true is pushed to the stack instead of 1,
0301: * and false is pushed to the stack instead of 0.
0302: * @since flash 4
0303: */
0304: public void logicalNot() {
0305: flush_stack();
0306: p.logicalNot();
0307: }
0308:
0309: /**
0310: * Tests two strings for equality.
0311: * <P>
0312: * <OL>
0313: * <LI>Pops value A off the stack.
0314: * <LI>Pops value B off the stack.
0315: * <LI>A and B are compared as strings. The comparison is case-sensitive.
0316: * <LI>If the strings are equal, a 1 (TRUE) is pushed to the stack.
0317: * <LI>Otherwise, a 0 is pushed to the stack.
0318: * </OL>
0319: * Note: When playing a Macromedia Flash 5 .SWF, true is pushed to the stack instead of 1,
0320: * and false is pushed to the stack instead of 0.
0321: * @since flash 4
0322: */
0323: public void stringEqual() {
0324: flush_stack();
0325: p.stringEqual();
0326: }
0327:
0328: /**
0329: * Computes the length of a string.
0330: * <P>
0331: * <OL>
0332: * <LI>Pops a string off the stack.
0333: * <LI>The length of the string is calculated and pushed to the stack.
0334: * </OL>
0335: * @since flash 4
0336: */
0337: public void stringLength() {
0338: flush_stack();
0339: p.stringLength();
0340: }
0341:
0342: /**
0343: * Tests if a string is less than another string.
0344: * <P>
0345: * <OL>
0346: * <LI>Pops value A off the stack.
0347: * <LI>Pops value B off the stack.
0348: * <LI>If B < A using a byte-by-byte comparison, a 1 is pushed to the stack;
0349: * otherwise, a 0 is pushed to the stack.
0350: * </OL>
0351: * Note: When playing a Macromedia Flash 5 .SWF, true is pushed to the stack instead of 1,
0352: * and false is pushed to the stack instead of 0.
0353: * @since flash 4
0354: */
0355: public void stringLessThan() {
0356: flush_stack();
0357: p.stringLessThan();
0358: }
0359:
0360: /**
0361: * Extracts a substring from a string.
0362: * <P>
0363: * <OL>
0364: * <LI>Pops number <B>count</B> off the stack.
0365: * <LI>Pops number <B>index</B> off the stack.
0366: * <LI>Pops string <B>string</B> off the stack.
0367: * <LI>The substring of <B>string</B> starting at the <B>index</B>’th character and
0368: * <B>count</B> characters in length is pushed to the stack.
0369: * <LI>If either <B>index</B> or <B>count</B> do not evaluate to integers, the result
0370: * is the empty string.
0371: * </OL>
0372: * @since flash 4
0373: */
0374: public void subString() {
0375: flush_stack();
0376: p.subString();
0377: }
0378:
0379: /**
0380: * Concatenates two strings.
0381: * <P>
0382: * <OL>
0383: * <LI>Pops value A off the stack.
0384: * <LI>Pops value B off the stack.
0385: * <LI>The concatenation BA is pushed to the stack.
0386: * </OL>
0387: * @since flash 4
0388: */
0389: public void addString() {
0390: flush_stack();
0391: p.addString();
0392: }
0393:
0394: /**
0395: * Computes the length of a string, multi-byte aware.
0396: * <P>
0397: * <OL>
0398: * <LI>Pops a string off the stack.
0399: * <LI>The length of the string in characters is calculated and pushed to the stack.
0400: * <LI>This is a multi-byte aware version of ActionStringLength.
0401: * On systems with double-byte support, a double-byte character is counted as a single character.
0402: * </OL>
0403: * @since flash 4
0404: */
0405: public void mbLength() {
0406: flush_stack();
0407: p.mbLength();
0408: }
0409:
0410: /**
0411: * Converts ASCII to character code, multi-byte aware.
0412: * <P>
0413: * <OL>
0414: * <LI>Pops value off the stack.
0415: * <LI>The value is converted from a number to the corresponding character.
0416: * If the character is a 16-bit value (>= 256), a double-byte character
0417: * is constructed with the first byte containing the high-order byte,
0418: * and the second byte containing the low-order byte.
0419: * <LI>The resulting character is pushed to the stack.
0420: * </OL>
0421: * @since flash 4
0422: */
0423: public void mbChr() {
0424: flush_stack();
0425: p.mbChr();
0426: }
0427:
0428: /**
0429: * Converts character code to ASCII, multi-byte aware.
0430: * <P>
0431: * <OL>
0432: * <LI>Pops value off the stack.
0433: * <LI>The first character of value is converted to a numeric character code.
0434: * If the first character of value is a double-byte character, a 16-bit value
0435: * is constructed with the first byte as the high order byte and the second byte
0436: * as the low order byte.
0437: * <LI>The resulting character code is pushed to the stack.
0438: * </OL>
0439: * @since flash 4
0440: */
0441: public void mbOrd() {
0442: flush_stack();
0443: p.mbOrd();
0444: }
0445:
0446: /**
0447: * Extracts a substring from a string, multi-byte aware.
0448: * <P>
0449: * <OL>
0450: * <LI>Pops number <B>count</B> off the stack.
0451: * <LI>Pops number <B>index</B> off the stack.
0452: * <LI>Pops string <B>string</B> off the stack.
0453: * <LI>The substring of <B>string</B> starting at the <B>index</B>’th character and
0454: * <B>count</B> characters in length is pushed to the stack.
0455: * <LI>If either <B>index</B> or <B>count</B> do not evaluate to integers, the result
0456: * is the empty string.
0457: * <LI>This is a multi-byte aware version of ActionStringExtract. index and count are
0458: * treated as character indices, counting double-byte characters as single characters.
0459: * </OL>
0460: * @since flash 4
0461: */
0462: public void mbSubString() {
0463: flush_stack();
0464: p.mbSubString();
0465: }
0466:
0467: /**
0468: * Converts to integer.
0469: * <P>
0470: * <OL>
0471: * <LI>Pops a value off the stack.
0472: * <LI>The value is converted to a number.
0473: * <LI>Next, any digits after the decimal point are discarded, resulting in an integer.
0474: * <LI>The resulting integer is pushed to the stack.
0475: * </OL>
0476: * @since flash 4
0477: */
0478: public void toInt() {
0479: flush_stack();
0480: p.toInt();
0481: }
0482:
0483: /**
0484: * Converts character code to ASCII.
0485: * <P>
0486: * <OL>
0487: * <LI>Pops value off the stack.
0488: * <LI>The first character of value is converted to a numeric ASCII character code.
0489: * <LI>The resulting character code is pushed to the stack.
0490: * </OL>
0491: * @since flash 4
0492: */
0493: public void ord() {
0494: flush_stack();
0495: p.ord();
0496: }
0497:
0498: /**
0499: * Converts ASCII to character code.
0500: * <P>
0501: * <OL>
0502: * <LI>Pops value off the stack.
0503: * <LI>The value is converted from a number to the corresponding ASCII character..
0504: * <LI>The resulting character is pushed to the stack.
0505: * </OL>
0506: * @since flash 4
0507: */
0508: public void chr() {
0509: flush_stack();
0510: p.chr();
0511: }
0512:
0513: /**
0514: * Gets a movie property
0515: * <P>
0516: * <OL>
0517: * <LI>Pops index off the stack.
0518: * <LI>Pops target off the stack.
0519: * <LI>Retrieves the value of the property enumerated as index from
0520: * the movie clip with target path target and pushes the value to the stack.
0521: * </OL>
0522: * @since flash 4
0523: */
0524: public void getProperty() {
0525: flush_stack();
0526: p.getProperty();
0527: }
0528:
0529: /**
0530: * Gets a movie property. Leaves property value on the stack.
0531: *
0532: * @param target movie clip's target path
0533: * @param property property index
0534: */
0535: public void getProperty(String target, int property) {
0536: push(target);
0537: push(property);
0538: getProperty();
0539: }
0540:
0541: /**
0542: * Sets a movie property.
0543: * <P>
0544: * <OL>
0545: * <LI>Pops value off the stack.
0546: * <LI>Pops index off the stack.
0547: * <LI>Pops target off the stack.
0548: * <LI>Sets the property enumerated as index in the movie clip
0549: * with target path target to the value value.
0550: * </OL>
0551: * @since flash 4
0552: */
0553: public void setProperty() {
0554: flush_stack();
0555: p.setProperty();
0556: }
0557:
0558: /**
0559: * Sets property on specified movie clip.
0560: *
0561: * @param target movie clip's target path
0562: * @param property property index
0563: * @param value property value
0564: */
0565: public void setProperty(String target, int property, Object value) {
0566: push(target);
0567: push(property);
0568: push(value);
0569: setProperty();
0570: }
0571:
0572: /**
0573: * Clones a movie clip.
0574: * <P>
0575: * <OL>
0576: * <LI>Pops depth off the stack (has to be added to 16384)
0577: * <LI>Pops target off the stack.
0578: * <LI>Pops source off the stack.
0579: * <LI>Duplicates movie clip source, giving the new instance
0580: * the name target, at z-order depth depth.
0581: * </OL>
0582: * @since flash 4
0583: */
0584: public void duplicateClip() {
0585: flush_stack();
0586: p.cloneClip();
0587: }
0588:
0589: /**
0590: * Clones a movie clip.
0591: *
0592: * @param source source movie clip path
0593: * @param target target name
0594: * @param depth depth (z-order)
0595: */
0596: public void duplicateClip(String source, String target, int depth) {
0597: push(depth + 16384);
0598: push(target);
0599: push(source);
0600: duplicateClip();
0601: }
0602:
0603: /**
0604: * Removes a movie clip.
0605: * <P>
0606: * <OL>
0607: * <LI>Pops target off the stack.
0608: * <LI>Removes the clone movie clip identified by target path target.
0609: * </OL>
0610: * @since flash 4
0611: */
0612: public void removeClip() {
0613: flush_stack();
0614: p.removeClip();
0615: }
0616:
0617: /**
0618: * Removes a movie clip.
0619: *
0620: * @param target target movie clip path
0621: */
0622: public void removeClip(String target) {
0623: push(target);
0624: removeClip();
0625: }
0626:
0627: /**
0628: * Starts dragging a movie clip.
0629: * <P>
0630: * <OL>
0631: * <LI>Pops target off the stack. target identifies the movie clip to be dragged.
0632: * <LI>Pops lockcenter off the stack. If lockcenter evaluates to a nonzero value,
0633: * the center of the dragged movie clip is locked to the mouse position.
0634: * Otherwise, the movie clip moves relatively to the mouse position when
0635: * the drag started.
0636: * <LI>Pops constrain off the stack.
0637: * <LI>If constrain evaluates to a nonzero value:
0638: * <OL>
0639: * <LI>Pops y2 off the stack.
0640: * <LI>Pops x2 off the stack.
0641: * <LI>Pops y1 off the stack.
0642: * <LI>Pops x1 off the stack.
0643: * </OL>
0644: * </OL>
0645: * @since flash 4
0646: */
0647: public void startDrag() {
0648: flush_stack();
0649: p.startDrag();
0650: }
0651:
0652: /**
0653: * Ends drag operation.
0654: * <P>
0655: * <OL>
0656: * <LI>Ends the drag operation in progress, if any.
0657: * </OL>
0658: * @since flash 4
0659: */
0660: public void endDrag() {
0661: flush_stack();
0662: p.endDrag();
0663: }
0664:
0665: /**
0666: * Calculates a random number.
0667: * <P>
0668: * <OL>
0669: * <LI>Pops maximum off the stack.
0670: * <LI>Calculates a random number, an integer in the range 0 ... (maximum-1)
0671: * <LI>This random number is pushed to the stack.
0672: * </OL>
0673: * @since flash 4
0674: */
0675: public void random() {
0676: flush_stack();
0677: p.random();
0678: }
0679:
0680: /**
0681: * Calculates (pushes it to the stack) a random number in the range 0 .. (maximum-1)
0682: *
0683: * @param maximum maximum
0684: */
0685: public void random(int maximum) {
0686: push(maximum);
0687: random();
0688: }
0689:
0690: /**
0691: * Reports milliseconds since player started.
0692: * <P>
0693: * <OL>
0694: * <LI>Calculates the number of milliseconds since the Player was started (an integer).
0695: * <LI>This number is pushed to the stack.
0696: * </OL>
0697: * @since flash 4
0698: */
0699: public void getTimer() {
0700: flush_stack();
0701: p.getTimer();
0702: }
0703:
0704: /**
0705: * Instructs the player to go to the specified frame in the current movie.
0706: *
0707: * @param frame frame number
0708: * @since flash 3
0709: */
0710: public void gotoFrame(int frame) {
0711: flush_stack();
0712: p.gotoFrame(frame);
0713: }
0714:
0715: /**
0716: * Instructs the player to go to the specified frame in the current movie and play
0717: *
0718: * @param frame frame number
0719: */
0720: public void gotoFrameAndPlay(int frame) {
0721: p.gotoFrame(frame);
0722: play();
0723: }
0724:
0725: /**
0726: * Instructs the player to go to the specified frame in the current movie and stop
0727: *
0728: * @param frame frame number
0729: */
0730: public void gotoFrameAndStop(int frame) {
0731: gotoFrame(frame);
0732: stop();
0733: }
0734:
0735: /**
0736: * Go to frame and play, stack-based.
0737: * <P>
0738: * <OL>
0739: * <LI>Pops <b>frame</b> off the stack.
0740: * <LI>If <b>frame</b> is a number, the next frame of the movie to be displayed
0741: * will be the <b>frame</b>’th frame in the current movie clip.
0742: * <LI>If <b>frame</b> is a string, <b>frame</b> is treated as a frame label.
0743: * If the specified label exists in the current movie clip,
0744: * the labeled frame will become the current frame. Otherwise, the action is ignored.
0745: * <LI>Either a frame or a number may be prefixed by a target path, e.g. /MovieClip:3 or /MovieClip:FrameLabel
0746: * </OL>
0747: * @since flash 4
0748: */
0749: public void gotoFrameAndPlay() {
0750: flush_stack();
0751: p.gotoFrameAndPlay();
0752: }
0753:
0754: /**
0755: * Go to frame and stop, stack-based.
0756: * <P>
0757: * <OL>
0758: * <LI>Pops <b>frame</b> off the stack.
0759: * <LI>If <b>frame</b> is a number, the next frame of the movie to be displayed
0760: * will be the <b>frame</b>’th frame in the current movie clip.
0761: * <LI>If <b>frame</b> is a string, <b>frame</b> is treated as a frame label.
0762: * If the specified label exists in the current movie clip,
0763: * the labeled frame will become the current frame. Otherwise, the action is ignored.
0764: * <LI>Either a frame or a number may be prefixed by a target path, e.g. /MovieClip:3 or /MovieClip:FrameLabel
0765: * </OL>
0766: * @since flash 4
0767: */
0768: public void gotoFrameAndStop() {
0769: flush_stack();
0770: p.gotoFrameAndStop();
0771: }
0772:
0773: /**
0774: * Instructs the player to get the URL specified by UrlString.
0775: * The URL can be of any type, including an HTML file, an image
0776: * or another SWF movie. If the movie is playing in a browser,
0777: * the URL will be displayed in the frame specified by TargetString.
0778: * The special target names _level0 and _level1 are used to load another
0779: * SWF movie into levels 0 and 1 respectively.
0780: *
0781: * @param url specified url
0782: * @param target target
0783: * @since flash 3
0784: */
0785: public void getURL(String url, String target) {
0786: flush_stack();
0787: p.getURL(url, target);
0788: }
0789:
0790: /**
0791: * Get URL, stack-based.
0792: * <P>
0793: * <OL>
0794: * <LI>Pops window off the stack. window specifies the target window,
0795: * which may be an empty string to indicate the current window.
0796: * <LI>Pops url off the stack. url which specifies the URL to be retrieved.
0797: * </OL>
0798: *
0799: * @param method Method specifies the method to use for the HTTP request. If (method and 0x40) != 0 then target is movie clip target,
0800: * NOT browser window target!
0801: * <UL>
0802: * <LI>A value of 0 indicates that this is not a form request,
0803: * so the movie clip’s variables should not be encoded and submitted.
0804: * <LI>A value of 1 specifies a HTTP GET request.
0805: * <LI>A value of 2 specifies a HTTP POST request.
0806: * <LI>If method is 1 (GET) or 2 (POST), the variables in the current
0807: * movie clip are submitted to the URL using the standard
0808: * x-www-urlencoded encoding and the HTTP request method specified by method.
0809: * </UL>
0810: */
0811: public void getURL(int method) {
0812: flush_stack();
0813: p.getURL(method);
0814: }
0815:
0816: /**
0817: * Loads movie from specified url into specified level
0818: *
0819: * @param url movie url
0820: * @param level level. starts from 0
0821: * @param method <UL>
0822: * <LI>0 - does not send variables
0823: * <LI>1 - send variables using get
0824: * <LI>2 - send variables using post
0825: * </UL>
0826: */
0827: public void loadMovieNum(String url, int level, int method) {
0828: push(url);
0829: push("_level" + level);
0830: getURL(method);
0831: }
0832:
0833: /**
0834: * Loads movie from specified url into specified level
0835: *
0836: * @param url movie url
0837: * @param level level. starts from 0
0838: */
0839: public void loadMovieNum(String url, int level) {
0840: loadMovieNum(url, level, 0);
0841: }
0842:
0843: /**
0844: * Loads movie from specified url into specified target clip
0845: *
0846: * @param url movie url
0847: * @param target target movie clip
0848: * @param method <UL>
0849: * <LI>0 - does not send variables
0850: * <LI>1 - send variables using get
0851: * <LI>2 - send variables using post
0852: * </UL>
0853: */
0854: public void loadMovie(String url, String target, int method) {
0855: push(url);
0856: push(target);
0857: getURL(0x40 + method);
0858: }
0859:
0860: /**
0861: * Loads movie from specified url into specified level
0862: *
0863: * @param url movie url
0864: * @param target target movie clip
0865: */
0866: public void loadMovie(String url, String target) {
0867: loadMovie(url, target, 0);
0868: }
0869:
0870: /**
0871: * Unloads movie from specified level
0872: *
0873: * @param level level to unload the movie from
0874: */
0875: public void unloadMovieNum(int level) {
0876: loadMovieNum(null, level);
0877: }
0878:
0879: /**
0880: * Unload movie previously loaded into specified target clip
0881: *
0882: * @param target target movie clip
0883: */
0884: public void unloadMovie(String target) {
0885: loadMovie(null, target);
0886: }
0887:
0888: /**
0889: * Instructs the player to wait until the specified frame,
0890: * otherwise skip the specified number of actions.
0891: *
0892: * @param frame specified frame
0893: * @param skip specified number of actions to skip
0894: * @since flash 3
0895: */
0896: public void waitForFrame(int frame, int skip) {
0897: flush_stack();
0898: p.waitForFrame(frame, skip);
0899: }
0900:
0901: /**
0902: * Instructs the player to change the context of subsequent actions,
0903: * so they apply to a named object (TargetName) rather than the current movie.
0904: * <P>
0905: * For example, the SetTarget action can be used to control the timeline of a sprite
0906: * object. The following sequence of actions sends a sprite called "spinner" to the
0907: * first frame in its timeline:<BR>
0908: * <OL>
0909: * <LI>SetTarget "spinner"
0910: * <LI>GotoFrame zero
0911: * <LI>SetTarget "" (empty string)
0912: * <LI>End of actions. (Action code = 0)
0913: * </OL>
0914: * <P>
0915: * All actions following SetTarget "spinner" apply to the spinner
0916: * object until SetTarget "", which sets the action context back to
0917: * the current movie.
0918: * For a complete discussion of target names see DefineSprite.
0919: *
0920: * @param target name of the target
0921: * @since flash 3
0922: */
0923: public void setTarget(String target) {
0924: flush_stack();
0925: p.setTarget(target);
0926: }
0927:
0928: /**
0929: * Instructs the player to go to frame associated with the specified label.
0930: * A label can be attached to a frame with the FrameLabel tag.
0931: *
0932: * @param label specified frame label
0933: * @since flash 3
0934: */
0935: public void gotoFrameLabel(String label) {
0936: flush_stack();
0937: p.gotoLabel(label);
0938: }
0939:
0940: /**
0941: * Pops a value from the stack.
0942: * @since flash 4
0943: */
0944: public void pop() {
0945: flush_stack();
0946: p.pop();
0947: }
0948:
0949: /**
0950: * Creates label at current position
0951: * <P>
0952: * The label can be used for forward and backward jumps
0953: * <P>
0954: * For example:
0955: * <code><PRE>
0956: * as.getVar("i");
0957: * as.getVar("n");
0958: * as.equal();
0959: * as.jumpIfTrue("end10");
0960: * ......
0961: * as.label("end10");
0962: * </PRE></CODE>
0963: *
0964: * @param name name of label
0965: */
0966: public void label(String name) {
0967: flush_stack();
0968: labels.put(name, new ASLabel(name, p.getPos()));
0969: for (int i = 0; i < forward_refs.size(); i++) {
0970: ASLabel fref = (ASLabel) forward_refs.elementAt(i);
0971: if (fref.name.equals(name)) {
0972: int offset = fref.offset;
0973: p.body().writeWordAt(p.getPos() - offset - 2, offset);
0974: }
0975: }
0976: }
0977:
0978: /**
0979: * Jumps to specified label
0980: * <P>
0981: * Label has to be defined using 'label' method
0982: *
0983: * @param label_name label name
0984: */
0985: public void jump(String label_name) {
0986: flush_stack();
0987: ASLabel l = (ASLabel) labels.get(label_name);
0988: if (l != null) {
0989: int offset = l.offset;
0990: p.jump(offset - p.getPos() - 5);
0991: } else {
0992: forward_refs.addElement(new ASLabel(label_name,
0993: p.getPos() + 3));
0994: p.jump(0);
0995: }
0996: }
0997:
0998: /**
0999: * Pops top value off the stack and jumps to specified label if it's true
1000: * <P>
1001: * Label has to be defined using 'label' method
1002: *
1003: * @param label_name label name
1004: */
1005: public void jumpIfTrue(String label_name) {
1006: flush_stack();
1007: ASLabel l = (ASLabel) labels.get(label_name);
1008: if (l != null) {
1009: int offset = l.offset;
1010: p.jumpIfTrue(offset - p.getPos() - 5);
1011: } else {
1012: forward_refs.addElement(new ASLabel(label_name,
1013: p.getPos() + 3));
1014: p.jumpIfTrue(0);
1015: }
1016: }
1017:
1018: /**
1019: * Pushes a string to the stack.
1020: *
1021: * @param data string to push
1022: */
1023: public void push(String data) {
1024: delayed_stack.addElement(getString(data));
1025: }
1026:
1027: /**
1028: * Pushes a float to the stack.
1029: *
1030: * @param data float to push
1031: */
1032: public void push(float data) {
1033: delayed_stack.addElement(new Float(data));
1034: }
1035:
1036: /**
1037: * Pushes an int to the stack.
1038: *
1039: * @param data int to push
1040: */
1041: public void push(int data) {
1042: delayed_stack.addElement(new Integer(data));
1043: }
1044:
1045: /**
1046: * Pushes an double to the stack.
1047: *
1048: * @param data double to push
1049: */
1050: public void push(double data) {
1051: delayed_stack.addElement(new Double(data));
1052: }
1053:
1054: /**
1055: * Pushes an double to the stack.
1056: *
1057: * @param data double to push
1058: */
1059: public void push(boolean data) {
1060: delayed_stack.addElement(new Boolean(data));
1061: }
1062:
1063: /**
1064: * Pushes an double to the stack.
1065: *
1066: * @param data double to push
1067: */
1068: public void push(Object data) {
1069: if (data instanceof String)
1070: push((String) data);
1071: else if (data instanceof Expr)
1072: ((Expr) data).eval(this );
1073: else
1074: delayed_stack.addElement(data);
1075: }
1076:
1077: /**
1078: * Sets a variable.
1079: * <P>
1080: * <OL>
1081: * <LI>Pops value off the stack.
1082: * <LI>Pops name off the stack, which is a string naming the variable to set.
1083: * <LI>Sets the variable name in the current execution context to value.
1084: * </OL>
1085: * A variable in another execution context may be referenced by prefixing the variable name with
1086: * the target path and a colon. For example: /A/B:FOO references variable FOO in movie
1087: * clip with target path /A/B.
1088: */
1089: public void setVar() {
1090: flush_stack();
1091: p.setVar();
1092: }
1093:
1094: /**
1095: * Sets value to a variable
1096: *
1097: * @param var1 name of the variable
1098: * @param data new value
1099: */
1100: public void setVar(String var1, Object data) {
1101: push(var1);
1102: push(data);
1103: setVar();
1104: }
1105:
1106: /**
1107: * Defines local variable without init data
1108: *
1109: * @param var1 name of the variable
1110: */
1111: public void localVar(String var1) {
1112: push(var1);
1113: flush_stack();
1114: p.body().writeByte(Actions.DefineLocal2);
1115: }
1116:
1117: /**
1118: * Defines local variable with init value
1119: *
1120: * @param var1 name of the variable
1121: * @param data init value
1122: */
1123: public void localVar(String var1, Object data) {
1124: push(var1);
1125: push(data);
1126: flush_stack();
1127: p.body().writeByte(Actions.DefineLocal);
1128: }
1129:
1130: /**
1131: * Gets a variable’s value.
1132: * <P>
1133: * <OL>
1134: * <LI>Pops name off the stack, which is a string naming the variable to get.
1135: * <LI>Pushes the value of the variable to the stack.
1136: * </OL>
1137: */
1138: public void getVar() {
1139: flush_stack();
1140: p.eval();
1141: }
1142:
1143: /**
1144: * Pushes value of specified variable to the stack
1145: *
1146: * @param var1 variable name
1147: */
1148: public void getVar(String var1) {
1149: push(var1);
1150: flush_stack();
1151: p.eval();
1152: }
1153:
1154: /**
1155: * Pushes values of specified variables to the stack
1156: *
1157: * @param var1 variable name
1158: * @param var2 variable name
1159: */
1160: public void getVars(String var1, String var2) {
1161: push(var2);
1162: push(var1);
1163: getVar();
1164: swap();
1165: getVar();
1166: }
1167:
1168: /**
1169: * Swaps two topmost elements of the stack
1170: */
1171: public void swap() {
1172: flush_stack();
1173: p.body().writeByte(Actions.StackSwap);
1174: }
1175:
1176: /**
1177: * Duplicates top element of the stack
1178: */
1179: public void dup() {
1180: flush_stack();
1181: p.body().writeByte(Actions.PushDuplicate);
1182: }
1183:
1184: /**
1185: * Sets member to the specified value
1186: * <P>
1187: * <CODE><PRE>
1188: * // _root.myclip.mysize = 10;
1189: * as.setMember("_root.myclip.mysize", 10);
1190: *
1191: * // _root.myclip.mysize = Math.sin(i);
1192: * as.setMember("_root.myclip.mysize", new ASAssembler.Expr() {
1193: * public void eval( ASAssembler as ) {
1194: * as.callMethod("Math.sin", new ASAssembler.Expr() {
1195: * public void eval( ASAssembler as ) {
1196: * as.getVar("i");
1197: * }
1198: * });
1199: * }
1200: * });
1201: * </PRE></CODE>
1202: *
1203: * @param mem member name
1204: * @param value specified value
1205: */
1206: public void setMember(String mem, Object value) {
1207: IVVector t = parseMember(mem);
1208: if (t.size() == 1) {
1209: setVar(mem, value);
1210: } else {
1211: String iname = (String) t.elementAt(0);
1212: getVar(iname);
1213: int i = 1;
1214: for (; i < t.size() - 1; i++) {
1215: push(t.elementAt(i));
1216: flush_stack();
1217: p.getMember();
1218: }
1219: push(t.elementAt(i));
1220: push(value);
1221: flush_stack();
1222: p.setMember();
1223: }
1224: }
1225:
1226: /**
1227: * Set member.
1228: * Stack state must be [ object, member name, value ]
1229: *
1230: * @since flash 5
1231: */
1232: public void setMember() {
1233: flush_stack();
1234: p.setMember();
1235: }
1236:
1237: /**
1238: * Pushes member value on the stack
1239: * <P>
1240: * <CODE><PRE>
1241: * // sz = _root.myclip.mysize;
1242: * as.push("sz");
1243: * as.getMember("_root.myclip.mysize");
1244: * as.setVar();
1245: *
1246: * // var sz = _root.myclip.mysize;
1247: * as.localVar("sz", new ASAssembler.Expr() {
1248: * public void eval( ASAssembler as ) {
1249: * as.getMember("_root.myclip.mysize");
1250: * }
1251: * });
1252: * </PRE></CODE>
1253: *
1254: * @param mem member name
1255: */
1256: public void getMember(String mem) {
1257: IVVector t = parseMember(mem);
1258: String iname = (String) t.elementAt(0);
1259: getVar(iname);
1260: if (t.size() > 1) {
1261: int i = 1;
1262: for (; i < t.size(); i++) {
1263: push(t.elementAt(i));
1264: flush_stack();
1265: p.getMember();
1266: }
1267: }
1268: }
1269:
1270: /**
1271: * Pushes element of an array into the stack
1272: * <P>
1273: * <CODE><PRE>
1274: * // a = myarray[2];
1275: * as.push("a");
1276: * as.getArrayElement("myarray", 2);
1277: * as.setVar();
1278: * </PRE></CODE>
1279: *
1280: * @param array_name name of array variable
1281: * @param index index
1282: */
1283: public void getArrayElement(String array_name, int index) {
1284: getVar(array_name);
1285: push(index);
1286: getMember();
1287: }
1288:
1289: /**
1290: * Pushes element of an array into the stack
1291: * <P>
1292: * <CODE><PRE>
1293: * // a = myarray[i];
1294: * as.push("a");
1295: * as.getArrayElement("myarray", new ASAssembler.Expr() {
1296: * public void eval( ASAssembler as ) {
1297: * as.getVar("i");
1298: * }
1299: * });
1300: * as.setVar();
1301: * </PRE></CODE>
1302: *
1303: * @param array_name name of array variable
1304: * @param index index expression
1305: */
1306: public void getArrayElement(String array_name, Object index) {
1307: getVar(array_name);
1308: push(index);
1309: getMember();
1310: }
1311:
1312: /**
1313: * Sets element of an array into the specified value
1314: * <P>
1315: * <CODE><PRE>
1316: * // myarray[i] = 10;
1317: * as.setArrayElement("myarray", new ASAssembler.Expr() {
1318: * public void eval( ASAssembler as ) {
1319: * as.getVar("i");
1320: * }
1321: * }, new Integer(10));
1322: * </PRE></CODE>
1323: *
1324: * @param array_name name of array variable
1325: * @param index index expression
1326: */
1327: public void setArrayElement(String array_name, Object index,
1328: Object value) {
1329: getVar(array_name);
1330: push(index);
1331: push(value);
1332: getMember();
1333: }
1334:
1335: /**
1336: * New Object
1337: */
1338: public void newObject() {
1339: flush_stack();
1340: p.newObject();
1341: }
1342:
1343: /**
1344: * Creates new object
1345: * <P>
1346: * <CODE><PRE>
1347: * // ok = new Boolean(true);
1348: * as.push("ok");
1349: * as.newObject("Boolean", new Object[] {new Boolean(true)});
1350: * as.setVar();
1351: * </PRE></CODE>
1352: *
1353: * @param class_name class name
1354: * @param args arguments
1355: */
1356: public void newObject(String class_name, Object[] args) {
1357: if (args == null || args.length == 0) {
1358: push(0);
1359: } else {
1360: for (int i = 0; i < args.length; i++) {
1361: push(args[i]);
1362: }
1363: push(args.length);
1364: }
1365: newObject();
1366: }
1367:
1368: public void newObject(String class_name, Object arg) {
1369: newObject(class_name, new Object[] { arg });
1370: }
1371:
1372: public void newObject(String class_name, int arg) {
1373: newObject(class_name, new Integer(arg));
1374: }
1375:
1376: public void newObject(String class_name, double arg) {
1377: newObject(class_name, new Double(arg));
1378: }
1379:
1380: public void newObject(String class_name, boolean arg) {
1381: newObject(class_name, new Boolean(arg));
1382: }
1383:
1384: /**
1385: * Initialize object
1386: * <P>
1387: * <CODE><PRE>
1388: * // a = {radius:5, angle:pi/2};
1389: * as.push("a");
1390: * as.initObject(
1391: * new String[] {"radius", "angle"},
1392: * new Object[] {
1393: * new Integer(5),
1394: * new ASAssembler.Expr() {
1395: * public void eval(ASAssembler as) {
1396: * as.getVar("pi");
1397: * as.push(2);
1398: * as.divide();
1399: * }
1400: * }
1401: * }
1402: * );
1403: * as.setVar();
1404: * </PRE></CODE>
1405: *
1406: * @param props array of properties
1407: * @param values array of values
1408: */
1409: public void initObject(String[] props, Object[] values) {
1410: for (int i = 0; i < props.length; i++) {
1411: push(props[i]);
1412: push(values[i]);
1413: }
1414: push(props.length);
1415: flush_stack();
1416: p.body().writeByte(Actions.InitObject);
1417: }
1418:
1419: /**
1420: * Calls method with parameters
1421: * <P>
1422: * <CODE><PRE>
1423: * // sn = Math.sin(10);
1424: * as.push("sn");
1425: * as.callMember("Math.sin", new Object[] {new Integer(10)});
1426: * as.setVar();
1427: *
1428: * // _root.myclip.play();
1429: * as.callMember("_root.myclip.play", null);
1430: * as.pop(); // remove resultat
1431: * </PRE></CODE>
1432: *
1433: * @param method method name
1434: * @param args array of parameters
1435: */
1436: public void callMethod(String method, Object[] args) {
1437: IVVector t = parseMember(method);
1438: if (t.size() == 1) {
1439: callFunction(method, args);
1440: } else {
1441: if (args == null || args.length == 0) {
1442: push(0);
1443: } else {
1444: for (int i = 0; i < args.length; i++) {
1445: push(args[i]);
1446: }
1447: push(args.length);
1448: }
1449: String iname = (String) t.elementAt(0);
1450: getVar(iname);
1451: int i = 1;
1452: for (; i < t.size() - 1; i++) {
1453: push(t.elementAt(i));
1454: flush_stack();
1455: p.getMember();
1456: }
1457: push(t.elementAt(i));
1458: callMethod();
1459: }
1460: }
1461:
1462: public void callMethod(String method, Object arg) {
1463: callMethod(method, new Object[] { arg });
1464: }
1465:
1466: public void callMethod(String method, int arg) {
1467: callMethod(method, new Integer(arg));
1468: }
1469:
1470: public void callMethod(String method, double arg) {
1471: callMethod(method, new Double(arg));
1472: }
1473:
1474: public void callMethod(String method, boolean arg) {
1475: callMethod(method, new Boolean(arg));
1476: }
1477:
1478: /**
1479: * Calls a method of an object.
1480: * Stack state must be [ arguments, argCount, object, methodName ]
1481: *
1482: * @since flash 5
1483: */
1484: public void callMethod() {
1485: flush_stack();
1486: p.callMethod();
1487: }
1488:
1489: /**
1490: * Get member.
1491: * Stack state must be [ object, member name ]
1492: *
1493: * @since flash 5
1494: */
1495: public void getMember() {
1496: flush_stack();
1497: p.getMember();
1498: }
1499:
1500: /**
1501: * Calls function with parameters
1502: * <P>
1503: * <CODE><PRE>
1504: * // sn = myfunc(10);
1505: * as.push("sn");
1506: * as.callFunction("myfunc", new Object[] {new Integer(10)});
1507: * as.setVar();
1508: * </PRE></CODE>
1509: *
1510: * @param func_name function name
1511: * @param args array of parameters
1512: */
1513: public void callFunction(String func_name, Object[] args) {
1514: if (args == null || args.length == 0) {
1515: push(0);
1516: } else {
1517: for (int i = 0; i < args.length; i++) {
1518: push(args[i]);
1519: }
1520: push(args.length);
1521: }
1522: push(func_name);
1523: flush_stack();
1524: p.callFunction();
1525: }
1526:
1527: public void callFunction(String func_name, Object arg) {
1528: callFunction(func_name, new Object[] { arg });
1529: }
1530:
1531: public void callFunction(String func_name, int arg) {
1532: callFunction(func_name, new Integer(arg));
1533: }
1534:
1535: public void callFunction(String func_name, double arg) {
1536: callFunction(func_name, new Double(arg));
1537: }
1538:
1539: public void callFunction(String func_name, boolean arg) {
1540: callFunction(func_name, new Boolean(arg));
1541: }
1542:
1543: /**
1544: * Defines new function
1545: * <P>
1546: * <CODE><PRE>
1547: * // function printmsg(msg, name) {
1548: * // trace(msg+", "+name);
1549: * // }
1550: * as.defineFunction("printmsg", new String[] {"msg", "name"});
1551: * as.getVar("name");
1552: * as.push(" = ");
1553: * as.getVar("msg");
1554: * as.add();
1555: * as.add();
1556: * as.trace();
1557: * as.endFunction();
1558: * </PRE></CODE>
1559: *
1560: * @param func_name function name
1561: * @param parms parameter names
1562: */
1563: public void defineFunction(String func_name, String[] parms) {
1564: flush_stack();
1565: FlashBuffer fob = p.body();
1566: fob.writeByte(Actions.DefineFunction | 0x80); // 0x80 - with length
1567: int pos = fob.getPos();
1568: fob.writeWord(0); // size - will be stored later
1569: fob.writeStringZ(func_name);
1570: int num = parms == null ? 0 : parms.length;
1571: fob.writeWord(num);
1572: for (int i = 0; i < num; i++)
1573: fob.writeStringZ(parms[i]);
1574: fob.writeWordAt(fob.getSize() - pos, pos);
1575: funcs.push(p);
1576: p = new Program();
1577: }
1578:
1579: /**
1580: * End of function definition
1581: *
1582: * @see defineFunction
1583: */
1584: public void endFunction() {
1585: flush_stack();
1586:
1587: Program prev_p = (Program) funcs.pop();
1588: prev_p.body().writeWord(p.body().getSize());
1589: prev_p.body().writeFOB(p.body());
1590:
1591: p = prev_p;
1592: }
1593:
1594: /**
1595: * Function/method return statement
1596: */
1597: public void funcReturn() {
1598: flush_stack();
1599: p.body().writeByte(Actions.Return);
1600: }
1601:
1602: /**
1603: * Nested expression
1604: * <P>
1605: * Usage:
1606: * <P>
1607: * <CODE><PRE>
1608: * // _root.myclip.mysize = i*10;
1609: * as.setMember("_root.myclip.mysize", new ASAssembler.Expr() {
1610: * public void eval( ASAssembler as ) {
1611: * as.push(10);
1612: * as.getVar("i");
1613: * as.multiply();
1614: * }
1615: * });
1616: *
1617: * // var d = f*108;
1618: * as.localVar("d", new ASAssembler.Expr() {
1619: * public void eval( ASAssembler as ) {
1620: * as.push(108);
1621: * as.getVar("f");
1622: * as.multiply();
1623: * }
1624: * });
1625: * </PRE></CODE>
1626: */
1627: public abstract static class Expr {
1628: public abstract void eval(ASAssembler as);
1629: }
1630:
1631: ///////////////////////////////////////////////////////////////////////////////////////////
1632:
1633: private IVVector t = new IVVector();
1634:
1635: private IVVector parseMember(String m) {
1636: t.reset();
1637: int idx = 0;
1638: for (;;) {
1639: int idx2 = m.indexOf('.', idx);
1640: if (idx2 < 0) {
1641: if (idx == 0)
1642: t.addElement(m);
1643: else
1644: t.addElement(m.substring(idx));
1645: break;
1646: }
1647: t.addElement(m.substring(idx, idx2));
1648: idx = ++idx2;
1649: }
1650: return t;
1651: }
1652:
1653: /**
1654: * Returns index of specified string in contant pool
1655: *
1656: * @param s specified string
1657: * @return index of specified string wrapped in Short
1658: */
1659: private Short getString(String s) {
1660: Short i = (Short) pool.get(s);
1661: if (i == null) {
1662: i = new Short((short) pool.size());
1663: pool.put(s, i);
1664: }
1665: return i;
1666: }
1667:
1668: /**
1669: * Writes constant pool
1670: *
1671: * @param p program to write contant pool
1672: */
1673: private void writePool(Program p) {
1674: if (pool.size() == 0)
1675: return;
1676: String[] ss = new String[pool.size()];
1677: Set set = pool.entrySet();
1678: for (Iterator it = set.iterator(); it.hasNext();) {
1679: Map.Entry entry = (Map.Entry) it.next();
1680: String s = (String) entry.getKey();
1681: int idx = ((Short) entry.getValue()).intValue();
1682: ss[idx] = s;
1683: }
1684: p.addConstantPool(ss);
1685: }
1686:
1687: /**
1688: * Flushes push stack
1689: */
1690: private void flush_stack() {
1691: int n = delayed_stack.size();
1692: if (n == 0)
1693: return;
1694: if (n == 1) {
1695: p.push(delayed_stack.elementAt(0));
1696: } else {
1697: Object[] data = new Object[n];
1698: delayed_stack.copyInto(data);
1699: p.push(data);
1700: }
1701: delayed_stack.reset();
1702: }
1703:
1704: private static class ASLabel {
1705: String name;
1706: int offset;
1707:
1708: ASLabel(String name, int offset) {
1709: this.name = name;
1710: this.offset = offset;
1711: }
1712: }
1713:
1714: }
|