Changeset 13826


Ignore:
Timestamp:
01/29/12 22:09:01 (9 years ago)
Author:
ehuelsmann
Message:

Implement processArgs() using the ArgumentListProcessor?.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/abcl/src/org/armedbear/lisp/Closure.java

    r13825 r13826  
    648648  }
    649649
    650  
    651   private LispObject[] _processArgs(LispObject[] args, LispThread thread,
    652           Environment ext) {
    653         final LispObject[] array = new LispObject[variables.length];
    654         int index = 0;
    655 
    656         int argsLength = args.length;
    657        
    658         if (bindInitForms)
    659           if (envVar != null)
    660             bindArg(specials, envVar, environment, ext, thread);
    661         // Required parameters.
    662         for (int i = 0; i < minArgs; i++)
    663           {
    664             if (bindInitForms)
    665               bindArg(specials, requiredParameters[i].var, args[i], ext, thread);
    666             array[index++] = args[i];
    667           }
    668         int i = minArgs;
    669         int argsUsed = minArgs;
    670         // Optional parameters.
    671         for (Parameter parameter : optionalParameters)
    672           {
    673             if (i < argsLength)
    674               {
    675                 if (bindInitForms)
    676                   bindArg(specials, parameter.var, args[i], ext, thread);
    677                 array[index++] = args[i];
    678                 ++argsUsed;
    679                 if (parameter.svar != NIL)
    680                   {
    681                     if (bindInitForms)
    682                       bindArg(specials, (Symbol)parameter.svar, T, ext, thread);
    683                     array[index++] = T;
    684                   }
    685               }
    686             else
    687               {
    688                 // We've run out of arguments.
    689                 LispObject value;
    690                 if (parameter.initVal != null)
    691                   value = parameter.initVal;
    692                 else
    693                   value = eval(parameter.initForm, ext, thread);
    694                 if (bindInitForms)
    695                   bindArg(specials, parameter.var, value, ext, thread);
    696                 array[index++] = value;
    697                 if (parameter.svar != NIL)
    698                   {
    699                     if (bindInitForms)
    700                       bindArg(specials, (Symbol)parameter.svar, NIL, ext, thread);
    701                     array[index++] = NIL;
    702                   }
    703               }
    704             ++i;
    705           }
    706         // &rest parameter.
    707         if (restVar != null)
    708           {
    709             LispObject rest = NIL;
    710             for (int j = argsLength; j-- > argsUsed;)
    711               rest = new Cons(args[j], rest);
    712             if (bindInitForms)
    713                 bindArg(specials, restVar, rest, ext, thread);
    714             array[index++] = rest;
    715           }
    716         // Keyword parameters.
    717         if (keywordParameters.length > 0)
    718           {
    719             int argsLeft = argsLength - argsUsed;
    720             if (argsLeft == 0)
    721               {
    722                 // No keyword arguments were supplied.
    723                 // Bind all keyword parameters to their defaults.
    724                 for (int k = 0; k < keywordParameters.length; k++)
    725                   {
    726                     Parameter parameter = keywordParameters[k];
    727                     LispObject value;
    728                     if (parameter.initVal != null)
    729                       value = parameter.initVal;
    730                     else
    731                       value = eval(parameter.initForm, ext, thread);
    732                     if (bindInitForms)
    733                         bindArg(specials, parameter.var, value, ext, thread);
    734                     array[index++] = value;
    735                     if (parameter.svar != NIL)
    736                       {
    737                         if (bindInitForms)
    738                             bindArg(specials, (Symbol)parameter.svar, NIL, ext, thread);
    739                         array[index++] = NIL;
    740                       }
    741                   }
    742               }
    743             else
    744               {
    745                 if ((argsLeft % 2) != 0)
    746                   error(new ProgramError("Odd number of keyword arguments."));
    747                 LispObject allowOtherKeysValue = null;
    748                 for (Parameter parameter : keywordParameters)
    749                   {
    750                     Symbol keyword = parameter.keyword;
    751                     LispObject value = null;
    752                     boolean unbound = true;
    753                     for (int j = argsUsed; j < argsLength; j += 2)
    754                       {
    755                         if (args[j] == keyword)
    756                           {
    757                             if (bindInitForms)
    758                                 bindArg(specials, parameter.var, args[j+1], ext, thread);
    759                             value = array[index++] = args[j+1];
    760                             if (parameter.svar != NIL)
    761                               {
    762                                 if (bindInitForms)
    763                                     bindArg(specials,(Symbol)parameter.svar, T, ext, thread);
    764                                 array[index++] = T;
    765                               }
    766                             args[j] = null;
    767                             args[j+1] = null;
    768                             unbound = false;
    769                             break;
    770                           }
    771                       }
    772                     if (unbound)
    773                       {
    774                         if (parameter.initVal != null)
    775                           value = parameter.initVal;
    776                         else
    777                           value = eval(parameter.initForm, ext, thread);
    778                         if (bindInitForms)
    779                             bindArg(specials, parameter.var, value, ext, thread);
    780                         array[index++] = value;
    781                         if (parameter.svar != NIL)
    782                           {
    783                             if (bindInitForms)
    784                                 bindArg(specials, (Symbol)parameter.svar, NIL, ext, thread);
    785                             array[index++] = NIL;
    786                           }
    787                       }
    788                     if (keyword == Keyword.ALLOW_OTHER_KEYS)
    789                       {
    790                         if (allowOtherKeysValue == null)
    791                           allowOtherKeysValue = value;
    792                       }
    793                   }
    794                 if (!allowOtherKeys)
    795                   {
    796                     if (allowOtherKeysValue == null || allowOtherKeysValue == NIL)
    797                       {
    798                         LispObject unrecognizedKeyword = null;
    799                         for (int j = argsUsed; j < argsLength; j += 2)
    800                           {
    801                             LispObject keyword = args[j];
    802                             if (keyword == null)
    803                               continue;
    804                             if (keyword == Keyword.ALLOW_OTHER_KEYS)
    805                               {
    806                                 if (allowOtherKeysValue == null)
    807                                   {
    808                                     allowOtherKeysValue = args[j+1];
    809                                     if (allowOtherKeysValue != NIL)
    810                                       break;
    811                                   }
    812                                 continue;
    813                               }
    814                             // Unused keyword argument.
    815                             boolean ok = false;
    816                             for (Parameter parameter : keywordParameters)
    817                               {
    818                                 if (parameter.keyword == keyword)
    819                                   {
    820                                     // Found it!
    821                                     ok = true;
    822                                     break;
    823                                   }
    824                               }
    825                             if (ok)
    826                               continue;
    827                             // Unrecognized keyword argument.
    828                             if (unrecognizedKeyword == null)
    829                               unrecognizedKeyword = keyword;
    830                           }
    831                         if (unrecognizedKeyword != null)
    832                           {
    833                             if (!allowOtherKeys &&
    834                                 (allowOtherKeysValue == null || allowOtherKeysValue == NIL))
    835                               error(new ProgramError("Unrecognized keyword argument " +
    836                                                       unrecognizedKeyword.printObject()));
    837                           }
    838                       }
    839                   }
    840               }
    841           }
    842         else if (argsUsed < argsLength)
    843           {
    844             // No keyword parameters.
    845             if (argsUsed + 2 <= argsLength)
    846               {
    847                 // Check for :ALLOW-OTHER-KEYS.
    848                 LispObject allowOtherKeysValue = NIL;
    849                 int n = argsUsed;
    850                 while (n < argsLength)
    851                   {
    852                     LispObject keyword = args[n];
    853                     if (keyword == Keyword.ALLOW_OTHER_KEYS)
    854                       {
    855                         allowOtherKeysValue = args[n+1];
    856                         break;
    857                       }
    858                     n += 2;
    859                   }
    860                 if (allowOtherKeys || allowOtherKeysValue != NIL)
    861                   {
    862                     // Skip keyword/value pairs.
    863                     while (argsUsed + 2 <= argsLength)
    864                       argsUsed += 2;
    865                   }
    866                 else if (andKey)
    867                   {
    868                     LispObject keyword = args[argsUsed];
    869                     if (keyword == Keyword.ALLOW_OTHER_KEYS)
    870                       {
    871                         // Section 3.4.1.4: "Note that if &KEY is present, a
    872                         // keyword argument of :ALLOW-OTHER-KEYS is always
    873                         // permitted---regardless of whether the associated
    874                         // value is true or false."
    875                         argsUsed += 2;
    876                       }
    877                   }
    878               }
    879             if (argsUsed < argsLength)
    880               {
    881                 if (restVar == null)
    882                   error(new WrongNumberOfArgumentsException(this));
    883               }
    884           }
    885         return array;
    886   }
    887  
    888650  protected final LispObject[] processArgs(LispObject[] args, LispThread thread)
    889 
    890   {
    891     if (optionalParameters.length == 0 && keywordParameters.length == 0)
    892       return fastProcessArgs(args);
    893     if (arity >= 0)
    894       {
    895         // Fixed arity.
    896         if (args.length != arity)
    897           error(new WrongNumberOfArgumentsException(this, arity));
    898         return args;
    899       }
    900     // Not fixed arity.
    901     if (args.length < minArgs)
    902       error(new WrongNumberOfArgumentsException(this, minArgs, -1));
    903    
    904     if (!bindInitForms)
    905         return _processArgs(args, thread, environment);
    906    
    907     // The bindings established here (if any) are lost when this function
    908     // returns. They are used only in the evaluation of initforms for
    909     // optional and keyword arguments.
    910     final SpecialBindingsMark mark = thread.markSpecialBindings();
    911     Environment ext = new Environment(environment);
    912     // Section 3.4.4: "...the &environment parameter is bound along with
    913     // &whole before any other variables in the lambda list..."
    914     try {
    915         return _processArgs(args, thread, ext);
    916     }
    917     finally {
    918         thread.resetSpecialBindings(mark);
    919     }
     651  {
     652    return arglist.match(args, environment, environment, thread);
    920653  }
    921654
Note: See TracChangeset for help on using the changeset viewer.