自製Monkey編程語言編譯器:增加數組操作API和Mapsh數據類型
前一節,我們為Monkey語言以及其編譯器增加了內置API len,以及數組數據類型,內置的len函數調用能作用到數組和字元串上,分別返回數組的元素個數和字元串的字元長度。本節我們繼續增加三個能作用到數組上的內置API,這樣Monkey語言能更方便的支持數組操作。
我們在這裡要增加的第一個API叫first。他返回數組首個元素,也就是它的作用與myArray[0]等價,但用first獲得首個元素,可以使得代碼的易讀性更強。我們看看它的實現,在MonkeyEvaluator.js中,增加如下代碼:
在builtins函數中,我們增加了對被調函數名字的檢測,當調用函數名為"first"時,我們知道代碼執行的是內嵌API。在函數執行時,它先檢測輸入參數的類型是否是數組,是的話,確保數組元素不為空,然後返回數組中的第一個元素。上面代碼完成後,在頁面的編輯框輸入下面代碼:
點擊"parsing"按鈕進行解釋執行後,得到結果如下:
我們的編譯器成功解析數組後,在執行first調用時,成功將數組第一個元素返回。
我們繼續接著實現的第二個API叫rest,它的輸入參數是數組,然後返回一個除了第一個元素外的新數組,它的實現如下:
上面代碼執行後,在編輯框中輸入如下代碼:
點擊按鈕"parsing"進行解釋執行後,得到結果如下:
從返回結果看,函數將輸入數組的第一個元素去除後,返回了一個新數組。最後一個有關數組操作的API叫push,它的作用是將一個新元素添加到給定數組的末尾,但它並不改變就數組,而是構造一個新數組,新數組包含舊數組的所有元素,同時在末尾添加了新的元素,它的實現如下:
完成上面代碼後,在編輯框中輸入如下代碼:
然後點擊"parsing"後,編譯器對上面代碼的執行結果如下:
接下來,我們為Monkey語言增添一種最為常用的數據結構,那就是map,它能夠把key和value一一對應起來,該數據結構是除了數組外,編程中最為常用的數據結構。我們希望編譯器能支持下面的代碼:
編譯器在讀取"myHash["age"]"時會找到它對應的數值72。任何數據類型都可以做map的key和value。為了能夠執行map有關的代碼,我們需要先讓詞法分析器識別有關字元,在MonkeyLexer.js中添加如下代碼:
有了上面代碼後,編譯器就可以識別與map有關的字元,例如"{","}"和":"。接下來我們增加對map代碼的語法解析。map的語法結構可以用下面的格式來抽象表達:
也就是map必須以一個左括弧開始,中間是表達式加一個冒號然後跟著另一個表達式,這種格式直到以右括弧終止。我們先為哈希表定義一個語法節點,在MonkeyCompilerPaser.js中添加如下代碼:
上面語法節點的定義邏輯,會體現在接下來實現的語法解析過程中。語法解析器的職責就是,當讀取到代碼字元串"{"one":1, "two":2}"後,將其解析並生成上面定義的語法節點對象。在實現解析邏輯時,我們一定要注意對空哈希表"{}"的處理,這些邊緣情況是最讓人掉頭髮的地方所在。
我們在前序解析表中定義一個解析函數,當解析器讀取到左括弧時,它就從解析表中取出解析函數解讀後面的字元,代碼實現如下:
完成上面代碼後,在編輯框中輸入如下代碼:
然後點擊parsing按鈕開始語法解析,執行結果如下:
從上圖可以看出,我們的編譯器能夠正確解析map的語法代碼。至於有關map對象代碼的執行,我們將在下一節去實現。
※使用物理引擎Box2D設計類憤怒小鳥的擊球遊戲-基本架構設置
TAG:Coding迪斯尼 |