compute

by lizhi
♥1 | Line 123 | Modified 2012-08-22 13:31:40 | MIT License
play

ActionScript3 source code

/**
 * Copyright lizhi ( http://wonderfl.net/user/lizhi )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/2W5g
 */

package  
{
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.text.TextField;
	import flash.text.TextFieldType;
	import flash.text.TextFormat;
	
	/**
	 * ...
	 * @author lizhi http://game-develop.net/
	 */
	public class Compute extends Sprite 
	{
		private var opPriority:Array;
		private var opArray:Array = [];
		private var opfuns:Array = [];
		private var numArray:Array = [];
		private var lastOp:String = "#";
		private var output:TextField;
		private var input:TextField;
		public function Compute() 
		{
			var ops:Array =        ["+", "-", "*", "/", "(", ")", "#"];
			var priority:Array = [                                               //0:>,1:<,2:=,3,null
									0, 0, 1, 1, 1, 0, 0,
									0, 0, 1, 1, 1, 0, 0,
									0, 0, 0, 0, 1, 0, 0,
									0, 0, 0, 0, 1, 0, 0,
									1, 1, 1, 1, 1, 2, 0,
									0, 0, 0, 0, 3, 0, 0,
									1, 1, 1, 1, 1, 3, 2
									];
			opPriority = [];
			for (var i:int = 0; i < ops.length;i++ ) {
				var line:Array = [];
				opPriority[ops[i]] = line;
				for (var j:int = 0; j < ops.length;j++ ) {
					line[ops[j]] = priority[i * ops.length + j];
				}
			}
			opfuns["+"] = add;
			opfuns["-"] = sub;
			opfuns["*"] = mul;
			opfuns["/"] = div;
			
			initUI();
		}
		
		private function initUI():void 
		{
			input = getTf(true);
			addChild(input);
			input.addEventListener(Event.CHANGE, tf_change);
			output = getTf();
			addChild(output);
			output.y = input.height;
			input.text = "1-3+5/3*(1+2)";
			tf_change(null);
		}
		
		private function tf_change(e:Event):void 
		{
			output.text = count(input.text)+"";
		}
		
		private function getTf(isInput:Boolean = false):TextField {
			var tf:TextField = new TextField;
			var tfm:TextFormat = new TextFormat;
			tfm.font = "宋体";
			tf.defaultTextFormat = tfm;
			if (isInput) {
				tf.width = 200;
				tf.height = 25;
				tf.border = true;
				tf.borderColor = 0;
				tf.type = TextFieldType.INPUT;
			}else {
				tf.autoSize = "left";
			}
			return tf;
		}
		
		private function count(str:String):Number {
			lastOp = "#";
			opArray = ["#"];
			numArray = [];
			var reg:RegExp =/[0-9]+\.?[0-9]*|[+,\-,*,\/,(,)]/g;
			var opreg:RegExp =/[+,\-,*,\/,(,)]/;
			var obj:Object;
			while ((obj=reg.exec(str))!=null) {
				var s:String = obj[0];
				if (opreg.test(s)) {
					addOp(s);
				}else {
					addNum(Number(s));
				}
			}
			addOp("#");
			return numArray[0];
		}
		
		private function addOp(op:String):void { trace("op",op);
			var code:int = opPriority[lastOp][op];
			if (code == 0) {//运算
				opArray.pop();
				if(opfuns[lastOp])numArray.push(opfuns[lastOp].call(null,numArray.pop(),numArray.pop()));
				lastOp = opArray[opArray.length - 1];
				addOp(op);
			}else if (code==1) {//压入
				lastOp = op;
				opArray.push(op);
			}else {//op = ) 弹出 (
				opArray.pop();
				lastOp = opArray[opArray.length - 1];
			}
		}
		private function addNum(num:Number):void { trace("num",num);
			numArray.push(num);
		}
		
		private function add(num1:Number, num2:Number):Number {
			return num1 + num2;
		}
		
		private function sub(num1:Number, num2:Number):Number {
			return num2 - num1;
		}
		
		private function mul(num1:Number, num2:Number):Number {
			return num1 * num2;
		}
		
		private function div(num1:Number, num2:Number):Number {
			return num2 / num1;
		}
	}

}