Java で書いてみました。やっつけなので汚いです。ライフゲームが動いたのでヨシ、というレベルのものです。
移植元
ベースになっているバージョン: 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"); } } }