BCPLのコードを読む日記
EDSACのInSインストラクションの挙動がわからないので、BCPLでの実装を読む。 http://www.cl.cam.ac.uk/users/mr/Edsac/edsac.tgz
BCPLの文法は全然知らないんだけど、類推力を駆使して読み解くのが面白い。
まずここがインストラクションを1個実行するところ。mem!scrが今風に言うとmem[scr]だね。scrはsequence_controlの略。シフトやビット演算は今風。ifがTESTなのとか面白いな。THENとELSEで区切るのはBASIC風だね。で、まあswitch文的なものがあって、肝心のInSのところではsts(addr, rd())をしている。
AND interpret() = VALOF
...
{ // Instruction execution loop
LET instr = mem!scr
LET addr = instr>>1 & #x3FF
TEST (instr&1)=0 THEN ldrs(addr)
ELSE ldrl(addrϾ)
scr := scr+1
SWITCHON instr & #b11111_0_0000000000_1 INTO
{ DEFAULT: RESULTIS 3
...
CASE #b00111_0_0000000000_0: stas(addr); ENDCASE // U n S
CASE #b00111_0_0000000000_1: stal(addrϼ); ENDCASE // U n L
CASE #b01000_0_0000000000_0: sts(addr, rd()); ENDCASE // I n Sstsの定義はこんな感じ
AND sts(a, x) BE mem!a := x & #x1FFFF
rdはテープから1文字入力を読み込んでEDSACの文字コードに変換して返す関数。RESULTISが今風に言うとreturnなんだな。'*t'とか'*n"のアスタリスクは今風に言うとバックスラッシュなんだろうなー。
AND rd() = VALOF
{ LET ch = ?
UNLESS tape DO
{ writef("*nNo input tape selected*n")
abort(999)
}
ch := rdch()
SWITCHON ch INTO
{ DEFAULT: code := asc2ed(ch)
IF code>=0 RESULTIS code
writef("Bad ch %n '%c'*n", ch, ch)
abort(999)
RESULTIS 0
CASE '*t':
CASE '*s':
CASE '*n': LOOP
}
} REPEAT