The Beginner’s Tutorial
Here I give a small tutorial on GRIP so that beginners can get a feel of
programming itself. The examples are all syntactically correct GRIP program
fragments.
The conventional style of programming is imperative. This means that programs
are sequences of statements. Statements denote actions to be executed in
the order which they appear in. The basic statement is the assignment statement
of the form
This means that we want to assign value into variable. That may be confusing
to someone who doesn't know anything about programming. If you are familiar
with calculators, you will know that the keys M+ and M- add and subtract
values from a place you can’t see called the memory. Now imagine that we
have several of these memory cells which have names and the assignment statement
sets the cell variable to contain value. The name of a cell, called an identifier,
is a sequence of letters and digits starting with a letter. Examples of valid
identifiers:
GRIP is not case sensitive, so bluebird, BLUEBIRD, and BlUeBiRd are the same!
Note that a value is not restricted to a simple number (numbers are written
like you would expect them to be). It can be an algebraic expression that
can contain identifiers. Such constructs are called expressions. Examples
of valid expressions:
Note that all operators have the same priority in GRIP, so the first expression
will be interpreted as
Because of this, do not forget to parenthesize! Now we can give you examples
of valid assignment statements:
nobodyOrSomebody <- nobody + somebody;
Besides the assignment statement, there is the cond (conditional) statement
of the form
The goal of the statement is to be able to modify how the program goes on
and choose which statement to execute. The statement works like this:
- Evaluate the first expression. If it is nonzero, execute the corresponding
statement and stop execution of the cond statement.
- Otherwise, check if we are on the last expression. If we are, then
check whether there is an else part. If yes, execute the statement corresponding
to the else. If no, stop execution of the conditional.
- If we aren’t on the last expression, repeat the procedure for the remaining
expressions.
For the conditional, there are the comparison operators <, >, and =
and the logical operators & (logical and), | (logical or), and ! (logical
negation) which return 1 for true and 0 for false. & and | are short-circuit
operators, which means that the second expression is not evaluated unless
absolutely necessary.
Examples of valid cond statements:
exit < 0 exit <- exit + 1;
exit > 0 exit <- exit - 10;
Another statement that is allowed is the for-statement, which allows you
to repeat a statement more than once. It is of the form
for (statement expression; statement) statement
It is executed as follows:
- Perform the first statement.
- If the value of expression is zero, proceed to the next statement after
the for-statement.
- Otherwise perform the last statement, then the second statement, then
start over from step 2.
Example of a valid for-statement:
for (i <- 1; i < 11; i <- i + 1;)
Here, we add to j all the numbers from 1 to 10. But what if we want to execute
more than one statement in a for-statement or conditional? The solution to
this dilemma is the compound statement. It is of the form
All the statements are executed sequentially. Here is an example:
for (i <- 1; i < 11; i <-
i + 1;)
Here, j is initialized to zero before execution of the for-statement begins.
There is one thing in GRIP I have not mentioned: we need to declare the variables
before we can use them! GRIP allows this with this construction: A compound
statement has an optional declaration part before the statements which consists
of a sequence of declarations. A declaration has the following form:
ident1 ident2 . . . identk : specifier;
A specifier contains type information about the variables that we want to
declare. For instance:
are all valid specifiers. Examples of valid declarations:
i prime k : integer;
unique : real;
A declaration can be overridden in an underlying compound statement.
Now I can introduce to you several other statements:
- The empty statement “;”does not do anything. It is included, for instance
if you want to exclude the initialization in a for loop, or (more often) the
incrementation.
put elem1 elem2 . . . elemk;
outputs all the expressions (may be strings enclosed in quotes, e.g. “Hello,
world!”) that are given to it, so you can see the results of the program.
For example:
put “X + Y = “ x + y “. X = “ x “. Y = “ y;
I shall now touch on another concept called vectors. A vector is like a variable
containing numbered elements. A specifier for a vector is of the form
where size is a number denoting how large the vector is. An element of a
vector can be extracted by the notation
meaning the expression-th element of the vector. You can assign to an element
of a vector:
but you can’t assign to the whole vector at once. It is an error if you reference
a vector’s element that is less than 0 or more than the size declared in
the specification.
A program in GRIP has the form of
program identifier statement
The identifier can be anything, it may even conflict with another identifier
somewhere in the program. It’s just a way to name the program, and give it
a sort of personality. There also can be comments enclosed in /* and */.
One valid program is (the classic “Hello, World!” :-P):
program HelloWorld
put “Hello, World!”;
Quite. That should be readable enough.
Now for a more complex example, which calculates the factorial of N.
The factorial of n (n!) is calculated as follows:
/* Check: we can’t calculate n! is n < 0. */
n < 0 put “Error : Can’t calculate
the factorial of a negative number!!”;
else { /* We can calculate it.
*/
for (j
<- 1; j - 1 < N; j <- j + 1;)
put “The
factorial of “ N “ is “ m;
Note that we check for an error (negative argument) using the cond statement
in here.