Question:
The grammar of Figure 15.6 assumes that all variables are global. In the presence of subroutines, we should need to generate different code (with fp-relative displacement mode addressing) to access local variables and parameters. In a language with nested scopes we should need to dereference the static chain (or index into the display) to access objects that are neither local nor global. Suppose that we are compiling a language with nested subroutines, and are using a static chain. Modify the grammar of Figure 15.6 to generate code to access objects correctly, regardless of scope. You may find it useful to define a to register subroutine that generates the code to load a given object. Be sure to consider both l-values and r-values, and parameters passed by both value and result.
Figure 15.6:
Transcribed Image Text:
reg_names : array [0..k-1] of register.name := ["r1, "r2" .., "rk"] -- ordered set of temporaries program + stmt stmt.next.free_reg := 0 program.code := ["main:"] + stmt.code + ["goto exit"] while : stmt expr stmtz stmtz expr.next.free_reg := stmt2.next.free_reg := stmt3.next.free.reg := stmtj.next.free_reg L1:= new.label(); L2 := newJabel() stmtj.code := ["goto" L1] + [L2 ":"] + stmt2.code + [L1 ":"] + expr.code + ["if" expr.reg "goto" L2] + stmt3.code if : stmti expr stmt2 stmtz stmtą expr.next_free_reg := stmt2.next.free reg := stmt3.next.free_reg := stmt4.next.free_reg := stmtj.next.free-reg L1:= new.label); L2 := newJabel() stmtj.code := expr.code + ["if" expr.reg "goto" L1] + stmt3.code + ["goto" L2] + [L1 ":"] + stmt2.code + [L2 ":"] + stmtą.code assign : stmt - id expr stmtz expr.next.free_reg := stmt2.next.freereg := stmtj.next.free.reg stmtı.code := expr.code + [id.stp→name ":=" expr.reg] + stmt2.code read : stmt + id, idz stmt2 stmtj.code := ["a1 := &" id.stp→name] + ["call" if id2.stp>type = int then "readint" else ...] + [idz.stp→name ":= rv"] + stmt2.code %3D -- file write : stmt → id expr stmt2 expr.next_free_reg := stmt2.next.freereg := stmtj.next.free.reg stmtj.code := ["a1 := &" id.stp→name] + ["a2 :=" expr.reg] + ["call" if id.stp type = int then "writeint" else ..] + stmt2.code -- file -- value writeln : stmti + id stmtz stmtj.code := ["a1 := &" id.stpname] + ["call writeln"] + stmt2.code null : stmt €