I suggest to move all rules that deal with SYSTEM or OOC specific
capabilities into separate documents.  For this list, the focus is
"core O2".  Extensions add their own accept and reject rules to
outline the differences to the core.

Missing Tests 2002/10/16: In calls, check that receiver and index in
designators computed once.



9.1 Assignments
---------------

  var := expr

REJECT:

  1) var is not a variable designator  [Assign1, Assign2]
  2) var is imported read-only  [Assign3, Assign4]

REJECT (assignment compatible):

  1) expr is not a value (e.g., is a type name)  [Assign5, Assign6]
  2) Texpr and Tvar have same structure, but are not the same type  [Assign7]
  3) expr is NIL, but Tvar is not pointer or procedure  [Assign8]
  4) Tvar is ARRAY n OF CHAR, expr is too long string const  [Assign9]
  5) Texpr and Tvar are procedure type, but the number of arguments
     do not match  [Assign10, Assign14]
  6) Texpr and Tvar are procedure type, but the result type is
     not the same  [Assign11]
  6) Texpr and Tvar are procedure type, but not all formal
     parameters types are equal  [Assign12]
  7) Texpr and Tvar are procedure type, but the there is a mismatch
     with VAR/value parameters  [Assign13]

ACCEPT (assignment compatible)

  1) Texpr and Tvar are the same type  [HOTLoop1]
  2) types are numeric and Tvar includes Texpr  [Array1]
  3) both are records, and Texpr extends Tvar  [Record11]
  4) both are record pointers, and Texpr extends Tvar  [With2]
  5) Tvar is pointer type, and expr is NIL  [OpExprCompat1]
  6) Tvar is procedure type, and expr is NIL  [ProcVar6]
  7) Tvar is ARRAY n OF CHAR, expr is "small enough" string const
     [OpExprCompat1]
  8) Tvar is procedure, expr is name of procedure with matching 
     formal parameters  [ProcVar1]

ERROR (assignment compatible)

  1) var is a record whose dynamic and static type differ [Record11]



9.2 Procedure Calls
-------------------

  proc[(arg1, arg2, ...)]

REJECT:

  1) type of proc is not procedure  [Proc1]
  2) proc is a function procedure  [Proc2, HOTFunction8]
  3) too few or too many entries in argument list  [Proc3, Proc4, Proc5]
  4) argument not assignment compatible to value parameter  [Proc6]
  5) argument to VAR parameter is not a variable designator  [Proc7]
  6) argument to VAR parameter is imported read-only  [Proc8]
  7) formal parameter type is an open array, but the argument is
     not array compatible (wrong base type, different number of
     dimensions)  [Proc9, Proc10, Proc11, Proc12]

ACCEPT:
  
  1) accept "proc" and "proc()" if the formal parameter list
     is empty  [TBProc1, TBProc2]
  2) argument of basic type (value and VAR); assignment 
     to value parameter are invisible outside proc, while
     assigning to VAR parameter is visible  [Proc13, HOTVarPar1]
  3) argument of record type (value and VAR); dito  [Record3, Record11]
  4) argument of array type (value and VAR); dito  [Array9, Array10]
  5) formal parameter Tf is a VAR record, and the argument type is
     an extension of Tf  [Record5, Record8]
  6) formal parameter is ARRAY OF CHAR, argument is a string
     constant  [HOTDesignator1]
  7) Check that a receiver designator is computed just once.
  8) Check that an index of an argument designator is computed just
     once. 


9.3 Statement sequences
-----------------------

ACCEPT:

  1) empty sequence  [HOTLoop6]
  2) several semicolons ";" between statements  [HOTIf1]
  3) ";" before and after a sequence  [HOTIf1]



9.4 If statements
------------------

  IF expr1 THEN seq1 { ELSIF exprN THEN seqN } [ELSE seqE] END

REJECT:

  1) expr is not boolean  [HOTIf4]

ACCEPT:

  1) first expr evaluating to TRUE wins  [HOTIf1, HOTIf2, HOTIf3]
  2) ELSE is executed if not guard is TRUE  [HOTIf1, HOTIf3]



9.5 Case statements
-------------------

  CASE expr OF Case {| Case} [ELSE seq] END

REJECT:

  1) expr is neither integer nor CHAR  [Case3]
  2) case label is not a constant  [Case4]
  3) case labels is not included in the type of expr  [Case5, Case6]
  4) a constant is used multiple times as case label [Case7, Case8, Case9]

ACCEPT:

  1) expr is an integer type  [Case1]
  2) expr is of type CHAR  [Case11]
  3) first case with a matching label wins  [Case1]
  4) ELSE seq is evaluated if no label matches  [Case1]
  5) "|" before and after case list, multiple "|" between cases  [Case11]
  6) labels with one element, with range, with empty range, and
     comma separated list  [Case1, Case10]

ERROR:

  1) abort program if no label matches, and there is no ELSE [Case2]



9.6 While statements
--------------------

  WHILE expr DO seq END

REJECT:

  1) expr is not boolean  [HOTLoop7]

ACCEPT:

  1) expr is evaluated before loop body  [HOTLoop2]



9.7 Repeat statements
--------------------

  REPEAT seq UNTIL expr

REJECT:

  1) expr is not boolean  [HOTLoop8]

ACCEPT:

  1) expr is evaluated after loop body  [HOTLoop1]



9.8 For statements
------------------

  FOR var := begin TO end [ BY step ] DO seq END;

REJECT:

  1) var is not a variable  [For2]
  2) var is a composite designator (i.e., not a single ident)  [For1]
  3) var is not integer  [For3]
  4) begin is not assignment compatible to var  [For4]
  5) end is not assignment compatible to var  [For5]
  6) var does not include step  [For6]
  7) step is not constant  [For7]
  8) step is zero  [For8]

ACCEPT:

  1) begin < end, no step: iterate end-begin+1 times  [Div1.Mod]
  2) begin < end, positive step  [For9.Mod]
  3) begin > end, negative step  [For10.Mod]

NOTE: There are known problems with overflows and wrap around, for
example with "FOR i := MIN(LONGINT) TO MAX (LONGINT) DO".  The
behaviour is undefined in this case.



9.9 Loop & Exit statements
-------------------

  LOOP seq END

REJECT:

  1) an EXIT than is not part of a LOOP  [HOTLoop9]

ACCEPT:

  1) zero, one, or more EXIT or RETURN statements in seq  [various]

WARN:

  1) a LOOP contains no EXIT or RETURN



9.10 Return statements
----------------------

  RETURN [expr]

REJECT:

  1) RETURN of a non-function procedure has an expr  [Return1, Return4]
  2) RETURN of a function procedure has no expr  [Return2]
  3) expr is not assignment compatible to function result  [Return3]

ERROR:

  1) control reaches end of a function's body [HOTFunction7]



9.11 With statements
--------------------

  WITH guard1 DO seq1 {| guardN DO seqN} [ELSE seq] END
  with guard being "var: type"

REJECT:

  1) var is no qualident  [With5]
  2) var is no variable parameter or record pointer  [With6]
  3) type is not an extension of var's type  [With7]

ACCEPT:

  1) within a guarded region, var is regarded as if it has
     the indicated static type  [With2]
  2) the type guard on a parameter variable does not change the
     signature of the parameter's procedure  [With4]

ERROR:

  1) no guard evaluates to TRUE, and no ELSE exists [With3]

WARN:

  1) a guard is unreachable because a preceding guard tests the same
     variable, but with a base type of the guard's type


