2017-01-23 17 views
0

我正在爲quazi JavaScript語言編寫一個簡單的解釋器。在JavaScript中,變量的類型由它的值定義。我試圖谷歌一些簡單的解決方案的源代碼或一些解釋如何做這種事情。我不知道在哪裏尋求幫助,這就是爲什麼我問你們一些文章或Git的項目。謝謝!!!解釋器 - 變量的值定義了類型

+0

什麼語言你寫你的解釋? – uliwitness

回答

1

在JavaScript中,變量實際上不是類型。 有類型,變量有值。您可以檢查變量的當前值的類型,但您始終可以將任何其他值分配給該變量。有時用於這種類型的變量的術語是「變體」。這是您可以爲您的語言選擇的一種選擇。

如果您想要輸入變量,那麼您需要靜態分析表達式。一旦你解析一行代碼,如:

var x = a.function() + b; 

...,然後才能開始執行它,你需要看看a.functionb確定數據類型,他們會回來,然後推導輸入operator +給出這兩種類型作爲輸入 - 然後可以將其指定爲x的變量類型。

這實際上還有很多工作要做,並且引入了一個全新的錯誤類別,可以防止代碼在第一位執行(「編譯時」錯誤)。

您可能正在尋找第一種方法,對於這種方法,您需要一個數據結構,該數據結構將值與值類型的描述組合在一起,並且該單元一起是您分配給變量,執行計算,函數返回等。如果幸運的話,你正在編寫解釋器的語言已經有了這樣一個概念 - 例如,如果你用JavaScript編寫解釋器,那麼你可以使用值直接,因爲他們已經封裝了這個概念。如果您使用Java或C#編寫解釋器,那麼Object類型可以引用任何值,並且可以使用語言的類型系統(以及必要時的反射)來檢查類型。

希望有幫助!

1

存儲各種類型的變量類型稱爲「變體」。基本上,你所做的就是每個變量都必須足夠大以容納你的語言所具有的所有類型,再加上一個標記它現在的類型。例如,在C你會使用聯盟這樣的:

struct Variant 
{ 
    enum VariantTypeEnum 
    { 
     VARIANT_TYPE_INT, 
     VARIANT_TYPE_STRING, 
     VARIANT_TYPE_BOOL 
    } type; 
    union VariantUnion 
    { 
     int intValue; 
     char* stringValue; 
     bool boolValue; 
    } value; 
}; 

當你有這種類型的變量,你現在可以分配這兩種類型的它和標記它是哪一個,然後根據運行不同的代碼它是什麼類型:

Variant x; 
x.type = VARIANT_TYPE_INT; 
x.value.intValue = 42; 

通常你會寫一個轉換爲所需類型的效用函數,以便您解釋不必擔心什麼類型的,它實際上是除非它是一個類型,它不能轉換到:

char* CopyStringFromVariant(Variant* inVariant) 
{ 
    if(inVariant->type == VARIANT_TYPE_STRING) 
    { 
     int strSize = strlen(inVariant.value.stringValue) +1; 
     char* strCopy = malloc(strSize); 
     memmove(strCopy,inVariant.value.stringValue, strSize); 
     return strCopy; 
    } 
    else if(inVariant->type == VARIANT_TYPE_BOOL) 
    { 
     const char* boolStr = inVariant.value.boolValue ? "true" : "false"; 
     int strSize = strlen(boolStr) +1; 
     char* strCopy = malloc(strSize); 
     memmove(strCopy, boolStr, strSize); 
     return strCopy; 
    } 
    else if(inVariant->type == VARIANT_TYPE_INT) 
    { 
     char strBuf[11] = {}; 
     snprintf(strBuf, sizeof(strBuf) -1, "%d", inVariant.value.intValue); 
     int strSize = strlen(strBuf) +1; 
     char* strCopy = malloc(strSize); 
     memmove(strCopy, strBuf, strSize); 
     return strCopy; 
    } 
    else 
     return NULL; // Indicate error. 
} 

如果你沒有寫一個純粹的線條式解釋器(即這不是一個人爲限制的家庭作業),但是可以創建一些混合,你可以先將代碼解析爲樹結構,然後遍歷樹節點並找出它們的類型。根據應用的操作,使用位域或集合來跟蹤存儲在變量中的哪些類型值。例如。如果有存儲在變量中的分割結果,最終的結果必須是從接着上的數字。

一旦你分析一樣,整個腳本,就可以生成代碼。這適用於大多數有效的程序,但程序的運行過程中一些JavaScript變量可能「改變類型」。然後你可能還需要實現變體或字符串(它可以存儲所有其他類型的相當低效的表示),然後按照我給出的CopyStringFromVariant()示例的樣式使用GetIntFromString()函數進行轉換。

免責聲明:筆試就在這裏提交表單的所有代碼,它可能有錯別字,而不是編譯。

注:另一種方法是do it like Smalltalk,其中的變量通常是指向一個對象,但一些簡單的類型是使用值,這將是無效的指針(例如,奇數地址,其中大部分分配器不會給你編碼,所以是如果你的地址指向不可能對象的開始)。