April 01, 2004
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!