The Elements of Computing Systems: Building a Modern Computer from First Principles (33 page)

BOOK: The Elements of Computing Systems: Building a Modern Computer from First Principles
8.15Mb size Format: txt, pdf, ePub
9.2.2 Program Structure
The basic programming unit in Jack is a class. Each class resides in a separate file and can be compiled separately. Class declarations have the following format:
Each class declaration specifies a name through which the class can be globally accessed. Next comes a sequence of zero or more field and static variable declarations. Then comes a sequence of one or more subroutine declarations, each defining a method, a
function
, or a constructor. Methods “belong to” objects and provide their functionality, while functions “belong to” the class in general and are not associated with a particular object (similar to Java’s static
methods
). A constructor “belongs to” the class and, when called, generates object instances of this class.
All subroutine declarations have the following format:
where
subroutine
is either constructor, method, or function. Each subroutine has a name through which it can be accessed, and a type describing the value returned by the subroutine. If the subroutine returns no value, the type is declared void; otherwise, it can be any of the primitive data types supported by the language, or any of the class types supplied by the standard library, or any of the class types supplied by other classes in the application. Constructors may have arbitrary names, but they must return an object of the class type. Therefore the type of a constructor must always be the name of the class to which it belongs.
Figure 9.5
Jack syntactic elements.
 
Following its header specification, the subroutine declaration contains a sequence of zero or more local variable declarations, then a sequence of zero or more statements.
As in Java, a
Jack program
is a collection of one or more classes. One class must be named Main, and this class must include at least one function named main. When instructed to execute a Jack program that resides in some directory, the Jack run-time environment will automatically start running the Main.main function.
9.2.3 Variables
Variables in Jack must be explicitly declared before they are used. There are four kinds of variables: field, static, local, and parameter variables, each with its associated scope. Variables must be typed.
 
Data Types
Each variable can assume either a primitive data type (int, char, boolean), as predefined in the Jack language specification, or an object type, which is the name of a class. The class that implements this type can be either part of the Jack standard library (e.g., String or Array), or it may be any other class residing in the program directory.
 
Primitive Types
Jack features three primitive data types:
• int: 16-bit 2’s complement
• boolean: false and true
• char: unicode character
Variables of primitive types are allocated to memory when they are declared. For example, the declarations var int age; var boolean gender; cause the compiler to create the variables age and gender and to allocate memory space to them.
 
Object Types
Every class defines an object type. As in Java, the declaration of an object variable only causes the creation of a reference variable (pointer). Memory for storing the object itself is allocated later, if and when the programmer actually
constructs
the object by calling a constructor. Figure 9.6 gives an example.
Figure 9.6
Object types (example).
 
The Jack standard library provides two built-in object types (classes) that play a role in the language syntax: Array and String.
 
Arrays
Arrays are declared using a built-in class called Array. Arrays are one-dimensional and the first index is always 0 (multi-dimensional arrays may be obtained as arrays of arrays). Array entries do not have a declared type, and different entries in the same array may have different types. The declaration of an array only creates a reference, while the actual construction of the array is done by calling the Array.new(length) constructor. Access to array elements is done using the a [j] notation. Figure 9.2 illustrates working with arrays.
 
Strings
Strings are declared using a built-in class called String. The Jack compiler recognizes the syntax “xxx” and treats it as the contents of some String object. The contents of String objects can be accessed and modified using the methods of the String class, as documented in its API. Example:
Type Conversions
The Jack language is weakly typed. The language specification does not define the results of attempted assignment or conversion from one type to another, and different Jack compilers may allow or forbid them. (This under-specification is intentional, allowing the construction of minimal Jack compilers that ignore typing issues.)
Having said that, all Jack compilers are expected to allow, and automatically perform, the following assignments:
 
■ Characters and integers are automatically converted into each other as needed, according to the Unicode specification. Example:
■ An integer can be assigned to a reference variable (of any object type), in which case it is treated as an address in memory. Example:
■ An object variable (whose type is a class name) may be converted into an Array variable, and vice versa. The conversion allows accessing the object fields as array entries, and vice versa. Example:
Variable Kinds and Scope
Jack features four kinds of variables. Static variables are defined at the class level and are shared by all the objects derived from the class. For example, a BankAccount class may have a totalBalance static variable holding the sum of balances of all the bank accounts, each account being an object derived from the BankAccount class. Field variables are used to define the properties of individual objects of the class, for example, account owner and balance. Local variables, used by subroutines, exist only as long as the subroutine is running, and parameter variables are used to pass arguments to subroutines. For example, our BankAccount class may include the method signature method void transfer- (BankAccount from, int sum), declaring the two parameters from and sum. Thus, if joeAccount and janeAccount were two variables of type BankAccount, the command joeAccount.transfer(janeAccount, 100) will effect a transfer of 100 from Jane to Joe.

Other books

The Haunting of Hill House by Shirley Jackson
Death in High Places by Jo Bannister
Connections by Amber Bourbon
License to Date by Susan Hatler
Pretty in Ink by Lindsey Palmer
Atlantis Redeemed by Alyssa Day