用自己的程式語言實現了一個網站(增強版)

2022-10-09 09:00:15

前言

前段時間在《用自己的程式語言實現了一個網站》用介紹了用 GScript 寫的一個簡單「網站」,雖然是打上引號的;頁面長這樣:

看起來確實非常的挫,其實之前一直也想做一個 GScript 的線上 playground ,於是國慶期間學了一點 皮毛 Vue 加上老弟的幫忙(他是前端開發),最終完成了下面這個網站:

https://gscript.crossoverjie.top/

❤列印原始碼參考了:https://wa-lang.org/playground/

在這裡可以線上執行 GScript 程式碼,藉助於前端的程式碼編輯器外掛甚至還能有一些語法提示。

不過有些提示與 GScript 的語法不相容,畢竟編輯器的提示是基於 JavaScript 的語法。

內建了幾個 demo,可以選擇執行試試。

同時也支援檢視 AST 樹和 symbol 符號表。

雖然顯示上還有待優化。


整個後端介面全都是用 GScript 原生程式碼編寫的,所以這也算是 GScript 的一個實際應用案例。

程式碼範例

func (HttpContext) run(HttpContext ctx) {
    string body = ctx.postFormValue("body");
    string local = d.getCurrentTime("Asia/Shanghai","2006-01-02 15:04:05");
    println("===" + local);
    println(body);
    println("===");
    RunResponse r = RunResponse();
    if (body == ""){
        r.body = "empty code";
        ctx.JSON(200, r);
        return;
    }
    string fileName = d.unix("Asia/Shanghai") + "temp.gs" ;
    s.writeFile(fileName, body, 438);
    string pwd = s.getwd();
    // string res = s.command("gscript", fileName);
    string res = s.command("docker","run","--rm","-v", pwd+":/usr/src/gscript","-w","/usr/src/gscript", "crossoverjie/gscript","gscript", fileName);
    s.remove(fileName);
    r.body = res;
    r.ast = dumpAST(body);
    r.symbol=dumpSymbol(body);
    ctx.JSON(200, r);
}

httpHandle("GET", "/index", index);
httpHandle("POST", "/run", run);
string[] args = s.getOSArgs();
if (len(args) ==3){
    httpRun(":" + args[2]);
}else {
    httpRun(":8000");
}

實際程式碼量也並不多,將前端輸入的程式碼寫入到一個臨時檔案,再呼叫 OS 的 command api 在本地執行執行 docker,最後將標準輸出和錯誤返回即可。

版本更新

為了能實現上述的需求,所以本次也更新了 GScript 的版本,新增了一些內建 API

主要是新增了 playground 需要的一些 OS api、檔案寫入、執行系統命令、日期相關等。

同時將同一類的 API 合併到一個 class 中,方便後期維護與呼叫。

編譯錯誤

除此之外也新增了一些易用功能,比如現在提供了更友好的編譯錯誤資訊:

執行時錯誤

執行時的異常現在也有對應提示:

只不過目前的顯示還不太友好,列印的堆疊還是 Go 的,之後會優化為只顯示 GScript 的堆疊。

總結

有了線上的 playground 後使得對 GScript 感興趣的門檻更低了一些,歡迎大家試用。


經過最近幾個版本的迭代,GScript 也逐步完善了,基本完成了第一版本的需求。

後續會繼續完善第二階段的,比如:

  • namespace
  • 包管理
  • 並行

等內容,每一項看起來都不是那麼容易啊。

之前有不少人問我 GScript 是拿來解決什麼問題的?當時我確實沒仔細想過;不過現在經過幾個版本的開發有了一點想法:

是否可以將 GScript 作為一個指令碼化的 Go 語言,畢竟 Go 是編譯型別的,每次修改釋出都需要經過編譯才能執行,但如果可以像指令碼語言,比如 Python、Bash 修改後就可以直接執行,這在寫一些不是那麼重的業務時非常有用。

同時藉助於語法糖甚至可以優化掉 Go 本身被人「吐槽」的地方,比如異常、append 函數、沒有運運算元過載、三目運運算元等。

部分吐槽 GScript 已經支援。

同時因為得益於本身也是 Go 編寫的,所以 Go 的一些優點也能繼承過來,比如輕量級的協程等。

Go 本身也有大量的第三方庫,後續甚至也能直接使用這些現成的庫。

以上只是一些美好的暢想,就像老闆畫的大餅一樣,具體在實現過程中可能又有不一樣的想法,歡迎提供建議。

playground 地址:
https://gscript.crossoverjie.top/

原始碼地址:
https://github.com/crossoverjie/gscript