Review: For array a[2,5], how would the memory for this array looks like using row major layout? What about column major layout? How to compute the address of array element a[i, j, k], assuming that the array is declared as a[10..20, 30..40, 40..50]? How to compute the address for the array element a[i1, i2, …, ik] assuming that the array is declared as a[low1..high1, …, lowk..hightk]?
In general, for any dimensional array, the address of a[i1, i2, i3, …, ik] can be computed as follows: Let highj and lowj be for bounds for ij Let nj = highj – lowj + 1 The address is ((…(i1*n2+i2)*n3+…)nk+ik)*width + base –((…low1*n2+low2)*n3+…)nk+lowk) * width When generating code for array references, we need to explicitly compute the address.
Translation scheme for array elements: Function limit(array, j) returns nj=highj-lowj+1 Place: an attribute represent the temporarys or variables offset: an attribute represent the offset from the base for an array element, null if not an array reference Grammar: S->L := E E->E+E E->(E) E->L L->Elist ] L->id Elist->Elist, E Elist->id[E
S->L := E { if L.offset = null then emit(L.place ‘:=‘ E.place) else emit(L.place’[‘L.offset ‘]’ ‘:=‘ E.place);} E->E1+E2 {E.place := newtemp; emit(E.place ‘:=‘ E1.place ‘+’ E2.place);} E->(E1) {E.place := E1.place;} E->L {if L.offset = null then E.place = L.place else {E.place = newtemp; emit(E.place ‘:=‘ L.place ‘[‘ L.offset ‘]’); } L->Elist ] {L.place = newtemp; L.offset = newtemp; emit(L.place ‘:=‘ c(Elist.array)); emit(L.offset ‘:=‘ Elist.place ‘*’ width(Elist.array);
L->id {L.place = lookup(id.name); L.offset = null; } Elist->Elist1, E { t := newtemp; m := Elist1.ndim + 1; emit(t ‘:=‘ Elist1.place ‘*’limit(Elist1.array, m)); emit(t, ‘:=‘ t ‘+’ E.place); Elist.array = Elist1.array; Elist.place := t; Elist.ndim := m; Elist->id[E {Elist.array := lookup(id.name); Elist.place := E.place Elist.ndim := 1;
Example: A: array[1..10, 1..20] of integer; Translate: x := A[y, z] Accessing fields in records? a.b.c.d := x X := a.b.c.d
Intermediate code generation for boolean expressions. Boolean expressions are composed of boolean operators (and, or and not), boolean variables and relational expressions (E1 relop E2) Grammer: E->E or E | E and E | not E | (E) | id relop id | true | false Two methods can be used to generate code for boolean expressions: Encode true and false numerically and evaluate the boolean expression just like evaluating the arithmetic expression. Implement boolean expressions as flow of controls (short circuit code)
Representing the boolean value numerically. How to do code generation: E -> E or E E-> E and E E ->not E E -> (E) E ->id relop id E ->true E->false
E -> E or E E-> E and E E ->not E E -> (E) E ->id relop id { E.place = newtemp; emit(if id1.place relop.op id2.place ‘goto’ nextstat+3); emit(E.place ‘:=‘ 0); emit(‘goto’ nextstat + 2); emit(E.place ‘:=‘ 1); } E ->true E->false