smacro.red 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. module smacro; % Support for SMACRO expansion.
  2. % Author: Anthony C. Hearn.
  3. % Copyright (c) 1987 The RAND Corporation. All rights reserved.
  4. symbolic procedure applsmacro(u,vals,name);
  5. % U is smacro body of form (lambda <varlist> <body>), VALS is
  6. % argument list, NAME is name of smacro.
  7. begin scalar body,remvars,varlist,w;
  8. varlist := cadr u;
  9. body := caddr u;
  10. if length varlist neq length vals
  11. then rerror(rlisp,15,list("Argument mismatch for SMACRO",name));
  12. if no!-side!-effect!-listp vals or one!-entry!-listp(varlist,body)
  13. then return subla!-q(pair(varlist,vals),body)
  14. else if length varlist>1
  15. then <<w := for each x in varlist collect (x . gensym());
  16. body := subla!-q(w,body);
  17. varlist := for each x in w collect cdr x>>;
  18. for each x in vals do
  19. <<if no!-side!-effectp x or one!-entryp(car varlist,body)
  20. then body := subla!-q(list(car varlist . x),body)
  21. else remvars := aconc(remvars,car varlist . x);
  22. varlist := cdr varlist>>;
  23. if null remvars then return body
  24. else <<w := list('lambda,
  25. for each x in remvars collect car x,
  26. body) .
  27. for each x in remvars collect cdr x;
  28. % if not eqcar(cadr w,'setq)
  29. % then <<prin2 "*** smacro: "; print cdr w>>;
  30. return w>>
  31. end;
  32. symbolic procedure no!-side!-effectp u;
  33. if atom u then numberp u or idp u and not(fluidp u or globalp u)
  34. else if car u eq 'quote then t
  35. else if flagp(car u,'nosideeffects)
  36. then no!-side!-effect!-listp cdr u
  37. else nil;
  38. symbolic procedure no!-side!-effect!-listp u;
  39. null u or no!-side!-effectp car u and no!-side!-effect!-listp cdr u;
  40. flag('(car cdr caar cadr cdar cddr caaar caadr cadar caddr cdaar cdadr
  41. cddar cdddr cons),'nosideeffects);
  42. symbolic procedure one!-entryp(u,v);
  43. % determines if id U occurs less than twice in V.
  44. if atom v then t
  45. else if smemq(u,car v)
  46. then if smemq(u,cdr v) then nil else one!-entryp(u,car v)
  47. else one!-entryp(u,cdr v);
  48. symbolic procedure one!-entry!-listp(u,v);
  49. null u or one!-entryp(car u,v) and one!-entry!-listp(cdr u,v);
  50. symbolic procedure subla!-q(u,v);
  51. begin scalar x;
  52. if null u or null v then return v
  53. else if atom v
  54. then return if x:= atsoc(v,u) then cdr x else v
  55. else if car v eq 'quote then return v
  56. else return(subla!-q(u,car v) . subla!-q(u,cdr v))
  57. end;
  58. put('smacro,'macrofn,'applsmacro);
  59. endmodule;
  60. end;