PageRenderTime 31ms CodeModel.GetById 12ms RepoModel.GetById 0ms app.codeStats 0ms

/streme/src/streme/lang/eval/MacroExpander.java

https://code.google.com/
Java | 892 lines | 847 code | 44 blank | 1 comment | 139 complexity | 9aaf0aeea85bc67bc7f81ef5677842a5 MD5 | raw file
  1. package streme.lang.eval;
  2. import java.util.ArrayList;
  3. import java.util.Arrays;
  4. import java.util.HashMap;
  5. import java.util.LinkedHashSet;
  6. import java.util.List;
  7. import java.util.Map;
  8. import java.util.Set;
  9. import streme.lang.StremeException;
  10. import streme.lang.ast.AstDataCompiler;
  11. import streme.lang.ast.analysis.RenamingStrategy;
  12. import streme.lang.ast.impl.StremeDataCompiler;
  13. import streme.lang.data.DataRewriter;
  14. import streme.lang.data.DataUnifier;
  15. import streme.lang.data.Lst;
  16. import streme.lang.data.Null;
  17. import streme.lang.data.Pair;
  18. import streme.lang.data.Parser2;
  19. import streme.lang.data.Sym;
  20. public class MacroExpander implements DataRewriter
  21. {
  22. private static final Object UNDEFINED = null;
  23. private static final RenamingStrategy renamer = RenamingStrategy.NUMBER_RENAMING_STRATEGY;
  24. private boolean rewriteLet;
  25. private boolean rewriteLetrec;
  26. private Set<Pattern> patterns;
  27. private Lst macros;
  28. private DataUnifier unifier;
  29. private DataEvaluator dataEvaluator;
  30. public MacroExpander()
  31. {
  32. this(null);
  33. }
  34. public MacroExpander(DataEvaluator dataEvaluator)
  35. {
  36. super();
  37. rewriteLet = true;
  38. rewriteLetrec = true;
  39. patterns = new LinkedHashSet<Pattern>();
  40. macros = new Null();
  41. unifier = new DataUnifier();
  42. this.dataEvaluator = dataEvaluator;
  43. }
  44. public void setLetToLambda(boolean rewriteLet)
  45. {
  46. this.rewriteLet = rewriteLet;
  47. }
  48. public void setLetrecToLambda(boolean rewriteLetrec)
  49. {
  50. this.rewriteLetrec = rewriteLetrec;
  51. }
  52. public Object rewrite(Object data)
  53. {
  54. if (data instanceof Pair)
  55. {
  56. Pair p = (Pair) data;
  57. Object car = p.car();
  58. if (car instanceof Sym)
  59. {
  60. Sym sym = (Sym) car;
  61. String name = sym.getName();
  62. if ("quote".equals(name))
  63. {
  64. return data;
  65. }
  66. if ("define".equals(name))
  67. {
  68. return rewriteDefine((Pair) p.cdr());
  69. }
  70. if ("lambda".equals(name))
  71. {
  72. return rewriteLambda((Pair) p.cdr());
  73. }
  74. if ("let".equals(name))
  75. {
  76. return rewriteLet((Pair) p.cdr());
  77. }
  78. if ("let||".equals(name))
  79. {
  80. return rewriteLetPar((Pair) p.cdr());
  81. }
  82. if ("let*".equals(name))
  83. {
  84. return rewriteLetStar((Pair) p.cdr());
  85. }
  86. if ("letrec".equals(name))
  87. {
  88. return rewriteLetrec((Pair) p.cdr());
  89. }
  90. if ("begin".equals(name))
  91. {
  92. return rewriteBegin((Lst) p.cdr());
  93. }
  94. if ("and".equals(name))
  95. {
  96. return rewriteAnd((Lst) p.cdr());
  97. }
  98. if ("or".equals(name))
  99. {
  100. return rewriteOr((Lst) p.cdr());
  101. }
  102. if ("cond".equals(name))
  103. {
  104. return rewriteCond((Lst) p.cdr());
  105. }
  106. if ("case".equals(name))
  107. {
  108. return rewriteCase((Pair) p.cdr());
  109. }
  110. if ("do".equals(name))
  111. {
  112. return rewriteDo((Pair) p.cdr());
  113. }
  114. if ("future".equals(name))
  115. {
  116. return rewriteFuture((Pair) p.cdr());
  117. }
  118. if ("quasiquote".equals(name))
  119. {
  120. return rewriteQuasiQuote((Pair) p.cdr());
  121. }
  122. if ("define-pattern".equals(name))
  123. {
  124. return rewriteDefinePattern((Pair) p.cdr());
  125. }
  126. if ("define-macro".equals(name))
  127. {
  128. return rewriteDefineMacro((Pair) p.cdr());
  129. }
  130. }
  131. for (Pattern pattern : patterns)
  132. {
  133. Map<Sym, Object> subs = unifier.unify(data, pattern.getPattern());
  134. if (subs != null)
  135. {
  136. Object rewritten = unifier.apply(subs, pattern.getRewrite(), true);
  137. return rewrite(rewritten);
  138. }
  139. }
  140. if (car instanceof Sym)
  141. {
  142. for (Object macroObj : macros)
  143. {
  144. Macro macro = (Macro) macroObj;
  145. if (car.equals(macro.getName()))
  146. {
  147. int args = (int) ((Lst) p.cdr()).length();
  148. if (macro.getArgs().length == args || (macro.getArgs().length < args && macro.getVararg() != null))
  149. {
  150. Map<Sym, Object> subs = new HashMap<Sym, Object>();
  151. Lst l = (Lst) p.cdr();
  152. for (int i = 0; i < macro.getArgs().length; i++)
  153. {
  154. subs.put(macro.getArgs()[i], l.car());
  155. l = (Lst) l.cdr();
  156. }
  157. if (macro.getVararg() != null)
  158. {
  159. subs.put(macro.getVararg(), l);
  160. }
  161. Object unified = unifier.apply(subs, macro.getRewrite(), true);
  162. Object evaluated = dataEvaluator.evaluateData(unified, dataEvaluator.globalEnv());
  163. return rewrite(evaluated);
  164. }
  165. }
  166. }
  167. String sym = car.toString();
  168. int slashIndex = sym.indexOf("/");
  169. if (slashIndex > 0)
  170. {
  171. Lst args = (Lst) p.cdr();
  172. String className = sym.substring(0, slashIndex);
  173. String[] members = sym.substring(slashIndex + 1).split("\\.");
  174. {
  175. Lst l = Lst
  176. .valueOf(new Sym("invoke-static"), Lst.valueOf(new Sym("class-for-name"), className), members[0]);
  177. for (int i = 1; i < members.length; i++)
  178. {
  179. l = Lst.valueOf(new Sym("invoke"), l, members[i]);
  180. }
  181. return rewrite(l.append(args));
  182. }
  183. }
  184. int dotIndex = sym.indexOf(".");
  185. if (dotIndex == 0)
  186. {
  187. Lst args = (Lst) p.cddr();
  188. return rewrite(Pair.cons(new Sym("invoke"), Pair.cons(p.cadr(), (Pair.cons(sym.substring(1), args)))));
  189. }
  190. if (sym.endsWith("."))
  191. {
  192. Lst args = (Lst) p.cdr();
  193. return rewrite(Pair.cons(new Sym("new"),
  194. Pair.cons(Lst.valueOf(new Sym("class-for-name"), sym.substring(0, sym.length() - 1)), args)));
  195. }
  196. }
  197. Pair array = p.toArray();
  198. Object[] a = (Object[]) array.cdr();
  199. for (int i = 0; i < a.length; i++)
  200. {
  201. a[i] = rewrite(a[i]);
  202. }
  203. if ((Boolean) array.car())
  204. {
  205. return Lst.valueOf(a);
  206. }
  207. else
  208. {
  209. return Lst.valueOfImproper(a);
  210. }
  211. }
  212. // only match with meta-vars in patterns, but not from source
  213. boolean isMetaVar = data instanceof Sym && ((Sym) data).getName().startsWith("?");
  214. if (data != null && !isMetaVar)
  215. {
  216. for (Pattern pattern : patterns)
  217. {
  218. Map<Sym, Object> subs = unifier.unify(data, pattern.getPattern());
  219. if (subs != null)
  220. {
  221. Object rewritten = unifier.apply(subs, pattern.getRewrite(), true);
  222. return rewrite(rewritten);
  223. }
  224. }
  225. }
  226. if (data instanceof Sym)
  227. {
  228. String sym = data.toString();
  229. int slashIndex = sym.indexOf('/');
  230. if (slashIndex > 0)
  231. {
  232. String className = sym.substring(0, slashIndex);
  233. String[] members = sym.substring(slashIndex + 1).split("\\.");
  234. {
  235. Lst l = Lst.valueOf(new Sym("invoke-static"), Lst.valueOf(new Sym("class-for-name"), className), members[0]);
  236. for (int i = 1; i < members.length; i++)
  237. {
  238. l = Lst.valueOf(new Sym("invoke"), l, members[i]);
  239. }
  240. return rewrite(l);
  241. }
  242. }
  243. }
  244. return data;
  245. }
  246. private Object rewriteFuture(Pair future)
  247. {
  248. return Pair.cons(new Sym("future"), Pair.cons(rewrite(future.car()), new Null()));
  249. }
  250. private Object rewriteLambda(Pair lambda)
  251. {
  252. return Pair.cons(new Sym("lambda"), Pair.cons(lambda.car(), rewriteBody((Lst) lambda.cdr())));
  253. }
  254. private Object rewriteDefine(Pair define)
  255. {
  256. Object idObj = define.car();
  257. Pair value = (Pair) define.cdr();
  258. if (idObj instanceof Pair)
  259. {
  260. Pair idPair = (Pair) idObj;
  261. Sym id = (Sym) idPair.car();
  262. Object args = idPair.cdr();
  263. return Lst.valueOf(new Sym("define"), id, rewrite(Pair.cons(new Sym("lambda"), Pair.cons(args, value))));
  264. }
  265. else
  266. {
  267. Object rewrittenValue = rewrite(value);
  268. return Pair.cons(new Sym("define"), Pair.cons(idObj, rewrittenValue));
  269. }
  270. }
  271. private Object rewriteCond(Lst clauses)
  272. {
  273. if (clauses.isNull())
  274. {
  275. return UNDEFINED;
  276. }
  277. Lst clause = (Lst) clauses.car();
  278. Object test = clause.car();
  279. if (clause.cdr() instanceof Null)
  280. {
  281. return rewrite(test);
  282. }
  283. if ("else".equals(Sym.getName(test)))
  284. {
  285. if (clause.cddr() instanceof Null)
  286. {
  287. return rewrite(clause.cadr());
  288. }
  289. else
  290. {
  291. return rewrite(Pair.cons(new Sym("begin"), clause.cdr()));
  292. }
  293. }
  294. else
  295. {
  296. if (clause.cddr() instanceof Null)
  297. {
  298. return rewrite(Lst.valueOf(new Sym("if"), test, clause.cadr(), Pair.cons(new Sym("cond"), clauses.cdr())));
  299. }
  300. else
  301. {
  302. return rewrite(Lst.valueOf(new Sym("if"), test, Pair.cons(new Sym("begin"), clause.cdr()), Pair.cons(new Sym("cond"), clauses.cdr())));
  303. }
  304. }
  305. }
  306. private Object rewriteCase(Pair pair)
  307. {
  308. Object value = pair.car();
  309. Lst clauses = (Lst) pair.cdr();
  310. List<Object> rewrittenClauses = new ArrayList<Object>();
  311. Sym temp = renamer.rename(new Sym("t"));
  312. for (Object clause : clauses)
  313. {
  314. Pair c = (Pair) clause;
  315. if ("else".equals(Sym.getName(c.car())))
  316. {
  317. rewrittenClauses.add(c);
  318. }
  319. else
  320. {
  321. rewrittenClauses.add(Pair.cons(Lst.valueOf(new Sym("memv"), temp, Lst.valueOf(new Sym("quote"), c.car())), c.cdr()));
  322. }
  323. }
  324. return rewrite(Lst.valueOf(new Sym("let"), Lst.valueOf(Lst.valueOf(temp, value)),
  325. Pair.cons(new Sym("cond"), Lst.valueOf(rewrittenClauses))));
  326. }
  327. private Object rewriteDo(Pair pair)
  328. {
  329. Lst varInitSteps = (Lst) pair.car();
  330. List<Object> vars = new ArrayList<Object>();
  331. List<Object> inits = new ArrayList<Object>();
  332. List<Object> steps = new ArrayList<Object>();
  333. for (Object varInitStepObj : varInitSteps)
  334. {
  335. Pair varInitStep = (Pair) varInitStepObj;
  336. vars.add(varInitStep.car());
  337. inits.add(varInitStep.cadr());
  338. if (varInitStep.cddr() instanceof Null)
  339. {
  340. steps.add(varInitStep.car());
  341. }
  342. else
  343. {
  344. steps.add(varInitStep.caddr());
  345. }
  346. }
  347. Lst testExps = (Lst) pair.cadr();
  348. Object test = testExps.car();
  349. Lst exps = (Lst) testExps.cdr();
  350. Object consequent = (exps.isNull() ? null : exps.cdr() instanceof Null ? exps.car() : Pair.cons(new Sym("begin"), exps));
  351. Sym loopName = renamer.rename(new Sym("loop"));
  352. Object loop = Pair.cons(loopName, Lst.valueOf(steps));
  353. Lst body = (Lst) pair.cddr();
  354. Object alternate;
  355. if (body.isNull())
  356. {
  357. alternate = loop;
  358. }
  359. else
  360. {
  361. alternate = Pair.cons(new Sym("begin"), body.append(Pair.cons(loop, new Null())));
  362. }
  363. Lst letrec = Lst.valueOf(
  364. new Sym("letrec"),
  365. Lst.valueOf(Lst.valueOf(loopName,
  366. Lst.valueOf(new Sym("lambda"), Lst.valueOf(vars), Lst.valueOf(new Sym("if"), test, consequent, alternate)))),
  367. Pair.cons(loopName, Lst.valueOf(inits)));
  368. return rewrite(letrec);
  369. }
  370. private Object rewriteAnd(Lst lst)
  371. {
  372. if (lst.isNull())
  373. {
  374. return new Boolean(true);
  375. }
  376. Lst rest = (Lst) lst.cdr();
  377. if (rest.isNull())
  378. {
  379. return rewrite(lst.car());
  380. }
  381. return rewrite(Lst.valueOf(new Sym("if"), lst.car(), Pair.cons(new Sym("and"), lst.cdr()), new Boolean(false)));
  382. }
  383. private Object rewriteOr(Lst lst)
  384. {
  385. if (lst.isNull())
  386. {
  387. return new Boolean(false);
  388. }
  389. Lst rest = (Lst) lst.cdr();
  390. if (rest.isNull())
  391. {
  392. return rewrite(lst.car());
  393. }
  394. Sym temp = renamer.rename(new Sym("t"));
  395. return rewrite(Lst.valueOf(new Sym("let"), Lst.valueOf(Lst.valueOf(temp, lst.car())),
  396. Lst.valueOf(new Sym("if"), temp, temp, Pair.cons(new Sym("or"), lst.cdr()))));
  397. }
  398. private Object rewriteLetStar(Pair pair)
  399. {
  400. Lst bindings = (Lst) pair.car();
  401. Pair body = (Pair) pair.cdr();
  402. if (bindings.isNull())
  403. {
  404. return rewrite(Pair.cons(new Sym("let"), Pair.cons(new Null(), body)));
  405. }
  406. Object firstBinding = bindings.car();
  407. Object restBindings = bindings.cdr();
  408. if (restBindings instanceof Null)
  409. {
  410. return rewrite(Pair.cons(new Sym("let"), Pair.cons(bindings, body)));
  411. }
  412. else
  413. {
  414. return rewrite(Pair.cons(new Sym("let"),
  415. Lst.valueOf(Pair.cons(firstBinding, new Null()), Pair.cons(new Sym("let*"), Pair.cons(restBindings, body)))));
  416. }
  417. }
  418. private Object rewriteLet(Pair pair)
  419. {
  420. if (pair.car() instanceof Sym)
  421. {
  422. Sym name = (Sym) pair.car();
  423. Lst bindings = (Lst) pair.cadr();
  424. Lst body = (Lst) pair.cddr();
  425. if (body.isNull())
  426. {
  427. throw new StremeException("no body for named let " + pair);
  428. }
  429. List<Object> params = new ArrayList<Object>();
  430. List<Object> operands = new ArrayList<Object>();
  431. for (Object bindingObj : bindings)
  432. {
  433. Pair binding = (Pair) bindingObj;
  434. params.add(binding.car());
  435. operands.add(binding.cadr());
  436. }
  437. Lst r = Lst.valueOf(new Sym("letrec"),
  438. Lst.valueOf(Lst.valueOf(name, Pair.cons(new Sym("lambda"), Pair.cons(Lst.valueOf(params), body)))),
  439. Pair.cons(name, Lst.valueOf(operands)));
  440. return rewrite(r);
  441. }
  442. else
  443. {
  444. Lst bindings = (Lst) pair.car();
  445. if (pair.cdr() instanceof Null)
  446. {
  447. throw new StremeException("no body for let with bindings " + bindings);
  448. }
  449. Pair body = (Pair) pair.cdr();
  450. if (rewriteLet)
  451. {
  452. List<Object> params = new ArrayList<Object>();
  453. List<Object> operands = new ArrayList<Object>();
  454. for (Object bindingObj : bindings)
  455. {
  456. Pair binding = (Pair) bindingObj;
  457. params.add(binding.car());
  458. operands.add(binding.cadr());
  459. }
  460. return rewrite(Pair.cons(Pair.cons(new Sym("lambda"), Pair.cons(Lst.valueOf(params), body)), Lst.valueOf(operands)));
  461. }
  462. List<Object> rbindings = new ArrayList<Object>();
  463. for (Object bindingObj : bindings)
  464. {
  465. Pair binding = (Pair) bindingObj;
  466. rbindings.add(Pair.cons(binding.car(), Pair.cons(rewrite(binding.cadr()), new Null())));
  467. }
  468. return Pair.cons(new Sym("let"), Pair.cons(Lst.valueOf(rbindings), rewrite(body)));
  469. }
  470. }
  471. private Object rewriteLetPar(Pair pair)
  472. {
  473. Lst bindings = (Lst) pair.car();
  474. Pair body = (Pair) pair.cdr();
  475. List<Object> parbindings = new ArrayList<Object>();
  476. List<Object> touches = new ArrayList<Object>();
  477. for (Object bindingObj : bindings)
  478. {
  479. Pair binding = (Pair) bindingObj;
  480. parbindings.add(Lst.valueOf(binding.car(), Pair.cons(new Sym("future"), binding.cdr())));
  481. touches.add(Lst.valueOf(new Sym("set!"), binding.car(), Pair.cons(new Sym("touch"), Pair.cons(binding.car(), new Null()))));
  482. }
  483. return rewrite(Lst.valueOf(new Sym("let"), Lst.valueOf(parbindings)).append(Lst.valueOf(touches)).append(body));
  484. }
  485. private Object rewriteLetrec(Pair pair)
  486. {
  487. Lst bindings = (Lst) pair.car();
  488. Pair body = (Pair) pair.cdr();
  489. if (rewriteLetrec)
  490. {
  491. List<Object> nullBindings = new ArrayList<Object>();
  492. List<Object> setters = new ArrayList<Object>();
  493. for (Object bindingObj : bindings)
  494. {
  495. Pair binding = (Pair) bindingObj;
  496. nullBindings.add(Pair.cons(binding.car(), Pair.cons(null, new Null())));
  497. setters.add(Pair.cons(new Sym("set!"), Pair.cons(binding.car(), binding.cdr())));
  498. }
  499. Pair cons = Pair.cons(new Sym("let"), Pair.cons(Lst.valueOf(nullBindings), Lst.valueOf(setters).append(body)));
  500. return rewrite(cons);
  501. }
  502. List<Object> rbindings = new ArrayList<Object>();
  503. for (Object bindingObj : bindings)
  504. {
  505. Pair binding = (Pair) bindingObj;
  506. rbindings.add(Pair.cons(binding.car(), Pair.cons(rewrite(binding.cadr()), new Null())));
  507. }
  508. return Pair.cons(new Sym("letrec"), Pair.cons(Lst.valueOf(rbindings), rewrite(body)));
  509. }
  510. private Object rewriteBegin(Lst body)
  511. {
  512. List<Object> rewritten = new ArrayList<Object>();
  513. for (Object op : body)
  514. {
  515. rewritten.add(rewrite(op));
  516. }
  517. return Pair.cons(new Sym("begin"), Lst.valueOf(rewritten));
  518. }
  519. private Object rewriteQuasiQuote(Lst body)
  520. {
  521. return rewriteQuasiQuoteElement(body.car());
  522. }
  523. private Object rewriteQuasiQuoteElement(Object object)
  524. {
  525. if (object instanceof Pair)
  526. {
  527. Pair p = (Pair) object;
  528. if ("unquote".equals(Sym.getName(p.car())))
  529. {
  530. return rewrite(p.cadr());
  531. }
  532. else
  533. {
  534. return rewriteQuasiQuoteList(p);
  535. }
  536. }
  537. else if (object instanceof Null)
  538. {
  539. return new Null();
  540. }
  541. else
  542. {
  543. return Pair.cons(new Sym("quote"), Pair.cons(object, new Null()));
  544. }
  545. }
  546. private Lst rewriteQuasiQuoteList(Pair p)
  547. {
  548. List<Object> els = new ArrayList<Object>();
  549. while (true)
  550. {
  551. Object car = p.car();
  552. if (car instanceof Pair && "unquote-splicing".equals(Sym.getName(((Pair) car).car())))
  553. {
  554. Pair<Sym, Lst> l1 = Pair.cons(new Sym("list"), Lst.valueOf(els));
  555. Object l2 = ((Pair) car).cadr();
  556. Object l3 = p.cdr() instanceof Null ? new Null() : Pair.cons(new Sym("list"),
  557. Pair.cons(rewrite(Pair.cons(new Sym("quasiquote"), p.cdr())), new Null()));
  558. return Lst.valueOf(new Sym("append"), l1, l2, l3);
  559. }
  560. else
  561. {
  562. Object rewritten = rewriteQuasiQuoteElement(car);
  563. els.add(rewritten);
  564. }
  565. Object cdr = p.cdr();
  566. if (cdr instanceof Pair)
  567. {
  568. p = (Pair) cdr;
  569. continue;
  570. }
  571. if (cdr instanceof Null)
  572. {
  573. return Pair.cons(new Sym("list"), Lst.valueOf(els));
  574. }
  575. els.add(rewriteQuasiQuoteElement(cdr));
  576. return Pair.cons(new Sym("improper-list"), Lst.valueOf(els));
  577. }
  578. }
  579. private Lst rewriteBody(Lst body)
  580. {
  581. List<Object> internalDefineLambdaBindings = new ArrayList<Object>();
  582. List<Object> internalDefineValuesBindings = new ArrayList<Object>();
  583. List<Object> operations = new ArrayList<Object>();
  584. for (Object operand : body)
  585. {
  586. if (operand instanceof Pair && "define".equals(Sym.getName(((Pair) operand).car())))
  587. {
  588. Pair pair = (Pair) ((Pair) operand).cdr();
  589. Object idObj = pair.car();
  590. Lst definedValuePair = (Lst) pair.cdr();
  591. if (idObj instanceof Sym)
  592. {
  593. Object definedValueCar = definedValuePair.car();
  594. if (definedValueCar instanceof Pair && "lambda".equals(Sym.getName(((Pair) definedValueCar).car())))
  595. {
  596. internalDefineLambdaBindings.add(Pair.cons(idObj, definedValuePair));
  597. }
  598. else
  599. {
  600. internalDefineValuesBindings.add(Pair.cons(idObj, definedValuePair));
  601. }
  602. }
  603. else if (idObj instanceof Pair)
  604. {
  605. Pair idPair = (Pair) idObj;
  606. Sym id = (Sym) idPair.car();
  607. Object args = idPair.cdr();
  608. Pair defBody = (Pair) definedValuePair;
  609. internalDefineLambdaBindings.add(Pair.cons(id,
  610. Pair.cons(Pair.cons(new Sym("lambda"), Pair.cons(args, defBody)), new Null())));
  611. }
  612. else
  613. {
  614. throw new StremeException("define: illegal syntax");
  615. }
  616. }
  617. else
  618. {
  619. operations.add(operand);
  620. }
  621. }
  622. if (operations.isEmpty())
  623. {
  624. throw new StremeException("body: no expressions in body");
  625. }
  626. List<Object> rewrittenOperations = new ArrayList<Object>();
  627. for (int i = 0; i < operations.size(); i++)
  628. {
  629. Object operation = operations.get(i);
  630. rewrittenOperations.add(rewrite(operation));
  631. }
  632. if (internalDefineLambdaBindings.isEmpty())
  633. {
  634. if (internalDefineValuesBindings.isEmpty())
  635. {
  636. return Lst.valueOf(rewrittenOperations);
  637. }
  638. else
  639. {
  640. return Lst.valueOf(rewrite(Pair.cons(new Sym("let*"),
  641. Pair.cons(Lst.valueOf(internalDefineValuesBindings), Lst.valueOf(rewrittenOperations)))));
  642. }
  643. }
  644. else
  645. {
  646. if (internalDefineValuesBindings.isEmpty())
  647. {
  648. return Lst.valueOf(rewrite(Pair.cons(new Sym("letrec"),
  649. Pair.cons(Lst.valueOf(internalDefineLambdaBindings), Lst.valueOf(rewrittenOperations)))));
  650. }
  651. else
  652. {
  653. return Lst.valueOf(rewrite(Pair.cons(
  654. new Sym("let*"),
  655. Pair.cons(
  656. Lst.valueOf(internalDefineValuesBindings),
  657. Lst.valueOf(rewrite(Pair.cons(new Sym("letrec"),
  658. Pair.cons(Lst.valueOf(internalDefineLambdaBindings), Lst.valueOf(rewrittenOperations)))))))));
  659. }
  660. }
  661. }
  662. private static class Pattern
  663. {
  664. private Object pattern;
  665. private Object rewrite;
  666. public Pattern(Object pattern, Object rewrite)
  667. {
  668. super();
  669. this.pattern = pattern;
  670. this.rewrite = rewrite;
  671. }
  672. public int hashCode()
  673. {
  674. final int prime = 31;
  675. int result = 1;
  676. result = prime * result + ((pattern == null) ? 0 : pattern.hashCode());
  677. return result;
  678. }
  679. public boolean equals(Object obj)
  680. {
  681. if (this == obj)
  682. return true;
  683. if (obj == null)
  684. return false;
  685. if (getClass() != obj.getClass())
  686. return false;
  687. final Pattern other = (Pattern) obj;
  688. if (pattern == null)
  689. {
  690. if (other.pattern != null)
  691. return false;
  692. }
  693. else if (!pattern.equals(other.pattern))
  694. return false;
  695. return true;
  696. }
  697. public Object getPattern()
  698. {
  699. return pattern;
  700. }
  701. public Object getRewrite()
  702. {
  703. return rewrite;
  704. }
  705. public String toString()
  706. {
  707. return "<pattern " + pattern + ">";
  708. }
  709. }
  710. private static class Macro
  711. {
  712. private Sym name;
  713. private Sym[] args;
  714. private Sym vararg;
  715. private Object rewrite;
  716. public Macro(Sym name, Sym[] args, Sym vararg, Object rewrite)
  717. {
  718. super();
  719. this.name = name;
  720. this.args = args;
  721. this.vararg = vararg;
  722. this.rewrite = rewrite;
  723. }
  724. public int hashCode()
  725. {
  726. final int prime = 31;
  727. int result = 1;
  728. result = prime * result + Arrays.hashCode(args);
  729. result = prime * result + ((name == null) ? 0 : name.hashCode());
  730. result = prime * result + ((vararg == null) ? 0 : vararg.hashCode());
  731. return result;
  732. }
  733. public boolean equals(Object obj)
  734. {
  735. if (this == obj)
  736. return true;
  737. if (obj == null)
  738. return false;
  739. if (getClass() != obj.getClass())
  740. return false;
  741. final Macro other = (Macro) obj;
  742. if (!Arrays.equals(args, other.args))
  743. return false;
  744. if (name == null)
  745. {
  746. if (other.name != null)
  747. return false;
  748. }
  749. else if (!name.equals(other.name))
  750. return false;
  751. if (vararg == null)
  752. {
  753. if (other.vararg != null)
  754. return false;
  755. }
  756. else if (!vararg.equals(other.vararg))
  757. return false;
  758. return true;
  759. }
  760. public Sym getName()
  761. {
  762. return name;
  763. }
  764. public Sym[] getArgs()
  765. {
  766. return args;
  767. }
  768. public Sym getVararg()
  769. {
  770. return vararg;
  771. }
  772. public Object getRewrite()
  773. {
  774. return rewrite;
  775. }
  776. public String toString()
  777. {
  778. return "<macro " + name + ">";
  779. }
  780. }
  781. private Object rewriteDefinePattern(Pair pair)
  782. {
  783. Object pattern = pair.car();
  784. Lst rewrite = (Lst) pair.cdr();
  785. Object actualRewrite;
  786. if (rewrite.length() > 1)
  787. {
  788. actualRewrite = Pair.cons(new Sym("begin"), rewrite);
  789. }
  790. else
  791. {
  792. actualRewrite = rewrite.car();
  793. }
  794. Pattern p = new Pattern(pattern, actualRewrite);
  795. patterns.add(p);
  796. return p;
  797. }
  798. private Object rewriteDefineMacro(Pair pair)
  799. {
  800. Lst rewrite = (Lst) pair.cdr();
  801. Object actualRewrite;
  802. if (rewrite.length() > 1)
  803. {
  804. actualRewrite = Pair.cons(new Sym("begin"), rewrite);
  805. }
  806. else
  807. {
  808. actualRewrite = rewrite.car();
  809. }
  810. Lst sig = (Lst) pair.car();
  811. Sym name = (Sym) sig.car();
  812. Object ps = sig.cdr();
  813. Macro macro;
  814. if (ps instanceof Lst)
  815. {
  816. Pair<Boolean, Sym[]> params = ((Lst) ps).toArray(Sym.class);
  817. if (params.car())
  818. {
  819. macro = new Macro(name, params.cdr(), null, actualRewrite);
  820. }
  821. else
  822. {
  823. Sym varparam = params.cdr()[params.cdr().length - 1];
  824. macro = new Macro(name, Arrays.copyOfRange(params.cdr(), 0, params.cdr().length - 1), varparam, actualRewrite);
  825. }
  826. }
  827. else
  828. {
  829. Sym varparam = (Sym) ps;
  830. macro = new Macro(name, new Sym[0], varparam, actualRewrite);
  831. }
  832. macros = Pair.cons(macro, macros);
  833. return macro;
  834. }
  835. public static void main(String[] args)
  836. {
  837. Parser2 parser = new Parser2();
  838. MacroExpander macroExpander = new MacroExpander();
  839. macroExpander.setLetToLambda(false);
  840. macroExpander.setLetrecToLambda(false);
  841. Object source = parser.parse("((lambda () (begin 42 (define x 1)) x))");
  842. System.out.println(source);
  843. Object expanded = macroExpander.rewrite(source);
  844. System.out.println(expanded);
  845. AstDataCompiler compiler = new StremeDataCompiler();
  846. System.out.println(compiler.compile(source));
  847. }
  848. }