(* This testcase demonstrates the idea of syntax-directed testing, which will
* help you develop a comprehensive set of testcases for your project.
*
* There are rules in the handout that appear roughly as follows:
*
* Expr -> Expr1 AddMulOp Expr2
* AddMulOp -> T_MINUS | T_PLUS | T_STAR
* if type of Expr1 and Expr2 is numeric
* then type of Expr is smallest numeric type including the types
* of both operands
* else error
*
* The goal is to test ``all possible'' combinations of the application of
* this rule and the associated check. If all the tests pass as expected,
* you should have high confidence in the result. There are 3 operators
* appearing here ( -, +, * ), and 3 types, INTEGER, REAL, and ``error''.
* There are also 2 operands (left and right) that permits try all pairs of
* types. One might also count ``all'' kinds of erroneous types: BOOLEAN,
* etc. You might even have an ERROR type. Unfortunately, there are an
* infinite number of user defined types, so we can't do that. You might
* try one or two user-defined types, or verify by visual inspection of
* your code that user-defined types are handled here the same as BOOLEAN.
*
* In any case, all combinations of the above suggests having 3 * (3 ^ 2) = 27
* testcases for this rule. Your actual number could be lower if by visual
* inspection and rules of symmetry (e.g., left operand is handled the same
* as right operand) you can reason that certain testcases are unnecessary.
* Your number could be higher if you have more than one type falling into
* the error category (you probably should).
*
* Below is a single program that tests ``all'' combinations, assuming that
* - and * are handled the same as plus (test only +), and that there is
* only one erroneous type (BOOLEAN). The correct cases can really only
* be determined correct if your compiler prints the expression type to
* the standard error output (probably with the line number). In practice,
* you probably want to throw in a couple of + and * cases, as well as some
* with different erroneous types other than BOOLEAN.
*
* Putting several tests in a single program only works if your
* compiler keeps running after encountering the first error and
* doesn't get confused by the previous errors (it shouldn't).
*
* Beyond syntax-directed testing, you want to do ``stress testing'', which
* means writing complicated programs, testing weird conditions, etc.
*)
VAR x, y : INTEGER;
r, s : REAL;
b, c : BOOLEAN;
BEGIN
(* the assignments are here only to make the program syntactically correct *)
x := x + y; (* no error, expression is type INTEGER *)
r := r + s; (* no error, expression is type REAL *)
r := x + r; (* no error, expression is type REAL *)
r := r + x; (* no error, expression is type REAL *)
r := x + b; (* error, numeric expected, got BOOLEAN *)
r := b + x; (* error, numeric expected, got BOOLEAN *)
r := r + b; (* error, numeric expected, got BOOLEAN *)
r := b + r; (* error, numeric expected, got BOOLEAN *)
(* this might report two errors *)
x := b + c (* error, numeric expected, got BOOLEAN *)
END.