[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Pragma Specs



I added some minor corrections to pragma specs and decided to pass it
round on the mailing list.

I'm especially interested in
a) comments on loopholes in this document (ambiguous formulations,
   missing specs, etc; anything you don't understand after reading the
   whole text twice is definitely ambiguous), and
b) answers to the open questions in the last paragraph.

Since this list has 20 subscribers by now, some opinions should be
available.

-- mva




#	$Id: Pragmas,v 1.4 1996/04/18 19:56:16 acken Exp $	
PRAGMAS

This draft is partially based on a text by B.Cygan, E.Henne, and
A.Wiedemann presented as comments to D106 by DIN (AK DIN NI-22.13,
dated August 28 1995).  I copied most of their suggestions, left
things out that were Modula-2 specific, simplified some things (turned
3 assignment variants into a single one), and extended some things
(values can be integer, expressions are far more powerful).

------------------------------------------------------------------------

A set of standard names should control the detection of the standard
exceptions (the following list derived from the Modula-2 draft
standard ISO10514, 7.5.1):

Case Range (CaseSelectException)
  case selector out of range
Conversion Error 
  expression cannot be converted to the new type
Index Range (IndexException)
  array indexed out of range
NIL Dereference 
  attempt to dereference NIL
No Return (FunctionException)
  no return statement before the end of a function 
Real Overflow (RealValueException)
  overflow in evaluation of a REAL expression
Real Zero Division (RealDivException)
  divide by zero in the evaluation of a REAL expression
Set Range (RangeException)
  set value out of range
Whole Overflow (WholeValueException)
  overflow in the evaluation of a whole number expression 
Whole Zero Division (WholeDivException)
  2nd operand of DIV or MOD is zero
Invalid Cast 
  alignment problem with cast SYSTEM.VAL
Type Guard (TypeGuardException)
  failed type guard

The names (see the end of this file for a list), if known by the
compiler, shall represent values defining whether or not code shall be
generated for the detection of the specific exception.

The following standard names should also be provided:
  StackCheck -- generate stack tests
  PragmaCheck -- generate warnings for unrecognized pragmas 
  ConformantMode -- (conformant to _what_?)
  DebugMode -- generate debug information

The assignment to these names is done like Oberon-2 assignments.
Examples: 
  <* IndexCheck := TRUE *>     
    generate code for index check
  <* RangeCheck := FALSE *>
    switch of detection of invalid set elements

If the compiler does not know the identifier or cannot provide the
desired function (e.g. cannot generate code for a specific check, check
is always done by hardware and cannot be turned off) it shall produce
a warning message [mva: the Modula-2 text says `error', but I think
this is to harsh; the state of those variables has to be tested before
compilation starts and after every assigment to one of them].

Two pragmas ("PUSH" / "POP") shall allow to save the state of all
pragmas in effect on a stack and restore this state later.  

New variables are defined by  "DEFINE" var ":=" value.
The identifer var must not be already known (or an error message is
produced), that is, one cannot override existing variables (known to
the compiler or defined earlier).  Once defined, the value can be
changed with an assignment.

The condition pragmas shall have the form:
  "IF" boolean_expression "THEN"
  "ELSIF" boolean_expression "THEN"
  "ELSE"
  "END"

Example:
  <* DEFINE CpuType := "Intel" *>

  <* IF CpuType="Intel" THEN *>
  IMPORT IntelPrimitives;
  <* ELSIF CpuType="Motorola" THEN *>
  IMPORT MotorolaPrimitives;
  <* END *>

Pragma sequences within "<*" and "*>" are allowed, the pragmas are
seperated by ";".  WhiteSpace in pragmas is allowed and skipped.
Pragmas within comments are not recognized.  The empty pragma exists.

------------------------------------------------------------------------

Collected Syntax in EBNF:

pragma = "<*" single_pragma {";" single_pragma} "*>".

single_pragma = [assignment | definition | save_restore | condition].

assignment = known_variable ":=" Expression.

definition = "DEFINE" unknown_variable ":=" Expression.

save_restore = "PUSH" | "POP".

condition = ifpart {elsifpart} [elsepart] endifpart.

ifpart = "IF" boolean_expression "THEN"
elsifpart = "ELSIF" boolean_expression "THEN"
elsepart = "ELSE".
endifpart = "END".

boolean_expression = Expression.
Expression = SimpleExpression [Relation SimpleExpression]. 
Relation = "=" | "#" | "<" | "<=" | ">" | ">=".
SimpleExpression = Term {"OR" term}.
Term = Factor {"&" Factor}.
Factor = value | "(" Expression ")" | "~" Factor.

known_variable = identifier.
unknown_variable = identifier.
indentifier = any legal Oberon-2 identifier.
value = any legal Oberon-2 string or integer value | "TRUE" | "FALSE"
        | identifier.



Annotations

  Oberon-2 keywords and the symbols "TRUE", "FALSE", "PUSH", "POP",
and "DEFINE" cannot be used as variable names.

  Any Oberon-2 string (including the empty string) and all integer
numbers (including hex numbers) are valid values.  Character constants
(like 20X) are equivalent to string constants of length 1 (or length 0
in the case of 0X).  Hex constants with values greater than
MAX(LONGINT) are mapped to negative LONGINT values.

  The operands of ~, &, and OR have to be of boolean type.  It's an
error if they are evaluated and turn out to be of integer or string
type.

  Boths operands of the relational operators have to be of the same
type.  The operators "<", "<=", ">", ">=" are only defined for
integers and strings, "=" and "#" also for booleans.

  A conditional compilation clause consists of opening ifpart, any
number of elsifparts, an optional elsepart, and a terminating
endifpart.  Nested conditional compilation clauses are allowed.  If
the boolean_expression of the ifpart is true, the text until the next
corresponding elsifpart, elsepart, or endifpart is fully interpreted.
The remaining text until the corresponding endifpart is skipped.
Otherwise, the text following the ifpart is skipped.  If the next
condition is an elsifpart, its boolean_expression is tested and so
on.  If no condition holds, the text following the elsepart is
interpreted.  "Skipping" of text means that no interpretation is done
except recognition of comments and nested condition clauses.  That is,
the pragma syntax in the skipped text is checked, though the meaning
of the pragmas is not recognized.

  PUSH pushes all predefined and all user defined variables on the
stack.   

  The compiler should provide `safe' defaults for all predefined
variables, i.e. all useful run-time checks are enabled and no compiler
specific options are enabled.  These values can be redefined in the
configuration file and by command line options.

  The boolean operators & and OR are evaluated like their Oberon-2
counterparts (shortcut evaluation).  Not evaluated expressions and
skipped text are only check syntactically, type errors for operators
or undefined variables are ignored.

  Abbreviation of compiler-known identifiers is not allowed.

  The character sequence `<*' cannot appear inside a `<* ... *>'.
This means that pragma delimiters can't be nested.

  Comments can appear inside a pragma.  


------------------------------------------------------------------------


Implementation notes:

o The predefined variables are declared in `Attributes', except for
  `warnings' which is declared in `Error'

o These variables correspond to the above mentioned exceptions:
  CaseSelectCheck
    trap if a case selector doesn't match any label; toggles activation of
    trap statement in the ELSE part
  IndexCheck
    trap if an array index is out of range; effects boundIndex instr
  RangeCheck
    trap if a set value is out of range; effects boundRange instr
  DerefCheck
    trap if an invalid pointer is dereferenced; in practice `invalid' means
    usually `NIL'; most systems will catch such an error anyway (segmentation
    violation), so enabling this check means that the program exits 
    gracefully, giving some sort of error message and possibly an indication
    of the faulty instruction; effects access-heap and update-heap
  FunctResult
    trap if a function procedure is left without a return statement; toggles 
    activation of trap instruction at end of function
  TypeGuard
    trap if a type guard fails or no branch of a WITH statement triggers; 
    toggles activation of type-guard and trap instructions
  OverflowCheck
    trap if an integer operation or a conversion to integer overflows; toggles
    placement of `instrCheckOverflow' flag
  IntDivCheck
    trap if an integer division has a right hand side of zero; toggles
    placement of `instrCheckDiv' flag
  RealOverflowCheck
    trap if an real operation overflows; toggles placement of 
    `instrCheckOverflow' flag
  RealDivCheck
    trap if a real division has a right hand side of zero; toggles
    placement of `instrCheckDiv' flag

o Misc variables:
  Warnings
    unless set, suppress all warnings emitted by the compiler
  Assertions
    only put assertions into output if set
  Initialize
    initalize local variables and memory blocks to zero; toggles placement of
    `objIsInitialized' and `instrInitialize' flags

------------------------------------------------------------------------

[Open questions]

The following exceptions aren't part of the OOC front-end yet:

Conversion Error  -- don't know what this should be
Invalid Cast      -- don't know what this should be

Could someone explain these two to me?  --mva


The following predefined variables aren't part of the OOC front-end
yet: 

StackCheck        -- how should this be marked in the GSA code?
PragmaCheck       -- OOC has no undefined pragmas; an unknown name is
                     assumed to be an undefined variable and produces
                     an error message
ConformantMode    -- (conformant to _what_?)
DebugMode         -- how should this be marked in the GSA code?

I suggest to discard `PragmaCheck'.  If someone comes up with a
specification of `StackCheck', `DebugMode', and `ConformantMode' I'll
add the necassry code to the front-end.  With specification I mean a
detailed and complete list of what should be enabled and what should
be disabled whenever the given variable is set to TRUE .  I don't want
to see just prose.  --mva