Declarations and Assignment Statements
(with Type Checks)

Declarations, Assignment Statements, and Type Checks (with 1D Arrays)
ProductionSemantic Rules
pd → PROC np IS ds BEG s ss END ;
ds.offset = 0
pd.code = s.code || ss.code
np → di ( ps ) | di not used yet
ds → d ds1 d.offset = ds.offset
ds1.offset = d.newoffset
ds.totalSize = ds1.totalSize
ds → ε ds.totalSize = ds.offset
d → di : ty ; addType(di.entry, ty.type)
addBaseType(di.entry, ty.basetype)
addSize(di.entry, ty.size)
addOffset(di.entry, d.offset)
d.newoffset = d.offset + ty.size
di → ID di.entry = ID.entry
ty → ARRAY [ NUM ] OF ty1 ty.type = array(NUM.value, ty1.type)
ty.basetype = ty1.basetype
ty.size = NUM.value * ty1.size
ty → INT ty.type = integer
ty.basetype = integer
ty.size = 4
ty → REAL ty.type = real
ty.basetype = real
ty.size = 8
e → t e.addr = t.addr
e.type = t.type
e.code = t.code
e → e1 ADDOP t e.addr = new Temp()
e.type = LUB(e1.type, t.type)
widen(e1.addr, e1.type, e.type, e.code1, e.addr1)
widen(t.addr, t.type, e.type, e.code2, e.addr2)
e.code = e1.code || e.code1 || t.code || e.code2 ||
      gen(e.addr = e.addr1 ADDOP.lexeme e.addr2)
t → f t.addr = f.addr
t.type = f.type
t.code = f.code
t → t1 MULOP f t.addr = new Temp()
t.type = LUB(t1.type, f.type)
widen(t1.addr, t1.type, t.type, t.code1, t.addr1)
widen(f.addr, f.type, t.type, t.code2, t.addr2)
t.code = t1.code || t.code1 || f.code || t.code2 ||
      gen(t.addr = t.addr1 MULOP.lexeme t.addr2)
f → ( e ) f.addr = e.addr
f.type = e.type
f.code = e.code
f → NUM f.addr = get(NUM.lexeme)
f.type = NUM.entry.type
f.code = ""
f → ID
(i.e., indices=ε)
f.addr = ID.lexeme
f.type = getBaseType(ID.entry)
f.code = ""
f → ID i
Note: i not is
f.t1 = new Temp()
f.addr = new Temp()
f.type = getBaseType(ID.entry)
f.code = i.code || gen(f.t1=i.addr*getBaseWidth(ID.entry))
      || gen(f.addr=ID.lexeme[f.t1])
i → [ e ] i.addr = e.addr
i.type = e.type
i.code = e.code
ss → s ss1 ss.code = s.code || ss1.code
ss → ε ss.code = ""
s → ids s.code = ids.code
ids → ID ra
ra.id = ID.entry
ids.code = ra.code
ra → := e ; widen(e.addr, e.type, ra.id.basetype, ra.code1, ra.addr)
ra.code = e.code || ra.code1 || gen(ra.id.lexeme=ra.addr)
ra → i = e ;
Note: i not is
ra.t1 = newTemp()
widen(e.addr, e.type, ra.id.basetype, ra.code1, ra.addr)
ra.code = i.code || gen(ra.t1 = getBaseWidth(ra.id)*i.addr) ||
      e.code || ra.code1 || gen(ra.id.lexeme[ra.t1]=ra.addr)