CSE443 Compilers
- Dr. Carl Alphonce
CSE443 Compilers Dr. Carl Alphonce alphonce@buffalo.edu 343 Davis - - PowerPoint PPT Presentation
CSE443 Compilers Dr. Carl Alphonce alphonce@buffalo.edu 343 Davis Hall Announcements Weekly team meetings with me: - Doodle poll link in Piazza Wednesday (4/ 4) will be a workshop Wednesday - Post questions you'd like addressed in Piazza
Figure 1.6, page 5 of text
# of dimensions size of dimension 1 (integer) (0) (1) (2) (3) (4) 1 5 V A X E S
https:/ / en.wikipedia.org/wiki/VAX Q: Since the number of dimensions is part of the type, do we need to store it at runtime? A: No.
https:/ / en.wikipedia.org/wiki/VAX
size of dimension 1 (integer) (0) (1) (2) (3) (4) 5 V A X E S
What is the size of a multi- dimensional array of type T? sizes of dimensions (Si): X*4 bytes data: (āiāX Si) * sizeOf(T)
size of first dimension 2 size of second dimension 3 a(0,0) first row a(0,1) a(0,2) a(1,0) second row a(1,1) a(1,2)
T = int w = 4 t = int w = 4 t = array(3,int) w = 12 t = array(2,array(3,int)) w = 24 t = array(2,array(3,int)) w = 24
For the purposes of type checking the number of dimensions is relevant, but the size of each dimension is not. Q: if a and b are compatible array types, what are the semantics of a := b ?
character w = 1
w = 6 w = 3 9+array(2,arr(3,character)) w = 9 + 6 * 1 = 15 w = 2 * 3
What if type info comes after dimensions?
dblocks (6.3.5 and 6.3.6)
records (in separate symbol table), sequence of declarations at start of sblock
definition ā> type identifier ':' dblock { st.put(identifier.lexeme, TYPE, dblock.type, dblock.width } dblock ā> '[' { Env.push(st); st = new Env(); Stack.push(offset); offset = 0; } declaration-list ']' { dblock.type=record(st); dblock.width=offset; st=Env.pop(); offset=Stack.pop(); } declaration-list ā> declaration ';' declaration-list declaration-list ā> declaration declaration ā> identifier ':' { id-list.type = identifier; } <ā however you store types identifier-list (maybe pointer into st?) identifier-list ā> identifier ( sBinOp constant ) ',' { st.put(identifier.lexeme, VAR, identifier-list.type, offset);
identifier-list identifier-list ā> identifier ( sBinOp constant ) { st.put(identifier.lexeme, VAR, identifier-list.type, offset);
Just suggestions, not to be taken literally Just suggestions, not to be taken literally
dblocks (6.3.5 and 6.3.6)
records (in separate symbol table), sequence of declarations at start of sblock
definition ā> type identifier ':' dblock { st.put(identifier.lexeme, TYPE, dblock.type, dblock.width } dblock ā> '[' { Env.push(st); st = new Env(); Stack.push(offset); offset = 0; } declaration-list ']' { dblock.type=record(st); dblock.width=offset; st=Env.pop(); offset=Stack.pop(); } declaration-list ā> declaration ';' declaration-list declaration-list ā> declaration declaration ā> identifier ':' { id-list.type = identifier; } <ā however you store types identifier-list (maybe pointer into st?) identifier-list ā> identifier ( sBinOp constant ) ',' { st.put(identifier.lexeme, VAR, identifier-list.type, offset);
identifier-list identifier-list ā> identifier ( sBinOp constant ) { st.put(identifier.lexeme, VAR, identifier-list.type, offset);
Just suggestions, not to be taken literally Just suggestions, not to be taken literally
We can specialize due to the structure of our grammar: see next slide!
dblock ā> '[' { Env.push(st); st = new Env(); Stack.push(offset); offset = 0; } declaration-list ']' { dblock.type=record(st); dblock.width=offset; st=Env.pop(); offset=Stack.pop(); }
{ ( integer : x , y ) { ( real : x , z ) ⦠⦠} { ( Boolean : y ; character : z ) ⦠⦠} }
dblocks (6.3.5 and 6.3.6)
records (in separate symbol table), sequence of declarations at start of sblock
integer: x integer: y
Since declarations must be gathered together at the start of an sblock, and cannot themselves be directly nested, we can do better:
push offset = 8 onto stack
pop offset = 8 from stack push offset = 8 onto stack
pop offset = 8 from stack integer: x integer: y real: x real: z integer: x integer: y
Boolean: y character: zdblock ā> '[' { Env.push(st); st = new Env(); Stack.push(offset); offset = 0; } declaration-list ']' { dblock.type=record(st); dblock.width=offset; st=Env.pop(); offset=Stack.pop(); }
{ ( integer : x , y ) { ( real : x , z ) ⦠⦠} { ( Boolean : y ; character : z ) ⦠⦠} }
dblocks (6.3.5 and 6.3.6)
records (in separate symbol table), sequence of declarations at start of sblock
integer: x integer: y
Since declarations must be gathered together at the start of an sblock, and cannot themselves be directly nested, we can do better:
push offset = 8 onto stack
pop offset = 8 from stack push offset = 8 onto stack
pop offset = 8 from stack
AT RUNTIME
dblock ā> '[' { Env.push(st); st = new Env(); Stack.push(offset); offset = 0; } declaration-list ']' { dblock.type=record(st); dblock.width=offset; st=Env.pop(); offset=Stack.pop(); }
{ ( integer : x , y ) { ( real : x , z ) ⦠⦠} { ( Boolean : y ; character : z ) ⦠⦠} }
dblocks (6.3.5 and 6.3.6)
records (in separate symbol table), sequence of declarations at start of sblock
integer: x integer: y
Since declarations must be gathered together at the start of an sblock, and cannot themselves be directly nested, we can do better:
push offset = 8 onto stack
pop offset = 8 from stack push offset = 8 onto stack
pop offset = 8 from stack integer: x integer: y real: x real: z
AT RUNTIME
dblock ā> '[' { Env.push(st); st = new Env(); Stack.push(offset); offset = 0; } declaration-list ']' { dblock.type=record(st); dblock.width=offset; st=Env.pop(); offset=Stack.pop(); }
{ ( integer : x , y ) { ( real : x , z ) ⦠⦠} { ( Boolean : y ; character : z ) ⦠⦠} }
dblocks (6.3.5 and 6.3.6)
records (in separate symbol table), sequence of declarations at start of sblock
integer: x integer: y
Since declarations must be gathered together at the start of an sblock, and cannot themselves be directly nested, we can do better:
push offset = 8 onto stack
pop offset = 8 from stack push offset = 8 onto stack
pop offset = 8 from stack
AT RUNTIME
dblock ā> '[' { Env.push(st); st = new Env(); Stack.push(offset); offset = 0; } declaration-list ']' { dblock.type=record(st); dblock.width=offset; st=Env.pop(); offset=Stack.pop(); }
{ ( integer : x , y ) { ( real : x , z ) ⦠⦠} { ( Boolean : y ; character : z ) ⦠⦠} }
dblocks (6.3.5 and 6.3.6)
records (in separate symbol table), sequence of declarations at start of sblock
integer: x integer: y
Since declarations must be gathered together at the start of an sblock, and cannot themselves be directly nested, we can do better:
push offset = 8 onto stack
pop offset = 8 from stack push offset = 8 onto stack
pop offset = 8 from stack integer: x integer: y
Boolean: y character: zAT RUNTIME
dblock ā> '[' { Env.push(st); st = new Env(); Stack.push(offset); offset = 0; } declaration-list ']' { dblock.type=record(st); dblock.width=offset; st=Env.pop(); offset=Stack.pop(); }
{ ( integer : x , y ) { ( real : x , z ) ⦠⦠} { ( Boolean : y ; character : z ) ⦠⦠} }
dblocks (6.3.5 and 6.3.6)
records (in separate symbol table), sequence of declarations at start of sblock
integer: x integer: y
Since declarations must be gathered together at the start of an sblock, and cannot themselves be directly nested, we can do better:
push offset = 8 onto stack
pop offset = 8 from stack push offset = 8 onto stack
pop offset = 8 from stack
AT RUNTIME