素朴な自作言語のコンパイラをJavaに移植した


移植一覧に戻る


Java で書いてみました。やっつけなので汚いです。ライフゲームが動いたのでヨシ、というレベルのものです。

github.com


移植元

memo88.hatenablog.com

ベースになっているバージョン: tag:47 のあたり

メモ

  • アセンブラVM は移植対象から外しました。Ruby 版のものを使います。
  • テストのステップをさらに細かくした
    • トークナイザの最初のテストを通すときが重い(一番最初に無から作り始める段階なので重い)ので、 最初のテストの入力を最低限のもの(func + 半角スペース だけ)にしたりとか
  • 例外まわりが雑

今回はパーサをいじって call を不要にしてみました。

(追記 2021-03-31: この修正はいったん revert しましたが、一応 trial ブランチに残してあります。)

 func main() {
-  call my_func();
+  my_func();
 }

set のとき と同じです。 文の先頭の call で判別するのをやめて、識別子だったら parseCall_v2() を呼ぶ。

    private NodeList parseStmt() {
        Token t = peek();

        if (t.is(Token.Type.SYM, "}")) {
            return NodeList.empty();
        }

        switch (t.getStr()) {
        case "func"    : return parseFunc();
        case "var"     : return parseVar();
        case "set"     : return parseSet();
        // case "call"    : return parseCall();
        case "call_set": return parseCallSet();
        case "return"  : return parseReturn();
        case "while"   : return parseWhile();
        case "case"    : return parseCase();
        case "_cmt"    : return parseVmComment();
        default:
            if (t.type == Token.Type.IDENT &&
                    peek(1).is(Token.Type.SYM, "(")
            ) {
                return parseCall_v2();
            } else {
                throw unexpected("Unexpected token");
            }
        }
    }