PROPOSAL: opSeq()

Russell Lewis webmaster at villagersonline.com
Mon Apr 7 11:10:52 PDT 2008


PROPOSAL: A way to handle sequences of expressions which otherwise would 
have been syntax errors


EXAMPLE CODE:
	my_for(i=0, i<10, i++) { <code> }


PARSER DETAILS:

Add a grammar rule that works as follows:
	expression:
		expression expression+

(I'm not sure exactly where in the associativity hierarchy it should go. 
  Maybe assign expression?)


GRAMMAR DETAILS:

Any time that we parse the above rule, the left-hand expression must be 
a "sequence handler."  A sequence handler is either a delegate, or a 
struct which implements the function "opSeq()".

The number and type of arguments of the handler determine how many, and 
what type, of expressions can follow the handler.

The return value from the handler can be void, or a value.

If the handler has fewer arguments than we have expressions in the 
sequence, then the return value from the first handler may be a second 
handler, and thus we can chain handlers.

If the types of the expressions don't match, or the sequence of 
expressions has too few elements, then we have a syntax error.

Handlers are always right-associative.  This means that if we have a 
series of expressions:
	handler1 expressionA handler2 expressionB

then this first becomes:
	handler1 expressionA handler2(expressionB)

Then, if handler1 has 2 arguments, it becomes
	handler1(expressionA, handler2(expressionB))

However, if handler1 has only 1 argument, then it must return a handler 
for the second expression:
	handler1(expressionA)(handler2(expressionB))


IMPLEMENTATION EXAMPLE:

// my_for().
//
// Note that the "lazy void" overload of opSeq handles single-line
// bodies with no {} while the "void delegate()" overload handles
// bodies with {}.


MyFor my_for(lazy void init, lazy bool test, lazy void inc)
{
   MyFor ret;
     ret.init = init;
     ret.test = test;
     ret.inc  = inc;
   return ret;
}


struct MyFor
{
   void delegate() init;
   bool delegate() test;
   void delegate() inc;

   void opSeq(lazy void body)
   {
     opSeq({ body() });
   }

   void opSeq(void delegate() body)
   {
     init();

     while(test())
     {
       body();
       inc;
     }
   }
}



More information about the Digitalmars-d mailing list