Changeset 13831


Ignore:
Timestamp:
01/29/12 23:57:04 (9 years ago)
Author:
ehuelsmann
Message:

Remove lambda list parsing from Closure: it's now fully handled
by ArgumentListProcessor?.

File:
1 edited

Legend:

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

    r13829 r13831  
    4848  public static final int AUX      = 4;
    4949
    50   // States.
    51   private static final int STATE_REQUIRED = 0;
    52   private static final int STATE_OPTIONAL = 1;
    53   private static final int STATE_KEYWORD  = 2;
    54   private static final int STATE_REST     = 3;
    55   private static final int STATE_AUX      = 4;
    56 
    57   private Parameter[] requiredParameters = new Parameter[0];
    58   private Parameter[] optionalParameters = requiredParameters;
    59   private Parameter[] keywordParameters = requiredParameters;
    60   private Parameter[] auxVars = requiredParameters;
    6150  private final LispObject body;
    6251  private final LispObject executionBody;
    6352  private final Environment environment;
    64   private final boolean andKey;
    65   private final boolean allowOtherKeys;
    66   private Symbol restVar;
    67   private Symbol envVar;
    6853  private int arity;
    6954
     
    9883          ? maxArgs : -1;
    9984
    100       requiredParameters = required;
    101       optionalParameters = optional;
    102       keywordParameters = keyword;
    103 
    10485      if (rest != NIL)
    10586        restVar = rest;
    106 
    107       andKey = keys != NIL;
    108       allowOtherKeys = moreKeys != NIL;
    10987
    11088      // stuff we don't need: we're a compiled function
     
    11593      ArrayList<ArgumentListProcessor.RequiredParam> reqParams =
    11694              new ArrayList<ArgumentListProcessor.RequiredParam>();
    117       for (Parameter req : requiredParameters)
     95      for (Parameter req : required)
    11896          reqParams.add(new ArgumentListProcessor.RequiredParam(req.var, false));
    11997
    12098      ArrayList<ArgumentListProcessor.OptionalParam> optParams =
    12199              new ArrayList<ArgumentListProcessor.OptionalParam>();
    122       for (Parameter opt : optionalParameters)
     100      for (Parameter opt : optional)
    123101          optParams.add(new ArgumentListProcessor.OptionalParam(opt.var, false,
    124102                  (opt.svar == NIL) ? null : (Symbol)opt.svar, false,
     
    127105      ArrayList<ArgumentListProcessor.KeywordParam> keyParams =
    128106              new ArrayList<ArgumentListProcessor.KeywordParam>();
    129       for (Parameter key : keywordParameters)
     107      for (Parameter key : keyword)
    130108          keyParams.add(new ArgumentListProcessor.KeywordParam(key.var, false,
    131109                  (key.svar == NIL) ? null : (Symbol)key.svar, false, key.initForm,
    132110                  key.keyword));
    133       arglist = new ArgumentListProcessor(this, reqParams, optParams, keyParams, andKey, allowOtherKeys, restVar);
     111      arglist = new ArgumentListProcessor(this, reqParams, optParams,
     112                                          keyParams, keys != NIL,
     113                                          moreKeys != NIL, restVar);
    134114  }
    135115
     
    150130      error(new ProgramError("The lambda list " + lambdaList.princToString() +
    151131                           " is invalid."));
    152     boolean _andKey = false;
    153     boolean _allowOtherKeys = false;
    154     if (lambdaList instanceof Cons)
    155       {
    156         final int length = lambdaList.length();
    157         ArrayList<Parameter> required = null;
    158         ArrayList<Parameter> optional = null;
    159         ArrayList<Parameter> keywords = null;
    160         ArrayList<Parameter> aux = null;
    161         int state = STATE_REQUIRED;
    162         LispObject remaining = lambdaList;
    163         while (remaining != NIL)
    164           {
    165             LispObject obj = remaining.car();
    166             if (obj instanceof Symbol)
    167               {
    168                 if (state == STATE_AUX)
    169                   {
    170                     if (aux == null)
    171                       aux = new ArrayList<Parameter>();
    172                     aux.add(new Parameter((Symbol)obj, NIL, AUX));
    173                   }
    174                 else if (obj == Symbol.AND_OPTIONAL)
    175                   {
    176                     state = STATE_OPTIONAL;
    177                     arity = -1;
    178                   }
    179                 else if (obj == Symbol.AND_REST || obj == Symbol.AND_BODY)
    180                   {
    181                     if (_andKey)
    182                       {
    183                         error(new ProgramError(
    184                           "&REST/&BODY must precede &KEY."));
    185                       }
    186                     state = STATE_REST;
    187                     arity = -1;
    188                     maxArgs = -1;
    189                     remaining = remaining.cdr();
    190                     if (remaining == NIL)
    191                       {
    192                         error(new ProgramError(
    193                           "&REST/&BODY must be followed by a variable."));
    194                       }
    195                     if (restVar != null)
    196                       {
    197                         error(new ProgramError(
    198                           "&REST/&BODY may occur only once."));
    199                       }
    200                     final LispObject remainingcar =  remaining.car();
    201                     if (remainingcar instanceof Symbol)
    202                       {
    203                         restVar = (Symbol) remainingcar;
    204                       }
    205                     else
    206                       {
    207                         error(new ProgramError(
    208                           "&REST/&BODY must be followed by a variable."));
    209                       }
    210                   }
    211                 else if (obj == Symbol.AND_ENVIRONMENT)
    212                   {
    213                     remaining = remaining.cdr();
    214                     envVar = (Symbol) remaining.car();
    215                     arity = -1; // FIXME
    216                   }
    217                 else if (obj == Symbol.AND_KEY)
    218                   {
    219                     state = STATE_KEYWORD;
    220                     _andKey = true;
    221                     arity = -1;
    222                   }
    223                 else if (obj == Symbol.AND_ALLOW_OTHER_KEYS)
    224                   {
    225                     _allowOtherKeys = true;
    226                     maxArgs = -1;
    227                   }
    228                 else if (obj == Symbol.AND_AUX)
    229                   {
    230                     // All remaining specifiers are aux variable specifiers.
    231                     state = STATE_AUX;
    232                     arity = -1; // FIXME
    233                   }
    234                 else
    235                   {
    236                     if (state == STATE_OPTIONAL)
    237                       {
    238                         if (optional == null)
    239                           optional = new ArrayList<Parameter>();
    240                         optional.add(new Parameter((Symbol)obj, NIL, OPTIONAL));
    241                         if (maxArgs >= 0)
    242                           ++maxArgs;
    243                       }
    244                     else if (state == STATE_KEYWORD)
    245                       {
    246                         if (keywords == null)
    247                           keywords = new ArrayList<Parameter>();
    248                         keywords.add(new Parameter((Symbol)obj, NIL, KEYWORD));
    249                         if (maxArgs >= 0)
    250                           maxArgs += 2;
    251                       }
    252                     else
    253                       {
    254                         if (state != STATE_REQUIRED)
    255                           {
    256                             error(new ProgramError(
    257                               "required parameters cannot appear after &REST/&BODY."));
    258                           }
    259                         if (required == null)
    260                           required = new ArrayList<Parameter>();
    261                         required.add(new Parameter((Symbol)obj));
    262                         if (maxArgs >= 0)
    263                           ++maxArgs;
    264                       }
    265                   }
    266               }
    267             else if (obj instanceof Cons)
    268               {
    269                 if (state == STATE_AUX)
    270                   {
    271                     Symbol sym = checkSymbol(obj.car());
    272                     LispObject initForm = obj.cadr();
    273                     Debug.assertTrue(initForm != null);
    274                     if (aux == null)
    275                       aux = new ArrayList<Parameter>();
    276                     aux.add(new Parameter(sym, initForm, AUX));
    277                   }
    278                 else if (state == STATE_OPTIONAL)
    279                   {
    280                     Symbol sym = checkSymbol(obj.car());
    281                     LispObject initForm = obj.cadr();
    282                     LispObject svar = obj.cdr().cdr().car();
    283                     if (optional == null)
    284                       optional = new ArrayList<Parameter>();
    285                     optional.add(new Parameter(sym, initForm, svar, OPTIONAL));
    286                     if (maxArgs >= 0)
    287                       ++maxArgs;
    288                   }
    289                 else if (state == STATE_KEYWORD)
    290                   {
    291                     Symbol keyword;
    292                     Symbol var;
    293                     LispObject initForm = NIL;
    294                     LispObject svar = NIL;
    295                     LispObject first = obj.car();
    296                     if (first instanceof Cons)
    297                       {
    298                         keyword = checkSymbol(first.car());
    299                         var = checkSymbol(first.cadr());
    300                       }
    301                     else
    302                       {
    303                         var = checkSymbol(first);
    304                         keyword =
    305                           PACKAGE_KEYWORD.intern(var.name);
    306                       }
    307                     obj = obj.cdr();
    308                     if (obj != NIL)
    309                       {
    310                         initForm = obj.car();
    311                         obj = obj.cdr();
    312                         if (obj != NIL)
    313                           svar = obj.car();
    314                       }
    315                     if (keywords == null)
    316                       keywords = new ArrayList<Parameter>();
    317                     keywords.add(new Parameter(keyword, var, initForm, svar));
    318                     if (maxArgs >= 0)
    319                       maxArgs += 2;
    320                   }
    321                 else
    322                   invalidParameter(obj);
    323               }
    324             else
    325               invalidParameter(obj);
    326             remaining = remaining.cdr();
    327           }
    328         if (arity == 0)
    329           arity = length;
    330         if (required != null)
    331           {
    332             requiredParameters = new Parameter[required.size()];
    333             required.toArray(requiredParameters);
    334           }
    335         if (optional != null)
    336           {
    337             optionalParameters = new Parameter[optional.size()];
    338             optional.toArray(optionalParameters);
    339           }
    340         if (keywords != null)
    341           {
    342             keywordParameters = new Parameter[keywords.size()];
    343             keywords.toArray(keywordParameters);
    344           }
    345         if (aux != null)
    346           {
    347             auxVars = new Parameter[aux.size()];
    348             aux.toArray(auxVars);
    349           }
    350       }
    351     else
    352       {
    353         // Lambda list is empty.
    354         Debug.assertTrue(lambdaList == NIL);
    355         arity = 0;
    356         maxArgs = 0;
    357       }
    358132    this.body = lambdaExpression.cddr();
    359133    LispObject bodyAndDecls = parseBody(this.body, false);
     
    362136
    363137    this.environment = env;
    364     this.andKey = _andKey;
    365     this.allowOtherKeys = _allowOtherKeys;
    366     minArgs = requiredParameters.length;
    367     if (arity >= 0)
    368       Debug.assertTrue(arity == minArgs);
    369138
    370139    arglist = new ArgumentListProcessor(this, lambdaList, specials);
    371140    freeSpecials = arglist.freeSpecials(specials);
    372   }
    373 
    374   private static final void invalidParameter(LispObject obj)
    375 
    376   {
    377     error(new ProgramError(obj.princToString() +
    378                          " may not be used as a variable in a lambda list."));
     141    minArgs = arglist.getMinArgs();
     142    arity = arglist.getArity();
    379143  }
    380144
Note: See TracChangeset for help on using the changeset viewer.