CSC 330 Lecture Notes Week 7
Midterm Study Guide
Further Discussion of Operational Semantics, Topics from Chapters 4 & 5
Finish Topics from Week 6



  1. Corrections to Notes Week 6:
  2. Final pre-handin notes for Assignment 4.
    1. Please do install the evalPrint method
      1. A copy is available in Assignment 4 web index, so you can copy without retyping (which could be error-prone).
      2. The EJay print statement will be used to test your implementation of array and struct programs, since memory dumps of these data may not be entirely revealing.
    2. Feel free to define new classes or modify support classes.
      1. E.g., adding ReturnValue and CompositeLValue as discussed in class.
      2. In the case of modifying an existing class, you can compile fine with your modified source file along with a4-support.jar; your modified class will replace the one in the .jar file.

  3. Midterm study guide -- see the handout.

    Some Additional Discussion Semantics; in EJay and Other Languages; These Topics are NOT on the Midterm (but maybe the final)

  4. Coercion and casting (Section 4.3.5, but book's terminology is unconventional).
    1. Coercion is when the interpreter (or compiler) automatically converts otherwise non-equivalent data types.
      1. E.g., consider this EJay++ program:
        int i;
        string s;
        void main() {
            i = 10;
            s = "123";
            print i + s;
        }
        
      2. What happens with this in the current EJay interpreter, as specified for Assignment 4?
      3. What would it take to make this work?
    2. Casting is when the programmer explicitly converts one type to another.
      1. Casting may or may not involve the data conversion that goes on with coercion.
      2. In C, for example, casting is strictly a matter of calling one type of data another type, without any data conversion; this can be called a pure cast.
      3. E.g., in the following EJay++ program, a character type is cast to an integer type, without any change to the underlying data, then the addition is performed, then the data value is cast back to a char.
        int i;
        char c;
        int main() {
            c = 'x';
            i = (int) c;
            i = i + 1;
            c = (char) i;
            printf c;          // Prints the value 'y'
        }
        
        1. What happens with this in the current EJay interpreter, as specified for Assignment 4?
        2. What would it take to make this work?
      4. Consider now the following example, which runs without error if we use a C semantics of casting, but does not have at all the same result as the preceding example.
        int i;
        string s;
        int main() {
            s = "x";
            i = (int) s;
            i = i + 1;
            s = (string) i;
            print s;           // Prints the empty string.  Why?
        }
        
        What's going on here?

  5. Pointers (Section 5.3).
    1. Consider the following Pascal and C programs, which are semantically equivalent.

      Pascal:

      program
      var i: integer;
      var ip: pointer to integer;
      begin
      i = 10;
      ip = new integer;
      ^ip = i;
      print i, *ip;
      end;


      C:

      int i;
      int* ip;
      int main() {
      i = 10;
      ip = (int*) malloc(sizeof(int));
      *ip = i;
      printf("%d, %d0, i, *ip);
      }


    2. Semantically, a pointer is a memory address.
      1. Most commonly, it's an address into the heap.
      2. In C and C++, one can use the address-of operator to get a pointer to a memory location in the static pool or stack
        1. E.g., this is how call-by-reference is done in C, as illustrated at the end of Notes 6).
        2. Here's that example again:
          int i,j;
          
          void swap(int* x, int* y) {
              int temp;
              temp = *x;
              *x = *y;
              *y = temp;
          }
          
          int main() {
              i = 10;  j = 20;
              swap(&i, &j);
              printf("i=%d, j=%d", i, j);
          }
          
    3. Suppose we wanted to add pointers to EJay.
      1. What syntax should we use?
      2. Should we provide an address-of operator?
      3. How would the dereference and address-of operators be implemented in the interpreter?

  6. Garbage collection and memory leaks (Section 5.7).
    1. This is a pretty huge issue in the real world implementation of compilers and interpreter.
    2. The definition of "garbage" is a really excellent band with a Scottish lead singer.
    3. Oops, wrong environment -- the definition of "garbage" is when a program loses all references to a data value (aka, object) that has been allocated in the heap.
    4. E.g., consider the following EJay++ program:
      int i;
      ref int ip;
      
      void main() {
          ip = new int;
          f();
          g();
          ip = new int;      // Garbagizes the first new int pointed to by ip
      }
      
      ref int f() {
          ref int fip = new int;
          ...
      }                      // Return from f garbagizes the int pointed to by fip
      
      ref int g() {
          ref int gip = new int;
          ...
          free gip;          // This explicitly frees the int pointed to by gip
      }                      // thereby keeping it from becoming garbage
      
      1. The integer pointed to by the global ip variable turns into garbage when the first allocated integer is replaced by the second new integer.
      2. The integer pointed to by fip turns into garbage when f returns, since the lifetime of the fip local variable is over when f returns.
      3. The integer pointed to by gip does not turn into garbage, because of the explicit free command at the end of g.
    5. In languages, such as Java, that have garbage collection, garbaged values are periodically reclaimed, as the program runs.
    6. In languages, such as C++, that do not have garbage collection, garbaged values are consider memory leaks, which go unreclaimed until the program terminates.
    7. Questions:
      1. In the current EJay interpreter (not EJay++), is there garbage collection going on at any time?
      2. In an EJay++ interpreter, with pointers in the language, would garbage collection be necessary and/or advisable?
      3. Can garbage collection co-exist with an explicit free operator in a programming language?

  7. Some thoughts on the "bulkiness" of the EJayInterpreter, as currently designed.
    1. Consider the implementation of the operator methods.
      1. In the current design, it's done by textual copy/paste/modify.
      2. When on looks at the code for methods like evalPlus and evalTimes, it would seem that some kind of parameterization could be employed to get an more general method, like evalArithmeticOperator.
    2. What might the Java implementation of evalArithmeticOperator look like?
    3. If we had an eval method in Java itself, could that help?

  8. Adding eval as a first-class function into the EJay language (or Java, or any other language, for that matter).
    1. At this point, we have an EJay interpreter written in Java, with an implementation of an eval method that can evaluate an EJay construct.
    2. Suppose we wanted to make eval available to the EJay programmer, as a built-in EJay function.
    3. E.g., consider this
      int i,j,k;
      void main() {
          i = 10;
          j = 20;
          k = eval("i + j");
      }
      
    4. Would this be a useful EJay feature?
    5. How would it be implemented?




index | lectures | handouts | assignments | examples | doc | solutions | bin