flash on 2012-2-17

by tepe
♥0 | Line 834 | Modified 2012-05-30 17:52:50 | MIT License
play

ActionScript3 source code

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

package { 
    import flash.utils.Dictionary;
    import flash.display.*;
    import flash.text.*;
    import flash.events.*;
    import flash.net.*;
    import flash.utils.*;
    import net.hires.debug.Stats;
    


    public class FlashTest extends Sprite {
        private var t1:TextEditor = new TextEditor();//原文
        private var t2:TextField = new TextField();
        
        public function FlashTest() {
            // write as3 code here..
            init();
            //FPS計測    
            addChild( new Stats() );
            Wonderfl.capture(stage);
            onChange(null);
            
        }
        
 
        private function init():void{
            //原文テキスト入力ボックス
            t1.border = true;
            t1.width = 230;
            t1.height = 360;
            t1.y=100;
            t1.type = "input";
            //t1.multiline = true;
            t1.text = "1234567890\ntest\nあいうえお test";
            addChild(t1);
            t1.addEventListener(Event.CHANGE,onChange);
            t2.x = 230;
            t2.width=230;
            t2.height=460;
            t2.wordWrap =true;
            addChild(t2);

            
        }
        
        

        private var tk:token;
        private function onChange(e:Event=null):void{
            var cnt:int=0;
            tk = new token();
            var i:int;
            var index:int=0;
            var len:int = t1.length;
            


            //tk.getToken(t1.text,0,100);
            tk.addEventListener(Event.COMPLETE,onComplete);
            tk.addEventListener(Event.CHANGE,onChange2);
            count1=0;
            tk.getToken2(t1.text);
           // t2.text = String(Math.random()*50);
            //tk.func2();
            //tk.setKeywordAS3();
            
        }
        private var count1:int=0;
        private function onChange2(e:Event):void{
            t2.text = count1.toString();
            count1++;
        }
        
        //スペースとコメント以外が出るまで進める
        private function spaceCut(cnt:int):int{//
            var i:int;
            for(i=cnt;i<tk.listLength;i++){
                if(tk.list[i].type=="space")continue;
                if(tk.list[i].type=="comment")continue;

                break;
            }
            return i;
        }

        //token.textが同一のものをリスト化
        private var nameList:Dictionary;
        private function addNameList(name:String,tokenID:int):int{
            if(nameList.hasOwnProperty(name)){//
                nameList[name].push(tokenID);
            }
            else{//
                var idList:Array = new Array();
                idList.push(tokenID);
                nameList[name] = idList;
            }
            return nameList[name].length;

        }

        private function onComplete(e:Event):void{//
            tk.removeEventListener(Event.COMPLETE,onComplete);
            t2.text ="";
            nameList = null;
            nameList = new Dictionary();
            var i:int;
            for(i=0; i<tk.listLength; i++){//
                //i=spaceCut(i);
                if(tk.list[i].type=="space")continue;
                if(i==tk.listLength)break;
                t2.appendText(tk.list[i].text +" "+tk.list[i].type+ "\n");
                if(tk.list[i].type == "text"){
                    addNameList(tk.list[i].text,i);
                    //t2.appendText(tk.list[i].text + "\n"+ tk.list[i].tag);

                }
            }
            //t2.text ="";
            for(var str:String in nameList){// 
               // t2.appendText("["+str+"] ");
                //t2.appendText(nameList[str].length.toString());
               // t2.appendText("\n");
            }
            return; 

            for(i=0;i<tk.listLength;i++){
                
  
                //スコープ
                /*if(tk.list[i].type=='}'){
                    
                    //t2.text = tk.func3(tk.list[i].pair);
                    t2.text = tk.getBlockText(tk.list[i].pair);
                    return;
                }*/
                if(tk.list[i].type=="statement"){//
                    
                    t2.appendText(tk.list[i].text+" ");//要素の種類
                    
                    //import
                    if(tk.list[i].text=="import"){
                        i+=2;//スペース
                        while(tk.list[i].type!="space"){
                            t2.appendText(tk.list[i].text);
                            i++;
                        }
                        t2.appendText("\n");
                        continue;
                    }

                    //class
                    if(tk.list[i].text=="class"){
                        i+=2;
                        //識別子
                        if(tk.list[i].type=="string")t2.appendText(tk.list[i].text);
                        i++;
                        i=spaceCut(i);
                        //extends
                        
                        if(tk.list[i].text == "extends"){//
                            t2.appendText(" "+tk.list[i].text+" ");
                            i++;
                            i=spaceCut(i);
                            t2.appendText(tk.list[i].text);
                        }
                        t2.appendText("\n");
                        continue;
                    }

                    //function 
                    if(tk.list[i].text=="function"){
                        i+=2;
                        //識別子
                        if(tk.list[i].type=="string"){//
                            t2.appendText(tk.list[i].text);
                            i++;
                        }
                        // ()
                        i=spaceCut(i);
                        if(tk.list[i].text=="("){
                            t2.appendText("("+tk.getBlockText(i)+"):");
                            
                            i=tk.list[i].pair;
                        }
                        else t2.appendText("():");
                        i++;
                        // :
                        i=spaceCut(i);
                        if(tk.list[i].text == ":"){//
                            i++;
                            i=spaceCut(i);
                            t2.appendText(tk.list[i].text);
                        }
                        else t2.appendText("void");
                        t2.appendText("\n");
                        continue;

                    }
                    
                    //var const     ※Vector未対応
                    if(tk.list[i].text=="var" || tk.list[i].text=="const"){
                        i+=2;
                        while(true){//
                            i=spaceCut(i);
                            //識別子
                            if(tk.list[i].type=="string"){//
                                t2.appendText(tk.list[i].text);
                                i++;
                            }
                            i=spaceCut(i);
                            //型
                            if(tk.list[i].text == ":"){//
                                t2.appendText(" "+tk.list[i].text+" ");
                                i++;
                                i=spaceCut(i);
                                t2.appendText(tk.list[i].text);
                            }
                            i++;
                            i=spaceCut(i);
                            //初期化
                            if(tk.list[i].text == "="){//
                                t2.appendText(" "+tk.list[i].text+" ");
                                i++;
                                while(i < tk.listLength){
                                    if(tk.list[i].text == ",")break;
                                    if(tk.list[i].text == ";")break;
                                    if(tk.list[i].type == "statement")break;
                                    if(tk.list[i].type == "operation")break;
                                    t2.appendText(tk.list[i].text);
                                    i++;
                                    
                                }

                                
                            }
                            else{//初期化なし
                                //i++;
                            }
                            //i++;
                            i=spaceCut(i);
                            //宣言が続くならループ
                            if(tk.list[i].text!=",")break;
                            else{
                                t2.appendText("\n"+"var ");
                                i++;
                            }
                        

                        }
                        t2.appendText("\n");       
                        continue;                 
                    }


                    //識別子
                    if(tk.list[i+2].type=="string")t2.appendText(tk.list[i+2].text+"\n");
                    else t2.appendText("\n");
                    
                }

                //if(tk.list[i].type=="space")continue;
                //t2.appendText(tk.list[i].tag+" "+tk.list[i].text+"\n");
                
         
            }
        }


    }
}


import flash.display.*;
import flash.events.*;
import flash.text.*;
class editorBase extends Sprite{
    private var color1:uint = 0xdddddd;
    private var s1:Sprite = new Sprite();
    private var tytle:TextField = new TextField();
    private var source:TextEditor = new TextEditor();
    private var btn:Sprite = new Sprite();
    private var mode:String = new String();
    public function editorBase(name:String="tytle",t:String=""){
        //mode = "open";
        source.type = "input";
        source.y = 20;
        source.text = t;
        source.width = 400;
        source.height = source.textHeight+20;
        tytle.text = name;
        tytle.doubleClickEnabled = true;
        //tytle.type = "input";
        tytle.selectable = false;
        tytle.height = 20;
        tytle.width = tytle.textWidth+20;
        s1.addChild(tytle);
        addChild(s1);
        func1();
        addEventListener(MouseEvent.MOUSE_DOWN,onDown);
        addEventListener(MouseEvent.DOUBLE_CLICK,onDouble);
        
    }
    private function onDouble(e:MouseEvent):void{
        this.tytle.type = "input";
        this.tytle.selectable = true;
        stage.focus = this.tytle;
        if(mode != "open")func2();
        else func1();
        
        
    }

    private function onDown(e:MouseEvent):void{
        e.currentTarget.startDrag();
        var _parent:DisplayObjectContainer = this.parent;
        this.parent.removeChild(this);
        _parent.addChild(this);
        //this.parent.addChild(this);
        addEventListener(MouseEvent.MOUSE_UP,onUp);
    }
    private function onUp(e:MouseEvent):void{
        e.currentTarget.stopDrag();
        removeEventListener(MouseEvent.MOUSE_UP,onUp);
    }


    //省略モードで表示
    public function func1():void{
        
        if(mode == "open")removeChild(source);
        s1.graphics.clear();
        s1.graphics.beginFill(color1,0.8);
        s1.graphics.drawRoundRect(0,0,tytle.width,tytle.height,15,15);
        s1.graphics.endFill();
        mode = "close";
        
    }
    public function func2():void{
        if(mode != "open")addChild(source);
        s1.graphics.clear();
        s1.graphics.beginFill(color1,0.8);
        s1.graphics.drawRect(0,0,tytle.width,tytle.height);
        s1.graphics.drawRect(0,20,source.width,source.height);
        s1.graphics.endFill();
        mode = "open";
    }



}


import org.libspark.thread.Thread;
import org.libspark.thread.threads.display.LoaderThread;

class MainThread extends Thread {
    private var func:Function;
    //private var 
    public function MainThread(func1:Function=null) {//
        
        func = func1;
    }
    
    //Thread.start()で実行される
    private var cnt:int=0;
    override protected function run():void {
        if(func==null)return;
        next(mainloop);
        
        //next(run);//次に実行するスレッドを指定指定しなければスレッド終了
    }
    
    private function mainloop():void{
        func();
        if(_stop!=true)next(mainloop);//次に実行するスレッドを指定指定しなければスレッド終了
    }
    private var _stop:Boolean=false;
    public function stop():void{
        _stop=true;
    }

    public function setFunction(func1:Function=null):void{
        if(func1==null)return;
        func = func1;
    }


    //スレッド終了時に実行される
    override protected function finalize():void {
    }

}



//////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////
import flash.display.*;
import flash.events.*;
import org.libspark.thread.Thread;
import org.libspark.thread.EnterFrameThreadExecutor;

//テキストからトークンを抽出する
class token extends Sprite{
    public var list:Object;//トークン列
    private var source:String;
    public var listLength:int = 0;
    private var thread:MainThread;
    public function token(){
        list = new Object();
        if (!Thread.isReady) Thread.initialize(new EnterFrameThreadExecutor());//スレッドライブラリ初期化
        
        
    }

    public function getToken2(str:String):void{
        if(str!=source){
            source=str;
            list=null;
            list=new Object;
            listLength = 0;
            index01=0;
            thread = new MainThread(func05);//スレッド作成
            thread.start();
            thread.join();
            this.dispatchEvent(new Event(Event.CHANGE));
        }
        
    }
    
    private function func05():void{//
        this.dispatchEvent(new Event(Event.CHANGE));
        var currentIndex:int=0;
        var cnt:int = 0;
        while(currentIndex<source.length){
            
            currentIndex = func01();
            cnt++;
            if(200<cnt)break;
        }
        currentIndex = func01();
        if(currentIndex==source.length){//
            setBlock();
            setKeywordAS3();
            this.dispatchEvent(new Event(Event.COMPLETE));
            thread.stop();
        }
        
    }
    

    //指定インデクスからmax個までトークン抽出
    //抽出したトークンはlistに追加
    //抽出したところまでのインデクスを返す
    public function getToken(str:String,index:int=0,max:int=1000):int{
        if(str!=source){
            source=str;
            list=null;
            list=new Object;
            listLength = 0;
            index01=0;
        }
        var currentIndex:int = index;
        var cnt:int = 0;
        while(currentIndex<source.length){
            
            currentIndex = func01();
            cnt++;
            if(max<cnt)break;
        }
        return currentIndex;
    }

/*
    public function func4():void{
        // ;
            else if(list[i].type==';'){
                //list[i].step = stepCnt[stepCnt.length-1];
                //list[i].group = stac[stac.length-1];
                //stepCnt[stepCnt.length-1]++;//ステップをカウントアップ
                continue;
            }
// space            
            else if(list[i].type=="space"){
                //list[i].step = stepCnt[stepCnt.length-1];
                //list[i].group = stac[stac.length-1];
                if(list[i].text.search(/[\n\r]/gm)!=-1){
                    list[i].tag += "onReturn\n";//改行が含まれる
                    //lineCnt[stepCnt.length-1]++;
                }
                if(list[i].text.search(/ /gm)!=-1)list[i].tag += "onFullwidthSpace\n";//全角スペースが含まれる
                continue;
            }

// その他
            else{
                //list[i].step = stepCnt[stepCnt.length-1];
                //list[i].group = stac[stac.length-1];
                continue;

            }
    }

*/
    //ActionScript3
    public function setKeywordAS3():void{//
        //宣言系
        const statement:Array = new Array("function", "var", "class", "const", "package","import","namespace");
        //処理系
        const operation:Array = new Array("for","while","if","else","do","switch","each","case","with",
                                        "break","return","continue","default","in","is","as","to",
                                        "try","catch","finally","throw","typeof","super","this","label");
        //データ型                                
        const DataType:Array = new Array("null","void","int","uint",
                                         "Boolean","Number","String","Object","Array",
                                         "Date","RegExp","Error","Function","XML","XMLList");
        //アクセス制御系                                
        const access:Array = new Array("private","protected","internal","public",
                                       "static","internal","dynamic","final","native","override");
        
        getStringToken();
        var i:int;
        //変数、定数、関数、クラス、
        for(i=0;i<statement.length;i++){
            setType(statement[i],"statement");
        }
        //制御
        for(i=0;i<operation.length;i++){
            setType(operation[i],"operation");
        }
        //標準データ型
        for(i=0;i<DataType.length;i++){
            setType(DataType[i],"datatype");
        }
        //アクセス修飾子
        for(i=0;i<access.length;i++){
            setType(access[i],"access");
        }

    }


    //token.type="string"からタイプを書き換える
    private var strToken:Array;
    private function setType(str:String,type:String):void{
        for(var i:int=0;i<strToken.length;i++){
            if(list[strToken[i]].text==str){
                list[strToken[i]].type=type;
            }

        }
        regetStringToken();

    }
    private function regetStringToken(str:String="string"):void{
        var ary:Array=strToken;
        var ary2:Array = new Array();
        for(var i:int=0;i<ary.length;i++){
            if(list[ary[i]].type==str){
                ary2.push(ary[i]);
            }

        }
        strToken = null;
        strToken = ary2;

    }

    //type == string のトークンid列を取得
    private function getStringToken(str:String="string"):void{//
        strToken = new Array();
        for(var i:int=0;i<listLength;i++){
            if(list[i].type==str){
                strToken.push(i);
            }

        }

    }



    //func2から得たArrayで指定
    public function getBlockTokenList(entry:int=-1):Array{
        var i:int;
        var lastToken:int;
        var tokenIdList:Array = new Array();
        if(entry == -1){//トークン全体全体
            lastToken = listLength;
            for(i=0;i<lastToken;i++){
                tokenIdList.push(i);
            }
            return tokenIdList;
        }
        else{
            lastToken = list[entry].pair;
            for(i=entry+1;i<lastToken;i++){
                tokenIdList.push(i);
            }
            return tokenIdList;
        }
    }
    //指定したスコープ内のテキスト取得
    public function getBlockText(entry:int=-1):String{
        var i:int;
        var lastToken:int;
        var str:String = new String();
        if(entry == -1){//トークン全体全体
            lastToken = listLength;
            for(i=0;i<lastToken;i++){
                str += list[i].text;
            }
            return str;
        }
        else{
            lastToken = list[entry].pair;
            for(i=entry+1;i<lastToken;i++){
                str += list[i].text;
            }
            return str;
        }
    }




    //スコープ別にテキストを取り出す
    public function func3(tokenID:int):String{
        var n:int=tokenID;
        var str:String = new String();
        
        if(list[n].type!='{'){
            n=list[n].group;
        }
        for(var i:int = n;i<list[n].pair+1;i++){
            str+=list[i].text;
            if(list[i].type=='{')i=list[i].pair-1;//スコープ内を省略
        }

        return str;
    }

    //トークンにブロックを割り当てる { } ( ) [ ]
    private var scopeEntry:Array;
    public function setBlock():void{
        const err1:String = "scopeError1\n";//スコープの終了がない
        const err2:String = "scopeError2\n";//ペアの種類が異なる
        const err3:String = "scopeError3\n";//スコープの開始がない
        var stac:Array = new Array();
        
        scopeEntry = null;
        scopeEntry = new Array();//スコープの開始位置のトークンID列
        scopeEntry.push(-1);//最上位登録
        
        for(var i:int=0;i<listLength;i++){
            if(list[i].type != "mark")continue;//記号以外はスルー
// { }
            if(list[i].text=='{'){
                stac.push(i);
                continue;
            }
            else if(list[i].text=='}'){
                if(stac.length==0){
                    list[i].tag += err3;//エラー
                    continue;
                }
                if(list[stac[stac.length-1]].text != '{'){
                    list[i].tag += err2;//エラー
                    continue;
                }
                
                //ペア登録
                list[i].pair = stac.pop();
                list[list[i].pair].pair = i;
                scopeEntry.push(list[i].pair);
                list[i].type="block";
                list[list[i].pair].type ="block";
                continue;
            }
// ( )
            else if(list[i].text=='('){
                stac.push(i);
                continue;
            }
            else if(list[i].text==')'){
                if(stac.length==0){
                    list[i].tag += err3;//エラー
                    continue;
                }
                if(list[stac[stac.length-1]].text != '('){
                    list[i].tag += err2;//エラー
                    continue;
                }
                //ペア登録
                list[i].pair = stac.pop();
                list[list[i].pair].pair = i;
                scopeEntry.push(list[i].pair);
                list[i].type="block";
                list[list[i].pair].type ="block";
                continue;
            }
// [ ]
            else if(list[i].text=='['){
                stac.push(i);

                continue;
            }
            else if(list[i].text==']'){
                if(stac.length==0){//スコープ開始位置が存在しない
                    list[i].tag += err3;//エラー
                    continue;
                }
                if(list[stac[stac.length-1]].text != '['){//種類が異なる
                    list[i].tag += err2;//エラー
                    continue;
                }
                //ペア登録
                list[i].pair = stac.pop();
                list[list[i].pair].pair = i;
                scopeEntry.push(list[i].pair);
                list[i].type="block";
                list[list[i].pair].type ="block";
                continue;
            }
                  
        }//for

        if(stac.length!=0){//スコープが閉じられる前に最期まで到達した時
            for(var j:int=0;j<stac.length;j++){
                list[stac[j]].tag += err1;
            }
        }
        return;
    }

//-------------------------------------------------------------
    //開始インデクスを受け取りトークンのタイプを返す
    private var index01:int=0;
    private function func01():int{//
        if(index01>=source.length)return source.length;
        var index:int = index01;
        var token:Object = new Object();
        var reg:RegExp = new RegExp();                
        var result:Object;
        list[listLength] = token;
        listLength++;
        token.tag = "";
        //トークンタイプ:空白か?
        if(    source.charAt(index)== " " ||
               source.charAt(index)=="\t" ||
               source.charAt(index)=="\n" ||
               source.charAt(index)=="\r" ){
                   token.type = "space";
                   reg = /[^\s]/mg;
                   reg.lastIndex = index;
                   result = reg.exec(source);
                   //トークン作成
                   if(result == null){//
                       token.text = source.substring(index,source.length);
                       index01 = source.length;//次の開始位置
                       return index01;
                   }
                   else{//
                       token.text = source.substring(index,result.index);
                       index01 = result.index;
                       return index01;
                   }
                                       
               }

        
        //トークンタイプ:文字列定数1
        if(source.charAt(index)== "'"){
            token.type = "text";
            var indexA:int = index;
            reg = /['\n\r]/mg;//改行か次の[']が現れる位置
            do{//エスケープ処理
                reg.lastIndex = indexA+1;
                result = reg.exec(source);
                if(result==null)break;
                else indexA = result.index;
            }while(source.charAt(indexA-1)=="\\");//["]が現れてもその前がエスケープなら再検索
            
            //トークン作成
            if(result == null){//エラー
                token.text = "'";
                token.type = "other";
                index01 = index+1;//次の開始位置
                return index01;
            }
            else{//
                token.text = source.substring(index,result.index+1);
                index01 = result.index+1;//次の開始位置
                return index01;
            }
                
        }
 
        //トークンタイプ:文字列定数2
        if(source.charAt(index)== '"'){
            token.type = "text";
            var indexB:int = index;
            reg = /["\n\r]/mg;//改行か次の["]が現れる位置
            do{//エスケープ処理
                reg.lastIndex = indexB+1;
                result = reg.exec(source);
                if(result==null)break;
                else indexB = result.index;
            }while(source.charAt(indexB-1)=="\\");//["]が現れてもその前がエスケープなら再検索
            
            //トークン作成
            if(result == null){//エラー
                token.text = '"';
                token.type = "other";
                index01 = index+1;//次の開始位置
                return index01;
            }
            else{//
                token.text = source.substring(index,result.index+1);
                index01 = result.index+1;//次の開始位置
                return index01;
            }
        }
        
        if(source.charAt(index)== "/"){
               //一行コメント
               if(source.charAt(index+1)== "/"){//
                   reg = /[\n\r]/mg;
                   reg.lastIndex = index+2;
                   result = reg.exec(source);
                   //トークン作成
                   token.type = "comment";
                   if(result == null){
                       token.text = source.substring(index,source.length);
                       index01 = source.length;//次の開始位置
                       return index01;
                       
                   }
                   else{// 
                       token.text = source.substring(index,result.index);
                       index01 = result.index;//次の開始位置
                       return index01;
                   }
               }
               //複数行コメント
               if(source.charAt(index+1)== "*"){
                   reg = /\*\//mg;
                   reg.lastIndex = index+2;
                   result = reg.exec(source);
                   
                   //トークン作成
                   token.type = "comment";
                   if(result == null){//エラー
                       token.type = "other";
                       token.text = '/*';
                       index01 = index+2;//次の開始位置
                       return index01;
                   }
                   else{//
                       token.text = source.substring(index,result.index+2);
                       index01 = result.index+2;//次の開始位置
                       return index01;
                   }
               }
        }

        //英数字
        if((source.charCodeAt(index) > 64 && source.charCodeAt(index) < 91) ||// A-Z
           (source.charCodeAt(index) > 96 && source.charCodeAt(index) < 123)||// a-z
            source.charCodeAt(index) == 95 ){// _
                reg = /[^a-zA-Z0-9_]/mg;//英数字以外が現れる位置
                reg.lastIndex = index+1;
                result = reg.exec(source);
                
                token.type = "string";//半角英数字
                if(result == null){//
                    token.text = source.substring(index,source.length);
                    index01 = source.length;//次の開始位置
                    return index01;
                }
                else{//
                    token.text = source.substring(index,result.index);
                    index01 = result.index;//次の開始位置
                    return index01;
                }
                
        }
        
        
        //数値
        if(source.charCodeAt(index) > 47 && source.charCodeAt(index) < 58){
            reg = /[^a-zA-Z0-9_.]/mg;
            reg.lastIndex = index+1;
            result = reg.exec(source);
            
            token.type = "number";//半角英数字
            if(result == null){
                token.text = source.substring(index,source.length);
                index01 = source.length;//次の開始位置
                //return index01;
            }
            else{// 
                token.text = source.substring(index,result.index);
                index01 = result.index;//次の開始位置
                //return index01;
            }
            num();//種類判別
            return index01;

        }
        
        //半角記号
        if(source.charCodeAt(index)<127 && source.charCodeAt(index)>32){
            token.type = "mark";
            token.text = source.charAt(index);
            
            index01 = index+1;
            return index01;
        }
    
        //その他文字列 マルチバイト文字等はここに入る
        token.type = "other";
        reg = /[\x01-\x7f]/mg;
        reg.lastIndex = index+1;
        result = reg.exec(source);
        if(result == null){
            token.text = source.substring(index,source.length);
            index01 = source.length;//次の開始位置
            return index01;
        }
        else{// 
            token.text = source.substring(index,result.index);
            index01 = result.index;//次の開始位置
            return index01;
        }
    }

//数値の処理
//-------------------------------------------------------------------
    private function num():void{
        var token:Object= list[listLength-1];
        var index:int = token.index;
        
        
        //0~9だけなら整数値。小数点が1つだけあるなら実数値。どちらにも該当しなければ数値ではない。
                if(token.text.search(/[^0-9]/mg)== -1){//数字のみ →整数値or8進数
                    if(token.text.charAt(0)=="0" && 1<token.text.length){//0から始まれば8進数かも(ただし0以降に数字があれば)
                        if(token.text.search(/[^0-7]/mg)!= -1){//0から始まったけど8進数ではなかった
                            token.type = "other";
                            token.tag += "oct:1\n";
                        }
                        //8進数確定
                        token.tag += "oct\n";
                        token.value = uint(parseInt(token.text,8));
                    }
                    //整数
                    token.tag += "int\n";
                    token.value = uint(parseInt(token.text));
                }
                else{
                    var a:Array = token.text.match(/[.]/mg);//小数点が1つだけなら実数。それ以外はよくわからない何か。
                    if(a.length == 1){//実数値
                        if(token.text.search(/[^0-9.]/mg) != -1 || //数字と小数点以外の文字が入ってたらNG
                            token.text.search(/[.]/mg) == token.text.length-1){//小数点で終わってたらNG
                            token.type = "other";
                            token.tag += "real:NG1\n";
                        }

                        token.tag += "real\n";
                        token.value = Number(token.text);
                    }
                    else{//整数、実数以外
                        if(token.text.charAt(0)=="0"){//
                            //2進
                            if(token.text.charAt(1)=="b" || token.text.charAt(1)=="B"){
                                a = token.text.match(/[^01]/mg);
                                if(a.length != 1 || token.text.length<3)token.type = "other";
                                else{
                                    token.tag += "bin\n";
                                    var bin:String = token.text.substring(2,token.text.length);
                                    token.value = uint(parseInt(bin,2));
                                }

                            }
                            //16進
                            else if(token.text.charAt(1)=="x" || token.text.charAt(1)=="X"){//
                                a = token.text.match(/[^0-9a-fA-F]/mg);
                                if(a.length != 1 || token.text.length<3)token.type = "other";
                                else{
                                    token.tag += "hex\n";
                                    token.value = uint(parseInt(token.text,16));
                                }
                            }
                            //8進
                            else if(token.text.charAt(1)=="o" || token.text.charAt(1)=="O"){
                                a = token.text.match(/[^0-7]/mg);
                                if(a.length != 1 || token.text.length<3)token.type = "other";
                                else{
                                    token.tag += "oct\n";
                                    var oct:String = token.text.substring(2,token.text.length);
                                    token.value = uint(parseInt(oct,8));
                                }
                            }
                            else{
                                //8進
                                a = token.text.match(/[^0-7]/mg);
                                if(a.length != 0 || token.text.length<2)token.type = "other";
                                else{//
                                    token.tag += "oct\n";
                                    token.value = uint(parseInt(token.text,8));
                                }
                            }                            
                        }
                        else{//
                            token.type = "other";
                        }
                    }
                }
    }//function
//-------------------------------       
}//class


////////////////////////////////////////////////////////////////////////
//  TextEditor class
////////////////////////////////////////////////////////////////////////

/*
    --TextFieldへの追加機能--
        ・改行入力
        ・タブ入力
        ・オートインデント
        ・アンドゥ/リドゥ
        ・エディタの前後関係
*/

    import flash.text.TextField;
    import flash.events.*;
    class TextEditor extends TextField {
        private var prevText:String = "";//text変更前の状態
        private var indentStr:String;
        private var sc:StringComparator = new StringComparator();
        private var historyManager:HistoryManager = new HistoryManager();
        private var comparator:StringComparator = new StringComparator();
        
        public function TextEditor():void {
            this.type = "input";//入力可能
            //this.multiline = true;//マルチライン
            this.addEventListener(KeyboardEvent.KEY_DOWN, onKey); 
            this.addEventListener(FocusEvent.KEY_FOCUS_CHANGE,focusChangeListener);//タブキーによるフォーカス変更をキャンセル
            this.addEventListener(Event.CHANGE,onChange);//textの変更

        }
        
        private var sw:Boolean;
        private function onChange(e:Event):void{  
    
            if(sw==false)addHistory();
            if(sw2==true){
                this.multiline = false;
                sw2=false;
            }

            prevText = this.text;
            sw=false;      
        }
      
        private function focusChangeListener(e:FocusEvent):void{
            e.preventDefault();
        }
        
        //入力履歴更新
        private function addHistory():void{
            comparator.compare(prevText, this.text);   
            var entry:HistoryEntry = new HistoryEntry(comparator.commonPrefixLength);      
                entry.removeText = prevText.substring(comparator.commonPrefixLength, prevText.length - comparator.commonSuffixLength);
                entry.addText = this.text.substring(comparator.commonPrefixLength, this.text.length - comparator.commonSuffixLength);
                historyManager.appendEntry(entry); 
                prevText = this.text;
        }

        
        //キー入力
        private var sw2:Boolean;
        private function onKey(e:KeyboardEvent):void {        
        
        
            //カーソル操作
            if(e.keyCode <=40 && e.keyCode>=37){
                moveCaret(e.keyCode);
            }

            
            // Ctrl+Z : UNDO
            if (e.keyCode == 90 && e.ctrlKey) {
                sw=true;
                undo();
                return;
            }
        
            // Ctrl+Y : REDO
            if (e.keyCode == 89 && e.ctrlKey) {
                sw=true;
                redo();
                return;
            }
            //ペースト
            if(e.keyCode == 86 && e.ctrlKey){
                this.multiline = true;//改行を含むコピーに対応
                sw2=true;
            }

            
            //キャレット位置に改行文字を挿入
            if(e.keyCode == 13 || e.keyCode == 108){
                lineFeed();
                return;
            }
            //tab
            if (e.keyCode == 9) {
                tab();
                return;
            }
        }
        
        
        private function moveCaret(keyCode:int):void{
            if(keyCode == 40 && this.caretIndex == this.length){// ↓
                if(nextTF==null)return;
                stage.focus = nextTF;
                //キャレット位置セット
                nextTF.setSelection(0,0);
            }
            if(keyCode == 39 && this.caretIndex == this.length){// →
                if(nextTF==null)return;
                stage.focus = nextTF;
                nextTF.setSelection(0,0);
            }
            if(keyCode == 38 && this.caretIndex == 0){// ↑
                if(prevTF==null)return;
                stage.focus = prevTF;
                prevTF.setSelection(prevTF.length,prevTF.length);      
            }
            if(keyCode == 37 && this.caretIndex == 0){// ←
                if(prevTF==null)return;
                stage.focus = prevTF;
                prevTF.setSelection(prevTF.length,prevTF.length);
            }
        }
        
        //テキストフィールド間のキャレット移動
        public function setNextTF(TF:TextField):void{
            nextTF=TF;
        }
        public function setPrevTF(TF:TextField):void{
            prevTF=TF;
        }
        private var prevTF:TextField = null;
        private var nextTF:TextField = null;
             


        
        //改行
        
        public function lineFeed():void{
            //sw2=true;
            var str1:String;
            var str2:String;
            var scrV:int = this.scrollV;
            str1 = this.text.substring(0, this.caretIndex);
            str2 = this.text.substring(this.caretIndex, this.length);
            this.text = str1;
            this.appendText("\n");//キャレット位置で改行
                
            //インデント構造(タブ&スペースの構成)を調べる
            var indent:int=0;
            var prevReturn:int = this.text.lastIndexOf('\r', this.caretIndex-1);//前回の改行位置
            //一つ前の改行直後に続くタブコードの数=インデント深度
            for (var j:int = prevReturn+1; j < this.caretIndex; j++) {
                if (this.text.charAt(j) == '\t' || this.text.charAt(j) == ' ' ) indent++;
                else break;
            }
            //上の行のインデントに従う
            var iStr:String = this.text.slice(prevReturn + 1, prevReturn + 1 + indent);
            indentStr = iStr;
            this.appendText(iStr);//インデント
            this.text += str2;//結合 
             
            //キャレット位置をインクリメント
            this.scrollV = scrV;
            this.setSelection(this.caretIndex +indent + 1, this.caretIndex +indent + 1);
            
            this.dispatchEvent(new Event(Event.CHANGE));
            
        }

        //タブ
        public function tab():void{
            var str1:String;
            var str2:String;
            str1 = this.text.substring(0, this.caretIndex);
            str2 = this.text.substring(this.caretIndex, this.length);
            this.text = str1 + '\t' + str2;
            //キャレット位置をインクリメント
            this.setSelection(this.caretIndex + 1, this.caretIndex + 1);        
            this.dispatchEvent(new Event(Event.CHANGE));
        }

        //アンドゥ
        public function undo():void {
            if (historyManager.canBack) {
                var entry:HistoryEntry = historyManager.back();
                //テキストセット
                this.replaceText(entry.index, entry.index + entry.addText.length, entry.removeText);
                //キャレット位置セット
                this.setSelection(entry.index + entry.removeText.length, entry.index + entry.removeText.length);               
            }
            this.dispatchEvent(new Event(Event.CHANGE));           
        }
    
        //リドゥ
        public function redo():void {
            if (historyManager.canForward) {
                var entry:HistoryEntry = historyManager.forward();
                //テキストセット
                this.replaceText(entry.index, entry.index + entry.removeText.length, entry.addText);
                //キャレット位置セット
                this.setSelection(entry.index + entry.addText.length, entry.index + entry.addText.length);            
            }
            this.dispatchEvent(new Event(Event.CHANGE));         
        }
        
    }


import __AS3__.vec.Vector;

class HistoryManager {
    public var currentIndex:int = 0;
    public var length:int=0;
    private var entries:Vector.<HistoryEntry>;
    
    public function HistoryManager() {
        entries = new Vector.<HistoryEntry>();
    }
    //履歴追記
    public function appendEntry(entry:HistoryEntry):void {
        entries.length = currentIndex;
        length = entries.length;
        entries.push(entry);
        currentIndex++;// = entries.length;
    }
    //履歴削除
    public function clear():void {
        currentIndex = 0;
        entries.length = 0;
    }
    //リドゥ可能
    public function get canForward():Boolean {
        return currentIndex < entries.length;
    }
    //アンドゥ可能
    public function get canBack():Boolean {
        return currentIndex > 0;
    }
    //リドゥ
    public function forward():HistoryEntry {
        return entries[currentIndex++];
    }
    //アンドゥ
    public function back():HistoryEntry {
        return entries[--currentIndex];
    }

}


class HistoryEntry {
    public var index:int;
    public var removeText:String;
    public var addText:String;
    
    public function HistoryEntry(index:int=0, remove:String="", add:String="") {
        this.index   = index;//文字列先頭位置
        this.removeText = remove;//消した文字列
        this.addText = add;//追加した文字列
    }
}
    

 // 文字列の左右一致を数える
class StringComparator {
    // 左側の共通文字列長
    public var commonPrefixLength:int;    
    // 右側の共通文字列長
    public var commonSuffixLength:int;
    /**
     * 2つの文字列を比較し、commonPrefixLengthとcommonSuffixLengthをセットする
     * 
     * @param str1 比較する文字列の一方
     * @param str2 比較する文字列の他方
     */
    public function compare(str1:String, str2:String):void {
        var minLength:int = Math.min(str1.length, str2.length);
        var step:int, l:int, r:int;
        
        step = Math.pow(2, Math.floor(Math.log(minLength) / Math.log(2)));
        for (l=0; l<minLength; ) {
            if (str1.substr(0, l + step) != str2.substr(0, l + step)) {
                if (step == 1) { break; }
                step >>= 1;
            } else {
                l += step;
            }
        }
        l = Math.min(l, minLength);
        
        minLength -= l;
        
        step = Math.pow(2, Math.floor(Math.log(minLength) / Math.log(2)));
        for (r=0; r<minLength; ) {
            if (str1.substr(-r - step) != str2.substr(-r - step)) {
                if (step == 1) { break; }
                step >>= 1;
            } else {
                r += step;
            }
        }
        r = Math.min(r, minLength);
        
        commonPrefixLength = l;
        commonSuffixLength = r;
    }    
}  


//スクロールバー
import flash.display.*;
class scroolBar extends Sprite{
    private var s1:Sprite;//スライダー
    private var s2:Sprite;//スクロールバー
    public function scroolBar():void{
        
    }

    
}