Game Programming
Language
Program 7: Statements and Event Handlers
Once you get this phase
done, you are very close to finishing.
Overview:
Add the ability to parse and execute statements and event handler
blocks ("on blocks") to
the parser you created in program 6.
To get credit on this assignment, your program must open a window an
draw objects (as specified in p6), and it
must handle events correctly.
In other words, it should work just like my posted gpl
executables with everything except animation blocks and initialization blocks. See the gpl
manual.
Requirements:
For this assignment you will need to implement the following classes
(you can name them whatever you want):
Class
|
Inherits
|
Purpose
|
Statement
|
nothing
|
Base class for all statements,
has pure virtual function void execute()
|
If_stmt
|
Statement
|
Implements an if
statement. Contains: an Expression and Statement_blocks for then
and else (the else block is optional).
|
Print_stmt
|
Statement
|
Implements a print
statement. Contains: an Expression. The
Expression is evaluated to a string and that string is printed.
|
| Exit_stmt |
Statement |
Implements an exit statement. Contains: an Expression
that is evaluated to calculate the exit status. I.e. the value of
the expression is sent to the system function exit(). |
Assignment_stmt
|
Statement
|
Implements an assignment
statement. Contains: a Variable (the LHS), an
expression (the RHS), and an operator type (=, +=,. -=)
|
For_stmt
|
Statement
|
Implements a for loop
statement. Contains three Statement_blocks (one for initializer,
one
for incrementor, one for body of the loop) and an Expression.
|
Statement_block
|
nothing
|
Holds an ordered collection of
Statements and implements execute(). Contains a vector of
Statements. You may start with the Statement_block I posted for
p6.
|
Event_manager
|
nothing
|
Provides a mechanism for
associating Statement_blocks with events (space, leftarrow, rightarrow,
etc.). Contains: a vector of Statement_blocks for each type of
event
(space, leftarrow, etc.). Its functions must match those used in
window.cpp (or you must alter window.cpp to match your class).
You may start with the class Event_manager I posted for p6.
|
Hints:
Get one statement completely working (print is the easiest) to the
point that
you can parse and run a simple gpl program such as:
// this is test t001.gpl
on space
{
print("hello -- space key was pressed");
}
It is easy to implement statements if you have a base class (I call
mine class Statement) and have each type of statement (if, print, etc)
inherit this base class. The only things that the base class
needs to handle are construction and execution.
Every statement must belong to one and only one statement
block. Since statement blocks can be nested, it is easiest
to keep a global stack of statement blocks (this is the hardest part of this phase).
Here is a summary of parsing statements:
- When you see an "{", create an empty statement block and push it
on the global statement block stack (that is what the non-terminal
statement_block_creator is for).
- When you parse a statement, insert the statement onto the
statement block at the top of the global statement block stack.
- When you parse an "}", pop a statement off of the global
statement block stack (this is what the non-terminal
end_of_statement_block is for). A pointer to this statement block
will always be used by either (1) an if statement, (2) a for statement,
(3) an event
handler, or (4) an animation block.
The event manager is called from window.cpp thus you must either (1)
use the same functions names for Event_manager that I use in window.cpp
or (2) modify window.cpp so that
it calls the names in your class Event_manager.
All the event manager does is keep a vector of pointers to
Statement_block (an stl vector works well) for each type of event
(space, leftarrow, rightarrow, downarrow, uparrow, etc. See gpl
manual for the complete list). When an event
block is parsed (an "on block") you insert the new statement_block into
the event_manager (this is done in the action for the non-terminal
on_block).
The print and exit statements print the line number in the .gpl file on
which the statement appears. Consider the following program:
on space
{
print("hello -- space key was pressed");
}
The output for the print statement is:
gpl[3]: hello -- space key was pressed
In order to implement this, you need to
pass the line number to the parser from gpl.y. When you parse the
tokens T_PRINT and T_EXIT, put the line number in the union.
Turning in and Testing:
See
docs/turnin.html for a description of how to turn in assingments.
For this phase the tests include keyboard input which is redirected to
gpl from a file. See the p7/p8 section at the end of
docs/testing.html for a description of how the keyboard input testing works in gpl.