顯示具有 HTML5 標籤的文章。 顯示所有文章
顯示具有 HTML5 標籤的文章。 顯示所有文章

2012年10月11日 星期四

JForthBlocks--使用[IF]...[ELSE]...[THEN]積木

使用[IF]...[ELSE]...[THEN]積木可以讓Forther選擇控制哪些程式碼段落需要編譯與解譯,哪些段落則不需要

在開發Library時,因為各個Forth系統不一定實作Library所用到的符式詞(Forth word),需要用到[IF]...[ELSE]...[THEN]積木適時補上缺漏

以下範例說明,如何選擇哪些段落需要執行,可到JForthBlocks線上試玩版 jforthblocks.appspot.com試玩看看

寄件者 scratchlab02
寄件者 scratchlab02

2012年9月26日 星期三

JForthBlocks--Import New Blocks(.FS檔自動轉成新積木)

萬歲!!!JForthBlocks終於可以將.FS檔(Forth Library File)自動轉成新積木了

幫JForthBlocks做新積木是件繁瑣又累人的差事,Jimmy's papa已經將這部份自動化,讓使用者自行載入自己定義的Forth Library檔案,便可自動產生新積木,不用再做苦工了,不知道其他的程式語言的函式庫轉積木的難度如何,改天Jimmy's papa試著轉轉看

打從第一次接觸MIT Scratch,Jimmy's papa就夢想有朝一日能在Scratch-like tool上有豐富的函式庫支援,JForthBlocks能成功邁向這個目標一小步,真的很感謝Blockly與JeForth等專案相關開發者的貢獻哩!!!

打開文字編輯器先定義如下的My Library.fs,並存檔
: 3dup dup dup dup ;
: 4dup dup dup dup dup ;
: 5dup dup dup dup dup dup ;

請按Import Library
寄件者 scratchlab02
寄件者 scratchlab02
寄件者 scratchlab02
寄件者 scratchlab02

2012年9月19日 星期三

JForthBlocks--測試有無DoLit的效能

在Forth裡DoLit指令是用來取字面值(literal)的巧妙機制,當定義高階詞時,如有字面值(literal)編入詞典時,會同時夾帶DoLit編入字面值(literal)的前一個位址,如此一來,當Forth執行到DoLit指令時,便會自動取下一個位址的字面值(literal),這技巧在以低階語言開發的Forth系統上很有效率

不過,JForthBlocks所依賴的以Javascript開發的JeForth,DoLit是否還保有同樣的優勢?

Jimmy's papa動手修改JeForth部份程式碼,再用JForthBlocks同一份積木程式,測試看看有無DoLit的效能,是否有很大的差異,底下是跑五百萬次迴圈的輸出結果,第一次跑出的結果,有無DoLit指令似乎只有幾百微秒(milliseconds)的差異,隨後兩次的結果,執行時間會爆增,或許是垃圾收集機制的干擾

首先,測試compilecode('doLit',n)的效能
        function call(xt){// high level definition inner execution loop
            highLevelLooping=true; ip=xt;
            do{
                var id=dictionary[ip++];
                //if(typeof(id)=='object'){var v=id['lit'];stack.push(v);continue;}
                ........
                ........            
            }
        }

        function exec(src){ //source code interpreting loop
            .....
            .....
            do{token=nexttoken(); word=token;
                var id=findword(token);
                ......
                ......    
                       if(typeof(n)==='string'||n<=0||n>0){
                        if(compiling)
                            compilecode('doLit',n);// compile an literal
                            //compilecode({lit : n});
                ......
                ......
            }while(error===0&&ntib<tib.length);}

          }
寄件者 scratchlab02
連續執行三次的結果




再來,測試compilecode({lit : n})的效能,執行時則統一由call(xt)代勞取字面值(literal)
        function call(xt){// high level definition inner execution loop
            highLevelLooping=true; ip=xt;
            do{
                var id=dictionary[ip++];
                if(typeof(id)=='object'){var v=id['lit'];stack.push(v);continue;}
                ........
                ........            
            }
        }

        function exec(src){ //source code interpreting loop
            .....
            .....
            do{token=nexttoken(); word=token;
                var id=findword(token);
                ......
                ......    
                       if(typeof(n)==='string'||n<=0||n>0){
                        if(compiling)
                            //compilecode('doLit',n);// compile an literal
                            compilecode({lit : n});
                ......
                ......
            }while(error===0&&ntib<tib.length);}

          }
寄件者 scratchlab02
連續執行三次的結果,看來三戰兩勝,以微幅差距領先



底下是積木的XML,可以貼到JForthBlocks的XML編輯區,便會將這次測試所用到的積木載入
<xml xmlns="http://www.w3.org/1999/xhtml">
  <block type="procedures_defnoreturn" notchtype="Top_Bottom_Right" inline="false" x="137" y="55">
    <title name="NAME">TestLiteral</title>
    <statement name="STACK">
      <block type="math_PushNumber" notchtype="TOP_BOTTOM">
        <title name="NUM">5000000</title>
        <next>
          <block type="control_ForNext" notchtype="Top_Bottom_Right" inline="false">
            <statement name="STACK">
              <block type="math_PushNumber" notchtype="TOP_BOTTOM_RIGHT" inline="false">
                <title name="NUM">0</title>
                <value name="NEXTWORD">
                  <block type="math_PushNumber" notchtype="LEFT_RIGHT" inline="false">
                    <title name="NUM">0</title>
                    <value name="NEXTWORD">
                      <block type="stack_2drop" notchtype="LEFT_RIGHT" inline="false"></block>
                    </value>
                  </block>
                </value>
                <next>
                  <block type="math_PushNumber" notchtype="TOP_BOTTOM_RIGHT" inline="false">
                    <title name="NUM">0</title>
                    <value name="NEXTWORD">
                      <block type="math_PushNumber" notchtype="LEFT_RIGHT" inline="false">
                        <title name="NUM">0</title>
                        <value name="NEXTWORD">
                          <block type="stack_2drop" notchtype="LEFT_RIGHT" inline="false"></block>
                        </value>
                      </block>
                    </value>
                  </block>
                </next>
              </block>
            </statement>
          </block>
        </next>
      </block>
    </statement>
  </block>
  <block type="utility_milliseconds" notchtype="LEFT_RIGHT" inline="false" x="89" y="289">
    <value name="NEXTWORD">
      <block type="procedures_callnoreturn" notchtype="LEFT_RIGHT" inline="false">
        <mutation name="TestLiteral"></mutation>
        <value name="NEXTWORD">
          <block type="utility_milliseconds" notchtype="LEFT_RIGHT" inline="false">
            <value name="NEXTWORD">
              <block type="stack_swap" notchtype="LEFT_RIGHT" inline="false">
                <value name="NEXTWORD">
                  <block type="math_Minus" notchtype="LEFT_RIGHT" inline="false">
                    <value name="NEXTWORD">
                      <block type="print_DotS" notchtype="LEFT_RIGHT" inline="false"></block>
                    </value>
                  </block>
                </value>
              </block>
            </value>
          </block>
        </value>
      </block>
    </value>
  </block>
</xml>

2012年9月11日 星期二

JForthBlocks--Linked List

目前JForthBlocks沒有高階的資料結構可用,或許過陣子引用其他現成的積木庫試試看效果如何,不過Jimmy's papa自己動手寫個簡單的連接串列,嗯!還蠻簡單的哩!!!

底下是配置ABCD四個記憶區塊,每個區塊都可儲存下一個連接地址與區塊紀錄的字串內容,ABCD區塊分別對應大野狼,大豬,二豬與豬小弟

不過區塊一多的話,就不能用這個法子,因為要幫每個區塊取名很麻煩!!!
寄件者 scratchlab02

2012年8月25日 星期六

JForthBlocks-以美味蟹堡當範例,八歲的Jimmy學如何使用堆疊指令

Jimmy's papa為了方便Jimmy小朋友能很快的進入狀況,以他喜歡看的卡通海綿寶寶當範例,先造好一些美味蟹堡製作手藝的中文程式積木,這樣一來他就可以專注在堆疊的操作學習上

在Jimmy小朋友邊try邊與我討論時,我也在觀察中文程式積木的命名,是否能讓小朋友快速理解單個積木的功能,再由多次嘗試錯誤的組裝過程,進一步對程式運作的原理心領神會

這段是Jimmy小朋友親自操作解說的


這整段是合集

2012年8月9日 星期四

JForthBlocks--Define Chinese High Word以中文定義新積木

之前JForthBlocks以中文定義新積木是無法執行,原因是引用中文積木時產生的Javascript code會有亂碼,Jimmy's papa已修正這個bug

寄件者 scratchlab02

2012年8月5日 星期日

JForthBlocks--POSTPONE與WORD的練習

這是Jimmy's papa試著解決網友提出的問題,順便當作自己的練習,也幫JForthBlocks補上了BL及WORD幾個積木

POSTPONE--可延遲立即詞(immediate words)在編譯狀態不會立即執行
WORD--依置於堆疊頂端的限定字元,解析WORD後面的字串,然後將解析好的字串置入堆疊
寄件者 scratchlab02
寄件者 scratchlab02
由於Mary尚未定義,所以不能編譯
寄件者 scratchlab02
在解譯狀態下,Mary可作為Greeting解析的對象
寄件者 scratchlab02

2012年6月11日 星期一

Google-Blockly : "Scratch-like"家族又有生力軍加入

Google-Blockly是一套新釋出的"Scratch-like"視覺化程式語言,如同Jimmy's papa之前研究過的WaterBear工具,Blockly也是以HTML5,CSS3和Javascript打造而成的,視覺化可拖拉拼貼式程式積木系統,不過比起已經好幾個月沒改版的WaterBear,新釋出的Blockly似乎提供程式積木更多的操作特色,這有待Jimmy's papa研究看看,如果順利的話,也許不久後JForthBlocks就會移植到Blockly

Google-Blockly Project

底下是Blockly提供的走迷宮(Maze)範例,右邊是小Jimmy試玩的解法,沒用上Logic積木
寄件者 scratchlab02

2012年5月31日 星期四

JForthBlocks--用see積木幫有Create...Does>積木照張X光,果然有物件繼承的fu喔~~

Jimmy's papa查閱許多文件也看了JeForth的JS原始碼,一直搞不懂create...does>積木的運作原理,但為了搞懂如何做出Object-Oriented Forth,只好動用了Forth的X光機--see積木

底下的實驗Jimmy's papa做了個const高階積木,接著將0指定給a積木,1000指定給b積木,雖然目前用see積木還看不大清楚所有積木內部構造,但依實驗結果大約可知,const積木裡面的does>編譯後竟然變成does r>

而更有趣的是,a積木(ip位址在132)與b積木(ip位址在136)執行到最後,都會往前跳到ip位址127,也就是共用在does後面的r> @ >r r> exit,神奇吧!!!
寄件者 scratchlab02
寄件者 scratchlab02
寄件者 scratchlab02
這是產生出來的Forth原始碼,有空再附上註解
: const create , 0 , does> @ >r r> ; 0 const a 1000 const b see const see a see b create cc 11 , 22 , see cc ' const ' a ' b ' cc a b .s

2012年5月23日 星期三

JForthBlocks--execute指令

Jimmy's papa今天測試execute指令,
先以 '積木測測看能否取得 *積木的序號id
寄件者 scratchlab02
取得*積木的序號id是6
寄件者 scratchlab02
接著將7與5推入堆疊,然後將序號id 6 挪到堆疊頂端,讓execute積木執行
寄件者 scratchlab02
最後執行結果是35,等同於執行 7 5 *
寄件者 scratchlab02
這是產生出來的Forth原始碼
' * .s 7 5 rot execute .

2012年5月18日 星期五

JForthBlocks--控制結構begin..until

Jimmy's papa接下來要學習如何使用Forth的begin..until控制結構積木,只能在定義(編譯)高階積木時使用,且begin積木until積木必須成對使用

積木用法 begin [code] ( flag ) until

Jimmy's papa照舊先拉一拉積木作個實驗,讓程式由10遞減到0,並逐一推入堆疊,最後以.s積木列印在螢幕
寄件者 scratchlab02
寄件者 scratchlab02
這是產生出來的Forth原始碼
: test begin dup 1- dup 0 = until ; 10 test .s

2012年5月16日 星期三

JForthBlocks--控制結構do..loop

Jimmy's papa接下來要學習如何使用Forth的do..loop控制結構(Control Structure)積木,這類積木只能在定義(編譯)高階積木時使用,不能用在解譯時期,且do積木loop積木必須成對使用,do..loop積木之間可巢狀內含其他的do..loop積木,不過最多三層,因為Forth僅提供i j k三個迴圈計數索引(loop index)

為什麼只提供三個呢?或許長久以來Forth擅長用來開發短小精悍的應用,所以有人認為三個就夠用了,不過Jimmy's papa認為只提供這三個迴圈計數索引,可能是因為寄存在返回堆疊(Return Stack)的關係,某些書上還建議,操作堆疊的深度盡量避免超過三個

控制結構do..loop,可用的積木有..

do積木,從資料堆疊取上限值(limit)及起始值(startindex),至少會執行一次迴圈
?do積木,若上限值(limit)等於起始值(startindex),則不會執行迴圈
i積木,會將目前迴圈計數索引值從返回堆疊(Return Stack)複製到資料堆疊(Data Stack)
loop積木, 將迴圈計數索引值遞增1
+loop積木,從資料堆疊取遞增值,加總到迴圈計數索引值

Jimmy's papa先拉一拉積木作個實驗,讓程式從0開始跑10次迴圈,並將每次的索引值(loop index)推入資料堆疊,最後以.s積木列印在螢幕
寄件者 scratchlab02
執行結果會印出堆疊所有數值 0 1 2 3 4 5 6 7 8 9
寄件者 scratchlab02
這是產生出來的Forth原始碼
: test 10 0 do i loop ; test .s


接著測試?do積木,上限值(limit)及起始值(startindex)皆為0
寄件者 scratchlab02
執行結果,堆疊是空的(empty)
寄件者 scratchlab02
這是產生出來的Forth原始碼
: test 0 0 ?do i loop ; test .s


最後測試一下+loop積木,每次迴圈索引值(loop index)遞增3
寄件者 scratchlab02
執行結果
寄件者 scratchlab02
這是產生出來的Forth原始碼
: test 99 0 do i 3 +loop ; test .s

2012年5月15日 星期二

JForthBlocks--控制結構IF..ELSE..THEN

Jimmy's papa今天學習如何使用Forth的if..then控制結構(Control Structure)積木,這類積木只能在定義(編譯)高階積木時使用,不能用在解譯時期,且if積木與then積木必須成對使用,if..then積木之間可巢狀內含其他的if..then積木

由於Forth後置語法的關係,邏輯條件運算必需先於if積木完成,if積木會取堆疊頂端值(Top of Stack),若數值不為0,則為真(True),若數值等於0,則為假(False)
下面是Jimmy's papa拉一拉積木,所做的範例
寄件者 scratchlab02
寄件者 scratchlab02
這是產生出來的Forth原始碼
: test if s" TOS is non-zero" then ; 1 test .s
寄件者 scratchlab02
寄件者 scratchlab02
這是產生出來的Forth原始碼
: test if s" TOS is non-zero" then ; 0 test .s
寄件者 scratchlab02
寄件者 scratchlab02
這是產生出來的Forth原始碼
: test if s" TOS is non-zero." else s" TOS is zero." then ; 1 test 0 test .s
執行exit積木,Forth將從目前的高階積木離開,此動作會清掉返回堆疊(Return Stack)頂端, 所以若高階積木有用到>r積木將資料暫存於返回堆疊(Return Stack),則需在執行exit積木之前, 先執行r>積木將暫存資料從返回堆疊(Return Stack)移回資料堆疊(Data Stack)
寄件者 scratchlab02
寄件者 scratchlab02
這是產生出來的Forth原始碼
: test dup 1 = if drop s" one" exit then 2 = if s" two" exit then ; 2 test .s

2012年5月9日 星期三

JForthBlocks--套用Rapheal.js的click事件處理與旋轉圖形Demo

Jimmy's papa這幾天學習如何以JForthBlocks,重寫Rapheal.jsclick事件處理與旋轉圖形Demo,拉拉積木其實不難,但是難在怎麼安排堆疊,讓積木可以適時地吃到它要的參數,完成這個Demo也幫JForthBlocks多了好幾塊有用的積木

以下是JForthBlocks產生的Forth程式碼
準備畫紙 dup dup s" 魒" swap s" https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhVYD_pvecdEHosP10xCBcjK4N1RtCEfVB-BAACzD-ncI6VBDTPkz32Z3gF05Gz5LvgS9PcOAfMyfIxR4FsV0sKEgbrktTLUSBKjLzBgdqdkACqH-ClBp3njpahDhUa-C2rYpz7s937zOoI/s435/Screenshot-10.png" 160 120 320 240 貼圖 swap s" 魒" swap 320 240 200 畫圓 s" a={fill: '#000', 'fill-opacity': .5, 'stroke-width': 5}" javaScript 設圖形屬性 swap over over dup 產生群組 s" 魒" swap rot dup dup s" 魒" swap 24.833 26.917 26.667 畫圓 dup s" a={stroke: '#ccc', fill: '#fff', 'fill-opacity': .4, 'stroke-width': 2}" javaScript 設圖形屬性 rot rot s" 魒" swap s" M12.582,9.551C3.251,16.237,0.921,29.021,7.08,38.564l-2.36,1.689l4.893,2.262l4.893,2.262l-0.568-5.36l-0.567-5.359l-2.365,1.694c-4.657-7.375-2.83-17.185,4.352-22.33c7.451-5.338,17.817-3.625,23.156,3.824c5.337,7.449,3.625,17.813-3.821,23.152l2.857,3.988c9.617-6.893,11.827-20.277,4.935-29.896C35.591,4.87,22.204,2.658,12.582,9.551z" 畫線 dup s" a={stroke: 'none', fill: '#000'}" javaScript 設圖形屬性 swap s" 魒" swap 24.833 26.917 26.667 畫圓 dup s" a={fill: '#fff', opacity: 0}" javaScript 設圖形屬性 同一群組 20 150 平移 1 jsArrayItem value butt1[2] over value img 30 value angle : 旋轉 s" 魒" img s" 魒" s" transform" angle -30 + to angle angle s" r" swap strconcat s" ,320,240" strconcat jsNewObj 1000 s" <>" 動作特效 drop selfid ; 旋轉 butt1[2] swap setEventHandler click 往最前移 .s
這是Jimmy's papa第一次拉了那麼多積木,完成後頭昏腦脹,不知道是否動用到平常不用的95%腦細胞的關係,呵呵!!!
寄件者 scratchlab02
寄件者 scratchlab02
按按箭頭,便能轉轉圖
寄件者 scratchlab02