 |
≫ |
|
|
 |
名称bs ― 中規模の大きさのプログラム用のコンパイラ/インタプリタ 説明bs は、一部の C 言語が追加された BASIC および
SNOBOL4 の系列です。 bs は、プログラム開発時間がプログラムの実行スピードと同程度に重要な場合、そのタスクプログラミングを目的として設計されています。データ宣言の形式とファイル/プロセス操作は最小限にされています。1 行デバッギング、 trace および dump 文、および有効な実行時エラーメッセージにより、プログラムテストは単純になります。さらに、不完全なプログラムをデバッグすることもできます。つまり、 外側の 関数が作成される前に、 内側の 関数をテストすることができます。また、その逆も可能です。 file をコマンド行で指定すると、キーボードから入力が読み取られる前に、そのファイルが入力に使用されます。デフォルトでは、 file から読み取られた文は、後の実行のためにコンパイルされます。また、通常、キーボードから入力された文は、即座に実行されます (下記の compile および execute を参照)。
最後の操作が代入でない限り、即座に文の結果がプリントされます。 bs プログラムは入力行で構成されます。 行の最後の文字が \ ならば、行は続行します。 bs は、以下の形式で行を受け付けます。 statement label statement ラベルは、後にコロンが付いた name (以下を参照) です。 ラベルと変数は、同じ名前にすることができます。 bs 文は、式またはゼロ以上の式につづくキーワードです。
いくつかのキーワード (clear, compile, !, execute, include, ibase, obase, run)
は、つねにコンパイル時に実行されます。 文の構文| expression | | 式の実行結果を他の処理に使います (値、代入、または関数呼び出し)。
式の詳細については、以下の文のタイプの説明の後に示します。 | | break | | break は最も内部の for/while ループを終了します。 | | clear | | シンボルテーブルとコンパイル済みの文をクリアします。 clear は即座に実行されます。 | | compile [expression] | | | | 連続した文がコンパイルされます (即時の実行というデフォルトにオーバライドします)。
オプションの式が評価され、以降の入力のファイル名として使用されます。
後者の場合には clear が伴います。 compile は即座に実行されます。 | | continue | | continue は、現在の for/while ループのループ継続に移行します。 | | dump [name] | | 各非ローカル変数の名前と現在の値がプリントされます。
オプションにより、指定した変数だけがレポートされます。 エラーまたは割込み後に、最後の文の数が表示されます。
ユーザー関数のトレースは、関数で発生したエラーまたは stop の後に表示されます。 | | edit | | 呼び出しは、 EDITOR 環境変数が存在する場合には、それによって選択されるエディタに対して、 EDITOR が不定またはヌルならば ed(1) に対して行われます。 file 引き数がコマンド行にあれば、 file は、エディットするファイルとしてエディタに渡されます
(引き数が存在しなければ、ファイル名は使用されません)。 エディタを終了すると、そのファイル名を引き数として、 compile 文 (および、それに伴う clear ) が、実行されます。 | | exit [expression] | | | | システムレベルに戻ります。 式はプロセスステータスとして戻されます。 | | execute | | 即時実行モードに変わります (割込みには同様の効果があります)。 この文によって、ストアされた文が実行されることはありません (以下の run を参照)。 | | for name = expression expression statement | | | | | | for name = expression expression | | | | | | ... | | | | next | | | | for expression , expression , expression statement | | | | | | for expression , expression , expression | | | | | | ... | | | | next | | for 文は、指定した変数の制御下で、1 つの文 (第 1 の形式) または文のグループ (第 2 の形式) を繰り返し実行します。
変数は最初の式の値となり、 第 2 式の値を超えないように、各ループごとに 1 増分されます。
第 3 および第 4 の形式には、コンマで区切った 3 つの式が必要です。 3 つの式の第 1 は初期化であり、第 2 はテスト (真の場合に続行する) であり、第 3 はループ継続アクション (通常は増分) です。 | | fun f([a, ...]) [v, ...] | | | | | | ... | | | | nuf | | fun は、ユーザーが作成した関数に対して関数名、引き数、およびローカル変数を定義します。最大 10 個までの引き数とローカル変数を指定できます。これらの名前は配列とすることはできず、また
I/O と対応付けることもできません。 関数定義はネストできません。
未定義の関数の呼び出しは許されます。 以下の関数呼び出しを参照してください。 | | freturn | | ユーザーが作成した関数の失敗を示す方法。 以下の質問演算子
(?) を参照してください。 質問がなければ、 freturn はゼロに戻ります。
質問 が アクティブな場合、 freturn はその式に移行します (バイパスする中間関数が戻ります)。 | | goto name | | 内部ストアされた文の内でラベルが一致する文に制御を移します。 | | ibase n | | ibase は入力ベース (基数) を n に設定します。 n をサポートする値は、定数 8, 10 (デフォルト)、および 16 だけです。
16 進値 10〜15 は a-f として入力されます。
先行桁が必要です (つまり、 f0a は 0f0a として入力しなければなりません)。 ibase (および以下に説明する obase ) は即座に実行されます。 | | if expression statement | | | | | | if expression | | | | ... | | | | [else...] | | | | fi | | 式が非ゼロの評価値になる場合、文 (最初の形式) または文のグループ (第 2 の形式) が実行されます。
文字列 0 および""(ヌル) はゼロとして評価します。
第 2 の形式では、オプションの else は、最初のグループが実行されず、第 2 グループの文が実行されることを示します。 else と同じ行に認められる文は if だけです。他の fi だけを fi と同じ行に入れることができます。 else および if の elif への連結はサポートされます。 if ... elif ...
[ else ... ] シーケンスをクローズするには、単一の fi だけが必要です。 | | include expression | | | | expression は必ずファイル名の評価値になるので、 このファイルには bs ソース文を入れなければなりません。
このような文は、コンパイル対象のプログラムの一部になります。 include 文はネストできません。 | | obase n | | obase は出力ベースを n に設定します (上記の ibase を参照)。 | | onintr label | | | | onintr | | 割込みのプログラム制御ができます。 最初の形式では、制御は、 onintr の実行中に goto が実行された場合と同様に、与えられたラベルに渡されます。
文の効果は、それぞれの割込み後にクリアされます。 第 2 の形式では、割込みで、 bs が終了します。 | | return [expression] | | | | 式を評価し、結果を関数呼び出しの値として返します。
式を与えなければ、ゼロを返します。 | | run | | 乱数ジェネレータをリセットします。 制御は最初の内部文に渡されます。 run 文がファイルに含まれる場合は、それを最後の文にしなければなりません。 | | stop | | 内部文の実行を停止します。 bs は即時モードに戻ります。 | | trace [expression] | | | | trace 文は関数トレーシングを制御します。
式がヌルである (または、ゼロの評価値になる) 場合には、トレーシングはオフになります。
それ以外の場合には、ユーザー関数呼び出し/戻りの記録が表示されます。
各 return ごとに trace expression 値を減分します。 | | while expression statement | | | | | | while expression | | | | ... | | | | next | | while は for と同様ですが、ループ継続の条件式のみが与えらます。 | | ! shell command | | シェルへの即座のエスケープ。 | | # ... | | この文は無視されます (コメントとして処理されます)。 |
式の構文| name | | 名前は変数の指定に使用します。 名前は、1 文字の英字 (大文字または小文字)、オプションにより英字や数字がその後につづきます。
名前の最初の 6 文字だけが有効です。 fun 文で宣言される名前を除いて、名前はすべてプログラムではグローバルです。
名前は、数値 (倍精度実数型)、文字列に付けるか、または入出力に対応させることができます (以下の組込み関数 open () を参照)。 | | name ( [expression [ , expression] ... ] ) | | | | 名前とその後のかっこで囲んでコンマで区切った引き数によって、関数を呼び出すことができます。
組込み関数 (以下にリストがあります) を除いて、 名前は fun 文で定義しなければなりません。 関数への引き数は値で渡されます。
関数がまだ定義されていなければ、その関数の呼び出し履歴が表示され、式としての戻り値を要求します。
その式の結果は、未定義の関数の結果であるものと見なされます。 これにより、必ずしもすべての関数がまだ定義されていなくても、プログラムのデバッギングが可能です。
値は現在の入力ファイルから読み取られます。 | | name [ expression [ , expression ] ... ] | | | | この構文を使用して配列またはテーブルのいずれかを参照します
(以下の組込みの table 関数を参照)。 配列については、それぞれの式は整数に切り捨てられ、名前の指定子として使用されます。生成される配列参照は、構文で言えば名前と同じです。 a[1, 2] は a[1][2] と同じです。
式は、0 から 32767 までの値に制限され切り捨てられます。 | | number | | 数値は、定数値を表すのに使用します。 数値は Fortran スタイルで書きます。また、数値は
数字とオプションの小数点、そして場合によっては e とそれにつづくおそらく符号付きの指数からなるスケールファクタで構成されます。 | | string | | 文字列は " 文字で区切ります。 \ エスケープ文字を使って、文字列に現れる二重引用符 (\ "),改行 (\n), キャリッジリターン
(\r), バックスペース
(\b), タブ (\t)
文字を文字列に入れることができます。 それ以外の場合は、 \ はそれ自体の意味を表します。 | | ( expression ) | | 小かっこは、通常の評価の順序を変更するのに使用します。 | | ( expression , expression [ , expression ...
] ) [ expression ] | | | | 大かっこで囲まれた式は、小かっこで囲まれたリストからコンマで区切られた式を選択するための添え字として使用されます。リスト要素は、ゼロから始めて左から番号をつけられます。 次の式には、比較が真ならば値 True が入ります。 ( False, True )[ a == b ] | | ? expression | | 質問演算子は、その値ではなく式が正常終了するかどうかのテストを行います。
今のところ、これは、ファイルの最後 (以下の プログラミングのヒント の項の例を参照) と eval 組込み関数の結果のテストや、ユーザー作成の関数 ( freturn を参照) からの戻りをチェックする際に便利です。
一定の条件 (ファイルの最後など) により、 即座に最新の質問に移り、代入文または介在する関数レベルをスキップすることができます。 | | - expression | | 結果が式の否定となります。 | | ++ name | | 変数 (または配列参照) の値を増分します。 結果は新しい値になります。 | | -- name | | 変数の値を減分します。 結果は新しい値になります。 | | !expression | | 式の論理否定です。シェルエスケープ コマンドを監視します。 | | exression | | ふたつの引き数の operator 式 の共通関数を短縮するには、ふたつの引き数の間に関数を表す演算子を入れます。
代入割当て、連結、および関係演算子を除いて、オペランドは両方とも関数の適用前に数値形式に変換されます。 |
2 項演算子 (優先順位が高くなる順)| = | | = は代入演算子です。 左のオペランドは、名前または配列要素になります。
結果は右のオペランドです。 代入は右から左に設定され、その他すべての演算子は左から右に設定されます。 | | _ | | _ (アンダースコア) は連結演算子です。 | | & | | | & (論理 AND) は、その引き数のいずれかがゼロならば、結果がゼロになります。
その引き数が両方とも非ゼロならば、結果が 1 になります。 | (論理
OR) は、その引き数が両方ともゼロならば、結果がゼロになります。 その引き数のいずれかが非ゼロならば、結果が 1 になります。
どちらの演算子もヌル文字列をゼロとして処理します。 | | < <= > >= == != | | 関係演算子 (<: 小なり、 <=:
以下、 >: 大なり、 >=: 以上、 ==:
等しい、 !=: 等しくない) は、引き数が指定された関係にあれば、1 を返し、そうでなければ、0 を返します。
同レベルの関係演算子は次のように展開します。 a>b>c は、 a>b & b>c と等価です。両方のオペランドが文字列ならば、文字列の比較が行われます。 | | + - | | 加算と減算を行います。 | | * / % | | 乗算、除算、および剰余計算を行います。 | | ^ | | 指数化 |
組込み関数引数の扱い| arg(i) | | 関数呼び出しの現在のレベルで i-th の実際のパラメータ値です。 レベルゼロで、 arg は i-th コマンド行引き数 を返します arg(0) は bs を返します)。 | | narg() | | 渡される引き数の数を返します。 レベルゼロで、コマンド引き数カウントが返されます。 |
数学演算| abs(x) | | x の絶対値です。 | | atan(x) | | x のアークタンジェントです。 その値は、-π/2 と π/2 の間です。 | | ceil(x) | | x 以上の最小整数を返します。 | | cos(x) | | x (ラジアン) のコサインです。 | | exp(x) | | x の指数関数です。 | | floor(x) | | x 未満の最大整数を返します。 | | log(x) | | x の自然対数です。 | | rand() | | ゼロと 1 の間で均等に分散した乱数です。 | | sin(x) | | x (ラジアン) のサインです。 | | sqrt(x) | | x の平方根です。 |
文字列演算| size(s) | | s のサイズ (バイト単位の長さ) が返されます。 | | format(f, a) | | a のフォーマット済みの値を返します。 f は printf(3S) スタイルのフォーマット指定であると仮定します。 %...f, %...e,
および %...s タイプのみが確かです。 format 呼び出しがコーディングされる際に a が数値であるか、文字列であるかの判定が常に可能であるとは限りません。ですから、( e または f フォーマット用に) ゼロを加算するか、または ( s フォーマット用に)
(_) ヌル文字列を連結して、 強制的に a を f に必要なタイプにする検討をしてください。 | | index(x, y) | | y からの文字のいずれかが一致する x の最初の位置の数を返します。 一致しなければ、ゼロになります。 | | trans(s, f, t) | | f の一致する文字から、ソース s の文字を、 t の同じ位置の文字に変換します。 f に現れないソース文字は結果にコピーされます。 文字列 f が t よりも長いと、 f の超過部分で一致するソース文字は結果に表示されません。 | | substr(s, start, width) | | | | 開始 位置、および width の定義する s の部分文字列を返します。 | | match(string, pattern) | | | | mstring(n) pattern は、基本正規表現の定義に従った正規表現です ( regexp(5) を参照)。 mstring は、 match への最新呼び出しで、パターンシンボル \( および \) のペアの間にあった n-th (1 <= n <= 10) 部分文字列を返します。 正常終了には、パターンは (すべてのパターンが ^ で始まるかのように) 文字列の先頭に一致しなければなりません。
関数は、一致した文字数を返します。 例えば match("a123ab123", ".*\([a-z]\)") == 6 mstring(1) == "b" |
ファイル処理| open(name, file, function) | | | | | | close(name) | | name 引き数は bs 変数名でなければなりません (文字列として渡されます)。 open については、 file 引き数は次のようになります。 | 1. | | 0(ゼロ)、1、または 2 はそれぞれ標準入力、出力、またはエラー出力を表します。 | | 2. | | 文字列はファイル名を表します。または、 | | 3. | | ! で始まる文字列は ( sh
-c によって)、実行するコマンドを表します。 function 引き数は、 r (読み取り)、 w (書き込み)、 W (改行なしの書き込み)、または a (追加) のいずれかでなければなりません。 close の後に、 name は通常の変数状態に戻ります。 name がパイプであった場合は、クローズの完了前に wait() が実行されます ( wait(2) を参照)。 bs exit コマンドでは、このような待機は行いません。
初期の対応づけは次のとおりです。 open("get", 0, "r") open("put", 1, "w") open("puterr", 2, "w") 例は次項で示します。 |
| | access(s, m) | | access() を実行します ( access(2) を参照)。 | | ftype(s) | | 次の 1 文字のファイルタイプ表示を返します。 通常ファイルには f , FIFO
(つまり名前付きパイプ) には p , ディレクトリには d , ブロック型スペシャルには b , またはキャラクタ型スペシャルには c となります。 |
テーブル| table(name, size) | | | | bs におけるテーブルは、結合的にアクセスされる 1 次元配列です。
「添字」(キーという) は文字列です (数値は変換されます)。 name 引き数は bs 変数名でなければなりません (文字列として渡されます)。 size 引き数は、割り振る要素の最小数を設定します。 bs は、テーブルオーバフロー時にエラーメッセージをプリントして停止します。 table の結果は name です。 | | item(name, i) | | | | key() | | item 関数は連続的にテーブル要素にアクセスします
(通常の使用では、キー値は規則どおりに進行しません)。 item 関数が値にアクセスする場合、 key 関数は前の item 呼び出しの「添え字」にアクセスします。
前の item 呼び出しに有効な添え字がなかった場合、異常終了します (あるいは、 質問演算子 がない場合、ヌルを返します)。 name 引き数は引用符で囲まないでください。 正確なテーブルサイズは定義されないため、質問演算子はテーブルの終端の検出に使用してください。
例えば、 table("t", 100) ... # If word contains "party", the following expression adds one # to the count of that word: ++t[word] ... # To print out the the key/value pairs: for i = 0, ?(s = item(t, i)), ++i if key() put = key()_":"_s 質問演算子を使用しない場合、テーブルにこれ以上の要素がなければ、 item の結果はヌルです。ただし、ヌルは正当な「添え字」です。 | | iskey(name, word) | | | | iskey は、キー word がテーブル name にあるかどうか判断し、ある場合には 1、ない場合には 0 を返します。 |
その他| eval(s) | | 文字列引き数は bs 式として評価されます。
この関数は、数値文字列を数値内部形式に変換するのに便利です。 eval は、次のように、間接的な形としても使用できます。 name = "xyz" eval("++"_ name) これは、変数 xyz を増やします。 さらに、前に質問演算子がある eval で、(ユーザーは) bs エラー状態を制御できます。
例えば ?eval("open(\"X\", \"XXX\", \"r\")") は、 XXX という名前のファイルがなければ、
(ユーザーのプログラム停止) 値ゼロを返します。 次の指定では、 ラベル L (存在すれば) に対して goto を実行します。 label="L" if !(?eval("goto "_ label)) puterr = "no label" | | plot(request, args) | | | | tplot コマンドが利用できれば、 plot 関数は tplot で認識されるデバイスに出力します。 requests は次のとおりです。 | 呼び出し | | 機能 | | plot(0, term) | | これ以降の plot 出力が、 -Tterm. の引き数で tplot にパイプ接続されます。 term の長さは最大 40 文字です。 | | plot(1) | | プロッタ画面を「消去」します。 | | plot(2, string) | | string で、現在位置にラベルを付けます。 | | plot(3, x1, y1, x2, y2) | | | | x1,y1) と x2,y2) の間に線を引きます。 | | plot(4, x, y, r) | | 中心 x,y) および半径 r で円を描画します。 | | plot(5, x1, y1, x2, y2, x3, y3) | | | | 中心 x1,y1), 両端 x2,y2) および x3,y3) で (左回りの) 円弧を描画します。 | | plot(6) | | これは使用できません。 | | plot(7, x, y) | | 現在位置を x,y) にします。 | | plot(8, x, y) | | 現在位置から x,y) に線を引きます。 | | plot(9, x, y) | | x,y) に点を描画します。 | | plot(10, string) | | 行モードを string に設定します。 | | plot(11, x1, y1, x2, y2) | | | | x1,y1) をプロット領域の左下のコーナーにし、 x2,y2) をプロット領域の右上コーナーとします。 | | plot(12, x1, y1, x2, y2) | | | | プロットされる前に、続く x(y) 座標が x1 y1) で乗算され、次に x2 y2) に加算されます。 初期スケーリングは plot(12,
1.0, 1.0, 0.0, 0.0) です。 |
要求によっては、すべてのプロッタに適用されません。 0 と 12 を除いたすべての要求は、文字を tplot にパイプ接続することにより実行されます。 ピクチャの描画が一回の操作で完了しない場合、 キーボードから実行される各文により、 tplot が再び呼び出され、結果が予測できない状態になります。
したがって、単一のストリームですべての出力を tplot に向けられるように、
プロットは、関数または完全なプログラムで行わなければなりません。 | | last() | | 直接モードでは、 last は、最後に計算された値を返します。 |
多言語化対応環境変数LC_COLLATE により、正規表現を評価する際に使用される照合順序を決定します。 LC_CTYPE は、正規表現において、文字クラス式によって照合される文字を決定します。 LC_COLLATE または LC_CTYPE が (現在使用している) 環境で指定されていなかったり、 空の文字列に設定されている場合、 LANG の値がその変数のデフォルトとして用いられます。 LANG が指定されていなかったり、空の文字列の場合、"C"のデフォルト
( lang(5) 参照) が LANG の値として使われます。
いずれかの多言語化対応変数の設定が不適当な場合、 bs はすべての多言語化対応変数が
"C" に設定されるものとして動作します。 environ(5) を参照してください。 サポートされるコードセットシングルバイトの文字コードセットがサポートされています。 例電卓 として bs を使用するとします。 ($ はシェルプロンプト) $ bs # Distance (inches) light travels in a nanosecond. 186000 * 5280 * 12 / 1e9 11.78496 ... # Compound interest (6% for 5 years on $1,000). int = .06 / 4 bal = 1000 for i = 1 5*4 bal = bal + bal*int bal - 1000 346.855007 ... exit 代表的な bs プログラムの概要は次のとおりです。 # initialize things: var1 = 1 open("read", "infile", "r") ... # compute: while ?(str = read) ... next # clean up: close("read") ... # last statement executed (exit or stop): exit # last input line: run 入出力の例は次のとおりです。 # Copy file oldfile to file newfile. open("read", "oldfile", "r") open("write", "newfile", "w") ... while ?(write = read) ... # close "read" and "write": close("read") close("write") # Pipe between commands. open("ls", "!ls *", "r") open("pr", "!pr -2 -h 'List'", "w") while ?(pr = ls) ... ... # be sure to close (wait for) these: close("ls") close("pr") 警告グラフィックスモード (plot ...)
は、 tplot コマンドがシステムで利用可能でない限り、 特に有効ではありません。 bs は、一部のエラーに対しては許容しません。
例えば、 fun 宣言をミスタイプすると ( clear を行わずに新しい定義を行うことができないため)、訂正が困難です。
この場合の解決法としては、 edit コマンドを使って起動するのがよいでしょう。 参照ed(1), sh(1), access(2), printf(3S), stdio(3S), lang(5), regexp(5) 数学関数の詳細については、Section (3M) を参照してください。 pow() は、指数化に使用します ( exp(3M) を参照)。 bs は標準 I/O パッケージを使用します。
|