Download Object Oriented Extensions: Adding Methods and Instance Variables in CS414-2008S and more Study notes Computer Science in PDF only on Docsity!
10-0: Classes
- simpleJava classes are equivalent to C structs
class myclass { struct mystruct { int x; int x; int y; int y; boolean z; int z; } }
- What do we need to add to simpleJava classes to make them true objects?
10-1: Adding Methods to Classes
- To extend simpleJava to be a true object oriented language, classes will need methods.
- New definition of classes:
class { <List of instance variable declarations, method prototypes, & method definitions> }
- As in regular Java, instance variable declarations & method definitions can be interleaved.
10-2: Adding Methods to Classes
class Point { int xpos; int ypos; Point(int x, int y) { xpos = x; ypos = y; } int getX() { return xpos; } int getY() { return ypos; } void setX(int x) { xpos = x; } void setY(int y) { ypos = y; } }
10-3: Adding Methods to Classes
class Rectangle { Point lowerleftpt; Point upperrightpt; Rectangle(Point lowerleft, Point upperright) { lowerleftpt = lowerleft; upperrightpt = upperright; } int length() { return upperrightpt.getX() - lowerleftpt.getX(); } int height() { }return upperrightpt.getY() -^ lowerleftpt.getY(); int area() { return length() * height(); } }
10-4: “This” local variable
- All methods have an implicit “this” local variable, a pointer to the data block of the class
- Original version:
Point(int x, int y) { xpos = x; ypos = y; }
Point(int x, int y) { this.xpos = x; this.ypos = y; }
10-5: Compiler Changes for Methods
- Modify Abstract Syntax Tree
- Modify Semantic Analyzer
- Classes will need function environments
- “This” pointer defined for methods
- Modify Abstract Assembly Generator
- Maintain the “this” pointer
10-6: Modifications to AST
- What changes are necessary to the AST to add methods to classes?
- Which tree nodes need to be changed?
- How should they be modified?
10-7: Modifications to AST
- ASTClass: contain prototypes and method definitions as well as instance variable declarations
- Add abstract class ASTClassElem
- ASTMethod, ASTMethodPrototype, ASTInstanceVarDef would be subclasses
- What would .jj file look like?
10-8: Changes to .jj file
void classdef() : {} { classElems() } void classElems() : {} { (classElem())* } void classElem() : {} { ((( )* ) | ( formals() ) ( | statements() )) }
MethodCall(bar)
Integer_Literal(5)
identifier(B)
ClassVar
ArrayVar identifier(x)
BaseVar Integer_Literal(4)
10-16: Modifications to AST
- Constructors have slightly different syntax than other functions
class Integer {
int data;
Integer(int value) { data = value; }
int intValue() { return data; } }
10-17: Modifications to AST
Integer(int value) { data = value; }
- Create the abstract syntax
Integer Integer(int value) { data = value; return this; }
10-18: Modifications to AST
Integer(int value) { data = value; }
- Create the abstract syntax
Integer Integer(int value) { data = value; return this; }
10-19: Modifications to AST
- Constructors
- AST needs to be modified to allow constructors to take input parameters
10-20: Changes in Semantic Analysis
- Without methods, the internal representation of a class contains a only a variable enviornment
- How should this change if we add methods to classes?
10-21: Changes in Semantic Analysis
- Add Function Environment to to the internal representation of class types
class Integer {
int data;
Integer(int initvalue) { data = initvalue; }
int intValue() { return data; } }
10-22: Changes in Semantic Analysis Type Enviornment:
int boolean void
INTEGERTYPE BOOLEANTYPE VOIDTYPE int
void
Integer
boolean
KeyStack
Integer
data
CLASS TYPE KeyStack data newscope
newscope
Variable Enviornment
Integer
KeyStack intValue Integer
Function Enviornment
newscope
intValue
FUNCTION TYPE
Return Type Parameters
FUNCTION TYPE
Return Type Parameters
(none)
int bar(int x) { return foo(x); } }
10-29: SA: Methods & Instance Vars
- What extra work do we need to do to allow instaceVar to be seen in foo?
10-30: SA: Methods & Instance Vars
- What extra work do we need to do to allow instaceVar to be seen in foo?
- None! InstanceVar is already in the global variable environment.
- (We will need to do a little extra work to generate abstract assembly – why?)
10-31: SA: Methods from Methods
- What extra work do we need to do to allow bar to call the function foo?
10-32: SA: Methods from Methods
- What extra work do we need to do to allow bar to call the function foo?
- None!
- When we analyzed foo, we added the proper prototype to both the global function environment and the local function environment
10-33: SA: Constructors
- new MyClass(3,4)
- Look up “MyClass” in the type environment, to get the definition of the class
- Look up “MyClass” in the function environment for the class
- Check to see that the number & types of parameters match
- Return the type of MyClass
10-34: SA: Example
class SimpleClass { int x; int y; SimpleClass(int initialx, initialy) { x = initialx; y = initialy; void main { } SimpleClass z; int w; int average() { int ave; z = new SimpleClass(3,4); w = z.average(); ave = (x + y) / 2; } return ave; } }
10-35: SA – Example
- To analyze class SimpleClass
- Create a new empty variable & function environment
- Create a new class type that contains these environments
- Begin a new scope in the global function & variable environments
- Add “this” to the global variable environment, with type SimpleClass
- Add x and y to both the local and global variable environment
- Add the prototype for the constructor to the local and global environments
10-36: SA – Example
- To analyze class SimpleClass (continued)
- Analyze the body of SimpleClass
- Add prototype for average to both the local and global function environment
- Analyze the body of average
- End scope in global function & variable environments
10-37: SA – Example
- To analyze the body of SimpleClass
- Begin a new scope in the global variable environment
- Add initialx and intialy to the global variable environment (both with type INTEGER)
- Analyze statement x = initialx using global environments
- Analyze statement y = initialy using global environments
- Analyze statement return this; using global environments
- Added implicitly by the parser!
- End scope in the global variable environment
10-38: SA – Example
- To analyze the body of average
- Begin a new scope in the global variable environment
- Add ave to the global variable environment with type INTEGER
- Analyze the statement ave = (x + y) / 2 using global environments
- Analyze the statement return ave using global environments
- End scope in local variable environment
10-39: SA – Example
- To analyze the body of main
- Begin a new scope in the variable environment
- Add z to the variable environment, with the type SimpleClass
- Analyze the statement z = new SimpleClass(3,4);
SP
FP
Input Parameter 1
Input Parameter 2
Input Parameter n ...
Local Variables
Saved Registers
Current Activation Record
Previous Activation Record
this pointer
10-45: Activation Record for Methods
- To set up an activation record (at the beginning of a method call
- Save registers, as normal
- Set the FP to (SP + WORDSIZE)
- So that the “this” pointer ends up in the correct activation record
- Passed as the 0th parameter
- “this” is at location FP
- First local variable is at location FP-WORDSIZE
- First input parameter is at location FP+WORDSIZE
10-46: AATs for Method Calls
- Passing implicit “this” parameter
- Each method call needs to be modified to pass in the implicit “this” parameter.
- Need to handle two types of method calls
- Explicit method calls
- Implicit Method Calls
- Class contains methods foo and bar
- foo calls bar (without using “this”)
10-47: Explicit Method Calls
• AST:
MethodCall(foo)
Integer_Literal(4)
Integer_Literal(3)
BaseVar
identifier(x)
- What should the Abstract Assembly be for this method call?
- (What should we pass as the “this” pointer?)
10-48: Explicit Method Calls
Register(FP)
Operator(-)
Constant(x_offset)
- AAT for x.foo(3,4) CallExpression("foo")
Memory Constant(3) Constant(4)
Register(FP)
Operator(-)
Constant(x_offset)
10-49: Implicit Method Calls
class MyClass { void main() { int x; int foo(int y) { x = myfunction(3); return y + 1; } } void bar() { int x; x = foo(7); } } int myfunction(int a) { return a + 1; }
10-50: Implicit Method Calls
- x = myfunction() in main is a function call – don’t need to pass in a “this” pointer
- x = foo(7) in bar is a method call – need to pass in a “this” pointer
- Add another field to FunctionEntry: Method bit
- false if entry is a function (no need for “this” pointer)
- true if entry is a method (need 0th parameter for “this” pointer)
- Abstract Assembly for foo(7)
CallExpression("foo")
Memory Constant(7)
Register(FP)
10-58: Constructor Calls
- Just like any other method call
- But... we need an initial “this” pointer
- No space has been allocated yet!
10-59: Constructor Calls
- The AAT for a constructor call needs to:
- Allocate the necessary space for the object
- Call the constructor method, passing in the appropriate “this” pointer
- What should the AAT for new Integer(3) be?
10-60: Constructor Calls
- The AAT for a constructor call needs to:
- Allocate the necessary space for the object
- Call the constructor method, passing in the appropriate “this” pointer
- What should the AAT for new Integer(3) be?
CallExpression("Integer")
Constant(3)
Constant(Integer_Size)
CallExpression("Allocate")
10-61: AATs for Instance Variables
class InstanceVsLocal { int instance;
void method() { int local;
local = 3; /* line A / instance = 4; / line B */ }
- Stack / heap contents during method?
- AAT for line A?
- AAT for line B?
10-62: Instance vs. Local Variables
- Instance variables and local variables are implemented differently.
- Need to know which variables are local, and which variables are instance variables (just like methods)
- Add instanceVar bit to VariableEntry
- true for is instance variable
- false for local variables / parameters
10-63: Instance Variable Offsets
- Keep track of two offsets (using two globals)
- Local variable offset
- Instance variable offset
- At the beginning of a class definition:
- Set instance variable offset to 0
- Insert “this” pointer into the variable environment, as a local variable
- At the beginning of each method
- set the local variable offset to -WORDSIZE
- Remember the “this” pointer!
10-64: Instance Variable Offsets
- When an instance variable declaration is visited:
- Add variable to local & global variable environments, using the instance variable offset, with instance bit set to true
- Decrement instance variable offset by WORDSIZE
- When a local variable declaration is visited:
- Add variable to only the global variable environment, using the local variable offset, with instance bit set to false
- Insert local to the global variable environment, with the “instance variable” bit set to 0, with offset WORD- SIZE (remember “this” pointer!)
- Abstract Assembly for instance
10-70: AATs for Instance Variables
- Insert instance to the global variable environment, with the “instance variable” bit set to 1, with offset 0
- Insert local to the global variable environment, with the “instance variable” bit set to 0, with offset WORD- SIZE (remember “this” pointer!)
- Abstract Assembly for instance Memory
Register(FP)
Operator(-)
Memory Constant(Wordsize)
10-71: Instance vs. Local Variables
class MyClass {
int instance1; int instance2;
void method(int param) { int local;
local = instance1 - instance2 + param; } }
- Stack / heap contents during method?
- AAT for assignment statement?
10-72: AATs for Instance Variables
- What about class variables and array variables?
class Class1 { void main() { int x; Class2 C2 = new Class2(); int y[]; C2.C1 = new Class1(); } C2.C1.y = new int[10]; class Class2 { C2.array = new int[10]; C2.C2 = new Class1[5]; Class1 C1; C2.C2[3] = new Class1(); int array[]; C2.C2[3].y = new int[5]; Class1 C2[]; void method() { C2.method(); array[2] = 3; } C1.x = 3; C1.y[2] = 4; C2[3].y[4] = 5; } }
10-73: Code Generation
- When methods are added to classes, what changes are necessary in the code generation stage?
10-74: Code Generation
- When methods are added to classes, what changes are necessary in the code generation stage?
- None!
- The AAT structure is not changed
- Prior modifications create legal AAT
- Code Generator should work unchanged.
10-75: Inheritance
class Point { int xpos; int ypos; Point(int x, int y) { xpos = x; ypos = y; } int getX() { void setX(int x) { return xpos; xpos = x; } } int getY() { void setY(int y) { return ypos; ypos = y } } }
10-76: Inheritance
class Circle extends Point { int radiusval; Circle(int x, int y, int radius) { xpos = x; ypos = y; radiusval = radius; } int getRadius() { return radiusval; } void setRadius(int radius) { radiusval = radius; } }
10-77: Inheritance
- What changes are necessary to the lexical analyzer to add inheritance?
10-78: Inheritance
- What changes are necessary to the lexical analyzer to add inheritance?
- Add keyword “extends”
- No other changes necessary
10-79: Inheritance
- What changes are necessary to the Abstract Syntax Tree for adding inheritance?
10-80: Inheritance
- baseclass2 contains a, b
- subclass2 contains 4 instance variables, only 3 are accessible a, b (int), c
10-86: Environment Management
class baseclass2 { int a; boolean b; } class subclass2 extends baseclass2 { int b; boolean c; }
- subclass2 contains 4 instance variables, only 3 are accessible a, b (int), c
- How could we get at the boolean value of b?
10-87: Environment Management
class baseclass3 { int foo() { return 2; } int bar() { return 3; } } class subclass3 extends baseclass3 { int foo() { return 4; } }
10-88: Environment Management
- When subclass A extends a base class B
- Make clones of the variable & function environments of B
- Start A with the clones
- Add variable and function definitions as normal
10-89: Environment Management
- To analyze a class A which extends class B
- begin scope in the global variable and function environments
- Look up the definition of B in the type environment
- Set superclass pointer of A to be B
- Add all instance variables in B to variable environment for B, and the global variable environment
- Add all function definitions in B to the function environment for A and the global function environment
10-90: Environment Management
- To analyze a class A which extends class B (continued)
- Add “this” pointer to the variable environment of A
- Overriding the old “this” pointer, which was of type B
- Analyze the definition of A, as before
- End scope in global function & variable environments
10-91: Assignment Statements
- To analyze an assignment statement
- Analyze LHS and RHS recursively
- If types are not equal
- If RHS is a class variable, follow the superclass pointer of RHS until either LHS = RHS, or reach a null superclass
- Use a similar method for input parameters to function calls
10-92: Abstract Assembly
- What changes are necessary in the abstract assembly generator for adding inheritance?
10-93: Abstract Assembly
- What changes are necessary in the abstract assembly generator for adding inheritance?
- At the beginning of a class definition, set the instance variable offset = size of instance variables in super- class, instead of 0 - When instance variables are added to subclass, use the same offsets that they had in superclass.
- No other changes are necessary!
10-94: Code Generation
- What changes are necessary in the code generator for adding inheritance?
10-95: Code Generation
- What changes are necessary in the code generator for adding inheritance?
- None – generate standard Abstract Assembly Tree
10-96: Inheritance
- Adding inheritance without virtual functions can lead to some odd behavior
10-97: Inheritance