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>
相当のものかな?