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月25日 星期五

JForthBlocks--向量表(VectorTable)

Jimmy's papa今天的學習內容,是如何製作向量表,這在寫C程式是很常見的技巧,大概就是將函式指標存在陣列供大同卻有小異的狀況下使用, 相關積木可參考 JForthBlocks--execute指令, JForthBlocks--variable & create積木的用法

Jimmy's papa簡單的拉拉積木,做了3個高階積木Binary, Decimal, Hexadecimal來將數字以不同進制印出,接著建立名為VectorTable的記憶體區塊, 並將上述3個高階積木的序號id存入
寄件者 scratchlab02
結果將數字16顯示為10000(二進制) 16(十進制) 10(十六進制)
寄件者 scratchlab02
這是產生出來的Forth原始碼,並附上註解
: Decimal 10 base! . ; \ 十進制
: Binary 2 base! . ; \ 二進制
: Hexadecimal 16 base! . ; \ 十六進制
\ 建立向量表儲存三個高階詞序號id
create VectorTable ' Binary , ' Decimal , ' Hexadecimal ,
16 dup dup \ 16複製3份
VectorTable @ execute \ 執行向量表第一個指令也就是Binary
VectorTable 1 + @ execute \ 執行向量表第二個指令也就是Decimal
VectorTable 2 + @ execute \ 執行向量表第三個指令也就是Hexadecimal

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日 星期五

2075年,量子符思系統成功地植入阿賴耶識中

Jimmy's papa從小就對科幻很著迷,今天來寫個科幻神怪橋段...

話說公元2075年,地球的量子計算科學家,將量子符思(Quantum Forth)系統成功地植入阿賴耶識(Eight Consciousnesses)中, 開展了劃時代的符籙科技文明,藉由欲界人眾五蘊DNA互動介面,於雲水木石書寫九疊或雲篆字符, 便能騰雲駕霧,移物易形,降雷施雨,地球聯合政府為了普渡眾生加速文明開展 ,亟需招募大批Forther編譯高階符思字符...

寫得不好,請見諒

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

2012年5月7日 星期一

JForthBlocks--轉物件內容為字串

Jimmy's papa今天測試如何在JForthBlocks,將Javascript物件內容轉為字串

讓我們看看JeForth關於obj2str的原始碼
,{name:'obj2str',xt:function(){// string ( obj -- str ) obj 變成字串 str 
    stack[stack.length-1]=JSON.stringify(stack[stack.length-1]);}}
寄件者 scratchlab02
接著Jimmy's papa用JForthBlocks開始組積木,先偷個懶以Javascript語法產生物件,然後再幫它增加屬性speed,一切只要拉拉積木就好(這是Jimmy's papa的自言自語,拉拉積木之前還要知道很多"眉角"才行)
寄件者 scratchlab02
按Run,便能以JSON格式顯示物件內容字串
寄件者 scratchlab02

2012年5月4日 星期五

JForthBlocks- 操作回返堆疊 >r , r> 與r@積木的用法

Jimmy's papa今天學習如何使用>r,r> 與r@三塊積木,操作回返堆疊

回返堆疊(return stack),簡而言之,當Forth執行某個高階積木A時,中途需分心執行另一高階積木B,此時Forth會將此高階積木A目前執行的位置,擱置(暫存)於回返堆疊(return stack),等待高階積木B執行完畢之後再行取回,繼續執行此高階積木A尚未完成的工作

Forth程式設計師為了簡化資料堆疊(data stack)的操作,有時會在不影響回返堆疊(return stack)正常運作的情況下,暫時將資料移至回返堆疊(return stack),然後盡快將回返堆疊(return stack)的資料移回資料堆疊(data stack)

以下是操作回返堆疊相關積木說明
>r ( n -- ) \ 取出資料堆疊(data stack)頂端之數,將它移到回返堆疊(return stack)的頂端
r> ( -- n ) \ 取出回返堆疊(return stack)頂端之數,將它放回資料堆疊(data stack)的頂端
r@ ( -- n ) \ 複製回返堆疊(return stack)頂端之數,放到資料堆疊(data stack)的頂端

需注意
1. 在編譯模式下才能使用
2. >r 與 r>必須要成對的使用

JForthBlocks的Stack目錄可找到>r,r> 與r@三塊積木
寄件者 scratchlab02


在資料堆疊(data stack)先推入數值1,2,3
然後將3移到回返堆疊(return stack)的頂端
寄件者 scratchlab02
哇咧!執行結果告知 >r 只能在編譯模式下才能使用
寄件者 scratchlab02


於是Jimmy's papa,在Compile目錄找到這兩個積木
寄件者 scratchlab02


重新組裝後執行
寄件者 scratchlab02


執行結果告知有error,回返堆疊(return stack)是有借有還再借不難,可不是雜物堆哩!!!
寄件者 scratchlab02


再用 r> 試試看從回返堆疊(return stack)取值
寄件者 scratchlab02


順便加個 .s 積木,了解一下資料堆疊(data stack)狀況
寄件者 scratchlab02


結果資料堆疊(data stack)頂端多了個不明資料
寄件者 scratchlab02


將 >r 與 r>成對擺放試試看
寄件者 scratchlab02


嘿嘿,做虛工,資料堆疊(data stack)狀況不變
寄件者 scratchlab02


夾帶一個 r@ 積木看看
寄件者 scratchlab02


嘿嘿,資料堆疊(data stack)頂上多個3
寄件者 scratchlab02


試試看倒轉資料堆疊(data stack)數值1,2,3的順序
寄件者 scratchlab02


OK!成功
寄件者 scratchlab02

2012年5月3日 星期四

JForthBlocks--variable & create積木的用法

Jimmy's papa今天學習如何使用variable與create兩塊積木

使用Forth時若缺乏安全感,不想將數值推入時時刻刻變化的堆疊中,一不小心被不相干的積木吃掉,可以運用variable或create積木在Forth字典裡建立存放位址,再以!積木存值或@積木取值,有點類似C語言的指標觀念

以下是JForthBlocks自動產生的Forth程式碼範例,會建立變數並指定數值789然後推入堆疊,接著建立記憶體區塊並指定數值陣列再取得索引5的數值然後推入堆疊
variable 變數位址名稱 789 變數位址名稱 ! 變數位址名稱 @ create 記憶體區塊名稱 0 , 1 , 2 , 3 , 4 , 55 , 66 , 5 記憶體區塊名稱 + @ .s
寄件者 scratchlab02
Forth log顯示堆疊現況 789 55
寄件者 scratchlab02