SimpleLanguage 簡介

若要實作你自己的語言,請從擴展現有的語言(例如 SimpleLanguage)開始。SimpleLanguage 是一個使用 Language API 建構的示範語言。SimpleLanguage 專案展示如何使用 Language API 來撰寫你自己的語言。它旨在利用大部分可用的 Truffle 語言實作框架(以下簡稱「Truffle」)功能,並以內嵌原始碼文件廣泛記錄其使用方式。

SimpleLanguage 示範語言採用 通用許可證 (UPL) 授權。

先決條件 #

  • 你的系統中可使用 Maven
  • 已安裝 GraalVM
  • 用於 GraalVM 專案開發的 mx 工具(請見下方)。

開始使用 #

  1. 執行以下命令來複製 SimpleLanguage 儲存庫
     git clone https://github.com/graalvm/simplelanguage
    
  2. 從 SimpleLanguage 目錄執行 mvn package 來建置語言。在此之前,請驗證你的 GraalVM 安裝是否可以使用 native-image,以避免建置失敗
     cd simplelanguage
    
     native-image --version
    
     mvn package
    

    此命令會在 simplelanguage/native 目錄中建置 slnative 可執行檔,以及 sl-component.jar 語言元件。

    你可以在封裝階段透過執行以下命令來停用 SimpleLanguage 原生可執行檔建置

     export SL_BUILD_NATIVE=false
     mvn package
    
  3. 從專案根目錄執行 SimpleLanguage
     ./sl language/tests/HelloWorld.sl
    
  4. 若要查看已編譯函式的組合碼,請執行
     ./sl -disassemble language/tests/SumPrint.sl
    

IDE 設定 #

Truffle 框架 透過提供額外的 API,提供與語言無關的基礎架構來實現標準 IDE 功能。如果你想要試用你的語言並獲得 IDE 的優勢,請考慮將 SimpleLanguage 作為範例匯入。

Eclipse #

SimpleLanguage 教學專案已在 Eclipse Neon.2 Release 4.6.2 和 Eclipse Oxygen.3A 中測試過。若要將專案目錄匯入至所需的 Eclipse 環境

  1. 以新的工作區開啟 Eclipse。
  2. 從 Eclipse Marketplace 安裝 m2em2e-apt 外掛程式(說明 -> Eclipse Marketplace)。
  3. 最後,從「檔案」->「匯入」->「Maven」->「現有的 Maven 專案」-> 瀏覽至 SimpleLanguage 目錄 ->「完成」來匯入 SimpleLanguage 專案。

NetBeans #

NetBeans 提供 GUI 支援,可對任意語言進行偵錯。若要將 SimpleLanguage 上傳到 NetBeans 介面,請前往「檔案」->「開啟專案」-> 選取 simplelanguage 目錄 -> 勾選「開啟所需專案」-> 開啟專案。

IntelliJ IDEA #

SimpleLanguage 專案已在 IntelliJ IDEA 中測試過。開啟 IntelliJ IDEA,然後從主功能表列中,選取「檔案」->「開啟」-> 瀏覽並選取 simplelanguage 目錄 -> 按下「確定」。所有相依性都會自動包含在內。

傾印圖形 #

若要調查效能問題,請考慮在 GraalVM 之上使用 Ideal Graph Visualizer (IGV)。IGV 的開發目的是為了檢視和檢查中間表示圖形,這是由編譯器產生的原始語言和機器碼之間與語言無關的中間表示 (IR)。IGV 可免費使用。

  1. 在你的電腦上設定 mx 工具
    • 執行以下命令來複製 mx 儲存庫
       git clone https://github.com/graalvm/mx.git
      
    • Graal 儲存庫 複製到你的工作目錄
       git clone https://github.com/oracle/graal.git
      
    • mx 新增至 PATH 環境變數
       export PATH="/path/to/mx:$PATH"
      
    • 若要檢查安裝是否成功,請執行命令
       mx --version 
      
  2. 使用 mx 啟動 IGV
     mx -p graal/compiler igv
    
  3. 從 SimpleLanguage 根目錄執行以下命令,將圖形傾印到 IGV
     ./sl -dump language/tests/SumPrint.sl
    

這會將編譯器圖形以 IGV 格式透過網路傾印到接聽 127.0.0.1:4445 的 IGV 程序。建立連線後,你就能夠在「大綱」視窗中看到圖形。開啟特定圖形,依名稱、ID 或 property=value 資料搜尋節點,所有相符的結果都會顯示。請在此處深入瞭解

偵錯 #

若要使用 Java 偵錯工具開始偵錯 SimpleLanguage 實作,請將 -debug 選項傳遞到程式的命令列啟動器

./sl -debug language/tests/HelloWorld.sl

然後將 Java 遠端偵錯工具(例如 Eclipse)附加到連接埠 8000。

適用於 GraalVM 的 SimpleLanguage 元件 #

使用 Truffle 框架 實作的語言可以封裝為元件,稍後可以使用 GraalVM Updater 工具安裝到 GraalVM 中。在 SimpleLanguage 目錄中執行 mvn package 也會建置 sl-component.jar。此檔案是適用於 GraalVM 的 SimpleLanguage 元件,可透過執行以下命令來安裝

gu -L install /path/to/sl-component.jar

SimpleLanguage Native Image #

使用 Truffle 建置的語言可以使用 Native Image 進行 AOT 編譯。在 SimpleLanguage 目錄中執行 mvn package 也會在 native 目錄中建置 slnative 可執行檔。此可執行檔是完整的 SimpleLanguage 實作,屬於單一原生應用程式,不需要 GraalVM 即可執行 SimpleLanguage 程式碼。除此之外,與在 GraalVM 上執行相比,使用原生可執行檔的一大優勢是啟動時間快得多,如下所示

time ./sl language/tests/HelloWorld.sl
== running on org.graalvm.polyglot.Engine@2db0f6b2
Hello World!

real    0m0.405s
user    0m0.660s
sys     0m0.108s

time ./native/slnative
language/tests/HelloWorld.sl
== running on org.graalvm.polyglot.Engine@7fd046f06898
Hello World!

real    0m0.004s
user    0m0.000s
sys     0m0.000s

這段程式碼顯示使用 sl 啟動器指令碼(在 GraalVM 上執行 SimpleLanguage)和 Native Image 定時執行「Hello World」程式。我們可以發現,在 GraalVM 上執行時,執行需要 405 毫秒。由於我們的 SimpleLanguage 程式只會執行一個列印陳述式,因此我們可以得出結論,幾乎所有時間都花在啟動 GraalVM 和初始化語言本身。使用原生可執行檔時,我們發現執行只需要 4 毫秒,這表示啟動速度比在 GraalVM 上執行快兩個數量級。

如需有關 native-image 工具的詳細資訊,請考慮閱讀參考手冊

停用 SimpleLanguage Native Image 建置 #

透過 Maven 建置原生可執行檔已附加到 Maven package 階段。由於原生可執行檔建置可能需要一些時間,因此我們提供了選項,可透過將 SL_BUILD_NATIVE 環境變數設定為 false 來略過此建置,如下所示

export SL_BUILD_NATIVE=false
mvn package
...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building simplelanguage-graalvm-native
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- exec-maven-plugin:1.6.0:exec (make_native) @ simplelanguage-graalvm-native ---
Skipping the native image build because SL_BUILD_NATIVE is set to false.
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
...

使用最新(開發)版本的編譯器執行 SimpleLanguage #

若要使用 Graal 編譯器的開發版本執行 SimpleLanguage,我們必須使用該編譯器建置 GraalVM。複製 graal 儲存庫 (https://github.com/oracle/graal),並依照 vm/README.md 檔案中的指示建置 GraalVM。

完成後,將 JAVA_HOME 指向新建立的 GraalVM,然後繼續正常建置和執行 SimpleLanguage。

使用命令列執行 SimpleLanguage #

執行 SimpleLanguage 程式碼通常是使用 sl 指令碼完成,該指令碼會設定必要的命令列,具體取決於 JAVA_HOME 是指向 GraalVM 還是另一個 JVM 安裝。以下子章節描述這兩種情況下的命令列。

使用 GraalVM 作為 JAVA_HOME 執行 SimpleLanguage #

假設 JAVA_HOME 指向 GraalVM 安裝,且目前的工作目錄是 simplelanguage 目錄,若要執行 SimpleLanguage,應該執行以下命令

$JAVA_HOME/bin/java \
    -cp launcher/target/launcher-22.1.0-SNAPSHOT.jar \
    -Dtruffle.class.path.append=language/target/simplelanguage.jar \
    com.oracle.truffle.sl.launcher.SLMain language/tests/Add.sl

簡而言之,我們將啟動器 JAR 檔案放在類別路徑上,並執行其主類別,但我們透過使用 -Dtruffle.class.path.append 選項並提供 fat 語言 JAR 檔案的路徑,來通知 GraalVM SimpleLanguage 的存在。將語言放在單獨的類別路徑上,可確保語言實作及其嵌入內容(在此案例中為啟動器)之間有明確的區隔。

停用類別路徑分隔

注意!這只能在開發期間使用。

為了開發目的,停用類別路徑分隔並允許在應用程式類別路徑上使用語言實作會很有用(例如,為了測試語言的內部結構)。

Maven Central 上的 Language API JAR 檔案會在模組資訊中匯出所有 API 套件。將 --upgrade-module-path 選項與 -Dgraalvm.locatorDisabled=true 和此 JAR 檔案一起套用,以匯出 Language API 套件

-Dgraalvm.locatorDisabled=true --module-path=<yourModulePath>:${truffle.dir} --upgrade-module-path=${truffle.dir}/truffle-api.jar

使用 --upgrade-module-path 來匯出 Language API 套件的範例 POM 可在 Simple Language POM.xml 檔案中找到。

注意:停用定位器會有效地從模組路徑中移除所有已安裝的語言,因為定位器也會為這些語言建立類別載入器。若仍要使用內建語言,請將它們新增至模組路徑,方法是更新模組路徑以包含您所需的所有語言的路徑 (例如,$GRAALVM/languages/js)。

其他 JVM 實作 #

與 GraalVM 不同,GraalVM 包含了使用 Truffle 實作的語言所需的所有相依性,其他 JVM 實作需要在類別路徑中存在額外的 JAR 檔案。這些是可從 Maven Central 取得的 Language API 和 GraalVM SDK JAR 檔案。

假設 JAVA_HOME 指向一個標準的 JDK 安裝,並且目前的工作目錄是 simplelanguage 目錄,而且 Language API 和 GraalVM SDK JAR 檔案也存在於該目錄中,則可以使用以下命令執行 SimpleLanguage:

$JAVA_HOME/bin/java \
    -cp graal-sdk-22.1.0.jar:truffle-api-22.1.0.jar:launcher/target/launcher-22.1.0-SNAPSHOT.jar:language/target/simplelanguage.jar \
    com.oracle.truffle.sl.launcher.SLMain language/tests/Add.sl

與我們聯繫