;Exam2014H26春Prg2 数字列から和差積を求める
;--------------------------------
MAIN START
	LAD GR1,TEXT
	LAD GR2,KTBL
	CALL CALC
	ST GR0,ANS
	RET
TEXT DC '  101  +   55  .'
;TEXT DC '  101  - 55  .'
;TEXT DC '  202  * 55  .'
ANS DS 1
KTBL DS 55
	END
;----------------
CALC START
	RPUSH 
	LAD GR2,CTBL   ;
	CALL GETTKN    
	LD GR1,GR2     
	CALL DTOB      ;数字文字列１を２進数に変換して
	ST GR0,AA
	LD GR4,GR0     ;ＧＲ４に設定　　c 答え　エ
	LD GR1,3,GR2
	LD GR3,0,GR1   ; GR3 <---演算子の文字コード 
	SUBL GR3,='*'
	LAD GR1,6,GR2
	CALL DTOB      ;数字文字列２を２進数に変換して
	ST GR0,BB
	LD GR5,GR0     ; GR5に設定
	LD GR3,LTBL,GR3 ; d　答え　エ
	JUMP 0,GR3     ;演算子で指定された処理にジャンプ
MULT LD GR0,=0     ;乗算
	LD GR5,GR5
LP JZE FIN
	LD GR3,GR5
	AND GR3,=#0001 ;乗数の最下位ビットのチェック
	JZE NEXT
	ADDL GR0,GR4
NEXT SLL GR4,1     ;被乗数を１ビット左論理シフト
	SRL GR5,1     ; e 答え　オ
	JUMP LP
PLUS ADDL GR4,GR5  ;加算
	LD GR0,GR4
	JUMP FIN
MINUS SUBL GR4,GR5 ;減算
	LD GR0,GR4
FIN RPOP
	RET
CTBL DS 10     ;GETTKN用単語管理テーブル
LTBL DC MULT   ;演算子の分岐先アドレステーブル
	DC PLUS
	DS 1       ;ダミー
	DC MINUS
AA DS 1
BB DS 1
	END
;--------------
;GR1には数字列の先頭文字のアドレスを格納して渡す。
;先頭文字のアドレス番地の次の番地に桁数つまり文字数がある。
;数字を数値に変換するプログラム
DTOB START
	RPUSH
	LD GR5,=0    ;結果の数値を格納するGR5を初期化
	LD GR7,1,GR1	;桁数つまり文字数、であると同時に
	LD GR2,GR7    ;ループ回数でもある。
    LD GR6,0,GR1   ;数字列の先頭文字のアドレスを取得
LOOP1 LD GR0,0,GR6 ; GR0 <---数字のＮ桁目の数字取得
	AND GR0,=#000F ; 数値として取り出す
	PUSH 0,GR2     ;GR2 を退避
	LD GR2,XM,GR2  ;数値の位取り
	CALL MULT  ;GR0 X GR2 を計算、GR0に結果を入れて戻る。 
	POP GR2        ;GR2 を元に戻す
	ADDA GR5,GR0
	LAD GR6,1,GR6 ;次の数字のアドレスを取得
	SUBA GR2,=1   ;ループ回数をひとつ減らす
	JZE FIN
	JUMP LOOP1
FIN LD GR0,GR5
	RPOP
	RET
XM DC 0,1,10,100,1000,10000
	END
;------------------
;シフトによる乗算
;GR0 <---GR0 X GR2
MULT START
	RPUSH
	LD GR1,GR0
	LD GR0,=0
	LD GR3,=15
	LD GR2,GR2
LP JZE FIN
	JPL CONT
	LD GR4,GR1
	SLL GR4,0,GR3
	ADDL GR0,GR4
CONT LAD GR3,-1,GR3
	SLL GR2,1
	JUMP LP
FIN RPOP
	RET
	END
;---------------------------
GETTKN START
	RPUSH
	LD GR3,=-1     ;単語の種別の初期化
	LAD GR1,-1,GR1
LP LAD GR1,1,GR1	  ;単語の先頭アドレス
	LD GR4,0,GR1   ;
	CPL GR4,='.'
	JZE FIN
	CPL GR4,=' '
	JNZ ALNUM
	CALL SETTKN
	JUMP LP      ;a 答え　イ
ALNUM LD GR3,GR3 ;単語の処理中？
	JPL LP       ;処理中の単語が英字を含む場合はＬＰへ
	JZE ACHK     ;処理中の単語が数字だけの場合はACHKへ
	LD GR3,=0    ;次の単語の処理開始
;以下では、単語種別を”数字だけからなる”に設定
	LD GR6,GR1   ;先頭アドレスを退避
ACHK CPL GR4,='9'
	JPL NEXT
	CPL GR4,='0'
	JMI NEXT
	JUMP LP     ;取り出した文字が数字の場合はＬＰへ
NEXT LD GR3,=1   ;単語種別を”英字を含む”に設定
	JUMP LP
FIN CALL SETTKN
	LD GR5,=-1
	ST GR5,0,GR2 ;終端マークを格納
	RPOP
	RET
SETTKN LD GR3,GR3
	JMI FIN2     ;単語処理中でなければ何もしない
	ST GR6,0,GR2 ;単語の先頭アドレスを格納
	LD GR5,GR1
	SUBL GR5,GR6 ;b 答え　カ
	ST GR5,1,GR2 ;単語の長さを格納
	ST GR3,2,GR2 ;単語の種別を格納
	LD GR3,=-1   ;単語種別を初期化(処理中状態を解除）
	LAD GR2,3,GR2
FIN2 RET
	END
;--------------------------
