--- /dev/null
+package hxasm {
+
+ public class Context {
+ public function Context() : void {
+ this.lints = new Array();
+ this.lfloats = new Array();
+ this.lstrings = new Array();
+ this.lnamespaces = new Array();
+ this.lnssets = new Array();
+ this.lmtypes = new Array();
+ this.lnames = new Array();
+ this.lclasses = new Array();
+ this.lmethods = new Array();
+ this.hstrings = new Hash();
+ this.bytepos = 0;
+ this.emptyString = this.string("");
+ this.nsPublic = this.namespace(HNamespace.NPublic(this.emptyString));
+ this.arrayProp = this.name(Name.NMultiNameLate(this.nsset([this.nsPublic])));
+ this.beginFunction({ args : [], ret : null});
+ this.ops([OpCode.OThis,OpCode.OScope]);
+ this.init = this.curMethod;
+ this.init.maxStack = 2;
+ this.init.maxScope = 2;
+ }
+ protected var lints : Array;
+ protected var lfloats : Array;
+ protected var lstrings : Array;
+ protected var lnamespaces : Array;
+ protected var lnssets : Array;
+ protected var lnames : Array;
+ protected var hstrings : Hash;
+ protected var lclasses : Array;
+ protected var lmtypes : Array;
+ protected var lmethods : Array;
+ protected var curClass : *;
+ protected var curMethod : *;
+ protected var init : *;
+ protected var fieldSlot : int;
+ protected var bytepos : int;
+ protected var registers : Array;
+ public var emptyString : Index;
+ public var nsPublic : Index;
+ public var arrayProp : Index;
+ public function _int(i : int) : Index {
+ return this.lookup(this.lints,i);
+ }
+ public function float(f : Number) : Index {
+ return this.lookup(this.lfloats,f);
+ }
+ public function string(s : String) : Index {
+ var n : * = this.hstrings.get(s);
+ if(n == null) {
+ this.lstrings.push(s);
+ n = this.lstrings.length;
+ this.hstrings.set(s,n);
+ }
+ return Index.Idx(n);
+ }
+ public function namespace(n : HNamespace) : Index {
+ return this.elookup(this.lnamespaces,n);
+ }
+ public function nsset(ns : Array) : Index {
+ {
+ var _g1 : int = 0, _g : int = this.lnssets.length;
+ while(_g1 < _g) {
+ var i : int = _g1++;
+ var s : Array = this.lnssets[i];
+ if(s.length != ns.length) continue;
+ var ok : Boolean = true;
+ {
+ var _g3 : int = 0, _g2 : int = s.length;
+ while(_g3 < _g2) {
+ var j : int = _g3++;
+ if(!Type.enumEq(s[j],ns[j])) {
+ ok = false;
+ break;
+ }
+ }
+ }
+ if(ok) return Index.Idx(i + 1);
+ }
+ }
+ this.lnssets.push(ns);
+ return Index.Idx(this.lnssets.length);
+ }
+ public function name(n : Name) : Index {
+ return this.elookup(this.lnames,n);
+ }
+ public function type(path : String) : Index {
+ if(path == "*") return null;
+ var path1 : Array = path.split(".");
+ var cname : String = path1.pop();
+ var pid : Index = this.string(path1.join("."));
+ var nameid : Index = this.string(cname);
+ var pid1 : Index = this.namespace(HNamespace.NPublic(pid));
+ var tid : Index = this.name(Name.NName(nameid,pid1));
+ return tid;
+ }
+ public function property(pname : String,ns : Index = null) : Index {
+ var pid : Index = this.string("");
+ var nameid : Index = this.string(pname);
+ var pid1 : Index = (ns == null?this.namespace(HNamespace.NPublic(pid)):ns);
+ var tid : Index = this.name(Name.NName(nameid,pid1));
+ return tid;
+ }
+ public function methodType(m : *) : Index {
+ this.lmtypes.push(m);
+ return Index.Idx(this.lmtypes.length - 1);
+ }
+ protected function lookup(arr : Array,n : *) : Index {
+ {
+ var _g1 : int = 0, _g : int = arr.length;
+ while(_g1 < _g) {
+ var i : int = _g1++;
+ if(arr[i] == n) return Index.Idx(i + 1);
+ }
+ }
+ arr.push(n);
+ return Index.Idx(arr.length);
+ }
+ protected function elookup(arr : Array,n : *) : Index {
+ {
+ var _g1 : int = 0, _g : int = arr.length;
+ while(_g1 < _g) {
+ var i : int = _g1++;
+ if(Type.enumEq(arr[i],n)) return Index.Idx(i + 1);
+ }
+ }
+ arr.push(n);
+ return Index.Idx(arr.length);
+ }
+ public function getDatas() : * {
+ return { ints : this.lints, floats : this.lfloats, strings : this.lstrings, namespaces : this.lnamespaces, nssets : this.lnssets, names : this.lnames, mtypes : this.lmtypes, classes : this.lclasses, methods : this.lmethods, init : Index.Idx(0)}
+ }
+ protected function beginFunction(mt : *) : Index {
+ this.curMethod = { type : this.methodType(mt), nRegs : mt.args.length + 1, maxScope : 0, maxStack : 0, opcodes : []}
+ this.lmethods.push(this.curMethod);
+ this.registers = new Array();
+ {
+ var _g1 : int = 0, _g : int = this.curMethod.nRegs;
+ while(_g1 < _g) {
+ var x : int = _g1++;
+ this.registers.push(true);
+ }
+ }
+ return Index.Idx(this.lmethods.length - 1);
+ }
+ public function allocRegister() : int {
+ {
+ var _g1 : int = 0, _g : int = this.registers.length;
+ while(_g1 < _g) {
+ var i : int = _g1++;
+ if(!this.registers[i]) {
+ this.registers[i] = true;
+ return i;
+ }
+ }
+ }
+ this.registers.push(true);
+ this.curMethod.nRegs++;
+ return this.registers.length - 1;
+ }
+ public function freeRegister(i : int) : void {
+ this.registers[i] = false;
+ }
+ public function beginClass(path : String) : * {
+ this.endClass();
+ var index : Index = Index.Idx(this.lclasses.length);
+ var tpath : Index = this.type(path);
+ var st : Index = this.beginFunction({ args : [], ret : null});
+ this.op(OpCode.ORetVoid);
+ var m : Index = this.beginFunction({ args : [], ret : null});
+ this.op(OpCode.ORetVoid);
+ this.fieldSlot = 1;
+ this.curClass = { index : index, name : tpath, superclass : this.type("Object"), constructorType : this.curMethod.type, constructor : m, statics : st, fields : [], staticFields : []}
+ this.lclasses.push(this.curClass);
+ this.curMethod = null;
+ return this.curClass;
+ }
+ protected function endClass() : void {
+ if(this.curClass == null) return;
+ this.curMethod = this.init;
+ this.ops([OpCode.OGetGlobalScope,OpCode.OGetLex(this.type("Object")),OpCode.OScope,OpCode.OGetLex(this.curClass.superclass),OpCode.OClassDef(this.curClass.index),OpCode.OPopScope,OpCode.OInitProp(this.curClass.name)]);
+ this.curMethod = null;
+ this.curClass = null;
+ }
+ public function beginMethod(mname : String,targs : Array,tret : Index,isStatic : * = null,isOverride : * = null,isFinal : * = null) : * {
+ var m : Index = this.beginFunction({ args : targs, ret : tret});
+ var fl : Array = (isStatic?this.curClass.staticFields:this.curClass.fields);
+ fl.push({ name : this.property(mname), slot : 0, kind : FieldKind.FMethod(m,isFinal,isOverride)});
+ return this.curMethod;
+ }
+ public function defineField(fname : String,t : Index,isStatic : * = null) : int {
+ var fl : Array = (isStatic?this.curClass.staticFields:this.curClass.fields);
+ var slot : int = this.fieldSlot++;
+ fl.push({ name : this.property(fname), slot : slot, kind : FieldKind.FVar(t)});
+ return slot;
+ }
+ public function op(o : OpCode) : void {
+ this.curMethod.opcodes.push(o);
+ var w : OpWriter = new OpWriter();
+ w.write(o);
+ this.bytepos += w.getBytes().length;
+ }
+ public function ops(ops : Array) : void {
+ {
+ var _g1 : int = 0, _g : int = ops.length;
+ while(_g1 < _g) {
+ var i : int = _g1++;
+ this.op(ops[i]);
+ }
+ }
+ }
+ public function backwardJump() : Function {
+ var start : int = this.bytepos;
+ var me : Context = this;
+ this.op(OpCode.OLabel);
+ return function(jcond : JumpStyle) : void {
+ me.op(OpCode.OJump(jcond,start - me.bytepos - 4));
+ }
+ }
+ public function jump(jcond : JumpStyle) : Function {
+ var ops : Array = this.curMethod.opcodes;
+ var pos : int = ops.length;
+ this.op(OpCode.OJump(JumpStyle.JTrue,-1));
+ var start : int = this.bytepos;
+ var me : Context = this;
+ return function() : void {
+ ops[pos] = OpCode.OJump(jcond,me.bytepos - start);
+ }
+ }
+ public function finalize() : void {
+ this.endClass();
+ this.curMethod = this.init;
+ this.op(OpCode.ORetVoid);
+ this.curMethod = null;
+ this.curClass = null;
+ }
+ }
+}
--- /dev/null
+package hxasm {
+
+ public class FieldKind extends enum {
+ public static const __isenum : Boolean = true;
+ public function FieldKind( t : String, index : int, p : Array = null ) : void { this.tag = t; this.index = index; this.params = p; }
+ public static function FMethod(type : Index, isOverride : * = null, isFinal : * = null) : FieldKind { return new FieldKind("FMethod",1,[type,isOverride,isFinal]); }
+ public static function FVar(type : Index = null, _const : * = null) : FieldKind { return new FieldKind("FVar",0,[type,_const]); }
+ }
+}
--- /dev/null
+package hxasm {
+
+ public class HNamespace extends enum {
+ public static const __isenum : Boolean = true;
+ public function HNamespace( t : String, index : int, p : Array = null ) : void { this.tag = t; this.index = index; this.params = p; }
+ public static function NNamespace(ns : Index) : HNamespace { return new HNamespace("Namespace",1,[ns]); }
+ public static function NPublic(id : Index = null) : HNamespace { return new HNamespace("NPublic",0,[id]); }
+ }
+}
--- /dev/null
+package hxasm{
+ import flash.utils.Dictionary;
+
+ public class Hash {
+ public function Hash() : void {
+ this.h = new Dictionary();
+ }
+ public function set(key : String,value : *) : void {
+ this.h["$" + key] = value;
+ }
+ public function get(key : String) : * {
+ return this.h["$" + key];
+ }
+ public function exists(key : String) : Boolean {
+ return this.h.hasOwnProperty("$" + key);
+ }
+ public function remove(key : String) : Boolean {
+ key = "$" + key;
+ if(!this.h.hasOwnProperty(key)) return false;
+ delete(this.h[key]);
+ return true;
+ }
+ public function keys() : * {
+ return (function($this:Hash) : * {
+ var $r : *;
+ $r = new Array();
+ for(var $k : String in $this.h) $r.push($k.substr(1));
+ return $r;
+ }(this)).iterator();
+ }
+ public function iterator() : * {
+ return { ref : this.h, it : function($this:Hash) : * {
+ var $r : *;
+ $r = new Array();
+ for(var $k : String in $this.h) $r.push($k);
+ return $r;
+ }(this).iterator(), hasNext : function() : * {
+ return this.it.hasNext();
+ }, next : function() : * {
+ var i : * = this.it.next();
+ return this.ref[i];
+ }}
+ }
+ public function toString() : String {
+ var s : StringBuf = new StringBuf();
+ s.add("{");
+ var it : * = this.keys();
+ { var $it : * = it;
+ while( $it.hasNext() ) { var i : String = $it.next();
+ {
+ s.add(i);
+ s.add(" => ");
+ s.add((this.get(i)).toString());
+ if(it.hasNext()) s.add(", ");
+ }
+ }}
+ s.add("}");
+ return s.toString();
+ }
+ protected var h : *;
+ }
+}
--- /dev/null
+package hxasm {
+ public class Index extends enum {
+ public static const __isenum : Boolean = true;
+ public function Index( t : String, index : int, p : Array = null ) : void { this.tag = t; this.index = index; this.params = p; }
+ public static function Idx(v : int) : Index { return new Index("Idx",0,[v]); }
+ }
+}
--- /dev/null
+package hxasm {
+ public class JumpStyle extends enum {
+ public static const __isenum : Boolean = true;
+ public function JumpStyle( t : String, index : int, p : Array = null ) : void { this.tag = t; this.index = index; this.params = p; }
+ public static var JAlways : JumpStyle = new JumpStyle("JAlways",4);
+ public static var JEq : JumpStyle = new JumpStyle("JEq",7);
+ public static var JFalse : JumpStyle = new JumpStyle("JFalse",6);
+ public static var JGt : JumpStyle = new JumpStyle("JGt",11);
+ public static var JGte : JumpStyle = new JumpStyle("JGte",12);
+ public static var JLt : JumpStyle = new JumpStyle("JLt",9);
+ public static var JLte : JumpStyle = new JumpStyle("JLte",10);
+ public static var JNeq : JumpStyle = new JumpStyle("JNeq",8);
+ public static var JNotGt : JumpStyle = new JumpStyle("JNotGt",2);
+ public static var JNotGte : JumpStyle = new JumpStyle("JNotGte",3);
+ public static var JNotLt : JumpStyle = new JumpStyle("JNotLt",0);
+ public static var JNotLte : JumpStyle = new JumpStyle("JNotLte",1);
+ public static var JPhysEq : JumpStyle = new JumpStyle("JPhysEq",13);
+ public static var JPhysNeq : JumpStyle = new JumpStyle("JPhysNeq",14);
+ public static var JTrue : JumpStyle = new JumpStyle("JTrue",5);
+ }
+}
--- /dev/null
+package hxasm {
+
+ public class Name extends enum {
+ public static const __isenum : Boolean = true;
+ public function Name( t : String, index : int, p : Array = null ) : void { this.tag = t; this.index = index; this.params = p; }
+ public static function NMultiNameLate(nset : Index) : Name { return new Name("NMultiNameLate",1,[nset]); }
+ public static function NName(name : Index, namespace : Index) : Name { return new Name("NName",0,[name,namespace]); }
+ }
+}
--- /dev/null
+package hxasm {
+
+ public class OpCode extends enum {
+ public static const __isenum : Boolean = true;
+ public function OpCode( t : String, index : int, p : Array = null ) : void { this.tag = t; this.index = index; this.params = p; }
+ public static function OArray(nvalues : int) : OpCode { return new OpCode("OArray",45,[nvalues]); }
+ public static var OAsAny : OpCode = new OpCode("OAsAny",73);
+ public static var OAsObject : OpCode = new OpCode("OAsObject",76);
+ public static var OAsString : OpCode = new OpCode("OAsString",74);
+ public static function OAsType(t : Index) : OpCode { return new OpCode("OAsType",75,[t]); }
+ public static var OBreakPoint : OpCode = new OpCode("OBreakPoint",0);
+ public static function OBreakPointLine(n : int) : OpCode { return new OpCode("OBreakPointLine",89,[n]); }
+ public static function OByte(byte : int) : OpCode { return new OpCode("OByte",92,[byte]); }
+ public static function OCallMethod(slot : int, nargs : int) : OpCode { return new OpCode("OCallMethod",33,[slot,nargs]); }
+ public static function OCallPropLex(name : Index, nargs : int) : OpCode { return new OpCode("OCallPropLex",41,[name,nargs]); }
+ public static function OCallPropVoid(name : Index, nargs : int) : OpCode { return new OpCode("OCallPropVoid",43,[name,nargs]); }
+ public static function OCallProperty(name : Index, nargs : int) : OpCode { return new OpCode("OCallProperty",36,[name,nargs]); }
+ public static function OCallStack(nargs : int) : OpCode { return new OpCode("OCallStack",31,[nargs]); }
+ public static function OCallStatic(meth : Index, nargs : int) : OpCode { return new OpCode("OCallStatic",34,[meth,nargs]); }
+ public static function OCallSuper(name : Index, nargs : int) : OpCode { return new OpCode("OCallSuper",35,[name,nargs]); }
+ public static function OCallSuperVoid(name : Index, nargs : int) : OpCode { return new OpCode("OCallSuperVoid",42,[name,nargs]); }
+ public static function OCast(t : Index) : OpCode { return new OpCode("OCast",72,[t]); }
+ public static function OCatch(c : int) : OpCode { return new OpCode("OCatch",48,[c]); }
+ public static var OCheckIsXml : OpCode = new OpCode("OCheckIsXml",71);
+ public static function OClassDef(c : Index) : OpCode { return new OpCode("OClassDef",47,[c]); }
+ public static function OConstruct(nargs : int) : OpCode { return new OpCode("OConstruct",32,[nargs]); }
+ public static function OConstructProperty(name : Index, nargs : int) : OpCode { return new OpCode("OConstructProperty",40,[name,nargs]); }
+ public static function OConstructSuper(nargs : int) : OpCode { return new OpCode("OConstructSuper",39,[nargs]); }
+ public static function ODebugFile(file : Index) : OpCode { return new OpCode("ODebugFile",88,[file]); }
+ public static function ODebugLine(line : int) : OpCode { return new OpCode("ODebugLine",87,[line]); }
+ public static function ODebugReg(name : Index, r : int, line : int) : OpCode { return new OpCode("ODebugReg",86,[name,r,line]); }
+ public static function ODecrIReg(r : int) : OpCode { return new OpCode("ODecrIReg",83,[r]); }
+ public static function ODecrReg(r : int) : OpCode { return new OpCode("ODecrReg",78,[r]); }
+ public static function ODeleteProp(p : Index) : OpCode { return new OpCode("ODeleteProp",60,[p]); }
+ public static var ODup : OpCode = new OpCode("ODup",22);
+ public static var OFalse : OpCode = new OpCode("OFalse",19);
+ public static function OFindDefinition(d : Index) : OpCode { return new OpCode("OFindDefinition",51,[d]); }
+ public static function OFindProp(p : Index) : OpCode { return new OpCode("OFindProp",50,[p]); }
+ public static function OFindPropStrict(p : Index) : OpCode { return new OpCode("OFindPropStrict",49,[p]); }
+ public static function OFloat(v : Index) : OpCode { return new OpCode("OFloat",26,[v]); }
+ public static var OForEach : OpCode = new OpCode("OForEach",15);
+ public static var OForIn : OpCode = new OpCode("OForIn",11);
+ public static function OFunction(f : Index) : OpCode { return new OpCode("OFunction",30,[f]); }
+ public static var OGetGlobalScope : OpCode = new OpCode("OGetGlobalScope",56);
+ public static function OGetLex(p : Index) : OpCode { return new OpCode("OGetLex",52,[p]); }
+ public static function OGetProp(p : Index) : OpCode { return new OpCode("OGetProp",58,[p]); }
+ public static function OGetScope(n : int) : OpCode { return new OpCode("OGetScope",57,[n]); }
+ public static function OGetSlot(s : int) : OpCode { return new OpCode("OGetSlot",61,[s]); }
+ public static function OGetSuper(v : Index) : OpCode { return new OpCode("OGetSuper",3,[v]); }
+ public static var OHasNext : OpCode = new OpCode("OHasNext",12);
+ public static function OIncrIReg(r : int) : OpCode { return new OpCode("OIncrIReg",82,[r]); }
+ public static function OIncrReg(r : int) : OpCode { return new OpCode("OIncrReg",77,[r]); }
+ public static function OInitProp(p : Index) : OpCode { return new OpCode("OInitProp",59,[p]); }
+ public static var OInstanceOf : OpCode = new OpCode("OInstanceOf",80);
+ public static function OInt(v : int) : OpCode { return new OpCode("OInt",17,[v]); }
+ public static function OIntRef(v : Index) : OpCode { return new OpCode("OIntRef",25,[v]); }
+ public static function OIsType(t : Index) : OpCode { return new OpCode("OIsType",81,[t]); }
+ public static function OJump(j : JumpStyle, delta : int) : OpCode { return new OpCode("OJump",7,[j,delta]); }
+ public static var OLabel : OpCode = new OpCode("OLabel",6);
+ public static var ONaN : OpCode = new OpCode("ONaN",20);
+ public static function ONamespace(v : Index) : OpCode { return new OpCode("ONamespace",28,[v]); }
+ public static var ONewBlock : OpCode = new OpCode("ONewBlock",46);
+ public static function ONext(r1 : int, r2 : int) : OpCode { return new OpCode("ONext",29,[r1,r2]); }
+ public static var ONop : OpCode = new OpCode("ONop",1);
+ public static var ONull : OpCode = new OpCode("ONull",13);
+ public static function OObject(nfields : int) : OpCode { return new OpCode("OObject",44,[nfields]); }
+ public static function OOp(op : Operation) : OpCode { return new OpCode("OOp",91,[op]); }
+ public static var OPop : OpCode = new OpCode("OPop",21);
+ public static var OPopScope : OpCode = new OpCode("OPopScope",10);
+ public static var OPushWith : OpCode = new OpCode("OPushWith",9);
+ public static function OReg(r : int) : OpCode { return new OpCode("OReg",54,[r]); }
+ public static function ORegKill(r : int) : OpCode { return new OpCode("ORegKill",5,[r]); }
+ public static var ORet : OpCode = new OpCode("ORet",38);
+ public static var ORetVoid : OpCode = new OpCode("ORetVoid",37);
+ public static var OScope : OpCode = new OpCode("OScope",27);
+ public static function OSetProp(p : Index) : OpCode { return new OpCode("OSetProp",53,[p]); }
+ public static function OSetReg(r : int) : OpCode { return new OpCode("OSetReg",55,[r]); }
+ public static function OSetSlot(s : int) : OpCode { return new OpCode("OSetSlot",62,[s]); }
+ public static function OSetSuper(v : Index) : OpCode { return new OpCode("OSetSuper",4,[v]); }
+ public static var OSetThis : OpCode = new OpCode("OSetThis",85);
+ public static function OSmallInt(v : int) : OpCode { return new OpCode("OSmallInt",16,[v]); }
+ public static function OString(v : Index) : OpCode { return new OpCode("OString",24,[v]); }
+ public static var OSwap : OpCode = new OpCode("OSwap",23);
+ public static function OSwitch(def : int, deltas : Array) : OpCode { return new OpCode("OSwitch",8,[def,deltas]); }
+ public static var OThis : OpCode = new OpCode("OThis",84);
+ public static var OThrow : OpCode = new OpCode("OThrow",2);
+ public static var OTimestamp : OpCode = new OpCode("OTimestamp",90);
+ public static var OToBool : OpCode = new OpCode("OToBool",69);
+ public static var OToInt : OpCode = new OpCode("OToInt",66);
+ public static var OToNumber : OpCode = new OpCode("OToNumber",68);
+ public static var OToObject : OpCode = new OpCode("OToObject",70);
+ public static var OToString : OpCode = new OpCode("OToString",63);
+ public static var OToUInt : OpCode = new OpCode("OToUInt",67);
+ public static var OToXml : OpCode = new OpCode("OToXml",64);
+ public static var OToXmlAttr : OpCode = new OpCode("OToXmlAttr",65);
+ public static var OTrue : OpCode = new OpCode("OTrue",18);
+ public static var OTypeof : OpCode = new OpCode("OTypeof",79);
+ public static var OUndefined : OpCode = new OpCode("OUndefined",14);
+ }
+}
--- /dev/null
+package hxasm {
+
+ import flash.utils.ByteArray;
+
+ public class OpWriter {
+ public function OpWriter() : void {
+ this.o = new Output();
+ }
+ protected var o : Output;
+ protected function _int(i : int) : void {
+ writeInt(this.o,i);
+ }
+ protected function b(v : int) : void {
+ this.o.writeChar(v);
+ }
+ protected function reg(v : int) : void {
+ this.o.writeChar(v);
+ }
+ protected function idx(i : Index) : void {
+ var $e : enum = (i);
+ switch( $e.index ) {
+ case 0:
+ var i1 : int = $e.params[0];
+ {
+ this._int(i1);
+ }break;
+ }
+ }
+ protected function jumpCode(j : JumpStyle) : int {
+ return function($this:OpWriter) : int {
+ var $r : int;
+ var $e : enum = (j);
+ switch( $e.index ) {
+ case 0:
+ {
+ $r = 12;
+ }break;
+ case 1:
+ {
+ $r = 13;
+ }break;
+ case 2:
+ {
+ $r = 14;
+ }break;
+ case 3:
+ {
+ $r = 15;
+ }break;
+ case 4:
+ {
+ $r = 16;
+ }break;
+ case 5:
+ {
+ $r = 17;
+ }break;
+ case 6:
+ {
+ $r = 18;
+ }break;
+ case 7:
+ {
+ $r = 19;
+ }break;
+ case 8:
+ {
+ $r = 20;
+ }break;
+ case 9:
+ {
+ $r = 21;
+ }break;
+ case 10:
+ {
+ $r = 22;
+ }break;
+ case 11:
+ {
+ $r = 23;
+ }break;
+ case 12:
+ {
+ $r = 24;
+ }break;
+ case 13:
+ {
+ $r = 25;
+ }break;
+ case 14:
+ {
+ $r = 26;
+ }break;
+ default:{
+ $r = null;
+ }break;
+ }
+ return $r;
+ }(this);
+ }
+ protected function operationCode(o : Operation) : int {
+ return function($this:OpWriter) : int {
+ var $r : int;
+ var $e : enum = (o);
+ switch( $e.index ) {
+ case 0:
+ {
+ $r = 135;
+ }break;
+ case 1:
+ {
+ $r = 144;
+ }break;
+ case 2:
+ {
+ $r = 145;
+ }break;
+ case 3:
+ {
+ $r = 147;
+ }break;
+ case 4:
+ {
+ $r = 150;
+ }break;
+ case 5:
+ {
+ $r = 151;
+ }break;
+ case 6:
+ {
+ $r = 160;
+ }break;
+ case 7:
+ {
+ $r = 161;
+ }break;
+ case 8:
+ {
+ $r = 162;
+ }break;
+ case 9:
+ {
+ $r = 163;
+ }break;
+ case 10:
+ {
+ $r = 164;
+ }break;
+ case 11:
+ {
+ $r = 165;
+ }break;
+ case 12:
+ {
+ $r = 166;
+ }break;
+ case 13:
+ {
+ $r = 167;
+ }break;
+ case 14:
+ {
+ $r = 168;
+ }break;
+ case 15:
+ {
+ $r = 169;
+ }break;
+ case 16:
+ {
+ $r = 170;
+ }break;
+ case 17:
+ {
+ $r = 171;
+ }break;
+ case 18:
+ {
+ $r = 172;
+ }break;
+ case 19:
+ {
+ $r = 173;
+ }break;
+ case 20:
+ {
+ $r = 174;
+ }break;
+ case 21:
+ {
+ $r = 175;
+ }break;
+ case 22:
+ {
+ $r = 176;
+ }break;
+ case 23:
+ {
+ $r = 179;
+ }break;
+ case 24:
+ {
+ $r = 180;
+ }break;
+ case 25:
+ {
+ $r = 192;
+ }break;
+ case 26:
+ {
+ $r = 193;
+ }break;
+ case 27:
+ {
+ $r = 196;
+ }break;
+ case 28:
+ {
+ $r = 197;
+ }break;
+ case 29:
+ {
+ $r = 198;
+ }break;
+ case 30:
+ {
+ $r = 199;
+ }break;
+ default:{
+ $r = null;
+ }break;
+ }
+ return $r;
+ }(this);
+ }
+ public function write(op : OpCode) : void {
+ var $e : enum = (op);
+ switch( $e.index ) {
+ case 0:
+ {
+ this.b(1);
+ }break;
+ case 1:
+ {
+ this.b(2);
+ }break;
+ case 2:
+ {
+ this.b(3);
+ }break;
+ case 3:
+ var v : Index = $e.params[0];
+ {
+ this.b(4);
+ this.idx(v);
+ }break;
+ case 4:
+ var v2 : Index = $e.params[0];
+ {
+ this.b(5);
+ this.idx(v2);
+ }break;
+ case 5:
+ var r : int = $e.params[0];
+ {
+ this.b(8);
+ this.reg(r);
+ }break;
+ case 6:
+ {
+ this.b(9);
+ }break;
+ case 7:
+ var delta : int = $e.params[1], j : JumpStyle = $e.params[0];
+ {
+ this.b(this.jumpCode(j));
+ this.o.writeInt24(delta);
+ }break;
+ case 8:
+ var deltas : Array = $e.params[1], def : int = $e.params[0];
+ {
+ this.b(27);
+ this.o.writeInt24(def);
+ this._int(deltas.length - 1);
+ {
+ var _g : int = 0;
+ while(_g < deltas.length) {
+ var d : int = deltas[_g];
+ ++_g;
+ this.o.writeInt24(d);
+ }
+ }
+ }break;
+ case 9:
+ {
+ this.b(28);
+ }break;
+ case 10:
+ {
+ this.b(29);
+ }break;
+ case 11:
+ {
+ this.b(30);
+ }break;
+ case 12:
+ {
+ this.b(31);
+ }break;
+ case 13:
+ {
+ this.b(32);
+ }break;
+ case 14:
+ {
+ this.b(33);
+ }break;
+ case 15:
+ {
+ this.b(35);
+ }break;
+ case 16:
+ var v3 : int = $e.params[0];
+ {
+ this.b(36);
+ this.o.writeInt8(v3);
+ }break;
+ case 17:
+ var v4 : int = $e.params[0];
+ {
+ this.b(37);
+ this._int(v4);
+ }break;
+ case 18:
+ {
+ this.b(38);
+ }break;
+ case 19:
+ {
+ this.b(39);
+ }break;
+ case 20:
+ {
+ this.b(40);
+ }break;
+ case 21:
+ {
+ this.b(41);
+ }break;
+ case 22:
+ {
+ this.b(42);
+ }break;
+ case 23:
+ {
+ this.b(43);
+ }break;
+ case 24:
+ var v5 : Index = $e.params[0];
+ {
+ this.b(44);
+ this.idx(v5);
+ }break;
+ case 25:
+ var v6 : Index = $e.params[0];
+ {
+ this.b(45);
+ this.idx(v6);
+ }break;
+ case 26:
+ var v7 : Index = $e.params[0];
+ {
+ this.b(47);
+ this.idx(v7);
+ }break;
+ case 27:
+ {
+ this.b(48);
+ }break;
+ case 28:
+ var v8 : Index = $e.params[0];
+ {
+ this.b(49);
+ this.idx(v8);
+ }break;
+ case 29:
+ var r2 : int = $e.params[1], r1 : int = $e.params[0];
+ {
+ this.b(50);
+ this._int(r1);
+ this._int(r2);
+ }break;
+ case 30:
+ var f : Index = $e.params[0];
+ {
+ this.b(64);
+ this.idx(f);
+ }break;
+ case 31:
+ var n : int = $e.params[0];
+ {
+ this.b(65);
+ this._int(n);
+ }break;
+ case 32:
+ var n2 : int = $e.params[0];
+ {
+ this.b(66);
+ this._int(n2);
+ }break;
+ case 33:
+ var n3 : int = $e.params[1], s : int = $e.params[0];
+ {
+ this.b(67);
+ this._int(s);
+ this._int(n3);
+ }break;
+ case 34:
+ var n4 : int = $e.params[1], m : Index = $e.params[0];
+ {
+ this.b(68);
+ this.idx(m);
+ this._int(n4);
+ }break;
+ case 35:
+ var n5 : int = $e.params[1], p : Index = $e.params[0];
+ {
+ this.b(69);
+ this.idx(p);
+ this._int(n5);
+ }break;
+ case 36:
+ var n6 : int = $e.params[1], p2 : Index = $e.params[0];
+ {
+ this.b(70);
+ this.idx(p2);
+ this._int(n6);
+ }break;
+ case 37:
+ {
+ this.b(71);
+ }break;
+ case 38:
+ {
+ this.b(72);
+ }break;
+ case 39:
+ var n7 : int = $e.params[0];
+ {
+ this.b(73);
+ this._int(n7);
+ }break;
+ case 40:
+ var n8 : int = $e.params[1], p3 : Index = $e.params[0];
+ {
+ this.b(74);
+ this.idx(p3);
+ this._int(n8);
+ }break;
+ case 41:
+ var n9 : int = $e.params[1], p4 : Index = $e.params[0];
+ {
+ this.b(76);
+ this.idx(p4);
+ this._int(n9);
+ }break;
+ case 42:
+ var n10 : int = $e.params[1], p5 : Index = $e.params[0];
+ {
+ this.b(78);
+ this.idx(p5);
+ this._int(n10);
+ }break;
+ case 43:
+ var n11 : int = $e.params[1], p6 : Index = $e.params[0];
+ {
+ this.b(79);
+ this.idx(p6);
+ this._int(n11);
+ }break;
+ case 44:
+ var n12 : int = $e.params[0];
+ {
+ this.b(85);
+ this._int(n12);
+ }break;
+ case 45:
+ var n13 : int = $e.params[0];
+ {
+ this.b(86);
+ this._int(n13);
+ }break;
+ case 46:
+ {
+ this.b(87);
+ }break;
+ case 47:
+ var c : Index = $e.params[0];
+ {
+ this.b(88);
+ this.idx(c);
+ }break;
+ case 48:
+ var c2 : int = $e.params[0];
+ {
+ this.b(90);
+ this._int(c2);
+ }break;
+ case 49:
+ var p7 : Index = $e.params[0];
+ {
+ this.b(93);
+ this.idx(p7);
+ }break;
+ case 50:
+ var p8 : Index = $e.params[0];
+ {
+ this.b(94);
+ this.idx(p8);
+ }break;
+ case 51:
+ var d2 : Index = $e.params[0];
+ {
+ this.b(95);
+ this.idx(d2);
+ }break;
+ case 52:
+ var p9 : Index = $e.params[0];
+ {
+ this.b(96);
+ this.idx(p9);
+ }break;
+ case 53:
+ var p10 : Index = $e.params[0];
+ {
+ this.b(97);
+ this.idx(p10);
+ }break;
+ case 54:
+ var r3 : int = $e.params[0];
+ {
+ switch(r3) {
+ case 0:{
+ this.b(208);
+ }break;
+ case 1:{
+ this.b(209);
+ }break;
+ case 2:{
+ this.b(210);
+ }break;
+ case 3:{
+ this.b(211);
+ }break;
+ default:{
+ this.b(98);
+ this.reg(r3);
+ }break;
+ }
+ }break;
+ case 55:
+ var r4 : int = $e.params[0];
+ {
+ switch(r4) {
+ case 0:{
+ this.b(212);
+ }break;
+ case 1:{
+ this.b(213);
+ }break;
+ case 2:{
+ this.b(214);
+ }break;
+ case 3:{
+ this.b(215);
+ }break;
+ default:{
+ this.b(99);
+ this.reg(r4);
+ }break;
+ }
+ }break;
+ case 56:
+ {
+ this.b(100);
+ }break;
+ case 57:
+ var n14 : int = $e.params[0];
+ {
+ this.b(101);
+ this.b(n14);
+ }break;
+ case 58:
+ var p11 : Index = $e.params[0];
+ {
+ this.b(102);
+ this.idx(p11);
+ }break;
+ case 59:
+ var p12 : Index = $e.params[0];
+ {
+ this.b(104);
+ this.idx(p12);
+ }break;
+ case 60:
+ var p13 : Index = $e.params[0];
+ {
+ this.b(106);
+ this.idx(p13);
+ }break;
+ case 61:
+ var s2 : int = $e.params[0];
+ {
+ this.b(108);
+ this._int(s2);
+ }break;
+ case 62:
+ var s3 : int = $e.params[0];
+ {
+ this.b(109);
+ this._int(s3);
+ }break;
+ case 63:
+ {
+ this.b(112);
+ }break;
+ case 64:
+ {
+ this.b(113);
+ }break;
+ case 65:
+ {
+ this.b(114);
+ }break;
+ case 66:
+ {
+ this.b(115);
+ }break;
+ case 67:
+ {
+ this.b(116);
+ }break;
+ case 68:
+ {
+ this.b(117);
+ }break;
+ case 69:
+ {
+ this.b(118);
+ }break;
+ case 70:
+ {
+ this.b(119);
+ }break;
+ case 71:
+ {
+ this.b(120);
+ }break;
+ case 72:
+ var t : Index = $e.params[0];
+ {
+ this.b(128);
+ this.idx(t);
+ }break;
+ case 73:
+ {
+ this.b(130);
+ }break;
+ case 74:
+ {
+ this.b(133);
+ }break;
+ case 75:
+ var t2 : Index = $e.params[0];
+ {
+ this.b(134);
+ this.idx(t2);
+ }break;
+ case 76:
+ {
+ this.b(137);
+ }break;
+ case 77:
+ var r5 : int = $e.params[0];
+ {
+ this.b(146);
+ this.reg(r5);
+ }break;
+ case 78:
+ var r6 : int = $e.params[0];
+ {
+ this.b(148);
+ this.reg(r6);
+ }break;
+ case 79:
+ {
+ this.b(149);
+ }break;
+ case 80:
+ {
+ this.b(177);
+ }break;
+ case 81:
+ var t3 : Index = $e.params[0];
+ {
+ this.b(178);
+ this.idx(t3);
+ }break;
+ case 82:
+ var r7 : int = $e.params[0];
+ {
+ this.b(194);
+ this.reg(r7);
+ }break;
+ case 83:
+ var r8 : int = $e.params[0];
+ {
+ this.b(195);
+ this.reg(r8);
+ }break;
+ case 84:
+ {
+ this.b(208);
+ }break;
+ case 85:
+ {
+ this.b(212);
+ }break;
+ case 86:
+ var line : int = $e.params[2], r9 : int = $e.params[1], name : Index = $e.params[0];
+ {
+ this.b(239);
+ this.idx(name);
+ this.reg(r9);
+ this._int(line);
+ }break;
+ case 87:
+ var line2 : int = $e.params[0];
+ {
+ this.b(240);
+ this._int(line2);
+ }break;
+ case 88:
+ var file : Index = $e.params[0];
+ {
+ this.b(241);
+ this.idx(file);
+ }break;
+ case 89:
+ var n15 : int = $e.params[0];
+ {
+ this.b(242);
+ this._int(n15);
+ }break;
+ case 90:
+ {
+ this.b(243);
+ }break;
+ case 91:
+ var op1 : Operation = $e.params[0];
+ {
+ this.b(this.operationCode(op1));
+ }break;
+ case 92:
+ var byte : int = $e.params[0];
+ {
+ this.b(byte);
+ }break;
+ }
+ }
+ public function getBytes() : ByteArray {
+ return this.o.getBytes();
+ }
+ static public function writeInt(o : Output,n : int) : void {
+ var e : int = n >>> 28;
+ var d : int = (n >> 21) & 127;
+ var c : int = (n >> 14) & 127;
+ var b : int = (n >> 7) & 127;
+ var a : int = n & 127;
+ if(b != 0 || c != 0 || d != 0 || e != 0) {
+ o.writeChar(a | 128);
+ if(c != 0 || d != 0 || e != 0) {
+ o.writeChar(b | 128);
+ if(d != 0 || e != 0) {
+ o.writeChar(c | 128);
+ if(e != 0) {
+ o.writeChar(d | 128);
+ o.writeChar(e);
+ }
+ else o.writeChar(d);
+ }
+ else o.writeChar(c);
+ }
+ else o.writeChar(b);
+ }
+ else o.writeChar(a);
+ }
+ }
+}
--- /dev/null
+package hxasm {
+ public class Operation extends enum {
+ public static const __isenum : Boolean = true;
+ public function Operation( t : String, index : int, p : Array = null ) : void { this.tag = t; this.index = index; this.params = p; }
+ public static var OpAdd : Operation = new Operation("OpAdd",6);
+ public static var OpAnd : Operation = new Operation("OpAnd",14);
+ public static var OpAs : Operation = new Operation("OpAs",0);
+ public static var OpBitNot : Operation = new Operation("OpBitNot",5);
+ public static var OpDecr : Operation = new Operation("OpDecr",3);
+ public static var OpDiv : Operation = new Operation("OpDiv",9);
+ public static var OpEq : Operation = new Operation("OpEq",17);
+ public static var OpGt : Operation = new Operation("OpGt",21);
+ public static var OpGte : Operation = new Operation("OpGte",22);
+ public static var OpIAdd : Operation = new Operation("OpIAdd",28);
+ public static var OpIDecr : Operation = new Operation("OpIDecr",26);
+ public static var OpIIncr : Operation = new Operation("OpIIncr",25);
+ public static var OpIMul : Operation = new Operation("OpIMul",30);
+ public static var OpINeg : Operation = new Operation("OpINeg",27);
+ public static var OpISub : Operation = new Operation("OpISub",29);
+ public static var OpIn : Operation = new Operation("OpIn",24);
+ public static var OpIncr : Operation = new Operation("OpIncr",2);
+ public static var OpIs : Operation = new Operation("OpIs",23);
+ public static var OpLt : Operation = new Operation("OpLt",19);
+ public static var OpLte : Operation = new Operation("OpLte",20);
+ public static var OpMod : Operation = new Operation("OpMod",10);
+ public static var OpMul : Operation = new Operation("OpMul",8);
+ public static var OpNeg : Operation = new Operation("OpNeg",1);
+ public static var OpNot : Operation = new Operation("OpNot",4);
+ public static var OpOr : Operation = new Operation("OpOr",15);
+ public static var OpPhysEq : Operation = new Operation("OpPhysEq",18);
+ public static var OpShl : Operation = new Operation("OpShl",11);
+ public static var OpShr : Operation = new Operation("OpShr",12);
+ public static var OpSub : Operation = new Operation("OpSub",7);
+ public static var OpUShr : Operation = new Operation("OpUShr",13);
+ public static var OpXor : Operation = new Operation("OpXor",16);
+ }
+}
--- /dev/null
+package hxasm {
+ import flash.utils.Endian;
+ import flash.utils.ByteArray;
+
+ public class Output {
+ public function Output() : void {
+ this.b = new ByteArray();
+ this.b.endian = Endian.LITTLE_ENDIAN;
+ }
+ protected var b : ByteArray;
+ public function write(str : String) : void {
+ this.b.writeUTFBytes(str);
+ }
+ public function writeBinary(b : ByteArray) : void {
+ this.b.writeBytes(b);
+ }
+ public function writeChar(c : int) : void {
+ this.b.writeByte(c);
+ }
+ public function writeInt32(i : int) : void {
+ this.b.writeInt(i);
+ }
+ public function writeUInt32(i : int) : void {
+ this.b.writeUnsignedInt(i);
+ }
+ public function writeDouble(f : Number) : void {
+ this.b.writeDouble(f);
+ }
+ public function writeUInt16(x : int) : void {
+ if(x < 0 || x > 65535) throw "Overflow";
+ this.writeChar(x & 255);
+ this.writeChar(x >> 8);
+ }
+ public function writeUInt24(x : int) : void {
+ if(x < 0 || x > 16777215) throw "Overflow";
+ this.writeChar(x & 255);
+ this.writeChar((x >> 8) & 255);
+ this.writeChar(x >> 16);
+ }
+ public function writeInt24(x : int) : void {
+ if(x < -8388608 || x > 8388607) throw "Overflow";
+ if(x < 0) this.writeUInt24(16777216 + x);
+ else this.writeUInt24(x);
+ }
+ public function writeInt8(c : int) : void {
+ if(c < -128 || c > 127) throw "Overflow";
+ this.writeChar(c & 255);
+ }
+ public function getBytes() : ByteArray {
+ return this.b;
+ }
+ }
+}
--- /dev/null
+package hxasm{
+ public class StringBuf {
+ public function StringBuf() : void {
+ this.b = "";
+ }
+ public function add(x : * = null) : void {
+ this.b += x;
+ }
+ public function addSub(s : String,pos : int,len : * = null) : void {
+ if(len == null) this.b += s.substr(pos);
+ else this.b += s.substr(pos,len);
+ }
+ public function addChar(c : int) : void {
+ this.b += String["fromCharCode"](c);
+ }
+ public function toString() : String {
+ return this.b;
+ }
+ protected var b : *;
+ }
+}
--- /dev/null
+package hxasm {
+ import flash.utils.getDefinitionByName;
+ import flash.utils.getQualifiedClassName;
+ import flash.utils.describeType;
+ import flash.utils.getQualifiedSuperclassName;
+ public class Type {
+ static public function toEnum(t : *) : Class {
+ try {
+ if(!t.__isenum) return null;
+ return t;
+ }
+ catch( e : * ){
+ null;
+ }
+ return null;
+ }
+ static public function toClass(t : *) : Class {
+ try {
+ if(!t.hasOwnProperty("prototype")) return null;
+ return t;
+ }
+ catch( e : * ){
+ null;
+ }
+ return null;
+ }
+ static public function getClass(o : *) : Class {
+ var cname : String = getQualifiedClassName(o);
+ if(cname == "null" || cname == "Object" || cname == "int" || cname == "Number" || cname == "Boolean") return null;
+ if(o.hasOwnProperty("prototype")) return null;
+ var c : * = getDefinitionByName(cname) as Class;
+ if(c.__isenum) return null;
+ return c;
+ }
+ static public function getEnum(o : *) : Class {
+ var cname : String = getQualifiedClassName(o);
+ if(cname == "null" || cname.substr(0,8) == "builtin.") return null;
+ if(o.hasOwnProperty("prototype")) return null;
+ var c : * = getDefinitionByName(cname) as Class;
+ if(!c.__isenum) return null;
+ return c;
+ }
+ static public function getSuperClass(c : Class) : Class {
+ var cname : String = getQualifiedSuperclassName(c);
+ if(cname == "Object") return null;
+ return getDefinitionByName(cname) as Class;
+ }
+ static public function getClassName(c : Class) : String {
+ if(c == null) return null;
+ var str : String = getQualifiedClassName(c);
+ return str.split("::").join(".");
+ }
+ static public function getEnumName(e : Class) : String {
+ var n : String = getQualifiedClassName(e);
+ return n;
+ }
+ static public function resolveClass(name : String) : Class {
+ var cl : Class;
+ {
+ try {
+ cl = getDefinitionByName(name) as Class;
+ if(cl.__isenum) return null;
+ return cl;
+ }
+ catch( e : * ){
+ return null;
+ }
+ if(cl == null || cl.__name__ == null) return null;
+ else null;
+ }
+ return cl;
+ }
+ static public function resolveEnum(name : String) : Class {
+ var e : *;
+ {
+ try {
+ e = getDefinitionByName(name);
+ if(!e.__isenum) return null;
+ return e;
+ }
+ catch( e1 : * ){
+ return null;
+ }
+ if(e == null || e.__ename__ == null) return null;
+ else null;
+ }
+ return e;
+ }
+ static public function createInstance(cl : Class,args : Array) : * {
+ return function() : * {
+ var $r : *;
+ switch(args.length) {
+ case 0:{
+ $r = new cl();
+ }break;
+ case 1:{
+ $r = new cl(args[0]);
+ }break;
+ case 2:{
+ $r = new cl(args[0],args[1]);
+ }break;
+ case 3:{
+ $r = new cl(args[0],args[1],args[2]);
+ }break;
+ case 4:{
+ $r = new cl(args[0],args[1],args[2],args[3]);
+ }break;
+ case 5:{
+ $r = new cl(args[0],args[1],args[2],args[3],args[4]);
+ }break;
+ default:{
+ $r = function() : * {
+ var $r2 : *;
+ throw "Too many arguments";
+ return $r2;
+ }();
+ }break;
+ }
+ return $r;
+ }();
+ }
+ static public function getEnumConstructs(e : Class) : Array {
+ return e.__constructs__;
+ }
+ static public function enumEq(a : *,b : *) : Boolean {
+ if(a == b) return true;
+ try {
+ if(a.tag != b.tag) return false;
+ {
+ var _g1 : int = 0, _g : int = a.params.length;
+ while(_g1 < _g) {
+ var i : int = _g1++;
+ if(!enumEq(a.params[i],b.params[i])) return false;
+ }
+ }
+ }
+ catch( e : * ){
+ return false;
+ }
+ return true;
+ }
+ static public function enumConstructor(e : *) : String {
+ return e.tag;
+ }
+ static public function enumParameters(e : *) : Array {
+ return (e.params == null?[]:e.params);
+ }
+ static public function enumIndex(e : *) : int {
+ return e.index;
+ }
+ }
+}
--- /dev/null
+package hxasm {
+
+ import flash.utils.ByteArray;
+
+ public class Writer {
+ public function Writer(out : Output,ctx : Context) : void {
+ this.data = out;
+ this.ctx = ctx;
+ this.emptyIndex = Index.Idx(1);
+ }
+ protected var ctx : Context;
+ protected var data : Output;
+ protected var emptyIndex : Index;
+ protected function beginTag(id : int,len : int) : void {
+ if(len >= 63) {
+ this.data.writeUInt16((id << 6) | 63);
+ this.data.writeUInt32(len);
+ }
+ else this.data.writeUInt16((id << 6) | len);
+ }
+ protected function writeInt(n : int) : void {
+ OpWriter.writeInt(this.data,n);
+ }
+ protected function writeList(a : Array,write : Function) : void {
+ if(a.length == 0) {
+ this.writeInt(0);
+ return;
+ }
+ this.writeInt(a.length + 1);
+ {
+ var _g1 : int = 0, _g : int = a.length;
+ while(_g1 < _g) {
+ var i : int = _g1++;
+ write(a[i]);
+ }
+ }
+ }
+ protected function writeList2(a : Array,write : Function) : void {
+ this.writeInt(a.length);
+ {
+ var _g1 : int = 0, _g : int = a.length;
+ while(_g1 < _g) {
+ var i : int = _g1++;
+ write(a[i]);
+ }
+ }
+ }
+ protected function writeString(s : String) : void {
+ this.writeInt(s.length);
+ this.data.write(s);
+ }
+ protected function writeIndex(i : Index) : void {
+ var $e : enum = (i);
+ switch( $e.index ) {
+ case 0:
+ var n : int = $e.params[0];
+ {
+ this.writeInt(n);
+ }break;
+ }
+ }
+ protected function writeIndexOpt(i : Index) : void {
+ if(i == null) {
+ this.data.writeChar(0);
+ return;
+ }
+ this.writeIndex(i);
+ }
+ protected function writeNamespace(n : HNamespace) : void {
+ var $e : enum = (n);
+ switch( $e.index ) {
+ case 0:
+ var id : Index = $e.params[0];
+ {
+ this.data.writeChar(22);
+ this.writeIndex((id == null?this.emptyIndex:id));
+ }break;
+ case 1:
+ var ns : Index = $e.params[0];
+ {
+ this.data.writeChar(8);
+ this.writeIndex(ns);
+ }break;
+ }
+ }
+ protected function writeNsSet(n : Array) : void {
+ this.data.writeChar(n.length);
+ {
+ var _g : int = 0;
+ while(_g < n.length) {
+ var i : Index = n[_g];
+ ++_g;
+ this.writeIndex(i);
+ }
+ }
+ }
+ protected function writeName(n : Name) : void {
+ var $e : enum = (n);
+ switch( $e.index ) {
+ case 0:
+ var ns : Index = $e.params[1], id : Index = $e.params[0];
+ {
+ this.data.writeChar(7);
+ this.writeIndex(ns);
+ this.writeIndex(id);
+ }break;
+ case 1:
+ var nss : Index = $e.params[0];
+ {
+ this.data.writeChar(27);
+ this.writeIndex(nss);
+ }break;
+ }
+ }
+ protected function writeField(f : *) : void {
+ this.writeIndex(f.name);
+ var $e : enum = (f.kind);
+ switch( $e.index ) {
+ case 0:
+ var _const : * = $e.params[1], t : Index = $e.params[0];
+ {
+ this.data.writeChar((_const?6:0));
+ this.writeInt(f.slot);
+ this.writeIndexOpt(t);
+ this.data.writeChar(0);
+ }break;
+ case 1:
+ var isOverride : * = $e.params[2], isFinal : * = $e.params[1], t2 : Index = $e.params[0];
+ {
+ var flags : int = ((isFinal?16:0)) | ((isOverride?32:0));
+ this.data.writeChar(1 | flags);
+ this.writeInt(f.slot);
+ this.writeIndex(t2);
+ }break;
+ }
+ }
+ protected function writeClass(c : *) : void {
+ this.writeIndex(c.name);
+ this.writeIndex(c.superclass);
+ this.data.writeChar(0);
+ this.writeList2([],null);
+ this.writeIndex(c.constructorType);
+ this.writeList2(c.fields,this.writeField);
+ }
+ protected function writeStatics(c : *) : void {
+ this.writeIndex(c.statics);
+ this.writeList2(c.staticFields,this.writeField);
+ }
+ protected function writeMethodType(m : *) : void {
+ this.data.writeChar(m.args.length);
+ this.writeIndexOpt(m.ret);
+ {
+ var _g : int = 0, _g1 : Array = m.args;
+ while(_g < _g1.length) {
+ var a : Index = _g1[_g];
+ ++_g;
+ this.writeIndexOpt(a);
+ }
+ }
+ this.writeIndexOpt(null);
+ this.data.writeChar(0);
+ }
+ protected function writeMethod(m : *) : void {
+ this.writeIndex(m.type);
+ this.writeInt(m.maxStack);
+ this.writeInt(m.nRegs);
+ this.writeInt(0);
+ this.writeInt(m.maxScope);
+ var b : OpWriter = new OpWriter();
+ {
+ var _g : int = 0, _g1 : Array = m.opcodes;
+ while(_g < _g1.length) {
+ var o : OpCode = _g1[_g];
+ ++_g;
+ b.write(o);
+ }
+ }
+ var codeStr : ByteArray = b.getBytes();
+ this.writeInt(codeStr.length);
+ this.data.writeBinary(codeStr);
+ this.writeList2([],null);
+ this.writeList2([],null);
+ }
+ protected function writeInitSlot(c : *) : void {
+ this.writeIndex(c.name);
+ this.data.writeChar(4);
+ this.writeInt(1);
+ this.writeIndex(c.index);
+ }
+ protected function writeInit(init : Index,classes : Array) : void {
+ this.writeIndex(init);
+ this.writeList2(classes,this.writeInitSlot);
+ }
+ protected function writeAs3Header() : void {
+ var d : * = this.ctx.getDatas();
+ this.data.writeInt32(3014672);
+ this.writeList(d.ints,this.writeInt);
+ this.writeList([],null);
+ this.writeList(d.floats,this.data.writeDouble);
+ this.writeList(d.strings,this.writeString);
+ this.writeList(d.namespaces,this.writeNamespace);
+ this.writeList(d.nssets,this.writeNsSet);
+ this.writeList(d.names,this.writeName);
+ this.writeList2(d.mtypes,this.writeMethodType);
+ this.writeList2([],null);
+ this.writeList2(d.classes,this.writeClass);
+ {
+ var _g : int = 0, _g1 : Array = d.classes;
+ while(_g < _g1.length) {
+ var c : * = _g1[_g];
+ ++_g;
+ this.writeStatics(c);
+ }
+ }
+ this.writeList2([d.classes],function(f : Function,a1 : Index) : Function {
+ return function(a2 : Array) : void {
+ f(a1,a2);
+ return;
+ }
+ }(this.writeInit,d.init));
+ this.writeList2(d.methods,this.writeMethod);
+ }
+ protected function write() : void {
+ var out : Output = this.data;
+ out.write("FWS");
+ out.writeChar(9);
+ var header : Output = new Output();
+ this.data = header;
+ this.writeAs3Header();
+ this.data = out;
+ var header1 : ByteArray = header.getBytes();
+ var len : int = 23 + 6 + header1.length + (header1.length >= 63?6:2);
+ out.writeInt32(len);
+ {
+ var _g : int = 0, _g1 : Array = [120,0,3,232,0,0,11,184,0];
+ while(_g < _g1.length) {
+ var c : int = _g1[_g];
+ ++_g;
+ out.writeChar(c);
+ }
+ }
+ out.writeUInt16(7680);
+ out.writeUInt16(1);
+ this.beginTag(69,4);
+ out.writeInt32(25);
+ this.beginTag(72,header1.length);
+ out.writeBinary(header1);
+ this.beginTag(1,0);
+ this.beginTag(0,0);
+ }
+ static public function write(out : Output,ctx : Context) : void {
+ var w : Writer = new Writer(out,ctx);
+ w.write();
+ }
+ }
+}
--- /dev/null
+package hxasm{
+ public class enum {
+ public var tag : String;
+ public var index : int;
+ public var params : Array;
+ }
+}
--- /dev/null
+package it.sephiroth.expr
+{
+ import flash.utils.ByteArray;
+
+ import it.sephiroth.expr.ast.IExpression;
+
+ public class CompiledExpression
+ {
+ private var _expression: IExpression;
+ private var _symbols: SymbolTable;
+
+ public function CompiledExpression( expression: IExpression, symbols: SymbolTable )
+ {
+ _expression = expression;
+ _symbols = symbols;
+ }
+
+ public function execute( context: Object ): Number
+ {
+ for( var key: String in context )
+ {
+ var ident: Ident = _symbols.find( key );
+ if( ident )
+ {
+ ident.value = context[ key ];
+ }
+ }
+
+ return _expression.evaluate();
+ }
+
+ public function toString(): String
+ {
+ return _expression.toString();
+ }
+
+ public function compile(): ByteArray
+ {
+ var compiler: SWFCompiler = new SWFCompiler( _expression, _symbols );
+
+ return compiler.compile();
+ }
+
+ }
+}
\ No newline at end of file
--- /dev/null
+package it.sephiroth.expr
+{
+ public class Ident
+ {
+ private var _id: String;
+ private var _value: *;
+
+ public function Ident( id: String, value: * = null )
+ {
+ _id = id;
+ _value = value;
+ }
+
+ public function get id(): String
+ {
+ return _id;
+ }
+
+ public function get value(): *
+ {
+ return _value;
+ }
+
+ public function set value( v: * ): void
+ {
+ _value = v;
+ }
+
+ public function toString(): String
+ {
+ return _id;
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+package it.sephiroth.expr
+{
+ import it.sephiroth.expr.ast.AddExpression;
+ import it.sephiroth.expr.ast.CallExpression;
+ import it.sephiroth.expr.ast.DivExpression;
+ import it.sephiroth.expr.ast.IExpression;
+ import it.sephiroth.expr.ast.IdentExpression;
+ import it.sephiroth.expr.ast.MulExpression;
+ import it.sephiroth.expr.ast.NumberExpression;
+ import it.sephiroth.expr.ast.SubExpression;
+ import it.sephiroth.expr.ast.UnaryMinusExpression;
+ import it.sephiroth.expr.ast.UnaryPlusExpression;
+ import it.sephiroth.expr.errors.ExpressionError;
+
+ public class Parser
+ {
+ private var _token: Token;
+ private var _scanner: Scanner;
+ private var _symbols: SymbolTable;
+
+ public function Parser( scanner: Scanner )
+ {
+ _scanner = scanner;
+ _symbols = new SymbolTable();
+ }
+
+ public function parse(): CompiledExpression
+ {
+ _token = _scanner.nextToken();
+ var expr: IExpression = parseExpression();
+
+ if( _token.type == TokenType.EOF )
+ {
+ return new CompiledExpression( expr, _symbols );
+ }else
+ {
+ throw new ExpressionError( "Unexpected token: " + _token );
+ }
+ }
+
+ private function parseExpression(): IExpression
+ {
+ var operator: int;
+ var left: IExpression;
+ var right: IExpression;
+
+ left = parseTerm();
+
+ while( ( _token.type == TokenType.ADD ) || ( ( _token.type == TokenType.SUB ) ) )
+ {
+ operator = _token.type;
+ _token = _scanner.nextToken();
+ right = parseTerm();
+
+ if( operator == TokenType.ADD )
+ {
+ left = new AddExpression( left, right );
+ }else
+ {
+ left = new SubExpression( left, right );
+ }
+ }
+
+ return left;
+ }
+
+ private function parseTerm(): IExpression
+ {
+ var operator: int;
+ var left: IExpression;
+ var right: IExpression;
+
+ left = parseFactor();
+
+ while( ( _token.type == TokenType.MUL ) || ( ( _token.type == TokenType.DIV ) ) )
+ {
+ operator = _token.type;
+ _token = _scanner.nextToken();
+ right = parseFactor();
+
+ if( operator == TokenType.MUL )
+ {
+ left = new MulExpression( left, right );
+ }else
+ {
+ left = new DivExpression( left, right );
+ }
+ }
+
+ return left;
+ }
+
+ private function parseFactor(): IExpression
+ {
+ var tree: IExpression;
+ var unary: Array = new Array();
+
+ while( ( _token.type == TokenType.ADD ) || ( ( _token.type == TokenType.SUB ) ) )
+ {
+ unary.push( _token );
+ _token = _scanner.nextToken();
+ }
+
+ switch( _token.type )
+ {
+ case TokenType.NUM:
+ tree = new NumberExpression( _token.value );
+ _token = _scanner.nextToken();
+ break;
+
+ case TokenType.IDENT:
+ var ident_name: String = _token.value;
+ var ident: Ident = _symbols.findAndAdd( ident_name );
+ tree = new IdentExpression( ident );
+ _token = _scanner.nextToken();
+
+ if( _token.type == TokenType.LEFT_PAR )
+ {
+ var arguments: Array = new Array();
+ _token = _scanner.nextToken();
+
+ if( _token.type != TokenType.RIGHT_PAR )
+ {
+ do
+ {
+ arguments.push( parseExpression() );
+ } while( _token.type == TokenType.COMMA );
+
+ if( _token.type != TokenType.RIGHT_PAR )
+ {
+ throw new ExpressionError( "Unexpected token " + _token + ", expecting )" );
+ }else
+ {
+ _token = _scanner.nextToken();
+ }
+ }
+
+ tree = new CallExpression( ident, arguments );
+ }
+
+ break;
+
+ case TokenType.LEFT_PAR:
+ _token = _scanner.nextToken();
+ tree = parseExpression();
+ if( _token.type == TokenType.RIGHT_PAR )
+ {
+ _token = _scanner.nextToken();
+ }else
+ {
+ throw new ExpressionError( "Unexpected token " + _token + ", expecting )" );
+ }
+ break;
+
+ default:
+ throw new ExpressionError( "Unexpected token " + _token );
+ break;
+
+ }
+
+ while( unary.length > 0 )
+ {
+ if( unary.pop().type == TokenType.ADD )
+ {
+ tree = new UnaryPlusExpression( tree );
+ }else
+ {
+ tree = new UnaryMinusExpression( tree );
+ }
+ }
+
+ return tree;
+ }
+
+ }
+}
\ No newline at end of file
--- /dev/null
+package it.sephiroth.expr
+{
+ import flash.utils.ByteArray;
+
+ import hxasm.Context;
+ import hxasm.Index;
+ import hxasm.OpCode;
+ import hxasm.Output;
+ import hxasm.Writer;
+
+ import it.sephiroth.expr.ast.IExpression;
+
+ public class SWFCompiler
+ {
+ private var _max_stack: int;
+ private var _tnumber: Index;
+ private var _tany: Index;
+ private var _context: Context;
+
+ private var _symbols: SymbolTable;
+ private var _expression: IExpression;
+
+ public function SWFCompiler( expression: IExpression, symbols: SymbolTable )
+ {
+ _max_stack = 0;
+
+ _symbols = symbols;
+ _expression = expression;
+ }
+
+ public function compile(): ByteArray
+ {
+ var name: String;
+
+ _context = new Context();
+
+ _tnumber = _context.type( "Number" );
+ _tany = _context.type( "*" );
+ _context.beginClass( "CompiledExpression" );
+
+ var m: * = _context.beginMethod( "execute", [], _tnumber );
+
+ for each( name in _symbols.symbolNames )
+ {
+ _context.defineField( name, _tany );
+ }
+
+ var c: SWFContext = new SWFContext( _context );
+
+ for each( name in _symbols.symbolNames )
+ {
+ c.storeReg( name );
+ }
+
+ _expression.compile( c );
+
+ m.maxStack = c.maxStack;
+
+ _context.op( OpCode.ORet );
+
+ _context.finalize();
+
+ var output: Output = new Output();
+
+ Writer.write( output, _context );
+
+ return output.getBytes();
+
+ }
+
+ }
+}
\ No newline at end of file
--- /dev/null
+package it.sephiroth.expr
+{
+ import hxasm.Context;
+ import hxasm.OpCode;
+
+ public class SWFContext
+ {
+ private var _stack: int;
+ private var _max_stack: int;
+ private var _context: Context;
+ private var _regs: Object;
+
+ public function SWFContext( context: Context )
+ {
+ _stack = 0;
+ _max_stack = 0;
+ _regs = new Object();
+ _context = context;
+ }
+
+ public function get ctx(): Context
+ {
+ return _context;
+ }
+
+ public function get maxStack(): int
+ {
+ return _max_stack;
+ }
+
+ public function addStack( i: int ): void
+ {
+ _stack += i;
+ _max_stack = Math.max( _stack, _max_stack );
+ }
+
+ public function subStack( i: int ): void
+ {
+ _stack -= i;
+ _max_stack = Math.max( _stack, _max_stack );
+ }
+
+ public function storeReg( name: String ): void
+ {
+ var reg: int = _context.allocRegister();
+
+ _context.op( OpCode.OThis );
+ _context.op( OpCode.OGetProp( _context.property( name ) ) );
+ _context.op( OpCode.OSetReg( reg ) );
+
+ _regs[ name ] = reg;
+
+ addStack( 1 );
+ }
+
+ public function getReg( name: String ): int
+ {
+ return _regs[ name ];
+ }
+
+ }
+}
\ No newline at end of file
--- /dev/null
+package it.sephiroth.expr
+{
+ public class Scanner
+ {
+ private var _pos: int;
+ private var _pool: Array;
+ private var _source: String;
+
+ public function Scanner( source: String )
+ {
+ _pos = 0;
+ _source = source;
+ _pool = new Array();
+ }
+
+ public function nextToken(): Token
+ {
+ if( _pool.length > 0 )
+ {
+ return _pool.shift();
+ }
+
+ skipWhites();
+
+ if( isEOF() )
+ {
+ return new Token( TokenType.EOF );
+ }
+
+ var c: String = _source.charAt( _pos++ );
+
+ switch( c )
+ {
+ case '+': return new Token( TokenType.ADD );
+ case '-': return new Token( TokenType.SUB );
+ case '*': return new Token( TokenType.MUL );
+ case '/': return new Token( TokenType.DIV );
+ case '(': return new Token( TokenType.LEFT_PAR );
+ case ')': return new Token( TokenType.RIGHT_PAR );
+ case ',': return new Token( TokenType.COMMA );
+
+ default:
+
+ var buf: String = "";
+ var code: int = c.charCodeAt( 0 );
+
+ if( isNumber( code ) )
+ {
+ var num: Number;
+
+ while( isNumber( code ) )
+ {
+ buf += c;
+
+ if( isEOF() )
+ {
+ ++_pos;
+ break;
+ }
+
+ c = _source.charAt( _pos++ );
+ code = c.charCodeAt( 0 );
+ }
+
+ if( c == '.' )
+ {
+ buf += c;
+ c = _source.charAt( _pos++ );
+ code = c.charCodeAt( 0 );
+
+ while( isNumber( code ) )
+ {
+ buf += c;
+
+ if( isEOF() )
+ {
+ ++_pos;
+ break;
+ }
+
+ c = _source.charAt( _pos++ );
+ code = c.charCodeAt( 0 );
+ }
+
+ num = parseFloat( buf );
+ }else
+ {
+ num = parseInt( buf );
+ }
+
+ --_pos;
+ return new Token( TokenType.NUM, num );
+ }
+
+ if( isAlpha( code ) || ( c == '_' ) )
+ {
+
+ while( isAlpha( code ) || ( c == '_' ) || isNumber( code ) )
+ {
+ buf += c;
+
+ if( isEOF() )
+ {
+ ++_pos;
+ break;
+ }
+
+ c = _source.charAt( _pos++ );
+ code = c.charCodeAt( 0 );
+ }
+
+ --_pos;
+ return new Token( TokenType.IDENT, buf );
+ }
+
+ break;
+ }
+
+ return new Token( TokenType.NULL, c );
+ }
+
+ public function pushBack( token: Token ): void
+ {
+ _pool.push( token );
+ }
+
+ protected function isNumber( c: int ): Boolean
+ {
+ return ( c >= 48 ) && ( c <= 57 );
+ }
+
+ protected function isAlpha( c: int ): Boolean
+ {
+ return ( ( c >= 97 ) && ( c <= 122 ) ) || ( ( c >= 65 ) && ( c <= 90 ) );
+ }
+
+ protected function isEOF(): Boolean
+ {
+ return ( _pos >= _source.length );
+ }
+
+ protected function skipWhites(): void
+ {
+ while( !isEOF() )
+ {
+ var c: String = _source.charAt( _pos++ );
+ if( ( c != " " ) && ( c != "\t" ) )
+ {
+ --_pos;
+ break;
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+package it.sephiroth.expr
+{
+ import flash.utils.Dictionary;
+
+ public class SymbolTable
+ {
+ private var _symbols: Array;
+
+ public function SymbolTable()
+ {
+ _symbols = new Array();
+ }
+
+ public function get symbolNames(): Array
+ {
+ var names: Array = new Array();
+
+ for each( var ident: Ident in _symbols )
+ {
+ names.push( ident.id );
+ }
+
+ return names;
+ }
+
+ public function find( s: String ): Ident
+ {
+ for each( var ident: Ident in _symbols )
+ {
+ if( ident.id == s )
+ {
+ return ident;
+ }
+ }
+
+ return null;
+ }
+
+ public function add( ident: Ident ): void
+ {
+ _symbols.push( ident );
+ }
+
+ public function findAndAdd( s: String ): Ident
+ {
+ var ident: Ident = find( s );
+ if( ident == null )
+ {
+ ident = new Ident( s );
+ add( ident );
+ }
+
+ return ident;
+ }
+
+ }
+}
\ No newline at end of file
--- /dev/null
+package it.sephiroth.expr
+{
+ public class Token
+ {
+ private var _type: int;
+ private var _value: *;
+
+ public function Token( type: int, value: * = null )
+ {
+ _type = type;
+ _value = value;
+ }
+
+ public function get type(): int
+ {
+ return _type;
+ }
+
+ public function get value(): *
+ {
+ return _value;
+ }
+
+ public function toString(): String
+ {
+ if( !_value )
+ {
+ return TokenType.typeToString( _type );
+ }else
+ {
+ return "<" + TokenType.typeToString( _type ) + ", " + value + ">";
+ }
+ }
+
+ }
+}
\ No newline at end of file
--- /dev/null
+package it.sephiroth.expr
+{
+ public final class TokenType
+ {
+ public static const ADD: int = 1;
+ public static const SUB: int = 2;
+ public static const MUL: int = 3;
+ public static const DIV: int = 4;
+ public static const NUM: int = 5;
+ public static const IDENT: int = 6;
+ public static const LEFT_PAR: int = 7;
+ public static const RIGHT_PAR: int = 8;
+ public static const COMMA: int = 9;
+ public static const NULL: int = 0;
+ public static const EOF: int = -1;
+
+ public static function typeToString( type: int ): String
+ {
+ switch( type )
+ {
+ case 0: return "NULL";
+ case 1: return "ADD";
+ case 2: return "SUB";
+ case 3: return "MUL";
+ case 4: return "DIV";
+ case 5: return "NUM";
+ case 6: return "IDENT";
+ case 7: return "LEFT_PAR";
+ case 8: return "RIGHT_PAR";
+ case 9: return "COMMA";
+ default: return "EOF";
+ }
+
+ return null;
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+package it.sephiroth.expr.ast
+{
+ import hxasm.OpCode;
+ import hxasm.Operation;
+
+ import it.sephiroth.expr.SWFContext;
+
+ public class AddExpression implements IExpression
+ {
+ private var _left: IExpression;
+ private var _right: IExpression;
+
+ public function AddExpression( left: IExpression, right: IExpression )
+ {
+ _left = left;
+ _right = right;
+ }
+
+ public function evaluate(): Number
+ {
+ return _left.evaluate() + _right.evaluate();
+ }
+
+ public function toString(): String
+ {
+ return _left + " " + _right + " + ";
+ }
+
+ public function compile( c: SWFContext ): void
+ {
+ _left.compile( c );
+ _right.compile( c );
+
+ c.ctx.op( OpCode.OOp( Operation.OpAdd ) );
+
+ c.subStack( 1 );
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+package it.sephiroth.expr.ast
+{
+ import hxasm.OpCode;
+
+ import it.sephiroth.expr.Ident;
+ import it.sephiroth.expr.SWFContext;
+ import it.sephiroth.expr.errors.ExpressionError;
+
+ public class CallExpression implements IExpression
+ {
+ private var _name: Ident;
+ private var _arguments: Array;
+
+ public function CallExpression( name: Ident, arguments: Array )
+ {
+ _name = name;
+ _arguments = arguments;
+ }
+
+ public function evaluate(): Number
+ {
+ var args: Array = new Array();
+
+ for each( var argument: IExpression in _arguments )
+ {
+ args.push( argument.evaluate() );
+ }
+
+ if( !_name.value )
+ {
+ throw new ExpressionError( "Unknown function " + _name.id );
+ }
+
+ return ( _name.value as Function ).apply( null, args );
+ }
+
+ public function toString(): String
+ {
+ var args: Array = new Array();
+
+ for each( var argument: IExpression in _arguments )
+ {
+ args.push( argument.toString() );
+ }
+
+ return "( " + args.join( ", " ) + " ) " + _name;
+ }
+
+ public function compile( c: SWFContext ): void
+ {
+ var l: int = _arguments.length;
+
+ c.ctx.op( OpCode.OThis );
+
+ for each( var e: IExpression in _arguments )
+ {
+ e.compile( c );
+ }
+
+ c.ctx.op( OpCode.OCallProperty( c.ctx.property( _name.id ), l ) );
+
+ c.addStack( 2 );
+ }
+
+ }
+}
\ No newline at end of file
--- /dev/null
+package it.sephiroth.expr.ast
+{
+ import hxasm.OpCode;
+ import hxasm.Operation;
+
+ import it.sephiroth.expr.SWFContext;
+
+ public class DivExpression implements IExpression
+ {
+ private var _left: IExpression;
+ private var _right: IExpression;
+
+ public function DivExpression( left: IExpression, right: IExpression )
+ {
+ _left = left;
+ _right = right;
+ }
+
+ public function evaluate(): Number
+ {
+ return _left.evaluate() / _right.evaluate();
+ }
+
+ public function toString(): String
+ {
+ return _left + " " + _right + " / ";
+ }
+
+ public function compile( c: SWFContext ): void
+ {
+ _left.compile( c );
+ _right.compile( c );
+
+ c.ctx.op( OpCode.OOp( Operation.OpDiv ) );
+
+ c.subStack( 1 );
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+package it.sephiroth.expr.ast
+{
+ import hxasm.Context;
+
+ import it.sephiroth.expr.SWFContext;
+
+ public interface IExpression
+ {
+ function evaluate(): Number;
+ function compile( stack: SWFContext ): void;
+
+ function toString(): String;
+ }
+}
\ No newline at end of file
--- /dev/null
+package it.sephiroth.expr.ast
+{
+ import hxasm.OpCode;
+
+ import it.sephiroth.expr.Ident;
+ import it.sephiroth.expr.SWFContext;
+
+ public class IdentExpression implements IExpression
+ {
+ private var _value: Ident;
+
+ public function IdentExpression( value: Ident )
+ {
+ _value = value;
+ }
+
+ public function evaluate(): Number
+ {
+ return _value.value;
+ }
+
+ public function toString(): String
+ {
+ return "" + _value;
+ }
+
+ public function compile( c: SWFContext ): void
+ {
+ c.ctx.op( OpCode.OReg( c.getReg( _value.id ) ) );
+
+ c.addStack( 1 );
+
+ // added RF to coerce any string values to numbers (so "24"+2 is 26, not "242").
+ // See http://www.anotherbigidea.com/javaswf/avm2/AVM2Instructions.html .
+ // Ideally we need to do proper typing so we can evaluate string expressions
+ // too... but not yet!
+ c.ctx.op( OpCode.OToNumber );
+ c.addStack( 1 );
+ }
+
+ }
+}
\ No newline at end of file
--- /dev/null
+package it.sephiroth.expr.ast
+{
+ import hxasm.OpCode;
+ import hxasm.Operation;
+
+ import it.sephiroth.expr.SWFContext;
+
+ public class MulExpression implements IExpression
+ {
+ private var _left: IExpression;
+ private var _right: IExpression;
+
+ public function MulExpression( left: IExpression, right: IExpression )
+ {
+ _left = left;
+ _right = right;
+ }
+
+ public function evaluate(): Number
+ {
+ return _left.evaluate() * _right.evaluate();
+ }
+
+ public function toString(): String
+ {
+ return _left + " " + _right + " * ";
+ }
+
+ public function compile( c: SWFContext ): void
+ {
+ _left.compile( c );
+ _right.compile( c );
+
+ c.ctx.op( OpCode.OOp( Operation.OpMul ) );
+
+ c.subStack( 1 );
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+package it.sephiroth.expr.ast
+{
+ import hxasm.OpCode;
+
+ import it.sephiroth.expr.SWFContext;
+
+ public class NumberExpression implements IExpression
+ {
+ private var _value: Number;
+
+ public function NumberExpression( value: Number )
+ {
+ _value = value;
+ }
+
+ public function evaluate(): Number
+ {
+ return _value;
+ }
+
+ public function toString(): String
+ {
+ return "" + _value;
+ }
+
+ public function compile( c: SWFContext ): void
+ {
+ c.ctx.op( OpCode.OFloat( c.ctx.float( _value ) ) );
+
+ c.addStack( 1 );
+ }
+
+ }
+}
\ No newline at end of file
--- /dev/null
+package it.sephiroth.expr.ast
+{
+ import hxasm.OpCode;
+ import hxasm.Operation;
+
+ import it.sephiroth.expr.SWFContext;
+
+ public class SubExpression implements IExpression
+ {
+ private var _left: IExpression;
+ private var _right: IExpression;
+
+ public function SubExpression( left: IExpression, right: IExpression )
+ {
+ _left = left;
+ _right = right;
+ }
+
+ public function evaluate(): Number
+ {
+ return _left.evaluate() - _right.evaluate();
+ }
+
+ public function toString(): String
+ {
+ return _left + " " + _right + " - ";
+ }
+
+ public function compile( c: SWFContext ): void
+ {
+ _left.compile( c );
+ _right.compile( c );
+
+ c.ctx.op( OpCode.OOp( Operation.OpSub ) );
+
+ c.subStack( 1 );
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+package it.sephiroth.expr.ast
+{
+ import hxasm.OpCode;
+ import hxasm.Operation;
+
+ import it.sephiroth.expr.SWFContext;
+
+ public class UnaryMinusExpression implements IExpression
+ {
+ private var _value: IExpression;
+
+ public function UnaryMinusExpression( value: IExpression )
+ {
+ _value = value;
+ }
+
+ public function evaluate(): Number
+ {
+ return ( - _value.evaluate() );
+ }
+
+ public function toString(): String
+ {
+ return _value + " - ";
+ }
+
+ public function compile( c: SWFContext ): void
+ {
+ _value.compile( c );
+
+ c.ctx.op( OpCode.OOp( Operation.OpNeg ) );
+ }
+
+ }
+}
\ No newline at end of file
--- /dev/null
+package it.sephiroth.expr.ast
+{
+ import it.sephiroth.expr.SWFContext;
+
+ public class UnaryPlusExpression implements IExpression
+ {
+ private var _value: IExpression;
+
+ public function UnaryPlusExpression( value: IExpression )
+ {
+ _value = value;
+ }
+
+ public function evaluate(): Number
+ {
+ return _value.evaluate();
+ }
+
+ public function toString(): String
+ {
+ return _value + " + ";
+ }
+
+ public function compile( c: SWFContext ): void
+ {
+ return _value.compile( c );
+ }
+
+ }
+}
\ No newline at end of file
--- /dev/null
+package it.sephiroth.expr.errors
+{
+ public class ExpressionError extends Error
+ {
+ public function ExpressionError( message: String, id: int = 0 )
+ {
+ super( message, id );
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+package net.systemeD.halcyon.styleparser {
+
+ /*
+ === Eval ===
+
+ This serves as the EventListener for an eval rule and copes with subsequent invocations.
+
+ */
+
+ import flash.display.Loader;
+ import flash.display.LoaderInfo;
+ import flash.events.Event;
+ import flash.system.ApplicationDomain;
+ import flash.system.LoaderContext;
+ import flash.utils.ByteArray;
+
+ import it.sephiroth.expr.CompiledExpression;
+ import it.sephiroth.expr.Parser;
+ import it.sephiroth.expr.Scanner;
+
+ public class Eval extends Loader {
+
+ private var swfclass:Class;
+
+ public function Eval(s:String) {
+ var scanner:Scanner=new Scanner(s);
+ var parser:Parser=new Parser(scanner);
+ var compiled:CompiledExpression=parser.parse();
+ var swfdata:ByteArray=compiled.compile();
+
+ this.contentLoaderInfo.addEventListener(Event.COMPLETE, swfLoaded);
+ this.loadBytes(swfdata, new LoaderContext(false, new ApplicationDomain(ApplicationDomain.currentDomain)));
+ }
+
+ private function swfLoaded(event:Event):void {
+ var info:LoaderInfo = event.target as LoaderInfo;
+ swfclass=info.applicationDomain.getDefinition( "CompiledExpression" ) as Class;
+ }
+
+ public function exec(tags:Object):* {
+ var cp:Object=new swfclass();
+ for (var k:String in tags) { cp[k]=tags[k]; }
+ return cp.execute();
+ }
+ }
+}
\ No newline at end of file
private static const CONDITION_LE:RegExp =/^ \s* (\w+) \s* <= \s* (.+) \s* $/sx;
private static const CONDITION_REGEX:RegExp =/^ \s* (\w+) \s* =~\/ \s* (.+) \/ \s* $/sx;
- private static const ASSIGNMENT:RegExp =/^ \s* (\S+) \s* \: \s* (.+?) \s* $/sx;
- private static const SET_TAG:RegExp =/^ \s* set \s+(\S+)\s* = \s* (.+?) \s* $/sx;
- private static const SET_TAG_TRUE:RegExp =/^ \s* set \s+(\S+)\s* $/sx;
+ private static const ASSIGNMENT_EVAL:RegExp =/^ \s* (\S+) \s* \: \s* eval \s* \( \s* ' (.+?) ' \s* \) \s* $/isx;
+ private static const ASSIGNMENT:RegExp =/^ \s* (\S+) \s* \: \s* (.+?) \s* $/sx;
+ private static const SET_TAG_EVAL:RegExp =/^ \s* set \s+(\S+)\s* = \s* eval \s* \( \s* ' (.+?) ' \s* \) \s* $/isx;
+ private static const SET_TAG:RegExp =/^ \s* set \s+(\S+)\s* = \s* (.+?) \s* $/isx;
+ private static const SET_TAG_TRUE:RegExp =/^ \s* set \s+(\S+)\s* $/isx;
private static const EXIT:RegExp =/^ \s* exit \s* $/isx;
private static const oZOOM:uint=2;
var styles:Array=[];
var t:Object=new Object();
var o:Object=new Object();
- var a:String;
+ var a:String, k:String;
// Create styles\10
var ss:ShapeStyle =new ShapeStyle() ;
var xs:InstructionStyle=new InstructionStyle();
for each (a in s.split(';')) {
- if ((o=ASSIGNMENT.exec(a))) { t[o[1].replace(DASH,'_')]=o[2]; }
- else if ((o=SET_TAG.exec(a))) { xs.addSetTag(o[1],o[2]); }
+ if ((o=ASSIGNMENT_EVAL.exec(a))) { t[o[1].replace(DASH,'_')]=new Eval(o[2]); }
+ else if ((o=ASSIGNMENT.exec(a))) { t[o[1].replace(DASH,'_')]=o[2]; }
+ else if ((o=SET_TAG_EVAL.exec(a))) { xs.addSetTag(o[1],new Eval(o[2])); }
+ else if ((o=SET_TAG.exec(a))) { xs.addSetTag(o[1],o[2]); }
else if ((o=SET_TAG_TRUE.exec(a))) { xs.addSetTag(o[1],true); }
else if ((o=EXIT.exec(a))) { xs.setPropertyFromString('breaker',true); }
}
public var merged:Boolean=false;
public var edited:Boolean=false; // true once a property has been set from a string
public var sublayer:uint=5;
+ public var evals:Object={}; // compiled SWFs for each eval. We keep it here, not in the property
+ // | itself, so that we can retain typing for each property
// Return an exact copy of this object
// ** this needs some benchmarking - may be quicker to iterate over .properties, copying each one
public function get properties():Array {
return [];
}
+
+ // Eval handling
+
+ public function hasEvals():Boolean {
+ for (var k:String in evals) { return true; }
+ return false;
+ }
+
+ public function runEvals(tags:Object):void {
+ for (var k:String in evals) {
+ // ** Do we need to do typing here?
+ this[k]=evals[k].exec(tags);
+ }
+ }
// Set property and cast as correct type (used in stylesheet imports)
public function setPropertyFromString(k:String,v:*):Boolean {
if (!this.hasOwnProperty(k)) { return false; }
- // ** almost certainly need to do more here, e.g. true|1|yes=Boolean true
+ if (v is Eval) { evals[k]=v; v=1; }
switch (typeof(this[k])) {
case "number": this[k]=Number(v) ; edited=true; return true;
case "object": // **for some reason, typeof(string class variables) returns "object".
continue;
}
+ r.runEvals(tags);
if (a[r.sublayer]) {
// If there's already a style on this sublayer, then merge them
// (making a deep copy if necessary to avoid altering the root style)