program t46; (* s[i] with a VARIABLE index -- an address the code can only compute at run time. Until now a subscript had to fold: ParseSub accepted a constant and reported ENoLib for anything else, because off+i is not known when the symbol is. TP3 computes it once, in indstr/ialoop, and holds it in DI until the byte is loaded or stored (TPSRC9 1100-1111, 1200-1229); the assignment paths then save it across the right-hand side (TPSRC8 asnscal2 758-760, asnscal3 786-789), which is what keeps `g[i] := h[j]` storing where it read from. This mirrors that: LEA DI,[base] / ADD DI,AX, and a PUSH DI around an assignment's right-hand side. A STRING is still a length byte at s[0] then the characters, so s[i] is the one byte at off+i. A second subscript is not a type (ESimpType), and there is no range check yet -- {$R+} / {$I+} belong to item 2. *) var g : string[10] ; h : string[10] ; i, j : integer ; c : char ; procedure show (ch : char) ; begin write (ch) end ; procedure p ; var l : string[6] ; k : integer ; begin l := 'abcdef' ; k := 2 ; writeln (l[k]) ; (* local string: LEA DI,[BP+disp] *) l[k] := 'Z' ; (* local destination, variable index *) writeln (l) ; g[3] := l[k] (* constant destination, variable source *) end ; begin g := 'hello' ; h := 'world' ; i := 1 ; j := 4 ; writeln (g[i]) ; (* read *) c := g[j] ; writeln (c) ; (* read into a char *) g[i] := 'H' ; (* write *) writeln (g) ; if g[i] = 'H' then writeln ('y') else writeln ('n') ; writeln (g[j], h[i]) ; (* two variable reads in one call *) show (g[j]) ; (* a subscript as a procedure ARGUMENT *) writeln ; g[i] := h[j] ; (* both sides indexed at once *) writeln (g) ; writeln (g[i+1]) ; (* computed index: ADD DI,AX *) p ; writeln (g) end.