Changeset 14131
- Timestamp:
- 08/21/12 14:00:13 (8 years ago)
- Location:
- trunk/abcl/src/org/armedbear/lisp
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/abcl/src/org/armedbear/lisp/ArgumentListProcessor.java
r14022 r14131 39 39 import static org.armedbear.lisp.Lisp.*; 40 40 41 /** A class to parse a lambda list and match function call arguments with it 41 /** A class to parse a lambda list and match function call arguments with it. 42 * 43 * The lambda list may either be of type ORDINARY or MACRO lambda list. 44 * All other lambda lists are parsed elsewhere in our code base. 42 45 */ 43 46 public class ArgumentListProcessor { 47 48 public enum LambdaListType { 49 ORDINARY, 50 MACRO 51 } 44 52 45 53 // States. … … 163 171 * bind as specials during initform evaluation 164 172 */ 165 public ArgumentListProcessor(Operator fun, LispObject lambdaList, LispObject specials) { 173 public ArgumentListProcessor(Operator fun, LispObject lambdaList, 174 LispObject specials, LambdaListType type) { 166 175 function = fun; 167 176 … … 177 186 int state = STATE_REQUIRED; 178 187 LispObject remaining = lambdaList; 188 189 if (remaining.car() == Symbol.AND_WHOLE) { 190 if (type == LambdaListType.ORDINARY) { 191 error(new ProgramError("&WHOLE not allowed in ordinary lambda lists.")); 192 } else { 193 // skip the &WHOLE <var> part of the lambda list 194 remaining = remaining.cdr().cdr(); 195 } 196 } 197 198 179 199 while (remaining != NIL) 180 200 { … … 182 202 if (obj instanceof Symbol) 183 203 { 204 if (obj == Symbol.AND_WHOLE) { 205 if (type == LambdaListType.ORDINARY) 206 error(new ProgramError("&WHOLE not allowed in ordinary lambda lists.")); 207 else 208 error(new ProgramError("&WHOLE must appear first in macro lambda list.")); 209 } 184 210 if (state == STATE_AUX) 185 211 { … … 201 227 "&REST/&BODY must precede &KEY.")); 202 228 } 229 if (type == LambdaListType.ORDINARY && obj == Symbol.AND_BODY) 230 error(new ProgramError("&BODY not allowed in ordinary lambda lists.")); 203 231 state = STATE_REST; 204 232 arity = -1; … … 229 257 else if (obj == Symbol.AND_ENVIRONMENT) 230 258 { 259 if (type == LambdaListType.ORDINARY) 260 error(new ProgramError("&ENVIRONMENT not allowed in ordinary lambda lists.")); 231 261 remaining = remaining.cdr(); 232 262 envVar = (Symbol) remaining.car(); -
trunk/abcl/src/org/armedbear/lisp/Closure.java
r14130 r14131 96 96 this.environment = env; 97 97 98 arglist = new ArgumentListProcessor(this, lambdaList, specials); 98 /* In the bootstrapping process, functions with MACRO LAMBDA LIST 99 * lambda list types are being generated using the MACRO_FUNCTION instead 100 * of the LAMBDA or NAMED_LAMBDA keys. 101 * 102 * Use that to perform argument list lambda list keyword checking. 103 */ 104 arglist = new ArgumentListProcessor(this, lambdaList, specials, 105 (lambdaExpression.car() == Symbol.MACRO_FUNCTION) ? 106 ArgumentListProcessor.LambdaListType.MACRO 107 : ArgumentListProcessor.LambdaListType.ORDINARY); 99 108 freeSpecials = arglist.freeSpecials(specials); 100 109 } -
trunk/abcl/src/org/armedbear/lisp/Primitives.java
r14023 r14131 1880 1880 1881 1881 { 1882 /* Create an expansion function 1883 * `(lambda (,formArg ,envArg) 1884 * (apply (function (macro-function ,lambdaList 1885 * (block ,symbol ,@body))) 1886 * (cdr ,formArg))) 1887 */ 1882 1888 Symbol symbol = checkSymbol(args.car()); 1883 1889 LispObject lambdaList = checkList(args.cadr()); … … 1885 1891 LispObject block = new Cons(Symbol.BLOCK, new Cons(symbol, body)); 1886 1892 LispObject toBeApplied = 1887 list(Symbol.FUNCTION, list(Symbol. LAMBDA, lambdaList, block));1893 list(Symbol.FUNCTION, list(Symbol.MACRO_FUNCTION, lambdaList, block)); 1888 1894 final LispThread thread = LispThread.currentThread(); 1889 1895 LispObject formArg = gensym("FORM-", thread); … … 1900 1906 else 1901 1907 symbol.setSymbolFunction(macroObject); 1902 macroObject.setLambdaList( lambdaList);1903 thread._values = null;1908 macroObject.setLambdaList(args.cadr()); 1909 LispThread.currentThread()._values = null; 1904 1910 return symbol; 1905 1911 } … … 3657 3663 3658 3664 { 3665 /* Create an expansion function 3666 * `(lambda (,formArg ,envArg) 3667 * (apply (function (macro-function ,lambdaList 3668 * (block ,symbol ,@body))) 3669 * (cdr ,formArg))) 3670 */ 3659 3671 Symbol symbol = checkSymbol(definition.car()); 3660 3672 LispObject lambdaList = definition.cadr(); … … 3663 3675 new Cons(Symbol.BLOCK, new Cons(symbol, body)); 3664 3676 LispObject toBeApplied = 3665 list(Symbol. LAMBDA, lambdaList, block);3677 list(Symbol.FUNCTION, list(Symbol.MACRO_FUNCTION, lambdaList, block)); 3666 3678 final LispThread thread = LispThread.currentThread(); 3667 3679 LispObject formArg = gensym("WHOLE-", thread); -
trunk/abcl/src/org/armedbear/lisp/SpecialOperators.java
r13695 r14131 499 499 return type_error(name, FUNCTION_NAME); 500 500 } 501 if (car == Symbol.MACRO_FUNCTION) 502 return new Closure(arg, env); 501 503 } 502 504 return error(new UndefinedFunction(list(Keyword.NAME, arg)));
Note: See TracChangeset
for help on using the changeset viewer.