It can calculate Boolean expressions such as 1+-(-0), 1^0, -(1)*-(-0)... and prints the result. It can also use variables like A+B, C*(D^E)... to print a truth table of all possible values the variables could be.
You can also hover/click the upper left of the screen to type the Boolean expression.
/**
* Copyright CatHobo ( http://wonderfl.net/user/CatHobo )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/iQWw
*/
package {
import flash.display.Sprite;
import flash.display.Stage;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.system.System;
import net.hires.debug.Stats;
import flash.utils.Dictionary;
public class BooleanCalculator extends Sprite{
public function BooleanCalculator():void {
this.addChild(new Stats());
new Calculator(this);
}
}
}
import flash.text.TextField;
import flash.text.TextFieldType;
import flash.text.TextFormat;
import flash.text.TextFieldAutoSize;
import flash.events.TextEvent;
import flash.events.KeyboardEvent;
import flash.ui.Keyboard; //For the enumerations of some characters.
import flash.display.Sprite;
final class Calculator{
private var CalculatorBody:Sprite=new Sprite();
//Container for everything.
private var InputText:TextField=new TextField();
private static const TheOnlyCharactersAllowed:String=" A-Z0-1()+*\\-\\^";
//Allows "spaces", A to Z, 0, 1, +, -, *, (, ), and ^ to input as text.
public function Calculator(DocClass:BooleanCalculator):void{
var stage_w:Number=DocClass.stage.stageWidth;
var stage_h:Number=DocClass.stage.stageHeight;
with(CalculatorBody.graphics){
lineStyle(2,0x000000);
beginFill(0x5F5F5F);
CalculatorBody.x=stage_w/5;
CalculatorBody.y=2;
drawRoundRect(0,0,stage_w*3/5,stage_h-2,20,20);
}
DocClass.addChildAt(CalculatorBody,0);
InputText.defaultTextFormat=new TextFormat(
"System",25,0x000000,true);
InputText.type=TextFieldType.INPUT;
//Input characters in textfield.
/*for(var spam_i1:int=1;spam_i1<=0;spam_i1++){
for(var spam_i2:int=1;spam_i2<=0;spam_i2++){
InputText.appendText("a");
}
InputText.appendText(spam_i1+"\n");
}*/
InputText.restrict=TheOnlyCharactersAllowed;
InputText.autoSize=TextFieldAutoSize.LEFT;
InputText.width
=CalculatorBody.width-42-CustomScrollGUI.BAR_LENGTH;
InputText.multiline=true;
InputText.wordWrap=true;
InputText.addEventListener(
TextEvent.TEXT_INPUT,UpdateScroll);
InputText.addEventListener(
KeyboardEvent.KEY_DOWN,CheckExtraKeys);
InputText.addEventListener(
KeyboardEvent.KEY_UP,CheckExtraKeys);
InputScreen=new CustomScrollGUI(20,20
,CalculatorBody.width-40,CalculatorBody.height/3-15);
CalculatorBody.addChild(InputScreen);
InputScreen.AddDisplayObject(InputText);
//Adding buttons to interact with the calculator.
//Using the long way (with hard-coded "Magic Numbers").
CalculatorBody.addChild(new CustomButton(
InputScreen.x,InputScreen.y+InputScreen.height+BUTTON_SPACE
,70,25,"FALSE(0)",AddCharacters,["0"]));
CalculatorBody.addChild(new CustomButton(
InputScreen.x+70+BUTTON_SPACE
,InputScreen.y+InputScreen.height+BUTTON_SPACE
,70,25,"TRUE(1)",AddCharacters,["1"]));
CalculatorBody.addChild(new CustomButton(
InputScreen.x+140+BUTTON_SPACE*2
,InputScreen.y+InputScreen.height+BUTTON_SPACE
,70,25,"CLEAR",ClearText,[]));
CalculatorBody.addChild(new CustomButton(
InputScreen.x,InputScreen.y+InputScreen.height+25+BUTTON_SPACE*2
,70,25,"AND (*)",AddCharacters,["*"]));
CalculatorBody.addChild(new CustomButton(
InputScreen.x+70+BUTTON_SPACE
,InputScreen.y+InputScreen.height+25+BUTTON_SPACE*2
,70,25,"OR (+)",AddCharacters,["+"]));
CalculatorBody.addChild(new CustomButton(
InputScreen.x+140+BUTTON_SPACE*2
,InputScreen.y+InputScreen.height+25+BUTTON_SPACE*2
,70,25,"NOT (-)",AddCharacters,["-"]));
CalculatorBody.addChild(new CustomButton(
InputScreen.x,InputScreen.y+InputScreen.height+50+BUTTON_SPACE*3
,70,25,"XOR(^)",AddCharacters,["^"]));
CalculatorBody.addChild(new CustomButton(
InputScreen.x+70+BUTTON_SPACE
,InputScreen.y+InputScreen.height+50+BUTTON_SPACE*3
,70,25,"BACKSP",BackspaceText,[]));
CalculatorBody.addChild(new CustomButton(
InputScreen.x+140+BUTTON_SPACE*2
,InputScreen.y+InputScreen.height+50+BUTTON_SPACE*3
,70,25,"CANCEL",CancelParsing,[]));
CalculatorBody.addChild(new CustomButton(
InputScreen.x,InputScreen.y+InputScreen.height+75+BUTTON_SPACE*4
,15,25,"(",AddCharacters,["("]));
CalculatorBody.addChild(new CustomButton(
InputScreen.x+15+BUTTON_SPACE
,InputScreen.y+InputScreen.height+75+BUTTON_SPACE*4
,15,25,")",AddCharacters,[")"]));
CalculatorBody.addChild(new CustomButton(
InputScreen.x+30+BUTTON_SPACE*2
,InputScreen.y+InputScreen.height+75+BUTTON_SPACE*4
,15,25,"A",AddCharacters,["A"]));
CalculatorBody.addChild(new CustomButton(
InputScreen.x+45+BUTTON_SPACE*3
,InputScreen.y+InputScreen.height+75+BUTTON_SPACE*4
,15,25,"B",AddCharacters,["B"]));
CalculatorBody.addChild(new CustomButton(
InputScreen.x+60+BUTTON_SPACE*4
,InputScreen.y+InputScreen.height+75+BUTTON_SPACE*4
,15,25,"C",AddCharacters,["C"]));
CalculatorBody.addChild(new CustomButton(
InputScreen.x+75+BUTTON_SPACE*5
,InputScreen.y+InputScreen.height+75+BUTTON_SPACE*4
,15,25,"D",AddCharacters,["D"]));
CalculatorBody.addChild(new CustomButton(
InputScreen.x+90+BUTTON_SPACE*6
,InputScreen.y+InputScreen.height+75+BUTTON_SPACE*4
,15,25,"E",AddCharacters,["E"]));
CalculatorBody.addChild(new CustomButton(
InputScreen.x+105+BUTTON_SPACE*7
,InputScreen.y+InputScreen.height+75+BUTTON_SPACE*4
,15,25,"F",AddCharacters,["F"]));
CalculatorBody.addChild(new CustomButton(
InputScreen.x,InputScreen.y+InputScreen.height+100+BUTTON_SPACE*5
,15,25,"G",AddCharacters,["G"]));
CalculatorBody.addChild(new CustomButton(
InputScreen.x+15+BUTTON_SPACE
,InputScreen.y+InputScreen.height+100+BUTTON_SPACE*5
,15,25,"H",AddCharacters,["H"]));
CalculatorBody.addChild(new CustomButton(
InputScreen.x+30+BUTTON_SPACE*2
,InputScreen.y+InputScreen.height+100+BUTTON_SPACE*5
,15,25,"I",AddCharacters,["I"]));
CalculatorBody.addChild(new CustomButton(
InputScreen.x+45+BUTTON_SPACE*3
,InputScreen.y+InputScreen.height+100+BUTTON_SPACE*5
,15,25,"J",AddCharacters,["J"]));
CalculatorBody.addChild(new CustomButton(
InputScreen.x+60+BUTTON_SPACE*4
,InputScreen.y+InputScreen.height+100+BUTTON_SPACE*5
,15,25,"K",AddCharacters,["K"]));
CalculatorBody.addChild(new CustomButton(
InputScreen.x+75+BUTTON_SPACE*5
,InputScreen.y+InputScreen.height+100+BUTTON_SPACE*5
,15,25,"L",AddCharacters,["L"]));
CalculatorBody.addChild(new CustomButton(
InputScreen.x+90+BUTTON_SPACE*6
,InputScreen.y+InputScreen.height+100+BUTTON_SPACE*5
,18,25,"M",AddCharacters,["M"]));
CalculatorBody.addChild(new CustomButton(
InputScreen.x+90+18+BUTTON_SPACE*7
,InputScreen.y+InputScreen.height+100+BUTTON_SPACE*5
,18,25,"N",AddCharacters,["N"]));
CalculatorBody.addChild(new CustomButton(
InputScreen.x,InputScreen.y+InputScreen.height+125+BUTTON_SPACE*6
,15,25,"O",AddCharacters,["O"]));
CalculatorBody.addChild(new CustomButton(
InputScreen.x+BUTTON_SPACE+15
,InputScreen.y+InputScreen.height+125+BUTTON_SPACE*6
,15,25,"P",AddCharacters,["P"]));
CalculatorBody.addChild(new CustomButton(
InputScreen.x+BUTTON_SPACE*2+30
,InputScreen.y+InputScreen.height+125+BUTTON_SPACE*6
,15,25,"Q",AddCharacters,["Q"]));
CalculatorBody.addChild(new CustomButton(
InputScreen.x+BUTTON_SPACE*3+45
,InputScreen.y+InputScreen.height+125+BUTTON_SPACE*6
,15,25,"R",AddCharacters,["R"]));
CalculatorBody.addChild(new CustomButton(
InputScreen.x+BUTTON_SPACE*4+60
,InputScreen.y+InputScreen.height+125+BUTTON_SPACE*6
,15,25,"S",AddCharacters,["S"]));
CalculatorBody.addChild(new CustomButton(
InputScreen.x+BUTTON_SPACE*5+75
,InputScreen.y+InputScreen.height+125+BUTTON_SPACE*6
,15,25,"T",AddCharacters,["T"]));
CalculatorBody.addChild(new CustomButton(
InputScreen.x+BUTTON_SPACE*6+90
,InputScreen.y+InputScreen.height+125+BUTTON_SPACE*6
,15,25,"U",AddCharacters,["U"]));
CalculatorBody.addChild(new CustomButton(
InputScreen.x+BUTTON_SPACE*7+105
,InputScreen.y+InputScreen.height+125+BUTTON_SPACE*6
,15,25,"V",AddCharacters,["V"]));
CalculatorBody.addChild(new CustomButton(
InputScreen.x,InputScreen.y+InputScreen.height+150+BUTTON_SPACE*7
,20,25,"W",AddCharacters,["W"]));
CalculatorBody.addChild(new CustomButton(
InputScreen.x+BUTTON_SPACE+20
,InputScreen.y+InputScreen.height+150+BUTTON_SPACE*7
,15,25,"X",AddCharacters,["X"]));
CalculatorBody.addChild(new CustomButton(
InputScreen.x+BUTTON_SPACE*2+15+20
,InputScreen.y+InputScreen.height+150+BUTTON_SPACE*7
,15,25,"Y",AddCharacters,["Y"]));
CalculatorBody.addChild(new CustomButton(
InputScreen.x+BUTTON_SPACE*3+30+20
,InputScreen.y+InputScreen.height+150+BUTTON_SPACE*7
,15,25,"Z",AddCharacters,["Z"]));
CalculatorBody.addChild(new CustomButton(
InputScreen.x+BUTTON_SPACE*4+45+20
,InputScreen.y+InputScreen.height+150+BUTTON_SPACE*7
,120,25,"EVALUATE (=)",EvaluateBooleanString,[]));
}
private static const BUTTON_SPACE:Number=15;
private function AddCharacters(char:String):void{
InputText.appendText(char);
InputScreen.Update();
}
private function ClearText():void{
InputText.text="";
InputScreen.Update();
}
private function BackspaceText():void{
InputText.text=InputText.text.substr(0,-1);//Remove last character.
InputScreen.Update();
}
private function CancelParsing():void{
try{
pbs.CancelParsing=true;
}catch(E:Error){
}
}
private var pbs:ParseBooleanString;
private function EvaluateBooleanString():void{
try{
pbs=new ParseBooleanString(InputText.text,AddCharacters);
}catch(E:Error){
//Propogate custom errors in ParseBooleanString object
//to the screen.
InputText.appendText("\n"+String(E));
InputScreen.Update();
}
}
private function UpdateScroll(e:TextEvent):void{
if(e.text=="="){
EvaluateBooleanString();
} //Short way to EVALUATE when pressing "=".
InputScreen.Update();
}
private function CheckExtraKeys(e:KeyboardEvent):void{
switch(e.keyCode){
case Keyboard.RIGHT:
case Keyboard.LEFT:
case Keyboard.UP:
case Keyboard.DOWN:
case Keyboard.SHIFT:
case Keyboard.CONTROL: //Exclude some keys.
break;
case Keyboard.ENTER:
if(e.type==KeyboardEvent.KEY_DOWN){
EvaluateBooleanString();
}//Key Up will just update the scroll.
default:
InputScreen.Update();
}
//Extra keys such as Backspace, delete don't update the Scroll GUI.
}
private var InputScreen:CustomScrollGUI;
}
import flash.display.Sprite;
import flash.display.SimpleButton;
import flash.text.TextField;
import flash.text.TextFormat;
import flash.events.MouseEvent;
import flash.text.TextFieldAutoSize;
final class CustomButton extends SimpleButton{
//Makes buttons that connect to functions.
//Not sure why there is a graphical glitch (Indents in the letters).
public function CustomButton(
x:Number,y:Number,width:Number,height:Number,message:String,
listener_function:Function,arguments:Array):void{
M=message;
D=Vector.<Number>([width,height]);
super(ButtonTemplate(0x9F9F9F), //Mouse not roll over
ButtonTemplate(0xBFBFBF), //Mouse roll over
ButtonTemplate(0xFFFF00), //Mouse click
ButtonTemplate(0xFFFFFF)); //Area to click
this.x=x;
this.y=y;
this.addEventListener(MouseEvent.CLICK,ButtonListener);
LinkedFunction=listener_function;
LinkedArguments=arguments;
}
private var LinkedFunction:Function;
private var LinkedArguments:Array;
private function ButtonListener(e:MouseEvent):void{
LinkedFunction.apply(null,LinkedArguments);
} //Call a function given in the CustomButton constructor.
private static var D:Vector.<Number>;//Temporary variable for dimensions.
private static var M:String;//For the message in the button.
private function ButtonTemplate(color:uint):Sprite{
var spr_container:Sprite=new Sprite();
spr_container.graphics.lineStyle(2,0x3F3F3F);
spr_container.graphics.beginFill(color);
spr_container.graphics.drawRoundRect(0,0,D[0],D[1],20,20);
var t:TextField=new TextField();
t.defaultTextFormat=new TextFormat(
"Verdana",12,0x00FF00,true);
t.width=D[0]; //Resize textfield so it can be centered properly.
t.text=M;
t.autoSize=TextFieldAutoSize.CENTER;
spr_container.addChild(t);//Add to button.
return spr_container;
}
}
import flash.display.Sprite;
import flash.display.Stage;
import flash.display.DisplayObject;
import flash.geom.Rectangle;
import flash.events.Event;
import flash.events.MouseEvent;
final class CustomScrollGUI extends Sprite{
private var V_ScrollInner:Sprite=new Sprite();
private var V_ScrollOuter:Sprite=new Sprite();
private var H_ScrollInner:Sprite=new Sprite();
private var H_ScrollOuter:Sprite=new Sprite();
private var ContentsToSee:Sprite=new Sprite();
private var ContentsRect:Rectangle=new Rectangle();
private var ContentScrollRect:Rectangle=new Rectangle();
public static const BAR_LENGTH:int=20;
public static const SCROLL_TO_END_IF_UPDATED:Boolean=true;
public function AddDisplayObject(obj:DisplayObject
,to_x:Number=0,to_y:Number=0):void{
obj.x=to_x;
obj.y=to_y;
ContentsToSee.addChild(obj);
Update();
}//Custom "addChild" for the scrollbar.
private function GetContentBounds():Rectangle{
var init_rectangle:Rectangle=new Rectangle();
for(var i:int=0;i<ContentsToSee.numChildren;i++){
init_rectangle=init_rectangle.union(
ContentsToSee.getChildAt(i).getRect(ContentsToSee)
); //Get the largest rectangle for all children
//in the contents of the scrollbar.
}
return init_rectangle;
}
public function Update():void{
var LargestRectangle:Rectangle=GetContentBounds();
ContentsRect.height=LargestRectangle.height;
ContentsRect.width=LargestRectangle.width;
//Update ScrollRect for the scrollbar to work properly.
if(LargestRectangle.height>ContentScrollRect.height){
with(V_ScrollOuter.graphics){
clear(); //Clear to redraw properly.
lineStyle(2,0x000000);
beginFill(0xFFFFFF);
drawRoundRect(0,0
,BAR_LENGTH,
V_ScrollInner.height
*ContentScrollRect.height/LargestRectangle.height
,20,20);
}
V_ScrollInner.visible=true;
}else{
V_ScrollInner.visible=false;
} //Show scrollbar if content height is bigger than mask.
//by redrawing with the ratio of mask height to content height.
if(LargestRectangle.width>ContentScrollRect.width){
with(H_ScrollOuter.graphics){
clear();
lineStyle(2,0x000000);
beginFill(0xFFFFFF);
drawRoundRect(0,0,H_ScrollInner.width
*ContentScrollRect.width/LargestRectangle.width
,BAR_LENGTH,20,20);
}
H_ScrollInner.visible=true;
}else{
H_ScrollInner.visible=false;
}
CheckV_ScrollOutOfBounds();
CheckH_ScrollOutOfBounds();
}
private function CheckV_ScrollOutOfBounds():void{
/*Console.Print(GetContentBounds(),ContentScrollRect,
GetContentBounds().height-ContentScrollRect.height,
GetContentBounds().height>ContentScrollRect.height,
GetContentBounds().height-ContentScrollRect.height
<ContentScrollRect.y+0.2," ");*/
if(GetContentBounds().height>ContentScrollRect.height){
if(GetContentBounds().height-ContentScrollRect.height
<ContentScrollRect.y+0.2){
V_ScrollTo(GetScrollVSpace);
//Automatically change scrollbar and
//contents positions if using backspace.
}else{
if(SCROLL_TO_END_IF_UPDATED){
V_ScrollTo(GetScrollVSpace);
}//Extra code for the Boolean Calculator.
}
}else{
V_ScrollTo(0);
//If cutting a whole textfield,
//scroll back up to 0.
}
ContentScrollV();
}
private function CheckH_ScrollOutOfBounds():void{
if(GetContentBounds().width>ContentScrollRect.width){
if(GetContentBounds().width-ContentScrollRect.width
<ContentScrollRect.x+0.2){
H_ScrollTo(GetScrollHSpace);
}
}else{
H_ScrollTo(0);
//If cutting a whole textfield,
//scroll back up to 0.
}
ContentScrollH();
/*Console.Print(GetContentBounds(),ContentScrollRect,
GetContentBounds().width-ContentScrollRect.width,
GetContentBounds().width>ContentScrollRect.width,
GetContentBounds().width-ContentScrollRect.width
<ContentScrollRect.x+0.2," ");*/
}
public function CustomScrollGUI(init_x:Number,init_y:Number,
init_width:Number,init_height:Number):void{
x=init_x;
y=init_y;
with(graphics){
lineStyle(2,0x000000);
beginFill(0xFFFF9F);
drawRoundRect(0,0,init_width,init_height,20,20);
}
with(V_ScrollInner){
x=init_width-BAR_LENGTH-2;
y=2;
with(graphics){
lineStyle(2,0x000000);
beginFill(0xBFBFBF);
drawRoundRect(0,0,BAR_LENGTH,init_height-BAR_LENGTH,20,20);
}
}
V_ScrollInnerHeight=V_ScrollInner.height;
V_ScrollInner.visible=false;
this.addChild(V_ScrollInner);
with(V_ScrollOuter){
buttonMode=true;
with(graphics){
lineStyle(2,0x000000);
beginFill(0xFFFFFF);
drawRoundRect(0,0,BAR_LENGTH,init_height-BAR_LENGTH,20,20);
}
}
V_ScrollInner.addChild(V_ScrollOuter);
with(H_ScrollInner){
y=init_height-BAR_LENGTH;
with(graphics){
lineStyle(2,0x000000);
beginFill(0xBFBFBF);
drawRoundRect(0,0,init_width-BAR_LENGTH,BAR_LENGTH,20,20);
}
}
H_ScrollInnerWidth=H_ScrollInner.width;
H_ScrollInner.visible=false;
this.addChild(H_ScrollInner);
with(H_ScrollOuter){
buttonMode=true;
with(graphics){
lineStyle(2,0x000000);
beginFill(0xFFFFFF);
drawRoundRect(0,0,100,BAR_LENGTH,20,20);
}
}
H_ScrollInner.addChild(H_ScrollOuter);
with(ContentScrollRect){
width=this.width-BAR_LENGTH-4;
height=this.height-BAR_LENGTH-4;
}
ContentsToSee.scrollRect=ContentScrollRect;
//Used to scroll the contents with the scrollbars.
ContentsToSee.cacheAsBitmap=true;
this.addChild(ContentsToSee);
this.addEventListener(Event.ADDED_TO_STAGE,AddEventListeners);
//After "this" is added by addChild, this.root.stage is accessible.
}
private function AddEventListeners(e:Event):void{
V_ScrollInner.addEventListener(MouseEvent.MOUSE_DOWN,V_ScrollByInner);
this.root.stage.addEventListener(
MouseEvent.MOUSE_UP,V_ScrollByOuterRemove);
//Remove scrolling anywhere when mouse is up in the stage.
H_ScrollInner.addEventListener(MouseEvent.MOUSE_DOWN,H_ScrollByInner);
this.root.stage.addEventListener(
MouseEvent.MOUSE_UP,H_ScrollByOuterRemove);
}
private var V_ScrollInnerHeight:Number;
//Since V_ScrollOuter is a child, of V_ScrollInner
//would change the height. This is to preserve that.
private function get GetScrollVSpace():Number{
return V_ScrollInnerHeight-V_ScrollOuter.height;
} //Magic number to get the number by the difference of V_Scroll bars.
private function V_ScrollTo(to_y:Number):void{
var GetScrollVSpace:Number=this.GetScrollVSpace;
if(to_y<=GetScrollVSpace&&to_y>=0){
V_ScrollOuter.y=to_y;
}else if(to_y>GetScrollVSpace){
V_ScrollOuter.y=GetScrollVSpace;
}else if(to_y<0){
V_ScrollOuter.y=0;
}//Scroll inside the boundaries of ScrollBarInner.
}
private function ContentScrollV():void{
ContentScrollRect.y=(GetScrollVSpace!=0)
?(ContentsRect.height-ContentScrollRect.height)
*V_ScrollOuter.y/GetScrollVSpace
:(0); //No 0 division.
ContentsToSee.scrollRect=ContentScrollRect;
//Change scrolling positions using maths.
}
private function V_ScrollByInner(e:MouseEvent):void{
var GetDisp:DisplayObject=V_ScrollOuter;
var GetLocal_y:Number=0;
while(!(GetDisp is Stage)){
GetDisp=GetDisp.parent;
GetLocal_y+=GetDisp.y;
}//If GUI is nested inside display objects,
//add all of the y-offsets for the scroll
//to properly get the local y with respect to V_ScrollInner
//using e.stageY-GetLocal_y.
//Console.Print(V_ScrollInner.globalToLocal(new Point(0,e.stageY)).y);
V_ScrollTo(e.stageY-GetLocal_y-V_ScrollOuter.height/2);
//Scroll in the middle of the mouse y position.
ContentScrollV(); //Scroll the content vertically.
this.root.stage.addEventListener(
MouseEvent.MOUSE_MOVE,V_ScrollByInner);
}
private function V_ScrollByOuterRemove(e:MouseEvent):void{
this.root.stage.removeEventListener(
MouseEvent.MOUSE_MOVE,V_ScrollByInner);
}
private var H_ScrollInnerWidth:Number;
private function get GetScrollHSpace():Number{
return H_ScrollInnerWidth-H_ScrollOuter.width;
} //Magic number to get the number by the difference of V_Scroll bars.
private function H_ScrollTo(to_x:Number):void{
var GetScrollHSpace:Number=this.GetScrollHSpace;
if(to_x<=GetScrollHSpace&&to_x>=0){
H_ScrollOuter.x=to_x;
}else if(to_x>GetScrollHSpace){
H_ScrollOuter.x=GetScrollHSpace;
}else if(to_x<0){
H_ScrollOuter.x=0;
}//Scroll inside the boundaries of ScrollBarInner.
}
private function ContentScrollH():void{
ContentScrollRect.x=(GetScrollHSpace!=0)
?(ContentsRect.width-ContentScrollRect.width)
*H_ScrollOuter.x/GetScrollHSpace
:(0);
ContentsToSee.scrollRect=ContentScrollRect;
//Change scrolling positions using maths.
}
private function H_ScrollByInner(e:MouseEvent):void{
var GetDisp:DisplayObject=H_ScrollOuter;
var GetLocal_x:Number=0;
while(!(GetDisp is Stage)){
GetDisp=GetDisp.parent;
GetLocal_x+=GetDisp.x;
}
H_ScrollTo(e.stageX-GetLocal_x-H_ScrollOuter.width/2);
ContentScrollH();
this.root.stage.addEventListener(
MouseEvent.MOUSE_MOVE,H_ScrollByInner);
}
private function H_ScrollByOuterRemove(e:MouseEvent):void{
this.root.stage.removeEventListener(
MouseEvent.MOUSE_MOVE,H_ScrollByInner);
}
}
import flash.events.Event;
import flash.display.Sprite;
final class ParseBooleanString{
//Not sure if Parse is the right word.
private static var HandleEvents:Sprite=new Sprite();
private static const RegCheckSyntax:RegExp
=/(?:\(*\-?)*\(*[A-Z0-1]\)*(?:[\+\*\^](?:\(*\-?)*\(*[A-Z0-1]\)*)*/;
//This regexp seems to work for now.
private static const RegCheckChars:RegExp
=/([A-Z0-1])/
public function ParseBooleanString(s:String
,print_listener:Function):void{
PrintToScreen=print_listener;
if(s==""){
throw new Error("\nNo characters to evaluate.");
}
s=s.replace(/\s/g,"");//Remove all white spaces.
if(!(s.match(RegCheckChars) is Array)){
throw new Error("\nNeeds at least 1 letter/number.");
}//If capturing any letter/number, don't throw the error.
var LeftParenthesis:int=s.match(/\(/g).length;
var RightParenthesis:int=s.match(/\)/g).length;
if(s.match(RegCheckSyntax)[0].length!=s.length){
throw new Error("\nInvalid Syntax (Characters/Symbols are not used correctly), or the CLEAR button isn't pressed after an evaluation.");
}else if(LeftParenthesis>RightParenthesis){
throw new Error("\nToo many Left Parenthesis ("+LeftParenthesis+" counted). Counted only "+RightParenthesis+" Right Parenthesis.");
}else if(RightParenthesis>LeftParenthesis){
throw new Error("\nToo many Right Parenthesis ("+RightParenthesis+" counted). Counted only "+LeftParenthesis+" Left Parenthesis.");
}//For syntax errors in string.
GetVariablesFromString(s); //Get string variable names
//from "A" to "Z".
PrintToScreen("\nPrinting result(s) for: "+s);
StringCopy=s;
DoParsing(s);
}
private var PrintToScreen:Function;
private var StringCopy:String;
public var CancelParsing:Boolean=false;
private function DoNextVariableValues(e:Event):void{
HandleEvents.removeEventListener(Event.ENTER_FRAME,DoNextVariableValues);
if(!CancelParsing&&NextBooleanArrayValues(BooleanArray)){
DoParsing(StringCopy); //Do next boolean values.
}else{
if(CancelParsing){
PrintToScreen("\nCancelled.");
return;
}
PrintToScreen("\nDone.");
}
}
private static const RegParenthesis:RegExp
=/\(\-?[A-Z0-1](?:[\+\*\^]\-?[A-Z0-1])*\)/;
private static const RegNOTOperator:RegExp=/-[A-Z0-1]/;
private static const RegXOROperator:RegExp=/[A-Z0-1]\^[A-Z0-1]/;
private static const RegANDOperator:RegExp=/[A-Z0-1]\*[A-Z0-1]/;
private static const RegOROperator:RegExp=/[A-Z0-1]\+[A-Z0-1]/;
private function DoParsing(s:String):void{
s="("+s+")";
//Enclose string in parenthesis
//for the loop code below.
//Console.Print(s);
var Parser:Object=GetStringParser();
var inner_parenthesis:Array
=s.match(RegParenthesis);
//Capture an expression within parenthesis first.
//match returns an array if it finds any string matches.
var cloned_parenthesis:Array
=s.match(RegParenthesis);
//Clone contents by value (no pass by refernce).
var operations_array:Array;
var infinite_loop:int=0;
while(inner_parenthesis is Array){
operations_array=inner_parenthesis[0].match(RegNOTOperator);
while(operations_array is Array){
inner_parenthesis[0]
=inner_parenthesis[0].replace(operations_array[0]
,BooleanAsString(!Parser[operations_array[0].charAt(1)])
);
operations_array=inner_parenthesis[0].match(RegNOTOperator);
} //Evaluate the NOT operators.
operations_array=inner_parenthesis[0].match(RegXOROperator);
while(operations_array is Array){
inner_parenthesis[0]
=inner_parenthesis[0].replace(
operations_array[0]
,BooleanAsString(
(!Parser[operations_array[0].charAt(0)]
&&Parser[operations_array[0].charAt(2)])
||(Parser[operations_array[0].charAt(0)]
&&!Parser[operations_array[0].charAt(2)]))
);
operations_array=inner_parenthesis[0].match(RegXOROperator);
} //Evaluate the XOR operators.
operations_array=inner_parenthesis[0].match(RegANDOperator);
while(operations_array is Array){
inner_parenthesis[0]
=inner_parenthesis[0].replace(
operations_array[0]
,BooleanAsString(
Parser[operations_array[0].charAt(0)]
&&Parser[operations_array[0].charAt(2)])
);
operations_array=inner_parenthesis[0].match(RegANDOperator);
} //Evaluate the AND operators.
operations_array=inner_parenthesis[0].match(RegOROperator);
while(operations_array is Array){
inner_parenthesis[0]
=inner_parenthesis[0].replace(
operations_array[0]
,BooleanAsString(
Parser[operations_array[0].charAt(0)]
||Parser[operations_array[0].charAt(2)])
);
operations_array=inner_parenthesis[0].match(RegOROperator);
} //Evaluate the OR operators.
s=s.replace(
cloned_parenthesis
,inner_parenthesis[0].charAt(1));
//Replace a whole string inside parenthesis
//( Ex: (A+-1*0^-D) ) into 0 or 1.
if(++infinite_loop>1000){
throw new Error("Infinite loop at parser.");
}
inner_parenthesis
=s.match(RegParenthesis);
cloned_parenthesis
=s.match(RegParenthesis);
//Capture any new expressions within parenthesis.
}
var TempString:String="";
for(var i:int=0;i<VariableArray.length;i++){
TempString+="("+VariableArray[i]
+"="+BooleanAsString(BooleanArray[i])+") | ";
}
PrintToScreen("\n"+TempString+"(Result="+s+")");
HandleEvents.addEventListener(Event.ENTER_FRAME,DoNextVariableValues);
//Cycle through the next combination in the truth table.
}
private static function BooleanAsString(b:Boolean):String{
return (b?"1":"0");
}
private static const RegFindVariables:RegExp=/[A-Z]/g;
private var VariableArray:Vector.<String>;
private var BooleanArray:Vector.<Boolean>;
private function GetVariablesFromString(str:String):void{
VariableArray=new Vector.<String>();
var VariableCache:Object=new Object();
for each(var var_s:String in str.match(RegFindVariables)){
if(!VariableCache[var_s]){
VariableArray.push(var_s);
VariableCache[var_s]=true;
}//No duplicates of a string variable.
}
VariableArray.sort(0);
//Sort alphabetically.
BooleanArray
=new Vector.<Boolean>(VariableArray.length);
for(var i:int=0;i<BooleanArray.length;i++){
BooleanArray[i]=false;
}//Fill BooleanArray with false by the length of
//the VariableArray.
}
private function GetStringParser():Object{
var o:Object=new Object();
o["0"]=false; //0 always false
o["1"]=true; //1 always true
for(var i:int=0;i<VariableArray.length;i++){
o[VariableArray[i]]=BooleanArray[i];
} //Fill variable names with boolean values.
return o;
}
private function NextBooleanArrayValues(
v_ref:Vector.<Boolean>):Boolean{
var count_i:int=0;
while(count_i<v_ref.length){
if(v_ref[count_i]){
v_ref[count_i]=false;
count_i++;
}else{
v_ref[count_i]=true;
return true;
}
}
return false;
}//"Binary Addition by 1. Example: 0b000101+0b1=0b000110"
}