Thinking about it a bit more, it may be possible using something
like(hopefullyu I got the syntax right, don't have a file open on hand)
array_literal_expression : OPEN_BRACKET expression_list CLOSE_BRACKET
;
expression_list
: expression
| expression_list expression
;
its worth looking into, I'll probably delve into mono again in a day or two
and see what can be done.
With brackets[] you mean braces{} don't you?
Yes, I think that the mono parser calls { OPEN_BRACKET, but I could be
wrong. I forget what [ is identified as.
Some of the names in that parser are a little strange.
Heres my plan for the moment, let me know what you think:
1) m...n is a range generator. It returns am IEnumerable. It can be assigned
to any IEnumerable variable or used as IEnumerable in foreach or as a method
parameter.
2) [<enumerableExpression>,<literalExpression>,<sourceExpression>] generates
an IList containing those values.
2b) Lists take the best possible type. If your enumerable expression returns
int and you have a long literal, the list is IList<long>, if it returns ints
and you have a double literal, IList<double>, etc. If the list contains
heterogeneous types, such as int and string or int and date time, it is
typed as IList<object>. I still have to consider the exact rules of such.
3) {<enumerableExpression>,<literalExpression>,<sourceExpression>] generates
an array containing those values.
3b) For arrays all values have to be of the same type. Array literals take
on the numeric behaviour where the largest nessecery type is used, but
arrays cannot contain multiple types.
4) For enumerableExpression, every value is read out *unless* the expression
is cast to object or somesuch. This does leave a problem in that there is no
way to generate a list of IEnumerables, but if someone wants that edge case
they should probably use long-hand list or array syntax. Can you think of
any workarounds for this?
enumerableExpression is typed either object for IEnumerable or T for
IEnumerable<T>.
5) sourceExpression is any expression that returns a type, be it
mathematical or a method call. These aren't literals in a very strict sense,
every one of these values is generated at run time(unless compiletime
generation is possible).
6) Where possible, foreach over a list or generator will generate a for
loop. This will only occur if the list generates integers or other
structures that support > <, etc. If the compiler cannot determine a valid
for loop or if code complexity would become to great(too many ranges or
multiple types), the compiler will instead generate the list and foreach
will operate over that lists IEnumerable implementation.
7) Valid range increment values are *any* value the range type has a
operator+ defined for. The operator+ must return the range type however.
8) For contains checking, I'm still much more comfortable with isin over in,
so I will likely implement that keyword as it stands. However I will
consider adding a pragma that changes support to in so that eitehr can be
experimented with.
9) Experimental: If code contains the same range type twice only one
IEnumerable\IEnumerator class pair will be generated. That pair will take
parameters that determine ranges. This should cut down on class bloat
Well, thats a basic outline for what I'll do(assuming I can find time). Any
comments from anyone?
--
cody
[Freeware, Games and Humor]
www.deutronium.de.vu ||
www.deutronium.tk