本來今天是打算寫點心得就水過去了,但我一個朋友突然提了一個蠻有趣的點子:那就是教大家怎麼製作一個程式語言。
沒錯,在這最後一天,來一個超級衝刺吧!
說是自製程式語言,時間其實也不夠,所以今天我要帶著大家實作的是一個叫做brainfuck的程式語言的直譯器。
我們開發所使用的語言是Kotlin,所以拿出你們的Intellij IDEA吧!
首先是BrainFuck的介紹,BF是一個符合圖靈完備的程式語言,但他只使用8個字母來完成所有的程式。
你可以先想像有一個256格的char陣列a,跟一個叫做p的int,指向第零格。
符號 | 對應的程式碼 |
---|---|
+ | a[p]++ |
- | a[p]— |
[ | 如果a[p]==0就跳到後面的] |
] | 如果a[p]!=0就回到前面的[ |
< | p++ |
> | p-- |
, | 輸入a[p] |
. | 輸出a[p] |
首先我們先做一個Model來完成我們的運算部分。
class Model{
private var array = Array<Char>(256){Char(0)}
private var p = 0
}
首先是屬性的部分,我們的要維護一個array,一個p。
接下來是method的部分,我們簡單一點,寫一個fun run(cmd:String) ,參數就是我們的BF程式碼。
fun run(cmd:String){
var cmd_index = 0
}
然後是遍歷我們的程式碼,並判斷他是什麼指令,我們使用kotlin的when語法。
fun run(cmd:String){
cmd_index = 0
while(cmd_index < cmd.length){
when(cmd[cmd_index]){
',' -> //dosomething
'.' -> //dosomething
'+' -> //dosomething
'-' -> //dosomething
'>' -> //dosomething
'<' -> //dosomething
'[' -> //dosomething
']' -> //dosomething
}
cmd_index++
}
}
其實正常應該是要切成不同的method下去使用啦,不過由於這次的任務太簡單了,所以就算了。
來完成任務吧!
class Model{
private var array = Array<Char>(256){Char(0)}
private var p = 0
fun run(cmd:String){
var cmd_index = 0
while(cmd_index < cmd.length){
when(cmd[cmd_index]){
',' -> readln()
'.' -> print(array[p])
'+' -> array[p]++
'-' -> array[p]--
'>' -> p++
'<' -> p--
'[' -> {
if(array[p]==Char(0)){
while(cmd[cmd_index]!=']'){
cmd_index++
}
}
}
']' -> {
if(array[p]!=Char(0)){
while(cmd[cmd_index]!='['){
cmd_index--
}
}
}
}
cmd_index++
}
}
}
如此簡單,我們的Model就完成了。
接下來就是我們的main函式啦,我們要來實作輸入的部分。
fun main(args: Array<String>) {
val m = Model()
val cmd = readln()
m.run(cmd)
}
完成,最後輸入一段hello world,看看是否可以正常執行吧!
++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>.
輸出結果
Hello World!
總算是結束了這三十天的旅程,我介紹了各種的宗教戰爭,也介紹了很多有趣的東西,不知道各位是否喜歡呢?
今年總算不像去年一樣,超級半途而廢,在最後一天忘記上傳內容。
這次的題目元的真的輕鬆有趣,每一個題目都讓我想到很多事情,一路上資工的各種方向算是都接觸過,所以很多東西感受很深,比如剛開始寫C++的時候我其實是下放的,是後來寫了Java才真的覺得下放很醜然後改成不下放等等。
感謝各位30天的陪伴,明年的題目還沒想好,但應該還是會參賽吧!
所以,各位明年見啦~~
最後一個meme,一起嘲笑去年沒寫完的我吧!