BLOCKS; - Every block would trigger a new activation record. Delcarations in the new activation record would shadow (override) delcarations in the old record, but unshadowed declarations would still be accessible - essentially, you have a block scope- things defined in the block are searched for first, but if they don't exist, you go outside that innermost scope to find them - Activation record structure: # of variables in the structure (as an int) followed by a list of ints, each one containing the cumulative size of the variable list up to that point. So for instance, if I have {int x, float y, float[20] z} the record would be 3 [0,4,16]. After the list, you have the variables set up in adjacent bytes. So the location of x would be starting at loc of activation record + 4*4 (for the initial number and list of 3 elements) + 0. The location of y would be location of activiation record + 4*4 + 4. - the size of the activation recrod would be sizeof(int) + num_records * sizeof(int) + symbol_table->cur_size, where cur_size is a field of the environment that stores the current size of all elements in the symbol table - The methods for this are located in env.c. They are sizeof_record, which gets the size of the activation record, and locof_record, which gets the location of a single variable within the record.