Changeset 11777


Ignore:
Timestamp:
04/22/09 19:02:12 (14 years ago)
Author:
ehuelsmann
Message:

Put special bindings restoration-to-old-value in a FINALLY clause at the end of the block.

Location:
trunk/abcl/src/org/armedbear/lisp
Files:
3 edited

Legend:

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

    r11772 r11777  
    628628    // Section 3.4.4: "...the &environment parameter is bound along with
    629629    // &whole before any other variables in the lambda list..."
    630     if (bindInitForms)
    631       if (envVar != null)
    632   bindArg(specials, envVar, environment, ext, thread);
    633     // Required parameters.
    634     for (int i = 0; i < minArgs; i++)
    635       {
     630    try {
    636631        if (bindInitForms)
    637           bindArg(specials, requiredParameters[i].var, args[i], ext, thread);
    638         array[index++] = args[i];
    639       }
    640     int i = minArgs;
    641     int argsUsed = minArgs;
    642     // Optional parameters.
    643     for (Parameter parameter : optionalParameters)
    644       {
    645         if (i < argsLength)
     632          if (envVar != null)
     633            bindArg(specials, envVar, environment, ext, thread);
     634        // Required parameters.
     635        for (int i = 0; i < minArgs; i++)
    646636          {
    647637            if (bindInitForms)
    648               bindArg(specials, parameter.var, args[i], ext, thread);
     638              bindArg(specials, requiredParameters[i].var, args[i], ext, thread);
    649639            array[index++] = args[i];
    650             ++argsUsed;
    651             if (parameter.svar != NIL)
     640          }
     641        int i = minArgs;
     642        int argsUsed = minArgs;
     643        // Optional parameters.
     644        for (Parameter parameter : optionalParameters)
     645          {
     646            if (i < argsLength)
    652647              {
    653648                if (bindInitForms)
    654                   bindArg(specials, (Symbol)parameter.svar, T, ext, thread);
    655                 array[index++] = T;
     649                  bindArg(specials, parameter.var, args[i], ext, thread);
     650                array[index++] = args[i];
     651                ++argsUsed;
     652                if (parameter.svar != NIL)
     653                  {
     654                    if (bindInitForms)
     655                      bindArg(specials, (Symbol)parameter.svar, T, ext, thread);
     656                    array[index++] = T;
     657                  }
    656658              }
    657           }
    658         else
    659           {
    660             // We've run out of arguments.
    661             LispObject value;
    662             if (parameter.initVal != null)
    663               value = parameter.initVal;
    664659            else
    665               value = eval(parameter.initForm, ext, thread);
    666             if (bindInitForms)
    667               bindArg(specials, parameter.var, value, ext, thread);
    668             array[index++] = value;
    669             if (parameter.svar != NIL)
    670660              {
    671                 if (bindInitForms)
    672                   bindArg(specials, (Symbol)parameter.svar, NIL, ext, thread);
    673                 array[index++] = NIL;
    674               }
    675           }
    676         ++i;
    677       }
    678     // &rest parameter.
    679     if (restVar != null)
    680       {
    681         LispObject rest = NIL;
    682         for (int j = argsLength; j-- > argsUsed;)
    683           rest = new Cons(args[j], rest);
    684         if (bindInitForms)
    685     bindArg(specials, restVar, rest, ext, thread);
    686         array[index++] = rest;
    687       }
    688     // Keyword parameters.
    689     if (keywordParameters.length > 0)
    690       {
    691         int argsLeft = argsLength - argsUsed;
    692         if (argsLeft == 0)
    693           {
    694             // No keyword arguments were supplied.
    695             // Bind all keyword parameters to their defaults.
    696             for (int k = 0; k < keywordParameters.length; k++)
    697               {
    698                 Parameter parameter = keywordParameters[k];
     661                // We've run out of arguments.
    699662                LispObject value;
    700663                if (parameter.initVal != null)
     
    703666                  value = eval(parameter.initForm, ext, thread);
    704667                if (bindInitForms)
    705       bindArg(specials, parameter.var, value, ext, thread);
     668                  bindArg(specials, parameter.var, value, ext, thread);
    706669                array[index++] = value;
    707670                if (parameter.svar != NIL)
    708671                  {
    709672                    if (bindInitForms)
    710           bindArg(specials, (Symbol)parameter.svar, NIL, ext, thread);
     673                      bindArg(specials, (Symbol)parameter.svar, NIL, ext, thread);
    711674                    array[index++] = NIL;
    712675                  }
    713676              }
    714           }
    715         else
    716           {
    717             if ((argsLeft % 2) != 0)
    718               error(new ProgramError("Odd number of keyword arguments."));
    719             LispObject allowOtherKeysValue = null;
    720             for (Parameter parameter : keywordParameters)
     677            ++i;
     678          }
     679        // &rest parameter.
     680        if (restVar != null)
     681          {
     682            LispObject rest = NIL;
     683            for (int j = argsLength; j-- > argsUsed;)
     684              rest = new Cons(args[j], rest);
     685            if (bindInitForms)
     686                bindArg(specials, restVar, rest, ext, thread);
     687            array[index++] = rest;
     688          }
     689        // Keyword parameters.
     690        if (keywordParameters.length > 0)
     691          {
     692            int argsLeft = argsLength - argsUsed;
     693            if (argsLeft == 0)
    721694              {
    722                 Symbol keyword = parameter.keyword;
    723                 LispObject value = null;
    724                 boolean unbound = true;
    725                 for (int j = argsUsed; j < argsLength; j += 2)
    726                   {
    727                     if (args[j] == keyword)
    728                       {
    729                         if (bindInitForms)
    730         bindArg(specials, parameter.var, args[j+1], ext, thread);
    731                         value = array[index++] = args[j+1];
    732                         if (parameter.svar != NIL)
    733                           {
    734                             if (bindInitForms)
    735             bindArg(specials,(Symbol)parameter.svar, T, ext, thread);
    736                             array[index++] = T;
    737                           }
    738                         args[j] = null;
    739                         args[j+1] = null;
    740                         unbound = false;
    741                         break;
    742                       }
    743                   }
    744                 if (unbound)
    745                   {
     695                // No keyword arguments were supplied.
     696                // Bind all keyword parameters to their defaults.
     697                for (int k = 0; k < keywordParameters.length; k++)
     698                  {
     699                    Parameter parameter = keywordParameters[k];
     700                    LispObject value;
    746701                    if (parameter.initVal != null)
    747702                      value = parameter.initVal;
     
    749704                      value = eval(parameter.initForm, ext, thread);
    750705                    if (bindInitForms)
    751           bindArg(specials, parameter.var, value, ext, thread);
     706                        bindArg(specials, parameter.var, value, ext, thread);
    752707                    array[index++] = value;
    753708                    if (parameter.svar != NIL)
    754709                      {
    755710                        if (bindInitForms)
    756         bindArg(specials, (Symbol)parameter.svar, NIL, ext, thread);
     711                            bindArg(specials, (Symbol)parameter.svar, NIL, ext, thread);
    757712                        array[index++] = NIL;
    758713                      }
    759714                  }
    760                 if (keyword == Keyword.ALLOW_OTHER_KEYS)
    761                   {
    762                     if (allowOtherKeysValue == null)
    763                       allowOtherKeysValue = value;
    764                   }
    765715              }
    766             if (!allowOtherKeys)
     716            else
    767717              {
    768                 if (allowOtherKeysValue == null || allowOtherKeysValue == NIL)
    769                   {
    770                     LispObject unrecognizedKeyword = null;
     718                if ((argsLeft % 2) != 0)
     719                  error(new ProgramError("Odd number of keyword arguments."));
     720                LispObject allowOtherKeysValue = null;
     721                for (Parameter parameter : keywordParameters)
     722                  {
     723                    Symbol keyword = parameter.keyword;
     724                    LispObject value = null;
     725                    boolean unbound = true;
    771726                    for (int j = argsUsed; j < argsLength; j += 2)
    772727                      {
    773                         LispObject keyword = args[j];
    774                         if (keyword == null)
    775                           continue;
    776                         if (keyword == Keyword.ALLOW_OTHER_KEYS)
     728                        if (args[j] == keyword)
    777729                          {
    778                             if (allowOtherKeysValue == null)
     730                            if (bindInitForms)
     731                                bindArg(specials, parameter.var, args[j+1], ext, thread);
     732                            value = array[index++] = args[j+1];
     733                            if (parameter.svar != NIL)
    779734                              {
    780                                 allowOtherKeysValue = args[j+1];
    781                                 if (allowOtherKeysValue != NIL)
    782                                   break;
     735                                if (bindInitForms)
     736                                    bindArg(specials,(Symbol)parameter.svar, T, ext, thread);
     737                                array[index++] = T;
    783738                              }
    784                             continue;
     739                            args[j] = null;
     740                            args[j+1] = null;
     741                            unbound = false;
     742                            break;
    785743                          }
    786                         // Unused keyword argument.
    787                         boolean ok = false;
    788                         for (Parameter parameter : keywordParameters)
     744                      }
     745                    if (unbound)
     746                      {
     747                        if (parameter.initVal != null)
     748                          value = parameter.initVal;
     749                        else
     750                          value = eval(parameter.initForm, ext, thread);
     751                        if (bindInitForms)
     752                            bindArg(specials, parameter.var, value, ext, thread);
     753                        array[index++] = value;
     754                        if (parameter.svar != NIL)
    789755                          {
    790                             if (parameter.keyword == keyword)
     756                            if (bindInitForms)
     757                                bindArg(specials, (Symbol)parameter.svar, NIL, ext, thread);
     758                            array[index++] = NIL;
     759                          }
     760                      }
     761                    if (keyword == Keyword.ALLOW_OTHER_KEYS)
     762                      {
     763                        if (allowOtherKeysValue == null)
     764                          allowOtherKeysValue = value;
     765                      }
     766                  }
     767                if (!allowOtherKeys)
     768                  {
     769                    if (allowOtherKeysValue == null || allowOtherKeysValue == NIL)
     770                      {
     771                        LispObject unrecognizedKeyword = null;
     772                        for (int j = argsUsed; j < argsLength; j += 2)
     773                          {
     774                            LispObject keyword = args[j];
     775                            if (keyword == null)
     776                              continue;
     777                            if (keyword == Keyword.ALLOW_OTHER_KEYS)
    791778                              {
    792                                 // Found it!
    793                                 ok = true;
    794                                 break;
     779                                if (allowOtherKeysValue == null)
     780                                  {
     781                                    allowOtherKeysValue = args[j+1];
     782                                    if (allowOtherKeysValue != NIL)
     783                                      break;
     784                                  }
     785                                continue;
    795786                              }
     787                            // Unused keyword argument.
     788                            boolean ok = false;
     789                            for (Parameter parameter : keywordParameters)
     790                              {
     791                                if (parameter.keyword == keyword)
     792                                  {
     793                                    // Found it!
     794                                    ok = true;
     795                                    break;
     796                                  }
     797                              }
     798                            if (ok)
     799                              continue;
     800                            // Unrecognized keyword argument.
     801                            if (unrecognizedKeyword == null)
     802                              unrecognizedKeyword = keyword;
    796803                          }
    797                         if (ok)
    798                           continue;
    799                         // Unrecognized keyword argument.
    800                         if (unrecognizedKeyword == null)
    801                           unrecognizedKeyword = keyword;
    802                       }
    803                     if (unrecognizedKeyword != null)
    804                       {
    805                         if (!allowOtherKeys &&
    806                             (allowOtherKeysValue == null || allowOtherKeysValue == NIL))
    807                           error(new ProgramError("Unrecognized keyword argument " +
    808                                                   unrecognizedKeyword.writeToString()));
     804                        if (unrecognizedKeyword != null)
     805                          {
     806                            if (!allowOtherKeys &&
     807                                (allowOtherKeysValue == null || allowOtherKeysValue == NIL))
     808                              error(new ProgramError("Unrecognized keyword argument " +
     809                                                      unrecognizedKeyword.writeToString()));
     810                          }
    809811                      }
    810812                  }
    811813              }
    812814          }
    813       }
    814     else if (argsUsed < argsLength)
    815       {
    816         // No keyword parameters.
    817         if (argsUsed + 2 <= argsLength)
    818           {
    819             // Check for :ALLOW-OTHER-KEYS.
    820             LispObject allowOtherKeysValue = NIL;
    821             int n = argsUsed;
    822             while (n < argsLength)
     815        else if (argsUsed < argsLength)
     816          {
     817            // No keyword parameters.
     818            if (argsUsed + 2 <= argsLength)
    823819              {
    824                 LispObject keyword = args[n];
    825                 if (keyword == Keyword.ALLOW_OTHER_KEYS)
    826                   {
    827                     allowOtherKeysValue = args[n+1];
    828                     break;
    829                   }
    830                 n += 2;
     820                // Check for :ALLOW-OTHER-KEYS.
     821                LispObject allowOtherKeysValue = NIL;
     822                int n = argsUsed;
     823                while (n < argsLength)
     824                  {
     825                    LispObject keyword = args[n];
     826                    if (keyword == Keyword.ALLOW_OTHER_KEYS)
     827                      {
     828                        allowOtherKeysValue = args[n+1];
     829                        break;
     830                      }
     831                    n += 2;
     832                  }
     833                if (allowOtherKeys || allowOtherKeysValue != NIL)
     834                  {
     835                    // Skip keyword/value pairs.
     836                    while (argsUsed + 2 <= argsLength)
     837                      argsUsed += 2;
     838                  }
     839                else if (andKey)
     840                  {
     841                    LispObject keyword = args[argsUsed];
     842                    if (keyword == Keyword.ALLOW_OTHER_KEYS)
     843                      {
     844                        // Section 3.4.1.4: "Note that if &KEY is present, a
     845                        // keyword argument of :ALLOW-OTHER-KEYS is always
     846                        // permitted---regardless of whether the associated
     847                        // value is true or false."
     848                        argsUsed += 2;
     849                      }
     850                  }
    831851              }
    832             if (allowOtherKeys || allowOtherKeysValue != NIL)
     852            if (argsUsed < argsLength)
    833853              {
    834                 // Skip keyword/value pairs.
    835                 while (argsUsed + 2 <= argsLength)
    836                   argsUsed += 2;
     854                if (restVar == null)
     855                  error(new WrongNumberOfArgumentsException(this));
    837856              }
    838             else if (andKey)
    839               {
    840                 LispObject keyword = args[argsUsed];
    841                 if (keyword == Keyword.ALLOW_OTHER_KEYS)
    842                   {
    843                     // Section 3.4.1.4: "Note that if &KEY is present, a
    844                     // keyword argument of :ALLOW-OTHER-KEYS is always
    845                     // permitted---regardless of whether the associated
    846                     // value is true or false."
    847                     argsUsed += 2;
    848                   }
    849               }
    850           }
    851         if (argsUsed < argsLength)
    852           {
    853             if (restVar == null)
    854               error(new WrongNumberOfArgumentsException(this));
    855           }
    856       }
    857     thread.lastSpecialBinding = lastSpecialBinding;
     857          }
     858    }
     859    finally {
     860        thread.lastSpecialBinding = lastSpecialBinding;
     861    }
    858862    return array;
    859863  }
  • trunk/abcl/src/org/armedbear/lisp/Lisp.java

    r11772 r11777  
    17961796                        SpecialBinding lastSpecialBinding = thread.lastSpecialBinding;
    17971797                        thread.bindSpecial(Symbol.PRINT_ESCAPE, T);
    1798                         sb.append(obj.writeToString());
    1799                         thread.lastSpecialBinding = lastSpecialBinding;
     1798                        try {
     1799                            sb.append(obj.writeToString());
     1800                        }
     1801                        finally {
     1802                            thread.lastSpecialBinding = lastSpecialBinding;
     1803                        }
    18001804                      }
    18011805                  }
     
    18091813                        thread.bindSpecial(Symbol.PRINT_RADIX, NIL);
    18101814                        thread.bindSpecial(Symbol.PRINT_BASE, Fixnum.constants[10]);
    1811                         sb.append(obj.writeToString());
    1812                         thread.lastSpecialBinding = lastSpecialBinding;
     1815                        try {
     1816                            sb.append(obj.writeToString());
     1817                        }
     1818                        finally {
     1819                            thread.lastSpecialBinding = lastSpecialBinding;
     1820                        }
    18131821                      }
    18141822                  }
     
    18221830                        thread.bindSpecial(Symbol.PRINT_RADIX, NIL);
    18231831                        thread.bindSpecial(Symbol.PRINT_BASE, Fixnum.constants[16]);
    1824                         sb.append(obj.writeToString());
    1825                         thread.lastSpecialBinding = lastSpecialBinding;
     1832                        try {
     1833                            sb.append(obj.writeToString());
     1834                        }
     1835                        finally {
     1836                            thread.lastSpecialBinding = lastSpecialBinding;
     1837                        }
    18261838                      }
    18271839                  }
  • trunk/abcl/src/org/armedbear/lisp/UnboundVariable.java

    r11488 r11777  
    5959      }
    6060    catch (Throwable t) {}
     61    finally {
     62        thread.lastSpecialBinding = lastSpecialBinding;
     63    }
    6164    sb.append(" is unbound.");
    62     thread.lastSpecialBinding = lastSpecialBinding;
    6365    return sb.toString();
    6466  }
Note: See TracChangeset for help on using the changeset viewer.