Thank you for answering! No else questions in this post. Just my thoughts/remarks in case you want to read them.
Anyway, it is a fundamental property of Visual Prolog ...
Yes, I see. Changing a fundamental property can turn a lot of things upside down. I can imagine that it could easily produce an unreasonable large amount of work.
Finally notice, that given the current way things are now, both objA and objC are allowed to define domains (with functors) and constants with same names ...
Oh, I had not noticed that before. It means that for constants I can cure the problem 'manually' by simply declaring the constants from the super-interfaces again with same names in the sub-interface:
Code: Select all
interface objA
constants
c : unsigned = 1.
end interface objA
%===
interface objB supports objA
constants
c : unsigned = objA::c.
end interface objB
However for domains it does not work out that way.
When someone reads the code and sees objC::const1 it is quite nice that const1 is actually placed in objC
True. But uniformly referencing to
const1 which can be declared in
objC or any of its super-interfaces would be even nicer.
Furthermore, code like this would be fully legal, but somewhat confusing ...
Yes. However a sensible example is larger. I can report about the situation in my 'real' code on which I am working currently. But the story is not equally short:
I have a bunch of lexers which are similar to the one in the pfc, but which are customized to languages I want to parse.
The 1st lexer interface is just named
lexer (in a different namespace than the one from the pfc). The interface declares constants for three terminals. These are
bof_terminal,
eof_terminal, and
error_terminal ("bof" stands for Begin Of File). The interface is only an abstract root of my lexers, it has no class implementing it.
My 2nd lexer (interface and class) is
alphaLexer and it supports
lexer. It translates keywords to terminals and additionally declares terminal constants
id_terminal and
op_terminal. Where
id_terminal matches the usual upper- and lower-case IDs and
op_terminal matches for example "+", "**", and ":=".
The 3rd lexer is
alphaNumLexer supporting
alphaLexer. It additionally declares terminal constants
number_terminal and
decimal_terminal. The fist one matches unsigned integer numerals with arbitrary many digits, the last-mentioned matches unsigned decimal numerals also with arbitrary many digits.
The 4th lexer is
strNumLexer supporting
alphaNumLexer. It additionally declares terminal constants
char_terminal,
string_terminal, and further terminals for string literals without ESC-sequence replacement and for unterminated strings.
The 5th lexer is
fillerLexer supporting
strNumLexer. It additionally declares terminal constant
filler_terminal. This terminal matches parts of the source text which are surounded by certain terminals which are input to the constructor of the
fillerLexer class. For example
filler_terminal can match a leading part of the text which is surounded by
bof_terminal and a terminal which matches the keyword "begin".
The lexer interfaces/classes mentioned so far are part of my 'code library' (to accompany the pfc, I put it in namespace mfc).
In my application I have another lexer which contains the terminal constants for the application-specific keywords. It supports one of the above lexers and inherits its class. Let's take the worst case, it supports
fillerLexer.
The situation now is, that when I am writing the grammar rules, I need to refer to all the terminal constants and thus I am putting open qualifications for the application-specific lexer and all its super-lexer-interfaces into my code. I have but the feeling, that these are way too many open qualifications.
The alternative to place all terminal constants together in one file does not seem to be really appealing: In the above construction I never need to update an existant file to introduce new terminals (nor for lexers in the library, neither for lexers in an application). Instead I am just adding subtype interfaces, which is lot more elegant.