CSC 533: Programming Languages
Spring 2021

HW3: Implementing Scopes


In the HW2 version of the SILLY interpreter, all of the variables in a SILLY program were treated as being in the same, global scope. You are to modify the intepreter so that each compound statement defines a new scope. That is, statements inside the curly braces of a compound statement should be considered as inside a new, nested scope. When a variable is declared within a compound statement, it is assumed to be local to the current scope (assuming it does not currently exist). When execution reaches the end of that scope, the local variable's lifetime ends. As before, declaring a variable that already exists, even if it was declared in a larger scope, should result in a runtime error. When looking up the value of a variable, static scoping should be used. That is, if the variable is declared within the current scope, the corresponding value should be accessed. If it is not declared in the current scope, the enclosing scope should be checked next, then the scope that encloses that scope, etc.

To implement nested scopes, you will need to modify the MemorySpace class so that a stack of scopes (variable/value maps) is maintained (as opposed to a single, global scope/map). New methods should be added to the MemorySpace class for beginning a new scope (i.e., pushing a new map on the stack) and ending the current scope (i.e., popping the current map off the stack). When a compound statement is executed, a new scope should begin so that any variables declared within that compound statement are stored within that scope. When execution ends, that scope associated scope ends as well, removing any local variables. The methods for declaring, storing, and looking up variables in the stack segment will also need to be modified so that they properly access variable values from the stack.

SAMPLE CODE (output in red)
  >>> repeat 2 {
          str temp = "inside" ;
          output "temp" , "=" , temp ;
      }
  temp = inside
  temp = inside 
  >>> str temp = "outside" ;
  >>> output "temp" , "=" , temp ;
  temp = outside 
  >>> str x = "global" ;
  >>> repeat 4 {
          output x ;
          str y = "local" ;
          output y ;
      }
  global
  local
  global
  local
  global
  local
  global
  local 
  >>> output x ;
  global 
  >>> str test1 = "outer" ;
      {
          str test2 = "middle" ;
          {
              str test3 = "inner" ;
              output test1 , test2 , test3 ;
          }
          output test1 , test2 ;
      }
  outer middle inner
  outer middle 		
  >>> output test1 ;
  outer 
  >>> int test2 = 1010 ;
  >>> output test2 ;
  1010 
  >>> int i = 1 ;
  >>> while i <= 5 {
          int sum = 0 ;
          int j = 1 ;
          while j <= i {
              sum = sum + j ;
              j = j + 1 ;
          }
          output i , sum ;
          i = i + 1 ;
      }
  1 1
  2 3
  3 6
  4 10
  5 15    
  >>> output i ;
  6 
  >>> if i > 0 { 
          int double = 2 * i ;
          output double ;
      }
      else {
          int double = ( 0 - i ) * 2 ;
          output double ;
      }
  12 
  >>> i = -1 * i ;
  >>> output i ;
  -6 
  >>> if i > 0 {
          int double = 2 * i ;
          output double ;
      }
      else {
          int double = ( 0 - i ) * 2 ;
          output double ;
      }
  12  
  >>> str double = "new" ;
  >>> output double ;
  new