トップ «前の日記(2016-07-09) 最新 次の日記(2016-07-13)» 編集

Route 477



2016-07-10

[scheme] Fomentを読む(2)

前回からの続き。前回はリビジョンを書くのを忘れたが、現時点のgit masterを手元にダウンロードして読んでいる。

昨日はsyntax-rulesからだいぶ離れてしまったので、またsynrules.cppから見ていこう。

void SetupSyntaxRules()
{
    R.SyntaxRulesRecordType = MakeRecordTypeC("syntax-rules",
            sizeof(SyntaxRulesFieldsC) / sizeof(char *), SyntaxRulesFieldsC);
    R.PatternVariableRecordType = MakeRecordTypeC("pattern-variable",
            sizeof(PatternVariableFieldsC) / sizeof(char *), PatternVariableFieldsC);
    R.PatternRepeatRecordType = MakeRecordTypeC("pattern-repeat",
            sizeof(PatternRepeatFieldsC) / sizeof(char *), PatternRepeatFieldsC);
    R.TemplateRepeatRecordType = MakeRecordTypeC("template-repeat",
            sizeof(TemplateRepeatFieldsC) / sizeof(char *), TemplateRepeatFieldsC);
    R.SyntaxRuleRecordType = MakeRecordTypeC("syntax-rule",
            sizeof(SyntaxRuleFieldsC) / sizeof(char *), SyntaxRuleFieldsC);
}

レコード型

ここでは5つのレコード型を定義している。

  • SyntaxRuleRecordType
  • PatternVariableRecordType
  • PatternRepeatRecordType
  • TemplateRepeatRecordType
  • SyntaxRuleRecordType

型名は分かったが、フィールドの定義はどこにあるのだろう。それぞれSyntaxRulesFieldsCのようなシンボルを渡しているので、これを確認してみよう。

同じファイルを「FieldsC」で検索すると以下が見つかった。

static const char * SyntaxRulesFieldsC[] = {"literals", "rules", "syntactic-env"};
static const char * PatternVariableFieldsC[] = {"repeat-depth", "index", "variable"};
static const char * PatternRepeatFieldsC[] = {"leave-count", "ellipsis", "variables", "pattern",
static const char * TemplateRepeatFieldsC[] = {"ellipsis", "repeat-count", "variables", "template",
    "rest"};
static const char * SyntaxRuleFieldsC[] = {"num-variables", "variables", "pattern", "template"};

整理しておこう。

  • SyntaxRules = (literals, rules, syntactic-env)
  • PatternVariable = (repeat-depth, index, variable)
  • PatternRepeat = (leave-count, ellipsis, variables, pattern)
  • TemplateRepeat = (ellipsis, repeat-count, variables, template, rest)
  • SyntaxRule = (num-variables, variables, pattern, template)

メンバ名から察するに、以下の様な階層構造だと思われる。

  • SyntaxRules = (literals, rules, syntactic-env)
    • SyntaxRule = (num-variables, variables, pattern, template)
      • PatternVariable = (repeat-depth, index, variable)
      • PatternRepeat = (leave-count, ellipsis, variables, pattern)
      • TemplateRepeat = (ellipsis, repeat-count, variables, template, rest)

struct

一方でsynrules.cppでは以下のようなstructも定義されている。これとレコード型はどのような関係なのだろうか?

typedef struct
{
    FRecord Record;
    FObject Literals;
    FObject Rules;
    FObject SyntacticEnv;
} FSyntaxRules;

synrules.cppで定義されているstructは以下。全部のレコード型にstructがあるわけではないようだ。

  • FSyntaxRules
  • FSyntaxRule

FSyntaxRulesの定義の下に、MakeSyntaxRulesという関数がある。これによると、MakeRecordで生成したレコードを、struct FSyntaxRulesで受けられるらしい。

FSyntaxRules * sr = (FSyntaxRules *) MakeRecord(R.SyntaxRulesRecordType);
sr->Literals = lits;
sr->Rules = rules;
sr->SyntacticEnv = se;

synrules.cppをMakeRecordで検索すると、FPatternVariable, FPatternRepeat, FTemplateRepeatという識別子も存在することがわかる。これらの定義はsynrules.cppには無いが、compile.hppにあることが分かった。例えばFTemplateRepeatの定義は以下である。

typedef struct
{
    FRecord Record;
    FObject Ellipsis;
    FObject RepeatCount;
    FObject Variables;
    FObject Template;
    FObject Rest;
} FTemplateRepeat;

一方でTemplateRepeatFieldsCの定義は以下だったので、見比べると、最初のFRecord Record以外はレコード型のフィールド名と対応していることがわかる。

static const char * TemplateRepeatFieldsC[] = {"ellipsis", "repeat-count", "variables", "template",

ということで最初の疑問の答えだが、レコード型の値をMakeRecordで作成すると対応するstructの値が得られる、ということで良さそうだ。