我正在寫一個js-to-js解釋器(也就是說,一個JavaScript程序需要一個Javascript程序作爲參數並執行它)。我沒有受過編譯理論的訓練,我只是在僞造它。表達式評估機器正在工作(使用一種笨重的算子優先算法),但尚未用於函數。所以這是我的問題。JavaScript解釋器實現(功能)策略 - 我有道理嗎?
我想要實現函數的方式看起來像這樣:當函數被調用時,我將爲它創建一個名稱空間/上下文,並允許訪問函數名稱空間和全局名稱空間。
我還沒有實現閉包,但是這些命名空間是爲它們設計的。基本上,據我所知,閉包只是Javascript拒絕忘記函數的上下文,因爲它沒有忘記持有該函數的變量。
所以,當函數被調用時,我會傳入它的上下文對象一個調用它的語句的副本,以及一個指向觸發函數調用的表達式的指針。該語句中已經評估過的每個表達式都會記住它的值。當我們從函數返回時,該語句成爲當前語句,然後我開始再次執行它 - 但我不重新評估已經評估過的表達式,包括剛剛完成的函數。因此,我隨着聲明的其餘部分愉快地前進,潛在地調用更多函數等。
每個語句,表達式和函數都有一個在解析過程中構建的抽象表示。在執行過程中,只有當前語句有任何實際存在的,除了從抽象表示,因爲真的所有我需要在任何給定時間要記住的是:
- 變量在目前情況下在封閉環境中
- 變量(也就是說,最近的一個函數的調用 - 包括全球範圍內 - 包圍當前功能)
- 當前語句
- 什麼語句是未來
- 我的裏面有什麼塊(只是讓我知道當我點擊時該怎麼做之一)
- 調用堆棧,它是一堆包含變量的上下文和觸發調用的語句及其表達式。
- 一個指向要從函數/上下文返回值更新的特定表達式的指針。
那麼我有道理嗎?謝謝你的幫助!
爲什麼你這樣做,而不是簡單地使用eval()? –
因爲我想實現一個用戶友好的調試器。我沒有解釋整個項目,但我需要對接口進行非常精細的控制,如果我有eval()爲我完成所有繁重工作,我將不會得到它。感謝你的協助。 – NessBird