module.red 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. % module module; % Support for module and package use.
  2. % Author: Anthony C. Hearn.
  3. % Copyright (c) 1990 The RAND Corporation. All rights reserved.
  4. %
  5. % WARNING. This code is loaded quite early in the process of
  6. % bootstrapping. As a result it has to be written such that it
  7. % will work properly with the cut-down bootstrap version of the
  8. % RLISP parser. Various consructions such as <<...>> are not
  9. % available....
  10. %
  11. fluid '(!*backtrace !*mode !*faslp);
  12. global '(exportslist!* importslist!* loaded!-packages!* mode!-list!*);
  13. !*mode := 'symbolic; % initial value.
  14. remprop('exports,'stat);
  15. remprop('imports,'stat);
  16. remprop('module,'stat);
  17. symbolic procedure exports u;
  18. begin exportslist!* := union(u,exportslist!*) end;
  19. symbolic procedure imports u;
  20. begin importslist!* := union(u,importslist!*) end;
  21. symbolic procedure module u;
  22. % Sets up a module definition.
  23. begin
  24. mode!-list!* := !*mode . mode!-list!*;
  25. !*mode := 'symbolic
  26. end;
  27. symbolic procedure endmodule;
  28. begin
  29. if null mode!-list!*
  30. then rederr "ENDMODULE called outside module";
  31. exportslist!* := nil;
  32. importslist!* := nil;
  33. !*mode := car mode!-list!*;
  34. mode!-list!* := cdr mode!-list!*
  35. end;
  36. deflist('((exports rlis) (imports rlis) (module rlis)),'stat);
  37. put('endmodule,'stat,'endstat);
  38. flag('(endmodule),'go);
  39. flag('(module endmodule),'eval);
  40. put('xmodule,'newnam,'module); % Hook for module extensions.
  41. % Support for package loading.
  42. put('load,'stat,'rlis);
  43. put('load,'formfn,'formload);
  44. symbolic procedure formload(u,vars,mode);
  45. list((if eq(mode,'symbolic) then 'evload else 'load!_package),
  46. mkquote cdr u);
  47. symbolic procedure load!-package u;
  48. begin scalar x,y;
  49. if stringp u then return load!-package intern compress explode2 u
  50. else if null idp u then rederr list(u,"is not a package name")
  51. else if memq(u,loaded!-packages!*)
  52. % then progn(lprim list("Package",u,"already loaded"), return u)
  53. then return u
  54. else if or(atom(x:= errorset(list('evload,list('quote,list u)),
  55. nil,!*backtrace)),
  56. cdr x)
  57. then rederr
  58. list("error in loading package",u,"or package not found");
  59. if (x := get(u,'patchfn))
  60. then begin scalar !*usermode,!*redefmsg; eval list x end;
  61. loaded!-packages!* := u . loaded!-packages!*;
  62. x := get(u,'package);
  63. if x then x := cdr x;
  64. a: if null x then go to b
  65. else if null atom get(car x,'package) then load!-package car x
  66. else if or(atom(y := errorset(list('evload,
  67. list('quote,list car x)),
  68. nil,!*backtrace)),
  69. cdr y)
  70. then rederr list("module",car x,"of package",u,
  71. "cannot be loaded");
  72. x := cdr x;
  73. go to a;
  74. b: if (x := get(u,'patchfn)) then eval list x
  75. end;
  76. % Now a more user-friendly version.
  77. remprop('load!_package,'stat);
  78. remprop('packages!_to!_load,'stat);
  79. symbolic procedure load!_package u;
  80. begin scalar x;
  81. x := u;
  82. a: if null x then return nil;
  83. load!-package car x;
  84. x := cdr x;
  85. go to a
  86. end;
  87. symbolic procedure packages!_to!_load u;
  88. %% FJW: Load other packages at package load time only, i.e. do not
  89. %% load during building (hence not to be flagged eval).
  90. if null !*faslp then load!_package u;
  91. put('load!_package,'stat,'rlis);
  92. put('packages!_to!_load,'stat,'rlis);
  93. flag('(load!-package load!_package),'eval);
  94. % Support for patching REDUCE sources.
  95. symbolic procedure patchstat;
  96. % Read a patch for a given package.
  97. begin scalar !*mode,u,v,x,y,z,z2;
  98. x := scan(); % Package name.
  99. scan(); % Remove semicolon.
  100. a: !*mode := 'symbolic;
  101. y := xread nil;
  102. if eqcar(y,'symbolic) then y := cadr y
  103. else if flagpcar(y,'modefn)
  104. then progn(!*mode := car y, y := cadr y);
  105. if eq(y,'endpatch)
  106. then progn(u := name!-for!-patched!-version(x, z),
  107. z2 := list('de,u,nil,'progn . reversip z) . z2,
  108. z2 := list('put,mkquote x,mkquote 'patchfn,mkquote u)
  109. . z2,
  110. return ('patch . reversip z2))
  111. else if eqcar(y,'procedure)
  112. then progn(
  113. v := cadr y,
  114. u := name!-for!-patched!-version(v, y),
  115. z := list('instate!-patches,mkquote v,mkquote u,mkquote x) . z,
  116. z2 := convertmode(('procedure . u . cddr y),nil,
  117. 'symbolic,!*mode)
  118. . z2)
  119. else z := convertmode(y,nil,'symbolic,!*mode) . z;
  120. go to a;
  121. end;
  122. % hashtagged!-name (in CSL) constructs a name that stats with NAME
  123. % but then continues with a hash value based on EXTRA. The
  124. % improbability of hash collisions then makes it reasonable to use an
  125. % interned symbol.
  126. symbolic procedure name!-for!-patched!-version(name, extra);
  127. if member('csl, lispsystem!*) then hashtagged!-name(name, extra)
  128. else gensym();
  129. symbolic procedure instate!-patches(new, old, pkg);
  130. begin
  131. scalar x;
  132. x := getd old;
  133. if x then putd(new, car x, cdr x)
  134. else rerror('module, 1, list(new, "has a badly set-up patch"));
  135. return nil
  136. end;
  137. put('patch,'stat,'patchstat);
  138. symbolic procedure formpatch(u,vars,mode);
  139. 'progn . cdr u;
  140. put('patch,'formfn,'formpatch);
  141. % endmodule;
  142. end;