第 9 章 サブルーチン 59
12.1 文字列処理の基礎
12.1.1 文字列処理の基本的な考え方
この章では、文字列を処理するプログラムについて説明したいと思います。
COMET IIでは、文字列は、1語に1文字で、連続する主記憶装置の領域に格納されます。で
すから、文字単位で文字列を処理する方法は、第8.3節で説明した、データ列を処理する方法と 同じです。
12.1.2 文字列の逆転
まず最初に、とても簡単な文字列処理の例として、文字列を逆転させるプログラムを書いてみ ましょう。
プログラムの例 reverse.cas REVERSE START
IN INAREA,INLENGTH CALL REVSUB
OUT OUTAREA,INLENGTH RET
;
REVSUB LAD GR2,0
LD GR3,INLENGTH LAD GR3,-1,GR3 LOOP LD GR1,INAREA,GR2
ST GR1,OUTAREA,GR3 LAD GR2,1,GR2 LAD GR3,-1,GR3 CPA GR2,INLENGTH
JMI LOOP RET
;
INAREA DS 256 INLENGTH DS 1 OUTAREA DS 256
END
このプログラムは、文字列を読み込んで、その文字列を逆転させた文字列(文字を逆の順序に 並べ替えた文字列)を出力します。
メインルーチンは、IN命令を使って文字列を読み込んで、その文字列をINAREAから始まる領 域に、その文字列の長さをINLENGTHに格納します。そして、REVSUBから始まるサブルーチン を呼び出して、そののち、OUTAREAから始まる領域に格納された文字列を、OUT命令を使って出 力します。
REVSUBから始まるサブルーチンは、GR2を文字列の先頭の位置(0)からインクリメントする と同時に、GR3を文字列の末尾の位置(長さ−1)からデクリメントしながら、INAREAから始 まる領域に格納されている文字列のGR2番目の文字をGR1にロードして、OUTAREAから始まる領 域のGR3番目にそれをストアします。そして、GR2の内容とINLENGTHの内容とが等しくなった とき、ループから脱出して終了します。
実行例
IN ? I am a cat.
.tac a ma I
12.1.3 文字の置き換え
次に、文字列の中に含まれているすべての空白をドットに置き換えるプログラムを書いてみま しょう。
プログラムの例 sp2dot.cas SP2DOT START
IN INAREA,INLENGTH CALL S2DSUB
OUT OUTAREA,INLENGTH RET
;
S2DSUB LAD GR2,0
LOOP LD GR1,INAREA,GR2 CPL GR1,=’ ’ JPL SKIP JMI SKIP LD GR1,=’.’
SKIP ST GR1,OUTAREA,GR2 LAD GR2,1,GR2 CPA GR2,INLENGTH JMI LOOP
RET
;
INAREA DS 256 INLENGTH DS 1 OUTAREA DS 256
END
このプログラムは、文字列を読み込んで、その文字列に含まれているすべての空白をドットに 置き換えた文字列を出力します。
S2DSUBから始まるサブルーチンは、GR2を0からインクリメントしながら、INAREAから始ま る領域に格納されている文字列のGR2番目の文字(先頭は0番目)をGR1にロードして、それが 空白ならばGR1にドットをロードして、GR1の内容をOUTAREAから始まる領域のGR2番目にスト アします。そして、GR2の内容とINLENGTHの内容とが等しくなったとき、ループから脱出して 終了します。
実行例
IN ? dog cat mouse rabbit monkey dog..cat...mouse....rabbit...monkey
12.1. 文字列処理の基礎 75
12.1.4 小文字から大文字への変換
英字には、小文字と大文字があります。そこで、文字列に含まれているすべての小文字を大文 字に変換するプログラムを書いてみることにしましょう。
第1.3.6項で説明したように、COMET IIでは、文字は、日本工業規格が策定したJIS X 0201 という文字コードによって表現されます。
JIS X 0201では、A、B、C、D、……という英字の大文字は、それと同じ順番で、65、66、67、 68、……という連続した整数によってあらわされます。そして、a、b、c、d、……という英字の 小文字は、それと同じ順番で、97、98、99、100、……という連続した整数によってあらわされ ます。ですから、大文字をあらわす整数と、それに対応する小文字をあらわす整数とのあいだに は、常に32の差がある、ということになります。
プログラムの例 low2up.cas LOW2UP START
IN INAREA,INLENGTH CALL L2USUB
OUT OUTAREA,INLENGTH RET
;
L2USUB LAD GR2,0
LOOP LD GR1,INAREA,GR2 CALL ISLOWER
CPL GR3,=0 JZE SKIP SUBL GR1,=32
SKIP ST GR1,OUTAREA,GR2 LAD GR2,1,GR2 CPA GR2,INLENGTH JMI LOOP
RET
;
ISLOWER LAD GR3,0 CPL GR1,=’a’
JMI EXIT CPL GR1,=’z’
JPL EXIT LAD GR3,1 EXIT RET
;
INAREA DS 256 INLENGTH DS 1 OUTAREA DS 256
END
このプログラムは、文字列を読み込んで、その文字列に含まれているすべての英字の小文字を 大文字に変換した文字列を出力します。
ISLOWERから始まるサブルーチンは、GR1の内容が英字の小文字かどうかを判定して、GR3に、
英字の小文字ならば1、そうでないならば0を設定します。
実行例
IN ? Arithmetic Logic Unit ARITHMETIC LOGIC UNIT
12.1.5 大文字のみの取り出し
これまでに紹介した文字列処理の二つのプログラムは、どちらも、処理の対象となる文字列と 処理した結果の文字列とが同じ長さになるものばかりでしたが、文字列処理は、文字列の長さが 変化しないものばかりではありません。
文字列の長さが変化する文字列処理の例として、文字列から英字の大文字だけを取り出して並 べることによって、大文字だけの文字列を作るプログラムを書いてみましょう。
プログラムの例 acronym.cas ACRONYM START
IN INAREA,INLENGTH CALL ACROSUB
OUT OUTAREA,OUTLENGT RET
;
ACROSUB LAD GR2,0 LAD GR3,0
LOOP LD GR1,INAREA,GR2 CALL ISUPPER
CPL GR4,=0 JZE SKIP
ST GR1,OUTAREA,GR3 LAD GR3,1,GR3 SKIP LAD GR2,1,GR2
CPA GR2,INLENGTH JMI LOOP
ST GR3,OUTLENGT RET
;
ISUPPER LAD GR4,0 CPL GR1,=’A’
JMI EXIT CPL GR1,=’Z’
JPL EXIT LAD GR4,1 EXIT RET
;
INAREA DS 256 INLENGTH DS 1 OUTAREA DS 256 OUTLENGT DS 1
END
このプログラムは、文字列を読み込んで、その文字列から英字の大文字だけを取り出して、そ れらの大文字から構成される文字列を出力します。
実行例
IN ? Arithmetic Logic Unit ALU