目次
- 序論
- ランゲージの概要
- 変数とデータ型
- 式と演算子
- コマンド
- 文字列関数
- グローバルデータベース
- 入力/出力
- 間接参照 (Indirection)
- 特別変数
- ルーチンとプログラム構造
- まとめ
- コマンド参照表
- 関数参照表
- 特別変数参照表
- オペレータ参照表
- 構文要約
補遺 A: ASCII コード表
補遺 B: 用語集
1. 序論
1.1. MUMPS とは何か
- 創成: 1966 年、ボストンのマサチューセッツ総合病院(MGH)にて開発。
- 開発者:オクトー・バーネット (Octo Barnett)、ニール・パパリャード (Neil Pappalardo)、カーティス・マーブル (Curtis Marble)。
- 正式名称:Massachusetts General Hospital Utility Multi-Programming System の略称。
- 背景: 「医師と看護師が複数端末から患者データへリアルタイムでアクセス・更新する」という実用的なニーズ。
- 当時のハードウェア(DEC PDP-7 など)はメモリが極めて少なかった(8KB など)。
- OS やデータベースサーバーなどの独立したレイヤーが存在せず、すべてを一つの統合システムとして実装する必要があった。
- 特徴: 「組み込み階層型データベース」を搭載したプログラミング言語。
- 現代の文脈では**「統合型のプログラミング言語を搭載した NoSQL データベース」**と表現されることもある。
- コア概念: グローバル変数 (Global Variable)。
- スキーマフリーな順序付きキー値ストア。
- ディスク上に永続化され、全ユーザー間で共有される階層的疎配列。
; 例:患者情報の設定
SET ^PATIENT(12345,"NAME")="Smith, John"
SET ^PATIENT(12345,"DOB")="1945-03-15"
SET ^PATIENT(12345,"LAB","2024-01-15","GLUCOSE")=95
- メリット:
CREATE TABLE
やスキーマ定義、INSERT
ステートメントが必要ない。
- 必要な中間ノードは自動的に作成される。
KILL
で親ノードを削除すれば、子ツリーもすべて削除される。
1.2. 1976 年版標準
- 経緯: 互換性のない方言が多発したため、MDC(MUMPS Development Committee)が共通標準を策定。
- NBS ハンドブック 118(米国国家標準局発行)。
- プログラマース参照マニュアル (MDC/42) と併せて最初の形式的仕様となった。
- 内容: 極めて簡素な仕様の結晶化。
- コマンド: 19 種 (
BREAK
, CLOSE
, DO
, ELSE
, FOR
, GOTO
, HALT
, HANG
, IF
, KILL
, LOCK
, OPEN
, QUIT
, READ
, SET
, USE
, VIEW
, WRITE
, XECUTE
)
- 関数: 12 種 (
$ASCII
, $CHAR
, $DATA
, $EXTRACT
, $FIND
, $JUSTIFY
, $LENGTH
, $NEXT
, $PIECE
, $RANDOM
, $SELECT
, $TEXT
)
- 特別変数: 7 種 (
$HOROLOG
, $IO
, $JOB
, $STORAGE
, $TEST
, $X
, $Y
)
1.3. この本の対象読者
- 前提: 他のプログラミング言語の知識があること(MUMPS の事前経験は不要)。
- 目的:
- 導入: MUMPS の歴史と重要性を理解する。
- チュートリアル: 段階的な例題を通じた学習。
- クイック参照: 1976 年版標準の全コマンド・関数・変数の一覧。
1.4. スタートアップ
2. ランゲージの概要
2.1. あらゆるものは文字列である
- MUMPS はデータ型として文字列のみを持つ。
- 数値も見た目が数字の文字列に過ぎない(例:
"42"
と 42
)。
- 自動変換: 算術演算時に数値として解釈、連結時には文字列として扱う。型エラーは発生しない。
2.2. オペレータの優先順位なし
- 全ての二元演算子は厳密に左から右に評価される。
2+3*4
は 20 (足し算を先に実行)
- 乗算が優先されることはない。括弧(
()
)のみで順序を変更可能:(2+3)*4
= 20(※注記:元の文章の「14」という例は 2+(3*4)
の結果であるため、優先順位なしなら左から右なので 5*4=20
だが、括弧を入れることで 14
に変わる)。
- 厳密には
2+3*4
-> (2+3)*4
= 20。2+(3*4)
-> 14。
2.3. 行指向の構造
2.4. コマンドは簡潔な表現である
- 完全名(
SET
)と略号(S
)の両方が有効。
- 実務では高密度な略号が好まれるが、学習時は完全名を推奨する。
2.5. パーシステントデータベースは内蔵されている
- カーツ (
^
) 付きの変数: グローバル変数(永続的・共有)。
- カーツなしの変数: ローカル変数(メモリ上のみ、プロセス終了時に消失)。
3. 変数とデータ型
3.1. ローカル変数
3.2. 添字付き変数
3.3. 文字列、数値、および自動変換
3.4. 真偽値
4. 式と演算子
4.1. 厳密な左から右の評価
4.2. 算術演算子
| オペレータ | 意味 | 例 | 結果 |
|---|
+
| 加算 | 3+4
| 7
|
-
| 減算 | 10-3
| 7
|
*
| 乗算 | 6*7
| 42
|
/
| 除算 | 7/2
| 3.5
|
\
| 整数除算 (床) | 7\2
| 3
|
#
| 剰余 (modulo) | 7#3
| 1
|
- 整数除算は負の方向に切り捨て、剰余演算子は
A-(B*floor(A/B))
で定義される。
4.3. 一元演算子
| オペレータ | 意味 | 例 | 結果 |
|---|
+
| 数値解釈 (右側) | +"42ABC"
| 42
|
-
| 符号逆転 | -3
| -3
|
'
| 論理 NOT | '0'
| 1
|
- 右結合であり、
-'3
は「-3 の真偽値解釈(1)を否定(0)」となる。
4.4. 関係演算子
| オペレータ | 意味 | 例 |
|---|
=
| 文字列等価 | "AB"="AB" (1 ) |
<
| 数値未満 | 3<10 (1 ) |
>
| 数値より大きい | 10>3 (1 ) |
]
| ASCII オーダーで後続 | "B"]"A" (1 ) |
[
| 文字列が含まれる (部分一致) | "ABCDE"["CD" (1 ) |
?
| パターンマッチ | "ABC"?3A
|
'
(否定符) を付ければ否定される(例:!=
は等しくない)。
[
は右オペランドが左に含まれるかテストする。空文字列は全ての文字列に含まれる。
4.5. 論理演算子
| オペレータ | 意味 | 例 | 結果 |
|---|
&
| AND | 1&1
| 1
|
!
| OR | 0!1
| 1
|
- 否定形:
'&
(NAND)、!'
(NOR)。
- ショートサーキット評価はなし(両側を必ず評価)。
- 優先順位が同一なので、括弧を使用する必要がある。
4.6. 連結演算子
4.7. パターンマッチ (?
)
| コード | 意味 | キャラクタ |
|---|
A
| アルファベット | A-Z, a-z |
N
| 数値 | 0-9 |
U
| 大文字 | A-Z |
L
| 小文字 | a-z |
.
| 句点記号 | スペースを含む |
C
| コントロール文字 | DEL を含む |
E
| すべての ASCII | |
.N
は「任意の数個の数値」。
- リテラルハイフンをパターンに含める場合は
"-"
のように引用符で囲む。
5. コマンド
5.1. SET — 値の割り当て (S
)
- 変数への値設定。括弧で複数同時設定も可能。
SET X=42
SET (A,B,C)=0 ; A, B, C をすべて 0 に
5.2. WRITE — データの出力 (W
)
- フォーマットコード:
!
: 改行 ($X を 0、$Y を +1)
#
: フォームフィード(ページ送り)
?n
: n カラムへタブ移動
*n
: ASCII コード n の文字出力
WRITE #,!,"Report",!
WRITE ?10,"Column 10",?30,"Column 30",!
5.3. READ — データの入力 (R
)
- プロンプト表示と変数への入力値の格納。タイムアウト指定も可能($TEST 参照)。
READ "Enter name: ",NAME
5.4. IF と ELSE — 条件分岐
5.5. ポスト条件 (Post-Conditionals)
5.6. FOR — 反復処理 (F
)
5.7. DO — サブルーチンの呼び出し (D
)
5.8. GOTO — コントロールの転送 (G
)
- ラベルへのジャンプ(戻る機能なし)。
GOTO LABEL
G ^ROUTINE
5.9. QUIT — サブルーチンからの戻りまたはループの終了 (Q
)
- FOR スコープ内:最も内側のループを終了。
- FOR スコープ外:サブルーチンを抜ける(スタック空ならプロセス終了)。
5.10. HALT と HANG
H
(アルギメントなし): HALT(プロセス終了)。
H
(アルギメントあり): HANG(秒数分の停止)。
5.11. XECUTE — 文字列をコードとして実行 (X
)
5.12. KILL — 変数の削除 (K
)
- Selective: 指定ノードと子ツリーを削除 (
KILL ^A(3)
)。
- Exclusive: 括弧内の除外を除く全ローカル変数を削除 (
KILL (KEEP1, KEEP2)
)。
- Argumentless: 全ローカル変数削除 (
KILL
)。
5.13. BREAK
6. 文字列関数
| 関数 | 略号 | 説明 |
|---|
$LENGTH
| $L
| 文字列の長さ (文字数) |
$EXTRACT
| $E
| 位置による部分抽出 (1 ベース) |
$PIECE
| $P
| デリミター分割による部分取得 |
$FIND
| $F
| 部分文字列の検索(マッチ後の位置を返す) |
$JUSTIFY
| $J
| 右揃え・整形・小数点指定 |
$ASCII
| $A
| ASCII コード取得 |
$CHAR
| $C
| ASCII コードから文字列への変換 |
$RANDOM
| $R
| 擬似ランダム整数生成 |
$SELECT
| $S
| 条件分岐(MUMPS 版 Ternary Operator) |
$TEXT
| $T
| ルーチン内のソース行取得 |
- 例:
SET X="ABCDE"
WRITE $L(X) ; 5
WRITE $E(X,2,4) ; BCD
WRITE $P("A^B", "^", 1) ; A
WRITE $J("Hi", 10) ; " Hi" (右揃え)
7. グローバルデータベース
7.1. グローバル変数
- 名前が
^
で始まる。プロセス終了後も残る(永続的)、全ユーザーで共有。
- スキーマ定義不要。構造は設定時の SET により決定される。
7.2. データモデルの構築
- 階層型ツリー (
^NODE(1,"A")="Val"
, ^NODE(1,"B")=
など) が自然に形成される。
- スキーマフリー: 構造は「最初のアシグメント」により作成される。
7.3. $DATA
— ノードの確認
7.4. $NEXT
— ツリーの上を移動 ($N
)
7.5. ネーキー参照 (Naked Reference)
^(1)
のように添字を省略した参照(ネーキーインジケータの使用)。
- 注意: 保守性の観点から、明示的な参照を推奨する。
8. 入力/出力
8.1. 出力の整形
$X
(カラム位置), $Y
(行位置) が自動更新される。
8.2. 特別変数 $X
と $Y
- ライン折り返し:
WRITE #,! ; フォームフィード後、$X, $Y はリセットされる
WRITE "A", ; $X=1, $Y=1
"BC", ; $X=2, $Y=1
WRITE ?10,"10" ; カーソルを 10 へ移動後、出力
8.3. デバイス入出力(概略)
OPEN
: デバイスの取得
USE
: 現在のデバイスの指定
CLOSE
: デバイスの解放
9. 間接参照 (Indirection)
@
オペレータを使って、式の結果をコード内の「変数名」や「サブスクリプト」に置き換える。
10. 特別変数
| 変数名 | 略号 | 説明 |
|---|
$HOROLOG
| $H
| 現在の日付と時刻(1840-12-31 より経過した日数と秒数) |
$IO
| $I
| 現在のデバイス識別子 (USE で変更) |
$JOB
| $J
| プロセス ID (一意の正整数) |
$STORAGE
| $S
| 利用可能なメモリサイズ |
$TEST
| $T
| IF/READ の結果 (0:偽, 1:真) |
$X
| - | 水平カーソル位置 |
$Y
| - | 垂直カーソル位置 |
11. ルーチンとプログラム構造
11.1. ルーチンの構成
- ファイル単位で保存/交換。
- ルーチン頭:
ROUTINE_NAME
(一行目)
- 本体: ラベル付きの命令列 (
LABEL CMD
)
- 終端マーカー:
CR LF
(行終了)、ファイル終了は CR FF
(ページ終了)。
11.2. ラインとラベル
11.3. エントリー参照 (Entry References)
DO LABEL
、^ROUTINE
、LABEL^ROUTINE
など。オフセット (+n
) も指定可能。
12. まとめる
電話帳アプリケーションの例:
- グローバル (
^PHONE
) でデータを永続化。
- READ/WRITE で UI を構築。
- DO/GOTO と IF/ELSE で分岐制御。
- FOR + $NEXT でデータベースを遍历。
MENU WRITE !,"Options: (A)dd (L)ookup (Q)uit",!
READ "Choice: ",CH QUIT:CH=""
IF CH="A" DO ADD GOTO MENU
IF CH="L" DO LOOKUP GOTO MENU
QUIT
13. コマンド参照表
| コマンド | 略号 | 説明 |
|---|
| BREAK | B | 実行停止 (シグナル待機) |
| CLOSE | C | デバイスの解放 |
| DO | D | サブルーチン呼び出し |
| ELSE | E | IF の代替処理(アルギメントなし) |
| FOR | F | ループ制御 |
| GOTO | G | ラベル転送 |
| HALT | H(無) | プロセス終了 |
| HANG | H(有) | 一時的停止 (秒数指定) |
| IF | I | 条件分岐 |
| KILL | K | 変数削除 |
| LOCK | L | リソースロック |
| OPEN | O | デバイス取得 |
| QUIT | Q | サブルーチン終了/ループ抜ける |
| READ | R | 入力 |
| SET | S | 変数設定 |
| USE | U | デバイス指定 |
| VIEW | V | (実装依存) |
| WRITE | W | 出力 |
| XECUTE | X | コード実行 |
(詳細な構文と例は前章を参照)
14. 関数参照表
| 関数 | 略号 | 説明 |
|---|
| $ASCII | $A | ASCII コード取得 |
| $CHAR | $C | 文字列から変換 |
| $DATA | $D | ノード状態確認 (0,1,10,11) |
| $EXTRACT | $E | 部分文字列抽出 |
| $FIND | $F | 部分文字列検索位置 |
| $JUSTIFY | $J | 右揃え・整形 |
| $LENGTH | $L | 文字数カウント |
| $NEXT | $N | 次のサブスクリプト値 |
| $PIECE | $P | デリミター分割 |
| $RANDOM | $R | ランダム数生成 |
| $SELECT | $S | 条件分岐 |
| $TEXT | $T | ソース行取得 |
15. 特別変数参照表
| $HOROLOG | $H | 日付時刻(Epoch: 1840-12-31) |
|---|
| $IO | $I | カレントデバイス |
| $JOB | $J | プロセス ID |
| $STORAGE | $S | 利用可能なスペース |
| $TEST | $T | 最後に評価された結果 (0/1) |
| $X | - | 水平カーソル位置 |
| $Y | - | 垂直カーソル位置 |
16. オペレータ参照表
16.1. 一元演算子(右結合)
| オペレータ | 名前 | 説明 |
|---|
+
| PLUS | 数値解釈 |
-
| MINUS | 符号逆転 |
'
| NOT | 論理否定 (0 →1 ) |
16.2. 二元演算子(左から右)
- 算術:
+
, -
, *
, /
, \
(整数除算), #
(剰余)
- 文字列:
_
(連結)
- 関係:
=
, <
, >
, ]
, [
, ?
- 論理:
&
(AND), !
(OR), '&
(NAND), `'!' (NOR)
17. 構文要約
17.1. ライン構造
[ラベル] スペース コマンド アルギメント スペース コメント ;
- コマンド間: 単一スペース。
- アルギメントなしコマンド: 次のコマンドの前には二つのスペース。
17.2. ルーチン構造
ROUTINENAME
LABEL CMD ...
HALT
- 第一行はルーチン名のみ(
routinename eol
)。
17.3. ネーム構文
(%|alpha)(alpha|digit)*
17.4. 変数構文
- ローカル:
name
または name(添字)
- グローバル:
^name
, ^name(添字)
, ^(添字)
(ネーキー参照)
17.5. リテラル構文
- 数値:
[数字].[数字]E[+/-]数字
- 文字列:
"内容"
(内部の " は "" で表す)。
補遺 A: ASCII コード表
印字可能文字 (32-126)
| コード | 文字 | コード | 文字 |
|---|
32
| 48 0
| 64 @
| 80 P
|
| ... (略) | | | |
122 z
| | | |
コントロール文字 (0-31, 127)
- BEL (7): ビープ音
- LF (10): カーソル移動
- FF (12): ページ送り (
#
)
- CR (13): 改行 (
!
の一部)
補遺 B: 用語集
- グローバル変数: ディスク上に永続化され、プロセス間で共有される階層データ。
- ネーキーインジケータ: 最後に参照したグローバルの変数名と添字を隠して保持し、以後の参照を簡略化する仕組み(保守性の観点から推奨されない)。
- ラベル: ラインの識別子 (
DO
, GOTO
の対象)。
- エントリー参照: 制御先を指定する式 (
^ROUTINE
, LABEL
).