1. Adding a built-in functions isset and unset.
- isset(lvalue) evaluates to the int value:
- 1 if the lvalue has been set
- 0 if the lvalue has never been set or has been explicitly unset (using unset(lvalue) function)
- an lvalue becomes set when it is
- initialized at declaration
- assigned from a constant
- assignment from a set lvalue
assigned from a function call- arrays are considered set if any element has been set
- records are considered set if any field has been set
variables which are not set have the default values as follows:
- ints have default value 0
- strings have default value ""
- arrays and records have default value nil (the case of array differs from the original Tiger definition of array)
- fields of records have default values according to these rules
unset(lvalue) marks the object as not set as well as resetting its value to the default
NOTE: For the purpose of this question assume that a declaration statement may not have an initialization.
For example: "var i: int;" is now a legal declaration.Example of a Tiger program using the isset and unset functions.
let
type name = { first: string, last: string}
var customer_name: namefunction setname() =
/* sets the global variable customer_name via internet service */function printname() =
/* prints the global variable customer_name taking into
account only one name */
if isset(customer_name) then
if isset(customer_name.first) & isset(customer_name.last)=0 then
print( concat(customer_name.first, " first is last name"))
else if isset(customer_name.first) & isset(customer_name.last) then
print( concat(customer_name.first, customer_name.last))
else if isset(customer_name.first) = 0 & isset(customer_name.last) then
print( concat("last is first name ",customer_name.last))in
( setname();
printname())
endDescribe the changes needed to the various compiler phases and in particular code-generation, livenness analysis and register allocation. Demonstrate your answer on the example.
2. Adding type exceptions and statements try-catch-finally and throw.
Example of a Tiger program with exceptions:
- Defining exceptions
- syntax
- exception id(type);
- example
- exception MyException(int);
- notes
- The id specifies the name of the exception
- The type specifies the type of data to accompany the exception
- The type is optional, if there is no data
- Exceptions may only be defined in the global scope
- Handling exceptions
- syntax
- try (
...statements...
)
catch(Exception_name x) (
...statements...
)
...more catch constructs...
finally (
...statements...
)- notes
- A try block may be followed by zero or more catch constructs
- The finally construct is optional. If present, the code will be executed only when control transfers out of the block by break or when an exception is raised.
- The catch parameter name x may be omitted if it is not used
- The catch parameter name x must be omitted if there is no data type
- Raising exceptions
- syntax
- throw Exception_name(expr);
- example
- throw MyException(i);
- notes
- The exception name must be a defined exception
- The expression type must match the defined exception data type
- The expression must be omitted if the exception has no data type
- Control transfers to the catch construct for the named exception of the nearest enclosing try block, executing any finally blocks found along the way
- Control may transfer up the function call chain to find a handler
For example:
function p()
try ( q() )
catch(e1) ...function q()
try( r() )
catch(e1)
finally(...)function r()
try( u() )
catch(e2)
finally(...)function u()
throw e1The throw command will cause the execution of the finally block in function r, afterwards the execution of catch(e1) in function q() and the finally block in function q().
- Unhandled exceptions terminate the program with an error message
let
exception UnknownUser(string)
exception WrongPin()
type ID = { name: string, pin: int }
type IDarray = array of ID
var user: string = ""function getLogin(): ID =
/* gets form the user login name and pin */function login(): string =
let var ids := IDarray[2] of nil
var id: ID := getLogin()
var i: int := 0
var res:string := ""
in
( ids[1] := ID {name = "dal", pin=1234};
ids[2] := ID {name = "tball", pin= 5678};while i < 2 do
( if ids[i].name = id.name then
if ids[i].pin = id.pin then res := id.name
else throw WrongPin;
i := i+1 );if i = 2 then
throw UnknownUser(id.name)
else
res )
end
in
while(1) do
(try
user := login()
catch(UnknownUser u)
(print( concat( u, " is an invalid user name" ));
break );
catch(WrongPin)
(print( "invalid PIN" );
break );
print( concat(user ," is logged in" ) );
break )
end
a. (15%) Describe the changes needed to the various compiler phases and in particular code-generation.
Show the intermediate assembler representation of each relevant statement. Demonstrate your answer on the example.b.(5%) Do exceptions give the programmer any new power (can everything done with a program using exceptions be done by a
program without exceptions)? Give advantages/disadvantages of exceptions.
3. Removing user defined types. This means there is no declarations of type thus only string and int primitive data types are supported.Part III : General (20%)
a (17%) Which phases of the Tiger compiler will be affected and how?
b. (3%) How does this affect the usability of the Tiger language?4. Not allowing nested functions. This means all functions have the same level (like C).
a (17%) Which phases of the Tiger compiler will be affected and how?
b. (3%) How does this affect the usability of the Tiger language?
5. Identify for every activity when does it occur, i.e., at compile-time (at which phase), run-time, or different time (specify). Justify your answer.
- Nil dereference in Tiger. For example referring to a field of a Nil record variable.
- Spill of register ri into the current activation record.
- a reference in C to an element which have been freed.
- the regular expression r requires a lookahead buffer which is too big.
- "stack overflow" for a Tiger program. That is no more space in the activation record.