let_syntax.java 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. package kawa.standard;
  2. import kawa.lang.*;
  3. import gnu.lists.*;
  4. import gnu.mapping.*;
  5. import gnu.expr.*;
  6. import java.util.Stack;
  7. /** Implementation of the standard Scheme let-syntax and letrec-syntax forms.
  8. * Not quite working yet. */
  9. public class let_syntax extends Syntax
  10. {
  11. public static final let_syntax let_syntax
  12. = new let_syntax(false, "let-syntax");
  13. public static final let_syntax letrec_syntax
  14. = new let_syntax(true, "letrec-syntax");
  15. boolean recursive;
  16. public let_syntax(boolean recursive, String name)
  17. {
  18. super(name);
  19. this.recursive = recursive;
  20. }
  21. public Expression rewrite (Object obj, Translator tr)
  22. {
  23. if (! (obj instanceof Pair))
  24. return tr.syntaxError ("missing let-syntax arguments");
  25. Pair pair = (Pair) obj;
  26. Object bindings = pair.getCar();
  27. Object body = pair.getCdr();
  28. int decl_count = Translator.listLength(bindings);
  29. if (decl_count < 0)
  30. return tr.syntaxError("bindings not a proper list");
  31. Stack renamedAliases = null;
  32. int renamedAliasesCount = 0;
  33. Declaration[] decls = new Declaration[decl_count];
  34. Macro[] macros = new Macro[decl_count];
  35. Pair[] transformers = new Pair[decl_count];
  36. SyntaxForm[] trSyntax = new SyntaxForm[decl_count];
  37. LetExp let = new LetExp();
  38. SyntaxForm listSyntax = null;
  39. for (int i = 0; i < decl_count; i++)
  40. {
  41. while (bindings instanceof SyntaxForm)
  42. {
  43. listSyntax = (SyntaxForm) bindings;
  44. bindings = listSyntax.getDatum();
  45. }
  46. SyntaxForm bindingSyntax = listSyntax;
  47. Pair bind_pair = (Pair) bindings;
  48. Object bind_pair_car = bind_pair.getCar();
  49. if (bind_pair_car instanceof SyntaxForm)
  50. {
  51. bindingSyntax = (SyntaxForm) bind_pair_car;
  52. bind_pair_car = bindingSyntax.getDatum();
  53. }
  54. if (! (bind_pair_car instanceof Pair))
  55. return tr.syntaxError (getName()+" binding is not a pair");
  56. Pair binding = (Pair) bind_pair_car;
  57. Object name = binding.getCar();
  58. SyntaxForm nameSyntax = bindingSyntax;
  59. while (name instanceof SyntaxForm)
  60. {
  61. nameSyntax = (SyntaxForm) name;
  62. name = nameSyntax.getDatum();
  63. }
  64. if (! (name instanceof String || name instanceof Symbol))
  65. return tr.syntaxError("variable in "+getName()+" binding is not a symbol");
  66. Object binding_cdr = binding.getCdr();
  67. while (binding_cdr instanceof SyntaxForm)
  68. {
  69. bindingSyntax = (SyntaxForm) binding_cdr;
  70. binding_cdr = bindingSyntax.getDatum();
  71. }
  72. if (! (binding_cdr instanceof Pair))
  73. return tr.syntaxError(getName()+" has no value for '"+name+"'");
  74. binding = (Pair) binding_cdr;
  75. if (binding.getCdr() != LList.Empty)
  76. return tr.syntaxError("let binding for '"+name+"' is improper list");
  77. Declaration decl = new Declaration(name);
  78. Macro macro = Macro.make(decl);
  79. macros[i] = macro;
  80. transformers[i] = binding;
  81. trSyntax[i] = bindingSyntax;
  82. let.addDeclaration(decl);
  83. ScopeExp templateScope = nameSyntax == null ? null : nameSyntax.getScope();
  84. if (templateScope != null)
  85. {
  86. Declaration alias = tr.makeRenamedAlias(decl, templateScope);
  87. if (renamedAliases == null)
  88. renamedAliases = new Stack();
  89. renamedAliases.push(alias);
  90. renamedAliasesCount++;
  91. }
  92. macro.setCapturedScope(bindingSyntax != null ? bindingSyntax.getScope()
  93. : recursive ? let : tr.currentScope());
  94. decls[i] = decl;
  95. decl.setInitValue(QuoteExp.nullExp);
  96. bindings = bind_pair.getCdr();
  97. }
  98. if (recursive)
  99. push(let, tr, renamedAliases);
  100. Macro savedMacro = tr.currentMacroDefinition;
  101. for (int i = 0; i < decl_count; i++)
  102. {
  103. Macro macro = macros[i];
  104. tr.currentMacroDefinition = macro;
  105. Expression value = tr.rewrite_car(transformers[i], trSyntax[i]);
  106. Declaration decl = decls[i];
  107. decl.setInitValue(value);
  108. macro.expander = value;
  109. decl.noteValue(new QuoteExp(macro));
  110. if (value instanceof LambdaExp)
  111. {
  112. LambdaExp lvalue = (LambdaExp) value;
  113. lvalue.nameDecl = decl;
  114. lvalue.setSymbol(decl.getSymbol());
  115. }
  116. }
  117. tr.currentMacroDefinition = savedMacro;
  118. if (! recursive)
  119. push(let, tr, renamedAliases);
  120. Expression result = tr.rewrite_body(body);
  121. tr.pop(let);
  122. tr.popRenamedAlias(renamedAliasesCount);
  123. return result;
  124. }
  125. private void push (LetExp let, Translator tr, Stack renamedAliases)
  126. {
  127. tr.push(let);
  128. if (renamedAliases != null)
  129. for (int i = renamedAliases.size(); --i >= 0; )
  130. tr.pushRenamedAlias((Declaration) renamedAliases.pop());
  131. }
  132. }