syntax.java 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. package kawa.standard;
  2. import kawa.lang.*;
  3. import gnu.bytecode.*;
  4. import gnu.lists.*;
  5. import gnu.expr.*;
  6. public class syntax extends kawa.lang.Quote
  7. {
  8. public static final syntax syntax = new syntax("syntax", false);
  9. public static final syntax quasiSyntax = new syntax("quasisyntax", true);
  10. public syntax (String name, boolean isQuasi)
  11. {
  12. super(name, isQuasi);
  13. }
  14. protected boolean matchesUnquote(Pair pair, SyntaxForm syntax,
  15. Translator tr) {
  16. Object form = pair.getCar();
  17. if (tr.matches(form, syntax, "unsyntax"))
  18. return true;
  19. if (tr.matches(form, syntax, "unquote")) {
  20. tr.error('w',
  21. "unquote inside quasisyntax is deprecated - use unsyntax or #,",
  22. pair instanceof PairWithPosition ? (PairWithPosition)pair : tr);
  23. return true;
  24. }
  25. return false;
  26. }
  27. protected boolean matchesUnquoteSplicing(Pair pair, SyntaxForm syntax,
  28. Translator tr) {
  29. Object form = pair.getCar();
  30. if (tr.matches(form, syntax, "unsyntax-splicing"))
  31. return true;
  32. if (tr.matches(form, syntax, "unquote-splicing")) {
  33. tr.error('w',
  34. "unquote-splicing inside quasisyntax is deprecated - use unsyntax-splicing or #@,",
  35. pair instanceof PairWithPosition ? (PairWithPosition)pair : tr);
  36. return true;
  37. }
  38. return false;
  39. }
  40. protected boolean matchesQuasiQuote(Object form, SyntaxForm syntax,
  41. Translator tr) {
  42. return tr.matches(form, syntax, "quasisyntax");
  43. }
  44. protected boolean expandColonForms ()
  45. {
  46. return false;
  47. }
  48. static final ClassType typeTemplateScope =
  49. ClassType.make("kawa.lang.TemplateScope");
  50. static final Method makeTemplateScopeMethod =
  51. typeTemplateScope.getDeclaredMethod("make", 0);
  52. public Expression rewriteForm (Pair form, Translator tr)
  53. {
  54. if (! (form.getCdr() instanceof Pair)
  55. || (form = (Pair) (form.getCdr())).getCdr() != LList.Empty)
  56. return tr.syntaxError("syntax forms requires a single form");
  57. Declaration saveTemplateScopeDecl = tr.templateScopeDecl;
  58. if (saveTemplateScopeDecl == null)
  59. {
  60. tr.letStart();
  61. Expression init =
  62. new ApplyExp(makeTemplateScopeMethod,
  63. Expression.noExpressions);
  64. Declaration templateScopeDecl = tr.letVariable(null, typeTemplateScope, init);
  65. templateScopeDecl.setCanRead();
  66. tr.templateScopeDecl = templateScopeDecl;
  67. tr.letEnter();
  68. }
  69. try
  70. {
  71. Expression body = coerceExpression(expand(form.getCar(),
  72. isQuasi ? 1 : Quote.QUOTE_DEPTH, tr),
  73. tr);
  74. return saveTemplateScopeDecl == null ? tr.letDone(body) : body;
  75. }
  76. finally
  77. {
  78. tr.templateScopeDecl = saveTemplateScopeDecl;
  79. }
  80. }
  81. protected Expression leaf (Object val, Translator tr)
  82. {
  83. return makeSyntax(val, tr);
  84. }
  85. static Expression makeSyntax (Object form, Translator tr)
  86. {
  87. SyntaxTemplate template = new SyntaxTemplate(form, null,
  88. SyntaxRule.dots3Symbol, tr);
  89. Expression matchArray = QuoteExp.nullExp;
  90. PatternScope patternScope = tr.patternScope;
  91. if (patternScope != null && patternScope.matchArray != null)
  92. matchArray = new ReferenceExp(patternScope.matchArray);
  93. Expression[] args = { new QuoteExp(template), matchArray, new ReferenceExp(tr.templateScopeDecl) };
  94. return new ApplyExp(ClassType.make("kawa.lang.SyntaxTemplate")
  95. .getDeclaredMethod("execute",
  96. new Type[]{null, typeTemplateScope}),
  97. args);
  98. }
  99. }