read.c 137 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581
  1. /* read.c Copyright (C) 1990-1996 Codemist Ltd */
  2. /*
  3. * Reading and symbol-table support.
  4. */
  5. /* Signature: 69447962 12-Mar-2000 */
  6. #include <stdarg.h>
  7. #include <string.h>
  8. #include <ctype.h>
  9. #ifdef __WATCOMC__
  10. #include <float.h>
  11. #endif
  12. #include "machine.h"
  13. #include "tags.h"
  14. #include "cslerror.h"
  15. #include "externs.h"
  16. #include "read.h"
  17. #include "stream.h"
  18. #include "arith.h"
  19. #include "entries.h"
  20. #ifdef COMMON
  21. #include "clsyms.h"
  22. #endif
  23. #ifdef TIMEOUT
  24. #include "timeout.h"
  25. #endif
  26. #ifdef SOCKETS
  27. #include "sockhdr.h"
  28. #endif
  29. #define CTRL_C 3
  30. #define CTRL_D 4
  31. #ifdef Kanji
  32. #define ISalpha(a) iswalpha(a)
  33. #define ISdigit(a) iswdigit(a)
  34. #define ISspace(a) iswspace(a)
  35. #define TOupper(a) towupper(a)
  36. #define TOlower(a) towlower(a)
  37. int first_char(Lisp_Object ch)
  38. { /* ch is a symbol. Get the first character of its name. */
  39. int n;
  40. ch = qpname(ch);
  41. n = celt(ch, 0);
  42. if (is2byte(n) && length_of_header(vechdr(ch)) != CELL)
  43. n = (n << 8) + ucelt(ch, 1);
  44. return n;
  45. }
  46. #else /* Kanji */
  47. #define ISalpha(a) isalpha(a)
  48. #define ISdigit(a) isdigit(a)
  49. #define ISspace(a) isspace(a)
  50. #define TOupper(a) toupper(a)
  51. #define TOlower(a) tolower(a)
  52. #define first_char(ch) ucelt(qpname(ch), 0)
  53. #endif /* Kanji */
  54. /*
  55. * Basic version of Lisp reader.
  56. */
  57. static int curchar = NOT_CHAR;
  58. FILE *non_terminal_input;
  59. static int boffop;
  60. #define boffo_char(i) ucelt(boffo, i)
  61. Lisp_Object make_string(char *b)
  62. /*
  63. * Given a C string, create a Lisp (simple-) string.
  64. */
  65. {
  66. int32 n = strlen(b);
  67. Lisp_Object r = getvector(TAG_VECTOR, TYPE_STRING, CELL+n);
  68. char *s = (char *)r - TAG_VECTOR;
  69. int32 k = (n + 3) & ~(int32)7;
  70. Lisp_Object nil;
  71. errexit();
  72. /* Here I go to some trouble to zero out the last doubleword of the vector */
  73. #ifdef ADDRESS_64
  74. if (k != 0)
  75. { *(int32 *)(s + k + 4) = 0;
  76. *(int32 *)(s + k) = 0;
  77. }
  78. #else
  79. *(int32 *)(s + k + 4) = 0;
  80. if (k != 0) *(int32 *)(s + k) = 0;
  81. #endif
  82. memcpy(s + CELL, b, (size_t)n);
  83. return r;
  84. }
  85. static Lisp_Object copy_string(Lisp_Object str, int32 n)
  86. /*
  87. * Given a Lisp string, plus its length, create a Lisp (simple-) string.
  88. */
  89. {
  90. Lisp_Object nil, r;
  91. char *s;
  92. int32 k;
  93. push(str);
  94. r = getvector(TAG_VECTOR, TYPE_STRING, CELL+n);
  95. pop(str);
  96. s = (char *)r - TAG_VECTOR;
  97. k = (n + 3) & ~(int32)7;
  98. errexit();
  99. /* Here I go to some trouble to zero out the last doubleword of the vector */
  100. #ifdef ADDRESS_64
  101. if (k != 0)
  102. { *(int32 *)(s + k + 4) = 0;
  103. *(int32 *)(s + k) = 0;
  104. }
  105. #else
  106. *(int32 *)(s + k + 4) = 0;
  107. if (k != 0) *(int32 *)(s + k) = 0;
  108. #endif
  109. memcpy(s + CELL, (char *)str + (CELL-TAG_VECTOR), (size_t)n);
  110. return r;
  111. }
  112. Lisp_Object MS_CDECL Lbatchp(Lisp_Object nil, int nargs, ...)
  113. {
  114. CSL_IGNORE(nil);
  115. argcheck(nargs, 0, "batchp");
  116. #ifdef SOCKETS
  117. /*
  118. * If CSL is being run as a service (ie accessed via a socket) then I will
  119. * deem it to be in "interactive" mode. This leaves responsibility for stopping
  120. * after errors (if that is what is wanted) with the other end of the
  121. * communications link.
  122. */
  123. if (socket_server != 0) return onevalue(nil);
  124. #endif
  125. /*
  126. * If the user had specified input files on the command line I will say that
  127. * we are in batch mode even if there is a terminal present somewhere. So
  128. * a run of the form
  129. * csl inputfile.lsp
  130. * is a "batch" run, while
  131. * csl < inputfile.lsp
  132. * will MAYBE also be noticed as batch, but do not count on it!
  133. */
  134. if (non_terminal_input != NULL)
  135. return onevalue(batch_flag ? nil : lisp_true);
  136. /*
  137. * "sysxxx.c" now decides if we are in "batch processing" context,
  138. * in general by asking "isatty(fileno(stdin))" to see if stdin is
  139. * attached to an interactive terminal. Ideally this will say we are in
  140. * batch mode if the user has redirected input from a file, as in
  141. * csl < xxx.lsp
  142. * but catching such cases may be HARD with some operating systems.
  143. * With some operating systems we will NEVER report ourselves as "batch".
  144. */
  145. return onevalue(Lispify_predicate(batch_flag ? !batchp : batchp()));
  146. }
  147. Lisp_Object Lgetenv(Lisp_Object nil, Lisp_Object a)
  148. {
  149. char parmname[LONGEST_LEGAL_FILENAME];
  150. Header h;
  151. Lisp_Object r;
  152. int32 len;
  153. char *w;
  154. #ifdef COMMON
  155. if (complex_stringp(a))
  156. { a = simplify_string(a);
  157. errexit();
  158. }
  159. #endif
  160. if (symbolp(a))
  161. { a = get_pname(a);
  162. errexit();
  163. h = vechdr(a);
  164. }
  165. else if (!is_vector(a) ||
  166. type_of_header(h = vechdr(a)) != TYPE_STRING)
  167. return aerror1("getenv", a);
  168. len = length_of_header(h) - CELL;
  169. memcpy(parmname, (char *)a + (CELL-TAG_VECTOR), (size_t)len);
  170. parmname[len] = 0;
  171. w = my_getenv(parmname);
  172. if (w == NULL) return onevalue(nil); /* not available */
  173. r = make_string(w);
  174. errexit();
  175. return onevalue(r);
  176. }
  177. Lisp_Object Lsystem(Lisp_Object nil, Lisp_Object a)
  178. {
  179. char parmname[LONGEST_LEGAL_FILENAME];
  180. Header h;
  181. int32 len;
  182. int w;
  183. #ifdef SOCKETS
  184. /*
  185. * Security measure - remote client can not do "system"
  186. */
  187. if (socket_server != 0) return onevalue(nil);
  188. #endif
  189. if (a == nil) /* enquire if command processor is available */
  190. { w = my_system(NULL);
  191. return onevalue(Lispify_predicate(w != 0));
  192. }
  193. #ifdef COMMON
  194. if (complex_stringp(a))
  195. { a = simplify_string(a);
  196. errexit();
  197. }
  198. #endif
  199. if (symbolp(a))
  200. { a = get_pname(a);
  201. errexit();nil = C_nil;
  202. h = vechdr(a);
  203. }
  204. else if (!is_vector(a) ||
  205. type_of_header(h = vechdr(a)) != TYPE_STRING)
  206. return aerror1("system", a);
  207. len = length_of_header(h) - CELL;
  208. memcpy(parmname, (char *)a + (CELL-TAG_VECTOR), (size_t)len);
  209. parmname[len] = 0;
  210. w = my_system(parmname);
  211. return onevalue(fixnum_of_int((int32)w));
  212. }
  213. static unsigned32 hash_lisp_string_with_length(Lisp_Object s, int32 n)
  214. {
  215. /*
  216. * I start off the hash calculation with something that depends on the
  217. * length of the string n.
  218. */
  219. unsigned32 hh = 0x01000000 + n;
  220. unsigned32 *b = (unsigned32 *)((char *)s + (CELL-TAG_VECTOR));
  221. char *b1;
  222. while (n >= 8) /* Do as much as is possible word at a time */
  223. {
  224. unsigned32 temp;
  225. /*
  226. * The next few lines take a 32-bit value with digits PQRS and for a value
  227. * with digits Q^R and P^Q^R^S. Note that this is invariant under the change
  228. * to SRQP, and thus even though I fetched a whole word and the order of bytes
  229. * in that word is hard to know the hash value will not depend on the byte
  230. * order involved. By that time I have done all this and thereby lost any
  231. * chance of ABCD and DCBA not clashing maybe a simple byte at a time hash
  232. * procedure would have been more sense? Some day I should take comparative
  233. * timings and measurements of hash-table conflicts.
  234. */
  235. unsigned32 a = *b++; /* P Q R S */
  236. a = a ^ (a << 8); /* P^Q Q^R R^S S */
  237. a = a ^ (a >> 16); /* P^Q Q^R P^Q^R^S Q^R^S */
  238. a = a << 8; /* Q^R P^Q^R^S Q^R^S 0 */
  239. /*
  240. * And now compute a hash value using a CRC that has a period of
  241. * 0x7fffffff (i.e. maximum period in 31 bits). And at least if shift
  242. * operations are cheap on your computer it can be evaluated rapidly as well.
  243. */
  244. temp = hh << 7;
  245. hh = ((hh >> 25) ^
  246. (temp >> 1) ^
  247. (temp >> 4) ^
  248. (a >> 16)) & 0x7fffffff;
  249. n -= 4;
  250. }
  251. b1 = (char *)b;
  252. /*
  253. * Finish off the hash value byte-at-a-time. If I could be certain that
  254. * strings being hashed would always be zero-padded in their last word I
  255. * could avoid the need for this, but at present I can not.
  256. */
  257. while (n > 4)
  258. { unsigned32 temp;
  259. temp = hh << 7;
  260. hh = ((hh >> 25) ^
  261. (temp >> 1) ^
  262. (temp >> 4) ^
  263. (unsigned32)*b1++) & 0x7fffffff;
  264. n -= 1;
  265. }
  266. /*
  267. * At the end I multiply by 139 so that at least symbols that differ
  268. * by just having adjacent last letters will be better spread out.
  269. */
  270. return ((139*hh) & 0x7fffffff);
  271. }
  272. unsigned32 hash_lisp_string(Lisp_Object s)
  273. /*
  274. * Argument is a (lisp) string. Return a 31 bit hash value.
  275. */
  276. {
  277. return hash_lisp_string_with_length(s, length_of_header(vechdr(s)));
  278. }
  279. static int value_in_radix(int c, int radix)
  280. {
  281. if (ISdigit(c)) c = c - '0'; /* Assumes digit codes are consecutive */
  282. /*
  283. * The next section tries hard not to depend on any particular character
  284. * code - this may slow it down a little bit but reading numbers that
  285. * have an explicit radix will not usually matter that much.
  286. */
  287. else if (ISalpha(c))
  288. { char *v = "abcdefghijklmnopqrstuvwxyz";
  289. int n = 0;
  290. c = tolower(c);
  291. while (*v++ != c)
  292. if (++n >= 26) return -1; /* break on unrecognized letter */
  293. c = n + 10;
  294. }
  295. else return -1;
  296. if (c < radix) return c;
  297. else return -1;
  298. }
  299. Lisp_Object intern(int len, CSLbool escaped)
  300. /*
  301. * This takes whatever is in the first len characters of
  302. * the Lisp string boffo, and maps it into a number, string
  303. * or symbol as relevant.
  304. */
  305. {
  306. int i, numberp = escaped ? -1 : 0;
  307. #ifdef COMMON
  308. int fplength = 2, explicit_fp_format = 0;
  309. #endif
  310. Lisp_Object nil = C_nil;
  311. stackcheck0(0);
  312. for (i=0; i<len; i++)
  313. { int c = boffo_char(i);
  314. switch (numberp)
  315. {
  316. default:
  317. break;
  318. case 0:
  319. if (c == '+' | c == '-')
  320. { numberp = 1;
  321. continue;
  322. }
  323. /* drop through */
  324. case 1:
  325. if (c == '.')
  326. { numberp = 6;
  327. continue;
  328. }
  329. if (ISdigit(c)) /* Really wants to inspect *read-base* */
  330. { numberp = 2;
  331. continue;
  332. }
  333. numberp = -1;
  334. break;
  335. case 2:
  336. if (ISdigit(c)) continue; /* *read-base* */
  337. switch (c)
  338. {
  339. #ifdef COMMON
  340. case '/': numberp = 3; continue;
  341. #endif
  342. case '.': numberp = 5; continue;
  343. case 'e': case 'E':
  344. /*
  345. * in CSL mode I will read all floating point numbers as if they had been
  346. * double-precision, so I disable recognition of s,f,d and l exponent
  347. * markers and force the length. In Common Lisp mode I have to look at the
  348. * value of *read-default-float-format* to see what to do.
  349. */
  350. numberp = 9;
  351. continue;
  352. #ifdef COMMON
  353. case 's': case 'S':
  354. boffo_char(i) = 'e';
  355. explicit_fp_format = 1;
  356. fplength = 0;
  357. numberp = 9;
  358. continue;
  359. case 'f': case 'F':
  360. boffo_char(i) = 'e';
  361. explicit_fp_format = 1;
  362. fplength = 1;
  363. numberp = 9;
  364. continue;
  365. case 'd': case 'D':
  366. boffo_char(i) = 'e';
  367. explicit_fp_format = 1;
  368. numberp = 9;
  369. continue;
  370. case 'l': case 'L':
  371. boffo_char(i) = 'e';
  372. explicit_fp_format = 1;
  373. fplength = 3;
  374. numberp = 9;
  375. continue;
  376. #endif
  377. default:
  378. numberp = -1;
  379. break;
  380. }
  381. break;
  382. #ifdef COMMON
  383. case 3:
  384. case 4:
  385. if (ISdigit(c)) /* *read-base* */
  386. { numberp = 4;
  387. continue;
  388. }
  389. numberp = -1;
  390. break;
  391. #endif
  392. case 5:
  393. case 8:
  394. if (ISdigit(c))
  395. { numberp = 8;
  396. continue;
  397. }
  398. switch (c)
  399. {
  400. case 'e': case 'E':
  401. numberp = 9;
  402. continue;
  403. #ifdef COMMON
  404. case 's': case 'S':
  405. /* Clobbering the string is a DISASTER if it is not in fact numeric */
  406. boffo_char(i) = 'e';
  407. explicit_fp_format = 1;
  408. fplength = 0;
  409. numberp = 9;
  410. continue;
  411. case 'f': case 'F':
  412. boffo_char(i) = 'e';
  413. explicit_fp_format = 1;
  414. fplength = 1;
  415. numberp = 9;
  416. continue;
  417. case 'd': case 'D':
  418. boffo_char(i) = 'e';
  419. explicit_fp_format = 1;
  420. numberp = 9;
  421. continue;
  422. case 'l': case 'L':
  423. boffo_char(i) = 'e';
  424. explicit_fp_format = 1;
  425. fplength = 3;
  426. numberp = 9;
  427. continue;
  428. #endif
  429. default:
  430. numberp = -1;
  431. break;
  432. }
  433. break;
  434. case 6:
  435. if (ISdigit(c))
  436. { numberp = 8;
  437. continue;
  438. }
  439. numberp = -1;
  440. break;
  441. case 9:
  442. if (c == '+' || c == '-')
  443. { numberp = 10;
  444. continue;
  445. }
  446. /* Drop through */
  447. case 10:
  448. case 11:
  449. if (ISdigit(c))
  450. { numberp = 11;
  451. continue;
  452. }
  453. numberp = -1;
  454. break;
  455. }
  456. break;
  457. }
  458. /* Here the item has been scanned, and it is known if it is numeric! */
  459. switch (numberp)
  460. {
  461. default:
  462. /* Not a number... look up in package system */
  463. #ifdef COMMON
  464. if (!escaped && boffo_char(0) == ':')
  465. { int i = 0;
  466. for (i = 0; i<boffop; i++) boffo_char(i) = boffo_char(i+1);
  467. boffop--;
  468. return iintern(boffo, (int32)boffop, qvalue(keyword_package), 0);
  469. }
  470. #endif
  471. return iintern(boffo, (int32)boffop, CP, 0);
  472. case 5: /* Integer written as 12345. */
  473. boffo_char(--boffop) = 0; /* ... trim off the trailing dot */
  474. /* drop through */
  475. case 2:
  476. /*
  477. * I speed up reading by working 7 digits at a time (using C integer
  478. * arithmetic to gobble them) and only resorting to Lisp generic
  479. * arithmetic to combine the chunks.
  480. */
  481. if (boffo_char(0) == '+')
  482. { int i = 0;
  483. for (i = 0; i<boffop; i++) boffo_char(i) = boffo_char(i+1);
  484. boffop--;
  485. }
  486. { Lisp_Object v = fixnum_of_int(0);
  487. CSLbool sign = NO;
  488. int32 d = 0, d1 = 10;
  489. for (i=0; i<boffop; i++)
  490. { if (i==0 && boffo_char(i) == '-') sign = YES;
  491. else if (d1 == 10000000 || i == boffop-1)
  492. { d = 10*d + (int32)value_in_radix(boffo_char(i), 10);
  493. v = times2(v, fixnum_of_int(d1));
  494. errexit();
  495. v = plus2(v, fixnum_of_int(d));
  496. d = 0;
  497. d1 = 10;
  498. errexit();
  499. }
  500. else
  501. { d = 10*d + (int32)value_in_radix(boffo_char(i), 10);
  502. d1 = 10*d1;
  503. }
  504. }
  505. if (sign) v = negate(v);
  506. return v;
  507. }
  508. #ifdef COMMON
  509. case 4:
  510. { int p, q, g;
  511. Lisp_Object r;
  512. /* Beware bignum issue here... but take view that ratios are not used! */
  513. boffo_char(boffop) = 0;
  514. /* p and q were made int not int32 to match up with the %d in scanf ... */
  515. sscanf((char *)&boffo_char(0), "%d/%d", &p, &q);
  516. /* Limit myself to fixnums here */
  517. g = (int)int_of_fixnum(gcd(fixnum_of_int((int32)p),
  518. fixnum_of_int((int32)q)));
  519. p /= g;
  520. q /= g;
  521. if (q < 0)
  522. { p = -p;
  523. q = -q;
  524. }
  525. r = getvector(TAG_NUMBERS, TYPE_RATNUM, sizeof(Rational_Number));
  526. errexit();
  527. numerator(r) = fixnum_of_int((int32)p);
  528. denominator(r) = fixnum_of_int((int32)q);
  529. return r;
  530. }
  531. #endif
  532. case 8:
  533. case 11:
  534. { double d;
  535. Lisp_Object r;
  536. #ifdef COMMON
  537. float f;
  538. if (!explicit_fp_format && is_symbol(read_float_format))
  539. { Lisp_Object w = qvalue(read_float_format);
  540. if (w == short_float) fplength = 0;
  541. else if (w == single_float) fplength = 1;
  542. /* else if (w == double_float) fplength = 2; */
  543. else if (w == long_float) fplength = 3;
  544. }
  545. #endif
  546. boffo_char(boffop) = 0;
  547. d = atof((char *)&boffo_char(0));
  548. #ifdef COMMON
  549. switch (fplength)
  550. {
  551. case 0:
  552. { Float_union ff;
  553. ff.f = (float)d;
  554. return TAG_SFLOAT + (ff.i & ~(int32)0xf);
  555. }
  556. case 1:
  557. f = (float)d;
  558. r = getvector(TAG_BOXFLOAT, TYPE_SINGLE_FLOAT,
  559. sizeof(Single_Float));
  560. errexit();
  561. single_float_val(r) = f;
  562. return r;
  563. default:
  564. /* case 2: case 3: */
  565. r = getvector(TAG_BOXFLOAT, TYPE_DOUBLE_FLOAT,
  566. sizeof(Double_Float));
  567. errexit();
  568. double_float_val(r) = d;
  569. return r;
  570. }
  571. #else
  572. /*
  573. * Only support double precision in CSL mode
  574. */
  575. r = getvector(TAG_BOXFLOAT, TYPE_DOUBLE_FLOAT,
  576. sizeof(Double_Float));
  577. errexit();
  578. double_float_val(r) = d;
  579. return r;
  580. #endif
  581. }
  582. }
  583. }
  584. Lisp_Object make_undefined_symbol(char const *s)
  585. {
  586. return make_symbol(s, 0, undefined1, undefined2, undefinedn);
  587. }
  588. Lisp_Object make_symbol(char const *s, int restartp,
  589. one_args *f1, two_args *f2, n_args *fn)
  590. /*
  591. * Used from the startup code to create an interned symbol and (maybe)
  592. * put something in its function cell.
  593. */
  594. {
  595. Lisp_Object v, nil = C_nil;
  596. int first_try = 1;
  597. /*
  598. * Here I blandly assume that boffo is long enough to hold the string
  599. * that I am about to copy into it. All is guaranteed well for
  600. * symbols predefined in Lisp in the normal way, but ones established
  601. * using command-line options like -Dname could cause trouble?
  602. */
  603. #ifdef COMMON
  604. /*
  605. * For COMMON Lisp I will make all the built-in symbols upper case, unless
  606. * the "2" bit of restartp is set...
  607. */
  608. char const *p1 = s;
  609. char *p2 = (char *)&boffo_char(0);
  610. int c;
  611. if ((restartp & 2) == 0)
  612. { while ((c = *p1++) != 0)
  613. { c = toupper(c);
  614. *p2++ = c;
  615. }
  616. *p2 = 0;
  617. }
  618. else
  619. #endif
  620. strcpy((char *)&boffo_char(0), s);
  621. start_again:
  622. v = iintern(boffo, (int32)strlen((char *)&boffo_char(0)), CP, 0);
  623. errexit();
  624. /*
  625. * I instate the definition given if (a) the definition is a real
  626. * one (ie not for an undefined function) and if (b) either I am doing a cold
  627. * start or the name is still marked as having a definition in the form
  628. * of C code.
  629. */
  630. if (f1 != undefined1)
  631. { if ((restartp & 1)==0 || (qheader(v) & SYM_C_DEF) != 0 || !first_try)
  632. { if (qenv(v) == v) qenv(v) = nil;
  633. /* only set env field to nil if it was otherwise not in use */
  634. ifn1(v) = (int32)f1; ifn2(v) = (int32)f2; ifnn(v) = (int32)fn;
  635. qheader(v) |= SYM_C_DEF;
  636. }
  637. else
  638. { int l = strlen((char *)&boffo_char(0));
  639. /*
  640. * Another piece of curious behaviour here, intend to make it easier to
  641. * survive when the CSL/CCL kernel is extended. If a function that the
  642. * (new) kernel would like to define as a C-coded thing is already in
  643. * the current image either as undefined or with some other (byte-coded)
  644. * definition, I map the name of the new function, and XYZ goes to ~XYZ etc
  645. * by prefixing a '~'. The image as loaded can then access the new C coded
  646. * function by this name, and possibly transfer it across to the normal
  647. * name it was originally expected to have. Since this is a symptom of
  648. * somebody having done either a curious over-riding redefinition of something
  649. * in the kernel or not having re-build to get new symbols properly available,
  650. * I print a message about it. Note also that I only rename once, so if there
  651. * were to be existing symbols with names that started with "~" that could
  652. * make my attempts here less than fully effective.
  653. */
  654. if (init_flags & INIT_VERBOSE)
  655. term_printf(
  656. "+++ Built-in \"%s\" clashes with image file: => \"~%s\"\n",
  657. &boffo_char(0), &boffo_char(0));
  658. while (l >= 0) boffo_char(l+1) = boffo_char(l), l--;
  659. boffo_char(0) = '~';
  660. first_try = 0;
  661. goto start_again;
  662. }
  663. /*
  664. * All things that have been set up as copies of this symbol must be
  665. * initialised with the definition too.
  666. */
  667. if ((restartp & 1) != 0)
  668. {
  669. #ifdef COMMON
  670. Lisp_Object v1 = get(v, work_symbol, nil);
  671. #else
  672. Lisp_Object v1 = get(v, work_symbol);
  673. #endif
  674. while (consp(v1))
  675. { Lisp_Object w = qcar(v1);
  676. v1 = qcdr(v1);
  677. ifn1(w) = (int32)f1; ifn2(w) = (int32)f2; ifnn(w) = (int32)fn;
  678. qenv(w) = qenv(v); /* Copy across environment too */
  679. qheader(w) |= SYM_C_DEF;
  680. }
  681. }
  682. }
  683. return v;
  684. }
  685. static CSLbool add_to_hash(Lisp_Object s, Lisp_Object vector, unsigned32 hash)
  686. /*
  687. * Adds an item into a hash table given that it is known that it is not
  688. * already there.
  689. */
  690. {
  691. Header h = vechdr(vector);
  692. int32 size = (length_of_header(h) - CELL)/4;
  693. int32 i = (int32)(hash & (size - 1));
  694. /*
  695. * I have arranged (elsewhere) that the hash table will be a power of two
  696. * in size, so I can avoid primary clustering by stepping on by any odd
  697. * number. Furthermore I can replace the (perhaps expensive) remaindering
  698. * operations by (perhaps cheap) bitwise AND ones when I reduce my hash value
  699. * to the right range to be an index into the table.
  700. */
  701. int32 step = 1 | ((hash >> 10) & (size - 1));
  702. int32 probes = 0;
  703. while (++probes <= size)
  704. { if (is_fixnum(elt(vector, i)))
  705. { elt(vector, i) = s;
  706. return YES; /* Success */
  707. }
  708. i = i + step;
  709. if (i >= size) i -= size;
  710. }
  711. return NO; /* Table is totally full */
  712. }
  713. static int32 number_of_chunks;
  714. static Lisp_Object rehash(Lisp_Object v, Lisp_Object chunks, int grow)
  715. {
  716. /*
  717. * If (grow) is +1 this enlarges the table. If -1 it shrinks it. In the
  718. * case that the table is to shrink I should guarantee that the next smaller
  719. * table size down will have enough space for the number of active items
  720. * present. grow=0 leaves the table size alone but still rehashes.
  721. */
  722. int32 h = 16384, i;
  723. Lisp_Object new_obvec, nil;
  724. number_of_chunks = int_of_fixnum(chunks);
  725. /*
  726. * Now I decide how to format the new structure. To grow, If I had a single
  727. * vector at present I try to double its size. If that would give something
  728. * with over 40Kbytes I go to 48K, formatted as three chunks each of 16K.
  729. */
  730. if (grow > 0)
  731. { if (number_of_chunks == 1)
  732. { h = length_of_header(vechdr(v)) - CELL;
  733. if (h > 20480)
  734. { h = 16384;
  735. number_of_chunks = 3;
  736. }
  737. else h = 2*h;
  738. }
  739. else number_of_chunks++;
  740. /*
  741. * NB the linear growth of the hash table from this point on gives
  742. * bad performance for very large symbol tables due to excessive need
  743. * for rehashing.
  744. */
  745. }
  746. else if (grow < 0)
  747. { if (number_of_chunks == 1)
  748. { h = length_of_header(vechdr(v)) - CELL;
  749. /*
  750. * When shrinking, I will not permit the hash table to have room for
  751. * less than 8 entries.
  752. */
  753. if (h > 64) h = h / 2;
  754. }
  755. else if (number_of_chunks <= 3)
  756. { h = 32768;
  757. number_of_chunks = 1;
  758. }
  759. else number_of_chunks--;
  760. }
  761. nil = C_nil;
  762. stackcheck1(0, v);
  763. push(v);
  764. try_again:
  765. if (number_of_chunks == 1)
  766. { new_obvec = getvector_init(h+CELL, fixnum_of_int(0));
  767. errexitn(1);
  768. }
  769. else
  770. { new_obvec = nil;
  771. for (i=0; i<number_of_chunks; i++)
  772. { Lisp_Object w;
  773. push(new_obvec);
  774. w = getvector_init(h+CELL, fixnum_of_int(0));
  775. errexitn(2);
  776. pop(new_obvec);
  777. new_obvec = cons(w, new_obvec);
  778. errexitn(1);
  779. }
  780. }
  781. v = stack[0];
  782. while (v != nil)
  783. { Lisp_Object vv;
  784. if (is_vector(v))
  785. { vv = v;
  786. v = nil;
  787. }
  788. else
  789. { vv = qcar(v);
  790. v = qcdr(v);
  791. }
  792. h = length_of_header(vechdr(vv)) - CELL;
  793. h = h >> 2;
  794. while (h != 0)
  795. { Lisp_Object s, p, n = new_obvec;
  796. unsigned32 hash;
  797. h--;
  798. s = elt(vv, h);
  799. if (is_fixnum(s)) continue;
  800. p = qpname(s);
  801. hash = hash_lisp_string(p);
  802. if (number_of_chunks != 1)
  803. { int32 i = (hash ^ (hash >> 16)) % number_of_chunks;
  804. while (i-- != 0) n = qcdr(n);
  805. n = qcar(n);
  806. }
  807. if (!add_to_hash(s, n, hash))
  808. { number_of_chunks++;
  809. /*
  810. * In the grossly improbable case that clustering leads to one of the
  811. * sub-vectors overflowing I will go back and re-start the expansion
  812. * process but with yet more space available. This can ONLY happen
  813. * if I already had multiple sub-hash-tables.
  814. */
  815. goto try_again;
  816. }
  817. }
  818. }
  819. popv(1);
  820. return new_obvec;
  821. }
  822. #ifdef COMMON
  823. static Lisp_Object add_to_externals(Lisp_Object s,
  824. Lisp_Object p, unsigned32 hash)
  825. {
  826. Lisp_Object n = packnext_(p);
  827. Lisp_Object v = packext_(p);
  828. Lisp_Object nil = C_nil;
  829. int32 used = int_of_fixnum(packvext_(p));
  830. if (used == 1) used = length_of_header(vechdr(v));
  831. else used = 16384*used;
  832. /*
  833. * n is (16*sym_count+1)
  834. * used = 4*spaces+4
  835. * The effect is that I trigger a re-hash if the table reaches 70%
  836. * loading. For small vectors when I re-hash I will double the
  837. * table size, for large ones I will add another 16Kbytes (i.e. 4K
  838. * table entries). The effect will be that small packages will often
  839. * be fairly lightly loaded (down to 35% just after an expansion) while
  840. * very large ones will be kept close to the 70% mark. If I start off
  841. * all tables with size that is a power of 2 that state will persist.
  842. */
  843. try_again:
  844. if (5L*(int32)n >= 14L*used)
  845. { stackcheck3(0, s, p, v);
  846. push2(s, p);
  847. v = rehash(v, packvext_(p), 1);
  848. pop2(p, s);
  849. errexit();
  850. packext_(p) = v;
  851. packvext_(p) = fixnum_of_int(number_of_chunks);
  852. }
  853. packnext_(p) = n + (1<<4); /* increment as a Lisp fixnum */
  854. { int32 nv = int_of_fixnum(packvext_(p));
  855. if (nv == 1) add_to_hash(s, v, hash);
  856. else
  857. { nv = (hash ^ (hash >> 16)) % nv;
  858. /*
  859. * There is a systematic nasty problem here that I maybe ought to deal with
  860. * some time. Large packages are represented as a collection of smaller
  861. * hash tables, and part of the hash value of a symbol decides which of these
  862. * sub-tables any particular string will be placed in. I enlarge the whole
  863. * system when the set of tables (treated as a whole) is 70% full. But
  864. * clustering COULD potentially lead to one of the sub-tables becoming
  865. * totally full before then, and that would give a loop here if I was not
  866. * careful. To avoid the possibility I make add_to_hash() report any
  867. * trouble and if I have difficulty I go back and re-enlarge the tables.
  868. * This is not guaranteed safe, but I will be VERY unlucky if it ever bites
  869. * me!
  870. */
  871. while (nv-- != 0) v = qcdr(v);
  872. if (!add_to_hash(s, qcar(v), hash))
  873. { n = used = 0;
  874. goto try_again;
  875. }
  876. }
  877. }
  878. return nil;
  879. }
  880. #endif
  881. static Lisp_Object add_to_internals(Lisp_Object s,
  882. Lisp_Object p, unsigned32 hash)
  883. {
  884. Lisp_Object n = packnint_(p);
  885. Lisp_Object v = packint_(p);
  886. Lisp_Object nil = C_nil;
  887. int32 used = int_of_fixnum(packvint_(p));
  888. if (used == 1) used = length_of_header(vechdr(v));
  889. else used = 16384*used;
  890. try_again:
  891. if (5L*(int32)n >= 14L*used)
  892. { stackcheck3(0, s, p, v);
  893. push2(s, p);
  894. v = rehash(v, packvint_(p), 1);
  895. pop2(p, s);
  896. errexit();
  897. packint_(p) = v;
  898. packvint_(p) = fixnum_of_int(number_of_chunks);
  899. }
  900. packnint_(p) = (Lisp_Object)((int32)n + (1<<4));
  901. /* increment as a Lisp fixnum */
  902. { int32 nv = int_of_fixnum(packvint_(p));
  903. if (nv == 1) add_to_hash(s, v, hash);
  904. else
  905. { nv = (hash ^ (hash >> 16)) % nv;
  906. while (nv-- != 0) v = qcdr(v);
  907. if (!add_to_hash(s, qcar(v), hash))
  908. { n = used = 0;
  909. goto try_again;
  910. }
  911. }
  912. }
  913. return nil;
  914. }
  915. #ifdef __mips__
  916. #ifdef __GCC__
  917. /*
  918. * Bad news - with the version of gcc installed on the mips-based
  919. * DecStations in Cambridge as of February 1992 the memcmp() function
  920. * is plain broken. Here is a replacement.
  921. */
  922. static int my_memcmp(const void *a, const void *b, size_t n)
  923. {
  924. const unsigned char *ac = a, *bc = b;
  925. if ((((int)ac | (int)bc) & 3) == 0)
  926. { while (n >= 4 && *(int *)ac == *(int *)bc)
  927. ac += 4, bc += 4, n -= 4;
  928. }
  929. while (n-- > 0)
  930. { unsigned char c1,c2; /* unsigned cmp seems more intuitive */
  931. if ((c1 = *ac++) != (c2 = *bc++)) return c1 - c2;
  932. }
  933. return 0;
  934. }
  935. #define memcmp(a, b, n) my_memcmp(a, b, n)
  936. #endif
  937. #endif
  938. static CSLbool rehash_pending = NO;
  939. static Lisp_Object lookup(Lisp_Object str, int32 strsize,
  940. Lisp_Object v, Lisp_Object nv, int32 hash)
  941. /*
  942. * Searches a hash table for a symbol with name matching the given string,
  943. * and NOTE that the string passed down here is to be treated as having
  944. * just strsize characters in it. Return Lisp number 0 if not found.
  945. * Sets rehash_pending if the number of probes used to find the item is
  946. * at least half the size of the table. This case might arise in the following
  947. * way:
  948. * insert items into the table until it is just under 70% full.
  949. * remob (eg via EXPORT) items until the table is just over 25% full.
  950. * note that so far there will have been no need to rehash
  951. * insert more items, but select them so that thir hash values are all
  952. * different from the ones used before. You should be able to end up
  953. * with 70% of the table full of valid symbols and 30% left as the value
  954. * fixnum_of_int(1) which represents a place where a deleted symbol used
  955. * to be. There is now NO really empty space.
  956. * Now looking up symbols must keep searching past tombstones, and hence
  957. * here it will be necessary to scan the entire table before it is
  958. * possible to assert that a symbol is not present. Inserting new symbols
  959. * does not suffer in this way - only lookup. To help with this horror I set
  960. * rehash_pending if the lookup uses a number of probes > 75% of the table
  961. * size. This should only arise in degenerate cases!
  962. */
  963. {
  964. Header h;
  965. int32 size;
  966. int32 i = int_of_fixnum(nv), step, n;
  967. if (i != 1)
  968. { i = (hash ^ (hash >> 16)) % i; /* Segmented - find correct segment */
  969. while (i-- != 0) v = qcdr(v);
  970. v = qcar(v);
  971. }
  972. h = vechdr(v);
  973. size = (length_of_header(h) - CELL)/4;
  974. i = (int32)(hash & (size - 1));
  975. step = 1 | ((hash >> 10) & (size - 1));
  976. /*
  977. * I count the probes that I make here and if there are as many as the size
  978. * of the hash table then I allow the lookup to report that the symbol is not
  979. * present. But at least I do not get stuck in a loop.
  980. */
  981. for (n=0; n<size; n++)
  982. { Lisp_Object w = elt(v, i);
  983. Lisp_Object pn;
  984. if (w == fixnum_of_int(0))
  985. { if (4*n > 3*size) rehash_pending = YES;
  986. return w; /* Not found */
  987. }
  988. if (w != fixnum_of_int(1))
  989. { pn = qpname(w);
  990. /* v comes out of a package so has a proper pname */
  991. if (memcmp((char *)str + (CELL-TAG_VECTOR),
  992. (char *)pn + (CELL-TAG_VECTOR),
  993. (size_t)strsize) == 0 &&
  994. (int32)length_of_header(vechdr(pn)) - CELL == strsize)
  995. { if (4*n > 3*size) rehash_pending = YES;
  996. return w;
  997. }
  998. }
  999. i = i + step;
  1000. if (i >= size) i -= size;
  1001. }
  1002. rehash_pending = YES;
  1003. return fixnum_of_int(0);
  1004. }
  1005. static int ordersymbol(Lisp_Object v1, Lisp_Object v2)
  1006. /*
  1007. * Compare two symbols to see if they are in alphabetic order.
  1008. * Returns 0 is the symbols have the same name, otherwise
  1009. * the comparison is a lexical one on their names, with -ve if
  1010. * v1 comes alphabetically before v2. Deals with gensyms, and in so
  1011. * doing has to allocate names for them, which seems a great misery
  1012. * since it means that this procedure can provoke garbage collection..
  1013. *
  1014. * Note that the ordering here is based on the bit-patterns that
  1015. * represent the names, so Kanji (etc) symbols may not come out in
  1016. * an order that is especially useful.
  1017. */
  1018. {
  1019. Lisp_Object pn1 = qpname(v1), pn2 = qpname(v2);
  1020. int c;
  1021. int32 l1, l2;
  1022. #ifndef COMMON
  1023. if (qheader(v1) & SYM_UNPRINTED_GENSYM)
  1024. { Lisp_Object nil;
  1025. push(v2);
  1026. pn1 = get_pname(v1);
  1027. pop(v2);
  1028. nil = C_nil;
  1029. if (exception_pending()) return 0;
  1030. pn2 = qpname(v2);
  1031. }
  1032. if (qheader(v2) & SYM_UNPRINTED_GENSYM)
  1033. { Lisp_Object nil;
  1034. push(pn1);
  1035. pn2 = get_pname(v2);
  1036. pop(pn1);
  1037. nil = C_nil;
  1038. if (exception_pending()) return 0;
  1039. }
  1040. #endif
  1041. l1 = length_of_header(vechdr(pn1)) - CELL;
  1042. l2 = length_of_header(vechdr(pn2)) - CELL;
  1043. c = memcmp((char *)pn1 + (CELL-TAG_VECTOR),
  1044. (char *)pn2 + (CELL-TAG_VECTOR),
  1045. (size_t)(l1 < l2 ? l1 : l2));
  1046. if (c == 0) c = (int)(l1 - l2);
  1047. return c;
  1048. }
  1049. /*
  1050. * This has been coded so that it provides the behavious that Reduce expects
  1051. * of ordp(). This is the REDUCE 3.6/3.7 version - it will need re-work
  1052. * if REDUCE is altered. Note the curious situation that symbols are
  1053. * alphabetically ordered, EXCEPT that "nil" comes before everything else!
  1054. * (NB for 3.6 this is as provided in a patch file rather than the original
  1055. * release. The places with *** represent updates since 3.6 and the initial
  1056. * version of 3.6)
  1057. *
  1058. * symbolic procedure ordp(u,v);
  1059. * if null u then null v
  1060. * else if null v then t
  1061. * else if vectorp u then if vectorp v then ordpv(u,v) else atom v
  1062. * else if atom u
  1063. * then if atom v
  1064. * then if numberp u then numberp v and not (u<v)
  1065. * else if idp v then orderp(u,v)
  1066. * else numberp v
  1067. * else nil
  1068. * else if atom v then t
  1069. * else if car u=car v then %%% ordp(cdr u,cdr v)
  1070. *** ordpl(cdr u, cdr v) *** 8 Feb 1999
  1071. *** %% flagp(car u,'noncom) or ordpl(cdr u,cdr v) ***
  1072. * else if flagp(car u,'noncom)
  1073. * then if flagp(car v,'noncom) then ordp(car u,car v) else t
  1074. * else if flagp(car v,'noncom) then nil
  1075. * else ordp(car u,car v);
  1076. *
  1077. *** symbolic procedure ordpl(u,v)
  1078. *** if atom u then ordp(u,v)
  1079. *** else if atom v then t
  1080. *** else if car u=car v then ordpl(cdr u,cdr v)
  1081. *** else ordp(car u, car v);
  1082. *
  1083. */
  1084. static int orderp(Lisp_Object u, Lisp_Object v);
  1085. static int ordpv(Lisp_Object u, Lisp_Object v)
  1086. {
  1087. Header hu = vechdr(u), hv = vechdr(v);
  1088. int32 lu = length_of_header(hu), lv = length_of_header(hv), n = 4;
  1089. if (type_of_header(hu) != type_of_header(hv))
  1090. return (type_of_header(hu) < type_of_header(hv) ? -1 : 1);
  1091. if (vector_holds_binary(hu))
  1092. { while (n < lu && n < lv)
  1093. { unsigned int eu = *(unsigned char *)(u - TAG_VECTOR + n),
  1094. ev = *(unsigned char *)(v - TAG_VECTOR + n);
  1095. if (eu != ev) return (eu < ev ? -1 : 1);
  1096. n += 1;
  1097. }
  1098. return (lu == lv ? 0 : lu < lv ? -1 : 1);
  1099. }
  1100. /*
  1101. * At present it is an ERROR to include mixed vectors in structures passed
  1102. * to ordering functions, and if it is done the system may crash. Note that
  1103. * stream objects count as mixed for these purposes. I will get around to
  1104. * fixing things sometime...
  1105. */
  1106. else
  1107. { while (n < lu && n < lv)
  1108. { Lisp_Object eu = *(Lisp_Object *)(u - TAG_VECTOR + n),
  1109. ev = *(Lisp_Object *)(v - TAG_VECTOR + n),
  1110. nil = C_nil;
  1111. int w;
  1112. push2(u, v);
  1113. #ifdef SOFTWARE_TICKS
  1114. if (--countdown < 0) deal_with_tick();
  1115. #endif
  1116. if (stack >= (Lisp_Object *)stacklimit)
  1117. { push(ev);
  1118. eu = reclaim(eu, "stack", GC_STACK, 0);
  1119. pop(ev);
  1120. nil = C_nil;
  1121. /* stackcheck expanded by hand here to return an int, not nil, in bad case */
  1122. if (exception_pending()) { popv(2); return 0; }
  1123. }
  1124. w = orderp(eu, ev);
  1125. pop2(v, u);
  1126. nil = C_nil;
  1127. if (exception_pending()) return 0;
  1128. if (w != 0) return w;
  1129. n += 4;
  1130. }
  1131. return (lu == lv ? 0 : lu < lv ? -1 : 1);
  1132. }
  1133. }
  1134. static int ordpl(Lisp_Object u, Lisp_Object v)
  1135. {
  1136. for (;;)
  1137. { int w = orderp(qcar(u), qcar(v));
  1138. if (w != 0) return w;
  1139. u = qcdr(u);
  1140. v = qcdr(v);
  1141. if (!is_cons(u)) return orderp(u, v);
  1142. if (!is_cons(v)) return -1;
  1143. }
  1144. }
  1145. #define flagged_noncom(v) \
  1146. ((fv = qfastgets(v)) != nil && elt(fv, 0) != SPID_NOPROP)
  1147. static int orderp(Lisp_Object u, Lisp_Object v)
  1148. {
  1149. Lisp_Object nil = C_nil;
  1150. for (;;)
  1151. { if (u == nil) return v == nil ? 0 : 1;
  1152. else if (v == nil) return -1; /* Special cases of NIL done */
  1153. else if (u == v) return 0; /* useful optimisation? */
  1154. /*
  1155. * I migrate the vectorp test inside where I have tested for atoms, since
  1156. * I expect vectors to be a somewhat uncommon case
  1157. */
  1158. else if (!is_cons(u))
  1159. { if (!is_cons(v))
  1160. { if (is_vector(u))
  1161. { if (is_vector(v)) return ordpv(u, v);
  1162. else return -1;
  1163. }
  1164. else if (is_number(u))
  1165. { if (is_number(v)) return lessp2(u, v) ? 1 :
  1166. eql(u, v) ? 0 : -1;
  1167. else return 1;
  1168. }
  1169. else if (is_number(v)) return -1;
  1170. else if (is_symbol(u))
  1171. { if (is_symbol(v)) return ordersymbol(u, v);
  1172. else return 1;
  1173. }
  1174. else if (is_symbol(v)) return -1;
  1175. /*
  1176. * Now the objects are not symbols, vectors or numbers. That maybe
  1177. * leaves character objects. I compare representations to give a
  1178. * rather arbitrary ordering. Note that any comparisons that get
  1179. * down here are yielding non portable results.
  1180. */
  1181. else return (u == v) ? 0 : (u < v) ? 1 : -1;
  1182. }
  1183. else return 1;
  1184. }
  1185. else if (!is_cons(v)) return -1;
  1186. else
  1187. { Lisp_Object cu = qcar(u), cv = qcar(v);
  1188. Lisp_Object fv; /* used by flagged_noncom */
  1189. int w;
  1190. push2(u, v);
  1191. /* stackcheck2(2, cu, cv); */
  1192. #ifdef SOFTWARE_TICKS
  1193. if (--countdown < 0) deal_with_tick();
  1194. #endif
  1195. if (stack >= (Lisp_Object *)stacklimit)
  1196. { push(cv);
  1197. cu = reclaim(cu, "stack", GC_STACK, 0);
  1198. pop(cv);
  1199. nil = C_nil;
  1200. /* stackcheck expanded by hand here to return an int, not nil, in bad case */
  1201. if (exception_pending()) { popv(2); return 0; }
  1202. }
  1203. w = orderp(cu, cv);
  1204. pop2(v, u);
  1205. nil = C_nil;
  1206. if (exception_pending()) return 0;
  1207. if (w != 0)
  1208. { cu = qcar(u);
  1209. if (is_symbol(cu) && flagged_noncom(cu))
  1210. { cv = qcar(v);
  1211. if (is_symbol(cv) && flagged_noncom(cv)) return w;
  1212. else return -1;
  1213. }
  1214. else
  1215. { cv = qcar(v);
  1216. if (is_symbol(cv) && flagged_noncom(cv)) return 1;
  1217. else return w;
  1218. }
  1219. }
  1220. /*
  1221. * here car u = car v
  1222. */
  1223. u = qcdr(u);
  1224. v = qcdr(v);
  1225. if (!is_cons(u)) continue;
  1226. if (!is_cons(v)) return -1;
  1227. /*
  1228. * The function I can ordpl here has the atom tests lifted out from
  1229. * its top...
  1230. */
  1231. return ordpl(u, v);
  1232. }
  1233. }
  1234. }
  1235. Lisp_Object Lorderp(Lisp_Object nil,
  1236. Lisp_Object a, Lisp_Object b)
  1237. {
  1238. int w;
  1239. w = orderp(a, b);
  1240. errexit();
  1241. return onevalue(Lispify_predicate(w <= 0));
  1242. }
  1243. static unsigned32 removed_hash;
  1244. static CSLbool remob(Lisp_Object sym, Lisp_Object v, Lisp_Object nv)
  1245. /*
  1246. * Searches a hash table for a symbol with name matching the given string,
  1247. * and remove it.
  1248. */
  1249. {
  1250. Lisp_Object str = qpname(sym);
  1251. Header h;
  1252. unsigned32 hash;
  1253. int32 i = int_of_fixnum(nv), size, step, n;
  1254. if (qheader(sym) & SYM_ANY_GENSYM) return NO; /* gensym case is easy! */
  1255. #ifdef COMMON
  1256. /* If not in any package it has no home & is not available */
  1257. qheader(sym) &= ~SYM_EXTERN_IN_HOME & ~(0xffffffff<<SYM_IN_PKG_SHIFT);
  1258. #endif
  1259. removed_hash = hash = hash_lisp_string(str);
  1260. /*
  1261. * The search procedure used here MUST match that coded in lookup().
  1262. */
  1263. if (i != 1)
  1264. { i = (hash ^ (hash >> 16)) % i;
  1265. while (i-- != 0) v = qcdr(v);
  1266. v = qcar(v);
  1267. }
  1268. h = vechdr(v);
  1269. size = (length_of_header(h) - CELL)/4;
  1270. i = (int32)(hash & (size - 1));
  1271. step = 1 | ((hash >> 10) & (size - 1));
  1272. for (n=0; n<size; n++)
  1273. { Lisp_Object w = elt(v, i);
  1274. if (w == fixnum_of_int(0)) return NO; /* Not found */
  1275. if (w == sym)
  1276. { elt(v, i) = fixnum_of_int(1);
  1277. /*
  1278. * I will shrink the hash table if it becomes less than 25% full,
  1279. * but not in this bit of code... because I want this internal
  1280. * remob() function to avoid any possible failure or garbage collection
  1281. * so I can call it from C code without any formality. Thus I should do
  1282. * any tidying up afterwards.
  1283. */
  1284. return YES;
  1285. }
  1286. i = i + step;
  1287. if (i >= size) i -= size;
  1288. }
  1289. return NO;
  1290. }
  1291. #ifdef COMMON
  1292. static Lisp_Object Lmake_symbol(Lisp_Object nil, Lisp_Object str)
  1293. /*
  1294. * Lisp function (make-symbol ..) creates an uninterned symbol.
  1295. */
  1296. {
  1297. Lisp_Object s;
  1298. stackcheck1(0, str);
  1299. /*
  1300. * Common Lisp wants a STRING passed here, but as a matter of generosity and
  1301. * for the benefit of some of my system code I support symbols too.
  1302. */
  1303. if (symbolp(str))
  1304. { str = get_pname(str);
  1305. errexit();
  1306. }
  1307. else if (!is_vector(str)) return aerror1("make-symbol", str);
  1308. else if (complex_stringp(str))
  1309. { str = simplify_string(str);
  1310. errexit();
  1311. }
  1312. else if (type_of_header(vechdr(str)) != TYPE_STRING)
  1313. return aerror1("make-symbol", str);
  1314. push(str);
  1315. s = getvector(TAG_SYMBOL, TYPE_SYMBOL, symhdr_length);
  1316. errexitn(1);
  1317. pop(str);
  1318. qheader(s) = TAG_ODDS+TYPE_SYMBOL;
  1319. qvalue(s) = unset_var;
  1320. qpname(s) = str;
  1321. qplist(s) = nil;
  1322. qfastgets(s) = nil;
  1323. qpackage(s) = nil;
  1324. qenv(s) = s;
  1325. ifn1(s) = (int32)undefined1;
  1326. ifn2(s) = (int32)undefined2;
  1327. ifnn(s) = (int32)undefinedn;
  1328. qcount(s) = 0; /* set counts to zero to be tidy */
  1329. return onevalue(s);
  1330. }
  1331. #endif
  1332. Lisp_Object MS_CDECL Lgensym(Lisp_Object nil, int nargs, ...)
  1333. /*
  1334. * Lisp function (gensym) creates an uninterned symbol with odd name.
  1335. */
  1336. {
  1337. Lisp_Object id;
  1338. #ifdef COMMON
  1339. Lisp_Object pn;
  1340. char genname[64];
  1341. #endif
  1342. argcheck(nargs, 0, "gensym");
  1343. stackcheck0(0);
  1344. nil = C_nil;
  1345. #ifdef COMMON
  1346. sprintf(genname, "G%lu", (long unsigned)gensym_ser++);
  1347. pn = make_string(genname);
  1348. errexit();
  1349. push(pn);
  1350. #endif
  1351. id = getvector(TAG_SYMBOL, TYPE_SYMBOL, symhdr_length);
  1352. #ifdef COMMON
  1353. pop(pn);
  1354. #endif
  1355. errexit();
  1356. #ifdef COMMON
  1357. qheader(id) = TAG_ODDS+TYPE_SYMBOL+SYM_ANY_GENSYM;
  1358. qpname(id) = pn;
  1359. #else
  1360. qheader(id) = TAG_ODDS+TYPE_SYMBOL+SYM_UNPRINTED_GENSYM+SYM_ANY_GENSYM;
  1361. qpname(id) = gensym_base;
  1362. #endif
  1363. qvalue(id) = unset_var;
  1364. qplist(id) = nil;
  1365. qfastgets(id) = nil;
  1366. #ifdef COMMON
  1367. qpackage(id) = nil; /* Marks it as a uninterned */
  1368. #endif
  1369. qenv(id) = id;
  1370. ifn1(id) = (int32)undefined1;
  1371. ifn2(id) = (int32)undefined2;
  1372. ifnn(id) = (int32)undefinedn;
  1373. qcount(id) = 0; /* to be tidy */
  1374. return onevalue(id);
  1375. }
  1376. Lisp_Object Lgensym1(Lisp_Object nil, Lisp_Object a)
  1377. /*
  1378. * Lisp function (gensym1 base) creates an uninterned symbol with odd name.
  1379. * The case (gensym <number>) is DEPRECATED by the Common Lisp standards
  1380. * committee and so I will not implement it at least for now.
  1381. */
  1382. {
  1383. Lisp_Object id, genbase;
  1384. #ifdef COMMON
  1385. unsigned32 len;
  1386. char genname[64];
  1387. if (complex_stringp(a))
  1388. { a = simplify_string(a);
  1389. errexit();
  1390. }
  1391. #endif
  1392. if (is_vector(a) &&
  1393. type_of_header(vechdr(a)) == TYPE_STRING) genbase = a;
  1394. else if (symbolp(a)) genbase = qpname(a); /* copy gensym base */
  1395. else return aerror1("gensym1", a);
  1396. push(genbase);
  1397. stackcheck0(0);
  1398. #ifdef COMMON
  1399. len = length_of_header(vechdr(genbase)) - CELL;
  1400. if (len > 60) len = 60; /* Unpublished truncation of the string */
  1401. sprintf(genname, "%.*s%lu", (int)len,
  1402. (char *)genbase + (CELL-TAG_VECTOR), (long unsigned)gensym_ser++);
  1403. stack[0] = make_string(genname);
  1404. errexitn(1);
  1405. #endif
  1406. id = getvector(TAG_SYMBOL, TYPE_SYMBOL, symhdr_length);
  1407. errexitn(1);
  1408. pop(genbase);
  1409. #ifdef COMMON
  1410. qheader(id) = TAG_ODDS+TYPE_SYMBOL+SYM_ANY_GENSYM;
  1411. #else
  1412. qheader(id) = TAG_ODDS+TYPE_SYMBOL+SYM_UNPRINTED_GENSYM+SYM_ANY_GENSYM;
  1413. #endif
  1414. qvalue(id) = unset_var;
  1415. qpname(id) = genbase;
  1416. qplist(id) = nil;
  1417. qfastgets(id) = nil;
  1418. #ifdef COMMON
  1419. qpackage(id) = nil; /* Marks it as a uninterned */
  1420. #endif
  1421. qenv(id) = id;
  1422. ifn1(id) = (int32)undefined1;
  1423. ifn2(id) = (int32)undefined2;
  1424. ifnn(id) = (int32)undefinedn;
  1425. qcount(id) = 0; /* to be tidy */
  1426. return onevalue(id);
  1427. }
  1428. Lisp_Object Lgensym2(Lisp_Object nil, Lisp_Object a)
  1429. /*
  1430. * Lisp function (gensym2 base) whose name is exactly that given by the
  1431. * argument. This might be UNHELPFUL if one tried to print the value
  1432. * concerned, but seems to be what the Common Lisp syntax #:ggg expects
  1433. * to achieve!
  1434. */
  1435. {
  1436. Lisp_Object id, genbase;
  1437. unsigned32 len;
  1438. #ifdef COMMON
  1439. if (complex_stringp(a))
  1440. { a = simplify_string(a);
  1441. errexit();
  1442. }
  1443. #endif
  1444. if (is_vector(a) &&
  1445. type_of_header(vechdr(a)) == TYPE_STRING) genbase = a;
  1446. else if (symbolp(a)) genbase = qpname(a);
  1447. else return aerror1("gensym2", a);
  1448. push(genbase);
  1449. stackcheck0(0);
  1450. len = length_of_header(vechdr(genbase)) - CELL;
  1451. stack[0] = copy_string(genbase, len);
  1452. errexitn(1);
  1453. id = getvector(TAG_SYMBOL, TYPE_SYMBOL, symhdr_length);
  1454. errexitn(1);
  1455. pop(genbase);
  1456. qheader(id) = TAG_ODDS+TYPE_SYMBOL+SYM_ANY_GENSYM;
  1457. qvalue(id) = unset_var;
  1458. qpname(id) = genbase;
  1459. qplist(id) = nil;
  1460. qfastgets(id) = nil;
  1461. #ifdef COMMON
  1462. qpackage(id) = nil; /* Marks it as a uninterned */
  1463. #endif
  1464. qenv(id) = id;
  1465. ifn1(id) = (int32)undefined1;
  1466. ifn2(id) = (int32)undefined2;
  1467. ifnn(id) = (int32)undefinedn;
  1468. qcount(id) = 0; /* to be tidy */
  1469. return onevalue(id);
  1470. }
  1471. static Lisp_Object Lgensymp(Lisp_Object nil, Lisp_Object a)
  1472. {
  1473. if (is_symbol(a) &&
  1474. (qheader(a) & SYM_CODEPTR) == 0 &&
  1475. (qheader(a) & SYM_ANY_GENSYM) != 0) return onevalue(lisp_true);
  1476. else return onevalue(nil);
  1477. }
  1478. Lisp_Object iintern(Lisp_Object str, int32 h, Lisp_Object p, int str_is_ok)
  1479. /*
  1480. * Look up the first h chars of the string str with respect to the package p.
  1481. * The last arg is a boolean that allows me to decide if (when a new symbol
  1482. * has to be created) the string must be copied. If h differs from the
  1483. * real number of characters in arg1 then a copy MUST be made.
  1484. * If non-zero, the last arg is 1 for intern, 2 for extern, 3
  1485. * for find-symbol and 4 for "find-external-symbol" as in reader syntax p:x.
  1486. * NB in CSL mode only one value is returned.
  1487. */
  1488. {
  1489. Lisp_Object r, nil = C_nil;
  1490. unsigned32 hash;
  1491. stackcheck2(0, str, p);
  1492. hash = hash_lisp_string_with_length(str, h+CELL);
  1493. /* find-external-symbol will not look at the internals */
  1494. if (str_is_ok != 4)
  1495. { r = lookup(str, h, packint_(p), packvint_(p), hash);
  1496. /*
  1497. * rehash_pending is intended to deal with horrible cases that involve
  1498. * lots of remobs. But in the worst possible scenario one could have
  1499. * a symbol table where all symbols clashed on hashing, and then by
  1500. * restricting further use to just the last few symbols entered it would be
  1501. * possible for all lookup operations to take a number of probes that
  1502. * was almost 70% of the table size. In such cases rehashing (without
  1503. * expanding the table size at the same time) would leave the table
  1504. * unaltered and would not mend things. To avoid such repeated fruitless
  1505. * rehashing I only set rehash_pending if the number of probes was over
  1506. * 75% of the table size, and this should be impossible if there are no
  1507. * tombstones present.
  1508. */
  1509. if (rehash_pending)
  1510. { Lisp_Object v = packint_(p);
  1511. push2(p, r);
  1512. v = rehash(v, packvint_(p), 0);
  1513. pop2(r, p);
  1514. errexit();
  1515. packint_(p) = v;
  1516. packvint_(p) = fixnum_of_int(number_of_chunks);
  1517. rehash_pending = NO;
  1518. }
  1519. nil = C_nil;
  1520. if (r != fixnum_of_int(0))
  1521. {
  1522. #ifdef COMMON
  1523. mv_2 = internal_symbol;
  1524. #endif
  1525. return nvalues(r, 2);
  1526. }
  1527. }
  1528. #ifdef COMMON
  1529. r = lookup(str, h, packext_(p), packvext_(p), hash);
  1530. if (rehash_pending)
  1531. { Lisp_Object v = packext_(p);
  1532. push2(p, r);
  1533. v = rehash(v, packvext_(p), 0);
  1534. pop2(r, p);
  1535. errexit();
  1536. packext_(p) = v;
  1537. packvext_(p) = fixnum_of_int(number_of_chunks);
  1538. rehash_pending = NO;
  1539. }
  1540. if (r != fixnum_of_int(0))
  1541. {
  1542. mv_2 = external_symbol;
  1543. return nvalues(r, 2);
  1544. }
  1545. if (str_is_ok == 4)
  1546. {
  1547. #ifdef COMMON
  1548. mv_2 = nil;
  1549. #endif
  1550. return nvalues(nil, 2);
  1551. }
  1552. for (r = packuses_(p); r!=nil; r=qcdr(r))
  1553. { Lisp_Object w = qcar(r);
  1554. w = lookup(str, h, packext_(w), packvext_(w), hash);
  1555. if (rehash_pending)
  1556. { Lisp_Object v = packext_(p);
  1557. push2(p, r);
  1558. v = rehash(v, packvext_(p), 0);
  1559. pop2(r, p);
  1560. errexit();
  1561. packext_(p) = v;
  1562. packvext_(p) = fixnum_of_int(number_of_chunks);
  1563. rehash_pending = NO;
  1564. }
  1565. if (w != fixnum_of_int(0))
  1566. {
  1567. mv_2 = inherited_symbol;
  1568. return nvalues(w, 2);
  1569. }
  1570. }
  1571. #endif
  1572. if (str_is_ok == 3)
  1573. {
  1574. #ifdef COMMON
  1575. mv_2 = nil;
  1576. #endif
  1577. return nvalues(nil, 2);
  1578. }
  1579. { Lisp_Object s;
  1580. push2(str, p);
  1581. s = (Lisp_Object)getvector(TAG_SYMBOL, TYPE_SYMBOL, symhdr_length);
  1582. pop(p);
  1583. errexit();
  1584. qheader(s) = TAG_ODDS+TYPE_SYMBOL;
  1585. #ifdef COMMON
  1586. if (p == qvalue(keyword_package) && keyword_package != nil)
  1587. { qvalue(s) = (Lisp_Object)s;
  1588. qheader(s) |= SYM_SPECIAL_VAR;
  1589. }
  1590. else
  1591. #endif
  1592. qvalue(s) = unset_var;
  1593. qpname(s) = qpname(nil); /* At this stage the pname is a dummy */
  1594. qplist(s) = nil;
  1595. qfastgets(s) = nil;
  1596. #ifdef COMMON
  1597. qpackage(s) = p;
  1598. #endif
  1599. qenv(s) = (Lisp_Object)s;
  1600. ifn1(s) = (int32)undefined1;
  1601. ifn2(s) = (int32)undefined2;
  1602. ifnn(s) = (int32)undefinedn;
  1603. qcount(s) = 0;
  1604. push(s);
  1605. #ifdef COMMON
  1606. if ((p == qvalue(keyword_package) && keyword_package != nil) ||
  1607. str_is_ok == 2)
  1608. { add_to_externals(s, p, hash);
  1609. errexitn(2);
  1610. qheader(s) |= SYM_EXTERN_IN_HOME;
  1611. }
  1612. else
  1613. #endif
  1614. add_to_internals(s, p, hash);
  1615. pop(s); pop(str);
  1616. errexit();
  1617. /* Now the symbol-head is safe enough that I can let the GC look at it */
  1618. if (str_is_ok != 0) qpname(s) = str;
  1619. else
  1620. { Lisp_Object pn;
  1621. push(s);
  1622. pn = copy_string(str, h);
  1623. pop(s);
  1624. qpname(s) = pn;
  1625. }
  1626. errexit();
  1627. #ifdef COMMON
  1628. mv_2 = nil;
  1629. #endif
  1630. return nvalues((Lisp_Object)s, 2);
  1631. }
  1632. }
  1633. #ifdef COMMON
  1634. static Lisp_Object Lfind_package(Lisp_Object nil, Lisp_Object name);
  1635. Lisp_Object Lintern_2(Lisp_Object nil, Lisp_Object str, Lisp_Object pp)
  1636. #else
  1637. Lisp_Object Lintern(Lisp_Object nil, Lisp_Object str)
  1638. #endif
  1639. /*
  1640. * Lisp entrypoint for (intern ..)
  1641. */
  1642. {
  1643. Header h;
  1644. Lisp_Object p;
  1645. #ifdef COMMON
  1646. push(str);
  1647. p = Lfind_package(nil, pp);
  1648. pop(str);
  1649. errexit();
  1650. #else
  1651. p = CP;
  1652. #endif
  1653. #ifdef COMMON
  1654. if (complex_stringp(str))
  1655. { push(p);
  1656. str = simplify_string(str);
  1657. pop(p);
  1658. errexit();
  1659. }
  1660. #endif
  1661. /*
  1662. * For COMMON it is perhaps undue generosity to permit a symbol here
  1663. * rather than just a string. However it will make life a bit easier for
  1664. * me in porting existing code. Note that the Common Lisp book says quite
  1665. * explicitly that symbols are NOT allowed here.
  1666. */
  1667. if (symbolp(str))
  1668. { str = get_pname(str);
  1669. errexit();
  1670. }
  1671. if (!is_vector(str) ||
  1672. type_of_header(h = vechdr(str)) != TYPE_STRING)
  1673. return aerror1("intern (not a string)", str);
  1674. return iintern(str, length_of_header(h) - CELL, p, 1);
  1675. }
  1676. #ifdef COMMON
  1677. Lisp_Object Lintern(Lisp_Object nil, Lisp_Object a)
  1678. {
  1679. return Lintern_2(nil, a, CP);
  1680. }
  1681. static Lisp_Object Lfind_symbol(Lisp_Object nil,
  1682. Lisp_Object str, Lisp_Object pp)
  1683. {
  1684. Header h;
  1685. Lisp_Object p;
  1686. push(str);
  1687. p = Lfind_package(nil, pp);
  1688. pop(str);
  1689. errexit();
  1690. if (symbolp(str))
  1691. { push(p);
  1692. str = get_pname(str);
  1693. pop(p);
  1694. errexit();
  1695. }
  1696. if (complex_stringp(str))
  1697. { push(p);
  1698. str = simplify_string(str);
  1699. pop(p);
  1700. errexit();
  1701. }
  1702. if (!is_vector(str) ||
  1703. type_of_header(h = vechdr(str)) != TYPE_STRING)
  1704. {
  1705. return aerror1("find-symbol (not a string)", str);
  1706. }
  1707. return iintern(str, length_of_header(h) - CELL, p, 3);
  1708. }
  1709. Lisp_Object Lfind_symbol_1(Lisp_Object nil, Lisp_Object str)
  1710. {
  1711. return Lfind_symbol(nil, str, CP);
  1712. }
  1713. static Lisp_Object Lextern(Lisp_Object nil,
  1714. Lisp_Object sym, Lisp_Object package)
  1715. /*
  1716. * If sym is internal in given package make it external - the inside parts
  1717. * of the export function. Note that the second argument must be a real
  1718. * package object, not a package name. Higher level code must have done
  1719. * a find-package as necessary.
  1720. */
  1721. {
  1722. if (!is_symbol(sym)) return onevalue(nil);
  1723. if (remob(sym, packint_(package), packvint_(package)))
  1724. { Lisp_Object n = packnint_(package);
  1725. Lisp_Object v = packint_(package);
  1726. int32 used = int_of_fixnum(packvint_(package));
  1727. if (used == 1) used = length_of_header(vechdr(v));
  1728. else used = 16384*used;
  1729. /*
  1730. * I will shrink a hash table if a sequence of remob-style operations,
  1731. * which will especially include the case where a symbol ceases to be
  1732. * internal to a package so that it can be external, leaves the table
  1733. * less than 25% full. Note that normal growth is supposed to leave these
  1734. * tables between 35 and 70% full, so the activity here will not be
  1735. * triggered frivolously. However note the following oddity: if a package
  1736. * is of minimum size (8 entries in the hash table) then rehashing will not
  1737. * cause it to shrink (but it will rehash and hence tidy it up). Hence
  1738. * every remob on such a table will cause it to be re-hashed.
  1739. */
  1740. if ((int32)n < used)
  1741. { stackcheck3(0, sym, package, v);
  1742. push2(sym, package);
  1743. v = rehash(v, packvint_(package), -1);
  1744. pop2(package, sym);
  1745. errexit();
  1746. packint_(package) = v;
  1747. packvint_(package) = fixnum_of_int(number_of_chunks);
  1748. }
  1749. packnint_(package) -= (1<<4); /* decrement as fixnum */
  1750. /*
  1751. * removed_hash was left set up by remob, and it is known that the symbol
  1752. * was not already external, since it had been internal.
  1753. */
  1754. if (qpackage(sym) == package) qheader(sym) |= SYM_EXTERN_IN_HOME;
  1755. add_to_externals(sym, package, removed_hash);
  1756. errexit();
  1757. return onevalue(lisp_true);
  1758. }
  1759. return onevalue(nil);/* no action if it was not internal in this package */
  1760. }
  1761. static Lisp_Object Lextern_1(Lisp_Object nil, Lisp_Object str)
  1762. {
  1763. return Lextern(nil, str, CP);
  1764. }
  1765. static Lisp_Object Limport(Lisp_Object nil,
  1766. Lisp_Object sym, Lisp_Object package)
  1767. /*
  1768. * The internal part of the IMPORT and SHADOWING-IMPORT functions.
  1769. * makes sym internal in package. The symbol MUST NOT be present there
  1770. * before this function is called. The second argument must be a real
  1771. * package object, not just the name of one.
  1772. */
  1773. {
  1774. unsigned32 hash;
  1775. Lisp_Object pn;
  1776. if (!is_symbol(sym)) return onevalue(nil);
  1777. push2(sym, package);
  1778. pn = get_pname(sym);
  1779. errexitn(2);
  1780. hash = hash_lisp_string(pn);
  1781. add_to_internals(stack[-1], stack[0], hash);
  1782. pop2(package, sym);
  1783. errexit();
  1784. if (qpackage(sym) == nil) qpackage(sym) = package;
  1785. return onevalue(nil);
  1786. }
  1787. static Lisp_Object Limport_1(Lisp_Object nil, Lisp_Object str)
  1788. {
  1789. return Limport(nil, str, CP);
  1790. }
  1791. #endif
  1792. Lisp_Object ndelete(Lisp_Object a, Lisp_Object l)
  1793. /*
  1794. * Probably useful in various places throughout the system...
  1795. */
  1796. {
  1797. #ifdef COMMON
  1798. Lisp_Object nil = C_nil;
  1799. #endif
  1800. if (!consp(l)) return l;
  1801. if (a == qcar(l)) return qcdr(l);
  1802. { Lisp_Object z1 = l, z2 = qcdr(l);
  1803. while (consp(z2))
  1804. { if (a == qcar(z2))
  1805. { qcdr(z1) = qcdr(z2);
  1806. return l;
  1807. }
  1808. else
  1809. { z1 = z2;
  1810. z2 = qcdr(z2);
  1811. }
  1812. }
  1813. }
  1814. return l;
  1815. }
  1816. Lisp_Object Lunintern_2(Lisp_Object nil, Lisp_Object sym, Lisp_Object pp)
  1817. {
  1818. Lisp_Object package;
  1819. #ifdef COMMON
  1820. push(sym);
  1821. package = Lfind_package(nil, pp);
  1822. pop(sym);
  1823. errexit();
  1824. #else
  1825. package = pp;
  1826. #endif
  1827. if (!is_symbol(sym)) return onevalue(nil);
  1828. #ifdef COMMON
  1829. if (qpackage(sym) == package) qpackage(sym) = nil;
  1830. packshade_(package) = ndelete(sym, packshade_(package));
  1831. #endif
  1832. if ((qheader(sym) & SYM_C_DEF) != 0)
  1833. return aerror1("remob on function with kernel definition", sym);
  1834. if (remob(sym, packint_(package), packvint_(package)))
  1835. { Lisp_Object n = packnint_(package);
  1836. Lisp_Object v = packint_(package);
  1837. int32 used = int_of_fixnum(packvint_(package));
  1838. if (used == 1) used = length_of_header(vechdr(v));
  1839. else used = 16384*used;
  1840. if ((int32)n < used)
  1841. { stackcheck2(0, package, v);
  1842. push(package);
  1843. v = rehash(v, packvint_(package), -1);
  1844. pop(package);
  1845. errexit();
  1846. packint_(package) = v;
  1847. packvint_(package) = fixnum_of_int(number_of_chunks);
  1848. }
  1849. packnint_(package) -= (1<<4); /* decrement as fixnum */
  1850. return onevalue(lisp_true);
  1851. }
  1852. #ifdef COMMON
  1853. if (remob(sym, packext_(package), packvext_(package)))
  1854. { Lisp_Object n = packnext_(package);
  1855. Lisp_Object v = packext_(package);
  1856. int32 used = int_of_fixnum(packvext_(package));
  1857. if (used == 1) used = length_of_header(vechdr(v));
  1858. else used = 16384*used;
  1859. if ((int32)n < used)
  1860. { stackcheck2(0, package, v);
  1861. push(package);
  1862. v = rehash(v, packvext_(package), -1);
  1863. pop(package);
  1864. errexit();
  1865. packext_(package) = v;
  1866. packvext_(package) = fixnum_of_int(number_of_chunks);
  1867. }
  1868. packnext_(package) -= (1<<4); /* decrement as fixnum */
  1869. return onevalue(lisp_true);
  1870. }
  1871. #endif
  1872. return onevalue(nil);
  1873. }
  1874. Lisp_Object Lunintern(Lisp_Object nil, Lisp_Object str)
  1875. {
  1876. return Lunintern_2(nil, str, CP);
  1877. }
  1878. #ifdef COMMON
  1879. static Lisp_Object Lkeywordp(Lisp_Object nil, Lisp_Object a)
  1880. {
  1881. if (!symbolp(a)) return onevalue(nil);
  1882. return onevalue(Lispify_predicate(qpackage(a) == qvalue(keyword_package)));
  1883. }
  1884. #endif
  1885. /*
  1886. * If I have a window system then getting characters from the keyboard
  1887. * is deemed a system-dependent activity. On non-windowed systems I still
  1888. * do rather more than just getchar(), although under typical Unix what I
  1889. * do here may count as over-kill.
  1890. */
  1891. int tty_count;
  1892. #define TTYBUF_SIZE 256
  1893. #ifdef Kanji
  1894. static kchar_t tty_buffer[TTYBUF_SIZE];
  1895. static kchar_t *tty_pointer;
  1896. #else
  1897. /*
  1898. * Note: I should never have an END_OF_FILE in the buffere here: if I see
  1899. * this condition I pack in the character CTRL-D instead.
  1900. */
  1901. static char tty_buffer[TTYBUF_SIZE];
  1902. static char *tty_pointer;
  1903. #endif
  1904. static CSLbool int_nest = NO;
  1905. #ifndef CWIN
  1906. static int prevchar = '\n';
  1907. #endif
  1908. int terminal_pushed = NOT_CHAR;
  1909. int char_from_terminal(Lisp_Object dummy)
  1910. /*
  1911. * "What ..." you might ask, "is the meaning of this mess?". Well the answer
  1912. * is that when input is directly from the terminal I buffer up to 256
  1913. * characters in a private buffer, and I discount the time spent filling this
  1914. * buffer. On some miserable systems this will succeed in ensuring that the
  1915. * time reported at the end of a run reflects time that CSL spends computing
  1916. * and not time it spends waiting for the user to type something at it. Note
  1917. * that it is only stdin input that I intercept in this way, so the full cost
  1918. * of getting characters from disc files will be accounted. I also (rather
  1919. * improperly) map EOF onto a code (4) which will fit in a byte-sized buffer.
  1920. * I fill by buffer up as far as a newline or a vertical tab (or end of file),
  1921. * and hope that that will not seriously hurt any interactions with CSL.
  1922. * After all the operating system may well line-buffer input anyway, so that
  1923. * it can deal with the delete key on your keyboard for you.
  1924. *
  1925. * Furthermore here is where I display prompt strings to the user -
  1926. * in a way that Standard Lisp does not define, but PSL implements and
  1927. * some REDUCE programmers have come to expect... (in some cases I will
  1928. * let lower level code deal with prompts).
  1929. *
  1930. * If the user provokes an interrupt (^C, or ESC or whatever) while I am
  1931. * in here I will try to return promptly with an empty buffer and
  1932. * some indication of an exception.
  1933. */
  1934. {
  1935. /*
  1936. * I have a hook here for cases where I want to call CSL from other C
  1937. * code. In that case the variable used here points at a function that
  1938. * reads a single character. When I use this option I will NOT generate
  1939. * prompts.
  1940. */
  1941. int c;
  1942. Lisp_Object nil = C_nil;
  1943. CSL_IGNORE(dummy);
  1944. if (terminal_pushed != NOT_CHAR)
  1945. { c = terminal_pushed;
  1946. terminal_pushed = NOT_CHAR;
  1947. return c;
  1948. }
  1949. if (procedural_input != NULL) c = (*procedural_input)();
  1950. else if (non_terminal_input != NULL)
  1951. {
  1952. #ifdef Kanji
  1953. c = getwc(non_terminal_input);
  1954. #else
  1955. c = getc(non_terminal_input);
  1956. #endif
  1957. }
  1958. else
  1959. { if (tty_count == 0)
  1960. {
  1961. /*
  1962. * Time spent waiting for keyboard input is not counted against the user.
  1963. */
  1964. push_clock();
  1965. #ifdef CWIN
  1966. /* Under CWIN I will arrange prompts at a lower level. */
  1967. #else
  1968. if (prevchar == '\n')
  1969. { escaped_printing = 0;
  1970. if (prompt_thing != nil)
  1971. { push(active_stream);
  1972. active_stream = qvalue(terminal_io);
  1973. if (!is_stream(active_stream))
  1974. active_stream = lisp_terminal_io;
  1975. internal_prin(prompt_thing, NO);
  1976. nil = C_nil;
  1977. if (exception_pending()) flip_exception();
  1978. pop(active_stream);
  1979. }
  1980. }
  1981. ensure_screen();
  1982. if (exception_pending()) return EOF;
  1983. #endif
  1984. #ifdef WINDOW_SYSTEM
  1985. if (use_wimp)
  1986. { tty_count = wimpget(tty_buffer);
  1987. if (exception_pending()) return EOF;
  1988. if (interrupt_pending)
  1989. { interrupt_pending = 0;
  1990. if (miscflags & HEADLINE_FLAG) err_printf("+++ Interrupted\n");
  1991. exit_reason = (miscflags & MESSAGES_FLAG) ? UNWIND_ERROR :
  1992. UNWIND_UNWIND;
  1993. exit_value = exit_tag = nil;
  1994. exit_count = 0;
  1995. flip_exception();
  1996. }
  1997. }
  1998. else
  1999. #endif
  2000. for (;;) /* The while loop is so I can restart after ^C */
  2001. {
  2002. /*
  2003. * The setjmp here can not mask any bindings of fluid variables...
  2004. */
  2005. errorset_msg = NULL;
  2006. #ifdef __cplusplus
  2007. try
  2008. #else
  2009. if (!setjmp(sigint_buf))
  2010. #endif
  2011. { while (tty_count<TTYBUF_SIZE && !interrupt_pending)
  2012. { int c;
  2013. sigint_must_longjmp = YES;
  2014. #ifdef Kanji
  2015. c = getwc(stdin);
  2016. #else
  2017. c = getchar();
  2018. #endif
  2019. sigint_must_longjmp = NO;
  2020. if (c == EOF)
  2021. { clearerr(stdin); /* Believed to be what is wanted */
  2022. c = CTRL_D; /* Use ASCII ^D as EOF marker */
  2023. }
  2024. tty_buffer[tty_count++] = c;
  2025. if (c == '\n' || c == '\v' || c == CTRL_D) break;
  2026. }
  2027. if (interrupt_pending)
  2028. { push_clock();
  2029. /*
  2030. * Time spent in the interrupt handler here will not be counted as CPU
  2031. * time used.
  2032. */
  2033. interrupt_pending = NO;
  2034. if (int_nest)
  2035. { err_printf("\n+++ Nested interrupt ignored\n");
  2036. tty_count = 0;
  2037. break;
  2038. }
  2039. else
  2040. { int_nest = YES;
  2041. interrupted(nil);
  2042. int_nest = NO;
  2043. }
  2044. pop_clock();
  2045. tty_count = 0;
  2046. nil = C_nil;
  2047. if (!exception_pending()) continue;
  2048. }
  2049. break;
  2050. }
  2051. #ifdef __cplusplus
  2052. catch (int *)
  2053. #else
  2054. else
  2055. #endif
  2056. { if (errorset_msg != NULL)
  2057. { term_printf("\n%s detected\n", errorset_msg);
  2058. errorset_msg = NULL;
  2059. }
  2060. sigint_must_longjmp = NO;
  2061. interrupt_pending = YES;
  2062. tty_count = 0;
  2063. }
  2064. }
  2065. pop_clock();
  2066. tty_pointer = tty_buffer;
  2067. }
  2068. if (tty_count == 0) c = '\n'; /* ^C odd case */
  2069. else
  2070. { tty_count--;
  2071. c = *tty_pointer++;
  2072. #ifndef Kanji
  2073. c &= 0xff;
  2074. #endif
  2075. }
  2076. }
  2077. inject_randomness(c);
  2078. if (c == EOF || c == CTRL_D) return EOF;
  2079. if (qvalue(echo_symbol) != nil)
  2080. { Lisp_Object stream = qvalue(standard_output);
  2081. if (!is_stream(stream)) stream = qvalue(terminal_io);
  2082. if (!is_stream(stream)) stream = lisp_terminal_io;
  2083. putc_stream(c, stream);
  2084. if (exception_pending()) flip_exception();
  2085. }
  2086. else if (spool_file != NULL) putc(c, spool_file);
  2087. return c;
  2088. }
  2089. Lisp_Object Lrds(Lisp_Object nil, Lisp_Object a)
  2090. {
  2091. Lisp_Object old = qvalue(standard_input);
  2092. if (a == nil) a = qvalue(terminal_io);
  2093. if (a == old) return onevalue(old);
  2094. else if (!is_stream(a)) return aerror1("rds", a);
  2095. else if (stream_read_fn(a) == char_from_illegal)
  2096. return aerror("rds"); /* closed stream or output stream */
  2097. qvalue(standard_input) = a;
  2098. return onevalue(old);
  2099. }
  2100. Lisp_Object Lrtell_1(Lisp_Object nil, Lisp_Object stream)
  2101. {
  2102. int32 n;
  2103. if (!is_stream(stream)) return onevalue(nil);
  2104. n = other_read_action(READ_TELL, stream);
  2105. if (n == -1) return onevalue(nil);
  2106. else return onevalue(fixnum_of_int(n));
  2107. }
  2108. Lisp_Object MS_CDECL Lrtell(Lisp_Object nil, int nargs, ...)
  2109. /*
  2110. * RTELL returns an integer that indicates the position of the current
  2111. * input stream (as selected by RDS). If the position is not available
  2112. * (as would be the case for an interactive stream) then NIL is returned.
  2113. * Otherwise the result is an integer suitable for use with rseek. In the
  2114. * case that the file was opened in binary mode the number returned is a
  2115. * direct indication of the position in the file and arithmetic will
  2116. * behave predictably - for text streams the value returned should be
  2117. * thought of as an abstract position-tag.
  2118. */
  2119. {
  2120. argcheck(nargs, 0, "rtell");
  2121. return Lrtell_1(nil, qvalue(standard_input));
  2122. }
  2123. Lisp_Object Lrseekend(Lisp_Object nil, Lisp_Object stream)
  2124. {
  2125. if (!is_stream(stream)) stream = qvalue(terminal_io);
  2126. if (!is_stream(stream)) stream = lisp_terminal_io;
  2127. other_read_action(READ_FLUSH, stream);
  2128. if (other_read_action(READ_END, stream) != 0) return onevalue(nil);
  2129. else return onevalue(lisp_true);
  2130. }
  2131. Lisp_Object Lrseek_2(Lisp_Object nil, Lisp_Object stream, Lisp_Object a)
  2132. {
  2133. int32 n;
  2134. if (!is_stream(stream)) stream = qvalue(terminal_io);
  2135. if (!is_stream(stream)) stream = lisp_terminal_io;
  2136. if (is_fixnum(a)) n = (int32)int_of_fixnum(a);
  2137. else return aerror("rseek");
  2138. other_read_action(READ_FLUSH, stream);
  2139. if (other_read_action(n | 0x80000000, stream) != 0) return onevalue(nil);
  2140. else return onevalue(lisp_true);
  2141. }
  2142. Lisp_Object Lrseek(Lisp_Object nil, Lisp_Object a)
  2143. /*
  2144. * If the current input stream supports random access this re-positions
  2145. * it to a place indicated by the argument a. If the file was opened in
  2146. * binary mode then a can be an integer indicating how far down the file
  2147. * to set the position. For text files arguments to RSEEK should only be
  2148. * values returned by previous calls to RTELL. RSEEK returns nil if it
  2149. * failed (and if it noticed that fact) or T if it succeeded.
  2150. */
  2151. {
  2152. return Lrseek_2(nil, qvalue(standard_input), a);
  2153. }
  2154. /*
  2155. * The getc_stream() method must NEVER be able to cause garbage collection,
  2156. * since I code the reader here on the assumption that file control blocks
  2157. * do not move while individual characters are read.
  2158. */
  2159. /*
  2160. * While I am in the middle of reading a whole expression the variable
  2161. * curchar will hold the most recent character (or NOT_CHAR if there is none),
  2162. * but between expressions I will push that back into the stream header.
  2163. */
  2164. static void skip_whitespace(Lisp_Object stream)
  2165. {
  2166. Lisp_Object nil;
  2167. for (;;)
  2168. { switch (curchar)
  2169. {
  2170. case NOT_CHAR:
  2171. case 0: case '\v': case '\f':
  2172. case ' ': case '\t': case '\n':
  2173. case '\r': case CTRL_C:
  2174. curchar = getc_stream(stream);
  2175. errexitv();
  2176. continue;
  2177. #ifndef COMMON
  2178. case '%':
  2179. #else
  2180. case ';':
  2181. #endif
  2182. while (curchar != '\n' &&
  2183. curchar != EOF &&
  2184. curchar != CTRL_D)
  2185. { curchar = getc_stream(stream);
  2186. errexitv();
  2187. }
  2188. continue;
  2189. default:
  2190. return;
  2191. }
  2192. }
  2193. }
  2194. static Lisp_Object read_s(Lisp_Object stream);
  2195. #ifdef COMMON
  2196. static Lisp_Object read_hash(Lisp_Object stream);
  2197. #endif
  2198. static Lisp_Object read_list(Lisp_Object stream)
  2199. /*
  2200. * There is no code here to do anything about general read-macros,
  2201. * and it will be awkward to fit it in here because of the reliance
  2202. * that the Common Lisp readmacro scheme puts on the ability to return
  2203. * no values at all using (values). I implement ' and ; and ` since
  2204. * they seem very useful, but only simple cases of #.
  2205. * I require that when this function is called I have already done
  2206. * a skip_whitespace(), and as a result curchar will not be NOT_CHAR.
  2207. */
  2208. {
  2209. Lisp_Object l, w, nil = C_nil;
  2210. stackcheck0(0);
  2211. if (curchar == ')')
  2212. { curchar = NOT_CHAR;
  2213. return C_nil;
  2214. }
  2215. push(stream);
  2216. #ifdef COMMON
  2217. if (curchar == '#')
  2218. { l = read_hash(stream);
  2219. if (l == SPID_NOINPUT)
  2220. { pop(stream);
  2221. return read_list(stream);
  2222. }
  2223. }
  2224. else
  2225. #endif
  2226. l = read_s(stream);
  2227. errexitn(1);
  2228. l = ncons(l);
  2229. errexitn(1);
  2230. push(l); /* this will be the final result */
  2231. for (;;)
  2232. { skip_whitespace(stack[-1]);
  2233. switch (curchar)
  2234. {
  2235. #ifndef COMMON
  2236. case ']':
  2237. #endif
  2238. case ')':
  2239. curchar = NOT_CHAR;
  2240. pop2(l, stream);
  2241. return l;
  2242. case EOF:
  2243. case CTRL_D:
  2244. pop2(l, stream);
  2245. return l;
  2246. /* This code treats '.' as a special lexical marker, while the */
  2247. /* full version of the reader has to be more subtle. */
  2248. case '.':
  2249. curchar = NOT_CHAR;
  2250. push(l);
  2251. w = read_s(stack[-2]);
  2252. pop(l);
  2253. errexitn(2);
  2254. qcdr(l) = w;
  2255. skip_whitespace(stack[-1]);
  2256. if (curchar == ')') curchar = NOT_CHAR;
  2257. /* else error("missing rpar or bad dot"); */
  2258. pop2(l, stream);
  2259. return l;
  2260. #ifdef COMMON
  2261. case '#':
  2262. push(l);
  2263. w = read_hash(stack[-2]);
  2264. errexitn(3);
  2265. if (w == SPID_NOINPUT)
  2266. { pop(l);
  2267. continue;
  2268. }
  2269. w = ncons(w);
  2270. errexitn(3);
  2271. pop(l);
  2272. qcdr(l) = w;
  2273. l = w;
  2274. continue;
  2275. #endif
  2276. default:
  2277. push(l);
  2278. w = read_s(stack[-2]);
  2279. errexitn(3);
  2280. w = ncons(w);
  2281. errexitn(3);
  2282. pop(l);
  2283. qcdr(l) = w;
  2284. l = w;
  2285. continue;
  2286. }
  2287. }
  2288. }
  2289. static Lisp_Object list_to_vector(Lisp_Object l)
  2290. {
  2291. int32 len = 0;
  2292. Lisp_Object p = l, nil = C_nil;
  2293. while (consp(p)) len++, p = qcdr(p);
  2294. push(l);
  2295. p = getvector_init(CELL*(len+1), nil);
  2296. pop(l);
  2297. errexit();
  2298. len = 0;
  2299. while (consp(l))
  2300. { elt(p, len) = qcar(l);
  2301. len++;
  2302. l = qcdr(l);
  2303. }
  2304. return p;
  2305. }
  2306. #ifdef COMMON
  2307. static CSLbool evalfeature(Lisp_Object u)
  2308. {
  2309. Lisp_Object w, nil = C_nil;
  2310. if (consp(u))
  2311. { Lisp_Object fn = qcar(u);
  2312. u = qcdr(u);
  2313. if (!consp(u)) return NO;
  2314. if (fn == not_symbol) return !evalfeature(qcar(u));
  2315. else if (fn == and_symbol)
  2316. { while (consp(u))
  2317. { if (!evalfeature(qcar(u))) return NO;
  2318. nil = C_nil;
  2319. if (exception_pending()) return NO;
  2320. u = qcdr(u);
  2321. }
  2322. return YES;
  2323. }
  2324. else if (fn == or_symbol)
  2325. { while (consp(u))
  2326. { if (evalfeature(qcar(u))) return YES;
  2327. nil = C_nil;
  2328. if (exception_pending()) return NO;
  2329. u = qcdr(u);
  2330. }
  2331. return NO;
  2332. }
  2333. else return NO;
  2334. }
  2335. w = qvalue(features_symbol);
  2336. while (consp(w))
  2337. { if (u == qcar(w)) return YES;
  2338. w = qcdr(w);
  2339. }
  2340. return NO;
  2341. }
  2342. static Lisp_Object read_hash(Lisp_Object stream)
  2343. {
  2344. /*
  2345. * A small subset of the # escaped read-macros will be supported here.
  2346. * curchar must already be set to the character that follows the '#'
  2347. */
  2348. int32 v, w = -1;
  2349. int radix;
  2350. Lisp_Object nil = C_nil;
  2351. Lisp_Object p;
  2352. curchar = getc_stream(stream);
  2353. errexit();
  2354. if (ISdigit(curchar))
  2355. { w = 0;
  2356. do
  2357. { w = 10*w + curchar - '0';
  2358. curchar = getc_stream(stream);
  2359. errexit();
  2360. } while (ISdigit(curchar));
  2361. }
  2362. switch (curchar)
  2363. {
  2364. default:
  2365. /* error("Unknown # escape"); */
  2366. return pack_char(0, 0, '#');
  2367. #ifdef COMMON
  2368. case '#':
  2369. curchar = NOT_CHAR;
  2370. p = reader_workspace;
  2371. while (p != nil)
  2372. { Lisp_Object k = qcar(p);
  2373. if (fixnum_of_int(w) == qcar(k)) return qcdr(k);
  2374. p = qcdr(p);
  2375. }
  2376. return aerror1("Label not found with #n# syntax", fixnum_of_int(w));
  2377. case '=':
  2378. curchar = NOT_CHAR;
  2379. push(stream);
  2380. /*
  2381. * Hmmm - is it necessary for #nn# to refer back to the label here from
  2382. * within the value about to be read?
  2383. */
  2384. p = read_s(stream);
  2385. pop(stream);
  2386. errexit();
  2387. push(p);
  2388. p = acons(fixnum_of_int(w), p, reader_workspace);
  2389. errexitn(1);
  2390. reader_workspace = p;
  2391. pop(p);
  2392. return p;
  2393. #endif
  2394. case ':': /* #:XXX reads in a gensym... */
  2395. curchar = NOT_CHAR;
  2396. { Lisp_Object base = read_s(stream), al; /* The XXX bit unadorned */
  2397. errexit();
  2398. /*
  2399. * This keeps an association list of gensyms present in this call to READ.
  2400. * Note that if you use #.(read) [or other clever things] you may get
  2401. * muddled about contexts. Note that this is sometimes helpful with
  2402. * Standard Lisp but that for Common Lisp the more general #= and ##
  2403. * mechanism should be used and this behaviour here would count as
  2404. * WRONG.
  2405. */
  2406. al = reader_workspace;
  2407. while (al != nil)
  2408. { Lisp_Object k = qcar(al);
  2409. if (base == qcar(k)) return qcdr(k);
  2410. al = qcdr(al);
  2411. }
  2412. push(base);
  2413. /*
  2414. * Beware that #:ggg has just ggg as its name, with no numeric suffix.
  2415. */
  2416. al = Lgensym2(nil, base);
  2417. pop(base);
  2418. errexit();
  2419. al = acons(base, al, reader_workspace);
  2420. errexit();
  2421. reader_workspace = al;
  2422. return qcdr(qcar(al));
  2423. }
  2424. case '(': /* Simple vector */
  2425. curchar = getc_stream(stream);
  2426. errexit();
  2427. skip_whitespace(stream);
  2428. errexit();
  2429. { Lisp_Object l = read_list(stream);
  2430. errexit();
  2431. return list_to_vector(l);
  2432. }
  2433. case '\'':
  2434. curchar = NOT_CHAR;
  2435. p = read_s(stream);
  2436. errexit();
  2437. return list2(function_symbol, p);
  2438. case '\\':
  2439. /*
  2440. * The character just after "#\" is read without any case folding
  2441. */
  2442. curchar = getc_stream(stream);
  2443. errexit();
  2444. w = curchar;
  2445. #ifdef COMMON
  2446. /*
  2447. * The word after "#\" is always spelt in regular ASCII so Kanji support
  2448. * doe snot cut in here.
  2449. */
  2450. if (isalpha(w))
  2451. { char buffer[32];
  2452. int bp = 0, w0 = w;
  2453. while (isalpha(w) && bp < 30)
  2454. { buffer[bp++] = toupper(w); /* Force word to upper case */
  2455. curchar = getc_stream(stream);
  2456. errexit();
  2457. w = curchar;
  2458. }
  2459. if (bp == 1)
  2460. #ifdef Kanji
  2461. return pack_char(0, 0, w0 & 0xffff);
  2462. #else
  2463. return pack_char(0, 0, w0 & 0xff);
  2464. #endif
  2465. buffer[bp] = 0;
  2466. p = make_string(buffer);
  2467. errexit();
  2468. p = Lintern_2(nil, p, qvalue(keyword_package));
  2469. errexit();
  2470. p = get(p, named_character, nil);
  2471. errexit();
  2472. return p;
  2473. }
  2474. #endif
  2475. curchar = NOT_CHAR;
  2476. errexit();
  2477. #ifdef Kanji
  2478. return pack_char(0, 0, w & 0xffff);
  2479. #else
  2480. return pack_char(0, 0, w & 0xff);
  2481. #endif
  2482. case '.':
  2483. curchar = NOT_CHAR;
  2484. p = read_s(stream);
  2485. errexit();
  2486. /*
  2487. * The next is in case the expression evaluated involves reading from
  2488. * this or another stream.
  2489. */
  2490. if (curchar != NOT_CHAR)
  2491. { other_read_action(curchar, stream);
  2492. curchar = NOT_CHAR;
  2493. }
  2494. p = eval(p, nil);
  2495. errexit();
  2496. return onevalue(p);
  2497. case '+':
  2498. case '-':
  2499. v = (curchar == '-');
  2500. curchar = NOT_CHAR;
  2501. /*
  2502. * In March 1988 X3J13 voted that feature names read here should be in
  2503. * the keyword package unless explicily otherwise qualified, but (I guess)
  2504. * the AND, OR and NOT operators applying to them are NOT in the keyword
  2505. * package. Thus I can not just rebind *package* here in any simple way.
  2506. * Oh dear - I hope nobody relies on what those kind experts decided!
  2507. * Meanwhile REMEMBER to go #+ :whatever please.
  2508. */
  2509. push(stream);
  2510. p = read_s(stream);
  2511. errexitn(1);
  2512. w = evalfeature(p);
  2513. pop(stream);
  2514. errexit();
  2515. if (w == v)
  2516. { read_s(stream);
  2517. errexit();
  2518. }
  2519. /*
  2520. * The following flag-value shows that read_hash() has not actually read
  2521. * anything - but it may have skipped over some unwanted stuff.
  2522. */
  2523. return onevalue(SPID_NOINPUT);
  2524. case 'r': case 'R':
  2525. radix = (w>=2 && w<=36) ? (int)w : 10;
  2526. break;
  2527. case 'b': case 'B':
  2528. radix = 2;
  2529. break;
  2530. case 'o': case 'O':
  2531. radix = 8;
  2532. break;
  2533. case 'x': case 'X':
  2534. radix = 16;
  2535. break;
  2536. }
  2537. /* Here I have a number specified in some unusual radix */
  2538. w = fixnum_of_int(0);
  2539. curchar = getc_stream(stream);
  2540. errexit();
  2541. while ((v = value_in_radix(curchar, radix)) >= 0)
  2542. { w = times2(w, fixnum_of_int((int32)radix));
  2543. errexit();
  2544. w = plus2(w, fixnum_of_int(v));
  2545. errexit();
  2546. curchar = getc_stream(stream);
  2547. errexit();
  2548. }
  2549. return w;
  2550. }
  2551. #endif /* COMMON */
  2552. CSLbool is_constituent(int c)
  2553. {
  2554. if (c == EOF) return NO;
  2555. if (c & ESCAPED_CHAR) return YES; /* escaped */
  2556. switch (c)
  2557. {
  2558. /* The following characters terminate symbols */
  2559. case ' ': case '\n': case '\t': case '\v': case '\f': case 0:
  2560. case '(': case ')': case '\'': case ';': case '"': case '`':
  2561. case ',':
  2562. case CTRL_D: /* character 4 is EOF in ASCII */
  2563. #ifndef COMMON
  2564. case '+': case '-': case '*': case '/': case '~': case '\\':
  2565. case '@': case '#': case '$': case '%': case '^': case '&':
  2566. case '=': case '{': case '}': case '[': case ']': case ':':
  2567. case '<': case '>': case '?': case '!': case '|':
  2568. /*
  2569. * case '_': In OLD Standard Lisp underscore was a break character -
  2570. * these days it is classified rather oddly, in that it does not terminate
  2571. * a symbol but behaves specially if it starts one.
  2572. * What about '.', which may need to be treated specially?
  2573. */
  2574. case '.':
  2575. #endif
  2576. return NO;
  2577. default:
  2578. return YES;
  2579. }
  2580. }
  2581. static Lisp_Object backquote_expander(Lisp_Object a)
  2582. /*
  2583. * ClTl (edition 2) seems to suggest that nested backquotes are a disgusting
  2584. * morass - this code does not worry about the fine details!
  2585. */
  2586. {
  2587. Lisp_Object w1, f, nil = C_nil;
  2588. if (a == nil) return a;
  2589. if (!consp(a)) return list2(quote_symbol, a);
  2590. stackcheck1(0, a);
  2591. nil = C_nil;
  2592. f = qcar(a);
  2593. if (f == comma_symbol) return qcar(qcdr(a));
  2594. if (consp(f) && qcar(f) == comma_at_symbol)
  2595. { w1 = qcar(qcdr(f));
  2596. push(w1);
  2597. a = backquote_expander(qcdr(a));
  2598. errexit();
  2599. pop(w1);
  2600. w1 = list2(w1, a);
  2601. errexit();
  2602. return cons(append_symbol, w1);
  2603. }
  2604. /*
  2605. * There is noticable scope for further optimisation here, with the
  2606. * introduction of uses of list, list* as well as just cons and append.
  2607. * It is also probably useful to worry about ,. as well as ,@ but for
  2608. * now I defer that until the full version of the reader is installed.
  2609. */
  2610. push(a);
  2611. f = backquote_expander(f);
  2612. pop(a);
  2613. errexit();
  2614. push(f);
  2615. a = backquote_expander(qcdr(a));
  2616. pop(f);
  2617. errexit();
  2618. a = list2(f, a);
  2619. errexit();
  2620. return cons(cons_symbol, a);
  2621. }
  2622. static CSLbool read_failure;
  2623. static void packbyte(int c)
  2624. {
  2625. Lisp_Object nil = C_nil;
  2626. int32 boffo_size = length_of_header(vechdr(boffo));
  2627. /*
  2628. * I expand boffo (maybe) several characters earlier than you might
  2629. * consider necessary. Some of that is to be extra certain about having
  2630. * space in it when I pack a multi-byte (eg Kanji) character.
  2631. */
  2632. if (boffop >= (int)boffo_size - 12)
  2633. { Lisp_Object new_boffo =
  2634. getvector(TAG_VECTOR, TYPE_STRING, 2*boffo_size);
  2635. nil = C_nil;
  2636. if (exception_pending())
  2637. { flip_exception();
  2638. /*
  2639. * What should I do if I fail to expand boffo - for present I silently
  2640. * truncate the object I am reading. But I set a flag that will be checked
  2641. * on the way out of read/compress, so the user will know.
  2642. */
  2643. read_failure = YES;
  2644. return;
  2645. }
  2646. memcpy((void *)((char *)new_boffo + (CELL-TAG_VECTOR)),
  2647. &boffo_char(0), boffop);
  2648. boffo = new_boffo;
  2649. }
  2650. #ifdef Kanji
  2651. if (iswchar(c)) boffo_char(boffop++) = c >> 8;
  2652. #endif
  2653. boffo_char(boffop) = c;
  2654. boffop++;
  2655. }
  2656. #ifdef COMMON
  2657. static char package_name[32];
  2658. #endif
  2659. static Lisp_Object read_s(Lisp_Object stream)
  2660. {
  2661. Lisp_Object w, nil = C_nil;
  2662. for (;;)
  2663. { skip_whitespace(stream);
  2664. errexit();
  2665. switch (curchar)
  2666. {
  2667. case EOF:
  2668. case CTRL_D:
  2669. return CHAR_EOF;
  2670. case '(':
  2671. curchar = NOT_CHAR;
  2672. skip_whitespace(stream);
  2673. errexit();
  2674. return read_list(stream);
  2675. #ifndef COMMON
  2676. case '[':
  2677. curchar = NOT_CHAR;
  2678. skip_whitespace(stream);
  2679. errexit();
  2680. w = read_list(stream);
  2681. errexit();
  2682. return list_to_vector(w);
  2683. case ']':
  2684. #endif
  2685. case ')':
  2686. curchar = NOT_CHAR;
  2687. continue; /* Ignore spurious rpar */
  2688. case '\'':
  2689. curchar = NOT_CHAR;
  2690. w = read_s(stream);
  2691. errexit();
  2692. return list2(quote_symbol, w);
  2693. case '`':
  2694. curchar = NOT_CHAR;
  2695. w = read_s(stream);
  2696. errexit();
  2697. return backquote_expander(w);
  2698. case ',':
  2699. curchar = getc_stream(stream);
  2700. errexit();
  2701. if (curchar == '@')
  2702. { curchar = NOT_CHAR;
  2703. w = read_s(stream);
  2704. errexit();
  2705. return list2(comma_at_symbol, w);
  2706. }
  2707. else
  2708. { w = read_s(stream);
  2709. errexit();
  2710. return list2(comma_symbol, w);
  2711. }
  2712. /*
  2713. * Neither Standard nor Common Lisp make stray dots very welcome. In Common
  2714. * Lisp multiple adjacent dots are supposed to be an error. Here I just ignore
  2715. * stray dots, and hope that nobody is silly enough to have them in their code.
  2716. */
  2717. case '.':
  2718. /* error("Bad dot"); */
  2719. curchar = NOT_CHAR;
  2720. continue; /* Ignore spurious dot */
  2721. #ifdef COMMON
  2722. case '#':
  2723. push(stream);
  2724. w = read_hash(stream);
  2725. pop(stream);
  2726. if (w != SPID_NOINPUT) return w;
  2727. else return read_s(stream);
  2728. #endif
  2729. case '"':
  2730. boffop = 0;
  2731. { for (;;) /* Used to cope with "abc""def" */
  2732. { curchar = getc_stream(stream);
  2733. errexit();
  2734. #ifdef COMMON
  2735. if (curchar == ESCAPE_CHAR)
  2736. { curchar = getc_stream(stream);
  2737. errexit();
  2738. if (curchar!=EOF) curchar |= ESCAPED_CHAR;
  2739. }
  2740. #endif
  2741. if (curchar == EOF || curchar == CTRL_D)
  2742. return CHAR_EOF;
  2743. while (curchar != '"' &&
  2744. curchar != EOF &&
  2745. curchar != CTRL_D)
  2746. { push(stream);
  2747. packbyte(curchar);
  2748. pop(stream);
  2749. curchar = getc_stream(stream);
  2750. errexit();
  2751. #ifdef COMMON
  2752. if (curchar == ESCAPE_CHAR)
  2753. { curchar = getc_stream(stream);
  2754. errexit();
  2755. if (curchar!=EOF) curchar |= ESCAPED_CHAR;
  2756. }
  2757. #endif
  2758. }
  2759. #ifndef COMMON
  2760. curchar = getc_stream(stream);
  2761. errexit();
  2762. if (curchar == '"')
  2763. { push(stream);
  2764. packbyte(curchar);
  2765. pop(stream);
  2766. continue; /* Handle "abc""def" for Standard Lisp */
  2767. }
  2768. #else
  2769. curchar = NOT_CHAR;
  2770. #endif
  2771. return copy_string(boffo, boffop);
  2772. }
  2773. }
  2774. #ifndef COMMON
  2775. case '+': case '-':
  2776. case '0': case '1': case '2': case '3': case '4':
  2777. case '5': case '6': case '7': case '8': case '9':
  2778. /*
  2779. * I treat numbers specially here since I want to allow '.' within
  2780. * numbers, but NOT within symbols. Common Lisp views '.' as a
  2781. * constituent character and so does not need quite so much effort
  2782. * just here.
  2783. */
  2784. { boffop = 0;
  2785. if (curchar == '+' || curchar == '-')
  2786. { push(stream);
  2787. packbyte(curchar);
  2788. pop(stream);
  2789. curchar = getc_stream(stream);
  2790. errexit();
  2791. /* + or - not followed by a digit will be read as a symbol */
  2792. if (!ISdigit(curchar)) return intern(boffop, NO);
  2793. }
  2794. while (ISdigit(curchar))
  2795. { push(stream);
  2796. packbyte(curchar);
  2797. pop(stream);
  2798. curchar = getc_stream(stream);
  2799. errexit();
  2800. }
  2801. /* accept possible decimal point */
  2802. if (curchar == '.')
  2803. { push(stream);
  2804. packbyte(curchar);
  2805. pop(stream);
  2806. curchar = getc_stream(stream);
  2807. errexit();
  2808. while (ISdigit(curchar))
  2809. { push(stream);
  2810. packbyte(curchar);
  2811. pop(stream);
  2812. curchar = getc_stream(stream);
  2813. errexit();
  2814. }
  2815. }
  2816. /* accept possible exponent */
  2817. if (curchar == 'e' || curchar == 'E')
  2818. { push(stream);
  2819. packbyte('e');
  2820. pop(stream);
  2821. curchar = getc_stream(stream);
  2822. errexit();
  2823. if (curchar == '+' || curchar == '-')
  2824. { push(stream);
  2825. packbyte(curchar);
  2826. pop(stream);
  2827. curchar = getc_stream(stream);
  2828. errexit();
  2829. }
  2830. while (ISdigit(curchar))
  2831. { push(stream);
  2832. packbyte(curchar);
  2833. pop(stream);
  2834. curchar = getc_stream(stream);
  2835. errexit();
  2836. }
  2837. }
  2838. return intern(boffop, NO);
  2839. }
  2840. case '_': /* This seems to have to be a funny case for REDUCE */
  2841. boffop = 0;
  2842. push(stream);
  2843. packbyte(curchar);
  2844. pop(stream);
  2845. curchar = getc_stream(stream);
  2846. errexit();
  2847. return intern(boffop, NO);
  2848. #endif
  2849. default:
  2850. { CSLbool escaped = NO;
  2851. #ifdef COMMON
  2852. CSLbool within_vbars = NO;
  2853. int colon = -1, double_colon = -1, i;
  2854. #endif
  2855. boffop = 0;
  2856. #ifdef COMMON
  2857. while (curchar == '|')
  2858. { nil = C_nil;
  2859. stackcheck0(0);
  2860. curchar = getc_stream(stream);
  2861. errexit();
  2862. within_vbars = !within_vbars;
  2863. /*
  2864. * A funny thought arises here - maybe the characters ||123 are a potential
  2865. * number, since there are no characters inside the vertical bars to show
  2866. * otherwise! Hence I need to set escaped only when I find a genuine character
  2867. * within the vertical-bar protected region. Hence this coded as a while
  2868. * loop not a simple IF statement. Another horrid issue is that the input
  2869. * "|| " (where there are two initial vertical bars and then a terminating
  2870. * character) ought to parse as an identifier with an empty name. Thus
  2871. * if I read ahead here and find whitespace etc I need to exit here.
  2872. */
  2873. if (!within_vbars && !is_constituent(curchar))
  2874. return intern(0, YES);
  2875. }
  2876. #endif
  2877. if (curchar == ESCAPE_CHAR)
  2878. { nil = C_nil;
  2879. stackcheck0(0);
  2880. curchar = getc_stream(stream);
  2881. errexit();
  2882. /* However, any character escaped with '\' means we do not have a number */
  2883. escaped = YES;
  2884. }
  2885. else
  2886. #ifdef COMMON
  2887. if (!within_vbars)
  2888. { if (curchar == ':') colon = boffop, escaped = YES;
  2889. #else
  2890. {
  2891. #endif
  2892. if (curchar != EOF)
  2893. { if (qvalue(lower_symbol) != nil)
  2894. curchar = TOlower(curchar);
  2895. else if (qvalue(raise_symbol) != nil)
  2896. curchar = TOupper(curchar);
  2897. #ifdef Kanji
  2898. if (qvalue(hankaku_symbol) != nil)
  2899. is (iszenkaku(curchar))
  2900. curchar = tohankaku(curchar);
  2901. #endif
  2902. }
  2903. }
  2904. /*
  2905. * Here is the main loop that reads an identifier. Observe the extra
  2906. * complication that Common Lisp generates with the need to support
  2907. * package markers and '|' style escapes...
  2908. */
  2909. do
  2910. { push(stream);
  2911. packbyte(curchar);
  2912. pop(stream);
  2913. curchar = getc_stream(stream);
  2914. errexit();
  2915. #ifdef COMMON
  2916. if (within_vbars) escaped = YES;
  2917. while (curchar == '|')
  2918. { nil = C_nil;
  2919. stackcheck0(0);
  2920. curchar = getc_stream(stream);
  2921. errexit();
  2922. within_vbars = !within_vbars;
  2923. }
  2924. #endif
  2925. if (curchar == EOF) break;
  2926. else if (curchar == ESCAPE_CHAR)
  2927. { nil = C_nil;
  2928. stackcheck0(0);
  2929. curchar = getc_stream(stream);
  2930. errexit();
  2931. curchar |= ESCAPED_CHAR;
  2932. escaped = YES;
  2933. }
  2934. #ifdef COMMON
  2935. else if (!within_vbars)
  2936. { if (curchar == ':')
  2937. { if (colon >= 0) double_colon = boffop;
  2938. else colon = boffop, escaped = YES;
  2939. }
  2940. #endif
  2941. else if (qvalue(lower_symbol) != nil)
  2942. curchar = TOlower(curchar);
  2943. else if (qvalue(raise_symbol) != nil)
  2944. curchar = TOupper(curchar);
  2945. #ifdef Kanji
  2946. if (qvalue(hankaku_symbol) != nil)
  2947. is (iszenkaku(curchar))
  2948. curchar = tohankaku(curchar);
  2949. #endif
  2950. #ifdef COMMON
  2951. }
  2952. } while (within_vbars || is_constituent(curchar));
  2953. #else
  2954. } while (is_constituent(curchar));
  2955. #endif
  2956. #ifdef COMMON
  2957. /*
  2958. * If there are no colons present, or if there are two but they
  2959. * are not consecutive, or of there are three or more, or if the last
  2960. * character of the symbol was a colon, I will just look it up in
  2961. * the current package.
  2962. */
  2963. if (colon < 0 || colon+1==boffop)
  2964. return intern(boffop, escaped);
  2965. if ((double_colon >= 0 && double_colon != colon+1) ||
  2966. double_colon+1==boffop)
  2967. return intern(boffop, escaped);
  2968. /*
  2969. * If the first character was a colon I use the keyword package.
  2970. */
  2971. memset(package_name, 0, sizeof(package_name));
  2972. strncpy(package_name, &celt(boffo, 0), (size_t)colon);
  2973. package_name[sizeof(package_name)-1] = 0;
  2974. /* term_printf("Package lookup <%.*s>\n", (int)colon, &celt(boffo, 0)); */
  2975. if (colon == 0) w = qvalue(keyword_package);
  2976. else w = find_package(&celt(boffo, 0), colon);
  2977. /*
  2978. * Here I rely on find_package never raising an exception and never giving
  2979. * a possible entry into a break loop (etc), since I need boffo[] intact
  2980. * after the call.
  2981. */
  2982. if (w == nil)
  2983. { err_printf(
  2984. "+++ Package %s not found: using current package\n",
  2985. package_name);
  2986. /*
  2987. * Similarly I assume, unreasonably, that boffo can not be disturbed by
  2988. * printing this warning message.
  2989. */
  2990. w = CP; /* default behaviour: unknown package */
  2991. }
  2992. if (double_colon >= 0) colon = double_colon;
  2993. i = 0;
  2994. colon++;
  2995. while (colon < boffop)
  2996. boffo_char(i++) = boffo_char(colon++);
  2997. boffop = i;
  2998. /* term_printf("Name within package <%.*s>\n", (int)boffop, &celt(boffo, 0)); */
  2999. if (double_colon < 0 && w != qvalue(keyword_package))
  3000. { /* In the case ppp:sss it MUST be external in ppp */
  3001. Lisp_Object wx;
  3002. push(w);
  3003. wx = iintern(boffo, (int32)boffop, w, 4);
  3004. pop(w);
  3005. errexit();
  3006. if (mv_2 == nil)
  3007. { err_printf("+++ Symbol %.*s not external in %s\n",
  3008. (int)boffop, &celt(boffo, 0), package_name);
  3009. err_printf("+++ Treating as internal symbol...\n");
  3010. }
  3011. else return wx;
  3012. }
  3013. /*
  3014. * Curiously I will always take keywords (as in :kkk) through the path
  3015. * that corresponds to looking up an internal symbol, ie ::kkk, since that
  3016. * way I allow the reader to create a new symbol. If I handled the keyword
  3017. * case in the usual external symbol way it would demand that the keyword
  3018. * already existed (since in all other packages nothing is external unless
  3019. * it already exists and has been exported).
  3020. */
  3021. return iintern(boffo, (int32)boffop, w, 0);
  3022. #else
  3023. return intern(boffop, escaped);
  3024. #endif
  3025. }
  3026. }
  3027. }
  3028. }
  3029. int char_from_synonym(Lisp_Object stream)
  3030. {
  3031. stream = qvalue(stream_read_data(stream));
  3032. if (!is_stream(stream)) return aerror1("bad synonym stream", stream);
  3033. return getc_stream(stream);
  3034. }
  3035. int char_from_concatenated(Lisp_Object stream)
  3036. {
  3037. Lisp_Object l = stream_read_data(stream), s1;
  3038. Lisp_Object nil = C_nil;
  3039. int c;
  3040. while (consp(l))
  3041. { s1 = qcar(l);
  3042. if (!is_symbol(s1))
  3043. { l = qcdr(l);
  3044. stream_read_data(stream) = l;
  3045. continue;
  3046. }
  3047. s1 = qvalue(s1);
  3048. if (!is_stream(s1))
  3049. { l = qcdr(l);
  3050. stream_read_data(stream) = l;
  3051. continue;
  3052. }
  3053. push2(l, stream);
  3054. c = getc_stream(s1);
  3055. pop2(stream, l);
  3056. errexit();
  3057. if (c == EOF)
  3058. { l = qcdr(l);
  3059. stream_read_data(stream) = l;
  3060. continue;
  3061. }
  3062. }
  3063. return EOF;
  3064. }
  3065. int char_from_echo(Lisp_Object stream)
  3066. {
  3067. int c;
  3068. Lisp_Object stream1 = qvalue(stream_read_data(stream));
  3069. if (!is_stream(stream1)) return aerror1("bad synonym stream", stream1);
  3070. c = getc_stream(stream1);
  3071. char_to_synonym(c, stream);
  3072. return c;
  3073. }
  3074. int char_from_file(Lisp_Object stream)
  3075. {
  3076. Lisp_Object nil = C_nil;
  3077. int ch = stream_pushed_char(stream);
  3078. if (ch == NOT_CHAR)
  3079. {
  3080. #ifdef Kanji
  3081. ch = getwc(stream_file(stream));
  3082. #else
  3083. ch = getc(stream_file(stream));
  3084. #endif
  3085. if (ch == EOF
  3086. /* || ch == CTRL_D */
  3087. ) return EOF;
  3088. if (qvalue(echo_symbol) != nil)
  3089. { Lisp_Object stream1 = qvalue(standard_output);
  3090. if (!is_stream(stream1)) stream1 = qvalue(terminal_io);
  3091. if (!is_stream(stream1)) stream1 = lisp_terminal_io;
  3092. putc_stream(ch, stream1);
  3093. if (exception_pending()) flip_exception();
  3094. }
  3095. }
  3096. else stream_pushed_char(stream) = NOT_CHAR;
  3097. return ch;
  3098. }
  3099. int32 read_action_illegal(int32 op, Lisp_Object f)
  3100. {
  3101. CSL_IGNORE(f);
  3102. if (op != READ_CLOSE && op != READ_IS_CONSOLE)
  3103. aerror1("Illegal operation on stream",
  3104. cons_no_gc(fixnum_of_int(op), stream_type(f)));
  3105. return 0;
  3106. }
  3107. int32 read_action_file(int32 op, Lisp_Object f)
  3108. {
  3109. if (op < -1) return fseek(stream_file(f), op & 0x7fffffff, SEEK_SET);
  3110. else if (op <= 0xffff) return (stream_pushed_char(f) = op);
  3111. else switch (op)
  3112. {
  3113. case READ_CLOSE:
  3114. if (stream_file(f) == NULL) op = 0;
  3115. else op = fclose(stream_file(f));
  3116. set_stream_read_fn(f, char_from_illegal);
  3117. set_stream_read_other(f, read_action_illegal);
  3118. set_stream_file(f, NULL);
  3119. return op;
  3120. case READ_FLUSH:
  3121. stream_pushed_char(f) = NOT_CHAR;
  3122. return 0;
  3123. case READ_TELL:
  3124. if ((op = stream_pushed_char(f)) != NOT_CHAR)
  3125. { ungetc(op, stream_file(f));
  3126. stream_pushed_char(f) = NOT_CHAR;
  3127. }
  3128. return (int32)ftell(stream_file(f));
  3129. case READ_END:
  3130. return fseek(stream_file(f), 0L, SEEK_END);
  3131. case READ_IS_CONSOLE:
  3132. return 0;
  3133. default:
  3134. return 0;
  3135. }
  3136. }
  3137. int32 read_action_output_file(int32 op, Lisp_Object f)
  3138. {
  3139. if (op < -1) return fseek(stream_file(f), op & 0x7fffffff, SEEK_SET);
  3140. else if (op <= 0xffff) return 0;
  3141. else switch (op)
  3142. {
  3143. case READ_TELL:
  3144. op = ftell(stream_file(f));
  3145. return op;
  3146. case READ_END:
  3147. return fseek(stream_file(f), 0L, SEEK_END);
  3148. default:
  3149. return 0;
  3150. }
  3151. }
  3152. int32 read_action_terminal(int32 op, Lisp_Object f)
  3153. {
  3154. CSL_IGNORE(f);
  3155. if (op < -1) return 1;
  3156. else if (op <= 0xffff) return (terminal_pushed = op);
  3157. else switch (op)
  3158. {
  3159. case READ_CLOSE:
  3160. return 0;
  3161. case READ_FLUSH:
  3162. terminal_pushed = NOT_CHAR;
  3163. tty_count = 0;
  3164. return 0;
  3165. case READ_TELL:
  3166. return -1;
  3167. case READ_IS_CONSOLE:
  3168. return 1;
  3169. default:
  3170. return 0;
  3171. }
  3172. }
  3173. int32 read_action_synonym(int32 c, Lisp_Object f)
  3174. {
  3175. int32 r;
  3176. Lisp_Object f1;
  3177. f1 = qvalue(stream_read_data(f));
  3178. if (!is_stream(f1)) return aerror1("bad synonym stream", f1);
  3179. r = other_read_action(c, f1);
  3180. if (c == READ_CLOSE)
  3181. { set_stream_read_fn(f, char_from_illegal);
  3182. set_stream_read_other(f, read_action_illegal);
  3183. set_stream_file(f, NULL);
  3184. }
  3185. return r;
  3186. }
  3187. int32 read_action_concatenated(int32 c, Lisp_Object f)
  3188. {
  3189. int32 r = 0, r1;
  3190. Lisp_Object l, f1;
  3191. #ifdef COMMON
  3192. Lisp_Object nil = C_nil;
  3193. #endif
  3194. l = stream_read_data(f);
  3195. while (consp(l))
  3196. { f1 = qcar(l);
  3197. l = qcdr(l);
  3198. if (!is_symbol(f1)) continue;
  3199. f1 = qvalue(f1);
  3200. if (!is_stream(f1)) continue;
  3201. push2(l, f);
  3202. r1 = other_read_action(c, f1);
  3203. pop2(f, l);
  3204. if (r == 0) r = r1;
  3205. }
  3206. if (c == READ_CLOSE)
  3207. { set_stream_read_fn(f, char_from_illegal);
  3208. set_stream_read_other(f, read_action_illegal);
  3209. set_stream_file(f, NULL);
  3210. }
  3211. return r;
  3212. }
  3213. int32 read_action_list(int32 op, Lisp_Object f)
  3214. {
  3215. if (op < -1) return 1;
  3216. else if (op <= 0xffff) return (stream_pushed_char(f) = op);
  3217. else switch (op)
  3218. {
  3219. case READ_CLOSE:
  3220. set_stream_read_fn(f, char_from_illegal);
  3221. set_stream_read_other(f, read_action_illegal);
  3222. set_stream_file(f, NULL);
  3223. stream_read_data(f) = C_nil;
  3224. return 0;
  3225. case READ_FLUSH:
  3226. stream_pushed_char(f) = NOT_CHAR;
  3227. return 0;
  3228. case READ_TELL:
  3229. return -1;
  3230. case READ_IS_CONSOLE:
  3231. return 0;
  3232. default:
  3233. return 0;
  3234. }
  3235. }
  3236. int32 read_action_vector(int32 op, Lisp_Object f)
  3237. {
  3238. if (op < -1) return 1;
  3239. else if (op <= 0xffff) return (stream_pushed_char(f) = op);
  3240. else switch (op)
  3241. {
  3242. case READ_CLOSE:
  3243. set_stream_read_fn(f, char_from_illegal);
  3244. set_stream_read_other(f, read_action_illegal);
  3245. set_stream_file(f, NULL);
  3246. stream_read_data(f) = C_nil;
  3247. return 0;
  3248. case READ_FLUSH:
  3249. stream_pushed_char(f) = NOT_CHAR;
  3250. return 0;
  3251. case READ_TELL:
  3252. return -1;
  3253. case READ_IS_CONSOLE:
  3254. return 0;
  3255. default:
  3256. return 0;
  3257. }
  3258. }
  3259. static int most_recent_read_point = 0;
  3260. Lisp_Object MS_CDECL Lread(Lisp_Object nil, int nargs, ...)
  3261. /*
  3262. * The full version of read_s() has to support extra optional args
  3263. * that deal with error and eof returns... and a recursive-p arg!
  3264. */
  3265. {
  3266. Lisp_Object w, stream = qvalue(standard_input);
  3267. int cursave = curchar;
  3268. argcheck(nargs, 0, "read");
  3269. #ifdef COMMON
  3270. push(reader_workspace);
  3271. reader_workspace = nil;
  3272. #endif
  3273. read_failure = NO;
  3274. if (!is_stream(stream)) stream = qvalue(terminal_io);
  3275. if (!is_stream(stream)) stream = lisp_terminal_io;
  3276. curchar = NOT_CHAR;
  3277. most_recent_read_point = other_read_action(READ_TELL, stream);
  3278. push(stream);
  3279. w = read_s(stream);
  3280. pop(stream);
  3281. if (curchar != NOT_CHAR) other_read_action(curchar, stream);
  3282. curchar = cursave;
  3283. current_file = stream_type(stream);
  3284. #ifdef COMMON
  3285. nil = C_nil;
  3286. if (exception_pending())
  3287. { flip_exception();
  3288. pop(reader_workspace);
  3289. flip_exception();
  3290. return nil;
  3291. }
  3292. pop(reader_workspace);
  3293. #else
  3294. errexit();
  3295. #endif
  3296. if (read_failure) return aerror("read");
  3297. return onevalue(w);
  3298. }
  3299. static Lisp_Object MS_CDECL Lwhere_was_that(Lisp_Object nil, int nargs, ...)
  3300. {
  3301. Lisp_Object w;
  3302. argcheck(nargs, 0, "where-was-that");
  3303. #ifdef COMMON
  3304. w = list3(current_file, fixnum_of_int(most_recent_read_point),
  3305. packname_(CP));
  3306. #else
  3307. w = list2(current_file, fixnum_of_int(most_recent_read_point));
  3308. #endif
  3309. errexit();
  3310. return onevalue(w);
  3311. }
  3312. #ifdef COMMON
  3313. Lisp_Object Lread_1(Lisp_Object nil, Lisp_Object stream)
  3314. {
  3315. int cursave = curchar;
  3316. Lisp_Object w;
  3317. Lisp_Object save = Lrds(nil, stream);
  3318. errexit();
  3319. push2(reader_workspace, save);
  3320. reader_workspace = nil;
  3321. read_failure = NO;
  3322. stream = qvalue(standard_input);
  3323. if (!is_stream(stream)) stream = qvalue(terminal_io);
  3324. if (!is_stream(stream)) stream = lisp_terminal_io;
  3325. curchar = NOT_CHAR;
  3326. w = read_s(stream);
  3327. if (curchar != NOT_CHAR) other_read_action(curchar, stream);
  3328. curchar = cursave;
  3329. nil = C_nil;
  3330. if (exception_pending())
  3331. { flip_exception();
  3332. pop2(save, reader_workspace);
  3333. Lrds(nil, save);
  3334. errexit();
  3335. flip_exception();
  3336. return nil;
  3337. }
  3338. pop2(save, reader_workspace);
  3339. push(w);
  3340. Lrds(nil, save);
  3341. pop(w);
  3342. errexit();
  3343. if (read_failure) return aerror("read");
  3344. return onevalue(w);
  3345. }
  3346. #endif
  3347. /*
  3348. * compress is not a Common Lisp function, but it is another on those
  3349. * things that I want within my implementation for internal purposes as
  3350. * well as for real use.
  3351. */
  3352. int char_from_list(Lisp_Object f)
  3353. {
  3354. #ifdef COMMON
  3355. Lisp_Object nil = C_nil;
  3356. #else
  3357. nil_as_base
  3358. #endif
  3359. Lisp_Object ch = stream_pushed_char(f);
  3360. if (ch == NOT_CHAR)
  3361. { if (!consp(stream_read_data(f))) ch = EOF;
  3362. else
  3363. { ch = qcar(stream_read_data(f));
  3364. stream_read_data(f) = qcdr(stream_read_data(f));
  3365. }
  3366. /*
  3367. * here I tend towards generosity - a symbol stands for the first character
  3368. * of its name, and character objects and numbers (representing internal
  3369. * codes) are also permitted. Incomplete gensyms are OK here - I just
  3370. * use the first character of the base of the name.
  3371. */
  3372. if (is_symbol(ch)) ch = first_char(ch);
  3373. else if (is_char(ch)) ch = (char)code_of_char(ch);
  3374. else if (is_fixnum(ch)) ch = (char)int_of_fixnum(ch);
  3375. else ch = EOF; /* Bad item in the list */
  3376. }
  3377. else stream_pushed_char(f) = NOT_CHAR;
  3378. return ch;
  3379. }
  3380. int char_from_vector(Lisp_Object f)
  3381. {
  3382. #ifdef COMMON
  3383. Lisp_Object nil = C_nil;
  3384. #else
  3385. nil_as_base
  3386. #endif
  3387. Lisp_Object ch = stream_pushed_char(f);
  3388. if (ch == NOT_CHAR)
  3389. { char *v = (char *)stream_file(f);
  3390. if (v == NULL) ch = EOF;
  3391. else
  3392. { ch = *v++;
  3393. if (ch == 0) ch = EOF;
  3394. else set_stream_file(f, (FILE *)v);
  3395. }
  3396. }
  3397. else stream_pushed_char(f) = NOT_CHAR;
  3398. return ch;
  3399. }
  3400. Lisp_Object read_from_vector(char *v)
  3401. {
  3402. int savecur = curchar;
  3403. Lisp_Object nil = C_nil, r;
  3404. stream_read_data(lisp_work_stream) = nil;
  3405. set_stream_read_fn(lisp_work_stream, char_from_vector);
  3406. set_stream_read_other(lisp_work_stream, read_action_vector);
  3407. stream_pushed_char(lisp_work_stream) = NOT_CHAR;
  3408. set_stream_file(lisp_work_stream, (FILE *)v);
  3409. read_failure = NO;
  3410. curchar = NOT_CHAR;
  3411. r = read_s(lisp_work_stream);
  3412. errexit();
  3413. curchar = savecur;
  3414. if (read_failure) return aerror("read-from-vector");
  3415. return onevalue(r);
  3416. }
  3417. Lisp_Object Lcompress(Lisp_Object env, Lisp_Object stream)
  3418. {
  3419. int savecur = curchar;
  3420. Lisp_Object nil = C_nil;
  3421. stream_read_data(lisp_work_stream) = stream;
  3422. set_stream_read_fn(lisp_work_stream, char_from_list);
  3423. set_stream_read_other(lisp_work_stream, read_action_list);
  3424. stream_pushed_char(lisp_work_stream) = NOT_CHAR;
  3425. read_failure = NO;
  3426. curchar = NOT_CHAR;
  3427. env = read_s(lisp_work_stream);
  3428. errexit();
  3429. stream_read_data(lisp_work_stream) = C_nil;
  3430. curchar = savecur;
  3431. if (read_failure) return aerror("compress");
  3432. return onevalue(env);
  3433. }
  3434. Lisp_Object Llist_to_string(Lisp_Object nil, Lisp_Object stream)
  3435. {
  3436. int n = 0, k;
  3437. Lisp_Object str;
  3438. char *s;
  3439. stream_read_data(lisp_work_stream) = stream;
  3440. set_stream_read_fn(lisp_work_stream, char_from_list);
  3441. set_stream_read_other(lisp_work_stream, read_action_list);
  3442. stream_pushed_char(lisp_work_stream) = NOT_CHAR;
  3443. while (consp(stream)) n++, stream = qcdr(stream);
  3444. str = getvector(TAG_VECTOR, TYPE_STRING, CELL+n);
  3445. errexit();
  3446. s = (char *)str - TAG_VECTOR;
  3447. k = (n + 3) & ~7;
  3448. /* Here I zero out the last doubleword of the new string */
  3449. *(int32 *)(s + k + 4) = 0;
  3450. if (k != 0) *(int32 *)(s + k) = 0;
  3451. s = s + 4;
  3452. for (k=0; k<n; k++) *s++ = char_from_list(lisp_work_stream);
  3453. return onevalue(str);
  3454. }
  3455. Lisp_Object Llist_to_symbol(Lisp_Object nil, Lisp_Object stream)
  3456. {
  3457. stream = Llist_to_string(nil, stream);
  3458. errexit();
  3459. #ifdef COMMON
  3460. stream = Lintern_2(nil, stream, CP);
  3461. errexit();
  3462. return onevalue(stream); /* NB intern would have returned 2 values */
  3463. #else
  3464. return Lintern(nil, stream);
  3465. #endif
  3466. }
  3467. void read_eval_print(int noisy)
  3468. {
  3469. Lisp_Object nil = C_nil, *save = stack;
  3470. #ifndef __cplusplus
  3471. jmp_buf this_level, *saved_buffer = errorset_buffer;
  3472. #endif
  3473. push2(codevec, litvec);
  3474. for (;;) /* Loop for each s-expression found */
  3475. { Lisp_Object u;
  3476. #ifdef COMMON
  3477. int32 nvals, i;
  3478. #endif
  3479. miscflags |= (HEADLINE_FLAG | MESSAGES_FLAG);
  3480. errorset_msg = NULL;
  3481. #ifdef __cplusplus
  3482. try
  3483. #else
  3484. if (!setjmp(this_level))
  3485. #endif
  3486. {
  3487. #ifndef __cplusplus
  3488. errorset_buffer = &this_level;
  3489. #endif
  3490. u = Lread(nil, 0);
  3491. }
  3492. #ifdef __cplusplus
  3493. catch (char *)
  3494. #else
  3495. else
  3496. #endif
  3497. { if (errorset_msg != NULL)
  3498. { term_printf("\n%s detected\n", errorset_msg);
  3499. errorset_msg = NULL;
  3500. }
  3501. unwind_stack(save, NO);
  3502. stack = save;
  3503. signal(SIGFPE, low_level_signal_handler);
  3504. #ifdef __WATCOMC__
  3505. _control87(_EM_OVERFLOW | _EM_INVALID | _EM_DENORMAL |
  3506. _EM_ZERODIVIDE | _EM_INEXACT | _EM_UNDERFLOW,
  3507. _MCW_EM);
  3508. #endif
  3509. if (segvtrap) signal(SIGSEGV, low_level_signal_handler);
  3510. #ifdef SIGBUS
  3511. if (segvtrap) signal(SIGBUS, low_level_signal_handler);
  3512. #endif
  3513. #ifdef SIGILL
  3514. if (segvtrap) signal(SIGILL, low_level_signal_handler);
  3515. #endif
  3516. err_printf("\n... read failed\n");
  3517. continue;
  3518. }
  3519. nil = C_nil;
  3520. if (exception_pending())
  3521. { flip_exception();
  3522. /*
  3523. * Maybe (stop) or (preserve) was called from a read-macro? Otherwise
  3524. * errors reading are ignored and the system tries to read the next
  3525. * expression for evaluation. Note that this behaviour means that
  3526. * perhaps unreasonably or unexpectedly, THROW will not be propagated
  3527. * back past a read_eval_print loop.
  3528. */
  3529. if (exit_reason == UNWIND_RESTART)
  3530. {
  3531. #ifndef __cplusplus
  3532. errorset_buffer = saved_buffer;
  3533. #endif
  3534. pop2(litvec, codevec);
  3535. flip_exception();
  3536. return;
  3537. }
  3538. err_printf("\n... read failed\n");
  3539. continue;
  3540. }
  3541. /*
  3542. * This will stop at end of file. That could EITHER be a real proper
  3543. * end of file, or the user having #\eof in the input file. These are NOT
  3544. * equivalent, in that #\eof is read once and then further stuff from the
  3545. * stream can be read, while a real EOF (eg typing ^D at the terminal in
  3546. * some cases) ends the stream once and for all.
  3547. */
  3548. if (u == CHAR_EOF)
  3549. {
  3550. #ifndef __cplusplus
  3551. errorset_buffer = saved_buffer;
  3552. #endif
  3553. pop2(litvec, codevec);
  3554. return;
  3555. }
  3556. if (qvalue(standard_input) == lisp_terminal_io &&
  3557. spool_file != NULL) putc('\n', spool_file);
  3558. miscflags |= (HEADLINE_FLAG | MESSAGES_FLAG);
  3559. errorset_msg = NULL;
  3560. #ifdef __cplusplus
  3561. try
  3562. #else
  3563. if (!setjmp(this_level))
  3564. #endif
  3565. { u = eval(u, nil);
  3566. nil = C_nil;
  3567. if (exception_pending())
  3568. { flip_exception(); /* safe again! */
  3569. if (exit_reason == UNWIND_RESTART)
  3570. {
  3571. #ifndef __cplusplus
  3572. errorset_buffer = saved_buffer;
  3573. #endif
  3574. pop2(litvec, codevec);
  3575. flip_exception();
  3576. return;
  3577. }
  3578. err_printf("\n... continuing after error\n");
  3579. if (spool_file != NULL) fflush(spool_file);
  3580. continue;
  3581. }
  3582. if (noisy)
  3583. {
  3584. #ifndef COMMON
  3585. print(u); /* Always exactly one value */
  3586. stdout_printf("\n");
  3587. nil = C_nil;
  3588. if (exception_pending()) flip_exception();
  3589. #else
  3590. nvals = exit_count;
  3591. /*
  3592. * These days I have to push mv_2 because print can call find-symbol to
  3593. * decide if it needs to display a package qualifier, and in that case
  3594. * it alters mv_2 on the way... But at present it should never change
  3595. * any higher multiple value. I guess if it were interrupted then a break
  3596. * loop (if one existed) could corrupt almost anything, but I will
  3597. * ignore that worry.
  3598. */
  3599. if (nvals > 0)
  3600. { push(mv_2);
  3601. print(u);
  3602. pop(u);
  3603. }
  3604. nil = C_nil;
  3605. if (exception_pending()) flip_exception();
  3606. mv_2 = u;
  3607. miscflags |= (HEADLINE_FLAG | MESSAGES_FLAG);
  3608. for (i=2; i<=nvals; i++)
  3609. { print((&mv_2)[i-2]);
  3610. nil = C_nil;
  3611. if (exception_pending())
  3612. { flip_exception();
  3613. break;
  3614. }
  3615. }
  3616. stdout_printf("\n");
  3617. #endif
  3618. }
  3619. }
  3620. #ifdef __cplusplus
  3621. catch (char *)
  3622. #else
  3623. else
  3624. #endif
  3625. { if (errorset_msg != NULL)
  3626. { term_printf("\n%s detected\n", errorset_msg);
  3627. errorset_msg = NULL;
  3628. }
  3629. unwind_stack(save, NO);
  3630. stack = save;
  3631. signal(SIGFPE, low_level_signal_handler);
  3632. #ifdef __WATCOMC__
  3633. _control87(_EM_OVERFLOW | _EM_INVALID | _EM_DENORMAL |
  3634. _EM_ZERODIVIDE | _EM_INEXACT | _EM_UNDERFLOW,
  3635. _MCW_EM);
  3636. #endif
  3637. if (segvtrap) signal(SIGSEGV, low_level_signal_handler);
  3638. #ifdef SIGBUS
  3639. if (segvtrap) signal(SIGBUS, low_level_signal_handler);
  3640. #endif
  3641. #ifdef SIGILL
  3642. if (segvtrap) signal(SIGILL, low_level_signal_handler);
  3643. #endif
  3644. err_printf("\n... continuing after error\n");
  3645. if (spool_file != NULL) fflush(spool_file);
  3646. continue;
  3647. }
  3648. }
  3649. }
  3650. /*
  3651. * RDF is wanted as it is in Standard Lisp. In Common Lisp the corresponding
  3652. * function is LOAD. LOAD takes keyword arguments, which are decoded
  3653. * elsewhere, leaving the code here which takes a variable number of
  3654. * args, but all with definite simple interpretations.
  3655. */
  3656. Lisp_Object Lrdf4(Lisp_Object nil, Lisp_Object file, Lisp_Object noisyp,
  3657. Lisp_Object verbosep, Lisp_Object nofilep)
  3658. {
  3659. Lisp_Object r = nil;
  3660. int noisy = (noisyp != nil),
  3661. #ifdef COMMON
  3662. nofile = (nofilep != nil),
  3663. #endif
  3664. verbose = (verbosep != nil);
  3665. #ifndef COMMON
  3666. CSL_IGNORE(nofilep);
  3667. #endif
  3668. /*
  3669. * (rdf nil)/(load nil) obeys Lisp commands from the current input
  3670. */
  3671. push3(nil, nil, file);
  3672. /*
  3673. * I have a somewhat comical chunk of code here. If the file-name passed
  3674. * across ends in a suffix that is one of ".o", ".fsl" or ".fasl" then
  3675. * instead of reading a textual source file the way one might have
  3676. * expected I will subvert things and perform LOAD-MODULE instead.
  3677. */
  3678. if (file != nil)
  3679. { Header h;
  3680. char *filestring;
  3681. char tail[8];
  3682. int32 i, len;
  3683. #ifdef COMMON
  3684. if (complex_stringp(file))
  3685. { file = simplify_string(file);
  3686. errexitn(3);
  3687. }
  3688. #endif
  3689. if (symbolp(file))
  3690. { file = get_pname(file);
  3691. errexitn(3);
  3692. h = vechdr(file);
  3693. }
  3694. else if (!is_vector(file) ||
  3695. type_of_header(h = vechdr(file)) != TYPE_STRING)
  3696. return aerror1("load", file);
  3697. len = length_of_header(h) - CELL;
  3698. filestring = (char *)file + CELL-TAG_VECTOR;
  3699. for (i=0; i<6; i++)
  3700. { if (len == 0)
  3701. { tail[i] = 0;
  3702. break;
  3703. }
  3704. else tail[i] = tolower(filestring[--len]);
  3705. }
  3706. if (strncmp(tail, "lsf.", 4) == 0 ||
  3707. strncmp(tail, "lasf.", 5) == 0 ||
  3708. strncmp(tail, "o.", 2) == 0)
  3709. { stack[0] = file;
  3710. if (verbose)
  3711. {
  3712. #ifdef COMMON
  3713. trace_printf("\n;; Loading module ");
  3714. #else
  3715. trace_printf("\nReading module ");
  3716. #endif
  3717. loop_print_trace(file); trace_printf("\n");
  3718. }
  3719. Lload_module(nil, stack[0]);
  3720. errexitn(3);
  3721. if (verbose)
  3722. {
  3723. #ifdef COMMON
  3724. trace_printf("\n;; Loaded module ");
  3725. #else
  3726. trace_printf("\nRead module ");
  3727. #endif
  3728. loop_print_trace(stack[0]); trace_printf("\n");
  3729. }
  3730. popv(3);
  3731. #ifdef COMMON
  3732. return onevalue(lisp_true);
  3733. #else
  3734. return onevalue(nil);
  3735. #endif
  3736. }
  3737. stack[-1] = r = Lopen(nil, file, fixnum_of_int(1+64));
  3738. errexitn(3);
  3739. #ifdef COMMON
  3740. /*
  3741. * The test here is necessary since in Common Lisp mode an attempt to OPEN a
  3742. * file that can not be accessed returns NIL rather than raising an
  3743. * exception.
  3744. */
  3745. if (r == nil)
  3746. { pop(file);
  3747. popv(2);
  3748. if (nofile) return error(1, err_open_failed, file);
  3749. else return onevalue(nil);
  3750. }
  3751. #endif
  3752. stack[-2] = r = Lrds(nil, r);
  3753. errexitn(3);
  3754. if (verbose)
  3755. { file = stack[0];
  3756. #ifdef COMMON
  3757. trace_printf("\n;; Loading "); loop_print_trace(file); trace_printf("\n");
  3758. #else
  3759. trace_printf("\nReading "); loop_print_trace(file); trace_printf("\n");
  3760. #endif
  3761. }
  3762. errexitn(3);
  3763. }
  3764. read_eval_print(noisy);
  3765. nil = C_nil;
  3766. if (exception_pending())
  3767. { flip_exception();
  3768. if (exit_reason == UNWIND_ERROR)
  3769. {
  3770. #ifdef COMMON
  3771. trace_printf("\n;; Loaded ");
  3772. #else
  3773. trace_printf("\nFinished reading ");
  3774. #endif
  3775. loop_print_trace(stack[0]);
  3776. trace_printf(" (bad)\n");
  3777. }
  3778. if (stack[0] != nil)
  3779. { Lclose(nil, stack[-1]);
  3780. nil = C_nil;
  3781. if (exception_pending()) flip_exception();
  3782. Lrds(nil, stack[-2]);
  3783. errexitn(3);
  3784. }
  3785. flip_exception();
  3786. popv(3);
  3787. return nil;
  3788. }
  3789. #ifdef COMMON
  3790. trace_printf("\n;; Loaded ");
  3791. #else
  3792. trace_printf("\nRead ");
  3793. #endif
  3794. loop_print_trace(stack[0]);
  3795. trace_printf("\n");
  3796. if (stack[0] != nil)
  3797. { Lclose(nil, stack[-1]);
  3798. nil = C_nil;
  3799. if (exception_pending()) flip_exception();
  3800. Lrds(nil, stack[-2]);
  3801. errexitn(3);
  3802. }
  3803. popv(3);
  3804. #ifdef COMMON
  3805. return onevalue(lisp_true);
  3806. #else
  3807. return onevalue(nil);
  3808. #endif
  3809. }
  3810. Lisp_Object Lrdf1(Lisp_Object nil, Lisp_Object file)
  3811. {
  3812. return Lrdf4(nil, file, lisp_true, lisp_true, lisp_true);
  3813. }
  3814. Lisp_Object Lrdf2(Lisp_Object nil, Lisp_Object file, Lisp_Object noisy)
  3815. {
  3816. return Lrdf4(nil, file, noisy, lisp_true, lisp_true);
  3817. }
  3818. Lisp_Object MS_CDECL Lrdfn(Lisp_Object nil, int nargs, ...)
  3819. {
  3820. va_list a;
  3821. Lisp_Object file, noisy, verbose, nofile = lisp_true;
  3822. if (nargs < 3 || nargs > 4) return aerror("load");
  3823. va_start(a, nargs);
  3824. file = va_arg(a, Lisp_Object);
  3825. noisy = va_arg(a, Lisp_Object);
  3826. verbose = va_arg(a, Lisp_Object);
  3827. if (nargs > 3) nofile = va_arg(a, Lisp_Object);
  3828. va_end(a);
  3829. return Lrdf4(nil, file, noisy, verbose, nofile);
  3830. }
  3831. #ifdef COMMON
  3832. #define spool_name "dribble"
  3833. #else
  3834. #define spool_name "spool"
  3835. #endif
  3836. Lisp_Object Lspool(Lisp_Object nil, Lisp_Object file)
  3837. {
  3838. char filename[LONGEST_LEGAL_FILENAME];
  3839. Header h;
  3840. int32 len;
  3841. #ifdef SOCKETS
  3842. /*
  3843. * Security measure - remote client can not do "spool"
  3844. */
  3845. if (socket_server != 0) return onevalue(nil);
  3846. #endif
  3847. if (spool_file != NULL)
  3848. {
  3849. #ifdef COMMON
  3850. fprintf(spool_file, "\nFinished dribbling to %s.\n", spool_file_name);
  3851. #else
  3852. fprintf(spool_file, "\n+++ End of transcript +++\n");
  3853. #endif
  3854. fclose(spool_file);
  3855. spool_file = NULL;
  3856. }
  3857. if (file == nil) return onevalue(lisp_true);
  3858. #ifdef COMMON
  3859. if (complex_stringp(file))
  3860. { file = simplify_string(file);
  3861. errexit();
  3862. }
  3863. #endif
  3864. if (symbolp(file))
  3865. { file = get_pname(file);
  3866. errexit();
  3867. h = vechdr(file);
  3868. }
  3869. if (!is_vector(file) ||
  3870. type_of_header(h = vechdr(file)) != TYPE_STRING)
  3871. return aerror1(spool_name, file);
  3872. len = length_of_header(h) - CELL;
  3873. spool_file = open_file(filename,
  3874. (char *)file + (CELL-TAG_VECTOR),
  3875. (size_t)len, "w", NULL);
  3876. if (spool_file != NULL)
  3877. { time_t t0 = time(NULL);
  3878. strncpy(spool_file_name, filename, 32);
  3879. spool_file_name[31] = 0;
  3880. #ifdef COMMON
  3881. fprintf(spool_file, "Starts dribbling to %s (%.24s)\n",
  3882. spool_file_name, ctime(&t0));
  3883. #else
  3884. fprintf(spool_file, "+++ Transcript to %s started at %.24s +++\n",
  3885. spool_file_name, ctime(&t0));
  3886. #endif
  3887. return onevalue(lisp_true);
  3888. }
  3889. return onevalue(nil);
  3890. }
  3891. static Lisp_Object MS_CDECL Lspool0(Lisp_Object nil, int nargs, ...)
  3892. {
  3893. argcheck(nargs, 0, spool_name);
  3894. return Lspool(nil, nil);
  3895. }
  3896. #ifdef COMMON
  3897. #define STARTING_SIZE_X 32
  3898. #define STARTING_SIZE_I 32
  3899. Lisp_Object make_package(Lisp_Object name)
  3900. /*
  3901. * ... assuming that there is not already one with this name. Packages
  3902. * can grow as extra symbols are inserted into them, so I can reasonably
  3903. * start off with a very small package.
  3904. */
  3905. {
  3906. Lisp_Object nil = C_nil;
  3907. Lisp_Object p = getvector_init(sizeof(Package), nil), w;
  3908. errexit();
  3909. packhdr_(p) = TYPE_STRUCTURE + (packhdr_(p) & ~header_mask);
  3910. packid_(p) = package_symbol;
  3911. packname_(p) = name;
  3912. packext_(p) = getvector_init(STARTING_SIZE_X+CELL, fixnum_of_int(0));
  3913. errexit();
  3914. packint_(p) = getvector_init(STARTING_SIZE_I+CELL, fixnum_of_int(0));
  3915. errexit();
  3916. packflags_(p) = fixnum_of_int(++package_bits);
  3917. packvext_(p) = fixnum_of_int(1);
  3918. packvint_(p) = fixnum_of_int(1);
  3919. packnext_(p) = fixnum_of_int(0);
  3920. packnint_(p) = fixnum_of_int(0);
  3921. w = cons(p, all_packages);
  3922. errexit();
  3923. all_packages = w;
  3924. return onevalue(p);
  3925. }
  3926. static Lisp_Object want_a_string(Lisp_Object name)
  3927. {
  3928. #ifdef COMMON
  3929. Lisp_Object nil = C_nil;
  3930. if (complex_stringp(name)) return simplify_string(name);
  3931. #else
  3932. nil_as_base
  3933. #endif
  3934. if (symbolp(name)) return get_pname(name);
  3935. else if (is_vector(name) &&
  3936. type_of_header(vechdr(name)) == TYPE_STRING) return name;
  3937. else return aerror1("name or string needed", name);
  3938. }
  3939. static Lisp_Object Lfind_package(Lisp_Object nil, Lisp_Object name)
  3940. /*
  3941. * This should be given a string as an argument. If it is given a
  3942. * symbol it takes its pname as the string to be used. It scans the list
  3943. * of all packages and returns the first that it finds where the name
  3944. * or a nickname matches the string passed in.
  3945. */
  3946. {
  3947. Lisp_Object w;
  3948. Header h;
  3949. int32 len;
  3950. CSL_IGNORE(nil);
  3951. if (is_vector(name))
  3952. { h = vechdr(name);
  3953. if (type_of_header(h) == TYPE_STRUCTURE &&
  3954. packid_(name) == package_symbol) return onevalue(name);
  3955. }
  3956. name = want_a_string(name);
  3957. errexit();
  3958. h = vechdr(name);
  3959. len = length_of_header(h) - CELL;
  3960. for (w = all_packages; w!=nil; w=qcdr(w))
  3961. { Lisp_Object nn, n = packname_(qcar(w));
  3962. if (is_vector(n) && vechdr(n) == h &&
  3963. memcmp((char *)name + (CELL-TAG_VECTOR),
  3964. (char *)n + (CELL-TAG_VECTOR), (size_t)len) == 0)
  3965. return onevalue(qcar(w));
  3966. for (nn = packnick_(qcar(w)); nn!=nil; nn=qcdr(nn))
  3967. { n = qcar(nn);
  3968. if (!is_vector(n) || vechdr(n) != h) continue;
  3969. if (memcmp((char *)name + (CELL-TAG_VECTOR),
  3970. (char *)n + (CELL-TAG_VECTOR), (size_t)len) == 0)
  3971. return onevalue(qcar(w));
  3972. }
  3973. }
  3974. return onevalue(nil);
  3975. }
  3976. Lisp_Object find_package(char *name, int len)
  3977. /*
  3978. * This is like Lfind_package but takes a C string as its arg. Note that
  3979. * this can not cause garbage collection or return an error, so is safe to
  3980. * call from the middle of other things...
  3981. */
  3982. {
  3983. Lisp_Object w, nil = C_nil;
  3984. for (w = all_packages; w!=nil; w=qcdr(w))
  3985. { Lisp_Object nn, n = packname_(qcar(w));
  3986. if (is_vector(n) &&
  3987. length_of_header(vechdr(n))==(unsigned32)(len+CELL) &&
  3988. memcmp(name, (char *)n + (CELL-TAG_VECTOR), (size_t)len) == 0)
  3989. return qcar(w);
  3990. for (nn = packnick_(qcar(w)); nn!=nil; nn=qcdr(nn))
  3991. { n = qcar(nn);
  3992. if (!is_vector(n) ||
  3993. length_of_header(vechdr(n)) != (unsigned32)(len+CELL))
  3994. continue;
  3995. if (memcmp(name,
  3996. (char *)n + (CELL-TAG_VECTOR), (size_t)len) == 0)
  3997. return qcar(w);
  3998. }
  3999. }
  4000. return nil;
  4001. }
  4002. static Lisp_Object Luse_package(Lisp_Object nil, Lisp_Object uses,
  4003. Lisp_Object pkg)
  4004. {
  4005. CSL_IGNORE(nil);
  4006. push(uses);
  4007. pkg = Lfind_package(nil, pkg);
  4008. pop(uses);
  4009. errexit();
  4010. if (pkg == nil) return onevalue(nil);
  4011. if (consp(uses))
  4012. { while (consp(uses))
  4013. { push2(uses, pkg);
  4014. Luse_package(nil, qcar(uses), pkg);
  4015. errexitn(2);
  4016. pop2(pkg, uses);
  4017. uses = qcdr(uses);
  4018. }
  4019. }
  4020. else
  4021. { Lisp_Object w, w1;
  4022. push(pkg);
  4023. uses = Lfind_package(nil, uses);
  4024. pop(pkg);
  4025. errexit();
  4026. if (uses == nil || uses == pkg) return onevalue(nil);
  4027. push2(pkg, uses);
  4028. /*
  4029. * Around here I am supposed to do a large-scale check to ensure that there
  4030. * are no unexpected name conflicts between the packages that are being
  4031. * worked linked.
  4032. */
  4033. w = cons(uses, packuses_(pkg));
  4034. errexitn(2);
  4035. uses = stack[0];
  4036. pkg = stack[-1];
  4037. push(w);
  4038. w1 = cons(pkg, packused_(uses));
  4039. errexitn(3);
  4040. pop3(w, uses, pkg);
  4041. packuses_(pkg) = w;
  4042. packused_(uses) = w1;
  4043. }
  4044. return onevalue(lisp_true);
  4045. }
  4046. static Lisp_Object MS_CDECL Lmake_package(Lisp_Object nil, int nargs, ...)
  4047. {
  4048. Lisp_Object name, nicknames = nil, uses = nil, w = nil, k;
  4049. CSLbool has_use = NO;
  4050. va_list a;
  4051. int i;
  4052. if (nargs == 0) return aerror("make-package");
  4053. /*
  4054. * First I scan the arguments - there may be a lot of them - looking for
  4055. * any relevant keyword parameters
  4056. */
  4057. va_start(a, nargs);
  4058. push_args(a, nargs);
  4059. name = stack[1-nargs];
  4060. if ((nargs & 1) == 0)
  4061. { popv(1);
  4062. nargs--;
  4063. }
  4064. for (i=1; i<nargs; i+=2)
  4065. { pop2(k, w);
  4066. if (w == nicknames_symbol) nicknames = k;
  4067. else if (w == use_symbol) has_use = YES, uses = k;
  4068. }
  4069. popv(1);
  4070. /*
  4071. * I provide a default value for the ":use" argument
  4072. */
  4073. if (!has_use)
  4074. { push2(name, nicknames);
  4075. uses = make_string("LISP");
  4076. errexitn(2);
  4077. uses = ncons(uses);
  4078. errexitn(2);
  4079. pop2(nicknames, name);
  4080. }
  4081. push2(uses, nicknames);
  4082. /*
  4083. * Now I need to ensure that the name I had for the package is
  4084. * a string...
  4085. */
  4086. name = want_a_string(name);
  4087. errexitn(2);
  4088. push(name);
  4089. w = Lfind_package(nil, name);
  4090. pop(name);
  4091. errexitn(2);
  4092. /*
  4093. * It is SUPPOSED to be a continuable error if the package already exists.
  4094. * For the present I will just display a message and keep going.
  4095. */
  4096. if (w != nil)
  4097. { popv(2);
  4098. err_printf("\n+++++ package already exists: ");
  4099. prin_to_error(name);
  4100. err_printf("\n");
  4101. return onevalue(w);
  4102. }
  4103. /*
  4104. * The package does not exist yet - so I will make one...
  4105. */
  4106. name = make_package(name);
  4107. errexitn(2);
  4108. /*
  4109. * ensure that NICKNAMES is a list of strings...
  4110. */
  4111. uses = nil;
  4112. while (consp(stack[0]))
  4113. { w = stack[0];
  4114. push(uses);
  4115. w = want_a_string(qcar(w));
  4116. errexitn(3);
  4117. pop(uses);
  4118. uses = cons(w, uses);
  4119. errexitn(2);
  4120. stack[0] = qcdr(stack[0]);
  4121. }
  4122. nicknames = nil;
  4123. while (uses != nil)
  4124. { w = uses;
  4125. uses = qcdr(w);
  4126. qcdr(w) = nicknames;
  4127. nicknames = w;
  4128. }
  4129. popv(1);
  4130. packnick_(name) = nicknames;
  4131. uses = stack[0];
  4132. stack[0] = name;
  4133. Luse_package(nil, uses, name);
  4134. errexitn(1);
  4135. pop(name);
  4136. return onevalue(name);
  4137. }
  4138. static Lisp_Object Lmake_package_2(Lisp_Object nil, Lisp_Object a, Lisp_Object b)
  4139. {
  4140. return Lmake_package(nil, 2, a, b);
  4141. }
  4142. static Lisp_Object Lmake_package_1(Lisp_Object nil, Lisp_Object a)
  4143. {
  4144. return Lmake_package(nil, 1, a);
  4145. }
  4146. static Lisp_Object MS_CDECL Llist_all_packages(Lisp_Object nil, int nargs, ...)
  4147. {
  4148. CSL_IGNORE(nargs);
  4149. CSL_IGNORE(nil);
  4150. return onevalue(all_packages);
  4151. }
  4152. #endif
  4153. Lisp_Object MS_CDECL Ltyi(Lisp_Object nil, int nargs, ...)
  4154. {
  4155. int ch;
  4156. argcheck(nargs, 0, "tyi");
  4157. if (curchar == NOT_CHAR)
  4158. { Lisp_Object stream = qvalue(standard_input);
  4159. if (!is_stream(stream)) stream = qvalue(terminal_io);
  4160. if (!is_stream(stream)) stream = lisp_terminal_io;
  4161. ch = getc_stream(stream);
  4162. errexit();
  4163. }
  4164. else
  4165. { ch = curchar;
  4166. curchar = NOT_CHAR;
  4167. }
  4168. if (ch == EOF || ch == CTRL_D) return onevalue(CHAR_EOF);
  4169. #ifdef Kanji
  4170. return onevalue(pack_char(0, 0, ch & 0xffff));
  4171. #else
  4172. return onevalue(pack_char(0, 0, ch & 0xff));
  4173. #endif
  4174. }
  4175. Lisp_Object Lreadch1(Lisp_Object nil, Lisp_Object stream)
  4176. {
  4177. Lisp_Object w;
  4178. int ch;
  4179. if (!is_stream(stream)) stream = qvalue(terminal_io);
  4180. if (!is_stream(stream)) stream = lisp_terminal_io;
  4181. ch = getc_stream(stream);
  4182. errexit();
  4183. if (ch == EOF || ch == CTRL_D) w = CHAR_EOF;
  4184. else
  4185. {
  4186. if (qvalue(lower_symbol) != nil) ch = TOlower(ch);
  4187. else if (qvalue(raise_symbol) != nil) ch = TOupper(ch);
  4188. #ifdef Kanji
  4189. if (qvalue(hankaku_symbol) != nil)
  4190. is (iszenkaku(curchar)) curchar = tohankaku(curchar);
  4191. if (iswchar(ch))
  4192. { boffo_char(0) = ch >> 8;
  4193. boffo_char(1) = ch;
  4194. w = iintern(boffo, 2, lisp_package, 1);
  4195. errexit();
  4196. }
  4197. else
  4198. { w = elt(charvec, ch & 0xff);
  4199. if (w == nil)
  4200. { boffo_char(0) = ch;
  4201. /* NB I always want to intern in the LISP package here */
  4202. w = iintern(boffo, 1, lisp_package, 0);
  4203. errexit();
  4204. elt(charvec, ch & 0xff) = w;
  4205. }
  4206. }
  4207. #else
  4208. w = elt(charvec, ch & 0xff);
  4209. if (w == nil)
  4210. { boffo_char(0) = ch;
  4211. /* NB I always want to intern in the LISP package here */
  4212. w = iintern(boffo, 1, lisp_package, 0);
  4213. errexit();
  4214. elt(charvec, ch & 0xff) = w;
  4215. }
  4216. #endif
  4217. }
  4218. return onevalue(w);
  4219. }
  4220. Lisp_Object MS_CDECL Lreadch(Lisp_Object nil, int nargs, ...)
  4221. {
  4222. argcheck(nargs, 0, "readch");
  4223. return Lreadch1(nil, qvalue(standard_input));
  4224. }
  4225. Lisp_Object Lpeekch2(Lisp_Object nil, Lisp_Object type, Lisp_Object stream)
  4226. {
  4227. Lisp_Object w;
  4228. int ch;
  4229. if (!is_stream(stream)) stream = qvalue(terminal_io);
  4230. if (!is_stream(stream)) stream = lisp_terminal_io;
  4231. if (type != nil)
  4232. { do
  4233. { ch = getc_stream(stream);
  4234. errexit();
  4235. } while (ISspace(ch));
  4236. }
  4237. else
  4238. { ch = getc_stream(stream);
  4239. errexit();
  4240. }
  4241. other_read_action(ch, stream);
  4242. errexit();
  4243. if (ch == EOF || ch == CTRL_D) w = CHAR_EOF;
  4244. else
  4245. { if (qvalue(lower_symbol) != nil) ch = TOlower(ch);
  4246. else if (qvalue(raise_symbol) != nil) ch = TOupper(ch);
  4247. #ifdef Kanji
  4248. if (qvalue(hankaku_symbol) != nil)
  4249. is (iszenkaku(curchar)) curchar = tohankaku(curchar);
  4250. if (iswchar(curchar))
  4251. { boffo_char(0) = curchar >> 8;
  4252. boffo_char(1) = curchar;
  4253. w = iintern(boffo, 2, lisp_package, 0);
  4254. errexit();
  4255. }
  4256. else
  4257. { w = elt(charvec, ch & 0xff);
  4258. if (w == nil)
  4259. { boffo_char(0) = ch;
  4260. /* NB I always want to intern in the LISP package here */
  4261. w = iintern(boffo, 1, lisp_package, 0);
  4262. errexit();
  4263. elt(charvec, ch & 0xff) = w;
  4264. }
  4265. }
  4266. #else
  4267. w = elt(charvec, ch & 0xff);
  4268. if (w == nil)
  4269. { boffo_char(0) = ch;
  4270. /* NB I always want to intern in the LISP package here */
  4271. w = iintern(boffo, 1, lisp_package, 0);
  4272. errexit();
  4273. elt(charvec, ch & 0xff) = w;
  4274. }
  4275. #endif
  4276. }
  4277. return onevalue(w);
  4278. }
  4279. Lisp_Object Lpeekch1(Lisp_Object nil, Lisp_Object type)
  4280. {
  4281. return Lpeekch2(nil, type, qvalue(standard_input));
  4282. }
  4283. Lisp_Object MS_CDECL Lpeekch(Lisp_Object nil, int nargs, ...)
  4284. {
  4285. argcheck(nargs, 0, "peekch");
  4286. return Lpeekch2(nil, nil, qvalue(standard_input));
  4287. }
  4288. Lisp_Object Lunreadch2(Lisp_Object nil, Lisp_Object a, Lisp_Object stream)
  4289. {
  4290. int ch;
  4291. CSL_IGNORE(nil);
  4292. if (!is_stream(stream)) stream = qvalue(terminal_io);
  4293. if (!is_stream(stream)) stream = lisp_terminal_io;
  4294. if (a == CHAR_EOF) ch = EOF;
  4295. else
  4296. { if (is_symbol(a)) a = pack_char(0, 0, first_char(a));
  4297. ch = (char)code_of_char(a);
  4298. }
  4299. other_read_action(ch, stream);
  4300. return onevalue(a);
  4301. }
  4302. Lisp_Object Lunreadch(Lisp_Object nil, Lisp_Object a)
  4303. {
  4304. return Lunreadch2(nil, a, qvalue(standard_input));
  4305. }
  4306. Lisp_Object Lreadline1(Lisp_Object nil, Lisp_Object stream)
  4307. {
  4308. Lisp_Object w;
  4309. int ch, n = 0, k;
  4310. char *s;
  4311. if (!is_stream(stream)) stream = qvalue(terminal_io);
  4312. if (!is_stream(stream)) stream = lisp_terminal_io;
  4313. boffop = 0;
  4314. while ((ch = getc_stream(stream)) != EOF && ch != '\n')
  4315. { errexit();
  4316. packbyte(ch);
  4317. n++;
  4318. }
  4319. errexit();
  4320. if (ch == EOF && n == 0) w = CHAR_EOF;
  4321. else
  4322. { w = getvector(TAG_VECTOR, TYPE_STRING, CELL+n);
  4323. errexit();
  4324. s = (char *)w - TAG_VECTOR;
  4325. k = (n + 3) & ~7;
  4326. *(int32 *)(s + k + 4) = 0;
  4327. if (k != 0) *(int32 *)(s + k) = 0;
  4328. s = s + 4;
  4329. memcpy(s, &boffo_char(0), n);
  4330. }
  4331. #ifdef COMMON
  4332. mv_2 = Lispify_predicate(ch == EOF);
  4333. #endif
  4334. return nvalues(w, 2);
  4335. }
  4336. Lisp_Object MS_CDECL Lreadline(Lisp_Object nil, int nargs, ...)
  4337. {
  4338. argcheck(nargs, 0, "readline");
  4339. return Lreadline1(nil, qvalue(standard_input));
  4340. }
  4341. setup_type const read_setup[] =
  4342. {
  4343. {"batchp", wrong_no_na, wrong_no_nb, Lbatchp},
  4344. {"rseek", Lrseek, Lrseek_2, wrong_no_1},
  4345. #ifdef COMMON
  4346. {"rseekend", Lrseekend, too_many_1, wrong_no_1},
  4347. #endif
  4348. {"rtell", Lrtell_1, wrong_no_nb, Lrtell},
  4349. {"gensym1", Lgensym1, too_many_1, wrong_no_1},
  4350. {"gensym2", Lgensym2, too_many_1, wrong_no_1},
  4351. {"gensymp", Lgensymp, too_many_1, wrong_no_1},
  4352. {"getenv", Lgetenv, too_many_1, wrong_no_1},
  4353. {"orderp", too_few_2, Lorderp, wrong_no_2},
  4354. {"rdf", Lrdf1, Lrdf2, Lrdfn},
  4355. {"rds", Lrds, too_many_1, wrong_no_1},
  4356. {"peekch", Lpeekch1, Lpeekch2, Lpeekch},
  4357. {"readch", Lreadch1, wrong_no_nb, Lreadch},
  4358. {"unreadch", Lunreadch, Lunreadch2, wrong_no_1},
  4359. {"readline", Lreadline1, wrong_no_nb, Lreadline},
  4360. {"setpchar", Lsetpchar, too_many_1, wrong_no_1},
  4361. {"spool", Lspool, too_many_1, Lspool0},
  4362. {"system", Lsystem, too_many_1, wrong_no_1},
  4363. {"~tyi", wrong_no_na, wrong_no_nb, Ltyi},
  4364. {"list-to-string", Llist_to_string, too_many_1, wrong_no_1},
  4365. {"list-to-symbol", Llist_to_symbol, too_many_1, wrong_no_1},
  4366. {"where-was-that", wrong_no_na, wrong_no_nb, Lwhere_was_that},
  4367. #ifdef COMMON
  4368. {"compress1", Lcompress, too_many_1, wrong_no_1},
  4369. {"dribble", Lspool, too_many_1, Lspool0},
  4370. {"read", Lread_1, wrong_no_nb, Lread},
  4371. {"intern", Lintern, Lintern_2, wrong_no_1},
  4372. {"gensym", Lgensym1, wrong_no_nb, Lgensym},
  4373. {"extern", Lextern_1, Lextern, wrong_no_1},
  4374. {"import*", Limport_1, Limport, wrong_no_1},
  4375. {"find-symbol", Lfind_symbol_1, Lfind_symbol, wrong_no_1},
  4376. {"keywordp", Lkeywordp, too_many_1, wrong_no_1},
  4377. {"find-package", Lfind_package, too_many_1, wrong_no_1},
  4378. {"make-package", Lmake_package_1, Lmake_package_2, Lmake_package},
  4379. {"use-package*", too_few_2, Luse_package, wrong_no_2},
  4380. {"list-all-packages", wrong_no_na, wrong_no_nb, Llist_all_packages},
  4381. {"make-symbol", Lmake_symbol, too_many_1, wrong_no_1},
  4382. {"unintern", Lunintern, Lunintern_2, wrong_no_1},
  4383. #else
  4384. {"compress", Lcompress, too_many_1, wrong_no_1},
  4385. {"read", wrong_no_na, wrong_no_nb, Lread},
  4386. {"intern", Lintern, too_many_1, wrong_no_1},
  4387. {"gensym", Lgensym1, wrong_no_nb, Lgensym},
  4388. {"ordp", too_few_2, Lorderp, wrong_no_2},
  4389. {"remob", Lunintern, too_many_1, wrong_no_1},
  4390. #endif
  4391. {NULL, 0, 0, 0}
  4392. };
  4393. /* end of read.c */