|
JavaScript 2.0
根拠
単位
|
09/20/2002 (Fri)
単位は Spice の草案から引き出されたもので、元々 JavaScript 2.0 草案に含まれていたが、JavaScript 2.0 の軽量化のために将来のバージョンに見送られた。実装されるとしたら名前付き引数は本節で述べるような振る舞いをしていた。
単位式は 7cm のように普通数値とその後に空白文字が間に入らず単位名が続く形で構成される。単位名には引用符を付けることができ
(例えば 7 "cm") 、この場合は数値と単位の間に空白文字があってもよく、単位名には単位パターンを使うこともできる
(例えば 7 "Kg*cm^2/s")。
数値リテラルのすぐ後ろに識別子が続いている場合、レキシカルアナライザは識別子を文字列リテラルに変換し、パーサはその数値と文字列を単位式として扱う。この識別子をアンダースコアで始めることはできないが、予約語の制限は無い。つまり表音文字で始まるあらゆる識別子はたとえ予約語であっても正しく機能する。
例えば 3in は 3 "in" に、5xena は 5 "xena" に変換される。一方
0xena は 0xe "na" に変換される。単位の定義に単独或いは後ろに10進数値が続く e
、E や、後ろに16進数値が続く x 、X
で始まる名前を使用するのは賢明ではない。このような名前は指数表記や16進表記とのあいまいさを孕むからである。
nulltruefalsepublicthis後ろに String リテラルが続く Number リテラル、ParenListExpression 、UnitExpression は単位式であり、以下のように評価される:
String リテラルを評価し文字列 S
を得る。その文字列を単位パターンの文法とセマンティクスに従って解析し、識別子と指数のリスト
[id1e1,
id2e2, ...,
idnen] を得る。解析に失敗した場合は構文エラーを出す。リストが空であれば
U を nullUnit という関数にする。この関数は省略不可能である引数と可能である引数を1つずつとり、省略可能な引数を無視して最初の引数を返す。
リストが空でなければ1から n までの i に対して、システムの名前空間 unit から探索された
idi の値を Vi とし、i が1のときは Fi =
Vi 、それ以外のときは Fi =
Vi.public::pow(ei) とする。更に U =
F1*F2*...*Fn
とする。例えば S が "Kg*m^2/s^2*q" であれば U は
unit::Kg*unit::m.public::pow(2)*unit::s.public::pow(–2)*unit::q.public::pow(–1)
の値となる。ただし unit はシステムの unit 名前空間である (unit と名前 unit
の相違が問題になるのは unit という名前の局所定義を持つひねくれたコードが存在するときだけである。そのような局所定義が存在するかどうかは単位の探索には影響しない)。
結果として得られた U は、省略不可能である引数と可能である引数を1つずつとる関数として呼び出し可能でなければならない。単位式は
Number リテラル、ParenListExpression
、或いは UnitExpression の数値を第1引数として U を呼び出す。第2引数は
UnitExpression Number [no line break] String
生成規則のときのみ与えられ、元の Number リテラルの文字列表現である。先の例の話を続けると単位式
32.50 "Kg*m^2/s^2*q" は (unit::Kg*unit::m.public::pow(2)*unit::s.public::pow(–2)*unit::q.public::pow(–1))(32.5, "32.50")
の結果として評価される。
U の第2引数は数値の拡張構文を定義するユーザ定義の単位クラスでもよい。例えば長整数パッケージは
Number リテラルを最初に64ビット浮動小数点数に丸めずに完全な64ビット数値として扱う単位
"L" を定義できる。このような単位は他の単位を後ろに続けて並べることで他の単位と結合することができる。先頭の単位は数値のすぐ後ろに続いていれば引用符が無くても字句構造上は問題ないという点に注意していただきたい。つまり
3L "cm" は 3 "L" "cm" と同じであり、unit::cm(unit::L(3, "3"))
の結果として評価される。
単位は名前空間 unit に置くことで定義する。この名前空間はシステムにより定義済みで、単位式は
unit 名前空間を使って暗黙に限定される。単位名前空間はデフォルトでは use
されていないので、既存の単位定義にアクセスするには識別子を unit:: で明示的に限定する必要がある。
単位定義の最も簡単な方法は既存の単位の変換、乗算、除算である。例えば次のようなものである:
unit const µm = unit::m/1e6; unit const Å = unit::m/1e10; unit const dm = unit::m/10; unit const \_in = unit::m*0.0254; unit const liter = unit::dm.pow(3);
in は予約語であるので単位 in の定義には \_ を使わなければならない。しかしながら単位
in は引用符を用いずに 3in + 5cm のように使うことができる。
クラスの拡張が言語に追加されれば、単位の定義として unit
名前空間の代わりにクラス拡張の機構が使用できる。この方法だと単位を internal や private などとして設計できる。
unit 属性は
const unit = extend(Unit);
のように定義され、トップレベルで評価される。Unit は単位名の定義を保持するクラスである。
|
Waldemar Horwat 最終更新: 2002年9月20日 (金) |