In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

Whitespace Interpreter

Whitespace Interpreter
* 
* 変態プログラミング言語Whitespaceのインタプリタです.
* ソースコードは改行, タブ, 半角スペースからのみ成り立っており,
* それ以外は全てコメントとみなします.
* エラー処理はまじめにやっていないので適当に書くと落ちるかもしれません.
*  
* Whitespace Official
* @see http://compsoc.dur.ac.uk/whitespace/
* 
* Update Log
* 2010.06.29 ソースコードにフォーカスが当たったときに全選択するようにした
* 2010.06.29 無限ループによるブラウザクラッシュを回避するようにした
* 
* @author Yukiya Okuda<alumican.net>
Get Adobe Flash player
by alumican_net 29 Jun 2010
/**
 * Copyright alumican_net ( http://wonderfl.net/user/alumican_net )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/gpUu
 */

/**
 * Whitespace Interpreter
 * 
 * 変態プログラミング言語Whitespaceのインタプリタです.
 * ソースコードは改行, タブ, 半角スペースからのみ成り立っており,
 * それ以外は全てコメントとみなします.
 * エラー処理はまじめにやっていないので適当に書くと落ちるかもしれません.
 *  
 * Whitespace Official
 * @see http://compsoc.dur.ac.uk/whitespace/
 * 
 * Update Log
 * 2010.06.29 ソースコードにフォーカスが当たったときに全選択するようにした
 * 2010.06.29 無限ループによるブラウザクラッシュを回避するようにした
 * 
 * @author Yukiya Okuda<alumican.net>
 */
package
{
	import com.bit101.components.ComboBox;
	import com.bit101.components.FPSMeter;
	import com.bit101.components.HUISlider;
	import com.bit101.components.Label;
	import com.bit101.components.Panel;
	import com.bit101.components.PushButton;
	import com.bit101.components.TextArea;
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.BlendMode;
	import flash.display.DisplayObjectContainer;
	import flash.display.Shape;
	import flash.display.Sprite;
	import flash.display.StageScaleMode;
	import flash.events.Event;
	import flash.events.FocusEvent;
	import flash.events.MouseEvent;
	import flash.events.TimerEvent;
	import flash.geom.ColorTransform;
	import flash.geom.Matrix;
	import flash.geom.Point;
	import flash.text.TextField;
	import flash.text.TextFieldAutoSize;
	import flash.text.TextFormat;
	import flash.utils.Timer;
	
	public class Main extends Sprite
	{
		public function Main():void 
		{
			Wonderfl.disable_capture();
			
			_setupInterpreter();
			_setupInterface();
			
			_resetInterpreter();
			_uiSetSource(Whitespace.SAMPLE_HELLO_WORLD);
		}
		
		
		
		
		
		/**************************************************************//**
		 * インタプリタ
		 */
		private var _whitespace:Whitespace;
		private var _stepTimer:Timer;
		private var _stepInterval:int;
		
		private function _setupInterpreter():void
		{
			_whitespace = new Whitespace();
			_whitespace.useDebugLog = false;
			_whitespace.addEventListener(Whitespace.EVENT_EXIT, _whitespaceExitHandler);
			_whitespace.addEventListener(Whitespace.EVENT_OUT, _whitespaceOutHandler);
			_whitespace.addEventListener(Whitespace.EVENT_IN_REQUEST, _whitespaceInRequestHandler);
			_whitespace.addEventListener(Whitespace.EVENT_STEP, _whitespaceStepHandler);
			_whitespace.addEventListener(Whitespace.EVENT_ERROR, _whitespaceErrorHandler);
			
			_stepInterval = 50;
			_stepTimer = new Timer(_stepInterval);
			_stepTimer.addEventListener(TimerEvent.TIMER, _stepTimerHandler);
		}
		
		private function _runInterpreter():void
		{
			_uiControllerRunButton.alpha = 0.3;
			
			if (!_whitespace.isRunning)
			{
				_uiClearOutput();
				_uiClearInput();
				_uiClearStatus();
				_uiSetOutput("[run]");
				_whitespace.source = _uiSourceTextArea.text;
				_whitespace.run();
			}
			
			_stepTimer.delay = _stepInterval;
			_stepTimer.reset();
			_stepTimer.start();
		}
		
		private function _stopInterpreter():void
		{
			_stepTimer.stop();
			
			_uiControllerRunButton.alpha = 1.0;
		}
		
		private function _resetInterpreter():void
		{
			_whitespace.reset();
			_stepTimer.reset();
			_uiClearOutput();
			_uiClearInput();
			_uiClearStatus();
			
			_uiControllerRunButton.alpha = 1.0;
		}
		
		private function _inputInterpreter(message:String):void
		{
			if (_whitespace.isWaitingInputNumber) _whitespace.inputNumber(parseInt(message));
			if (_whitespace.isWaitingInputToken) _whitespace.inputToken(message);
		}
		
		private function _setStepInterval(time:int):void
		{
			_stepInterval = (time <= 0) ? 1 : time;
			_stepTimer.delay = time;
		}
		
		private function _stepTimerHandler(e:TimerEvent):void 
		{
			_whitespace.step();
		}
		
		private function _whitespaceStepHandler(e:Event):void 
		{
			_uiSetStatus();
		}
		
		private function _whitespaceOutHandler(e:Event):void 
		{
			_uiSetOutput("[run]", _whitespace.output);
		}
		
		private function _whitespaceInRequestHandler(e:Event):void 
		{
			_uiRequestInput();
		}
		
		private function _whitespaceExitHandler(e:Event):void 
		{
			_uiSetOutput("[run]", _whitespace.output, "[end]");
			
			_uiControllerRunButton.alpha = 1.0;
		}
		
		private function _whitespaceErrorHandler(e:Event):void 
		{
			if (_whitespace.hasSyntaxError)
			{
				_uiSetOutput("[run]", _whitespace.output, "[error] syntax error");
			}
			else
			{
				_uiSetOutput("[run]", _whitespace.output, "[error] error");
			}
			
			_uiControllerRunButton.alpha = 1.0;
		}
		
		
		
		
		
		/**************************************************************//**
		 * インターフェース
		 */
		private var _uiContainer:Sprite;
		private var _uiTitle:Label;
		private var _uiController:Sprite;
		private var _uiControllerRunButton:PushButton;
		private var _uiControllerStopButton:PushButton;
		private var _uiControllerResetButton:PushButton;
		private var _uiControllerSpeedSlider:HUISlider;
		private var _uiControllerStepLabel:Label;
		private var _uiControllerStepText:Label;
		private var _uiSource:Sprite;
		private var _uiSourceTitle:Label;
		private var _uiSourceTextArea:TextArea;
		private var _uiOutput:Sprite;
		private var _uiOutputTitle:Label;
		private var _uiOutputTextArea:TextArea;
		private var _uiInput:Sprite;
		private var _uiInputTitle:Label;
		private var _uiInputTextArea:TextArea;
		private var _uiInputSendButton:PushButton;
		private var _uiPreset:Sprite;
		private var _uiPresetTitle:Label;
		private var _uiPresetComboBox:ComboBox;
		private var _uiStatus:Sprite;
		private var _uiStatusStackLabel:Label;
		private var _uiStatusStackText:Label;
		private var _uiStatusPanel:Panel;
		private var _uiStatusPointer:Bitmap;
		private var _uiStatusPointerCanvas:BitmapData;
		private var _uiStatusPointerCanvasClear:BitmapData;
		private var _uiStatusPointerSlit0:BitmapData;
		private var _uiStatusPointerSlit1:BitmapData;
		private var _uiStatusPointerMatrix:Matrix;
		private var _uiStatusPointerMatrixWidth:int;
		private var _uiStatusPointerSlit:Shape;
		
		private function _setupInterface():void
		{
			stage.scaleMode = StageScaleMode.NO_SCALE;
			stage.align = "";
			stage.frameRate = 60;
			
			_uiContainer = addChild( new Sprite() ) as Sprite;
			
			//----------------------------------------
			_uiTitle = new Label(_uiContainer, 5, -8, "Whitespace Interpreter");
			_uiTitle.scaleX = _uiTitle.scaleY = 3;
			var ctf:ColorTransform = _uiTitle.transform.colorTransform;
			ctf.color = 0xcccccc;
			_uiTitle.transform.colorTransform = ctf;
			
			//----------------------------------------
			_uiSource = _uiContainer.addChild( new Sprite() ) as Sprite;
			_uiSource.x = 10;
			_uiSource.y = 35;
			
			_uiSourceTitle = new Label(_uiSource, -2, 0, "Source Code : ");
			
			_uiSourceTextArea = new TextArea(_uiSource, 0, 16);
			_uiSourceTextArea.width  = 250;
			_uiSourceTextArea.height = 240;
			_uiSourceTextArea.textField.addEventListener(FocusEvent.KEY_FOCUS_CHANGE, _uiSourceTextAreaKeyFocusChangeHandler);
			_uiSourceTextArea.textField.addEventListener(FocusEvent.FOCUS_IN, _uiSourceTextAreaFocusInHandler);
			
			//----------------------------------------
			_uiOutput = _uiContainer.addChild( new Sprite() ) as Sprite;
			_uiOutput.x = 270;
			_uiOutput.y = 35;
			
			_uiOutputTitle = new Label(_uiOutput, -2, 0, "Output : ");
			
			_uiOutputTextArea = new TextArea(_uiOutput, 0, 16);
			_uiOutputTextArea.width  = 185;
			_uiOutputTextArea.height = 120;
			
			//----------------------------------------
			_uiInput = _uiContainer.addChild( new Sprite() ) as Sprite;
			_uiInput.x = 270;
			_uiInput.y = 175;
			
			_uiInputTitle = new Label(_uiInput, -2, 0, "Input : ");
			
			_uiInputTextArea = new TextArea(_uiInput, 0, 16);
			_uiInputTextArea.textField.multiline = false;
			_uiInputTextArea.width  = 185;
			_uiInputTextArea.height = 100;
			
			_uiInputSendButton = new PushButton(_uiInput, 0, 97, "Send", _uiInputSendButtonClickHandler);
			_uiInputSendButton.width = 50;
			
			//----------------------------------------
			_uiController = _uiContainer.addChild( new Sprite() ) as Sprite;
			_uiController.x = 10;
			_uiController.y = 415;
			
			_uiControllerRunButton = new PushButton(_uiController, 0, 0, "Run", _uiControllerRunButtonClickHandler);
			_uiControllerRunButton.blendMode = BlendMode.LAYER;
			_uiControllerRunButton.height = 40;
			
			_uiControllerStopButton = new PushButton(_uiController, 110, 0, "Stop", _uiControllerStopButtonClickHandler);
			_uiControllerResetButton = new PushButton(_uiController, 220, 0, "Reset", _uiControllerResetButtonClickHandler);
			
			_uiControllerSpeedSlider = new HUISlider(_uiController, 330, 1 /*5*/, "Speed", _uiControllerSpeedSliderChangeHandler);
			_uiControllerSpeedSlider.width = 150;
			_uiControllerSpeedSlider.minimum = 0;
			_uiControllerSpeedSlider.maximum = 100;
			_uiControllerSpeedSlider.labelPrecision = 0;
			_uiControllerSpeedSlider.value = 100;
			_uiControllerSpeedSliderChangeHandler(null);
			
			//_uiControllerStepLabel = new Label(_uiController, 330, -10, "Step");
			//_uiControllerStepText = new Label(_uiController, 360, -10, "");
			
			//----------------------------------------
			_uiPreset = _uiContainer.addChild( new Sprite() ) as Sprite;
			_uiPreset.x = 10;  //10; //151;
			_uiPreset.y = 256; //35; //235;
			
			//_uiPresetTitle = new Label(_uiPreset, -2, 0, "Preset : ");
			
			_uiPresetComboBox = new ComboBox(_uiPreset, 0, 16, "Preset Code");
			_uiPresetComboBox.addEventListener(Event.SELECT, _uiPresetComboBoxSelectHandler);
			_uiPresetComboBox.addItem( { label : "Hello, World!"  , code : Whitespace.SAMPLE_HELLO_WORLD     } );
			_uiPresetComboBox.addItem( { label : "Hello, user!"   , code : Whitespace.SAMPLE_HELLO_USER      } );
			_uiPresetComboBox.addItem( { label : "Calculator"     , code : Whitespace.SAMPLE_CALCULATOR      } );
			_uiPresetComboBox.addItem( { label : "Factorial"      , code : Whitespace.SAMPLE_FRACTORIAL      } );
			_uiPresetComboBox.addItem( { label : "Towers of Hanoi", code : Whitespace.SAMPLE_TOWERS_OF_HANOI } );
			_uiPresetComboBox.addItem( { label : "Fibonacci"      , code : Whitespace.SAMPLE_FIBONACCI       } );
			//_uiPresetComboBox.selectedItem = _uiPresetComboBox.items[0];
			
			//----------------------------------------
			_uiStatus = _uiContainer.addChild( new Sprite() ) as Sprite;
			_uiStatus.x = 10;
			_uiStatus.y = 302;
			
			_uiStatusPanel = new Panel(_uiStatus, 0, 0);
			_uiStatusPanel.width = 444;
			_uiStatusPanel.height = 101;
			
			_uiControllerStepLabel = new Label(_uiStatus, 5, 5, "Step");
			_uiControllerStepText = new Label(_uiStatus, 35, 5, "");
			
			_uiStatusStackLabel = new Label(_uiStatus, 5, 20, "Stack");
			_uiStatusStackText = new Label(_uiStatus, 35, 20, "");
			
			var cover:Shape = _uiStatus.addChild( new Shape() ) as Shape;
			cover.x = 445;
			cover.graphics.beginFill(0xffffff);
			cover.graphics.drawRect(0, 0, 20, _uiStatusPanel.height);
			cover.graphics.endFill();
			
			_uiStatusPointerCanvas = new BitmapData(433, 51, true, 0x0);
			_uiStatusPointerCanvasClear = new BitmapData(_uiStatusPointerCanvas.width, _uiStatusPointerCanvas.height, true, 0xffeeeeee);
			_uiStatusPointerSlit0 = new BitmapData(2, _uiStatusPointerCanvas.height, true, 0xffff0066);
			_uiStatusPointerSlit1 = new BitmapData(_uiStatusPointerSlit0.width, _uiStatusPointerCanvas.height, true, 0x33000000);
			_uiStatusPointer = _uiStatus.addChild( new Bitmap(_uiStatusPointerCanvas) ) as Bitmap;
			_uiStatusPointer.x = 7;
			_uiStatusPointer.y = 45;
			_uiStatusPointerMatrix = new Matrix();
			_uiStatusPointerMatrixWidth = _uiStatusPointerCanvas.width - _uiStatusPointerSlit0.width;
			_uiStatusPointerSlit = _uiStatus.addChild( new Shape() ) as Shape;
			_uiStatusPointerSlit.x = _uiStatusPointer.x;
			_uiStatusPointerSlit.y = _uiStatusPointer.y;
			_uiStatusPointerSlit.graphics.beginFill(0xff0066);
			_uiStatusPointerSlit.graphics.drawRect(0, 0, _uiStatusPointerSlit0.width, _uiStatusPointerSlit0.height);
			_uiStatusPointerSlit.graphics.endFill();
			
			//----------------------------------------
			new FPSMeter(_uiContainer, 422, 440, "FPS ");
		}
		
		private function _uiSourceTextAreaFocusInHandler(e:FocusEvent):void 
		{
			var timer:Timer = new Timer(10);
			timer.addEventListener(TimerEvent.TIMER, function(e:TimerEvent):void
			{
				e.target.removeEventListener(e.type, arguments.callee);
				
				var tf:TextField = _uiSourceTextArea.textField;
				var scroll:int = tf.scrollV;
				tf.setSelection(0,  tf.text.length);
				tf.scrollV = scroll;
			} );
			timer.start();
		}
		
		private function _uiSourceTextAreaKeyFocusChangeHandler(e:FocusEvent):void 
		{
			e.preventDefault();
			
			var tf:TextField = _uiSourceTextArea.textField;
			var str1:String = tf.text.substr(0, tf.selectionBeginIndex);
			var str2:String = tf.text.substr(tf.selectionBeginIndex);
			tf.text = str1 + "\t"+ str2;
			tf.setSelection(tf.selectionBeginIndex + 1, tf.selectionEndIndex + 1);
		}
		
		private function _uiSetStatus():void
		{
			_uiControllerStepText.text = String(_whitespace.stepCount);
			
			_uiStatusStackText.text = _whitespace.stack.join(" ");
			
			var ratio:Number = _uiStatusPointerMatrixWidth / _whitespace.records.length;
			
			_uiStatusPointerCanvas.draw(_uiStatusPointerSlit1, _uiStatusPointerMatrix);
			_uiStatusPointerMatrix.tx = int(_whitespace.pointer * ratio);
		//	_uiStatusPointerCanvas.draw(_uiStatusPointerSlit0, _uiStatusPointerMatrix);
			_uiStatusPointerSlit.x = _uiStatusPointer.x + _uiStatusPointerMatrix.tx;
			_uiStatusPointerSlit.width = Math.max(_uiStatusPointerSlit0.width, (_whitespace.pointer - _whitespace.currentPointer) * ratio);
			var over:Number = (_uiStatusPointerSlit.x + _uiStatusPointerSlit.width) - (_uiStatusPointer.x + _uiStatusPointer.width);
			if (over > 0)  _uiStatusPointerSlit.width -= over;
			
		//	_uiSourceTextArea.textField.setSelection(_whitespace.currentPointer, _whitespace.pointer);
		}
		
		private function _uiClearStatus():void
		{
			_uiControllerStepText.text = "";
			_uiStatusStackText.text = "";
			_uiStatusPointerCanvas.copyPixels(_uiStatusPointerCanvasClear, _uiStatusPointerCanvasClear.rect, new Point());
			_uiStatusPointerSlit.x = _uiStatusPointer.x;
			_uiStatusPointerMatrix = new Matrix();
			_uiStatusPointerSlit.width = _uiStatusPointerSlit0.width;
			
		//	_uiSourceTextArea.textField.setSelection(0, 0);
		}
		
		private function _uiInputSendButtonClickHandler(e:MouseEvent):void
		{
			var message:String = _uiInputTextArea.text;
			_inputInterpreter(message);
		}
		
		private function _uiPresetComboBoxSelectHandler(e:Event):void 
		{
			var item:Object = _uiPresetComboBox.selectedItem;
			_uiSetSource(item["code"]);
		}
		
		private function _uiControllerRunButtonClickHandler(e:MouseEvent):void
		{
			_runInterpreter();
		}
		
		private function _uiControllerStopButtonClickHandler(e:MouseEvent):void
		{
			_stopInterpreter();
		}
		
		private function _uiControllerResetButtonClickHandler(e:MouseEvent):void
		{
			_stopInterpreter();
			_resetInterpreter();
		}
		
		private function _uiControllerSpeedSliderChangeHandler(e:Event):void
		{
			var min:int = 1;
			var max:int = 500;
			var time:int = min + (1 - _uiControllerSpeedSlider.value / 100) * (max - min);
			_setStepInterval(time);
		}
		
		private function _uiSetSource(source:String):void
		{
			_uiSourceTextArea.text = source;
		}
		
		private function _uiSetOutput(...m):void
		{
			_uiOutputTextArea.text = m.join("\n") + "\n";
			_uiOutputTextArea.textField.scrollV = _uiOutputTextArea.textField.maxScrollV;
			
			//var text:String = m.join("\n").split("\n").reverse().join("\n");
			//_uiOutputTextArea.text = text;
		}
		
		private function _uiClearOutput():void
		{
			_uiOutputTextArea.text = "";
		}
		
		private function _uiRequestInput():void
		{
			var fmt:TextFormat = new TextFormat();
			fmt.color = 0xff0066;
			_uiInputTextArea.textField.defaultTextFormat = fmt;
			_uiInputTextArea.text = "Prease answer here,\nthen push Send button!";
			_uiInputTextArea.addEventListener(FocusEvent.FOCUS_IN, _uiInputTextAreaFocusInHandler);
		}
		
		private function _uiInputTextAreaFocusInHandler(e:FocusEvent):void 
		{
			_uiClearInput();
		}
		
		private function _uiClearInput():void
		{
			var fmt:TextFormat = new TextFormat();
			fmt.color = 0x666666;
			_uiInputTextArea.textField.defaultTextFormat = fmt;
			_uiInputTextArea.removeEventListener(FocusEvent.FOCUS_IN, _uiInputTextAreaFocusInHandler);
			_uiInputTextArea.text = "";
		}
	}
}


//package  
//{
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.utils.Dictionary;
	
	/**
	 * Whitespace
	 * 
	 * @author Yukiya Okuda<alumican.net>
	 */
	/*public*/ class Whitespace extends EventDispatcher
	{
		//----------------------------------------
		//CLASS CONSTANTS
		
		//Character
		static public const C_SPACE:String = "S";
		static public const C_TAB:String   = "T";
		static public const C_LF:String    = "L";
		
		//Sign
		static public const SIGN_P:String = C_SPACE;
		static public const SIGN_N:String = C_TAB;
		
		//Bit
		static public const BIT_0:String = C_SPACE;
		static public const BIT_1:String = C_TAB;
		
		//IMP(Instruction Modification Parameter)
		static public const IMP_STACK:String = C_SPACE;
		static public const IMP_ARITH:String = C_TAB + C_SPACE;
		static public const IMP_HEAP:String  = C_TAB + C_TAB;
		static public const IMP_FLOW:String  = C_LF;
		static public const IMP_IO:String    = C_TAB + C_LF;
		
		//Command : Stack Manipulation (IMP : [Space])
		static public const STACK_PUSH:String      = C_SPACE;
		static public const STACK_DUPLICATE:String = C_LF + C_SPACE;
		static public const STACK_COPY:String      = C_TAB + C_SPACE;
		static public const STACK_SWAP:String      = C_LF + C_TAB;
		static public const STACK_DISCARD:String   = C_LF + C_LF;
		static public const STACK_SLIDE:String     = C_TAB + C_LF;
		
		//Command : Arithmetic (IMP : [Tab][Space])
		static public const ARITH_ADD:String  = C_SPACE + C_SPACE;
		static public const ARITH_SUB:String  = C_SPACE + C_TAB;
		static public const ARITH_MULT:String = C_SPACE + C_LF;
		static public const ARITH_DIV:String  = C_TAB + C_SPACE;
		static public const ARITH_MOD:String  = C_TAB + C_TAB;
		
		//Command : Heap Access (IMP : [Tab][Tab])
		static public const HEAP_STORE:String    = C_SPACE;
		static public const HEAP_RETRIEVE:String = C_TAB;
		
		//Command : Flow Control (IMP : [LF])
		static public const FLOW_MARK:String          = C_SPACE + C_SPACE;
		static public const FLOW_CALL_SUB:String      = C_SPACE + C_TAB;
		static public const FLOW_JUMP:String          = C_SPACE + C_LF;
		static public const FLOW_JUMP_IF_TOP_0:String = C_TAB + C_SPACE;
		static public const FLOW_JUMP_IF_TOP_N:String = C_TAB + C_TAB;
		static public const FLOW_END_SUB:String       = C_TAB + C_LF;
		static public const FLOW_EXIT:String          = C_LF + C_LF;
		
		//Command : I/O (IMP : [Tab][LF])
		static public const IO_PRINT_TOKEN:String  = C_SPACE + C_SPACE;
		static public const IO_PRINT_NUMBER:String = C_SPACE + C_TAB;
		static public const IO_READ_TOKEN:String   = C_TAB + C_SPACE;
		static public const IO_READ_NUMBER:String  = C_TAB + C_TAB;
		
		//Event
		static public const EVENT_STEP:String       = "step";
		static public const EVENT_OUT:String        = "out";
		static public const EVENT_IN_REQUEST:String = "inRequest";
		static public const EVENT_IN_RECEIPT:String = "inReceipt";
		static public const EVENT_EXIT:String       = "exit";
		static public const EVENT_ERROR:String      = "error";
		
		//Sample Code
		static public const SAMPLE_HELLO_WORLD:String     = "Say hello.   \n   \t  \t   \n\t\t    \t\n   \t\t  \t \t\n\t\t    \t \n   \t\t \t\t  \n\t\t    \t\t\n   \t\t \t\t  \n\t\t    \t  \n   \t\t \t\t\t\t\n\t\t    \t \t\n   \t \t\t  \n\t\t    \t\t \n   \t     \n\t\t    \t\t\t\n   \t\t\t \t\t\t\n\t\t    \t   \n   \t\t \t\t\t\t\n\t\t    \t  \t\n   \t\t\t  \t \n\t\t    \t \t \n   \t\t \t\t  \n\t\t    \t \t\t\n   \t\t  \t  \n\t\t    \t\t  \n   \t     \n\t\t    \t\t \t\n   \t\t \t\t\t\t\n\t\t    \t\t\t \n   \t\t  \t\t \n\t\t    \t\t\t\t\n   \t     \n\t\t    \t    \n   \t\t\t  \t\t\n\t\t    \t   \t\n   \t\t\t    \n\t\t    \t  \t \n   \t\t    \t\n\t\t    \t  \t\t\n   \t\t   \t\t\n\t\t    \t \t  \n   \t\t  \t \t\n\t\t    \t \t \t\n   \t\t\t  \t\t\n\t\t    \t \t\t \n   \t    \t\n\t\t    \t \t\t\t\n    \n\t\t     \n\n \t \t\t\t \t\t\t \t\t\t  \t  \t\t \t  \t \t\t\t \t   \t\t  \t \t\n\n \t \t\t \t\t\t  \t\t  \t \t \t\t\t \t\t\t \t\t \t\t   \t\t \t  \t \t\t \t\t\t  \t\t  \t \t\n\n\n\n\n   \t\t    \t \t\t  \t   \t\t  \t  \n\t   \n\t\n\n   \t\t\t \t\t\t \t\t\t  \t  \t\t \t  \t \t\t\t \t   \t\t  \t \t\n \n \t\t\t \n \n\t  \t\t\t \t\t\t \t\t\t  \t  \t\t \t  \t \t\t\t \t   \t\t  \t \t \t \t\t\t\t\t \t\t  \t \t \t\t \t\t\t  \t\t  \t  \n\t\n     \t\n\t   \n \n \t\t\t \t\t\t \t\t\t  \t  \t\t \t  \t \t\t\t \t   \t\t  \t \t\n\n   \t\t\t \t\t\t \t\t\t  \t  \t\t \t  \t \t\t\t \t   \t\t  \t \t \t \t\t\t\t\t \t\t  \t \t \t\t \t\t\t  \t\t  \t  \n \n\n \n\n\n\t\n\n   \t\t\t  \t  \t\t  \t \t \t\t    \t \t\t  \t  \n \n  \n \t\n\t \t\t\t \n    \t \t \n\t  \t\n\t  \t\t\t  \t  \t\t  \t \t \t\t    \t \t\t  \t   \t \t\t\t\t\t \t\t  \t \t \t\t \t\t\t  \t\t  \t  \n \n\n   \t\n\t   \n \n \t\t\t  \t  \t\t  \t \t \t\t    \t \t\t  \t  \n\n   \t\t\t  \t  \t\t  \t \t \t\t    \t \t\t  \t   \t \t\t\t\t\t \t\t  \t \t \t\t \t\t\t  \t\t  \t  \n \n\n   \t\n\t       \n\t\t \n\t\n\n   \t\t \t\t\t  \t\t  \t \t \t\t\t \t\t\t \t\t \t\t   \t\t \t  \t \t\t \t\t\t  \t\t  \t \t\n   \t \t \n   \t\t \t\n\t\n  \t\n  \n\t\n";
		static public const SAMPLE_COUNT:String           = "   \t\n\n   \t    \t\t\n \n \t\n \t   \t \t \n\t\n     \t\n\t    \n    \t \t\t\n\t  \t\n\t  \t   \t \t\n\n \n \t    \t\t\n\n   \t   \t \t\n \n\n\n\n\n\n   \t\t    \t \t\t  \t   \t\t  \t  \n\t   \n\t\n\n   \t\t\t \t\t\t \t\t\t  \t  \t\t \t  \t \t\t\t \t   \t\t  \t \t\n \n \t\t\t \n \n\t  \t\t\t \t\t\t \t\t\t  \t  \t\t \t  \t \t\t\t \t   \t\t  \t \t \t \t\t\t\t\t \t\t  \t \t \t\t \t\t\t  \t\t  \t  \n\t\n     \t\n\t   \n \n \t\t\t \t\t\t \t\t\t  \t  \t\t \t  \t \t\t\t \t   \t\t  \t \t\n\n   \t\t\t \t\t\t \t\t\t  \t  \t\t \t  \t \t\t\t \t   \t\t  \t \t \t \t\t\t\t\t \t\t  \t \t \t\t \t\t\t  \t\t  \t  \n \n\n \n\n\n\t\n\n   \t\t\t  \t  \t\t  \t \t \t\t    \t \t\t  \t  \n \n  \n \t\n\t \t\t\t \n    \t \t \n\t  \t\n\t  \t\t\t  \t  \t\t  \t \t \t\t    \t \t\t  \t   \t \t\t\t\t\t \t\t  \t \t \t\t \t\t\t  \t\t  \t  \n \n\n   \t\n\t   \n \n \t\t\t  \t  \t\t  \t \t \t\t    \t \t\t  \t  \n\n   \t\t\t  \t  \t\t  \t \t \t\t    \t \t\t  \t   \t \t\t\t\t\t \t\t  \t \t \t\t \t\t\t  \t\t  \t  \n \n\n   \t\n\t       \n\t\t \n\t\n\n   \t\t \t\t\t  \t\t  \t \t \t\t\t \t\t\t \t\t \t\t   \t\t \t  \t \t\t \t\t\t  \t\t  \t \t\n   \t \t \n   \t\t \t\n\t\n  \t\n  \n\t\n";
		static public const SAMPLE_HELLO_USER:String      = "Ask the user for their\nname. Then say hello.\t \t    \n\t\t    \t\n   \t\t \t\t  \n\t\t    \t \n   \t\t  \t \t\n\t\t    \t\t\n   \t\t    \t\n\t\t    \t  \n   \t\t\t  \t\t\n\t\t    \t \t\n   \t\t  \t \t\n\t\t    \t\t \n   \t     \n\t\t    \t\t\t\n   \t\t  \t \t\n\t\t    \t   \n   \t\t \t\t\t \n\t\t    \t  \t\n   \t\t\t \t  \n\t\t    \t \t \n   \t\t  \t \t\n\t\t    \t \t\t\n   \t\t\t  \t \n\t\t    \t\t  \n   \t     \n\t\t    \t\t \t\n   \t\t\t\t  \t\n\t\t    \t\t\t \n   \t\t \t\t\t\t\n\t\t    \t\t\t\t\n   \t\t\t \t \t\n\t\t    \t    \n   \t\t\t  \t \n\t\t    \t   \t\n   \t     \n\t\t    \t  \t \n   \t\t \t\t\t \n\t\t    \t  \t\t\n   \t\t    \t\n\t\t    \t \t  \n   \t\t \t\t \t\n\t\t    \t \t \t\n   \t\t  \t \t\n\t\t    \t \t\t \n   \t\t\t \t \n\t\t    \t \t\t\t\n   \t     \n\t\t    \t\t   \n    \n\t\t    \t\t\t\t \n   \t  \t   \n\t\t    \t\t\t\t\t\n   \t\t  \t \t\n\t\t    \t     \n   \t\t \t\t  \n\t\t    \t    \t\n   \t\t \t\t  \n\t\t    \t   \t \n   \t\t \t\t\t\t\n\t\t    \t   \t\t\n   \t     \n\t\t    \t  \t  \n    \n\t\t     \n\n \t \t\t\t \t\t\t \t\t\t  \t  \t\t \t  \t \t\t\t \t   \t\t  \t \t\n   \t\t  \t  \n\n \t \t\t\t  \t  \t\t  \t \t \t\t    \t \t\t  \t  \n   \t\t\t\t \n\n \t \t\t\t \t\t\t \t\t\t  \t  \t\t \t  \t \t\t\t \t   \t\t  \t \t\n   \t\t  \t  \n\n \t \t\t\t \t\t\t \t\t\t  \t  \t\t \t  \t \t\t\t \t   \t\t  \t \t\n\n \t \t\t \t\t\t  \t\t  \t \t \t\t\t \t\t\t \t\t \t\t   \t\t \t  \t \t\t \t\t\t  \t\t  \t \t\n\n\n\n\n   \t\t    \t \t\t  \t   \t\t  \t  \n\t   \n\t\n\n   \t\t\t \t\t\t \t\t\t  \t  \t\t \t  \t \t\t\t \t   \t\t  \t \t\n \n \t\t\t \n \n\t  \t\t\t \t\t\t \t\t\t  \t  \t\t \t  \t \t\t\t \t   \t\t  \t \t \t \t\t\t\t\t \t\t  \t \t \t\t \t\t\t  \t\t  \t  \n\t\n     \t\n\t   \n \n \t\t\t \t\t\t \t\t\t  \t  \t\t \t  \t \t\t\t \t   \t\t  \t \t\n\n   \t\t\t \t\t\t \t\t\t  \t  \t\t \t  \t \t\t\t \t   \t\t  \t \t \t \t\t\t\t\t \t\t  \t \t \t\t \t\t\t  \t\t  \t  \n \n\n \n\n\n\t\n\n   \t\t\t  \t  \t\t  \t \t \t\t    \t \t\t  \t  \n \n  \n \t\n\t \t\t\t \n    \t \t \n\t  \t\n\t  \t\t\t  \t  \t\t  \t \t \t\t    \t \t\t  \t   \t \t\t\t\t\t \t\t  \t \t \t\t \t\t\t  \t\t  \t  \n \n\n   \t\n\t   \n \n \t\t\t  \t  \t\t  \t \t \t\t    \t \t\t  \t  \n\n   \t\t\t  \t  \t\t  \t \t \t\t    \t \t\t  \t   \t \t\t\t\t\t \t\t  \t \t \t\t \t\t\t  \t\t  \t  \n \n\n   \t\n\t       \n\t\t \n\t\n\n   \t\t \t\t\t  \t\t  \t \t \t\t\t \t\t\t \t\t \t\t   \t\t \t  \t \t\t \t\t\t  \t\t  \t \t\n   \t \t \n   \t\t \t\n\t\n  \t\n  \n\t\n";
		static public const SAMPLE_CALCULATOR:String      = "Ask the user to enter\na list of numbers\tterminated by -1. \t \t\n\t\t    \t\nWhen they've finished, tell\t\t \t\t\t \nthem\twhat\tthe total is.  \t \n   \t\t\t \t  \n\t\t    \t\t\n   \t\t  \t \t\n\t\t    \t  \n   \t\t\t  \t \n\t\t    \t \t\n   \t     \n\t\t    \t\t \n   \t\t\t  \t\t\n\t\t    \t\t\t\n   \t\t \t\t\t\t\n\t\t    \t   \n   \t\t \t\t \t\n\t\t    \t  \t\n   \t\t  \t \t\n\t\t    \t \t \n   \t     \n\t\t    \t \t\t\n   \t\t \t\t\t \n\t\t    \t\t  \n   \t\t\t \t \t\n\t\t    \t\t \t\n   \t\t \t\t \t\n\t\t    \t\t\t \n   \t\t   \t \n\t\t    \t\t\t\t\n   \t\t  \t \t\n\t\t    \t    \n   \t\t\t  \t \n\t\t    \t   \t\n   \t\t\t  \t\t\n\t\t    \t  \t \n   \t \t\t  \n\t\t    \t  \t\t\n   \t     \n\t\t    \t \t  \n   \t\t\t \t  \n\t\t    \t \t \t\n   \t\t \t   \n\t\t    \t \t\t \n   \t\t  \t \t\n\t\t    \t \t\t\t\n   \t\t \t\t\t \n\t\t    \t\t   \n   \t     \n\t\t    \t\t  \t\n   \t \t\t \t\n\t\t    \t\t \t \n   \t\t   \t\n\t\t    \t\t \t\t\n   \t     \n\t\t    \t\t\t  \n   \t\t\t \t  \n\t\t    \t\t\t \t\n   \t\t \t\t\t\t\n\t\t    \t\t\t\t \n   \t     \n\t\t    \t\t\t\t\t\n   \t\t  \t\t \n\t\t    \t     \n   \t\t \t  \t\n\t\t    \t    \t\n   \t\t \t\t\t \n\t\t    \t   \t \n   \t\t \t  \t\n\t\t    \t   \t\t\n   \t\t\t  \t\t\n\t\t    \t  \t  \n   \t\t \t   \n\t\t    \t  \t \t\n    \n\t\t    \t \t \t \n   \t  \t\t\t \n\t\t    \t \t \t\t\n   \t\t\t \t \t\n\t\t    \t \t\t  \n   \t\t \t\t \t\n\t\t    \t \t\t \t\n   \t\t   \t \n\t\t    \t \t\t\t \n   \t\t  \t \t\n\t\t    \t \t\t\t\t\n   \t\t\t  \t \n\t\t    \t\t    \n   \t\t\t \t \n\t\t    \t\t   \t\n    \n\t\t    \t\t\t\t  \n   \t \t \t  \n\t\t    \t\t\t\t \t\n   \t\t \t\t\t\t\n\t\t    \t\t\t\t\t \n   \t\t\t \t  \n\t\t    \t\t\t\t\t\t\n   \t\t    \t\n\t\t    \t      \n   \t\t \t\t  \n\t\t    \t     \t\n   \t     \n\t\t    \t    \t \n   \t\t \t  \t\n\t\t    \t    \t\t\n   \t\t\t  \t\t\n\t\t    \t   \t  \n   \t     \n\t\t    \t   \t \t\n    \n\t\t     \n\n \t \t\t\t \t\t\t \t\t\t  \t  \t\t \t  \t \t\t\t \t   \t\t  \t \t\n\n \t \t\t \t\t\t  \t\t  \t \t \t\t\t \t\t\t \t\t \t\t   \t\t \t  \t \t\t \t\t\t  \t\t  \t \t\n   \t\t  \t  \n    \n\t\t \n   \t\t \t\t   \t\t \t\t\t\t \t\t \t\t\t\t \t\t\t    \n   \t \t \t \n\n \t \t\t\t \t\t\t \t\t\t  \t  \t\t \t  \t \t\t\t \t   \t\t  \t \t\n   \t\t  \t \t\n\t\n\t\t   \t\t  \t \t\n\t\t\t \n   \t\t\n\t  \t\n\t  \t\t\t     \t\t\t  \t  \t\t \t\t\t\t \t\t  \t\t\t \t\t  \t \t \t\t \t\t\t  \t\t  \t  \n   \t\t  \t  \n\t\t\t\t      \t\t  \t  \n \n\t\t\t \n \n \t\t \t\t   \t\t \t\t\t\t \t\t \t\t\t\t \t\t\t    \n\n   \t\t\t     \t\t\t  \t  \t\t \t\t\t\t \t\t  \t\t\t \t\t  \t \t \t\t \t\t\t  \t\t  \t  \n \n\n   \t\t\t\t  \n\n \t \t\t\t \t\t\t \t\t\t  \t  \t\t \t  \t \t\t\t \t   \t\t  \t \t\n   \t\t  \t  \n\t\t\t\t\n \t\n \t \t\t \t\t\t  \t\t  \t \t \t\t\t \t\t\t \t\t \t\t   \t\t \t  \t \t\t \t\t\t  \t\t  \t \t\n\n\n\n\n   \t\t    \t \t\t  \t   \t\t  \t  \n\t   \n\t\n\n   \t\t\t \t\t\t \t\t\t  \t  \t\t \t  \t \t\t\t \t   \t\t  \t \t\n \n \t\t\t \n \n\t  \t\t\t \t\t\t \t\t\t  \t  \t\t \t  \t \t\t\t \t   \t\t  \t \t \t \t\t\t\t\t \t\t  \t \t \t\t \t\t\t  \t\t  \t  \n\t\n     \t\n\t   \n \n \t\t\t \t\t\t \t\t\t  \t  \t\t \t  \t \t\t\t \t   \t\t  \t \t\n\n   \t\t\t \t\t\t \t\t\t  \t  \t\t \t  \t \t\t\t \t   \t\t  \t \t \t \t\t\t\t\t \t\t  \t \t \t\t \t\t\t  \t\t  \t  \n \n\n \n\n\n\t\n\n   \t\t\t  \t  \t\t  \t \t \t\t    \t \t\t  \t  \n \n  \n \t\n\t \t\t\t \n    \t \t \n\t  \t\n\t  \t\t\t  \t  \t\t  \t \t \t\t    \t \t\t  \t   \t \t\t\t\t\t \t\t  \t \t \t\t \t\t\t  \t\t  \t  \n \n\n   \t\n\t   \n \n \t\t\t  \t  \t\t  \t \t \t\t    \t \t\t  \t  \n\n   \t\t\t  \t  \t\t  \t \t \t\t    \t \t\t  \t   \t \t\t\t\t\t \t\t  \t \t \t\t \t\t\t  \t\t  \t  \n \n\n   \t\n\t       \n\t\t \n\t\n\n   \t\t \t\t\t  \t\t  \t \t \t\t\t \t\t\t \t\t \t\t   \t\t \t  \t \t\t \t\t\t  \t\t  \t \t\n   \t \t \n   \t\t \t\n\t\n  \t\n  \n\t\n";
		static public const SAMPLE_FRACTORIAL:String      = "Ask the user for a\nnumber, then calculate its\t   \t \t\nfactorial.\t\t    \t\n   \t\t \t\t\t \nThis\tprogram\tshows how we can handle\trecursion \nand arbitrarily big numbers.\t\t\t \t  \n\t\t    \t\t\nTry giving 10000 as\t\t  \t \t\ninput...\t\t    \t  \n   \t\t\t  \t \n\t\t    \t \t\n   \t     \n\t\t    \t\t \n   \t\t    \t\n\t\t    \t\t\t\n   \t     \n\t\t    \t   \n   \t\t \t\t\t \n\t\t    \t  \t\n   \t\t\t \t \t\n\t\t    \t \t \n   \t\t \t\t \t\n\t\t    \t \t\t\n   \t\t   \t \n\t\t    \t\t  \n   \t\t  \t \t\n\t\t    \t\t \t\n   \t\t\t  \t \n\t\t    \t\t\t \n   \t\t\t \t \n\t\t    \t\t\t\t\n   \t     \n\t\t    \t    \n    \n\t\t    \t \t  \n   \t    \t\n\t\t    \t \t \t\n   \t     \n\t\t    \t \t\t \n   \t\t\t\t \t\n\t\t    \t \t\t\t\n   \t     \n\t\t    \t\t   \n    \n\t\t     \n\n \t \t\t\t \t\t\t \t\t\t  \t  \t\t \t  \t \t\t\t \t   \t\t  \t \t\n   \t\t  \t  \n\t\n\t\t   \t\t  \t  \n\t\t\t\n \t \t\t  \t\t  \t\t    \t \t\t   \t\t \t\t\t \t  \n   \t\t  \t  \n\t\t\t\t\n \t   \t \t  \n\n \t \t\t\t \t\t\t \t\t\t  \t  \t\t \t  \t \t\t\t \t   \t\t  \t \t\n\t\n \t\n \t \t\t \t\t\t  \t\t  \t \t \t\t\t \t\t\t \t\t \t\t   \t\t \t  \t \t\t \t\t\t  \t\t  \t \t\n\n\n\n\n   \t\t  \t\t  \t\t    \t \t\t   \t\t \t\t\t \t  \n \n    \t\n\t  \t\n\t  \t\t  \t\t  \t\t    \t \t\t   \t\t \t\t\t \t   \t\t   \t  \t\t    \t \t\t\t  \t\t \t\t  \t \t\n \n    \t\n\t  \t\n \t \t\t  \t\t  \t\t    \t \t\t   \t\t \t\t\t \t  \n\t  \n\n\t\n\n   \t\t  \t\t  \t\t    \t \t\t   \t\t \t\t\t \t   \t\t   \t  \t\t    \t \t\t\t  \t\t \t\t  \t \t\n   \t\n \n\n\n\t\n\n   \t\t    \t \t\t  \t   \t\t  \t  \n\t   \n\t\n\n   \t\t\t \t\t\t \t\t\t  \t  \t\t \t  \t \t\t\t \t   \t\t  \t \t\n \n \t\t\t \n \n\t  \t\t\t \t\t\t \t\t\t  \t  \t\t \t  \t \t\t\t \t   \t\t  \t \t \t \t\t\t\t\t \t\t  \t \t \t\t \t\t\t  \t\t  \t  \n\t\n     \t\n\t   \n \n \t\t\t \t\t\t \t\t\t  \t  \t\t \t  \t \t\t\t \t   \t\t  \t \t\n\n   \t\t\t \t\t\t \t\t\t  \t  \t\t \t  \t \t\t\t \t   \t\t  \t \t \t \t\t\t\t\t \t\t  \t \t \t\t \t\t\t  \t\t  \t  \n \n\n \n\n\n\t\n\n   \t\t\t  \t  \t\t  \t \t \t\t    \t \t\t  \t  \n \n  \n \t\n\t \t\t\t \n    \t \t \n\t  \t\n\t  \t\t\t  \t  \t\t  \t \t \t\t    \t \t\t  \t   \t \t\t\t\t\t \t\t  \t \t \t\t \t\t\t  \t\t  \t  \n \n\n   \t\n\t   \n \n \t\t\t  \t  \t\t  \t \t \t\t    \t \t\t  \t  \n\n   \t\t\t  \t  \t\t  \t \t \t\t    \t \t\t  \t   \t \t\t\t\t\t \t\t  \t \t \t\t \t\t\t  \t\t  \t  \n \n\n   \t\n\t       \n\t\t \n\t\n\n   \t\t \t\t\t  \t\t  \t \t \t\t\t \t\t\t \t\t \t\t   \t\t \t  \t \t\t \t\t\t  \t\t  \t \t\n   \t \t \n   \t\t \t\n\t\n  \t\n  \n\t\n";
		static public const SAMPLE_TOWERS_OF_HANOI:String = "Towers of Hanoi solver. \n   \t   \t \t\n\t\t    \t\n   \t\t \t\t\t \n\t\t    \t \n   \t\t\t \t  \n\t\t    \t\t\n   \t\t  \t \t\n\t\t    \t  \n   \t\t\t  \t \n\t\t    \t \t\n   \t     \n\t\t    \t\t \n   \t\t    \t\n\t\t    \t\t\t\n   \t     \n\t\t    \t   \n   \t\t \t\t\t \n\t\t    \t  \t\n   \t\t\t \t \t\n\t\t    \t \t \n   \t\t \t\t \t\n\t\t    \t \t\t\n   \t\t   \t \n\t\t    \t\t  \n   \t\t  \t \t\n\t\t    \t\t \t\n   \t\t\t  \t \n\t\t    \t\t\t \n   \t\t\t \t \n\t\t    \t\t\t\t\n   \t     \n\t\t    \t    \n    \n\t\t    \t \t  \n   \t     \n\t\t    \t \t \t\n   \t \t\t \t\n\t\t    \t \t\t \n   \t\t\t\t\t \n\t\t    \t \t\t\t\n   \t     \n\t\t    \t\t   \n    \n\t\t     \n\n \t \t\t\t \t\t\t \t\t\t  \t  \t\t \t  \t \t\t\t \t   \t\t  \t \t\n   \t\t  \t  \n\t\n\t\t   \t\t  \t  \n\t\t\t   \t\n   \t\t\n   \t \n\n \t \t\t \t    \t\t    \t \t\t \t\t\t  \t\t \t\t\t\t \t\t \t  \t\n\n\n\n\n   \t\t \t    \t\t    \t \t\t \t\t\t  \t\t \t\t\t\t \t\t \t  \t\n   \t\t  \t\t\t\n \n\t\t\t    \t\t  \t\t \n \n\t\t\t    \t\t  \t \t\n \n\t\t\t    \t\t  \t  \n \n\t\t\t    \t\t  \t  \n\t\t\t\n\t  \t\t  \t \t \t\t \t\t\t  \t\t  \t   \t\t \t    \t\t    \t \t\t \t\t\t  \t\t \t\t\t\t \t\t \t  \t\n   \t\t  \t  \n\t\t\t   \t\t  \t \t\n\t\t\t   \t\t  \t\t \n\t\t\t   \t\t  \t\t\t\n\t\t\t   \t\t  \t  \n\t\t\t   \t\n\t  \t   \t\t  \t \t\n\t\t\t   \t\t  \t\t\t\n\t\t\t   \t\t  \t\t \n\t\t\t\n \t \t\t \t    \t\t    \t \t\t \t\t\t  \t\t \t\t\t\t \t\t \t  \t\n   \t\t  \t\t\t\n \n\t\t\t    \t\t  \t\t \n \n\t\t\t    \t\t  \t \t\n \n\t\t\t    \t\t  \t  \n \n\t\t\t    \t\t  \t \t\n\t\t\t\t\n \t   \t \t  \n\n \t \t\t\t \t\t\t \t\t\t  \t  \t\t \t  \t \t\t\t \t   \t\t  \t \t\n   \t\t  \t\t \n\t\t\t\t\n \t\n \t \t\t \t\t\t  \t\t  \t \t \t\t\t \t\t\t \t\t \t\t   \t\t \t  \t \t\t \t\t\t  \t\t  \t \t\n   \t\t  \t  \n\t\t\t   \t\t  \t \t\n\t\t\t   \t\t  \t\t \n\t\t\t   \t\t  \t\t\t\n\t\t\t   \t\t  \t  \n\t\t\t   \t\n\t  \t   \t\t  \t\t\t\n\t\t\t   \t\t  \t\t \n\t\t\t   \t\t  \t \t\n\t\t\t\n \t \t\t \t    \t\t    \t \t\t \t\t\t  \t\t \t\t\t\t \t\t \t  \t\n   \t\t  \t\t\t\n \n\t\t\t    \t\t  \t\t \n \n\t\t\t    \t\t  \t \t\n \n\t\t\t    \t\t  \t  \n \n\t\t\t \n   \t\t  \t \t \t\t \t\t\t  \t\t  \t   \t\t \t    \t\t    \t \t\t \t\t\t  \t\t \t\t\t\t \t\t \t  \t\n\n\t\n\n   \t\t    \t \t\t  \t   \t\t  \t  \n\t   \n\t\n\n   \t\t\t \t\t\t \t\t\t  \t  \t\t \t  \t \t\t\t \t   \t\t  \t \t\n \n \t\t\t \n \n\t  \t\t\t \t\t\t \t\t\t  \t  \t\t \t  \t \t\t\t \t   \t\t  \t \t \t \t\t\t\t\t \t\t  \t \t \t\t \t\t\t  \t\t  \t  \n\t\n     \t\n\t   \n \n \t\t\t \t\t\t \t\t\t  \t  \t\t \t  \t \t\t\t \t   \t\t  \t \t\n\n   \t\t\t \t\t\t \t\t\t  \t  \t\t \t  \t \t\t\t \t   \t\t  \t \t \t \t\t\t\t\t \t\t  \t \t \t\t \t\t\t  \t\t  \t  \n \n\n \n\n\n\t\n\n   \t\t\t  \t  \t\t  \t \t \t\t    \t \t\t  \t  \n \n  \n \t\n\t \t\t\t \n    \t \t \n\t  \t\n\t  \t\t\t  \t  \t\t  \t \t \t\t    \t \t\t  \t   \t \t\t\t\t\t \t\t  \t \t \t\t \t\t\t  \t\t  \t  \n \n\n   \t\n\t   \n \n \t\t\t  \t  \t\t  \t \t \t\t    \t \t\t  \t  \n\n   \t\t\t  \t  \t\t  \t \t \t\t    \t \t\t  \t   \t \t\t\t\t\t \t\t  \t \t \t\t \t\t\t  \t\t  \t  \n \n\n   \t\n\t       \n\t\t \n\t\n\n   \t\t \t\t\t  \t\t  \t \t \t\t\t \t\t\t \t\t \t\t   \t\t \t  \t \t\t \t\t\t  \t\t  \t \t\n   \t \t \n   \t\t \t\n\t\n  \t\n  \n\t\n";
		static public const SAMPLE_FIBONACCI:String       = "Ask the user how\tmany  \t   \nfibonacci\tnumbers\nthey want from the sequence \t\t \t\t\t\t\nand\tprint\nthat many one number per line.\t\t\t \t\t\t\n\t\n     \t     \n\t\n     \t\t \t\t \t\n\t\n     \t\t    \t\n\t\n     \t\t \t\t\t \n\t\n     \t\t\t\t  \t\n\t\n     \t\t\t\t\t\t\n\t\n     \t     \n\t\n     \t \n\t\n\t\t    \n   \t\n \n \t\n \t   \t \t \n\t\n  \n  \t\n \n    \t\n \n\t\t\t \t      \t\n\t\t\t \n\t \n \t\n \t   \t \t \n\t\n     \t \n\t\t\t   \t\n\t  \t \n    \t \n \n\t\t\t \n\t\t\t \n\n \n\t\n\n  \t \n\n\n\n";
		
		
		
		
		
		//----------------------------------------
		//VARIABLES
		
		/**
		 * ソースコード
		 */
		public function get source():String { return _source; }
		public function set source(value:String):void { _source = value; }
		private var _source:String;
		
		/**
		 * プリコンパイル済みレコード
		 */
		public function get records():Array { return _records.concat(); }
		private var _records:Array;
		
		/**
		 * 現在のレコード実行位置を示すポインタ
		 */
		public function get currentPointer():Number { return _currentPointer; }
		private var _currentPointer:Number;
		
		/**
		 * 次状態でのレコード実行位置を示すポインタ
		 */
		public function get pointer():Number { return _pointer; }
		private var _pointer:Number;
		
		/**
		 * スタック(int型)
		 */
		public function get stack():Array { return _stack.concat(); }
		private var _stack:Array;
		
		/**
		 * ヒープ(int型)
		 */
		public function get heap():Dictionary { return _heap; }
		private var _heap:Dictionary;
		
		/**
		 * サブルーチンの呼び出し元ポインタを格納するスタック(int型)
		 */
		public function get callStack():Array { return _callStack.concat(); }
		private var _callStack:Array;
		
		/**
		 * ラベルに対するレコードのポインタを格納する(int型)
		 */
		public function get labels():Dictionary { return _labels; }
		private var _labels:Dictionary;
		
		/**
		 * コード実行中の場合はtrue
		 */
		public function get isRunning():Boolean { return _isRunning; }
		private var _isRunning:Boolean;
		
		/**
		 * 現在のステップ数
		 */
		public function get stepCount():Number { return _stepCount; }
		private var _stepCount:Number;
		
		/**
		 * 現在の出力状態
		 */
		public function get output():String { return _output; }
		private var _output:String;
		
		/**
		 * ユーザからの数値入力待ちの場合はtrue
		 */
		public function get isWaitingInputNumber():Boolean { return _isWaitingInputNumber; }
		private var _isWaitingInputNumber:Boolean;
		
		/**
		 * ユーザからの文字入力待ちの場合はtrue
		 */
		public function get isWaitingInputToken():Boolean { return _isWaitingInputToken; }
		private var _isWaitingInputToken:Boolean;
		
		/**
		 * ラベルを探索中の場合はtrue
		 */
		private var _isSearchingLabel:Boolean;
		
		/**
		 * デバッグ出力を使用する場合はtrue
		 */
		public function get useDebugLog():Boolean { return _useDebugLog; }
		public function set useDebugLog(value:Boolean):void { _useDebugLog = value; }
		private var _useDebugLog:Boolean;
		
		/**
		 * 入力バッファ
		 */
		private var _inputBuffer:Array;
		
		/**
		 * 構文エラーが検出された場合はtrue
		 */
		public function get hasSyntaxError():Boolean { return _hasSyntaxError; }
		private var _hasSyntaxError:Boolean;
		
		/**
		 * いずれかのエラーが検出された場合はtrue
		 */
		public function get hasError():Boolean { return _hasError; }
		private var _hasError:Boolean;
		
		
		
		
		
		//----------------------------------------
		//STAGE INSTANCES
		
		
		
		
		
		//----------------------------------------
		//METHODS
		
		/**
		 * コンストラクタ
		 */
		public function Whitespace(source:String = ""):void 
		{
			_source = source;
			_useDebugLog = false;
			reset();
		}
		
		
		
		
		
		/**
		 * インタプリタを開始する
		 */
		public function run():void
		{
			if (_isRunning) return;
			reset();
			_isRunning = true;
			_searchLabels();
		}
		
		/**
		 * 状態を進める
		 */
		public function step():void
		{
			if (!_isRunning) return;
			if (_isWaitingInputToken) return;
			if (_isWaitingInputNumber) return;
			
			if (_pointer >= _records.length)
			{
				_log("records index error : pointer = " + _pointer + ", records.length = " + _records.length);
				return;
			}
			
			if (!_isSearchingLabel)
			{
				++_stepCount;
				//_log("STEP " + _stepCount);
			}
			
			//現在の実行位置
			_currentPointer = _pointer;
			
			//IMPの判別
			if      (equals(IMP_STACK)) impStack();
			else if (equals(IMP_ARITH)) impArith();
			else if (equals(IMP_HEAP )) impHeap();
			else if (equals(IMP_FLOW )) impFlow();
			else if (equals(IMP_IO   )) impIO();
			else    _notifyExit(1);
			
			if (!_isSearchingLabel)
			{
				//_log("stack : " + _stack);
				_notifyStep();
			}
		}
		
		/**
		 * 状態をリセットする
		 */
		public function reset():void
		{
			_records = precompile(_source).split("");
			_pointer = 0;
			_currentPointer = 0;
			_stack = new Array();
			_heap = new Dictionary();
			_callStack = new Array();
			_labels = new Dictionary();
			_isRunning = false;
			_stepCount = 0;
			_output = "";
			_isWaitingInputToken = false;
			_isWaitingInputNumber = false;
			_isSearchingLabel = false;
			_inputBuffer = new Array();
			_hasSyntaxError = false;
			_hasError = false;
		}
		
		/**
		 * 全てのラベルを探索する
		 */
		private function _searchLabels():void
		{
			_isSearchingLabel = true;
			while (!_hasError && _pointer < _records.length)
			{
				step();
			}
			_isSearchingLabel = false;
			_pointer = 0;
		}
		
		
		
		
		
		/**************************************************************//**
		 * IMP
		 * Each command consists of a series of tokens,
		 * beginning with the Instruction Modification Parameter (IMP).
		 */
		
		/**
		 * [Space] : Stack Manipulation
		 */
		public function impStack():void
		{
			_pointer += IMP_STACK.length;
			
			if      (equals(STACK_PUSH     )) stackPush();
			else if (equals(STACK_DUPLICATE)) stackDuplicate();
			else if (equals(STACK_COPY     )) stackCopy();
			else if (equals(STACK_SWAP     )) stackSwap();
			else if (equals(STACK_DISCARD  )) stackDiscard();
			else if (equals(STACK_SLIDE    )) stackSlide();
			else    _notifyExit(1);
		}
		
		/**
		 * [Tab][Space] : Arithmetic
		 */
		public function impArith():void
		{
			_pointer += IMP_ARITH.length;
			
			if      (equals(ARITH_ADD )) arithAdd();
			else if (equals(ARITH_SUB )) arithSub();
			else if (equals(ARITH_MULT)) arithMult();
			else if (equals(ARITH_DIV )) arithDiv();
			else if (equals(ARITH_MOD )) arithMod();
			else    _notifyExit(1);
		}
		
		/**
		 * [Tab][Tab] : Heap access
		 */
		public function impHeap():void
		{
			_pointer += IMP_HEAP.length;
			
			if      (equals(HEAP_STORE   )) heapStore();
			else if (equals(HEAP_RETRIEVE)) heapRetrieve();
			else    _notifyExit(1);
		}
		
		/**
		 * [LF] : Flow Control
		 */
		public function impFlow():void
		{
			_pointer += IMP_FLOW.length;
			
			if      (equals(FLOW_MARK         )) flowMark();
			else if (equals(FLOW_CALL_SUB     )) flowCallSub();
			else if (equals(FLOW_JUMP         )) flowJump();
			else if (equals(FLOW_JUMP_IF_TOP_0)) flowJumpIfTop0();
			else if (equals(FLOW_JUMP_IF_TOP_N)) flowJumpIfTopN();
			else if (equals(FLOW_END_SUB      )) flowEndSub();
			else if (equals(FLOW_EXIT         )) flowExit();
			else    _notifyExit(1);
		}
		
		/**
		 * [Tab][LF] : I/O
		 */
		public function impIO():void
		{
			_pointer += IMP_IO.length;
			
			if      (equals(IO_PRINT_TOKEN )) ioPrintToken();
			else if (equals(IO_PRINT_NUMBER)) ioPrintNumber();
			else if (equals(IO_READ_TOKEN  )) ioReadToken();
			else if (equals(IO_READ_NUMBER )) ioReadNumber();
			else    _notifyExit(1);
		}
		
		
		
		
		
		/**************************************************************//**
		 * Stack Manipulation (IMP : [Space])
		 * Stack manipulation is one of the more common operations,
		 * hence the shortness of the IMP [Space].
		 * There are four stack instructions.
		 */
		
		/**
		 * [Space] Number : Push the number onto the stack
		 */
		public function stackPush():void
		{
			_pointer += STACK_PUSH.length;
			if (_isSearchingLabel) { _readNumber(); return; }
			
			var value:Number = _readNumber();
			_stack.push(value);
			
			_log(">> STACK_PUSH [S S] value=" + value);
		}
		
		/**
		 * [LF][Space] : Duplicate the top item on the stack
		 */
		public function stackDuplicate():void
		{
			_pointer += STACK_DUPLICATE.length;
			if (_isSearchingLabel) return;
			
			var value:Number = _stack[_stack.length - 1];
			_stack.push(value);
			
			_log(">> STACK_DUPLICATE [S LS] value=" + value);
		}
		
		/**
		 * [Tab][Space]	Number : Copy the nth item on the stack (given by the argument) onto the top of the stack
		 */
		public function stackCopy():void
		{
			_pointer += STACK_COPY.length;
			if (_isSearchingLabel) { _readNumber(); return; }
			
			var index:Number = _readNumber();
			var value:Number = _stack[index];
			_stack.push(value);
			
			_log(">> STACK_COPY [S TS] value=" + value);
		}
		
		/**
		 * [LF][Tab] : Swap the top two items on the stack
		 */
		public function stackSwap():void
		{
			_pointer += STACK_SWAP.length;
			if (_isSearchingLabel) return;
			
			var index1:Number = _stack.length - 1;
			var index2:Number = index1 - 1;
			var value1:Number = _stack[index1];
			var value2:Number = _stack[index2];
			_stack[index1] = value2;
			_stack[index2] = value1;
			
			_log(">> STACK_SWAP [S LT] value1=" + value1 + ",value2=" + value2);
		}
		
		/**
		 * [LF][LF] : Discard the top item on the stack
		 */
		public function stackDiscard():void
		{
			_pointer += STACK_DISCARD.length;
			if (_isSearchingLabel) return;
			
			var value:Number = _stack.pop();
			
			_log(">> STACK_DISCARD [S LL] value=" + value);
		}
		
		/**
		 * [Tab][LF] Number : Slide n items off the stack, keeping the top item
		 */
		public function stackSlide():void
		{
			_pointer += STACK_SLIDE.length;
			if (_isSearchingLabel) { _readNumber(); return; }
			
			var n:Number = _readNumber();
			var values:Array = _stack.splice(_stack.length - n - 1, n);
			
			_log(">> STACK_SLIDE [S TL] values=[" + values + "]");
		}
		
		
		
		
		
		/**************************************************************//**
		 * Arithmetic (IMP : [Tab][Space])
		 * Arithmetic commands operate on the top two items on the stack,
		 * and replace them with the result of the operation.
		 * The first item pushed is considered to be left of the operator.
		 */
		
		/**
		 * [Space][Space] : Addition
		 */
		public function arithAdd():void
		{
			_pointer += ARITH_ADD.length;
			if (_isSearchingLabel) return;
			
			var r:Number = _stack.pop();
			var l:Number = _stack.pop();
			var n:Number = l + r;
			_stack.push(n);
			
			_log(">> ARITH_ADD [TS SS] l=" + l + ",r=" + r + ",result=" + n);
		}
		
		/**
		 * [Space][Tab] : Subtraction
		 */
		public function arithSub():void
		{
			_pointer += ARITH_SUB.length;
			if (_isSearchingLabel) return;
			
			var r:Number = _stack.pop();
			var l:Number = _stack.pop();
			var n:Number = l - r;
			_stack.push(n);
			
			_log(">> ARITH_SUB [TS ST] l=" + l + ",r=" + r + ",result=" + n);
		}
		
		/**
		 * [Space][LF] : Multiplication
		 */
		public function arithMult():void
		{
			_pointer += ARITH_MULT.length;
			if (_isSearchingLabel) return;
			
			var r:Number = _stack.pop();
			var l:Number = _stack.pop();
			var n:Number = l * r;
			_stack.push(n);
			
			_log(">> ARITH_MULT [TS SL] l=" + l + ",r=" + r + ",result=" + n);
		}
		
		/**
		 * [Tab][Space] : Integer Division
		 */
		public function arithDiv():void
		{
			_pointer += ARITH_DIV.length;
			if (_isSearchingLabel) return;
			
			var r:Number = _stack.pop();
			var l:Number = _stack.pop();
			var n:Number = Math.floor(l / r);
			_stack.push(n);
			
			_log(">> ARITH_DIV [TS TS] l=" + l + ",r=" + r + ",result=" + n);
		}
		
		/**
		 * [Tab][Tab] : Modulo
		 */
		public function arithMod():void
		{
			_pointer += ARITH_MOD.length;
			if (_isSearchingLabel) return;
			
			var r:Number = _stack.pop();
			var l:Number = _stack.pop();
			var n:Number = l % r;
			_stack.push(n);
			
			_log(">> ARITH_MOD [TS TT] l=" + l + ",r=" + r + ",result=" + n);
		}
		
		
		
		
		
		/**************************************************************//**
		 * Heap Access (IMP : [Tab][Tab])
		 * Heap access commands look at the stack to find the address of items to be stored or retrieved.
		 * To store an item, push the address then the value and run the store command.
		 * To retrieve an item, push the address and run the retrieve command,
		 * which will place the value stored in the location at the top of the stack. 
		 */
		
		/**
		 * [Space] : Store
		 */
		public function heapStore():void
		{
			_pointer += HEAP_STORE.length;
			if (_isSearchingLabel) return;
			
			var value:Number = _stack.pop();
			var address:Number = _stack.pop();
			_heap[address] = value;
			
			_log(">> HEAP_STORE [TT S] address=" + address + ",value=" + value);
		}
		
		/**
		 * [Tab] : Retrieve
		 */
		public function heapRetrieve():void
		{
			_pointer += HEAP_RETRIEVE.length;
			if (_isSearchingLabel) return;
			
			var address:Number = _stack.pop();
			var value:Number = _heap[address];
			_stack.push(value);
			
			_log(">> HEAP_RETRIEVE [TT T] address=" + address + ",value=" + value);
		}
		
		
		
		
		
		/**************************************************************//**
		 * Flow Control (IMP : [LF])
		 * Flow control operations are also common.
		 * Subroutines are marked by labels,
		 * as well as the targets of conditional and unconditional jumps, by which loops can be implemented.
		 * Programs must be ended by means of [LF][LF][LF] so that the interpreter can exit cleanly.
		 */
		
		 /**
		  * [Space][Space] Label : Mark a location in the program
		  */
		public function flowMark():void
		{
			_pointer += FLOW_MARK.length;
			
			var label:String = _readLabel();
			_labels[label] = _pointer;
			
			_log(">> FLOW_MARK [L SS] label=" + label + ",pointer=" + _pointer);
		}
		
		/**
		 * [Space][Tab] Label : Call a subroutine
		 */
		public function flowCallSub():void
		{
			_pointer += FLOW_CALL_SUB.length;
			if (_isSearchingLabel) { _readLabel(); return; }
			
			var label:String = _readLabel();
			_callStack.push(_pointer);
			_pointer = _labels[label];
			
			_log(">> FLOW_CALL_SUB [L ST] label=" + label + ",pointer=" + _pointer);
		}
		
		/**
		 * [Space][LF] Label : Jump unconditionally to a label
		 */
		public function flowJump():void
		{
			_pointer += FLOW_JUMP.length;
			if (_isSearchingLabel) { _readLabel(); return; }
			
			var label:String = _readLabel();
			_pointer = _labels[label];
			
			_log(">> FLOW_JUMP [L SL] label=" + label + ",pointer=" + _pointer);
		}
		
		/**
		 * [Tab][Space] Label : Jump to a label if the top of the stack is zero
		 */
		public function flowJumpIfTop0():void
		{
			_pointer += FLOW_JUMP_IF_TOP_0.length;
			if (_isSearchingLabel) { _readLabel(); return; }
			
			var condition:Number = _stack.pop();
			var label:String = _readLabel();
			
			if (condition == 0)
			{
				_pointer = _labels[label];
			}
			
			_log(">> FLOW_JUMP_IF_TOP_0 [L TS] label=" + label + ",pointer=" + _pointer + ",(" + condition + "==0)");
		}
		
		/**
		 * [Tab][Tab] Label : Jump to a label if the top of the stack is negative
		 */
		public function flowJumpIfTopN():void
		{
			_pointer += FLOW_JUMP_IF_TOP_N.length;
			if (_isSearchingLabel) { _readLabel(); return; }
			
			var condition:Number = _stack.pop();
			var label:String = _readLabel();
			
			if (condition < 0)
			{
				_pointer = _labels[label];
			}
			
			_log(">> FLOW_JUMP_IF_TOP_N [L TT] label=" + label + ",pointer=" + _pointer + ",(" + condition + "<0)");
		}
		
		/**
		 * [Tab][LF] : End a subroutine and transfer control back to the caller
		 */
		public function flowEndSub():void
		{
			_pointer += FLOW_END_SUB.length;
			if (_isSearchingLabel) return;
			
			_pointer = _callStack.pop();
			
			_log(">> FLOW_END_SUB [L TL] pointer=" + _pointer);
		}
		
		/**
		 * [LF][LF] : End the program
		 */
		public function flowExit():void
		{
			_pointer += FLOW_EXIT.length;
			if (_isSearchingLabel) return;
			
			_notifyExit(0);
			
			_log(">> FLOW_EXIT [L LL]");
		}
		
		
		
		
		
		/**************************************************************//**
		 * I/O (IMP : [Tab][LF])
		 * Finally, we need to be able to interact with the user.
		 * There are IO instructions for reading and writing numbers and individual characters.
		 * With these, string manipulation routines can be written.
		 * The read instructions take the heap address in which to store the result from the top of the stack. 
		 */
		
		/**
		 * [Space][Space] : Output the character at the top of the stack
		 */
		public function ioPrintToken():void
		{
			_pointer += IO_PRINT_TOKEN.length;
			if (_isSearchingLabel) return;
			
			var message:String = String.fromCharCode(_stack.pop());
			_notifyOutput(message);
			
			_log(">> IO_PRINT_TOKEN [TL SS] token=" + message);
		}
		
		/**
		 * [Space][Tab] : Output the number at the top of the stack
		 */
		public function ioPrintNumber():void
		{
			_pointer += IO_PRINT_NUMBER.length;
			if (_isSearchingLabel) return;
			
			var message:String = String(_stack.pop());
			_notifyOutput(message);
			
			_log(">> IO_PRINT_NUMBER [TL ST] token=" + message);
		}
		
		/**
		 * [Tab][Space] : Read a character and place it in the location given by the top of the stack
		 */
		public function ioReadToken():void
		{
			_pointer += IO_READ_TOKEN.length;
			if (_isSearchingLabel) return;
			
			//_notifyInputRequest(true);
			
			if (_inputBuffer.length > 0)
			{
				//バッファから取り出す
				var token:String = _inputBuffer.shift();
				var address:Number = _stack.pop();
				var value:Number = token.charCodeAt(0);
				_heap[address] = value;
				
				_log(">> IO_READ_TOKEN [TL TS] address=" + address + ",value=" + value + ",token=" + token);
			}
			else
			{
				//バッファが空
				_log(">> IO_READ_TOKEN [TL TS] request");
				_notifyInputRequest(true);
			}
		}
		
		/**
		 * [Tab][Tab] : Read a number and place it in the location given by the top of the stack
		 */
		public function ioReadNumber():void
		{
			_pointer += IO_READ_NUMBER.length;
			if (_isSearchingLabel) return;
			_log(">> IO_READ_NUMBER [TL TT]");
			
			if (_inputBuffer.length > 0)
			{
				//バッファから取り出す
				var token:String = _inputBuffer.shift();
				var address:Number = _stack.pop();
				var value:Number = token.charCodeAt(0);
				_heap[address] = value;
				
				_log(">> IO_READ_NUMBER [TL TT] address=" + address + ",value=" + value + ",token=" + token);
			}
			else
			{
				//バッファが空
				_log(">> IO_READ_NUMBER [TL TT] request");
				_notifyInputRequest(false);
			}
		}
		
		/**
		 * インタプリタに文字を入力する
		 */
		public function inputToken(string:String):void
		{
			if (!_isWaitingInputToken) return;
			_isWaitingInputToken = false;
			
			//バッファをセット
			_inputBuffer = string.split("\n")[0].split("").concat("\n");
			
			//バッファから取り出してヒープにセット
			var token:String = _inputBuffer.shift();
			var address:Number = _stack.pop();
			var value:Number = token.charCodeAt(0);
			_heap[address] = value;
			
			_log(">> USER_INPUT [] address=" + address + ",value=" + value + ",token=" + token);
			_notifyInputReceipt(true);
		}
		
		/**
		 * インタプリタに数値を入力する(整数値のみ)
		 */
		public function inputNumber(number:int):void
		{
			if (!_isWaitingInputNumber) return;
			_isWaitingInputNumber = false;
			
			//バッファをセット
			_inputBuffer = [number];
			
			//バッファから取り出してヒープにセット
			var address:Number = _stack.pop();
			var value:Number = Math.floor(_inputBuffer.shift());
			_heap[address] = value;
			
			_log(">> USER_INPUT [] address=" + address + ",value=" + value);
			_notifyInputReceipt(false);
		}
		
		
		
		
		
		/**************************************************************//**
		 * Numbers can be any number of bits wide, and are simply represented as a series of [Space] and [Tab],
		 * terminated by a [LF]. [Space] represents the binary digit 0, [Tab] represents 1.
		 * The sign of a number is given by its first character, [Space] for positive and [Tab] for negative.
		 * Note that this is not twos complement, it just indicates a sign.
		 */
		
		/**
		 * ポインタの示す位置から[LF]に到達するまで数値を読み取る
		 * 処理後ポインタは[FL]の次の位置を指す
		 * 1ビット目は符号を表す
		 */
		private function _readNumber():Number
		{
			var sign:String = _records[_pointer++];
			var value:Number = 0;
			var token:String;
			while ((token = _records[_pointer++]) != C_LF)
			{
				if (_pointer >= _records.length)
				{
					_notifyExit(1);
					return 0;
				}
				
				value <<= 1;
				value |= (token == BIT_0) ? 0 : 1;
			}
			return (sign == SIGN_P) ? value : -value;
		}
		
		/**
		 * ポインタの示す位置から[LF]に到達するまでラベルを読み取る
		 * 処理後ポインタは[FL]の次の位置を指す
		 */
		private function _readLabel():String
		{
			var value:String = "";
			var token:String = "";
			while ((token = _records[_pointer++]) != C_LF)
			{
				if (_pointer >= _records.length)
				{
					_notifyExit(1);
					return "";
				}
				
				value += (token == BIT_0) ? "0" : "1";
			}
			return value;
		}
		
		
		
		
		
		/**************************************************************//**
		 * The only lexical tokens in the whitespace language are Space (ASCII 32), Tab (ASCII 9) and Line Feed (ASCII 10).
		 * By only allowing line feed as a token, CR/LF problems are avoided across DOS/Unix file conversions.
		 * (Um, not sure. Maybe we'll sort this in a later version.). 
		 */
		
		/**
		 * ソースコードを読みやすい感じに書き換える
		 */
		public function precompile(source:String):String
		{
			if (source == null) return "";
			source = source.replace(/\r|\n|\r\n/g, "\n");
			var s:String = "";
			var n:Number = source.length;
			for (var i:Number = 0; i < n; ++i)
			{
				var c:String = source.charAt(i);
				s += (c == " " ) ? C_SPACE : //[SPACE]
				     (c == "\t") ? C_TAB   : //[TAB]
				     (c == "\n") ? C_LF    : //[LF]
					               ""      ; //Comment
			}
			return s;
		}
		
		/**
		 * 指定したインデックスを起点として指定長だけレコードを抽出する
		 * インデックスを指定しない場合は現在のポインタの位置を起点とする
		 * 処理によってポインタは移動しない
		 */
		public function extract(length:Number, index:Number = -1):String
		{
			index = (index < 0) ? _pointer : index;
			return _records.slice(index, index + length).join("");
		}
		
		/**
		 * 指定したインデックスを起点として指定長だけ抽出したレコードと,引数に指定したトークンを比較する
		 * インデックスを指定しない場合は現在のポインタの位置を起点とする
		 * 処理によってポインタは移動しない
		 */
		public function equals(token:String, index:Number = -1):Boolean
		{
			return extract(token.length, index) == token;
		}
		
		
		
		
		
		/**
		 * 各種イベントの発行
		 */
		private function _notifyStep():void
		{
			dispatchEvent( new Event(EVENT_STEP) );
		}
		
		private function _notifyOutput(m:String):void
		{
			_output += m;
			dispatchEvent( new Event(EVENT_OUT) );
		}
		
		private function _notifyInputRequest(isToken:Boolean):void
		{
			if (isToken) _isWaitingInputToken = true;
			if (!isToken) _isWaitingInputNumber = true;
			dispatchEvent( new Event(EVENT_IN_REQUEST) );
		}
		
		private function _notifyInputReceipt(isToken:Boolean):void
		{
			if (isToken) _isWaitingInputToken = false;
			if (!isToken) _isWaitingInputNumber = false;
			dispatchEvent( new Event(EVENT_IN_RECEIPT) );
		}
		
		private function _notifyExit(code:int):void
		{
			_isRunning = false;
			switch (code)
			{
				case 0:
					dispatchEvent( new Event(EVENT_EXIT) );
					break;
					
				case 1:
					_hasError = true;
					_hasSyntaxError = true;
					dispatchEvent( new Event(EVENT_ERROR) );
					break;
			}
		}
		
		
		
		
		
		/**
		 * デバッグ出力
		 */
		private function _log(...m):void
		{
			if (_useDebugLog)
			{
				trace(m.join(" "));
			}
		}
	}
//}