From: Randy Brukardt on
"Robert A Duff" <bobduff(a)shell01.TheWorld.com> wrote in message
news:wccr5nj247r.fsf(a)shell01.TheWorld.com...
> "Randy Brukardt" <randy(a)rrsoftware.com> writes:
....
>> I'd like to see a solution to this problem, but I don't think this is it.
>> The problem is that the compiler wouldn't know what components to
>> generate,
>> so it would effectively have to generate a giant case statement:
>>
>> X := (Token => T, others => <>) would become:
>>
>> case T is
>> when LEX_ID => X := (Token => LEX_ID, String_Id => <>);
>> when '!' => X := (Token => '!');
>> ...
>> end case;
>
> Well, this is not hugely different from the case statement that the
> compiler has to generate for:
>
> X : Token_Unit (Token => T);
>
> to default-initialize stuff.

Well, for Janus/Ada at least, that giant case statement is generated exactly
once, in the unit containing the type, to create an initialization "thunk".
We don't keep enough information to do it efficiently later.

Note that the example given is exactly the same as default initialization,
so that wouldn't be a problem, but if there are additional components
specified, the default initializer couldn't be used. (It would be incorrect
to call functions used by the default initial values of components that have
explicit values. The ACATS [mostly the Ada 83 version] checks for stuff like
that.)

Randy.


From: Randy Brukardt on
"Adam Beneschan" <adam(a)irvine.com> wrote in message
news:a4de16f2-1b14-4c9d-886a-2e61f6c01863(a)k6g2000prg.googlegroups.com...
On Mar 16, 4:39?pm, "Randy Brukardt" <ra...(a)rrsoftware.com> wrote:
....
>This has to use the same sort of case statement to initialize the
>components in the variant parts. So I thought that basically the code
>would be using the same logic, plus assigning initial values to the
>non-variant components.

As noted to Bob, that doesn't work in Janus/Ada. There also is a critical
limitation on our intermediate code: there cannot be case statement-like
control structures in expressions (we completely separate control flow and
values in the intermediate code; there cannot be live values when there is
control flow and vice-versa; values have very limited control flow
possibilities from short circuit operations and loop initializers).

If the idea offered much additional expressiveness, I wouldn't object, but
it doesn't seem to have enough.

Steve Baird and I had worked out a partially constrained discriminant
constraint which would have provided a much better solution to this problem
along with many others -- but Tucker Taft couldn't seem to wrap his mind
around the idea (it seemed natural to me) and thus it got quickly killed.
Thus I don't think there will be any relief.


Randy.

P.S. It probably isn't fair to single out Tucker for killing the idea, but
since he usually has a much more flexible view of the world, it was bizarre
that he couldn't understand it. I suspect many took that as an indication
that it was fatally flawed; I suspect the problem more was one of
presentation.


From: Warren on
Jeffrey R. Carter expounded in news:hnov3m$t4o$1(a)tornado.tornevall.net:

> Warren wrote:
>>
>> The other way for me to solve this is simply provide
>> a discrimanant that only identifies the few variants. But
>> to keep to 32-bits, I'd have to find a way to specify the
>> discriminant as 3-bits, which I don't think is possible.
>
> Looking at what you have, it looks like a design problem to me. You
> have a whole bunch of enumeration values, but you don't have a bunch
> of variants. I'd probably have an enumeration type with 3 values that
> serves as the discriminant. Then have 3 enumeration types, one for
> each variant, that gives the specific information that you're now
> trying to use for the discriminant as well.

I looked at this closely last night and ended up agreeing
with you (design problem). So I changed it along the
lines that you suggested:

type Token_Type(Aux : Aux_Kind := No_Aux) is
record
Token : Token_Kind := No_Token;
case Aux is
when SID_Aux =>
SID : String_ID;
when FID_Aux =>
FID : Func_ID;
when No_Aux =>
null;
end case;
end record;

I was also able to get the representation I wanted (yeah):

for Token_Type use
record
Aux at 0 range 0..2;
Token at 0 range 3..15;
SID at 0 range 16..31;
FID at 0 range 16..31;
end record;

This design allows me to flexible in the auxiliary
information provided. For example, each "token line"
ends with a linefeed token (LEX_LF). However, each
statement has an optional "inline" comment like:

01000 LET OPEN_FLAG = FALSE $ Mark file as not-opened.

Using the discriminant Aux allowed me to use a SID
(Aux = SID_Aux) or not ( Aux = No_Aux ) as required:

T := ( Aux => SID_Aux, Token => LEX_LF, SID => ID );

or

T := ( Aux = No_Aux, Token => LEX_LF );

As you pointed out, when designed this way, I always
know the static representation required, even though
the Token member may be variable.

I knew that we'd eventually converge on a solution.
Thanks everyone.

Warren
From: Warren on
Randy Brukardt expounded in news:hnrr6j$d7n$1(a)munin.nbi.dk:

...
> If the idea offered much additional expressiveness, I wouldn't object,
> but it doesn't seem to have enough.
>
> Steve Baird and I had worked out a partially constrained discriminant
> constraint which would have provided a much better solution to this
> problem along with many others -- but Tucker Taft couldn't seem to
> wrap his mind around the idea (it seemed natural to me) and thus it
> got quickly killed. Thus I don't think there will be any relief.
>
> Randy.

As it turned out (in my case at least), the problem was more
of a design problem (see upstream post). Once I reworked the
design, the problem vanished. ;-)

Warren