トップ 追記

Route 477

過去の日記


2016-08-13

[scheme] Fomentを読む(5)

前回からだいぶ間が空いた。ちょっと別にやりたいことができたので、実を言うとこっちは休載しようと思っていたのだけど、月一ペースで更新するというのもありかもしれない。一回分の更新にはそれほど時間がかからないし、考えたことは全て文字に落としているから思い出すのもそれほど難しくないし。

前回はExpandSyntaxRulesの他にCompileSyntaxRulesという関数がエクスポートされていることを発見したのだった。

なのでsynrules.cppのたくさんの関数は、もしかしたら2種類に分類できるかもしれない。今回はそのあたりを見ていく。

関数一覧

一覧を再掲する。引数のうち、型名が省略されているものはFObject。

static FObject LiteralFind(se, list, obj)
static FObject CopyLiterals(se, obj, ellip)
static FObject PatternVariableFind(se, list, var)
static FObject CompilePatternVariables(se, form, lits, pat, ellip, pvars, int_t rd)
static void AssignVariableIndexes(pvars, int_t idx)
static int_t CountPatternsAfterRepeat(pat)
static FObject RepeatPatternVariables(se, pvars, pat, rvars)
static FObject CompilePattern(se, lits, pvars, ellip, pat)
static int_t ListFind(list, obj)
static int_t AddVarToTemplateRepeat(var, trs)
static FObject CompileTemplate(se, form, pvars, ellip, tpl, trs, int_t qea)
static FObject CompileRule(se, form, lits, rule, ellip)
FObject CompileSyntaxRules(se, obj)

static void InitRepeatVariables(vars, vals[], rvals[])
static void GatherRepeatVariables(vars, vals[], rvals[])
static int_t MatchPattern(se, cpat, vals[], expr)
static int_t CheckRepeatVariables(vars, vals[], expr)
static void SetRepeatVariables(vars, vals[], rvals[])
static FObject ExpandTemplateRepeat(tse, use, ctpl, int_t nv, vals[], int_t rc, ret, expr)
static FObject ExpandTemplate(tse, use, ctpl, int_t nv, vals[], expr)
FObject ExpandSyntaxRules(se, sr, expr)

CompileSyntaxRulesとExpandSyntaxRulesだけがこのファイル外にエクスポートされているのだった。それ以外はprivate的な補助関数というわけだが、もしかしてこれ、ファイルの前半と後半で綺麗に分けてありますか?

試しに、InitRepeatVariables以下の関数がどこから呼ばれているかを確認してみる。やはり、ファイル後半にあるのはすべてExpandSyntaxRulesの方の補助関数だった。いやあ、こういうのを綺麗なソースっていうんですよね(嬉)

コールグラフ

作成したコールグラフは以下。各補助関数がどの関数から呼ばれているかを調べて、それを木にしたもの。

- ExpandSyntaxRules
 - MatchPattern
   - InitRepeatVariables
   - GatherRepeatVariables
 - ExpandTemplate
   - CheckRepeatVariables
   - SetRepeatVariables
   - ExpandTemplateRepeat
     - ExpandTemplate(相互再帰)

CompileSyntaxRulesの方もやってみよう。

- CompileSyntaxRules
  - CopyLiterals
    - LiteralFind
  - CompileRule
    - CompilePatternVariables
      - PatternVariableFind, LiteralFind
    - AssignVariableIndexes
    - CompilePattern
      - PatternVariableFind, LiteralFind
      - CountPatternsAfterRepeat
      - RepeatPatternVariables
        - PatternVariableFind
    - CompileTemplate
      - PatternVariableFind
      - AddVarToTemplateRepeat
        - ListFind

こっちのほうが少しでかそう。

というところで今日はここまで。


2016-08-09

[mac] Witchとアクセシビリティ設定(El Capitan)

気づいたらWitchが起動しなくなっていた。アクセス制御の設定を許可せよというダイアログが出るんだけど、やってみても再度同じダイアログが出る。

オフィシャルサイトに対策手順があった。僕の環境だとこの手順ではだめで、以下のようにする必要があった。

  1. 設定→セキュリティとプライバシー→プライバシー→アクセシビリティを開く
  2. 左下の鍵アイコンをクリックし、パスワードを入力
  3. Witch.appとwitchdaemon.appがあるので、両方ともマイナスボタンでいったん解除
  4. オフィシャルの手順でwitchdaemon.app ( /Applications/Witch.app/Contents/PlugIns/Witch.prefPane/Contents/Helpers/witchdaemon.app )を登録
  5. アプリケーションからWitchを起動。Witchの設定画面が開くが、一番上にアクセス制御の設定をしてください的なメッセージが出るのでそこをクリック
  6. Witch.appが追加されたことを確認。Witchが動くことを確認

2016-07-19

[zsh] ^[ h でmanを表示する(run-help)のをやめる

ergodox ezを使い始めてから、なんか変なタイミングでmanが表示される事故が起きるようになった。たぶん何らかのショートカットを誤入力してるんだろうなぁとは思ってたけど、http://syohex.hatenablog.com/entry/20121201/1354348504 によると、zshの機能だったようだ。

bindkeyコマンドで一覧を確認すると、^[ hがrun-helpに割り当てられている。.zshrcに以下を足して解決。

bindkey -r '^[h'

2016-07-15

[junk] 安いトイレットペーパーを買って失敗した話

http://nlab.itmedia.co.jp/nl/articles/1607/03/news019.html

うちのアパートがまさにこのタイプなんだけど、このタイプのトイレットペーパーホルダーには思わぬ罠があって、トイレットペーパーを適当に買うと、幅が足らなくて微妙に引っかからないことがあるのだ。結果として、紙を引き出そうとするたびにトイレットペーパーが勢い良く飛び出してくるというユーザ・エクスペリエンスを体験する羽目になる。

てかこんなもんJIS規格で統一しといてくれよと思ったのだが、なんと実際に114mm±2mmという規定があるらしい。こないだ買ったやつ、107mmなんだけどどうなってるんだ。JISマーク付いてないからいいのか。そうか。

[scheme] Fomentを読む(4)

前回からの続き。前回はsyntax-rulesを構成していそうな関数をリストアップしたのだった。

関数一覧

一覧を再掲する。ただし引数がFObjectであるものは型名を省略した。

static FObject LiteralFind(se, list, obj)
static FObject CopyLiterals(se, obj, ellip)
static FObject PatternVariableFind(se, list, var)
static FObject CompilePatternVariables(se, form, lits, pat, ellip, pvars, int_t rd)
static void AssignVariableIndexes(pvars, int_t idx)
static int_t CountPatternsAfterRepeat(pat)
static FObject RepeatPatternVariables(se, pvars, pat, rvars)
static FObject CompilePattern(se, lits, pvars, ellip, pat)
static int_t ListFind(list, obj)
static int_t AddVarToTemplateRepeat(var, trs)
static FObject CompileTemplate(se, form, pvars, ellip, tpl, trs, int_t qea)
static FObject CompileRule(se, form, lits, rule, ellip)
FObject CompileSyntaxRules(se, obj)
static void InitRepeatVariables(vars, vals[], rvals[])
static void GatherRepeatVariables(vars, vals[], rvals[])
static int_t MatchPattern(se, cpat, vals[], expr)
static int_t CheckRepeatVariables(vars, vals[], expr)
static void SetRepeatVariables(vars, vals[], rvals[])
static FObject ExpandTemplateRepeat(tse, use, ctpl, int_t nv, vals[], int_t rc, ret, expr)
static FObject ExpandTemplate(tse, use, ctpl, int_t nv, vals[], expr)
FObject ExpandSyntaxRules(se, sr, expr)

よく見るとstaticな関数とそうでないものが存在する。なんだっけ、staticを付けると関数のスコープがこのファイル内だけになるんだっけか。

ExpandSyntaxRulesの他にはCompileSyntaxRulesが、ファイル外にも公開されているようだ。ExpandとCompileはどう違うのだろうか。引数も返り値もFObjectだらけなので、実際に期待されている型がわかりにくいな...。

CompileSyntaxRules, ExpandSyntaxRules

CompileSyntaxRulesは最後の行がこれなので、FSyntaxRulesを返すことが分かる。

return(MakeSyntaxRules(lits, ReverseListModify(nr), se));

ExpandSyntaxRulesの最後の行はこれ。あれ、値を返さないのか?

return(NoValueObject);

いや、途中にもreturnがあった。

        return(ExpandTemplate(MakeSyntacticEnv(AsSyntaxRules(sr)->SyntacticEnv), se,
        ...略

ExpandTemplateの返り値を見てみる。

static FObject ExpandTemplate(FObject tse, FObject use, FObject ctpl, int_t nv, FObject vals[],
    FObject expr)
{
    if (PairP(ctpl))
        return(MakePair(ExpandTemplate(tse, use, First(ctpl), nv, vals, expr),
                ExpandTemplate(tse, use, Rest(ctpl), nv, vals, expr)));

    if (VectorP(ctpl))
        return(ListToVector(ExpandTemplate(tse, use, AsVector(ctpl)->Vector[0], nv, vals, expr)));
...略

最初のreturnを見るとPairを返しているようだが、次のreturnはVectorを返すはず。ああそうか、引数によって違うものが返るのか。Cだけど、Schemeのコードに近いな。

NoValueObject

さっき出てきたNoValueObject、どういうものなのか気になるので調べてみる。foment.hppに定義があった。

#define EndOfFileObject MakeImmediate(3, MiscellaneousTag)
#define EndOfFileObjectP(obj) ((obj) == EndOfFileObject)

#define NoValueObject MakeImmediate(4, MiscellaneousTag)
#define NoValueObjectP(obj) ((obj) == NoValueObject)

#define WantValuesObject MakeImmediate(5, MiscellaneousTag)
#define WantValuesObjectP(obj) ((obj) == WantValuesObject)

MakeImmediateが何をするのかは分からないが、EOFオブジェクトと定義の仕方が同じなので、たぶん他の値と絶対にeqにならない定数値を定義しているのだろう。Gaucheでいう#<undef>相当のものかな?


2016-07-13

[vim][mac] Escapeを押したら日本語入力もオフにしたい

http://atarimae.hatenablog.com/entry/2014/05/21/173856

Google日本語入力の「キャンセル後IMEを無効化」が効かなくて困っていたのだが、Terminal.appをやめてiTerm2にしたら効くようになった。

[scheme] Fomentを読む(3)

前回からの続き。前回はレコード型がstructと対応していることを確認したのだった。

なんとなくデータ構造が把握できたので、次はシーケンス、つまり「何がどの順で実行されるか」の調査に入る。

まずは、syntax-rulesが呼ばれた時に最初に実行される関数を見つけたいが、synrules.cppの冒頭も末尾もどうやら違いそうだ。名前的には、下から二番目のExpandSyntaxRulesがそれっぽい感じがする。

ExpandSyntaxRules

使われている場所をgit grepで確認する。

src/compile.hpp:FObject ExpandSyntaxRules(FObject se, FObject sr, FObject expr);
src/library.cpp:            return(CompileEvalExpr(ExpandSyntaxRules(MakeSyntacticEnv(env), op, Rest(obj)), env,
src/synpass.cpp:            return(SPassExpression(enc, se, ExpandSyntaxRules(se, val, Rest(expr))));
src/synpass.cpp://            return(SPassExpression(enc, se, ExpandSyntaxRules(MakeSyntacticEnv(se), val, Rest(expr))));
src/synpass.cpp:            return(SPassBodyExpression(se, ExpandSyntaxRules(se, val, Rest(expr))));
src/synpass.cpp://            return(SPassBodyExpression(se, ExpandSyntaxRules(MakeSyntacticEnv(se), val,
src/synrules.cpp:FObject ExpandSyntaxRules(FObject se, FObject sr, FObject expr)

library.cppとsynpass.cppで使われているようだ。ふーむ。

SyntaxRulesをExpandしたあとのことについてはあまり興味がないのでここを追ってもしかたないかなと思いつつ、呼び出し元の関数名だけ控えておく。

  • library.cpp
    • static FObject CompileEvalExpr(FObject obj, FObject env, FObject body)
  • synpass.cpp
    • static FObject SPassExpression(FObject enc, FObject se, FObject expr)
    • static FObject SPassBodyExpression(FObject se, FObject expr)

synrules.cpp

ファイル内のエントリポイントが分かったので、次はファイル内の概要を把握しよう。
関数宣言の一覧を作る。

static FObject MakeSyntaxRules(FObject lits, FObject rules, FObject se)
static FObject MakePatternVariable(int_t rd, FObject var)
static FObject MakePatternRepeat(int_t lc, FObject ellip, FObject vars, FObject pat,
static FObject MakeTemplateRepeat(FObject ellip, int_t rc)
static FObject MakeSyntaxRule(int_t nv, FObject vars, FObject pat, FObject tpl)

このへんまでは単なるデータのコンストラクタだろう。したがってこれ以降がsyntax-rulesの本体と思われる。

static FObject LiteralFind(FObject se, FObject list, FObject obj)
static FObject CopyLiterals(FObject se, FObject obj, FObject ellip)
static FObject PatternVariableFind(FObject se, FObject list, FObject var)
static FObject CompilePatternVariables(FObject se, FObject form, FObject lits, FObject pat, FObject ellip, FObject pvars, int_t rd)
static void AssignVariableIndexes(FObject pvars, int_t idx)
static int_t CountPatternsAfterRepeat(FObject pat)
static FObject RepeatPatternVariables(FObject se, FObject pvars, FObject pat, FObject rvars)
static FObject CompilePattern(FObject se, FObject lits, FObject pvars, FObject ellip, FObject pat)
static int_t ListFind(FObject list, FObject obj)
static int_t AddVarToTemplateRepeat(FObject var, FObject trs)
static FObject CompileTemplate(FObject se, FObject form, FObject pvars, FObject ellip, FObject tpl, FObject trs, int_t qea)
static FObject CompileRule(FObject se, FObject form, FObject lits, FObject rule, FObject ellip)
FObject CompileSyntaxRules(FObject se, FObject obj)
static void InitRepeatVariables(FObject vars, FObject vals[], FObject rvals[])
static void GatherRepeatVariables(FObject vars, FObject vals[], FObject rvals[])
static int_t MatchPattern(FObject se, FObject cpat, FObject vals[], FObject expr)
static int_t CheckRepeatVariables(FObject vars, FObject vals[], FObject expr)
static void SetRepeatVariables(FObject vars, FObject vals[], FObject rvals[])
static FObject ExpandTemplateRepeat(FObject tse, FObject use, FObject ctpl, int_t nv, FObject vals[], int_t rc, FObject ret, FObject expr)
static FObject ExpandTemplate(FObject tse, FObject use, FObject ctpl, int_t nv, FObject vals[], FObject expr)
FObject ExpandSyntaxRules(FObject se, FObject sr, FObject expr)

長い!こんなに関数があったのか。でも幸い、めちゃめちゃ長い関数はなかったので、次回は関数同士の呼び出し関係を調べるところからやる(かもしれないし、気分次第で別のことをするかもしれない)。


過去の日記