www.digitalmars.com         C & C++   DMDScript  

D - [HOWTO](MN002, part 2) Coding typesafe multi parameter functions, optional parameters and the like

Part 2 of how to code multi parameter functions, optional parameters,
positional parameters, default valued parameters and the like, using the
the syntax extension I just suggested.

With working example using the currently available syntax.


In part 1 I (re)introduced the notion of regular expressions in order to
show the close relation of multi parameter function calls to the suggested
syntax extension.

At the moment I see no need to extend the syntax for being able to support
regular expressions over signatures as a notion to describe the formal
parameter list of a multi parameter function, because regular expressions
have a close relation to finite state machines and I will show, how to
implement such for the simple cases usually arise.

2) Let S1=int and S2=real be signatures and let r=(S1|S2)* be the regular
expression that the actual call must conform to. Then all actual calls,
that consist of an arbitrary number, including none, of actual parameters
of type int intermixed with type real are accepted.

For the purpose of this writing a roughly useful finite state machine
(FSM) consists of states(:-)), from which exactly one is the start state
and at least one, may be more, are the ending aka accepting states. The
start state may be an accepting state also.

Furthermore for each state s1 and Signature S from the input alphabet of
signatures, that is a valid input in state s1, the FSM knows which is the
new state s2 to go to under input S. The FSM does not only know the new
state but the action to be taken also.

This may sound difficult, but is not.

Consider our example and let the FSM that we want to construct be in some
state s. What should we do when getting the input signature S=int or
S=real? Consider the following informal three commands:

   in s on getting int goto s exec something in s on getting real goto s
   exec somethingOther in s on getting EOM accept

Here the input EOM is a signature that is not part of the alphabet
provided to the FSM but which is generated by the compiler, as early as
the analyzing of the actual multi parameter list reaches the closing right
brace.

As one can see, being in state s the FSM is ready to accept either, the
signature int or the signature real and after that, is ready again. If we
make the state s the start state, we are all done, because the start state
being an accepting state means, that the empty list of parameters is
accepted also.

And now to the coding:

   struct State_s{
     State_s opCall(int elem){
       // exec something
       State_s next; return next;
     }
     State_s opCall(real elem){
       // exec somethingOther
       State_s next; return next;
     }
     void opEOM(){
       // do some postprocessing
     }
   }

This is the kernel of our FSM. For every valid signature in a given state
include an opCall, which has that signature and returns the according
state struct. Clearly the body of the opCall should execute the
appropriate action also.

If you need more then one state (:-)), then simply sequence them together:

   struct State_s0{
   }
   struct State_s1{
   }
   ...
   struct State_sn{
   }

You may have mentioned, that the opEOM does some postprocessing. So where
is the preprocessing done?

In order to be able to do some preprocessing and have an entry point to
the kernel of our FSM, we must enclose the kernel of our FSM with a class
and copy all opCall and if present the opEOM from the start state as
members into the scope of the class, rename them to opMultArg and
introduce the preprocessing actions into their bodies. Without the
renaming the compiler would not be able to distinguish between a normal
actual parameter list and an actual multi parameter list.

Do not forget to introduce for every state struct a member into the scope
of the enclosing class. Then in total we have laid the grounds for
processing multi parameter functions:

   class List{
     State_t1 opMultARg( ... ){
     }
     ...
     State_tn opMultArg( ... ){
     }
     struct State_s0{
       State_t1 opCall( ... ){
       }
       ...
       State_tn opCall( ... ){
       }
     }
     State_s0 state_s0;
     ....
   }
   List list= new List;     // instantiation ...
   list( 1; 2; 3; ... ; n); // use of the FSM

To be continued.

So long!
Mar 31 2004