Lambda.java 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668
  1. package kawa.lang;
  2. import gnu.mapping.*;
  3. import gnu.expr.*;
  4. import gnu.lists.*;
  5. import gnu.bytecode.Type;
  6. import gnu.kawa.lispexpr.LangObjType;
  7. import gnu.kawa.lispexpr.LispLanguage;
  8. import java.util.ArrayList;
  9. import kawa.standard.object;
  10. /**
  11. * The Syntax transformer that re-writes the lambda builtin.
  12. * @author Per Bothner
  13. */
  14. public class Lambda extends Syntax
  15. {
  16. public Object optionalKeyword;
  17. public Object restKeyword;
  18. public Object keyKeyword;
  19. static BindDecls defaultBindParser = new LambdaBindDecls();
  20. public BindDecls bindParser = defaultBindParser;
  21. static {
  22. defaultBindParser.allowShadowing = true;
  23. defaultBindParser.makeConstant = false;
  24. }
  25. public static final Keyword nameKeyword = Keyword.make("name");
  26. // This should technically have the type of Scheme.booleanType.
  27. public Expression defaultDefault = QuoteExp.falseExp;
  28. public void setKeywords(Object optional, Object rest, Object key)
  29. {
  30. optionalKeyword = optional;
  31. restKeyword = rest;
  32. keyKeyword = key;
  33. }
  34. @Override
  35. public Expression rewrite (Object obj, Translator tr)
  36. {
  37. if (! (obj instanceof Pair))
  38. return tr.syntaxError ("missing formals in lambda");
  39. int old_errors = tr.getMessages().getErrorCount();
  40. LambdaExp lexp = new LambdaExp();
  41. Pair pair = (Pair) obj;
  42. rewrite(lexp, pair.getCar(), pair.getCdr(), tr, null);
  43. if (tr.getMessages().getErrorCount() > old_errors)
  44. return new ErrorExp("bad lambda expression");
  45. return lexp;
  46. }
  47. /**
  48. * Higher-level constructor, that does the re-writing.
  49. * @param formals the formal parameter list (or symbol)
  50. * @param body the body of the procedure
  51. * @param tr the (Scheme) Translator
  52. */
  53. public void rewrite(LambdaExp lexp, Object formals, Object body,
  54. Translator tr, TemplateScope templateScopeRest)
  55. {
  56. lexp.setCallConvention(tr);
  57. rewriteFormals(lexp, formals, tr, templateScopeRest);
  58. if (body instanceof PairWithPosition)
  59. lexp.setFile(((PairWithPosition) body).getFileName());
  60. body = rewriteAttrs(lexp, body, tr);
  61. rewriteBody(lexp, body, tr);
  62. }
  63. public void rewriteFormals(LambdaExp lexp, Object formals,
  64. Translator tr, TemplateScope templateScopeRest)
  65. {
  66. tr.pushScope(lexp);
  67. if (lexp.getSymbol() == null)
  68. {
  69. String filename = lexp.getFileName();
  70. int line = lexp.getLineNumber();
  71. if (filename != null && line > 0)
  72. lexp.setSourceLocation(filename, line);
  73. }
  74. Object bindings = formals;
  75. int opt_args = -1;
  76. int rest_args = -1;
  77. int key_args = -1;
  78. Pair pair;
  79. bindings = formals;
  80. opt_args = -1;
  81. key_args = -1;
  82. ArrayList<Expression> defaultArgs = null;
  83. ArrayList<Keyword> keywords = null;
  84. Object mode = null;
  85. Object next = null;
  86. for (; ; bindings = next)
  87. {
  88. if (bindings instanceof SyntaxForm)
  89. {
  90. SyntaxForm sf = (SyntaxForm) bindings;
  91. bindings = sf.getDatum();
  92. // The SyntaxForm "surrounds" both the current binding (the car),
  93. // as well as the cdr - i.e. the remaining bindings.
  94. templateScopeRest = sf.getScope();
  95. }
  96. if (! (bindings instanceof Pair))
  97. break;
  98. TemplateScope templateScope = templateScopeRest;
  99. pair = (Pair) bindings;
  100. Object pair_car = pair.getCar();
  101. next = pair.getCdr();
  102. if (pair_car instanceof SyntaxForm)
  103. {
  104. SyntaxForm sf = (SyntaxForm) pair_car;
  105. pair_car = sf.getDatum();
  106. templateScope = sf.getScope();
  107. }
  108. Object pccar;
  109. if (pair_car == optionalKeyword)
  110. {
  111. if (opt_args >= 0)
  112. tr.syntaxError ("multiple "+optionalKeyword+" keywords in parameter list");
  113. else if (rest_args >= 0 || key_args >= 0)
  114. tr.syntaxError (optionalKeyword.toString()+" after " + restKeyword + " or " + keyKeyword);
  115. opt_args = 0;
  116. }
  117. else if (pair_car instanceof Pair
  118. && ((pccar = ((Pair) pair_car).getCar()) == LispLanguage.splice_sym
  119. || pccar == LispLanguage.splice_colon_sym))
  120. {
  121. if (rest_args >= 0)
  122. tr.syntaxError ("multiple " + restKeyword
  123. + " keywords in parameter list");
  124. mode = null;
  125. rest_args = 0;
  126. }
  127. else if (pair_car == restKeyword)
  128. {
  129. if (rest_args >= 0)
  130. tr.syntaxError ("multiple " + restKeyword
  131. + " keywords in parameter list");
  132. rest_args = 0;
  133. }
  134. else if (pair_car == keyKeyword)
  135. {
  136. if (key_args >= 0)
  137. tr.syntaxError ("multiple " + keyKeyword
  138. + " keywords in parameter list");
  139. key_args = 0;
  140. }
  141. else if (mode == keyKeyword)
  142. key_args++;
  143. else if (mode == restKeyword) {
  144. if (pair_car != Special.ifk)
  145. rest_args++;
  146. } else if (opt_args >= 0)
  147. opt_args++;
  148. else if (pair_car != Special.ifk) {
  149. lexp.min_args++;
  150. }
  151. if (pair_car == optionalKeyword
  152. || pair_car == restKeyword || pair_car == keyKeyword)
  153. {
  154. mode = pair_car;
  155. continue;
  156. }
  157. Object savePos = tr.pushPositionOf(pair);
  158. Object name = null;
  159. Object defaultValue = defaultDefault;
  160. Pair suppliedPair = null;
  161. Pair typeSpecPair = null;
  162. Pair p;
  163. if (tr.matches(pair_car, "::"))
  164. {
  165. tr.syntaxError("'::' must follow parameter name");
  166. break;
  167. }
  168. pair_car = tr.namespaceResolve(pair_car);
  169. Declaration decl = null;
  170. if (pair_car instanceof Symbol
  171. || pair_car == Special.ifk
  172. || bindParser.literalPattern(pair_car, tr) != null
  173. || (pair_car instanceof Pair
  174. && (mode == null
  175. || (pccar = ((Pair) pair_car).getCar()) == LispLanguage.splice_sym
  176. || pccar == LispLanguage.splice_colon_sym)
  177. && (Translator.listLength(pair_car) != 3
  178. || ! tr.matches(((Pair) ((Pair) pair_car).getCdr()).getCar(), "::"))))
  179. {
  180. Object[] r = parsePatternCar(pair, templateScope, lexp, tr);
  181. next = r[0];
  182. decl = (Declaration) r[1];
  183. if (decl == null)
  184. decl = new Declaration("<error>");
  185. if (decl.getFlag(Declaration.IS_REST_PARAMETER)) {
  186. if (rest_args > 0)
  187. tr.syntaxError("multiple rest arguments in parameter list");
  188. rest_args = 1;
  189. }
  190. name = decl == null ? null : decl.getSymbol();
  191. }
  192. else if (pair_car instanceof Pair)
  193. {
  194. Object[] r = parsePatternCar((Pair) pair_car, templateScope, lexp, tr);
  195. Object xrest = r[0];
  196. if (xrest instanceof Pair && mode != null) {
  197. p = (Pair) xrest;
  198. defaultValue = p.getCar();
  199. xrest = p.getCdr();
  200. }
  201. if (xrest instanceof Pair && mode != null) {
  202. p = (Pair) xrest;
  203. if (p.getCar() instanceof Symbol) {
  204. suppliedPair = p;
  205. }
  206. else
  207. tr.syntaxError("expected a supplied-parameter name");
  208. xrest = p.getCdr();
  209. }
  210. if (xrest != LList.Empty) {
  211. Object savePos1 = tr.pushPositionOf(r[0]);
  212. tr.syntaxError("junk at end of specifier for parameter");
  213. tr.popPositionOf(savePos1);
  214. }
  215. decl = (Declaration) r[1];
  216. if (decl == null)
  217. decl = new Declaration("<error>");
  218. name = decl == null ? null : decl.getSymbol();
  219. next = pair.getCdr();
  220. }
  221. if (decl == null) {
  222. if (name == null) {
  223. tr.syntaxError ("parameter is neither name nor (name :: type) nor (name default)"+": "+pair);
  224. break;
  225. }
  226. decl = new Declaration(name);
  227. }
  228. decl.setFlag(Declaration.IS_PARAMETER);
  229. if (mode == optionalKeyword || mode == keyKeyword)
  230. {
  231. decl.setInitValue(new LangExp(defaultValue));
  232. if (mode == keyKeyword)
  233. {
  234. if (keywords == null)
  235. keywords = new ArrayList<Keyword>();
  236. keywords.add(Keyword.make(name instanceof Symbol ? ((Symbol) name).getName() : name.toString()));
  237. }
  238. }
  239. Translator.setLine(decl, bindings);
  240. if (typeSpecPair != null)
  241. {
  242. decl.setType(new LangExp(typeSpecPair), null);
  243. decl.setFlag(Declaration.TYPE_SPECIFIED);
  244. }
  245. if (mode == restKeyword && pair_car != Special.ifk)
  246. {
  247. decl.setFlag(Declaration.IS_REST_PARAMETER);
  248. if (! decl.getFlag(Declaration.TYPE_SPECIFIED)) {
  249. decl.setType(LangObjType.listType);
  250. if (key_args < 0) {
  251. decl.setFlag(Declaration.KEYWORDS_OK);
  252. lexp.setFlag(LambdaExp.ALLOW_OTHER_KEYWORDS);
  253. }
  254. }
  255. }
  256. decl.setFlag(Declaration.IS_SINGLE_VALUE);
  257. if (suppliedPair != null) {
  258. Declaration suppliedDecl = addParam((Symbol) suppliedPair.getCar(),
  259. templateScope/*FIXME*/,
  260. lexp, tr);
  261. decl.setFlag(Declaration.IS_SUPPLIED_PARAMETER);
  262. suppliedDecl.setFlag(Declaration.IS_SUPPLIED_PARAMETER);
  263. suppliedDecl.setType(Type.booleanType);
  264. Translator.setLine(suppliedDecl, suppliedPair);
  265. }
  266. tr.popPositionOf(savePos);
  267. }
  268. if (bindings instanceof SyntaxForm)
  269. {
  270. SyntaxForm sf = (SyntaxForm) bindings;
  271. bindings = sf.getDatum();
  272. templateScopeRest = sf.getScope();
  273. }
  274. if (bindings instanceof Symbol)
  275. {
  276. if (opt_args >= 0 || key_args >= 0 || rest_args >= 0)
  277. {
  278. tr.syntaxError ("dotted rest-arg after " + optionalKeyword
  279. +", " + restKeyword + ", or " + keyKeyword);
  280. }
  281. else
  282. {
  283. rest_args = 1;
  284. Declaration decl = addParam((Symbol) bindings,
  285. templateScopeRest, lexp, tr);
  286. decl.setType(LangObjType.listType);
  287. decl.setFlag(Declaration.IS_SINGLE_VALUE
  288. |Declaration.IS_PARAMETER
  289. |Declaration.IS_REST_PARAMETER);
  290. // For compatibility
  291. decl.setFlag(Declaration.KEYWORDS_OK);
  292. lexp.setFlag(LambdaExp.ALLOW_OTHER_KEYWORDS);
  293. }
  294. }
  295. else if (bindings != LList.Empty)
  296. {
  297. tr.syntaxError ("misformed formals in lambda");
  298. }
  299. if (rest_args > 1)
  300. {
  301. tr.syntaxError ("multiple " + restKeyword + " parameters");
  302. rest_args = 1;
  303. }
  304. if (opt_args < 0)
  305. opt_args = 0;
  306. if (rest_args < 0)
  307. rest_args = 0;
  308. if (key_args < 0)
  309. key_args = 0;
  310. if (rest_args > 0)
  311. lexp.max_args = -1;
  312. else // Is this useful?
  313. lexp.max_args = lexp.min_args + opt_args;
  314. lexp.opt_args = opt_args;
  315. if (keywords != null)
  316. lexp.keywords = keywords.toArray(new Keyword[keywords.size()]);
  317. }
  318. protected Declaration addParam(Symbol name, TemplateScope templateScope,
  319. LambdaExp lexp, Translator tr) {
  320. return bindParser.define(name, templateScope, lexp, tr);
  321. }
  322. public Object rewriteAttrs(LambdaExp lexp, Object body, Translator tr)
  323. {
  324. String allocationFlagName = null;
  325. long accessFlag = 0;
  326. int allocationFlag = 0;
  327. SyntaxForm syntax0 = null;
  328. for (;;)
  329. {
  330. while (body instanceof SyntaxForm)
  331. {
  332. syntax0 = (SyntaxForm) body;
  333. body = syntax0.getDatum();
  334. }
  335. if (! (body instanceof Pair))
  336. break;
  337. Pair pair1 = (Pair) body;
  338. Object attrName = Translator.stripSyntax(pair1.getCar());
  339. if (tr.matches(attrName, "::"))
  340. attrName = null;
  341. else if (attrName instanceof Pair
  342. && isAnnotationSymbol(((Pair)attrName).getCar()))
  343. {
  344. if (lexp.nameDecl == null)
  345. tr.error('e', "annotation for anonymous function");
  346. else
  347. lexp.nameDecl.addAnnotation(new LangExp(pair1));
  348. body = pair1.getCdr();
  349. continue;
  350. }
  351. else if (! (attrName instanceof Keyword))
  352. break;
  353. SyntaxForm syntax1 = syntax0;
  354. Object pair1_cdr = pair1.getCdr();
  355. while (pair1_cdr instanceof SyntaxForm)
  356. {
  357. syntax1 = (SyntaxForm) pair1_cdr;
  358. pair1_cdr = syntax1.getDatum();
  359. }
  360. if (! (pair1_cdr instanceof Pair))
  361. break;
  362. Pair pair2 = (Pair) pair1_cdr;
  363. Object attrValue;
  364. if (attrName == null)
  365. {
  366. if (lexp.isClassMethod() && "*init*".equals(lexp.getName()))
  367. tr.error('e', "explicit return type for '*init*' method");
  368. else
  369. // Defer rewrite until rewriteBody.
  370. lexp.body = new LangExp(new Object[] { pair2, syntax1 });
  371. }
  372. else if (attrName == kawa.standard.object.accessKeyword)
  373. {
  374. accessFlag = object.addAccessFlags(pair2.getCar(),
  375. accessFlag,
  376. Declaration.METHOD_ACCESS_FLAGS,
  377. "method", tr);
  378. }
  379. else if (attrName == kawa.standard.object.allocationKeyword)
  380. {
  381. Expression attrExpr = tr.rewrite_car(pair2, syntax1);
  382. if (! (attrExpr instanceof QuoteExp)
  383. || ! ((attrValue = ((QuoteExp) attrExpr).getValue()) instanceof SimpleSymbol
  384. /* #ifdef use:java.lang.CharSequence */
  385. || attrValue instanceof CharSequence
  386. /* #else */
  387. // || attrValue instanceof String
  388. // || attrValue instanceof CharSeq
  389. /* #endif */
  390. ))
  391. tr.error('e', "allocation: value not a constant symbol or string");
  392. else if (lexp.nameDecl == null)
  393. tr.error('e', "allocation: not allowed for anonymous function");
  394. else
  395. {
  396. String value = attrValue.toString();
  397. if ("class".equals(value) || "static".equals(value))
  398. allocationFlag = Declaration.STATIC_SPECIFIED;
  399. else if ("instance".equals(value))
  400. allocationFlag = Declaration.NONSTATIC_SPECIFIED;
  401. else
  402. tr.error('e', "unknown allocation specifier");
  403. if (allocationFlagName != null && value != null)
  404. {
  405. tr.error('e', "duplicate allocation specifiers - "
  406. + allocationFlagName + " and "
  407. + value);
  408. }
  409. allocationFlagName = value;
  410. }
  411. }
  412. else if (attrName == kawa.standard.object.throwsKeyword)
  413. {
  414. attrValue = pair2.getCar();
  415. int count = Translator.listLength(attrValue);
  416. if (count < 0)
  417. tr.error('e', "throws: not followed by a list");
  418. else
  419. {
  420. Expression[] exps = new Expression[count];
  421. SyntaxForm syntax2 = syntax1;
  422. for (int i = 0; i < count; i++)
  423. {
  424. while (attrValue instanceof SyntaxForm)
  425. {
  426. syntax2 = (SyntaxForm) attrValue;
  427. attrValue = syntax2.getDatum();
  428. }
  429. Pair pair3 = (Pair) attrValue;
  430. exps[i] = tr.rewrite_car(pair3, syntax2);
  431. // Error-checking is done later.
  432. Translator.setLine(exps[i], pair3);
  433. attrValue = pair3.getCdr();
  434. }
  435. lexp.setExceptions(exps);
  436. }
  437. }
  438. else if (attrName == nameKeyword)
  439. {
  440. Expression attrExpr = tr.rewrite_car(pair2, syntax1);
  441. if (attrExpr instanceof QuoteExp)
  442. lexp.setName(((QuoteExp) attrExpr).getValue().toString());
  443. }
  444. else
  445. {
  446. Expression attrExpr = tr.rewrite_car(pair2, syntax1);
  447. attrName = ((Keyword) attrName).asSymbol();
  448. lexp.setProperty(attrName, attrExpr);
  449. }
  450. body = pair2.getCdr();
  451. }
  452. accessFlag |= allocationFlag;
  453. if (accessFlag != 0)
  454. lexp.nameDecl.setFlag(accessFlag);
  455. if (syntax0 != null)
  456. body = SyntaxForms.fromDatumIfNeeded(body, syntax0);
  457. return body;
  458. }
  459. public Object skipAttrs(LambdaExp lexp, Object body, Translator tr)
  460. {
  461. while (body instanceof Pair)
  462. {
  463. Pair pair = (Pair) body;
  464. if (! (pair.getCdr() instanceof Pair))
  465. break;
  466. Object attrName = pair.getCar();
  467. if (tr.matches(attrName, "::"))
  468. attrName = null;
  469. else if (! (attrName instanceof Keyword))
  470. break;
  471. body = ((Pair) pair.getCdr()).getCdr();
  472. }
  473. return body;
  474. }
  475. public void rewriteBody(LambdaExp lexp, Object body, Translator tr)
  476. {
  477. int numRenamedAlias = 0;
  478. // We view a top-level named function as a method, in the sense that the
  479. // form (this) is allowed, if the supertype is explicitly specified.
  480. if (tr.curMethodLambda == null
  481. && lexp.nameDecl != null
  482. && tr.getModule().getFlag(ModuleExp.SUPERTYPE_SPECIFIED))
  483. tr.curMethodLambda = lexp;
  484. if (lexp.nameDecl != null)
  485. rewriteAnnotations(lexp.nameDecl, tr);
  486. Declaration prev = null;
  487. int key_args = lexp.keywords == null ? 0 : lexp.keywords.length;
  488. int opt_args = lexp.opt_args;
  489. int arg_i = 0;
  490. tr.lexical.pop(lexp);
  491. for (Declaration cur = lexp.firstDecl(); cur != null; cur = cur.nextDecl())
  492. {
  493. if (cur.isAlias())
  494. {
  495. Declaration param = Translator.getOriginalRef(cur).getBinding();
  496. lexp.replaceFollowing(prev, param);
  497. param.context = lexp;
  498. tr.pushRenamedAlias(cur);
  499. numRenamedAlias++;
  500. cur = param;
  501. }
  502. Expression texp = cur.getTypeExpRaw();
  503. if (texp instanceof LangExp)
  504. {
  505. Pair typeSpecPair = (Pair) ((LangExp) texp).getLangValue();
  506. Type t = tr.exp2Type(typeSpecPair, cur, null/*FIXME*/);
  507. if (t != null)
  508. cur.setType(t);
  509. }
  510. prev = cur;
  511. if (cur.getFlag(Declaration.IS_PARAMETER)) {
  512. Expression initValue = cur.getInitValue();
  513. if (initValue != null)
  514. cur.setInitValue(tr.rewrite(initValue));
  515. if (cur.getFlag(Declaration.IS_REST_PARAMETER)
  516. && cur.getFlag(Declaration.TYPE_SPECIFIED)) {
  517. Type rstType = cur.getType();
  518. if (rstType == LangObjType.argListType
  519. || rstType == LangObjType.argVectorType) {
  520. cur.setFlag(Declaration.KEYWORDS_OK);
  521. lexp.setFlag(LambdaExp.ALLOW_OTHER_KEYWORDS);
  522. }
  523. }
  524. arg_i++;
  525. }
  526. tr.lexical.push(cur);
  527. }
  528. if (lexp.isClassMethod()
  529. && ! lexp.nameDecl.getFlag(Declaration.STATIC_SPECIFIED))
  530. {
  531. // We set the type of this in ClassExp.walkChildren.
  532. lexp.add(null, new Declaration(ThisExp.THIS_NAME));
  533. }
  534. LambdaExp saveLambda = tr.curLambda;
  535. tr.curLambda = lexp;
  536. Type rtype = lexp.returnType;
  537. Object[] tform = lexp.body instanceof LangExp
  538. ? (Object[]) ((LangExp) lexp.body).getLangValue()
  539. : null;
  540. lexp.body = auxillaryRewrite(body, tr);
  541. tr.curLambda = saveLambda;
  542. Expression[] exps;
  543. int len;
  544. Object val;
  545. try {
  546. if (tform != null) {
  547. Expression texp = tr.rewrite_car((Pair) tform[0],
  548. (SyntaxForm) tform[1]);
  549. lexp.setCoercedReturnValue(texp, tr.getLanguage());
  550. } else if (lexp.body instanceof BeginExp
  551. && body instanceof Pair
  552. && ((Pair) body).getCar() instanceof Symbol
  553. && (len = (exps = ((BeginExp) lexp.body).getExpressions()).length) > 1
  554. && (exps[0] instanceof ReferenceExp
  555. || ((val = exps[0].valueIfConstant()) instanceof Type
  556. || val instanceof Class))) {
  557. // Handle '<TYPENAME> BODY':
  558. tr.error('w', "deprecated return-type specifier - use '::TYPE'");
  559. Expression rexp = exps[0];
  560. len--;
  561. if (len == 1)
  562. lexp.body = exps[1];
  563. else {
  564. Expression[] new_body = new Expression[len];
  565. System.arraycopy(exps, 1, new_body, 0, len);
  566. lexp.body = BeginExp.canonicalize(new_body);
  567. }
  568. lexp.setCoercedReturnValue(rexp, tr.getLanguage());
  569. } else
  570. lexp.setCoercedReturnType(rtype);
  571. } finally {
  572. tr.pop(lexp);
  573. lexp.countDecls();
  574. tr.popRenamedAlias(numRenamedAlias);
  575. lexp.countDecls();
  576. }
  577. if (tr.curMethodLambda == lexp)
  578. tr.curMethodLambda = null;
  579. }
  580. public Expression auxillaryRewrite(Object body, Translator tr)
  581. {
  582. return tr.rewrite_body(body);
  583. }
  584. @Override
  585. public void print (Consumer out)
  586. {
  587. out.write("#<builtin lambda>");
  588. }
  589. public static boolean isAnnotationSymbol (Object key)
  590. {
  591. if (key instanceof Pair)
  592. {
  593. Pair keyp = (Pair) key;
  594. if (keyp.getCar() == LispLanguage.splice_sym)
  595. return true;
  596. }
  597. if (key instanceof SimpleSymbol) // Deprecated: Symbol starting with '@'
  598. {
  599. String name = ((SimpleSymbol) key).getName();
  600. if (name.length() > 1 && name.charAt(0) == '@')
  601. return true;
  602. }
  603. return false;
  604. }
  605. public static void rewriteAnnotations (Declaration decl, Translator tr)
  606. {
  607. int n = decl.numAnnotations();
  608. for (int i = 0; i < n; i++)
  609. {
  610. Expression ann = decl.getAnnotation(i);
  611. if (ann instanceof LangExp)
  612. {
  613. ann = tr.rewrite_car((Pair) ((LangExp) ann).getLangValue(), false);
  614. decl.setAnnotation(i, ann);
  615. }
  616. }
  617. }
  618. public Object[] parsePatternCar(Pair patList, TemplateScope templateScope,
  619. LambdaExp lexp, Translator comp) {
  620. return bindParser.parsePatternCar(patList, null, templateScope, 0,
  621. lexp, comp);
  622. }
  623. static class LambdaBindDecls extends BindDecls {
  624. @Override
  625. public Declaration define(Symbol name,
  626. TemplateScope templateScope,
  627. ScopeExp lexp, Translator tr) {
  628. Declaration decl0 = new Declaration(name);
  629. Declaration decl = decl0;
  630. if (templateScope != null)
  631. decl = tr.makeRenamedAlias(decl, templateScope);
  632. lexp.addDeclaration(decl);
  633. if (templateScope != null)
  634. decl.context = templateScope;
  635. Declaration old = tr.lexical.lookup(name, -1);
  636. if (old != null && old.context == decl.context)
  637. ScopeExp.duplicateDeclarationError((Declaration) old,
  638. decl, tr);
  639. tr.push(decl);
  640. return decl0;
  641. }
  642. }
  643. }