零.一版僅做了十分簡單的語義分析,即檢查符號使用之前是否有宣告。
零.二版的情況沒這麼簡單了。
首先,「若」語句以及「術」宣告語句中的基括號【】
將法咒切割成一個個區塊,深層的區塊能擷取外部區塊所宣告的變數,反之則不然。
若(甲)【
元.鼠=1
若(乙)【
元.牛=1
// 可以截取「鼠」
】
若(丙)【
元.虎=1
// 可以截取「鼠」
】
// 不能截取「牛」、「虎」
】
一個變數所能被擷取的範圍,被稱之為作用域,零.一版中,作用域是線性的,而零.二版有了區塊之後,作用域變為樹狀(或說巢狀的)。
零.一版中,由於作用域是線性的,變數一旦宣告,後續就一直可用,採用一個雜湊表來記錄目前作用域便已足夠。而在巢狀結構中,進入一個區塊時,會有某些變數被宣告,需將其移入雜湊表,二離開區塊時,又有某些變數的生命期耗盡,需要移出雜湊表。
仔細維護雜湊表確實是一種方法,但更簡單的寫法是採用持久化資料結構,每進一個區塊就用一個新的持久化雜湊表來儲存變數,離開了區塊就直接丟掉,如此實作最為簡單。性能方面,這些持久化資料結構的時空間複雜度也都很優秀,不會是編譯的瓶頸。
雖然零.二版限制每個變數只能是整數,但別忘了現在有了「術」,識別子可能是變數,也可能是術,其形態終究是不一樣的。例如:
元.甲=1
甲(2、3)
在施術時,應檢查欲施之術名是否確實為術,若是,還要進一步檢查它的形參與實參數長度是否相當。
類型檢查的實作可以參考音界咒源碼。