実数型コンパイラREALをひと言でいうと,「SLANGを実数対応にして,再帰をできなくしたもの」ということになります。SLANGと共通の特徴を簡単に説明しますと,ディスク上のASCIIファイルまたはメモリ上のソースプログラム(テープの場合はいったんメモリに読み込んでから)をコンパイルして,オプジェクトをメモリ上に出力する1パスのコンパイラで,ランタイムルーチンはオブジェクトの先頭にリロケートして出力されます。C言語のようにすべての処理は関数の形で記述し,変数や配列は大域的なものと局所的なものの2種類使えます。間接変数を使って「ポインタもどき」くらいは可能ですし.もちろんメモリやI/O,特殊ワークエリアを配列の形で直接アクセスしたり,マシン語やデータを直接オブジェクトに落とすこともできます。その他,関数名や変数名などにシフトJISの漢字を使用可能,ディスク使用時には#INCLUDEによるファイルの取り込みが可能,などとなっています。SLANGと異なるのは,おおよそ以下のようなことです。その他,細かいことについてはマニュアルを参照してください。
SLANGで扱えたのは整数型のみでしたが,REALではINT型(整数型)とREAL型(実数型)の2種類を扱えます。REAL型はプログラムの先頭で,アドレス宣言のSINGLE宣言かDOUBLE宣言によって,単精度か倍精度のどちらか一方を選びます。プログラム中で単精度実数と倍精度実数を同時に扱うことはできません。デフォルトは倍精度になっていますので,なにも宣言しないと倍精度になります。
INT型はSLANG同様符号なし整数値を扱いますが,自動的にREAL型に変換したり,REAL型からINT型に変換する場合は,符号付き整数値として処理しています。言語としては「美しくない」ものになってしまい,最後の最後まで迷ったのですが,実用性を考えてあえてこうしました。もちろん,符号なし整数値としてREAL型との変換を行う演算子も用意しでありますが,その一方でメモリ不足のため,整数型のデータを符号付きで演算するピリオド演算子をカットしてしまい,片手落ちとなっています。なんとかうまく使いこなしてやってください。
コンパイル時と実行時のどちらも,浮動小数点演算パッケージSOROBANが必要です(実数を全然使っていないときでも必要)。コンパイル時にもSOROBANを利用していますので,オブジェクトがSOROBANと重なってはいけません(「OUT
OF MEMORY!」のエラーになります)。SOROBANは1989年4月号の新型ローダ(配布ディスクに収録:LOADER)を使って読み込んでください。コンパイルと実行を続けて行う場合は,実行時に改めてSOROBANを読み込む必要はないでしょう。また,コンパイル時と実行時でSOROBANが同じアドレスにないといけません。実行時はランタイムルーチンでSOROBANのアドレスをチェックし,コンパイル時のアドレスと異なっていたらなにもしないで終了してしまいます。
C言語でいうプロトタイプ宣言が導入されました(というより必要になったのですが)。その時点で未定義の(後ろのほうで定義してある)関数を呼び出す場合1パスのコンパイラにはその関数や引数の型がわかりません。SLANGでは関数や引数の型はすべて整数型と決まっていましたから処理を続けることができましたが,REALではINT型とREAL型の2種類の型がありますからそういうわけにはいきません。そこでプログラムの頭のほうで,関数の型や引数の型と数を宣言しておこうというのがプロトタイプ宣言です。REALではDECLARE宣言(宣言宣言?意味不明ですね)といいます。コンパイラはこれを参照して関数の型を知り,引数の型や数のチェックをします。もちろん,関数呼び出し時にすでに定義しである関数は,宣言をする必要はありません。
SLANGでは引数や局所変数を動的にメモリ上に取りますから再帰が可能でしたが,REALでは引数や変数などをすべて静的にメモリ上に割り当てますので,再帰ができなくなっています。再帰は,その関数自身を直接または間接的に呼び出す機能ですが,呼び出すたびに局所的な変数などが保存されなくてはなりません。あれば便利な機能ですが,これを削ったおかげでREALが完成したようなものですから,勘弁してください。
その代わり,変数の値をスタックに一時的に保存する関数としてPUSH()とPOP()を追加しました。配列などは保存できませんが,これを利用すればなんとか再帰を実現できると思います。ただし,スタックはプログラムで使用しているスタックですので,使い方を間違えるといとも簡単に暴走するはずです。注意してください。
残念ながら整数型のデータを扱う場合,REALの実行速度はSLANGに比べるとやや遅くなっています。一例を挙げますと,100回ループの「エラトステネスのふるい」で,SLANGの137秒に対して,REALは158秒となっています。整数型のデータを扱う処理ではSLANGとまるで同じ処理をしていますので,SLANGとまったく同じ実行速度を得ることが可能だったのですが,メモリ不足のため最適化の処理部が入りきらず実現できませんでした。
実数型のデータを扱う処理では,一切最適化を考えていません。「実数を手経に扱える」ことだけを考えて設計しました(実行速度は二の次)。もっともREALの実数の実行速度が遅いとしたら,8割方はSOROBANの責任でしょう(結局みんな私の責任だったりする)。おそらく実行速度はSLANGで実数演算ライブラリを使用したときとたいして変わりがないと思います。
配列の宣言(ARRAY宣言)で要素数の指定がC言語に準じたものになりました。例を挙げると,
とすると,SLANGではA[0]からA[3]までの4個の配列が用意されましたが,REALではA[0]からA[2]までの3個が用意されます。注意してください。
IF文などの条件式にはカッコが必要になりました。また,MACHINE関数ではスタックを利用した方法がなくなりました。すべてレジスタを使って引数を渡します。
配布ディスクに収録されているオブジェクトはディスク版ですから,テープやQDを使用する場合は$3005の内容を$00に書き換えてください。ソースプログラムは別のエディタで作成し,デバイス上に保存してください。次に,REAL起動前に,ローダを使ってSOROBANを読み込んでおきます。起動の際は,コールドスタートアドレス(3000H)をコールします。ホットスタートアドレス(3003H)なら大域表の内容が保存されています(REALがメモリ上にあった場合)。起動するとコマンドモードになりますので,Cコマンドを使ってデバイス上やメモリ上のソースプログラムをコンパイルしてください。
●C ファイル名
ソースファイルをコンパイルする。ファイル名を省略した場合はメモリ上のソースをコンパイルする。Cの後ろに/を加えると,ソースリストを表示しながらコンパイルする。
●S ファイル名:nn1:nn2 [:nn3:[nn4]]
オブジェクトをセーブする。[ ]内は省略可を表わす。nn1~nn4はそれぞれ先頭,最終,実行,格納アドレスを表し,オフセットをつけない場合はnn4を省略する。
●X nn
ソースを格納するアドレスをnnに変更する。メモリ上にあるソーステキストをコンパイルする場合はこのコマンドでアドレスを指定する。
●O
定義された大域的な名前と,その値を出力する。
●D デバイス名:
ディレクトリを表示する。
●DV デバイス名:
デフォルトデバイスを変更する。
●Jnn
アドレスnnをコールする。
●!
S-OSのモニタにジャンプする。
●M
各機種のモニタにジャンプする。 |
|
●オンメモリ版 |
|
0000H |
3000H
|
7000H
|
B000H
|
#MEMAX |
|
S-OS |
REAL |
ソース
プログラム
|
オブジェクト
コード |
SOROBAN |
|
|
|
|
|
●ディスク版 |
|
3000H
|
7000H
|
8000H
|
B000H
|
#MEMAX
|
|
REAL
|
クラスタBUFF
|
|
オブジェクト
コード |
SOROBAN |
|
|
|
●S-OS特殊ワークエリア |
0000H
|
0100H
|
0300H
|
0400H
|
0800H |
|
|
|
|
定数表:文字列定数やREAL型の定数値をバッファリングする。
関数表:関数の引数の型や数を記録する。
局所表:局所的な名前の表。ブロックごとに初期化される。
ハッシュ表:大域表のためのハッシュ表
大域表:大域的な名前の表。他の4つの表の残りが表の大きさとなる。
*1 TEXT_TOPの初期値。変更可。
*2 OBJ初期値の初期値。変更可。
*3 SOROBANはソースやオブジェクトと重ならなければどこでもよい。
*4 クラスタBUFFの初期値。変更可。
*5 OBJ初期値の初期値。変更可。8000Hにするとよい。
*6 SOROBANはオブジェクトと重ならなければどこでもよい。
起動前に以下の値を書き換えておくことにより,作成するプログラムに合わせてワークエリア等を設定することが可能。
●$3005 (1バイト) [DISK] 初期値:01
00:オンメモリ版
01:ディスク版 ●3006H (2バイト) [OBJ初期値] 初期値:B000H
オブジェクトコードを生成する先頭アドレス。 ORG宣言を省略した場合に使用される(ディスク版の場合8000Hに)。 ●3008H (2バイト) [ランタイム最終ADR]
ランタイムルーチンの最終アドレス。ランタイムルーチンを追加した場合変更する。 ●300AH (2バイト) [クラスタBUFF] 初期値:7000H
ディスク版でソーステキストを読み込むための4Kバイトのバッファの先頭アドレス。 ●300CH (2バイト) [TEXT_TOP] 初期値:7000H
オンメモリ版でソーステキストを格納する先頭アドレス。
●300EH (2バイト) [定数表SIZE] 初期値:0100H
S-OS特殊ワークエリア上に取られる定数表のサイズ。 ●3010H (2バイト) [関数WKSIZE] 初期値:0200H
S-OS特殊ワークエリア上に取られる関数表のサイズ。
●3012H (2バイト) [局所表SIZE] 初期値:0100H S-OS特殊ワークエリア上に取られる局所表のサイズ。
●3014H (2バイト) [ハッシュ表SIZE] 初 期 値:0400H
S-OS特殊ワークエリア上に取られるハッシュ表のサイズ。
●3016H (1バイト) [BAT対応] 初期値:01
00:S-OSがバッチ処浬に対応していない。
01:S-OSがバッチ処理に対応している。 |
英文字(アルファベット,漢字,@,^)で始まり,英文字か数字からなる文字列。アルファベットの大文字と小文字の区別はしない。関数名,変数名,配列名,記号定数名,ラベルはすべてこの文字列からなる。
基本的にはC言語のようにフリーフォーマットで行の概念はなく,名前の途中以外どこで区切ってもよいが,例外がある。
・//コメント //以降はコメントとみなされ,その行の終わリまで無視される。
・“文字列” 2行にまたがることはできない。
・配列 配列名と[の間を空白などで区切ることはできない。
・関数 関数名と(の間を空白などで区切ることはできない。
空白は名前の途中と配列の[および関数の(の前以外ならどこに置いてもよい 。改行,コメント,#コマンドは空白と同等である。
注釈文。空白が置けるところなら,どこに置いてもよい。
//コメント //から行の終わりまで。
/*コメント*/ /*から */まで。ネスティング不可。
(*コメント*) (*から*)まで。ネスティング不可。
コンパイラに対する命令。空白が置けるところなら,どこに置いてもよい。
別のソースをその場所に取り込む。ネスティング不可。ファイルネーム以降は行の終わりまで無視される。オンメモリ版では使用できない。
続きのソースを読み込む。ファイルネーム以降はすべて無視される。オンメモリ版の場合,準備がよいかどうか聞いてくるので,なにかキーを押すと読み込みを始める。BREAKキーを仰すとコンパイルを中止する。
・#IF INT型定数式
#ELSE
#ENDIF
条件付コンパイルを行う。#IFの後ろの式が真(0以外)ならば#IFから#ELSEまでを,偽(0)ならば#ELSEから#ENDIFまでをコンパイルする。ただし,必ず行の先頭になければならない。#ELSEはなくてもよい。ネスティング不可。
型は基本的にはINT型とREAL型の2種類のみである。ただし,配列にはCHAR型とINT型とREAL型の3種類,関数にはVOID型とINT型とREAL型の3種類がある。
データは5バイト(単精度)または8バイト(倍精度)で表される実数値。SINGLE宣言がされれば単精度で,DOUBLE宣言がされれば倍精度で処理される。
データは2バイトで0から65535までの符号なし整数値。
配列のみにある型。データは1バイトで表される0から255までの整数値。
●CHAR型は自動的にINT型に変換してから演算を行う。
●INT型とREAL型との演算では自動的にINT型の値をREAL型に変換してから演算を行う。
●INT型は符号なし整数型だがREAL型に変換する場合は,符号付き整数値とみなして実数値に変換する。また,逆にREAL型からINT型に変換する場合は,実数値を符号付き整数値に変換する。
●関数の引数では,自動的な型変換は行わず型チェックのみ行う。
●MACHINE関数とPRINT関数の引数では,自動的な型変換も型チェックも行わない。
●RETURN文で値を返す場合は,自動的な型変換は行わず,その関数の型とのチェックのみ行う。
●VOID関数以外の型で値を返さなくてもエラーにはならない。
アドレス宣言
大域宣言
ブロック
:
大域宣言
ブロック
アドレス宣言,大域宣言とブロック(関数定義)からなる。必ず,
という関数が必要で,プログラムを実行させることは関数MAIN( )を実行することである。関数MAIN( )の定義はプログラムのどこにあってもよい。MAIN()はINT型の関数として宣言されている。
関数名や大域宣言で宣言された名前は大域的な名前となり,プログラム全体で使用できる。関数名以外は,宣言以後有効となる。
局所宣言で宣言された名前や仮引数,ラベル名は,局所的な名前となり,その関数(ブロック)内でのみ使用できる。大域的な名前に向じ名前があった場合,局所的な名前を優先する。
オブジェクトコードやワークエリアの先頭アドレスの指定や,REAL型の精度の指定(単精度か,倍精度か)を行う。宣言を省略した場合はデフォルト値が使われる。デフォルトは
ORG $B000;
OFFSET 0;
DOUBLE;
オブジェクトコードの先頭アドレスを指定する。実際には,先頭にランタイムルーチンがリロケートされ,その後ろにオブジェクトコードが続く。
変数や配列のワークエリアの先頭アドレスを指定する。宣言を省略した場合は,ワークエリアはオブジェクトコード中に含まれる。初期値を持つ変数や配列は宣言の有無にかかわらず,オブジェクトコード中に含まれる。
オブジェクトを実行するアドレスと異なるアドレスに生成する際のオフセットを指定する。
実行時のスタックを指定する。ただし,プログラム呼び出し時のスタックは保存されなければならない。宣言を省略した場合は呼び出し時のスタックが使用される。
大域的な名前を宣言する。それらの名前は宣言以後すべての場所で使用できる。
●MACHINE宣言 MACHINE関数を宣言する。
●DECLARE宣言 関数のプロトタイプ宣言をする。
局所的なまとまりで,この中で宣言された名前はこの中でのみ有効となる。BEGINからEND;までで,関数を定義する。BEGINとEND;は[
]でもよい。たとえば,
INT FUNC1 (INT X,Y)
VAR INT I;
BEGIN
I=X+Y;
RETURN (I);
END;
(* 関数頭書き *)
(* 局所宣言 *)
(* 関数定義 *)
の形で書く。型を省略すると,INT型とみなされる。仮引数を持たない場合は,
仮引数の書式はVAR宣言の書式と同じだが,格納アドレス指定と初期化はできない。複数個ある場合は,カンマで区切る。仮引数は関数呼び出し時の実引数の値を持ち(値渡し),自動的に静的な局所変数として宣言される。たとえば,
INT FUNC (REAL A, B, INT C)
とするとA,BはREAL型の局所変数,CはINT型の局所変数となる。
局所的な名前を宣言する(ブロック内でのみ使用できる)。
単純変数と間接変数があり,必ずVAR宣言か仮引数で宣言しないと使用できない。
単純変数は,変数としてのみ使用でき,配列としては扱えない。INT型とREAL型がある。
間接変数は,変数としても配列としても扱える。配列として扱う場合は間接変数の値を配列の先頭アドレスとみなして,配列と同じようにメモリをアクセスする。配列同様2次元まで扱える。間接変数自体はINT型の単純変数だが,宣言時には配列としての型を宣言する。型を省略した場合はINT型とみなされる。
たとえば,POINTがINT型の間接変数として宣言されていたとすると,
では,C006Hの内容を下位バイト,C007Hの内容を上位バイトとして,変数Iに代入される。2次元の間接変数は,主に2次元配列を受け取る仮引数として使用する。
VAR 型 変数名 ; (* 単純変数 *)
VAR 型 変数名 [ ] ; (* 1次元間接変数 *)
VAR 型 変数名 [ ][n] ; (* 2次元間接変数 *)
変数を宣言する。カンマで区切っていくつでも宣言でき,最後はセミコロンで終わる。型はINT型とREAL型のみ。ただし,間接変数にはCHAR型もある。型を省略した場合は,ひとつ前の型と同じとみなされる。デフォルトの型はINT型。間接変数は配列として使用する際の型を宣言する。たとえば,
VAR
INT A, B,
REAL C, D[],
CHAR E[];
とすると,A,BはINT型の単純変数,CはREAL型の単純変数,DはREAL型の間接変数,EはCHAR型の間接変数となる。
のようにする。ただし,第一の添字の2は意味をもたないので,
のように宣言する。添字はINT型の定数でなければならない。
: INT型定数式とすることにより,変数の格納アドレスを指定することができる。
VAR XY:$C000, BYTE Z[ ]: $D000;
と書くと,C000HとC001HをINT型単純変数XYの格納アドレス,D000HとD001HをCHAR型間接変数Zの格納アドレスとすることができる(間接変数自体はINT型の変数なので,2バイト必要)。
=定数式とすることにより,変数の初期化をすることができる。この場合,WORK宣言がなされていても,その変数はプログラム中に埋め込まれる。
VAR A=0, B=3, C[ ]=$C000;
VAR REAL R=12.3456;
この初期化はコンパイル時にのみ行われ.実行時には行われない。
小数点を含む表現か,Eを用いた指数表現の10進数は無条件でREAL型になる。小数点を含む表現でも指数表現でもない場合,-32768~65536の整数はINT型になり,その他はREAL型になる。
例) 1234, -5 (* INT型 *)
1.0,3E5,1.2E-2 (* REAL型 *)
'$'で始まり16進文字からなる文字列。INT型になる。
'0'と'1'からなり'B'で終わる文字列。INT型になる。
'(シングルクォーテーション)でくくった1文字で,文字のASCIIコードを値とする。エスケープ文字が使用可。INT型になる。
"(ダブルクォーテーション)でくくった文字列で,文字列が格納されているアドレスを値とする。文字列はオブジェクトコード中に埋め込まれ,自動的に最後に$00がつけられる。エスケープ文字が使用可。INT型になる。ただし,2行にまたがることはできず,定数式にも使用できない。
定数値に名前をつけて定数値と同等に扱える。CONST宣言で定義する。ただし,REAL型の記号定数は定数式に使用できない。
例) CONST REAL PAI=3.14159265359;
次に生成するオブジェクトコードのアドレスを値とする。INT型になる。
コンパイル時の定数式のアドレスのメモリの内容を値とする。1バイト単位でアクセスする。INT型。
例) CONST INT @WIDTH=CONST [$1F5C];
CONST [INT型定数式]と同様。2バイト単位でアクセスする。INT型。
例) CONST @@=CONSTW [CONSTW [$1F82]+2];
文字定数や文字列定数中に使われ,2バイトで1文字として扱われる。\の後ろに1文字を付けた形で使用されるが,該当する文字がない場合は\だけで1文字となる。大文字と小文字の区別はしない。
\\ … \
\" … "
\' … '
\N … $0D
\/ … $0D
\C … $0C
\R … $1C
\L … $1D
\U … $1E
\D … $1F
\0 … $00
定数からなる式だが,文字列定数とREAL型の記号定数,カンマ演算子は使用できない。定数には,オブジェクトを生成せずコンパイル時に値が確定している式も含まれる。つまり,
&変数名
配列名
&配列名[INT型定数式]
&定義済みのラベル名
また,INT型の定数式では,途中にREAL型の定数などが表れても,最終的にINT型の定数値になればよい。
記号定数を定義する。カンマで区切っていくつでも宣言でき,最後はセミコロンで終わる。型にはINT型とREAL型がある。型を省略した場合についてはVAR宣言と同様。たとえば,
CONST INT PC=9801,
REAL PAI=3.14;
とすると,PCはINT型の9801,PAIはREAL型の3.14という定数値を持つ名前となる。
配列は2次元まで可能で,配列の表現はC言語と同じ。型には,CHAR型,INT型,REAL型の3種類がある。CHAR型は1バイト単位で,INT型は2バイト単位で,REAL型は5または8バイト単位で,配列要紫をアクセスする。添字のチェックはしない。必ずARRAY宣言で宣言してから使用する。2次元配列は,
配列名は配列のワークの先頭のアドレスを指す定数である。
ARRAY 型 配列名 [n1]; (* 1次元配列 *)
ARRAY 型 配列名 [n1] [n2]; (* 2次元配列 *)
(* ただし,n1,n2はINT型定数式 *)
配列を宣言する。カンマで区切っていくつでも宣言でき,最後はセミコロンで終わる。型には,CHAR型,INT型,REAL型の3種類があり,型を省略した場合についてはVAR宣言と同様。たとえば,
と宣言すると,REAL型の配列がA[0]からA[9]までの10個分確保される。
:INT型定数式とすることにより,配列の格納アドレスを指定することができる。たとえば,
とすると,C000H以降を配列ABCのワークエリアとし,ABC[0]の格納アドレスはC000HとC001H,ABC[1]はC002HとC003H,……となる。この場合,添字は意味を持たないので,
={定数式,定数式,…}とすることにより,配列の初期化をすることができる(ただし,{}は文括弧)。この場合,WORK宣言がなされていても,その配列はプログラム中に埋め込まれる。
ARRAY BYTE DT[4]={0, 1, 2, 3};
初期値が足りない場合は,残りは0で埋められる。多すぎる場合は,エラーとなる。添字が省略された場合はチェックしない。型がCHAR型の場合のみ,CODE関数と同じ書式を使って初期化できる。
ARRAY CHAR STR1[ ]=["ガマちゃん" ,$0D ,0];
この初期化はコンパイル時にのみ行われ,実行時には行われない。
通常の関数とMACHINE関数がある。型はVOID型とINT型とREAL型の3種類がある。再帰はできない。引数の数は,通常の関数では8個まで,MACHINE関数では5個までである。
の形で関数を呼び出す。実引数と仮引数の型や数が合わないと,エラーになる。
MACHINE関数の場合は,引数の数のチェックは行われない。
関数のプロトタイプ宣言をする。関数の定義より前に関数を呼び出す場合,関数の型や,引数の型がコンパイラにわからないため,プログラムの頭のほうで(通常アドレス宣言の次の大域宣言で),関数の型や,引数の裂を宣言しておく。コンパイラはこれをたよりに,型のチェックや,引数の数のチェックを行う。宣言は,
DECLARE 型 関数名 (引数の型,引数の型,……);
の形で行う。複数の関数を宣言する場合は,カンマで区切る。DECLARE宣言がされずに,未定義の関数を呼び出した場合は,関数も引数もすべてINT型として処理される。
例) DECLARE REAL SUB1(REAL, INT),
INT SUB2(),
VOID SUB3(INT);
仮引数に間接変数を使用する場合は,DECLARE宣言ではINT型として宣言する。たとえば関数が,
REAL SUB4(CHAR P[ ], REAL R1[3]);
となっていたとすると,DECLARE宣言では以下のようになる。
DECLARE REAL SUB4(INT, INT);
MACHINE関数はMACHINE宣言した関数で,レジスタを使って引数を渡す。MACHINE関数呼び出し時には.引数の数のチェックは行われるが,引数の型のチェックは行われない。主に,外部のマシン語ルーチンをMACHINE関数として宣言するが,プログラム中でCODE関数を使って定義したマシン語関数もMACHINE関数とすることができる。ただし必ず使用,定義する前にMACHINE宣言しなければならないので,通常,アドレス宣言の次の大域宣言で宣言する。引数は最大5個までで,レジスタを使った呼び出し方は,次のようになる。
0個…CALLのみ。
1個…HLに代入してCALL。
2個…順にHL,DEに代入してCALL。
3個…順にHL,DE,BCに代入してCALL。
4個…順にHL,DE,BC,IXに代入してCALL。
5個…順にHL,DE,BC,IX,IYに代入してCALL。
関数の値は,INT型の場合,関数から戻ってきたときのHLレジスタの値となる。REAL型の場合は,HLレジスタが指しているアドレスのREAL型データが値となる。
の形で宣言。復数のMACHINE関数を宣言する場合は,カンマで区切る。
そして,後ろに:INT型定数式をつけると,外部にあるマシン語サブルーチンを関数として利用できる。上の場合,MSUBはC000Hにあり引数を2個持ちHLジスタの値を返すINT型の関数となる。
特に断りがないかぎリ,INT型の演算結果はINT型,REAL型の演算結果はREAL型となる。
+
-
+
-
*
/
%
正符号。単項演算子。
負符号。単項演算子。
加算。
減算。
乗算。
除算。
剰余算。
,
左から右へ計算され,最も右の論理項を値とする。
&&
!!
NOT
!
論理積。
論理和。
論理否定 (単項演算子)。
〃 ( 〃 )。
AND
OR
XOR
CPL
<<
>>
論理積。
論理和。
排他的論理和。
ビット反転 (単項演算子)。
左シフト。空いたビットには0が入る。C言語参照。
右シフト。空いたビットには0が入る。C言語参照。
==
<>
!=
<=
>=
<
>
等しい。
等しくない。
〃
小さいか等しい。
大きいか等しい。
小さい。
大きい。
CVITR
CVUTR
CVRTI
CVRTU
符号付き整数(INT型)をREAL型に変換。
符号なし整数(INT型)をREAL型に変換。
REAL型を符号付き整数(INT型)に変換。
REAL型を符号なし整数(INT型)に変換。
++
--
&
ABS
SGN
インクリメント演算子。C言語参照のこと。
デクリメント演算子。C言語参照のこと。
アドレス演算子。C言語参照のこと。結果はINT型。
絶対値。単項演算子。
正の数なら1,0なら0,負の数なら-1となる。単項演算子。
- [ ]
- ( ) ++ -- &
- + - ! NOT CPL ABS SGN CVITR CVUTR CVRTI CVRTU
- * / %
- + -
- << >>
- == <> != <= >= <> .<=. .>=. .<. .>.
- OR AND XOR
- &&
- !!
- =
- , (カンマ)
{ }は文括弧を表す。文括弧として[ ],( ),「」,BEGIN END; が使用できる。[ ]は省略可を表す。
GOTO文やEXIT TO文のジャンプ先を指定する。ラベル名は局所的な名前となる。
FOR INT型単純変数名= 式1 TO 式2 文
FOR INT型単純変数名= 式1 DOWNTO 式2 文
単純変数の値を式lから式2になるまで1ずつ増やし,文を繰り返す。DOWNTOの場合は1ずつ減らす。まず文を実行してから,終値の判定を行う 。
ただし,式1と式2が間に0をはさむ場合は,期待される繰り返しは行われず,1回で繰り返しを終了する。
C言語のFOR文と同じ。上記のPASCAL型FOR文よりもオブジエクト効率が劣るが,REAL型の変数など,より複雑な条件が使用できる。
FOR文,WHILE文,REPEAT文から脱出する。C言語のbreak文と同じ。
その関数を終了して,呼び出した関数に戻る。(式) ; をつけた場合は,式の値を関数の値とする。
ラベルにジャンプする(必ずラベルは同じ関数内に)。
CASE (INT型式0) {
INT型定数式1 : 文1
INT型定数式2 : 文2
… … …
[OTHERS [:] 文]
}
式0の値が定数式nと等しければ,文nを実行し,CASE文を脱出する。上から順に比較していき,いずれの定数式とも等しくなかった場合は,OTHERSの後ろの文を実行する。
INT型定数式1 TO INT型定数式2 : 文1
とすると,式0の値が定数式1以上,定数式2以下の場合,文1を実行する。
INT型定数式1, [INT型定数式2, …,] INT型定数式n : 文
とすると,式0の値が定数式1から定数式nまでのいずれかに等しい場合,文を実行する。
システム配列やシステム関数,登録済みの名前はすべて大域的な名前である。これらは宣言せずに使用できる。
・int FALSE = 0;
・int TRUE = 1;
CALL関数. GETREG関数で使用。CALL関数では値をAレジスタに代入してからマシン語ルーチンをコールし,終了後Aレジスタの値が代入される。
●int ^BC
int ^DE
int ^HL
int ^IX
int ^IY
^Aと同様。^AFの上位バイトと^Aの下位バイトは同じ値を持つ。
CALL関数 .GETREG関数で使用。現在のSPの値が代入される。
CALL関数,GETREG関数で使用。CYフラグが立っていれば1,立っていなければ0が代入される。
CALL関数,GETREG関数で使用。Zフラグ。^CYと同様。
式の値のアドレスの内容を1バイト単位でアクセスする。
式の値のアドレスの内容を2バイト単位でアクセスする。式のアドレスが下位バイト,式+1のアドレスが上位バイトに対応する。
式のアドレスに実数値が格納されているものとして5バイト単位(単精度),または8バイト単位(倍精度)でアクセスする。
式の値のI/Oポートを1バイト単位でアクセスする。
式の値のI/Oポートを2バイト単位でアクセスする。式のI/Oポートが下位バイト,式+1のI/Oポートが上位バイトに対応する。下位バイト,上位バイトの順にアクセスされる。
式の値のS-OS特殊ワークエリアを1バイト単位でアクセス。
式の値のS-OS特殊ワークエリアを2バイト単位でアクセスする。式の特殊ワークエリアが下位バイト,式+1の特殊ワークエリアが上位バイトに対応する。
n=0のときS-OSの#GETKYと同じ
n=1のときS-OSの#FLGETと同じ
その他のときS-OSの#INKEYと同じ
キーボードから入力された整数値を返す。先頭に$を付けると,16進数とみなす。コールした時点のカーソル以降を読み込み,正常な入力が行われた場合は^CY=0,BREAKキーが押されたり誤入力があった場合は^CY=1となる。
キーボードから入力された実数値を返す。コールした時点のカーソル以降を読み込み,正常な入力が行われた場合は^CY=0,BREAKキーが押されたり誤入力があった場合は^CY=1となる。変数^DEが10進文字列の終了アドレス+1を指している。
キーボードから1行入力し,アドレスaddrに格納して,行の長さを返す。BREAKキーが押されると-1を返す。行の最後は00H。
●int GETLlN (int addr, len)
1行の長さlenを指定できるほかは,GETL関数と同じ。オーバーした分は無視される。
●int LlNPUT(int addr, len)
コールし た時点のカーソル以降を続み込むほかはGETLlN関数と同じ。
画面モード(40キャラ,80キャラ)を切り替える。nが40以下だと40キャラ,40より大きいと80キャラとなる。S-OSの#WIDCH。
画面のx,y座標のキャラクターコードを返す。S-OSの#SCRN。
n=0のとき,画面にのみ出力
n=1のとき,画面とプリンタに出力
その他のとき,プリンタのみに出力
値valを符号付き1バイトとし,符号付き2バイト値にして返す。
各レジスタの値を,それぞれ変数,^AF,^BC,^DE,^HL,^IX,^IY,^CARRY,^ZERO,^SPに代入する。^SPに正しい値を代入したい場合は単独で用いること。
各レジスタに変数^A,^BC,^DE,^HL,^IX,^IYの値を代入して,addrをコールする。コールが終了すると,GETREG( )と同様の処理をし,HLレジスタの値を返す。
●int CVITS(int val, buff)
値valを10進数の文字列に直してbuffに格納し,文字列の先頭アドレスを返す。buffは6バイト必要。
●int CVRTS(real val, int buff)
値valを10進数の文字列に直してbuffに格納し,文字列の先頭アドレスを返す。buffは単精度で18バイト,倍精度で34バイト必要。
buffの10進数の文字列をREAL型に変換する。変数^DEが10進文字列の終了アドレス+1を指している。
変数の値を一時スタックに保存するためのシステム関数。
PUSH(式,式,…);
;
;
POP(変数名,変数名,…);
の形で使用する。関数ではあるが式中では使用せず,必ず単独で使用すること(演算や代入の式に使ってはいけない)。動作はZ80のマシン語のPUSH,POPと同様で,PUSHする順番と逆の順番でPOPしなければならないし,型も合っていなければならない(自動的な型変換は行われない)。値を保存するスタックはプログラムのスタックそのものなので,PUSH,POPする場所については注意が必要である。また,PUSHしたら必ずその関数内でPOPしなければならない。
PUSH(I,J,K);
SUB();
POP(K,J,I);
直接データをオブジェクトにするためのシステム関数。
の形で使用する。式中では,マシン語データを実行後,HLレジスタの値をINT型の値として返す。CODE項には以下のものがある。
定数式の値の下位バイトを1バイトのオブジェクトにする。
定数式の値を下位バイト,上位バイトの順で2バイトのオブジェクトにする。
文字列をそのまま,オブジェクトにする。最後に$00はつかない。
式がINT型の場合は式の値をHLレジスタに代入するオブジェクトを,式がREAL型の場合は,式の値が格納されているアドレスをHLレジスタに代入するオブジェクトを作る。
実数値を5バイト(単精度),または8バイト(倍精度)のオブジェクトにする。
ラベルのアドレスを,下位バイト,上位バイトの順で2バイトのオブジェクトにする
文字や数値を画面やプリンタに出力するシステム関数。
の形で使用する。PRMODE関数で出力先を変えることができる。書式項には以下のものがある。
aのアドレスから$0Dの直前までをASCII出力。
aのアドレスから$00の直前までをASCII出力。
●CAN'T INCLUDE!
INCLUDEの入れ子が深すぎる。オンメモリ版ではINCLUDEできない。入れ子は4レベルまで。
●CAN'T JUMP
ジャンプできない。
●CONST STACK O.F.!
定数スタックがあふれた。実数定数演算が複雑すぎる。
●CONST TBL O.F.!
定数表がいっぱいになった。300EHの値を大きくするとよい。
●DIV BY 0
0で割っている。
●FUNC TBL O.F.!
関数表がいっぱいになった。3010Hの値を大きくするとよい。
●GLOBAL TBL O.F.!
大域表がいっぱいになった。
●HASH TBL O.F.!
ハッシュ表があふれた。3014Hの値を大きくするとよい。
●ILLEGAL ADDRESS!
アドレス宣言のアドレスの指定が正しくない。
●ILLEGAL BRACE
カッコのエラー。あるべきカッコがない。または開きと閉じのカッコが合わない。
●ILLEGAL CONST
正しい定数式ではない。
●ILLEGAL STRING
文字列エラー。20H未満のコードがある。
●ILLEGAL TYPE
型が間違っている。
●ILLEGAL USE OF REAL!
REAL型は使用できない。
●ILLEGAL USE OF NAME
名前を誤使用している。
●LOCAL TBL O.F.!
局所表がいっぱいになった。3012Hの値を大きくするとよい。
●MISMATCHED NUMBER OF ARG
引数の数が合わない。
●MISMATCHED TYPE OF ARG
引数の型が合わない。
●MISSING UNTIL
UNTILがない。
●MISSING TO/DOWNTO
TO/DOWNTOがない。
●MISSING [文字]
あるべき文字がない。
●MISSING #IF
$IFがない。
●NESTING O.F.!
ループの入れ子が深すぎる。入れ子は16レベルまで。
●OUT OF MEMORY!
メモリオーバー。もしくはオブジェクトがSOROBANと重なった。
●OUT OF RANGE
値が大きすぎる。
●REDEF OF NAME!
2重に宣言している。
●SYNTAX ERROR!
文法エラー。
●TEMP TBL O.F.!
TEMP表がいっぱいになった。実数演算が複雑すぎる。
●TOO COMPLEX!
式が複雑すぎる。
●TOO LONG LINE!
1行が長すぎる。1行は128文字以内。
●TOO LONG NAME!
名前が長すぎる。名前は32文字以内。
●TOO LONG STRING
文字列が長すぎる。
●TOO MANY ARG!
引数が多すぎる。引数は8個まで。
●TOO MANY DATA
データが多すぎる。
●UNDEF ARRAY
未宣言配列。
●UNDEF FUNC
未宣言関数。
●UNDEF LABEL
未宣言ラベル。
●UNDEF VAR
未宣言変数。
●#IF NESTING
#IFは入れ子にできない。 |
(C)1991 Nobuaki Onuki(original)
(C)1997 Junji Okazaki(edited)
(C)2024 Oh!Ishi,Nibbles Lab.(formatted)