lap-to-asm.red 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164
  1. %
  2. % LAP-TO-ASM.RED - LAP to assembler translator
  3. %
  4. % Author: Eric Benson
  5. % Symbolic Computation Group
  6. % Computer Science Dept.
  7. % University of Utah
  8. % Date: 13 August 1981
  9. % Copyright (c) 1981 University of Utah
  10. %
  11. % 01-Mar-83 Nancy Kendzierski
  12. % Changed EVIN to PathIn in ASMOUT to enable search paths to be
  13. % used when doing system builds connected to a directory other
  14. % than pxx:, where xx=machine (hp, 20, vax, etc.)
  15. % Only set InputSymFile!*, OutputSymFile!*, GlobalDataFileName!*,
  16. % and InitFileNameFormat!* if they aren't already initialized.
  17. % Changed SEMIC!* declaration from global to fluid.
  18. % <PSL.COMP>LAP-TO-ASM.RED.5, 30-Apr-82 14:47:52, Edit by BENSON
  19. % Removed EVAL and IGNORE processing
  20. Imports '(PathIn);
  21. fluid '(Semic!*
  22. !*Comp
  23. !*PLap
  24. DfPrint!*
  25. CharactersPerWord
  26. AddressingUnitsPerItem
  27. AddressingUnitsPerFunctionCell
  28. InputSymFile!*
  29. OutputSymFile!*
  30. CodeOut!*
  31. DataOut!*
  32. InitOut!*;
  33. CodeFileNameFormat!*
  34. DataFileNameFormat!*
  35. InitFileNameFormat!*
  36. ModuleName!*
  37. UncompiledExpressions!*
  38. NextIDNumber!*
  39. OrderedIDList!*
  40. NilNumber!*
  41. !*MainFound
  42. !*MAIN
  43. !*DeclareBeforeUse
  44. MainEntryPointName!*
  45. EntryPoints!*
  46. LocalLabels!*
  47. CodeExternals!*
  48. CodeExporteds!*
  49. DataExternals!*
  50. DataExporteds!*
  51. ExternalDeclarationFormat!*
  52. ExportedDeclarationFormat!*
  53. LabelFormat!*
  54. FullWordFormat!*
  55. DoubleFloatFormat!*
  56. ReserveDataBlockFormat!*
  57. ReserveZeroBlockFormat!*
  58. UndefinedFunctionCellInstructions!*
  59. DefinedFunctionCellFormat!*
  60. PrintExpressionForm!*
  61. PrintExpressionFormPointer!*
  62. CommentFormat!*
  63. NumericRegisterNames!*
  64. ExpressionCount!*
  65. ASMOpenParen!*
  66. ASMCloseParen!*
  67. ToBeCompiledExpressions!*
  68. GlobalDataFileName!*
  69. );
  70. % Default values; set up if not already initialized.
  71. if null InputSymFile!* then InputSymFile!* := "psl.sym";
  72. if null OutputSymFile!* then OutputSymFile!* := "psl.sym";
  73. if null GlobalDataFileName!* then GlobalDataFileName!* := "global-data.red";
  74. if null InitFileNameFormat!* then InitFileNameFormat!* := "%w.init";
  75. lisp procedure DfPrintASM U; %. Called by TOP-loop, DFPRINT!*
  76. begin scalar Nam, Ty, Fn;
  77. if atom U then return NIL;
  78. Fn := car U;
  79. IF FN = 'PUTD THEN GOTO DB2;
  80. IF NOT (FN MEMQ '(DE DF DM DN)) THEN GOTO DB1;
  81. NAM:=CADR U;
  82. U:='LAMBDA . CDDR U;
  83. TY:=CDR ASSOC(FN, '((DE . EXPR)
  84. (DF . FEXPR)
  85. (DM . MACRO)
  86. (DN . NEXPR)));
  87. DB3: if Ty = 'MACRO then begin scalar !*Comp;
  88. PutD(Nam, Ty, U); % Macros get defined now
  89. end;
  90. if FlagP(Nam, 'Lose) then <<
  91. ErrorPrintF("*** %r has not been defined, because it is flagged LOSE",
  92. Nam);
  93. return NIL >>;
  94. IF FLAGP(TY,'COMPILE) THEN
  95. << PUT(NAM,'CFNTYPE,LIST TY);
  96. U := LIST('!*ENTRY,NAM,TY,LENGTH CADR U)
  97. . !&COMPROC(U, NAM);
  98. if !*PLAP then for each X in U do Print X;
  99. if TY neq 'EXPR then
  100. DfPrintASM list('put, MkQuote Nam, '(quote TYPE), MkQuote TY);
  101. ASMOUTLAP U >>
  102. ELSE % should never happen
  103. SaveUncompiledExpression LIST('PUTD, MKQUOTE NAM,
  104. MKQUOTE TY,
  105. MKQUOTE U);
  106. RETURN NIL;
  107. DB1: % Simple S-EXPRESSION, maybe EVAL it;
  108. IF NOT PAIRP U THEN RETURN NIL;
  109. if (Fn := get(car U, 'ASMPreEval)) then return Apply(Fn, list U)
  110. else if (Fn := GetD car U) and car Fn = 'MACRO then
  111. return DFPRINTASM Apply(cdr Fn, list U);
  112. SaveUncompiledExpression U;
  113. RETURN NIL;
  114. DB2: NAM:=CADR U;
  115. TY:=CADDR U;
  116. FN:=CADDDR U;
  117. IF EQCAR(NAM,'QUOTE) THEN << NAM:=CADR NAM;
  118. IF EQCAR(TY,'QUOTE) THEN << TY:=CADR TY;
  119. IF PAIRP FN AND CAR FN MEMBER '(FUNCTION QUOTE) THEN << FN:=CADR FN;
  120. IF TY MEMQ '(EXPR FEXPR MACRO NEXPR) THEN
  121. << U:=FN; GOTO DB3 >> >> >> >>;
  122. GOTO DB1;
  123. END;
  124. lisp procedure ASMPreEvalLoadTime U;
  125. DFPrintASM cadr U; % remove LOADTIME
  126. put('LoadTime, 'ASMPreEval, 'ASMPreEvalLoadTime);
  127. lisp procedure ASMPreEvalStartupTime U;
  128. SaveForCompilation cadr U;
  129. put('StartupTime, 'ASMPreEval, 'ASMPreEvalStartupTime);
  130. lisp procedure ASMPreEvalProgN U;
  131. for each X in cdr U do
  132. DFPrintASM X;
  133. put('ProgN, 'ASMPreEval, 'ASMPreEvalProgN);
  134. put('WDeclare, 'ASMPreEval, 'Eval); % do it now
  135. lisp procedure ASMPreEvalSetQ U;
  136. begin scalar X, Val;
  137. X := cadr U;
  138. Val := caddr U;
  139. return if ConstantP Val or Val = T then
  140. << FindIDNumber X;
  141. put(X, 'InitialValue, Val);
  142. NIL >>
  143. else if null Val then
  144. << FindIDNumber X;
  145. RemProp(X, 'InitialValue);
  146. Flag(list X, 'NilInitialValue);
  147. NIL >>
  148. else if EqCar(Val, 'QUOTE) then
  149. << FindIDNumber X;
  150. Val := cadr Val;
  151. if null Val then
  152. << RemProp(X, 'InitialValue);
  153. Flag(list X, 'NilInitialValue) >>
  154. else
  155. put(X, 'InitialValue, Val);
  156. NIL >>
  157. else if IDP Val and get(Val, 'InitialValue)
  158. or FlagP(Val, 'NilInitialValue) then
  159. << if (Val := get(Val, 'InitialValue)) then
  160. put(X, 'InitialValue, Val)
  161. else Flag(list X, 'NilInitialValue) >>
  162. else SaveUncompiledExpression U; % just check simple cases, else return
  163. end;
  164. put('SetQ, 'ASMPreEval, 'ASMPreEvalSetQ);
  165. lisp procedure ASMPreEvalPutD U;
  166. SaveUncompiledExpression CheckForEasySharedEntryPoints U;
  167. lisp procedure CheckForEasySharedEntryPoints U;
  168. %
  169. % looking for (PUTD (QUOTE name1) xxxx (CDR (GETD (QUOTE name2))))
  170. %
  171. begin scalar NU, Nam, Exp;
  172. NU := cdr U;
  173. Nam := car NU;
  174. if car Nam = 'QUOTE then Nam := cadr Nam else return U;
  175. NU := cdr NU;
  176. Exp := cadr NU;
  177. if not (car Exp = 'CDR) then return U;
  178. Exp := cadr Exp;
  179. if not (car Exp = 'GETD) then return U;
  180. Exp := cadr Exp;
  181. if not (car Exp = 'QUOTE) then return U;
  182. Exp := cadr Exp;
  183. FindIDNumber Nam;
  184. put(Nam, 'EntryPoint, FindEntryPoint Exp);
  185. if not (car NU = '(QUOTE EXPR)) then return list('Put, '(Quote Type),
  186. car NU);
  187. return NIL;
  188. end;
  189. put('PutD, 'ASMPreEval, 'ASMPreEvalPutD);
  190. lisp procedure ASMPreEvalFluidAndGlobal U;
  191. << if EqCar(cadr U, 'QUOTE) then Flag(cadr cadr U, 'NilInitialValue);
  192. SaveUncompiledExpression U >>;
  193. put('Fluid, 'ASMPreEval, 'ASMPreEvalFluidAndGlobal);
  194. put('Global, 'ASMPreEval, 'ASMPreEvalFluidAndGlobal);
  195. CommentOutCode <<
  196. fluid '(NewFluids!* NewGlobals!*);
  197. lisp procedure ASMPreEvalFluidAndGlobal U;
  198. begin scalar L;
  199. L := cadr U;
  200. return if car L = 'QUOTE then
  201. << L := cadr L;
  202. if car U = 'FLUID then
  203. NewFluids!* := UnionQ(NewFluids!*, L) % take union
  204. else NewGlobals!* := UnionQ(NewGlobals!*, L);
  205. Flag(L, 'NilInitialValue);
  206. NIL >>
  207. else SaveUncompiledExpression U;
  208. end;
  209. put('Fluid, 'ASMPreEval, 'ASMPreEvalFluidAndGlobal);
  210. put('Global, 'ASMPreEval, 'ASMPreEvalFluidAndGlobal);
  211. >>;
  212. lisp procedure ASMPreEvalLAP U;
  213. if EqCar(cadr U, 'QUOTE) then ASMOutLap cadr cadr U
  214. else SaveUncompiledExpression U;
  215. put('LAP, 'ASMPreEval, 'ASMPreEvalLAP);
  216. CommentOutCode <<
  217. lisp procedure InitialPut(Nam, Ind, Val);
  218. begin scalar L, P;
  219. FindIDNumber Nam;
  220. if (P := Atsoc(Ind, L := get(Nam, 'InitialPropertyList))) then
  221. Rplacd(P, Val)
  222. else put(Nam, 'InitialPropertyList, (Ind . Val) . L);
  223. end;
  224. lisp procedure InitialRemprop(Nam, Ind);
  225. begin scalar L;
  226. if (L := get(Nam, 'InitialPropertyList)) then
  227. put(Nam, 'InitialPropertyList, DelAtQIP(Ind, L));
  228. end;
  229. lisp procedure InitialFlag1(Nam, Ind);
  230. begin scalar L, P;
  231. FindIDNumber Nam;
  232. if not Ind memq (L := get(Nam, 'InitialPropertyList)) then
  233. put(Nam, 'InitialPropertyList, Ind . L);
  234. end;
  235. lisp procedure InitialRemFlag1(Nam, Ind);
  236. begin scalar L;
  237. if (L := get(Nam, 'InitialPropertyList)) then
  238. put(Nam, 'InitialPropertyList, DelQIP(Ind, L));
  239. end;
  240. lisp procedure ASMPreEvalPut U;
  241. begin scalar Nam, Ind, Val;
  242. Nam := second U;
  243. Ind := third U;
  244. Val := fourth U;
  245. if EqCar(Nam, 'QUOTE) and EqCar(Ind, 'QUOTE) and
  246. (ConstantP Val or Val = T or EqCar(Val, 'QUOTE)) then
  247. InitialPut(second Nam, second Ind, if EqCar(Val, 'QUOTE) then
  248. second Val else Val)
  249. else SaveUncompiledExpression U;
  250. end;
  251. put('put, 'ASMPreEval, 'ASMPreEvalPut);
  252. lisp procedure ASMPreEvalRemProp U;
  253. begin scalar Nam, Ind;
  254. Nam := second U;
  255. Ind := third U;
  256. if EqCar(Nam, 'QUOTE) and EqCar(Ind, 'QUOTE) then
  257. InitialRemProp(second Nam, second Ind)
  258. else SaveUncompiledExpression U;
  259. end;
  260. put('RemProp, 'ASMPreEval, 'ASMPreEvalRemProp);
  261. lisp procedure ASMPreEvalDefList U;
  262. begin scalar DList, Ind;
  263. DList := second U;
  264. Ind := third U;
  265. if EqCar(DList, 'QUOTE) and EqCar(Ind, 'QUOTE) then
  266. << DList := second DList;
  267. Ind := second Ind;
  268. for each X in Dlist do InitialPut(first X, Ind, second X) >>
  269. else SaveUncompiledExpression U;
  270. end;
  271. put('DefList, 'ASMPreEval, 'ASMPreEvalDefList);
  272. lisp procedure ASMPreEvalFlag U;
  273. begin scalar NameList, Ind;
  274. NameList := second U;
  275. Ind := third U;
  276. if EqCar(NameList, 'QUOTE) and EqCar(Ind, 'QUOTE) then
  277. << Ind := second Ind;
  278. for each X in second NameList do
  279. InitialFlag1(X, Ind) >>
  280. else SaveUncompiledExpression U;
  281. end;
  282. put('flag, 'ASMPreEval, 'ASMPreEvalFlag);
  283. lisp procedure ASMPreEvalRemFlag U;
  284. begin scalar NameList, Ind;
  285. NameList := second U;
  286. Ind := third U;
  287. if EqCar(NameList, 'QUOTE) and EqCar(Ind, 'QUOTE) then
  288. << Ind := second Ind;
  289. for each X in second NameList do
  290. InitialRemFlag1(X, Ind) >>
  291. else SaveUncompiledExpression U;
  292. end;
  293. put('RemFlag, 'ASMPreEval, 'ASMPreEvalRemFlag);
  294. lisp procedure ASMPreEvalGlobal U;
  295. begin scalar NameList;
  296. NameList := second U;
  297. if EqCar(NameList, 'QUOTE) then
  298. for each X in second NameList do
  299. InitialPut(X, 'TYPE, 'Global)
  300. else SaveUncompiledExpression U;
  301. end;
  302. put('Global, 'ASMPreEval, 'ASMPreEvalGlobal);
  303. lisp procedure ASMPreEvalFluid U;
  304. begin scalar NameList;
  305. NameList := second U;
  306. if EqCar(NameList, 'QUOTE) then
  307. for each X in second NameList do
  308. InitialPut(X, 'TYPE, 'FLUID)
  309. else SaveUncompiledExpression U;
  310. end;
  311. put('Fluid, 'ASMPreEval, 'ASMPreEvalFluid);
  312. lisp procedure ASMPreEvalUnFluid U;
  313. begin scalar NameList;
  314. NameList := second U;
  315. if EqCar(NameList, 'QUOTE) then
  316. for each X in second NameList do
  317. InitialRemProp(X, 'TYPE)
  318. else SaveUncompiledExpression U;
  319. end;
  320. put('UnFluid, 'ASMPreEval, 'ASMPreEvalUnFluid);
  321. >>;
  322. lisp procedure SaveUncompiledExpression U;
  323. if PairP U then
  324. begin scalar OldOut;
  325. OldOut := WRS InitOut!*;
  326. Print U;
  327. WRS OldOut;
  328. end;
  329. ToBeCompiledExpressions!* := NIL . NIL;
  330. lisp procedure SaveForCompilation U;
  331. if atom U or U member car ToBeCompiledExpressions!* then NIL
  332. else if car U = 'progn then
  333. for each X in cdr U do SaveForCompilation X
  334. else TConc(ToBeCompiledExpressions!*, U);
  335. SYMBOLIC PROCEDURE ASMOUT FIL;
  336. begin scalar OldOut;
  337. ModuleName!* := FIL;
  338. Prin2T "ASMOUT: IN files; or type in expressions";
  339. Prin2T "When all done execute ASMEND;";
  340. CodeOut!* := Open(BldMsg(CodeFileNameFormat!*, ModuleName!*), 'OUTPUT);
  341. OldOut := WRS CodeOut!*;
  342. LineLength 1000;
  343. WRS OldOut;
  344. CodeFileHeader();
  345. DataOut!* := Open(BldMsg(DataFileNameFormat!*, ModuleName!*), 'OUTPUT);
  346. OldOut := WRS DataOut!*;
  347. LineLength 1000;
  348. WRS OldOut;
  349. DataFileHeader();
  350. InitOut!* := Open(BldMsg(InitFileNameFormat!*, ModuleName!*), 'OUTPUT);
  351. ReadSYMFile();
  352. DFPRINT!* := 'DFPRINTASM;
  353. RemD 'OldLap;
  354. PutD('OldLap, 'EXPR, cdr RemD 'Lap);
  355. PutD('Lap, 'EXPR, cdr GetD 'ASMOutLap);
  356. !*DEFN := T;
  357. SEMIC!* := '!$ ; % to turn echo off for IN
  358. if not ((ModuleName!* = "main")
  359. or !*Main) then PathIn GlobalDataFileName!*
  360. else !*Main := T;
  361. end;
  362. lisp procedure ASMEnd;
  363. << off SysLisp;
  364. if !*MainFound then
  365. << CompileUncompiledExpressions();
  366. % WriteInitFile();
  367. InitializeSymbolTable() >>
  368. else WriteSymFile();
  369. CodeFileTrailer();
  370. Close CodeOut!*;
  371. DataFileTrailer();
  372. Close DataOut!*;
  373. Close InitOut!*;
  374. RemD 'Lap;
  375. PutD('Lap, 'EXPR, cdr GetD 'OldLap);
  376. DFPRINT!* := NIL;
  377. !*DEFN := NIL >>;
  378. FLAG('(ASMEND), 'IGNORE);
  379. DEFINEROP('ASMEND,NIL,ESTAT('ASMEND));
  380. lisp procedure CompileUncompiledExpressions();
  381. << CommentOutCode << AddFluidAndGlobalDecls(); >>;
  382. DFPRINTASM list('DE, 'INITCODE, '(),
  383. 'PROGN . car ToBeCompiledExpressions!*) >>;
  384. CommentOutCode <<
  385. lisp procedure AddFluidAndGlobalDecls();
  386. << SaveUncompiledExpression list('GLOBAL, MkQuote NewGlobals!*);
  387. SaveUncompiledExpression list('FLUID, MkQuote NewFluids!*) >>;
  388. >>;
  389. lisp procedure ReadSymFile();
  390. LapIN InputSymFile!*;
  391. lisp procedure WriteSymFile();
  392. begin scalar NewOut, OldOut;
  393. OldOut := WRS(NewOut := Open(OutputSymFile!*, 'OUTPUT));
  394. print list('SaveForCompilation,
  395. MkQuote('progn . car ToBeCompiledExpressions!*));
  396. SaveIDList();
  397. SetqPrint 'NextIDNumber!*;
  398. SetqPrint 'StringGenSym!*;
  399. MapObl function PutPrintEntryAndSym;
  400. WRS OldOut;
  401. Close NewOut;
  402. end;
  403. CommentOutCode <<
  404. lisp procedure WriteInitFile();
  405. begin scalar OldOut, NewOut;
  406. NewOut := Open(InitFileName!*, 'OUTPUT);
  407. OldOut := WRS NewOut;
  408. for each X in car UncompiledExpressions!* do PrintInit X;
  409. Close NewOut;
  410. WRS OldOut;
  411. end;
  412. lisp procedure PrintInit X;
  413. if EqCar(X, 'progn) then
  414. for each Y in cdr X do PrintInit Y
  415. else Print X;
  416. >>;
  417. lisp procedure SaveIDList();
  418. << Print list('setq, 'OrderedIDList!*, MkQuote car OrderedIDList!*);
  419. Print quote(OrderedIDList!* :=
  420. OrderedIDList!* . LastPair OrderedIDList!*) >>;
  421. lisp procedure SetqPrint U;
  422. print list('SETQ, U, MkQuote Eval U);
  423. lisp procedure PutPrint(X, Y, Z);
  424. print list('PUT, MkQuote X, MkQuote Y, MkQuote Z);
  425. lisp procedure PutPrintEntryAndSym X;
  426. begin scalar Y;
  427. if (Y := get(X, 'EntryPoint)) then PutPrint(X, 'EntryPoint, Y);
  428. if (Y := get(X, 'IDNumber)) then
  429. PutPrint(X, 'IDNumber, Y);
  430. CommentOutCode <<
  431. if (Y := get(X, 'InitialPropertyList)) then
  432. PutPrint(X, 'InitialPropertyList, Y);
  433. >>;
  434. if (Y := get(X, 'InitialValue)) then
  435. PutPrint(X, 'InitialValue, Y)
  436. else if FlagP(X, 'NilInitialValue) then
  437. print list('flag, MkQuote list X, '(quote NilInitialValue));
  438. if get(X, 'SCOPE) = 'EXTERNAL then
  439. << PutPrint(X, 'SCOPE, 'EXTERNAL);
  440. PutPrint(X, 'ASMSymbol, get(X, 'ASMSymbol));
  441. if get(X, 'WVar) then PutPrint(X, 'WVar, X)
  442. else if get(X, 'WArray) then PutPrint(X, 'WArray, X)
  443. else if get(X, 'WString) then PutPrint(X, 'WString, X)
  444. else if (Y := get(X, 'WConst)) then PutPrint(X, 'WConst, Y) >>;
  445. end;
  446. lisp procedure FindIDNumber U;
  447. begin scalar I;
  448. return if (I := ID2Int U) <= 128 then I
  449. else if (I := get(U, 'IDNumber)) then I
  450. else
  451. << put(U, 'IDNumber, I := NextIDNumber!*);
  452. OrderedIDList!* := TConc(OrderedIDList!*, U);
  453. NextIDNumber!* := NextIDNumber!* + 1;
  454. I >>;
  455. end;
  456. OrderedIDList!* := NIL . NIL;
  457. NextIDNumber!* := 129;
  458. lisp procedure InitializeSymbolTable();
  459. begin scalar MaxSymbol;
  460. MaxSymbol := get('MaxSymbols, 'WConst);
  461. if MaxSymbol < NextIDNumber!* then
  462. << ErrorPrintF("*** MaxSymbols %r is too small; at least %r is needed",
  463. MaxSymbol, NextIDNumber!*);
  464. MaxSymbol := NextIDNumber!* + 100 >>;
  465. Flag('(NIL), 'NilInitialValue);
  466. put('T, 'InitialValue, 'T);
  467. put('!$EOF!$, 'InitialValue, Int2ID get('EOF, 'CharConst));
  468. put('!$EOL!$, 'InitialValue, '!
  469. );
  470. NilNumber!* := CompileConstant NIL;
  471. DataAlignFullWord();
  472. %/ This is a BUG? M.L. G.
  473. %/ for I := NextIDNumber!* step 1 until MaxSymbol do
  474. %/ DataPrintFullWord NilNumber!*;
  475. InitializeSymVal();
  476. DataReserveBlock((MaxSymbol - NextIDNumber!*) + 1);
  477. InitializeSymPrp();
  478. DataReserveBlock((MaxSymbol - NextIDNumber!*) + 1);
  479. %/ This is a BUG? M.L. G.
  480. %/ for I := NextIDNumber!* step 1 until MaxSymbol do
  481. %/ DataPrintFullWord NilNumber!*;
  482. InitializeSymNam MaxSymbol;
  483. InitializeSymFnc();
  484. DataReserveFunctionCellBlock((MaxSymbol - NextIDNumber!*) + 1);
  485. DataAlignFullWord();
  486. DataPrintGlobalLabel FindGlobalLabel 'NextSymbol;
  487. DataPrintFullWord NextIDNumber!*;
  488. end;
  489. lisp procedure InitializeSymPrp();
  490. << CommentOutCode << InitializeHeap(); >>; % init prop lists
  491. DataPrintGlobalLabel FindGlobalLabel 'SymPrp;
  492. for I := 0 step 1 until 128 do
  493. InitSymPrp1 Int2ID I;
  494. for each X in car OrderedIDList!* do
  495. InitSymPrp1 X >>;
  496. lisp procedure InitSymPrp1 X;
  497. <<
  498. CommentOutCode <<
  499. DataPrintFullWord(if (X := get(X, 'InitialPropertyList)) then
  500. X
  501. else NilNumber!*);
  502. >>;
  503. DataPrintFullWord NilNumber!* >>;
  504. CommentOutCode <<
  505. lisp procedure InitializeHeap();
  506. begin scalar L;
  507. DataPrintGlobalLabel FindGlobalLabel 'Heap;
  508. for I := 0 step 1 until 128 do
  509. PrintPropertyList Int2ID I;
  510. for each X in car OrderedIDList!* do
  511. PrintPropertyList X;
  512. L := get('HeapSize, 'WConst);
  513. end;
  514. >>;
  515. lisp procedure InitializeSymNam MaxSymbol;
  516. << DataPrintGlobalLabel FindGlobalLabel 'SymNam;
  517. for I := 0 step 1 until 128 do
  518. DataPrintFullWord CompileConstant ID2String Int2ID I;
  519. for each IDName in car OrderedIDList!* do
  520. DataPrintFullWord CompileConstant ID2String IDName;
  521. MaxSymbol := MaxSymbol - 1;
  522. for I := NextIDNumber!* step 1 until MaxSymbol do
  523. DataPrintFullWord(I + 1);
  524. DataPrintFullWord 0 >>;
  525. lisp procedure InitializeSymVal();
  526. << DataPrintGlobalLabel FindGlobalLabel 'SymVal;
  527. for I := 0 step 1 until 128 do InitSymVal1 Int2ID I;
  528. for each X in car OrderedIDList!* do InitSymVal1 X >>;
  529. lisp procedure InitSymVal1 X;
  530. begin scalar Val;
  531. return DataPrintFullWord(if (Val := get(X, 'InitialValue)) then
  532. CompileConstant Val
  533. else if FlagP(X, 'NilInitialValue) then
  534. NilNumber!*
  535. else list('MkItem, get('Unbound, 'WConst),
  536. FindIDNumber X));
  537. end;
  538. lisp procedure InitializeSymFnc();
  539. << DataPrintGlobalLabel FindGlobalLabel 'SymFnc;
  540. for I := 0 step 1 until 128 do InitSymFnc1 Int2ID I;
  541. for each X in car OrderedIDList!* do InitSymFnc1 X >>;
  542. lisp procedure InitSymFnc1 X;
  543. begin scalar EP;
  544. EP := get(X, 'EntryPoint);
  545. if null EP then DataPrintUndefinedFunctionCell()
  546. else DataPrintDefinedFunctionCell EP;
  547. end;
  548. lisp procedure ASMOutLap U;
  549. begin scalar LocalLabels!*, OldOut;
  550. U := Pass1Lap U; % Expand cmacros, quoted expressions
  551. CodeBlockHeader();
  552. OldOut := WRS CodeOut!*;
  553. for each X in U do ASMOutLap1 X;
  554. WRS OldOut;
  555. CodeBlockTrailer();
  556. end;
  557. lisp procedure ASMOutLap1 X;
  558. begin scalar Fn;
  559. return if StringP X then PrintLabel X
  560. else if atom X then PrintLabel FindLocalLabel X
  561. else if (Fn := get(car X, 'ASMPseudoOp)) then Apply(Fn, list X)
  562. else
  563. % instruction output form is:
  564. % "space" <opcode> [ "space" <operand> { "comma" <operand> } ] "newline"
  565. << Prin2 '! ; % Space
  566. PrintOpcode car X;
  567. X := cdr X;
  568. if not null X then
  569. << Prin2 '! ; % SPACE
  570. PrintOperand car X;
  571. for each U in cdr X do
  572. << Prin2 '!,; % COMMA
  573. PrintOperand U >> >>;
  574. Prin2 !$EOL!$ >>; % NEWLINE
  575. end;
  576. put('!*Entry, 'ASMPseudoOp, 'ASMPrintEntry);
  577. lisp procedure ASMPrintEntry X;
  578. begin scalar Y;
  579. PrintComment X;
  580. X := cadr X;
  581. Y := FindEntryPoint X;
  582. if not FlagP(X, 'InternalFunction) then FindIDNumber X;
  583. if X eq MainEntryPointName!* then
  584. << !*MainFound := T;
  585. SpecialActionForMainEntryPoint() >>
  586. else CodeDeclareExportedUse Y;
  587. end;
  588. Procedure CodeDeclareExportedUse Y;
  589. if !*DeclareBeforeUse then
  590. << CodeDeclareExported Y;
  591. PrintLabel Y >>
  592. else
  593. << PrintLabel Y;
  594. CodeDeclareExported Y >>;
  595. lisp procedure FindEntryPoint X;
  596. begin scalar E;
  597. return if (E := get(X, 'EntryPoint)) then E
  598. else if ASMSymbolP X and not get(X, 'ASMSymbol) then
  599. << put(X, 'EntryPoint, X);
  600. X >>
  601. else
  602. << E := StringGenSym();
  603. put(X, 'EntryPoint, E);
  604. E >>;
  605. end;
  606. lisp procedure ASMPseudoPrintFloat X;
  607. PrintF(DoubleFloatFormat!*, cadr X);
  608. put('Float, 'ASMPseudoOp, 'ASMPseudoPrintFloat);
  609. lisp procedure ASMPseudoPrintFullWord X;
  610. for each Y in cdr X do PrintFullWord Y;
  611. put('FullWord, 'ASMPseudoOp, 'ASMPseudoPrintFullWord);
  612. lisp procedure ASMPseudoPrintByte X;
  613. PrintByteList cdr X;
  614. put('Byte, 'ASMPseudoOp, 'ASMPseudoPrintByte);
  615. lisp procedure ASMPseudoPrintHalfWord X;
  616. PrintHalfWordList cdr X;
  617. put('HalfWord, 'ASMPseudoOp, 'ASMPseudoPrintHalfWord);
  618. lisp procedure ASMPseudoPrintString X;
  619. PrintString cadr X;
  620. put('String, 'ASMPseudoOp, 'ASMPseudoPrintString);
  621. lisp procedure PrintOperand X;
  622. if StringP X then Prin2 X
  623. else if NumberP X then PrintNumericOperand X
  624. else if IDP X then Prin2 FindLabel X
  625. else begin scalar Hd, Fn;
  626. Hd := car X;
  627. if (Fn := get(Hd, 'OperandPrintFunction)) then
  628. Apply(Fn, list X)
  629. else if (Fn := GetD Hd) and car Fn = 'MACRO then
  630. PrintOperand Apply(cdr Fn, list X)
  631. else if (Fn := WConstEvaluable X) then PrintOperand Fn
  632. else PrintExpression X;
  633. end;
  634. put('REG, 'OperandPrintFunction, 'PrintRegister);
  635. lisp procedure PrintRegister X;
  636. begin scalar Nam;
  637. X := cadr X;
  638. if StringP X then Prin2 X
  639. else if NumberP X then Prin2 GetV(NumericRegisterNames!*, X)
  640. else if Nam := RegisterNameP X then Prin2 Nam
  641. else
  642. << ErrorPrintF("***** Unknown register %r", X);
  643. Prin2 X >>;
  644. end;
  645. lisp procedure RegisterNameP X;
  646. get(X, 'RegisterName);
  647. lisp procedure ASMEntry X;
  648. PrintExpression
  649. list('plus2, 'SymFnc,
  650. list('times2, AddressingUnitsPerFunctionCell,
  651. list('IDLoc, cadr X)));
  652. put('Entry, 'OperandPrintFunction, 'ASMEntry);
  653. lisp procedure ASMInternalEntry X;
  654. Prin2 FindEntryPoint cadr X;
  655. put('InternalEntry, 'OperandPrintFunction, 'ASMInternalEntry);
  656. put('InternalEntry, 'ASMExpressionFunction, 'ASMInternalEntry);
  657. macro procedure ExtraReg U;
  658. list('plus2, '(WArray ArgumentBlock), (cadr U - (LastActualReg!& + 1))
  659. * AddressingUnitsPerItem);
  660. lisp procedure ASMSyslispVarsPrint X;
  661. Prin2 FindGlobalLabel cadr X;
  662. DefList('((WVar ASMSyslispVarsPrint)
  663. (WArray ASMSyslispVarsPrint)
  664. (WString ASMSyslispVarsPrint)), 'OperandPrintFunction);
  665. DefList('((WVar ASMSyslispVarsPrint)
  666. (WArray ASMSyslispVarsPrint)
  667. (WString ASMSyslispVarsPrint)), 'ASMExpressionFunction);
  668. lisp procedure ASMPrintValueCell X;
  669. PrintExpression list('plus2, 'SymVal,
  670. list('times, AddressingUnitsPerItem,
  671. list('IDLoc, cadr X)));
  672. DefList('((fluid ASMPrintValueCell)
  673. (!$fluid ASMPrintValueCell)
  674. (global ASMPrintValueCell)
  675. (!$global ASMPrintValueCell)), 'OperandPrintFunction);
  676. % Redefinition of WDeclare for output to assembler file
  677. % if either UpperBound or Initializer are NIL, they are considered to be
  678. % unspecified.
  679. fexpr procedure WDeclare U;
  680. for each X in cddr U do WDeclare1(car X, car U, cadr U, cadr X, caddr X);
  681. flag('(WDeclare), 'IGNORE);
  682. lisp procedure WDeclare1(Name, Scope, Typ, UpperBound, Initializer);
  683. if Typ = 'WCONST then
  684. if Scope = 'EXTERNAL and not get(Name, 'WCONST) then
  685. ErrorPrintF("*** A value has not been defined for WConst %r",
  686. Name)
  687. else
  688. << put(Name, 'SCOPE, if Scope = 'EXPORTED then 'EXTERNAL else Scope);
  689. put(Name, 'WCONST, WConstReform Initializer) >>
  690. else
  691. << put(Name, Typ, Name);
  692. if Scope = 'EXTERNAL then
  693. << put(Name, 'SCOPE, 'EXTERNAL);
  694. if not RegisterNameP Name then % kludge to avoid declaring
  695. << Name := LookupOrAddASMSymbol Name;
  696. DataDeclareExternal Name; % registers as variables
  697. CodeDeclareExternal Name >> >>
  698. else
  699. << put(Name, 'SCOPE, if Scope = 'EXPORTED then 'EXTERNAL else Scope);
  700. Name := LookupOrAddASMSymbol Name;
  701. if !*DeclareBeforeUse then DataDeclareExported Name;
  702. DataInit(Name,
  703. Typ,
  704. UpperBound,
  705. Initializer);
  706. if not !*DeclareBeforeUse then DataDeclareExported Name;
  707. CodeDeclareExternal Name >> >>;
  708. lisp procedure DataInit(ASMSymbol, Typ, UpperBound, Initializer);
  709. << DataAlignFullWord();
  710. if Typ = 'WVAR then
  711. << if UpperBound then
  712. ErrorPrintF "*** An UpperBound may not be specified for a WVar";
  713. Initializer := if Initializer then WConstReform Initializer else 0;
  714. DataPrintVar(ASMSymbol, Initializer) >>
  715. else
  716. << if UpperBound and Initializer then
  717. ErrorPrintF "*** Can't have both UpperBound and initializer"
  718. else if not (UpperBound or Initializer) then
  719. ErrorPrintF "*** Must have either UpperBound or initializer"
  720. else if UpperBound then
  721. DataPrintBlock(ASMSymbol, WConstReform UpperBound, Typ)
  722. else
  723. << Initializer := if StringP Initializer then Initializer
  724. else WConstReformLis Initializer;
  725. DataPrintList(ASMSymbol, Initializer, Typ) >> >> >>;
  726. lisp procedure WConstReform U;
  727. begin scalar X;
  728. return if FixP U or StringP U then U
  729. else if IDP U then
  730. if get(U, 'WARRAY) or get(U, 'WSTRING) then U
  731. else if get(U,'WVAR) then list('GETMEM,U)
  732. else if (X := get(U, 'WCONST)) then X
  733. else ErrorPrintF("*** Unknown symbol %r in WConstReform", U)
  734. else if PairP U then
  735. if (X := get(car U, 'WConstReformPseudo)) then Apply(X, list U)
  736. else if (X := get(car U, 'DOFN)) then X . WConstReformLis cdr U
  737. else if MacroP car U then WConstReform Apply(cdr GetD car U, list U)
  738. else car U . WConstReformLis cdr U
  739. else ErrorPrintF("*** Illegal expression %r in WConstReform", U);
  740. end;
  741. lisp procedure WConstReformIdent U;
  742. U;
  743. put('InternalEntry, 'WConstReformPseudo, 'WConstReformIdent);
  744. lisp procedure WConstReformQuote U;
  745. CompileConstant cadr U;
  746. put('QUOTE, 'WConstReformPseudo, 'WConstReformQuote);
  747. lisp procedure WConstReformLis U;
  748. for each X in U collect WConstReform X;
  749. lisp procedure WConstReformLoc U; %. To handle &Foo[23]
  750. << U := WConstReform cadr U;
  751. if car U neq 'GETMEM then
  752. ErrorPrintF("*** Illegal constant addressing expression %r",
  753. list('LOC, U))
  754. else cadr U >>;
  755. put('LOC, 'WConstReformPseudo, 'WConstReformLoc);
  756. lisp procedure WConstReformIDLoc U;
  757. FindIDNumber cadr U;
  758. put('IDLoc, 'WConstReformPseudo, 'WConstReformIDLoc);
  759. lisp procedure LookupOrAddASMSymbol U;
  760. begin scalar X;
  761. if not (X := get(U, 'ASMSymbol)) then X := AddASMSymbol U;
  762. return X;
  763. end;
  764. lisp procedure AddASMSymbol U;
  765. begin scalar X;
  766. X := if ASMSymbolP U and not get(U, 'EntryPoint) then U
  767. else StringGensym();
  768. put(U, 'ASMSymbol, X);
  769. return X;
  770. end;
  771. lisp procedure DataPrintVar(Name, Init);
  772. begin scalar OldOut;
  773. DataPrintLabel Name;
  774. OldOut := WRS DataOut!*;
  775. PrintFullWord Init;
  776. WRS OldOut;
  777. end;
  778. lisp procedure DataPrintBlock(Name, Siz, Typ);
  779. << if Typ = 'WSTRING
  780. then Siz := list('quotient, list('plus2, Siz, CharactersPerWord + 1),
  781. CharactersPerWord)
  782. else Siz := list('plus2, Siz, 1);
  783. DataReserveZeroBlock(Name, Siz) >>;
  784. lisp procedure DataPrintList(Nam, Init, Typ);
  785. begin scalar OldOut;
  786. DataPrintLabel Nam;
  787. OldOut := WRS DataOut!*;
  788. if Typ = 'WSTRING then
  789. if StringP Init then
  790. << PrintFullWord Size Init;
  791. PrintString Init >>
  792. else
  793. << PrintFullWord(Length Init - 1);
  794. PrintByteList Append(Init, '(0)) >>
  795. else
  796. if StringP Init then begin scalar S;
  797. S := Size Init;
  798. for I := 0 step 1 until S do
  799. PrintFullWord Indx(Init, I);
  800. end else for each X in Init do
  801. PrintFullWord X;
  802. WRS OldOut;
  803. end;
  804. lisp procedure DataPrintGlobalLabel X;
  805. << if !*DeclareBeforeUse then DataDeclareExported X;
  806. DataPrintLabel X;
  807. if not !*DeclareBeforeUse then DataDeclareExported X;
  808. CodeDeclareExternal X >>;
  809. lisp procedure DataDeclareExternal X;
  810. if not (X member DataExternals!* or X member DataExporteds!*) then
  811. << DataExternals!* := X . DataExternals!*;
  812. DataPrintF(ExternalDeclarationFormat!*, X, X) >>;
  813. lisp procedure CodeDeclareExternal X;
  814. if not (X member CodeExternals!* or X member CodeExporteds!*) then
  815. << CodeExternals!* := X . CodeExternals!*;
  816. CodePrintF(ExternalDeclarationFormat!*, X, X) >>;
  817. lisp procedure DataDeclareExported X;
  818. << if X member DataExternals!* or X member DataExporteds!* then
  819. ErrorPrintF("***** %r multiply defined", X);
  820. DataExporteds!* := X . DataExporteds!*;
  821. DataPrintF(ExportedDeclarationFormat!*, X, X) >>;
  822. lisp procedure CodeDeclareExported X;
  823. << if X member CodeExternals!* or X member CodeExporteds!* then
  824. ErrorPrintF("***** %r multiply defined", X);
  825. CodeExporteds!* := X . CodeExporteds!*;
  826. CodePrintF(ExportedDeclarationFormat!*, X, X) >>;
  827. lisp procedure PrintLabel X;
  828. PrintF(LabelFormat!*, X,X);
  829. lisp procedure DataPrintLabel X;
  830. DataPrintF(LabelFormat!*, X,X);
  831. lisp procedure CodePrintLabel X;
  832. CodePrintF(LabelFormat!*, X,X);
  833. lisp procedure PrintComment X;
  834. PrintF(CommentFormat!*, X);
  835. PrintExpressionForm!* := list('PrintExpression, MkQuote NIL);
  836. PrintExpressionFormPointer!* := cdadr PrintExpressionForm!*;
  837. % Save some consing
  838. % instead of list('PrintExpression, MkQuote X), reuse the same list structure
  839. lisp procedure PrintFullWord X;
  840. << RplacA(PrintExpressionFormPointer!*, X);
  841. PrintF(FullWordFormat!*, PrintExpressionForm!*) >>;
  842. lisp procedure DataPrintFullWord X;
  843. << RplacA(PrintExpressionFormPointer!*, X);
  844. DataPrintF(FullWordFormat!*, PrintExpressionForm!*) >>;
  845. lisp procedure CodePrintFullWord X;
  846. << RplacA(PrintExpressionFormPointer!*, X);
  847. CodePrintF(FullWordFormat!*, PrintExpressionForm!*) >>;
  848. lisp procedure DataReserveZeroBlock(Nam, X);
  849. << RplacA(PrintExpressionFormPointer!*,
  850. list('Times2, AddressingUnitsPerItem, X));
  851. DataPrintF(ReserveZeroBlockFormat!*, Nam, PrintExpressionForm!*) >>;
  852. lisp procedure DataReserveBlock X;
  853. << RplacA(PrintExpressionFormPointer!*,
  854. list('Times2, AddressingUnitsPerItem, X));
  855. DataPrintF(ReserveDataBlockFormat!*, PrintExpressionForm!*) >>;
  856. lisp procedure DataReserveFunctionCellBlock X;
  857. << RplacA(PrintExpressionFormPointer!*,
  858. list('Times2, AddressingUnitsPerFunctionCell, X));
  859. DataPrintF(ReserveDataBlockFormat!*, PrintExpressionForm!*) >>;
  860. lisp procedure DataPrintUndefinedFunctionCell();
  861. begin scalar OldOut;
  862. OldOut := WRS DataOut!*;
  863. for each X in UndefinedFunctionCellInstructions!* do
  864. ASMOutLap1 X;
  865. WRS OldOut;
  866. end;
  867. lisp procedure DataPrintDefinedFunctionCell X;
  868. <<DataDeclareExternal X;
  869. DataPrintF(DefinedFunctionCellFormat!*, X, X)>>;
  870. % in case it's needed twice
  871. lisp procedure DataPrintByteList X;
  872. begin scalar OldOut;
  873. OldOut := WRS DataOut!*;
  874. PrintByteList X;
  875. WRS OldOut;
  876. end;
  877. lisp procedure DataPrintExpression X;
  878. begin scalar OldOut;
  879. OldOut := WRS DataOut!*;
  880. PrintExpression X;
  881. WRS OldOut;
  882. end;
  883. lisp procedure CodePrintExpression X;
  884. begin scalar OldOut;
  885. OldOut := WRS CodeOut!*;
  886. PrintExpression X;
  887. WRS OldOut;
  888. end;
  889. ExpressionCount!* := -1;
  890. lisp procedure PrintExpression X;
  891. (lambda(ExpressionCount!*);
  892. begin scalar Hd, Tl, Fn;
  893. X := ResolveWConstExpression X;
  894. if NumberP X or StringP X then Prin2 X
  895. else if IDP X then Prin2 FindLabel X
  896. else if atom X then
  897. << ErrorPrintF("***** Oddity in expression %r", X);
  898. Prin2 X >>
  899. else
  900. << Hd := car X;
  901. Tl := cdr X;
  902. if (Fn := get(Hd, 'BinaryASMOp)) then
  903. << if ExpressionCount!* > 0 then Prin2 ASMOpenParen!*;
  904. PrintExpression car Tl;
  905. Prin2 Fn;
  906. PrintExpression cadr Tl;
  907. if ExpressionCount!* > 0 then Prin2 ASMCloseParen!* >>
  908. else if (Fn := get(Hd, 'UnaryASMOp)) then
  909. << Prin2 Fn;
  910. PrintExpression car Tl >>
  911. else if (Fn := get(Hd, 'ASMExpressionFormat)) then
  912. Apply('PrintF, Fn . for each Y in Tl collect
  913. list('PrintExpression, MkQuote Y))
  914. else if (Fn := GetD Hd) and car Fn = 'MACRO then
  915. PrintExpression Apply(cdr Fn, list X)
  916. else if (Fn := get(Hd, 'ASMExpressionFunction)) then
  917. Apply(Fn, list X)
  918. else
  919. << ErrorPrintF("***** Unknown expression %r", X);
  920. PrintF("*** Expression error %r ***", X) >> >>;
  921. end)(ExpressionCount!* + 1);
  922. lisp procedure ASMPrintWConst U;
  923. PrintExpression cadr U;
  924. put('WConst, 'ASMExpressionFunction, 'ASMPrintWConst);
  925. DefList('((Plus2 !+)
  926. (WPlus2 !+)
  927. (Difference !-)
  928. (WDifference !-)
  929. (Times2 !*)
  930. (WTimes2 !*)
  931. (Quotient !/)
  932. (WQuotient !/)), 'BinaryASMOp);
  933. DefList('((Minus !-)
  934. (WMinus !-)), 'UnaryASMOp);
  935. lisp procedure CompileConstant X;
  936. << X := BuildConstant X;
  937. if null cdr X then car X
  938. else
  939. << If !*DeclareBeforeUse then CodeDeclareExported cadr X;
  940. ASMOutLap cdr X;
  941. DataDeclareExternal cadr X;
  942. If Not !*DeclareBeforeUse then CodeDeclareExported cadr X;
  943. car X >> >>;
  944. CommentOutCode <<
  945. lisp procedure CompileHeapData X;
  946. begin scalar Y;
  947. X := BuildConstant X;
  948. return if null cdr X then car X
  949. else
  950. << Y := WRS DataOut!*;
  951. for each Z in cdr X do ASMOutLap1 Z;
  952. DataDeclareExported cadr X;
  953. WRS Y;
  954. car X >>;
  955. end;
  956. >>;
  957. lisp procedure DataPrintString X;
  958. begin scalar OldOut;
  959. OldOut := WRS DataOut!*;
  960. PrintString X;
  961. WRS OldOut;
  962. end;
  963. lisp procedure FindLabel X;
  964. begin scalar Y;
  965. return if (Y := Atsoc(X, LocalLabels!*)) then cdr Y
  966. else if (Y := get(X, 'ASMSymbol)) then Y
  967. else if (Y := get(X, 'WConst)) then Y
  968. else FindLocalLabel X;
  969. end;
  970. lisp procedure FindLocalLabel X;
  971. begin scalar Y;
  972. return if (Y := Atsoc(X, LocalLabels!*)) then cdr Y
  973. else
  974. << LocalLabels!* := (X . (Y := StringGensym())) . LocalLabels!*;
  975. Y >>;
  976. end;
  977. lisp procedure FindGlobalLabel X;
  978. get(X, 'ASMSymbol) or ErrorPrintF("***** Undefined symbol %r", X);
  979. lisp procedure CodePrintF(Fmt, A1, A2, A3, A4);
  980. begin scalar OldOut;
  981. OldOut := WRS CodeOut!*;
  982. PrintF(Fmt, A1, A2, A3, A4);
  983. WRS OldOut;
  984. end;
  985. lisp procedure DataPrintF(Fmt, A1, A2, A3, A4);
  986. begin scalar OldOut;
  987. OldOut := WRS DataOut!*;
  988. PrintF(Fmt, A1, A2, A3, A4);
  989. WRS OldOut;
  990. end;
  991. % Kludge of the year, just to avoid having IDLOC defined during compilation
  992. CompileTime fluid '(MACRO);
  993. MACRO := 'MACRO;
  994. PutD('IDLoc, MACRO,
  995. function lambda X;
  996. FindIDNumber cadr X);
  997. END;