iT邦幫忙

2023 iThome 鐵人賽

DAY 30
0
Software Development

寫程式的那些宗教戰爭系列 第 30

Day30 最後的一天,我們來自製一個程式語言吧!~~The END~~

  • 分享至 

  • xImage
  •  

本來今天是打算寫點心得就水過去了,但我一個朋友突然提了一個蠻有趣的點子:那就是教大家怎麼製作一個程式語言。

沒錯,在這最後一天,來一個超級衝刺吧!

說是自製程式語言,時間其實也不夠,所以今天我要帶著大家實作的是一個叫做brainfuck的程式語言的直譯器。

我們開發所使用的語言是Kotlin,所以拿出你們的Intellij IDEA吧!

BrainFuck

首先是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

最後一個meme,一起嘲笑去年沒寫完的我吧!
https://ithelp.ithome.com.tw/upload/images/20231014/201335743pcOL7wHkd.png


上一篇
Day29 JavaScript大法好
系列文
寫程式的那些宗教戰爭30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言