comment switch on the RULE TYPE of control card read; switch CARDKIND := QCARD, TAPE, TEND, SKIP, HERE, DEBUG, LIST, END, STOP, TIME, DISC; comment switch on the RULE TYPE of Turing machine rule being obeyed; switch RULE TYPE := type 1 rule, type 2 rule, type 3 rule; comment switch on the debugging mode; switch DEBUG MODE := rule found, debug mode 1, debug mode 2, debug mode 3; integer incnt, hereq, debug mode; boolean tape input mode, found; integer current state, current symbol, next state, next symbol, rule type; A := 33; B := A + 1; C := B + 1; D := C + 1; E := D + 1; F := E + 1; G := F + 1; H := G + 1; I := H + 1; J := I + 1; K := J + 1; L := K + 1; M := L + 1; N := M + 1; O := N + 1; P := O + 1; Q := P + 1; R := Q + 1; S := R + 1; T := S + 1; U := T + 1; V := U + 1; W := V + 1; X := W + 1; Y := X + 1; Z := Y + 1; SP := 0; LS := 2; SLASH := 15; ZERO := 20; NINE := 29; comment set up the input scheme; nextch := 0; comment set up the heap in the array LAV; set up the heap(LAV(1), LAV(LSL), LAV(LSL+1), LAV(LAL), IDP); clear list stack; comment create a dynamic scope in the heap; begin list scope; comment declare ILF as an array of pointers into the heap; declare list array(ILF, LIL); comment set up the output buffering; comment the EGDON routine DEFIOP(IDP, 0) is not supported; begin comment the following appalling code sets up the control card matching tree in the heap; integer length, node c, node d, node e; integer array name [1:10]; comment upper bound set generously; integer procedure make name branch (name length, switching code); value name length, switching code; integer name length, switching code; comment enter a word, held in name(1..name length), and its switching code, into the name-matching tree and return a pointer to its root; begin integer cell, i; cell := switching code; for i := 1 step 1 until name length do cell := IJK(cell, name(i), 0); make name branch := cell; end of make name branch; procedure add letter to name (letter); value letter; integer letter; comment add a letter of a word to name, IN REVERSE ORDER; begin name(length) := -letter; length := length - 1; end of add letter to name; comment declare heap pointers; declare list(name tree); begin list scope; declare list(node c); declare list(node d); declare list(node e); comment set heap pointers to NIL; name tree := node d := node e := node c := 0; comment build the control-card matching tree in the heap; comment insert LIST; length := 5; for char := L, I, S, T, SP, do add letter to name(char); node e := make name branch(5, 7); comment insert HERE; length := 5; for char := H, E, R, E, SP, do add letter to name(char); node d := make name branch(5, 5); setK(node d, node e); node e := node d; comment insert END; length := 4; for char := E, N, D, SP, do add letter to name(char); node d := make name branch(4, 8); setK(node d, node e); node e := node d; comment insert ISC, the D of DISC goes in via DEBUG; length := 4; for char := I, S, C, SP do add letter to name(char); node c := make name branch(4, 11); comment insert DEBUG; length := 6; for char := D, E, B, U, G, SP do add letter to name(char); node d := make name branch(6, 6); setK(node d, node e); node e := node d; setK(iP(node d), node c); comment insert TOP, the S of STOP goes in via SKIP; length := 4; for char := T, O, P, SP, do add letter to name(char); node c := make name branch(4, 9); comment insert SKIP; length := 5; for char := S, K, I, P, SP, do add letter to name(char); node d := make name branch(5, 4); setK(node d, node e); node e := node d; node d := iP(node d); setK(node d, node c); comment insert END, the T of TEND goes in via TAPE; length := 4; for char := E, N, D, SP do add letter to name(char); node c := make name branch(4, 3); comment insert IME, the T of TIME goes in via TAPE; length := 4; for char := I, M, E, SP do add letter to name(char); node d := make name branch(4, 10); setK(node c, node d); comment insert /TAPE; length := 6; for char := SLASH, T, A, P, E, SP do add letter to name(char); node d := make name branch(6, 2); comment finalize the name tree; setK(iP(node d), node e); setK(iP(iP(node d)), node c); node e := node d; setK(node e, IJK(IJK(1, 0, 0), Q, 0)); name tree := node e; comment close the dynamic scope; end list scope; end of setting up name tree with the control card matches; SETUP: clear the tape; for a := 0 step 1 until LIL do ILF(a) := 0; incnt := hereq := debug mode := 0; tape input mode := found := false herep := 1; right limit := 32; left limit := 72; time limit := CPU time in seconds + 10; skip past the end of the line: if nextch != LS then goto skip past the end of the line; get a new line: inpch; MAIN: comment switching on input RULE TYPE; goto CARDKIND(treesw); FAIL: comment The nature of the line is not recognised. If we are in tape input mode then the line is added to the TM tape else it is ignored; if tape input mode then add to the tape else goto skip past the end of the line; QCARD: begin integer this state, this symbol, action, next state; this state := inint; this symbol := inpch; action := inpch; if action != 50 and action != 44 then nextch else if action = 50 then action := 62 else action := 63; next state := inpch; next state := inint; begin list scope; ILF(this state) := insert rule(next state, action, this symbol, ILF(this state)); end list scope; if this state != current state or this symbol != current symbol then goto get a new line; comment The Q card matches the current configuration of the Turing machine, so resume simulation; end TICK: if CPU time in seconds > time limit then begin comment print /TIME UP; for char := SLASH, 52, 41, 45, 37, SP, 53, 48, 64 do outch(char); comment the EGDON FDUMP is not supported; end else begin split(find(current symbol, ILF(current state)), next state, next symbol); rule type := if next symbol < 62 then 1 else next symbol-60 end comment Check for debugging modes and act accordingly; goto DEBUG MODE(debug mode+1); debug mode 3: print the tape expression; debug mode 2: print state; if found then goto RULE TYPE(rule type) else goto no rule found; debug mode 1: print the tape expression; if found then goto RULE TYPE(rule type) else goto no rule found; rule found: if found then goto RULE TYPE(rule type); no rule found: if debug mode = 2 then print the tape expression; goto get a new line; type 1 rule: write to tape(next symbol); current symbol := next symbol; current state := next state; goto TICK; type 2 rule: move the tape left; current symbol := read from tape; current state := next state; goto TICK; type 3 rule: move the tape right; current symbol := read from tape; current state := next state; goto TICK; TAPE: if tape input mode then add to the tape; incnt := herep := hereq := 0; tape input mode := true clear the tape; goto skip past the end of the line; TEND: if not tape input mode or incnt = 0 then goto skip past the end of the line; for a := incnt step -1 until herep do move the tape right; herep := 1; tape input mode := false read from tape(current symbol); current state := hereq; DNET: if inpch != LS then goto DNET; goto TICK; SKIP: if tape input mode then begin integer amount, i; amount := inint; for i := 1 step - until amount do begin write to tape(SP); move the tape left; end; incnt := incnt + amount; goto get a new line end goto skip past the end of the line; HERE: if tape input mode then begin next non blank; herep := incnt + 1; hereq := inint; goto get a new line end goto skip past the end of the line; DEBUG: if tape input mode then add to the tape; debug mode := inint; goto get a new line; LIST: if tape input mode then add to the tape; left limit := inint; right limit := inint; goto get a new line; END: if tape input mode then add to the tape; end list scope; print the tape expression; goto SETUP; TIME: if tape input mode then add to the tape; time limit := CPU time in seconds + inint; goto get a new line; DISC: if tape input mode then add to the tape; comment is no longer relevant; goto skip past the end of the line; STOP: if tape input mode then add to the tape; for char := LS, SLASH, S, T, O, P, S, LS do outch(char); end of inner block end of AMTSIM |