Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add experimental syntax-rules #327

Closed
wants to merge 2 commits into from
Closed

Conversation

Hamayama
Copy link
Contributor

@Hamayama Hamayama commented Dec 6, 2017

実験的に SRFI-149 の syntax-rules を追加してみました。

環境変数 GAUCHE_EXP_SYNTAX_RULES を設定すると、
srfi-149-mod.scm の syntax-rules を使用します。

現状、マージできるレベルではなく、make check で以下のエラーが出ます。
また、環境変数ありで Gauche をビルドしてしまうと、
以後、環境変数なしで Gauche を実行したときにエラーが出たりするようです。。。

Testing macro ...                                                failed.
discrepancies found.  Errors are:
test bad ellipsis 6: expects #<error> => got #<undef>
test alt-elli3: expects literal => got ellipsis

Testing SRFIs ...                                                *** ERROR: unbound variable: test-assert
    While loading "../test/srfi.scm" at line 1568
Stack Trace:
_______________________________________
  0  (test-assert '(hash-table-exists? ht 'dog) (hash-table-exists ...
        expanded from (test-assert (hash-table-exists? ht 'dog))
        at "../test/srfi.scm":1419
  1  (test-assert '(hash-table-exists? ht 'dog) (hash-table-exists ...
        expanded from (test-assert (hash-table-exists? ht 'dog))
        at "../test/srfi.scm":1419

Total: 16546 tests, 16544 passed,     2 failed,     1 aborted.

ただ、齊藤さんの
https://github.com/SaitoAtsushi/pattern-match-lambda
については、正常に動作するようでした。

デバッグは、compile.scm 等に print を追加して行っていますが、結構つらい感じです。

Sagittarius Scheme のソースのコメントが大変参考になりました。

まずは、make check が正常に終了することを目指してみようと思います。

気になる点等がありましたら、連絡をお願いします。

<テスト環境>
OS : Windows 8.1 (64bit)
Gauche : コミット e541e38 + 変更
開発環境 : MSYS2/MinGW-w64 (64bit) (gcc version 7.1.0 (Rev2, Built by MSYS2 project))

@shirok
Copy link
Owner

shirok commented Dec 7, 2017

srfi-149は既に組み込みのsyntax-rulesが対応してるので、srfi-149を期待してるコードで問題が起きるようでしたらマクロのバグとして報告してください。

@shirok
Copy link
Owner

shirok commented Dec 7, 2017

それとは別に、Schemeで書かれた代わりのマクロ展開器を走らせようとしてGaucheのバグに当たることがあります。そういうケースでも個別にバグ報告していただけるとありがたいです。

@Hamayama
Copy link
Contributor Author

Hamayama commented Dec 8, 2017

  • compile.scm を一部変更して、make check が完走するようになりました。

    変更内容ですが、cenv-toplevel? で SYNTAX の frame も判定するようにしました。

    トップレベルに letrec-syntax があった場合、SYNTAX の frame が cenv に追加されますが、
    cenv-toplevel? では LEXICAL の frame のみチェックしていたため、
    ローカルマクロがすべてトップレベルと判定されて、
    %make-er-transformer/toplevel によってマクロ定義時の環境がすべて空に設定されていました。

    最初の変更で、er-comparer の cenv-lookup-variable を cenv-lookup-syntax に
    変更したのも、同様の理由です。

    テストは通っていますが、他に影響がないか少し心配ではあります。

  • あと、現状、main.c で環境変数を見て syntax-rules を切り替えていますが、
    プリコンパイルの結果が変わってしまうので、問題があります。
    (ONにしてコンパイル → OFFにして実行 でエラー等)

    今のところ、コンパイラも含めて変更/確認しているためこのようにしていますが、
    最終的には外部ライブラリにするのがよいかと思っています。

  • また、現状把握している不具合については、以下の通りです。

<組み込みの syntax-rules >

(1) https://github.com/SaitoAtsushi/pattern-match-lambda
の test.scm で 3件 NG になる。

(2) Gauche の test/macro.scm で、
コメントアウトされているテストが6件あり、NG になる。
(最後の2個は srfi-147 not supported なので問題ないと思われる)
_ (a) internal define-syntax and scope 2
_ (b) internal define-syntax and scope 3
_ (c) internal define-syntax and scope 4
_ (d) let-syntax - let-syntax 2 (letrec-syntax にすると動くが。。。)
_ (e) srfi-147 begin (internal) 1 (not supported)
_ (f) srfi-147 begin (internal) 2 (not supported)

<今回追加した syntax-rules >

(3) Gauche の test/macro.scm で、6件 NG になる。(4件は(2)と同じもの)
_ (a) bad ellipsis 6 (エラーチェックがなさそう。。。)
_ (b) alt-elli3 (ellipsis と literal の優先順位がちがう?)
_ (c) internal define-syntax and scope 4 (pass1/body-rec あたりが関係している?)
_ (d) let-syntax - let-syntax 2 (letrec-syntax にすると動くが。。。)
_ (e) srfi-147 begin (internal) 1 (not supported)
_ (f) srfi-147 begin (internal) 2 (not supported)

<一覧>

組み込み 今回追加 Sagittarius Racket
(1) ×
(2)-(a) ×
(2)-(b) ×
(2)-(c) × ×
(2)-(d) ×1 ×1 ×1 ×1
(2)-(e)
(2)-(f)
(3)-(a) ×2 ×2 ×4
(3)-(b) ×3 ×3 ×5

○ : OK
× : NG
- : not supported
×1 : letrec-syntax にすると動くが。。。仕様では?
×2 : エラーチェックがなさそう。。。
×3 : ellipsis と literal の優先順位がちがう?
×4 : misplaced ellipsis in pattern
×5 : bad syntax

<テスト環境>
OS : Windows 8.1 (64bit)
Gauche : コミット e541e38 + 変更
Sagittarius : v0.8.4 (R7RSモード)
Racket : v6.7

次の目標としては、今回追加の syntax-rules で (2)-(c) を通したいと思っています。

@shirok
Copy link
Owner

shirok commented Dec 9, 2017

ありがとうございます。助かります。
2-a,b,cについては将来のマクロシステムの書き換え時に対応予定で放置してました。
2-dは確かに外側がletrec-syntaxでないとおかしいですね。どこから取ってきたんだろう。
3-bはテストのコメントに書いてあるsrfi-148の議論で出てきた例で、R7RSを厳密に解釈すれば通るはずです。R6RSではエラーでもおかしくありません。
pattern-match-lambdaのエラーについては調査します。

マクロシステムをSchemeで書いたものに置き換える予定はありますが、性能のためGaucheの内部情報を利用する形になると思うので、現時点でGaucheにマクロの別実装をバンドルする予定はありません。

compile.scmのfixは検証後いただきます。

@shirok
Copy link
Owner

shirok commented Dec 9, 2017

マクロの別実装について、Gauche本体にバンドルすることはないと思いますが、サードパーティの拡張ライブラリとして使えるものがあるのは歓迎なので、「独立したライブラリとして別マクロ実装をロードした場合に不都合が出る部分」があれば都度レポートしていただけるとマージします。

shirok added a commit that referenced this pull request Dec 9, 2017
Not sure why I thought the outer construct should be let-syntax.
The mdm-foo4 macro is apparently intended to be recursive, thus
it should use letrec-syntax.

See #327 (comment)
shirok added a commit that referenced this pull request Dec 9, 2017
@Hamayama
Copy link
Contributor Author

方針については了解です。
ややこしくなってきたので、こちらは一度クローズします。
(2)-(a)(b)(c) は原因が分かった感じですが、ちょっと影響範囲が読めないので、
別のプルリクエストにしてみます。

@Hamayama
Copy link
Contributor Author

外部モジュールにしてみました。
https://github.com/Hamayama/srfi-149-mod

@shirok
Copy link
Owner

shirok commented Dec 15, 2017

このfixでpattern-match-lambdaのテストが通るようになりました。
5159911

@Hamayama
Copy link
Contributor Author

こちらの環境でも問題ないことを確認しました。
長かった戦いが。。。

ソースを見ていて ひとつ気になったのですが、ctx->literals についても、
以下の点が、変更前の ctx->tvars と似た処理になっていると思います。

(i) preprocess_literals で、identifier の場合は wrap せずにそのまま登録

(ii) compile_rule1 の下の方で、id_memq による一致チェック

ctx->literals についても ctx->tvars と同様の変更が必要でしょうか?

@shirok
Copy link
Owner

shirok commented Dec 15, 2017

うーむ、確かに危ない感じではありますね。リテラルはfree-identifier=?で比較するから、問題が出るとすればマクロで再帰しつつ一回のイテレーションでidentifierに束縛を導入しつつそのidentifierをそれまでのリテラルリストに追加し、さらにそういったリテラルにマッチさせるマクロ呼び出しも生成する、といったコードになるのかな。まずはそのバグを突くテストコードを作ってみる必要がありそうです。

@shirok
Copy link
Owner

shirok commented Dec 15, 2017

新しいissue建てました。 #329

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants