Skip to content
hikalium edited this page Mar 27, 2017 · 16 revisions

LANG01

  • nv/experimentalのデフォルト言語
  • (nv/experimentalでは、構文や演算子を自由に追加する機能は重視されていない(できるけれども))

ノードが持てるデータ型(NodeType)

  • None
  • Relation
  • BLOB
  • String
  • Integer

ノードの振る舞いを規定する型(TermType)

カッコ内は、TermTypeが指定されるノードが持つべきNodeType(Anyならば、いずれでも可)

  • (指定なし)
  • Array(Any)
  • Variable(Any)
  • Op(Any)
  • Path(Any)
  • ID(String)

値そのもの(primVal)か、値への参照(refVal)か

将来的にはVariableもPathに統合可能?
  • refVal: TermTypeがVariableもしくはPathであるNode
    • refValに対しては、参照も代入もできる。
  • primVal: refValでないNodeのこと
    • primValに対して代入することはできない。

getPrimVal

  • refValが指し示すprimValを返す。もし、もともとprimValだった場合はそれを返す。
  • ただし、コンテキストに存在する変数名として解釈可能で、かつリテラルで書かれていなかった文字列は、すべて変数に変換されてから上記作業が行われる。
if(!isLiteralString(n)){
  n = getVariableData(n);
}
if(isPath(n)) return getPrimVal(getPathTargetData(n));
return n;

参照取得演算子

ドット演算子

p.q.r
.p.q.r
- if ドット演算子の左辺がパスオブジェクトなら
  - 右辺を左辺のパスに追加する
- else if 左辺 == (演算子 or NOT_FOUND)
  - ルートノードを起点とするパスを作成し、それに右辺を追加する
- else if 左辺 isFoundIn 現在のコンテキスト
  - 左辺が指すノードを起点とするパスを作成し、それに右辺を追加する
- else
  - エラー

等しいことと等しくないこと

二種類の考え方がある

  1. IDが等しい(完全に同一のオブジェクトを指している)
  2. そのIDが表現するデータが、値として等しい(IDは等しくなくてもいい)

1が成立するなら2も成立するが、逆は成り立たない。

逆は成り立たないけれど、それに遭遇した時にマージしてしまえばいいのでは?
ノードの値は作成後不変である、という制約をつける必要がある。
(現在のところ、Relationが不変ではない。)

それぞれ以下の関数で表現される。

  1. int NV_ID_isEqual(const NV_ID *a, const NV_ID *b);
  2. int NV_ID_isEqualInValue(const NV_ID *a, const NV_ID *b);

関係(Relation)

関係は、以下の3つのIDをデータとして持つノードである。

  1. from: 関係の元となるノードID
  2. rel: どのような関係なのかをあらわすノードID
  3. to: 関係の先となるノードID

「関係」を取得すること

二種類のものが取得できる。

  1. その関係性が指すノードのID(RelNode.to.id)
  2. その関係性を表現する(RelNode.id)

「関数」の実行

nvでは、関数は存在せず、コードブロックという形で存在する。コードブロックは、単なる配列である。 直前にコードブロックがある状態で(演算子が発動した場合、これは関数呼び出しを意味する。

nvのスコープ

nvのスコープは、動的ブロックスコープである。ある変数は、その変数が宣言されたブロックの実行が終了する際に破棄される。 スコープとは、実質的に、構造体である。この構造体には、現在実行中のブロックや、そのブロックを起動した際のスコープへの参照が保存されている。

実行環境の構造

  • NV_STATIC_ROOT (固定UUID)
    • NV_CONTEXT (実行環境。これを1単位として止めたり動かしたりする)
      • evalStack[]

NV_CONTEXT

evalStackが存在する。 evalStackの各要素(codeBlock)に、スコープオブジェクトが存在する。

スコープオブジェクト

基本的に、そのスコープに属する変数をもつ構造体。 ただし、特別なキーがいくつかあり、それは親スコープなどへの参照をもつ。