Changeset 5253


Ignore:
Timestamp:
12/26/03 16:28:30 (17 years ago)
Author:
piso
Message:

processArgs(): bind keyword arguments in correct order.

File:
1 edited

Legend:

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

    r5252 r5253  
    33 *
    44 * Copyright (C) 2002-2003 Peter Graves
    5  * $Id: Closure.java,v 1.62 2003-12-25 17:19:07 piso Exp $
     5 * $Id: Closure.java,v 1.63 2003-12-26 16:28:30 piso Exp $
    66 *
    77 * This program is free software; you can redistribute it and/or
     
    587587                if ((argsLeft % 2) != 0)
    588588                    signal(new ProgramError("odd number of keyword arguments"));
    589                 LispObject[] valueArray = new LispObject[keywordParameters.length];
    590                 boolean[] boundpArray = new boolean[keywordParameters.length];
    591589                LispObject allowOtherKeysValue = null;
    592                 LispObject unrecognizedKeyword = null;
    593                 for (int j = argsUsed; j < args.length; j += 2) {
    594                     LispObject keyword = args[j];
    595                     if (keyword == Keyword.ALLOW_OTHER_KEYS) {
    596                         if (allowOtherKeysValue == null)
    597                             allowOtherKeysValue = args[j+1];
     590                for (int k = 0; k < keywordParameters.length; k++) {
     591                    Parameter parameter = keywordParameters[k];
     592                    Symbol keyword = parameter.keyword;
     593                    LispObject value = null;
     594                    boolean unbound = true;
     595                    for (int j = argsUsed; j < args.length; j += 2) {
     596                        if (args[j] == keyword) {
     597                            bind(parameter.var, args[j+1], ext);
     598                            value = array[index++] = args[j+1];
     599                            if (parameter.svar != NIL) {
     600                                bind((Symbol)parameter.svar, T, ext);
     601                                array[index++] = T;
     602                            }
     603                            args[j] = null;
     604                            args[j+1] = null;
     605                            unbound = false;
     606                            break;
     607                        }
    598608                    }
    599                     // Find it.
    600                     int k;
    601                     for (k = keywordParameters.length; k-- > 0;) {
    602                         if (keywordParameters[k].keyword == keyword) {
    603                             // Found it!
    604                             if (!boundpArray[k]) {
    605                                 Parameter parameter = keywordParameters[k];
    606                                 Symbol symbol = parameter.var;
    607                                 bind(symbol, args[j+1], ext);
    608                                 valueArray[k] = args[j+1];
    609                                 if (parameter.svar != NIL)
    610                                     bind((Symbol)parameter.svar, T, ext);
    611                                 boundpArray[k] = true;
    612                             }
    613                             break;
    614                         }
    615                     }
    616                     if (k < 0) {
    617                         // Not found.
    618                         if (keyword != Keyword.ALLOW_OTHER_KEYS)
    619                             if (unrecognizedKeyword == null)
    620                                 unrecognizedKeyword = keyword;
    621                     }
    622                 }
    623                 if (unrecognizedKeyword != null) {
    624                     if (!allowOtherKeys &&
    625                         (allowOtherKeysValue == null || allowOtherKeysValue == NIL))
    626                         signal(new ProgramError("unrecognized keyword argument " +
    627                                                 unrecognizedKeyword));
    628                 }
    629                 for (int n = 0; n < keywordParameters.length; n++) {
    630                     Parameter parameter = keywordParameters[n];
    631                     if (boundpArray[n]) {
    632                         // Parameter was bound above, so we don't have to bind
    633                         // it again here.
    634                         array[index++] = valueArray[n];
    635                         if (parameter.svar != NIL) {
    636                             // svar was bound above, so we don't have to bind
    637                             // it again here.
    638                             array[index++] = T;
    639                         }
    640                     } else {
    641                         // Not supplied.
     609                    if (unbound) {
    642610                        LispObject initForm = parameter.initForm;
    643                         LispObject value =
    644                             initForm != null ? eval(initForm, ext, thread) : NIL;
     611                        value = initForm != null ? eval(initForm, ext, thread) : NIL;
    645612                        bind(parameter.var, value, ext);
    646613                        array[index++] = value;
     
    648615                            bind((Symbol)parameter.svar, NIL, ext);
    649616                            array[index++] = NIL;
     617                        }
     618                    }
     619                    if (keyword == Keyword.ALLOW_OTHER_KEYS) {
     620                        if (allowOtherKeysValue == null)
     621                            allowOtherKeysValue = value;
     622                    }
     623                }
     624                if (!allowOtherKeys) {
     625                    if (allowOtherKeysValue == null || allowOtherKeysValue == NIL) {
     626                        LispObject unrecognizedKeyword = null;
     627                        for (int j = argsUsed; j < args.length; j += 2) {
     628                            LispObject keyword = args[j];
     629                            if (keyword == null)
     630                                continue;
     631                            if (keyword == Keyword.ALLOW_OTHER_KEYS) {
     632                                if (allowOtherKeysValue == null) {
     633                                    allowOtherKeysValue = args[j+1];
     634                                    if (allowOtherKeysValue != NIL)
     635                                        break;
     636                                }
     637                                continue;
     638                            }
     639                            // Unused keyword argument.
     640                            boolean ok = false;
     641                            for (int k = keywordParameters.length; k-- > 0;) {
     642                                if (keywordParameters[k].keyword == keyword) {
     643                                    // Found it!
     644                                    ok = true;
     645                                    break;
     646                                }
     647                            }
     648                            if (ok)
     649                                continue;
     650                            // Unrecognized keyword argument.
     651                            if (unrecognizedKeyword == null)
     652                                unrecognizedKeyword = keyword;
     653                        }
     654                        if (unrecognizedKeyword != null) {
     655                            if (!allowOtherKeys &&
     656                                (allowOtherKeysValue == null || allowOtherKeysValue == NIL))
     657                                signal(new ProgramError("unrecognized keyword argument " +
     658                                                        unrecognizedKeyword));
    650659                        }
    651660                    }
Note: See TracChangeset for help on using the changeset viewer.