December 16, 2001 Re: ... Lets get a compiler out fast - And a D test suite! | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter | Walter wrote:
> I'm still in a bit of a quandary about casts. Should casting be:
>
> (type)expression
>
> or:
>
> cast(type)expression
My I brainstorm a bit?
personally I like the:
<type> expression
Syntax, and it is easy parseable in a LALR syntax, as it requires only one look ahead. However I've seen people having feelings against it.
How about using the right apostrophe? Is it used it already by something
different?
`type` expression
Well however I thing trying to see pure, type casting can best be viewed as a kind of function or? It gets one input value, and returns another output value, sometimes different as the input. Then the above expression should be look like this better:
cast(type, expression)
or the pascal form type(expression)
But types cannot normally be function paramteres, they are something
different. I think type casting should use the same syntax as generic
programming in the same language should do. It's the same paradigm, calling
a function whose implementation is dependant on the type you specify.
How about then:
cast<type>(expression)
?
|
December 16, 2001 Re: ... Lets get a compiler out fast - And a D test suite! | ||||
---|---|---|---|---|
| ||||
Posted in reply to Axel Kittenberger | "Axel Kittenberger" <axel@dtone.org> wrote in message news:9vhomg$1re4$1@digitaldaemon.com... > Walter wrote: > > I'm still in a bit of a quandary about casts. Should casting be: > > > > (type)expression > > > > or: > > > > cast(type)expression > > My I brainstorm a bit? > > personally I like the: > <type> expression > > Syntax, and it is easy parseable in a LALR syntax, as it requires only one look ahead. However I've seen people having feelings against it. It's also hard to distinguish from normal expression containing < and > operands. > How about using the right apostrophe? Is it used it already by something > different? > `type` expression > > Well however I thing trying to see pure, type casting can best be viewed as > a kind of function or? It gets one input value, and returns another output value, sometimes different as the input. Then the above expression should be look like this better: > > cast(type, expression) It doesn't seem "right" to me =) > or the pascal form > type(expression) This is, IMHO, acceptable, since there's no temporaries in D, so the syntax is unused. > But types cannot normally be function paramteres, they are something different. I think type casting should use the same syntax as generic programming in the same language should do. It's the same paradigm, calling > a function whose implementation is dependant on the type you specify. How about then: > > cast<type>(expression) Back to C++ days... I just hate angle brackets! And anyhow, what's the problem with the way it's done now? |
December 16, 2001 Re: ... Lets get a compiler out fast - And a D test suite! | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter | "Walter" <walter@digitalmars.com> writes:
> I'm still in a bit of a quandary about casts. Should casting be:
>
> (type)expression
>
> or:
>
> cast(type)expression
>
> ? The latter is far easier to parse. I'm so used to the former I am reluctant to give it up. A kludgy compromise might be allowing the former only for types that start with a keyword, not a typedef.
Please let D abandon the abominable syntax that C uses for casts. I know, I know, people are used to it, but this is one case where compatibility should be given second place to forward progress.
On the compromise idea - If a new syntax is introduced then the old
syntax should be eliminated. C++ made the mistake of adding a new
syntax for casting while also retaining the old, and that's been
a source of confusion. Also, having two forms which are sometimes
but not always interchangeable is asking for trouble. Again, I
know about the compatibility arguments, but let's try to make some
forward progress with D in this area.
As for what syntax to use.. One thing about C that's always seemed rather poorly thought out is the funny way that prefix operators and postfix operators interact. (Incidentally, C++ retains these problems and makes them worse with a prefix 'new' operator. But I digress.) If one thinks of casting as a kind of operator - admittedly one that doesn't usually execute any instructions - I think it makes more sense to put the cast operator after the operand, as for example
operand.as(type)
or if necessary
(expression).as(type)
If the syntax for expressions were expanded to include a syntax for types, with semantics allowing some run-time representation for values of type Type (which seems like a good idea independent of casting), then no special syntax is needed for casting. Indeed if this were so then the only difference between the casting 'as' operators and regular (method) functions is that 'as' is overloaded on return type.
Note how nicely this functional form cascades:
x[i].as(Window).redraw()
Compare that to:
(cast(Window) x[i]).redraw()
Perhaps it's my many years of using object-oriented programming languages, but the first form seems much easier to understand than the second.
Let me add a couple of disclaimers as anti-flame insurance :)
(1) There is a fundamental and important difference between the notion
of type and the notion of class. The comments above gloss over that
distinction. It's important that some implementation along these
lines not do that.
(2) C uses the same syntax for "casting" (like changing one pointer
type into another with no bit changes) and "conversion" (changing an
integer value into a floating point value, bits definitely change).
It seems obvious that these notions, although related, are different
operations and should have distinct syntaxes. Or at least different
operator names.
Hopefully the comments and suggestions made above find some resonance amongst the readers of the newsgroup and potential users of D.
|
December 16, 2001 Re: LALR vs LL(k) grammar | ||||
---|---|---|---|---|
| ||||
Posted in reply to Axel Kittenberger | "Axel Kittenberger" <axel@dtone.org> wrote in message news:9vho6a$1rdg$1@digitaldaemon.com... > Walter wrote: > > I can never remember the definitions of those grammars. The current D parser, however, is pretty simple and is implemented as recursive descent. > > I have little use for LEX/YACC. The code output always seems to require a > > little hand editting, and then automating the build process doesn't work. > Well the today active GNU projects are called "flex" and "bison". Bison requires hand editting? Thats not true in my eyes. First primary bison creates only the parser tables, not much more not much less. If you want to > make changes in the parser, you can change the bison.simple template. Once for all. There are some limits in bison, as it doesn't allow you to specify > how the actions are coded, which is interesting if you are doing non-C parsers. My experience with GNU bison under Win32 is the output generated many warnings from the compiler. The port of it to Win32 was incomplete. I didn't want to rely on a decent port of bison existing on each platform I wanted to port the product to. Even worse, in the end it didn't save any time. Ok, so I'm not remotely a bison expert, and perhaps these are non-issues to someone who has taken the time to thoroughly learn it. > However I agree that hand writing a parser can have it's advantages. It's only too complicated for a small brain like mine :o) I personally never got > unary operators right this way, the miny languages I once wrote the parser by hand quickly came out of my control, while bison parsers seems to be pretty easy you got it, however sometimes configuring out how to resolve some shift/reduce conflicuts can be as tedious. A hand-tuned parser can be very fast as well <g>. > > Lexers are so simple anyway I can't see a reason to use LEX. > I totally agree on that. However it personally confuses me somewhat why there are all two different tools for spelling and for grammar, after all it is in principle the same or? Only once your tokens are the alphabet and once your tokens are the words outputed by the lexer grammar. In principle they are the same, in practice not. You're not really after a data graph being built by the lexer, just a token stream. Whereas with a parser, a syntax graph is the desired result. Also, despite what compiler textbooks imply, lexing and parsing are only minor parts of a compiler. The real work is in the semantic analysis, optimization, and code generation. For example, the lexer in D is 1400 lines and the parser is 2600. Of course, the goal was to make them simple <g>. |
December 16, 2001 Re: LALR vs LL(k) grammar | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter | Walter wrote:
> My experience with GNU bison under Win32 is the output generated many warnings from the compiler. The port of it to Win32 was incomplete. I didn't want to rely on a decent port of bison existing on each platform I wanted to port the product to. Even worse, in the end it didn't save any time.
>
> Ok, so I'm not remotely a bison expert, and perhaps these are non-issues to someone who has taken the time to thoroughly learn it.
I had no problems whatever compiling and running bison with MSVC++ (back at the times I still have used it)
- Axel
|
December 16, 2001 Re: ... Lets get a compiler out fast - And a D test suite! | ||||
---|---|---|---|---|
| ||||
Posted in reply to la7y6nvo | > > (2) C uses the same syntax for "casting" (like changing one pointer > type into another with no bit changes) and "conversion" (changing an > integer value into a floating point value, bits definitely change). > It seems obvious that these notions, although related, are different > operations and should have distinct syntaxes. Or at least different > operator names. True, in fact there are 4 casts I know of, conversion cast, upcast, downcast and reinterpret cast. C++ decides in after the context what to use that can be very error prone. Where a const cast is only a finer issue I do not count as a seperate cast form. class Borg b* = (Corg) a*; Can have different code results dependant that you included #include "Corg.h" and defined the class with it. Took me once several days to find a bug, where the code did an upcast (pointer should decrement by casting) but the class defintion was not included in that file, so he did a reinterpred cast, pointing at nonsense at the end. - Axel |
December 16, 2001 Re: ... Lets get a compiler out fast - And a D test suite! | ||||
---|---|---|---|---|
| ||||
Posted in reply to Axel Kittenberger | "Axel Kittenberger" <axel@dtone.org> wrote in message news:9vj699$2l18$1@digitaldaemon.com... > True, in fact there are 4 casts I know of, conversion cast, upcast, downcast and reinterpret cast. C++ decides in after the context what to use > that can be very error prone. Where a const cast is only a finer issue I do > not count as a seperate cast form. > > class Borg b* = (Corg) a*; > > Can have different code results dependant that you included #include "Corg.h" and defined the class with it. Took me once several days to find a > bug, where the code did an upcast (pointer should decrement by casting) but > the class defintion was not included in that file, so he did a reinterpred cast, pointing at nonsense at the end. D shouldn't suffer from that problem, as there shouldn't be any forward referenced class names. D will just use one cast form, not the 4 different ones. (There is no const cast in D, because there is no const type modifier.) To do a type paint, cast it to void* first and then cast the result. |
December 16, 2001 Re: ... Lets get a compiler out fast - And a D test suite! | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter | "Walter" <walter@digitalmars.com> wrote in message news:9vhegn$1l01$1@digitaldaemon.com... > I'm still in a bit of a quandary about casts. Should casting be: > > (type)expression > > or: > > cast(type)expression > > ? The latter is far easier to parse. I'm so used to the former I am reluctant to give it up. A kludgy compromise might be allowing the former only for types that start with a keyword, not a typedef. There's a related issue for declarations, is: a * b; a declaration or an expression? Currently, the ambiguity is resolved with the rule "if it will parse as a declaration, it is a declaration". I'm not particularly thrilled with that, as it requires lookahead in the parser. One solution is to require a "var" keyword in front of declarations. But to my eyes, typing all those var's in is annoying: void func() { var int i,j; var X* y; .... } |
December 17, 2001 Re: ... Lets get a compiler out fast - And a D test suite! | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter | Walter wrote:
>
> I'm still in a bit of a quandary about casts. Should casting be:
>
> (type)expression
>
> or:
>
> cast(type)expression
>
> ? The latter is far easier to parse. I'm so used to the former I am reluctant to give it up. A kludgy compromise might be allowing the former only for types that start with a keyword, not a typedef.
If you ever allow any form of generic programming (templates, etc.)
this could come back and haunt you. Also, it may cause unnecessary
breakage if some one switches code from using int to some FOO_t sort of
datatype. You've gone to such extremes to do things one way (at least
in the first release) that is seems odd to have two ways for this.
I don't like the way the second form looks like a function call
followed by an expression, but I can't give a good justification for the
identifier in parens followed by an expression either. Go with the cast
keyword and keep it clean.
Dan
|
December 17, 2001 Re: ... Lets get a compiler out fast - And a D test suite! | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter | "Walter" <walter@digitalmars.com> wrote in message news:9vj9l0$2n1j$2@digitaldaemon.com... > There's a related issue for declarations, is: > > a * b; > > a declaration or an expression? Currently, the ambiguity is resolved with the rule "if it will parse as a declaration, it is a declaration". I'm not particularly thrilled with that, as it requires lookahead in the parser. One If "a" is type in current scope, it's a declaration; If "a" is something else, it's an expression, so: class Apple { } int main() { Apple * x; // x is pointer to apple int Apple; Apple * y; // multiply Apple by y } |
Copyright © 1999-2021 by the D Language Foundation