2016-10-20
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が起動しなくなっていた。アクセス制御の設定を許可せよというダイアログが出るんだけど、やってみても再度同じダイアログが出る。
オフィシャルサイトに対策手順があった。僕の環境だとこの手順ではだめで、以下のようにする必要があった。
- 設定→セキュリティとプライバシー→プライバシー→アクセシビリティを開く
- 左下の鍵アイコンをクリックし、パスワードを入力
- Witch.appとwitchdaemon.appがあるので、両方ともマイナスボタンでいったん解除
- オフィシャルの手順でwitchdaemon.app ( /Applications/Witch.app/Contents/PlugIns/Witch.prefPane/Contents/Helpers/witchdaemon.app )を登録
- アプリケーションからWitchを起動。Witchの設定画面が開くが、一番上にアクセス制御の設定をしてください的なメッセージが出るのでそこをクリック
- 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>
相当のものかな?