syslisp-syntax.red 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. %
  2. % SYSLISP-SYNTAX.RED - SMacros and redefinition of arithmetic operators
  3. % and other syslisp syntax
  4. %
  5. % Author: Eric Benson and M. L. griss
  6. % Symbolic Computation Group
  7. % Computer Science Dept.
  8. % University of Utah
  9. % Date: 11 July 1981
  10. % Copyright (c) 1981 University of Utah
  11. %
  12. fluid '(!*SYSLISP);
  13. % <PSL.COMP>SYSLISP-SYNTAX.RED.3, 5-May-82 11:33:48, Edit by BENSON
  14. % Wrapped if GetD 'BEGIN1 around parser calls
  15. % New WDECLARE constructs
  16. % Modify ***** [] vector syntax for PREFIX and INFIX forms
  17. % At lower prec
  18. SYMBOLIC PROCEDURE ParseLVEC(VNAME,VEXPR);
  19. IF OP EQ '!*RVEC!* THEN <<OP :=SCAN(); LIST('INDX,VNAME,VEXPR)>>
  20. ELSE PARERR("Missing ] in index expression ");
  21. % Use normal parsing, then CLEAN
  22. SYMBOLIC PROCEDURE ParseWDEC0(FN,DMODES,DLIST);
  23. BEGIN SCALAR PLIST;
  24. IF EQCAR(DLIST,'!*COMMA!*) THEN DLIST:=REVERSE CDR DLIST
  25. ELSE DLIST:=LIST DLIST;
  26. PLIST:=FOR EACH DEC IN DLIST COLLECT ParseWDEC1(FN,DEC);
  27. RETURN ('WDECLARE . DMODES . FN . REVERSE PLIST);
  28. END;
  29. SYMBOLIC PROCEDURE ParseWDEC1(FN,DEC);
  30. % Process each WDEC to check legal modes
  31. if EqCar(DEC,'EQUAL) THEN
  32. AConc(ParseWDEC2(FN,CADR DEC), ParseWDEC3(FN,CADDR DEC))
  33. ELSE AConc(ParseWDEC2(FN,DEC), NIL);
  34. SYMBOLIC PROCEDURE ParseWDEC2(FN,X);
  35. % Remove INDXs from LHS of =
  36. IF IDP X THEN list(X, NIL)
  37. ELSE IF EQCAR(X,'INDX) THEN LIST(CADR X,CADDR X)
  38. ELSE PARERR "Only [] allowed on LHS of WDECLARATION";
  39. SYMBOLIC PROCEDURE ParseWDEC3(FN,X);
  40. % Remove INDX's from RHS of =
  41. IF IDP X THEN X
  42. ELSE IF EQCAR(X,'INDX)
  43. THEN (IF CADR X EQ '!*PREFIXVECT!*
  44. THEN REMCOM(CADDR X)
  45. ELSE PARERR("Only [...] is legal INIT in WDECLARE"))
  46. ELSE X;
  47. if not FUnBoundP 'BEGIN1 then << % kludge #+Rlisp
  48. DEFINEBOP('!*LVEC!*,121,5,ParseLVEC);
  49. DEFINEROP('!*LVEC!*,5,ParseLVEC('!*PREFIXVECT!*,X));
  50. DEFINEBOP('!*RVEC!*,4,5);
  51. DEFINEROP('WCONST,1,ParseWDEC0('WCONST,'DEFAULT,X));
  52. DEFINEROP('WVAR,1,ParseWDEC0('WVAR,'DEFAULT,X));
  53. DEFINEROP('WARRAY,1,ParseWDEC0('WARRAY,'DEFAULT,X));
  54. DEFINEROP('WSTRING,1,ParseWDEC0('WSTRING,'DEFAULT,X));
  55. DEFINEBOP('WCONST,1,1,ParseWDEC0('WCONST,X,Y));
  56. DEFINEBOP('WVAR,1,1,ParseWDEC0('WVAR,X,Y));
  57. DEFINEBOP('WARRAY,1,1,ParseWDEC0('WARRAY,X,Y));
  58. DEFINEBOP('WSTRING,1,1,ParseWDEC0('WSTRING,X,Y));
  59. % Operators @ for GetMem, & for Loc
  60. put('!@, 'NewNam, 'GetMem);
  61. put('!&, 'NewNam, 'Loc);
  62. >>;
  63. % SysName hooks for REFORM
  64. REMFLAG('(REFORM),'LOSE);
  65. SYMBOLIC PROCEDURE REFORM U;
  66. IF ATOM U OR CAR U MEMQ '(QUOTE WCONST)
  67. THEN U
  68. ELSE IF CAR U EQ 'COND THEN 'COND . REFORM CDR U
  69. ELSE IF CAR U EQ 'PROG
  70. THEN PROGN(RPLCDX(CDR U,REFORMLIS CDDR U),U)
  71. ELSE IF CAR U EQ 'LAMBDA
  72. THEN PROGN(RPLACA(CDDR U,REFORM CADDR U),U)
  73. ELSE IF CAR U EQ 'FUNCTION AND ATOM CADR U
  74. THEN BEGIN SCALAR X;
  75. IF NULL !*CREF AND (X:= GET(CADR U,'SMACRO))
  76. THEN RETURN LIST('FUNCTION,X)
  77. ELSE IF GET(CADR U,'NMACRO) OR MACROP CADR U
  78. THEN REDERR "MACRO USED AS FUNCTION"
  79. ELSE RETURN U END
  80. % ELSE IF CAR U EQ 'MAT THEN RPLCDX(U,MAPC2(CDR U,FUNCTION REFORM))
  81. ELSE IF ATOM CAR U
  82. THEN BEGIN SCALAR X,Y,FN;
  83. FN := CAR U;
  84. IF (Y := GETD FN) AND CAR Y EQ 'MACRO
  85. AND EXPANDQ FN
  86. THEN RETURN REFORM APPLY(CDR Y,LIST U);
  87. X := REFORMLIS CDR U;
  88. IF NULL IDP FN THEN RETURN(FN . X);
  89. IF !*SYSLISP AND (Y:=GET(FN,'SYSNAME)) THEN <<FN:=Y;U:=FN.CDR U>>;
  90. IF (NULL !*CREF OR EXPANDQ FN)
  91. AND (Y:= GET(FN,'NMACRO))
  92. THEN RETURN
  93. APPLY(Y,IF FLAGP(FN,'NOSPREAD) THEN LIST X ELSE X)
  94. ELSE IF (NULL !*CREF OR EXPANDQ FN)
  95. AND (Y:= GET(FN,'SMACRO))
  96. THEN RETURN SUBLIS(PAIR(CADR Y,X),CADDR Y)
  97. %we could use an atom SUBLIS here (eg, SUBLA);
  98. ELSE RETURN PROGN(RPLCDX(U,X),U)
  99. END
  100. ELSE REFORM CAR U . REFORMLIS CDR U;
  101. RemFlag('(Plus Times), 'NARY)$
  102. DefList('((Plus WPlus2)
  103. (Plus2 WPlus2)
  104. (Minus WMinus)
  105. (Difference WDifference)
  106. (Times WTimes2)
  107. (Times2 WTimes2)
  108. (Quotient WQuotient)
  109. (Remainder WRemainder)
  110. (Mod WRemainder)
  111. (Land WAnd)
  112. (Lor WOr)
  113. (Lxor WXor)
  114. (Lnot WNot)
  115. (LShift WShift)
  116. (LSH WShift)), 'SysName);
  117. DefList('((Neq WNeq)
  118. (Equal WEq)
  119. (Eqn WEq)
  120. (Eq WEq)
  121. (Greaterp WGreaterp)
  122. (Lessp WLessp)
  123. (Geq WGeq)
  124. (Leq WLeq)
  125. (Getv WGetv)
  126. (Indx WGetv)
  127. (Putv WPutv)
  128. (SetIndx WPutv)), 'SysName);
  129. % modification to arithmetic FOR loop for SysLisp
  130. LISP PROCEDURE MKSYSFOR U;
  131. BEGIN SCALAR ACTION,BODY,EXP,INCR,LAB1,LAB2,RESULT,TAIL,VAR,X;
  132. VAR := second second U;
  133. INCR := cddr second U;
  134. if FixP third Incr or WConstEvaluable third Incr then return
  135. ConstantIncrementFor U;
  136. ACTION := first third U;
  137. BODY := second third U;
  138. RESULT := LIST LIST('SETQ,VAR,CAR INCR);
  139. INCR := CDR INCR;
  140. X := LIST('WDIFFERENCE,first INCR,VAR);
  141. IF second INCR NEQ 1 THEN X := LIST('WTIMES2,second INCR,X);
  142. IF NOT ACTION EQ 'DO THEN
  143. REDERR "Only do expected in SysLisp FOR";
  144. LAB1 := GENSYM();
  145. LAB2 := GENSYM();
  146. RESULT := NCONC(RESULT,
  147. LAB1 .
  148. LIST('COND,LIST(LIST('WLESSP,X,0),LIST('GO,LAB2))) .
  149. BODY .
  150. LIST('SETQ,VAR,LIST('WPLUS2,VAR,second INCR)) .
  151. LIST('GO,LAB1) .
  152. LAB2 .
  153. TAIL);
  154. RETURN MKPROG(VAR . EXP,RESULT)
  155. END;
  156. LISP PROCEDURE ConstantIncrementFor U;
  157. BEGIN SCALAR ACTION,BODY,EXP,INCR,LAB1,RESULT,VAR,X,
  158. StepValue, Limit;
  159. VAR := second second U;
  160. INCR := cddr second U;
  161. ACTION := first third U;
  162. BODY := second third U;
  163. RESULT := LIST LIST('SETQ,VAR,CAR INCR);
  164. INCR := CDR INCR;
  165. StepValue := if FixP second Incr then second Incr
  166. else WConstEvaluable second Incr;
  167. Limit := first Incr;
  168. IF NOT ACTION EQ 'DO THEN
  169. REDERR "Only do expected in SysLisp FOR";
  170. LAB1 := GENSYM();
  171. RESULT := NCONC(RESULT,
  172. LAB1 .
  173. LIST('COND,LIST(LIST(if MinusP StepValue then 'WLessP
  174. else 'WGreaterP,
  175. Var,
  176. Limit),'(return 0))) .
  177. BODY .
  178. LIST('SETQ,VAR,LIST('WPLUS2,VAR,StepValue)) .
  179. LIST('GO,LAB1) .
  180. NIL);
  181. RETURN MKPROG(VAR . EXP,RESULT)
  182. END;
  183. LISP PROCEDURE MKFOR1 U;
  184. IF !*SYSLISP THEN MKSYSFOR U ELSE MKLISPFOR U;
  185. PUTD('MKLISPFOR,'EXPR,CDR GETD 'FOR); % grab old FOR definition
  186. macro procedure For U; MkFor1 U; % redefine FOR
  187. END;