• 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