I wrote:
: GPC supports a number of keywords that do not belong to all (or any : ;-) known Pascal standards/dialects. To relieve the resulting : problems, there are currently 3 mechanisms: : : - If any dialect option (`--extended-pascal' etc.) is used, all : keywords not belonging to this standard are deactivated : completely. : : - Individual keywords can be disabled using `--disable-keyword'. : : - Some keywords are recognized only depending on context, so : compiling a program that uses them as identifiers is still : possible without any of the above options. : : However, the 3rd approach only works in some situations (and can : never work perfectly, since at some points there would simply be : syntactic ambiguities between certain keywords and identifiers). : : I think for some words it would be easier to recognize them as : keywords only if they have no current meaning (as identifiers) in : the program, rather than turning them on and off in certain : syntactic places (which is quite error-prone and probably still has : some subtle bugs). I'm not sure if this approach will work for all : problematic keywords, but at least for some. : : So this will still work:
[Examples changed since my original mail due to the new `attribute' syntax, but that's beside the point of this mail.]
: program Foo; : : var : Foo: Integer; attribute (static); : : begin : end. : : Also this: : : program Foo; : : procedure Bar; : var attribute: Integer; : begin : end; : : var : Foo: Integer; attribute (static); : : begin : end. : : But not this: : : program Foo; : : var : attribute: Integer; : Foo: Integer; attribute (static); : : begin : end. : : It should not affect the ability to compile, say, EP code without : `--extended-pascal' *as far as* that was possible before, since EP : code can't use `attribute' directives (and it can't use as : identifiers what are keywords in EP).
I've done this now and analyzed all problematic keywords. Fortunately, most of them could be completely resolved this way. In addition, some of them can even be used as "keywords" (directives) and identifiers in parallel, in particular `forward' (which the Pascal standards require) and `near' and `far' (which BP seems to do, though its documentation says otherwise).
There are only two exceptions:
- `Operator' can't be used as a type, untyped constant or exported interface (unless it's disabled as a keyword explicitly or by dialect options). This is because of the following conflict:
type Foo = record end; Operator = (a, b); { enum type }
vs.
type Foo = record end;
operator = (a, b: Foo) c: Foo;
This is not a complete ambiguity, but requires 6 tokens look-ahead to decide whether `operator' is a keyword. That's way too much (IMHO), so since the operator `=' should be definable, we have to make the restriction as stated.
- The following keywords can't be used immediately after an `import' part: uses, implementation, operator, constructor, destructor. This is because of conflicts such as the following:
import Foo; Uses only (a); { import only `a' from `Uses' }
vs.
import Foo;
uses Only (a); { import `a' from `Only' }
All of them are mixes of different standards (`import' is EP, the other keywords are BP, OP and PXSC -- EP's meaning of `implementation' isn't affected since it can't occur there, anyway).
So the decision was between disallowing the keywords there, or forbidding those identifiers as module names in `import'. I think the former restriction is less severe -- it can always be resolved by putting some other declaration in between (or by using `uses' instead of `import').
Frank