define_library.java 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. package kawa.standard;
  2. import gnu.bytecode.ClassType;
  3. import gnu.expr.*;
  4. import gnu.lists.*;
  5. import gnu.mapping.SimpleSymbol;
  6. import gnu.mapping.Symbol;
  7. import gnu.text.SourceMessages;
  8. import kawa.lang.*;
  9. import java.util.LinkedHashMap;
  10. import java.util.Map;
  11. /** Implements the R7RS 'define-library' form. */
  12. public class define_library extends Syntax {
  13. public static final define_library define_library = new define_library();
  14. public static final define_library define_library_scan = new define_library();
  15. static { define_library.setName("define-library"); }
  16. @Override
  17. public void scanForm(Pair st, ScopeExp defs, Translator tr) {
  18. if (this != define_library_scan)
  19. createModulePass(st, defs, tr);
  20. else {
  21. tr.push(defs);
  22. scanModulePass(st.getCdr(), defs, tr);
  23. }
  24. }
  25. public void createModulePass(Pair st, ScopeExp defs, Translator tr) {
  26. Object cdr1 = st.getCdr();
  27. if (! (cdr1 instanceof Pair)) {
  28. tr.error('e', "missing library name");
  29. return;
  30. }
  31. if (! (defs instanceof ModuleExp)) {
  32. tr.error('e', "define-library must be a top level");
  33. return;
  34. }
  35. defs.setFlag(ModuleExp.HAS_SUB_MODULE);
  36. Pair pair2 = (Pair) cdr1;
  37. Object car2 = pair2.getCar();
  38. if (LList.listLength(car2, false) <= 0) {
  39. tr.error('e', "invalid list in library name");
  40. return;
  41. }
  42. Language language = tr.getLanguage();
  43. ModuleExp module = new ModuleExp();
  44. module.setFile(defs.getFileName());
  45. NameLookup lexical = new NameLookup(language);
  46. SourceMessages messages = tr.getMessages();
  47. // It might be cleaner to re-use the incoming Compilation.
  48. // However Compilation does not currently support multiple ModuleExps.
  49. SchemeCompilation mcomp = new SchemeCompilation(language, messages, lexical, gnu.mapping.Environment.make());
  50. mcomp.setPedantic(tr.isPedantic());
  51. mcomp.explicit = tr.explicit;
  52. mcomp.immediate = tr.immediate;
  53. String name = module_name.listToModuleName(car2, tr);
  54. String className = name;
  55. int index = name.lastIndexOf('.');
  56. if (index >= 0)
  57. mcomp.classPrefix = name.substring(0, index+1);
  58. else
  59. className = tr.classPrefix + Mangling.mangleClassName(name);
  60. ClassType moduleClass = new gnu.bytecode.ClassType(className);
  61. mcomp.mainLambda = module;
  62. module.setType(tr.mainClass);
  63. module.setName(name);
  64. ModuleInfo curinfo = tr.getMinfo();
  65. ModuleManager manager = ModuleManager.getInstance();
  66. ModuleInfo info = manager.createWithClassName(className);
  67. info.setCompilation(mcomp);
  68. curinfo.addDependency(info);
  69. // It might be desirable to process 'export' forms at this point,
  70. // though so far I don't have a test case where it matters (even if
  71. // a cycle is involved). Note to process 'export' early, we first
  72. // have to expand 'include-library-declarations' and 'cond-expand'.
  73. mcomp.setState(Compilation.PROLOG_PARSED);
  74. mcomp.pendingForm = tr.makePair(pair2,
  75. define_library_scan, pair2.getCdr());
  76. SchemeCompilation curcomp = (SchemeCompilation) tr;
  77. Map<String,ModuleInfo> subModuleMap = curcomp.subModuleMap;
  78. if (subModuleMap == null) {
  79. subModuleMap = new LinkedHashMap<String,ModuleInfo>();
  80. curcomp.subModuleMap = subModuleMap;
  81. }
  82. ModuleInfo oldinfo = subModuleMap.get(name);
  83. if (oldinfo != null)
  84. tr.error('e', "duplicate library name "+name);
  85. subModuleMap.put(name, info);
  86. }
  87. void scanModulePass(Object form, ScopeExp defs, Translator tr) {
  88. while (form instanceof Pair) {
  89. Pair pform = (Pair) form;
  90. Object save1 = tr.pushPositionOf(form);
  91. Object clause = pform.getCar();
  92. if (clause instanceof Pair) {
  93. Pair pclause = (Pair) clause;
  94. Object clauseHead = pclause.getCar();
  95. Syntax syntax = null;
  96. if (clauseHead == beginSymbol)
  97. syntax = begin.begin;
  98. else if (clauseHead == exportSymbol)
  99. syntax = export.export;
  100. else if (clauseHead == includeSymbol)
  101. syntax = Include.include;
  102. else if (clauseHead == includeCiSymbol)
  103. syntax = Include.includeCi;
  104. else if (clauseHead == importSymbol)
  105. syntax = ImportFromLibrary.instance;
  106. if (clauseHead == includeLibraryDeclarationsSymbol) {
  107. Object forms = Include.includeRelative
  108. .process(pclause.getCdr(), tr, null, false);
  109. scanModulePass(forms, defs, tr);
  110. } else if (clauseHead == condExpandSymbol) {
  111. Object forms = IfFeature.condExpand
  112. .evaluate(pclause.getCdr(), tr);
  113. scanModulePass(forms, defs, tr);
  114. } else if (syntax != null) {
  115. syntax.scanForm(pclause, defs, tr);
  116. }
  117. else {
  118. if (tr.isPedantic())
  119. tr.error('e', ("unknown define-library keyword: "
  120. +clauseHead));
  121. tr.scanForm(clause, defs);
  122. }
  123. } else {
  124. tr.error('e', "define-library clause is not a list");
  125. }
  126. form = pform.getCdr();
  127. tr.popPositionOf(save1);
  128. }
  129. tr.errorIfNonEmpty(form);
  130. }
  131. public static final SimpleSymbol beginSymbol = Symbol.valueOf("begin");
  132. public static final SimpleSymbol condExpandSymbol = Symbol.valueOf("cond-expand");
  133. public static final SimpleSymbol exportSymbol = Symbol.valueOf("export");
  134. public static final SimpleSymbol importSymbol = Symbol.valueOf("import");
  135. public static final SimpleSymbol includeSymbol = Symbol.valueOf("include");
  136. public static final SimpleSymbol includeCiSymbol = Symbol.valueOf("include-ci");
  137. public static final SimpleSymbol includeLibraryDeclarationsSymbol = Symbol.valueOf("include-library-declarations");
  138. }