author | Alan Dipert
<alan@dipert.org> 2019-10-30 14:36:32 UTC |
committer | Alan Dipert
<alan@dipert.org> 2019-10-30 14:36:32 UTC |
parent | 092f439ab4f18df9ef625b93ef8d106783d8d9db |
jacl.js | +12 | -50 |
diff --git a/jacl.js b/jacl.js index effedb1..75c1571 100644 --- a/jacl.js +++ b/jacl.js @@ -870,6 +870,12 @@ const parseLambdaList = list => { x.packageName === 'COMMON-LISP' && x.name === name; + const checkLocal = x => { + if (!(x instanceof LispSymbol) || x.packageName == 'KEYWORD') + throw new Error(`${x} not a valid local variable`); + return x; + }; + let arr = Cons.toArray(list), sections = { required: [], @@ -891,7 +897,7 @@ const parseLambdaList = list => { } else if (clSym(x, '&REST')) { state = 'rest'; } else if (x instanceof LispSymbol) { - sections.required.push(x); + sections.required.push(checkLocal(x)); } else { throw new Error(`Required argument is not a symbol`); } @@ -904,7 +910,7 @@ const parseLambdaList = list => { } else if (clSym(x, '&REST')) { state = 'rest'; } else if (x instanceof LispSymbol) { - sections.optional.push([x, UNDEFINED, UNDEFINED]); + sections.optional.push([checkLocal(x), UNDEFINED, UNDEFINED]); } else if (x instanceof Cons) { if (!Cons.isProperList(x)) throw new Error(`&OPTIONAL parameter list is improper`); @@ -912,20 +918,14 @@ const parseLambdaList = list => { case 0: throw new Error(`Empty optional parameter`); case 1: - if (!(x.car instanceof LispSymbol)) - throw new Error(`Optional parameter name not a symbol`); - sections.optional.push([x.car, UNDEFINED, UNDEFINED]); + sections.optional.push([checkLocal(x.car), UNDEFINED, UNDEFINED]); break; case 2: - if (!(x.car instanceof LispSymbol)) - throw new Error(`Optional parameter name not a symbol`); - sections.optional.push([x.car, x.cdr.car, UNDEFINED]); + sections.optional.push([checkLocal(x.car), x.cdr.car, UNDEFINED]); break; case 3: { - if (!(x.car instanceof LispSymbol)) - throw new Error(`Optional parameter name not a symbol`); - if (!(Cons.nth(x, 2) instanceof LispSymbol)) - throw new Error(`Optional parameter svar not a symbol`); + checkLocal(x.car); + checkLocal(Cons.nth(x, 2)); sections.optional.push(Cons.toArray(x)); break; } @@ -960,44 +960,6 @@ const parseLambdaList = list => { } break; case 'key': - if (clSym(x, '&OPTIONAL')) { - throw new Error(`Misplaced &OPTIONAL`); - } else if (clSym(x, '&KEY')) { - throw new Error(`Repeated &KEY`); - } else if (clSym(x, '&REST')) { - state = 'rest'; - } else if (x instanceof LispSymbol) { - sections.key.push([x, UNDEFINED, UNDEFINED]); - } else if (x instanceof Cons) { - if (!Cons.isProperList(x)) - throw new Error(`&OPTIONAL parameter list is improper`); - switch (Cons.length(x)) { - case 0: - throw new Error(`Empty optional parameter`); - case 1: - if (!(x.car instanceof LispSymbol)) - throw new Error(`Optional parameter name not a symbol`); - sections.optional.push([x.car, UNDEFINED, UNDEFINED]); - break; - case 2: - if (!(x.car instanceof LispSymbol)) - throw new Error(`Optional parameter name not a symbol`); - sections.optional.push([x.car, x.cdr.car, UNDEFINED]); - break; - case 3: { - if (!(x.car instanceof LispSymbol)) - throw new Error(`Optional parameter name not a symbol`); - if (!(Cons.nth(x, 2) instanceof LispSymbol)) - throw new Error(`Optional parameter svar not a symbol`); - sections.optional.push(Cons.toArray(x)); - break; - } - default: - throw new Error(`Invalid &OPTIONAL spec`); - } - } else { - throw new Error(`Optional argument not symbol or list`); - } break; case 'aux': break;