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 S
stsの定義はこんな感じ
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