home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume26 / veos-2.0 / part12 < prev    next >
Encoding:
Text File  |  1993-04-25  |  65.3 KB  |  2,913 lines

  1. Newsgroups: comp.sources.unix
  2. From: voodoo@hitl.washington.edu (Geoffery Coco)
  3. Subject: v26i195: veos-2.0 - The Virtual Environment Operating Shell, V2.0, Part12/16
  4. Sender: unix-sources-moderator@vix.com
  5. Approved: paul@vix.com
  6.  
  7. Submitted-By: voodoo@hitl.washington.edu (Geoffery Coco)
  8. Posting-Number: Volume 26, Issue 195
  9. Archive-Name: veos-2.0/part12
  10.  
  11. #! /bin/sh
  12. # This is a shell archive.  Remove anything before this line, then unpack
  13. # it by saving it into a file and typing "sh file".  To overwrite existing
  14. # files, type "sh file -c".  You can also feed this as standard input via
  15. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  16. # will see the following message at the end:
  17. #        "End of archive 12 (of 16)."
  18. # Contents:  src/kernel_current/nancy/nancy_fundamental.c
  19. #   src/xlisp/xcore/c/xlcont.c
  20. # Wrapped by vixie@efficacy.home.vix.com on Sun Apr 25 23:10:44 1993
  21. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  22. if test -f 'src/kernel_current/nancy/nancy_fundamental.c' -a "${1}" != "-c" ; then 
  23.   echo shar: Will not clobber existing file \"'src/kernel_current/nancy/nancy_fundamental.c'\"
  24. else
  25. echo shar: Extracting \"'src/kernel_current/nancy/nancy_fundamental.c'\" \(31245 characters\)
  26. sed "s/^X//" >'src/kernel_current/nancy/nancy_fundamental.c' <<'END_OF_FILE'
  27. X/****************************************************************************************
  28. X *                                            *
  29. X * file: nancy.c                                    *
  30. X *                                            *
  31. X * August 21, 1990: the world(s)' interface to grouples.                       *
  32. X *                                            *
  33. X * by Geoffrey P. Coco at the HITLab, Seattle.                          *
  34. X *                                            *
  35. X ****************************************************************************************/
  36. X
  37. X/****************************************************************************************
  38. X * Copyright (C) 1992  Geoffrey P. Coco, Human Interface Technology Lab, Seattle    *
  39. X ****************************************************************************************/
  40. X
  41. X
  42. X/****************************************************************************************
  43. X *                          includes galore                    */
  44. X
  45. X#include "kernel.h"
  46. X#include <string.h>
  47. X#include <malloc.h>
  48. X#include <varargs.h>
  49. X
  50. X/****************************************************************************************/
  51. X
  52. X
  53. X/****************************************************************************************
  54. X *                     forward function declarations                */
  55. X
  56. X
  57. X/* nancy setup and preprocessing */
  58. X
  59. XTVeosErr Nancy_Init();
  60. X
  61. X
  62. X/* fundamental grouple data structure utils */
  63. X
  64. XTVeosErr Nancy_NewGrouple();                         
  65. XTVeosErr Nancy_DisposeGrouple();
  66. XTVeosErr Nancy_CopyGrouple();
  67. XTVeosErr Nancy_CreateElement();
  68. XTVeosErr Nancy_DisposeElement();
  69. XTVeosErr Nancy_CopyElement();
  70. XTVeosErr Nancy_NewElementsInGrouple();
  71. XTVeosErr Nancy_DeleteElementsInGrouple();
  72. X
  73. X
  74. X/* related public nancy utils */
  75. X
  76. XTVeosErr Nancy_GroupleToStream();
  77. XTVeosErr Nancy_ElementToStream();
  78. XTVeosErr Nancy_GroupleToStreamWithLevel();
  79. XTVeosErr Nancy_ElementToStreamWithLevel();
  80. X
  81. XTVeosErr Nancy_EmptyGrouple();
  82. XTVeosErr Nancy_InsertEltList();
  83. XTVeosErr Nancy_CopyEltList();
  84. XTVeosErr Nancy_ConcatGrouple();
  85. X
  86. XTVeosErr Nancy_GetFileSize();
  87. XTVeosErr Nancy_FileToGrouple();
  88. XTVeosErr Nancy_TrapErr();
  89. X
  90. X
  91. X/* private nancy utils */
  92. X
  93. XTVeosErr Nancy_ResizeEltList();
  94. XTVeosErr Nancy_SetupTypeSizes();
  95. X
  96. X/****************************************************************************************/
  97. X
  98. X
  99. X
  100. X
  101. X/****************************************************************************************
  102. X *                setup and preprocessing                    *
  103. X ****************************************************************************************/
  104. X
  105. X
  106. X/****************************************************************************************
  107. X * Nancy_Init                                    */
  108. X
  109. XTVeosErr Nancy_Init()
  110. X{
  111. X    TVeosErr        iSuccess;
  112. X
  113. X    iSuccess = VEOS_MEM_ERR;
  114. X    LINE_COUNT = 0;
  115. X    NANCY_MINTIME = 0;
  116. X    NANCY_TIME = 1;
  117. X
  118. X    /** setup runtime hash table for element sizes **/
  119. X
  120. X    iSuccess = Nancy_SetupFastMem();
  121. X    if (iSuccess == VEOS_SUCCESS) {
  122. X    
  123. X    /** StreamToElement assumes global buffer **/
  124. X    
  125. X    if (NEWPTR(NANCY_BUF, char *, VEOS_GROUPLE_BUF_SIZE)) {
  126. X        
  127. X        NIL_ELT.iType = GR_unspecified;
  128. X        NIL_ELT.u.pU = nil;
  129. X        NIL_ELT.tLastMod = 0x7FFFFFFF;
  130. X        NIL_ELT.iFlags = 0;
  131. X
  132. X        iSuccess = Nancy_NewGrouple(&GR_INSPACE);
  133. X        if (iSuccess == VEOS_SUCCESS) {
  134. X
  135. X        iSuccess = Nancy_NewGrouple(&WORK_SPACE);
  136. X        }
  137. X        }
  138. X    }
  139. X    
  140. X    return(iSuccess);
  141. X
  142. X    } /* Nancy_Init */
  143. X/****************************************************************************************/
  144. X
  145. X
  146. X
  147. X/****************************************************************************************
  148. X *             fundamental nancy data structure utils                *
  149. X ****************************************************************************************/
  150. X
  151. X
  152. X
  153. X/****************************************************************************************
  154. X * Nancy_NewGrouple                                    */
  155. X
  156. XTVeosErr Nancy_NewGrouple(hDestGrouple)
  157. X    THGrouple        hDestGrouple;
  158. X{
  159. X    TVeosErr        iSuccess;
  160. X    TPGrouple        pNewGrouple;
  161. X
  162. X
  163. X    iSuccess = VEOS_FAILURE;                       /* pessimism */
  164. X
  165. X
  166. X    if (hDestGrouple) {                    /* sanity check */
  167. X
  168. X    iSuccess = VEOS_MEM_ERR;            /* more pessimism */
  169. X
  170. X    *hDestGrouple = (TPGrouple) nil; 
  171. X
  172. X
  173. X
  174. X    /** allocate the grouple structure itself **/
  175. X
  176. X    iSuccess = Shell_NewBlock(TYPE_SIZES[GR_grouple], &pNewGrouple,
  177. X                  "grouple");
  178. X
  179. X    if (iSuccess == VEOS_SUCCESS) {
  180. X        pNewGrouple->pEltList = nil;
  181. X        pNewGrouple->iElts = 0;
  182. X        pNewGrouple->iFlags = 0;
  183. X
  184. X        *hDestGrouple = pNewGrouple;
  185. X        }
  186. X    }
  187. X
  188. X    return(iSuccess);
  189. X
  190. X    } /* Nancy_NewGrouple */
  191. X/****************************************************************************************/
  192. X
  193. X
  194. X
  195. X
  196. X/****************************************************************************************
  197. X * Nancy_DisposeGrouple                                    */
  198. X
  199. XTVeosErr Nancy_DisposeGrouple(pDeadGrouple)
  200. X    TPGrouple        pDeadGrouple;
  201. X{
  202. X    TVeosErr        iSuccess;
  203. X    int            iEltIndex;
  204. X    TPElt        pEltList;
  205. X
  206. X    iSuccess = VEOS_SUCCESS;            /* what could go wrong? */
  207. X
  208. X    if (pDeadGrouple) {                /* sanity check */
  209. X
  210. X
  211. X    /** clear all elements from grouple **/
  212. X
  213. X    Nancy_DeleteElementsInGrouple(pDeadGrouple, 0, pDeadGrouple->iElts);
  214. X        
  215. X
  216. X    /** deallocate element list itself **/
  217. X
  218. X    Nancy_ResizeEltList(pDeadGrouple, 0);
  219. X
  220. X
  221. X    /** deallocate the grouple structure itself **/
  222. X
  223. X    Shell_ReturnBlock(pDeadGrouple, TYPE_SIZES[GR_grouple], "grouple");
  224. X    }
  225. X
  226. X
  227. X    return(iSuccess);
  228. X
  229. X    } /* Nancy_DisposeGrouple */
  230. X/****************************************************************************************/
  231. X
  232. X
  233. X
  234. X
  235. X/****************************************************************************************
  236. X * Nancy_CopyGrouple                                    */
  237. XTVeosErr Nancy_CopyGrouple(pSrcGrouple, pDestGrouple)
  238. X    TPGrouple        pSrcGrouple;
  239. X    TPGrouple        pDestGrouple;
  240. X{
  241. X    TVeosErr        iSuccess;
  242. X
  243. X    iSuccess = VEOS_FAILURE;                          /* pessimism */
  244. X
  245. X    if (pSrcGrouple && pDestGrouple) {                /* sanity check */
  246. X
  247. X    /** allocate element list enough for all copied elements **/
  248. X
  249. X    iSuccess = Nancy_ResizeEltList(pDestGrouple, pSrcGrouple->iElts);
  250. X    if (iSuccess == VEOS_SUCCESS) {
  251. X
  252. X
  253. X        iSuccess = Nancy_CopyEltList(pSrcGrouple->pEltList,
  254. X                     pDestGrouple->pEltList,
  255. X                     pSrcGrouple->iElts);
  256. X        }
  257. X    }
  258. X
  259. X    return(iSuccess);
  260. X
  261. X    } /* Nancy_CopyGrouple */
  262. X/****************************************************************************************/
  263. X
  264. X
  265. X
  266. X
  267. X/****************************************************************************************
  268. X * Nancy_CreateElement                                    */
  269. X
  270. XTVeosErr Nancy_CreateElement(pDestElt, iType, iSize)
  271. X    TPElt        pDestElt;
  272. X    int            iType, iSize;
  273. X{
  274. X    TVeosErr        iSuccess;
  275. X    str15        sTypeName;
  276. X
  277. X    iSuccess = VEOS_FAILURE;
  278. X
  279. X    if (pDestElt) {        /* sane? */
  280. X
  281. X    pDestElt->iType = iType;
  282. X
  283. X    iSuccess = VEOS_MEM_ERR;
  284. X
  285. X    switch (iType) {
  286. X
  287. X    case GR_grouple:
  288. X        iSuccess = Nancy_NewGrouple(&pDestElt->u.pGr);
  289. X        break;
  290. X
  291. X    case GR_vector:
  292. X        iSuccess = Nancy_NewGrouple(&pDestElt->u.pGr);
  293. X        pDestElt->iType = GR_vector;
  294. X        break;
  295. X
  296. X    case GR_string:
  297. X    case GR_prim:
  298. X        if (iSize > 0) {
  299. X        if (NEWPTR(pDestElt->u.pS, char *, iSize))
  300. X            iSuccess = VEOS_SUCCESS;
  301. X        }
  302. X        else {
  303. X        pDestElt->u.pS = nil;
  304. X        iSuccess = VEOS_SUCCESS;
  305. X        }
  306. X        break;
  307. X
  308. X    case GR_float:    
  309. X    case GR_int:
  310. X    case GR_these:
  311. X    case GR_theseall:
  312. X    case GR_some:
  313. X    case GR_any:
  314. X    case GR_here:
  315. X        /* nothing to allocate */
  316. X        iSuccess = VEOS_SUCCESS;
  317. X        break;
  318. X
  319. X    case GR_unspecified:
  320. X    default:
  321. X        pDestElt->u.pU = nil;
  322. X        iSuccess = VEOS_SUCCESS;
  323. X        break;
  324. X
  325. X        } /* switch */
  326. X    }
  327. X
  328. X    return(iSuccess);
  329. X
  330. X    } /* Nancy_CreateElement */
  331. X/****************************************************************************************/
  332. X
  333. X
  334. X
  335. X
  336. X
  337. X/****************************************************************************************
  338. X * Nancy_DisposeElement                                    */
  339. X
  340. XTVeosErr Nancy_DisposeElement(pDestElt)
  341. X    TPElt        pDestElt;
  342. X{
  343. X    TVeosErr        iSuccess;
  344. X    str15        sTypeName;
  345. X
  346. X    iSuccess = VEOS_FAILURE;
  347. X
  348. X    if (pDestElt) {
  349. X    
  350. X    /** recurs to sublist if necessary **/
  351. X    switch (pDestElt->iType) {
  352. X        
  353. X    case GR_grouple:
  354. X    case GR_vector:
  355. X        Nancy_DisposeGrouple(pDestElt->u.pGr);
  356. X        break;
  357. X        
  358. X    case GR_string:
  359. X        DUMP(pDestElt->u.pS);
  360. X        break;
  361. X        
  362. X    case GR_float:    
  363. X    case GR_int:
  364. X    case GR_these:
  365. X    case GR_theseall:
  366. X    case GR_some:
  367. X    case GR_any:
  368. X    case GR_here:
  369. X    case GR_unspecified:
  370. X    default:
  371. X        /* nothing allocated */
  372. X        break;
  373. X        
  374. X        } /* switch */
  375. X    
  376. X    *pDestElt = NIL_ELT;
  377. X    
  378. X    iSuccess = VEOS_SUCCESS;
  379. X    }
  380. X
  381. X    return(iSuccess);
  382. X
  383. X    } /* Nancy_DisposeElement */
  384. X/****************************************************************************************/
  385. X
  386. X
  387. X
  388. X
  389. X/****************************************************************************************
  390. X * Nancy_CopyElement                                    */
  391. X
  392. XTVeosErr Nancy_CopyElement(pSrcElt, pDestElt)
  393. X    TPElt        pSrcElt, pDestElt;
  394. X{
  395. X    TVeosErr        iSuccess;
  396. X
  397. X    iSuccess = VEOS_FAILURE;
  398. X
  399. X    if (pSrcElt && pDestElt && pSrcElt->iType == pDestElt->iType) {    /* sane? */
  400. X
  401. X    iSuccess = VEOS_SUCCESS;
  402. X
  403. X    switch (pSrcElt->iType) {
  404. X
  405. X    case GR_grouple:
  406. X    case GR_vector:
  407. X        iSuccess = Nancy_CopyGrouple(pSrcElt->u.pGr,
  408. X                     pDestElt->u.pGr);
  409. X        break;
  410. X
  411. X    case GR_float:    
  412. X    case GR_int:
  413. X    case GR_these:
  414. X    case GR_some:
  415. X        pDestElt->u.iVal = pSrcElt->u.iVal;
  416. X        break;
  417. X
  418. X    case GR_theseall:
  419. X    case GR_any:
  420. X    case GR_here:
  421. X        /** no data to copy **/
  422. X        break;
  423. X
  424. X    case GR_string:
  425. X    case GR_prim:
  426. X        if (pDestElt->u.pS)
  427. X        strcpy(pDestElt->u.pS, pSrcElt->u.pS);
  428. X        else
  429. X        pDestElt->u.pS = strdup(pSrcElt->u.pS);
  430. X        break;
  431. X
  432. X    case GR_unspecified:
  433. X        break;
  434. X
  435. X        } /* switch */
  436. X
  437. X    pDestElt->tLastMod = pSrcElt->tLastMod;
  438. X    }
  439. X
  440. X    return(iSuccess);
  441. X
  442. X    } /* Nancy_CopyElement */
  443. X/****************************************************************************************/
  444. X
  445. X
  446. X
  447. X
  448. X/****************************************************************************************
  449. X * Nancy_NewElementsInGrouple                                */
  450. X
  451. XTVeosErr Nancy_NewElementsInGrouple(pDestGrouple, iInsertElt, iElts, iType, iSize)
  452. X    TPGrouple        pDestGrouple;
  453. X    int            iInsertElt, iElts, iType, iSize;
  454. X{
  455. X    TVeosErr        iSuccess;
  456. X    TPElt        pEltList;
  457. X    int            iIndex, iOldElts, iLimit;
  458. X
  459. X    iSuccess = VEOS_FAILURE;
  460. X
  461. X    if (pDestGrouple) {
  462. X
  463. X    iOldElts = pDestGrouple->iElts;        /* ResizeEltList() clobbers this field */
  464. X
  465. X    iSuccess = Nancy_ResizeEltList(pDestGrouple,
  466. X                       iOldElts > iInsertElt ?
  467. X                       (iOldElts + iElts) : (iInsertElt + iElts));
  468. X    if (iSuccess == VEOS_SUCCESS) {
  469. X
  470. X
  471. X
  472. X        /** use stack var for speed **/
  473. X
  474. X        pEltList = pDestGrouple->pEltList;
  475. X
  476. X
  477. X
  478. X        /** all elements which occur after insertion point are shifted down **/
  479. X
  480. X        iIndex = iOldElts + iElts - 1;            
  481. X        iLimit = iInsertElt + iElts;
  482. X
  483. X        while (iIndex >= iLimit) {
  484. X
  485. X        pEltList[iIndex] = pEltList[iIndex - iElts];
  486. X
  487. X        iIndex --;
  488. X        }
  489. X
  490. X
  491. X        /** initialize new elements that may have been created by list growth **/
  492. X
  493. X        iIndex = iOldElts;
  494. X        iLimit = iInsertElt + iElts;
  495. X
  496. X        while (iIndex < iLimit) {
  497. X
  498. X        pEltList[iIndex] = NIL_ELT;
  499. X
  500. X        iIndex ++;
  501. X        }
  502. X
  503. X
  504. X        /** attempt to create actual element data block, if requested **/
  505. X
  506. X        iIndex = iInsertElt;
  507. X        iLimit = iInsertElt + iElts;
  508. X        while (iIndex < iLimit && iSuccess == VEOS_SUCCESS) {
  509. X
  510. X        iSuccess = Nancy_CreateElement(&pEltList[iIndex], iType, iSize);
  511. X
  512. X        iIndex ++;
  513. X        }
  514. X        }
  515. X    }
  516. X
  517. X    return(iSuccess);
  518. X
  519. X    } /* Nancy_NewElementsInGrouple */
  520. X/****************************************************************************************/
  521. X
  522. X
  523. X
  524. X
  525. X/****************************************************************************************
  526. X * Nancy_DeleteElementsInGrouple                            */
  527. X
  528. XTVeosErr Nancy_DeleteElementsInGrouple(pGrouple, iStartElt, iElts)
  529. X    TPGrouple        pGrouple;
  530. X    int            iStartElt, iElts;
  531. X{
  532. X    TVeosErr        iSuccess;
  533. X    int            iIndex, iEndElt, iNewElts;
  534. X    TPElt        pEltList;
  535. X
  536. X    iSuccess = VEOS_SUCCESS;
  537. X    iEndElt = iStartElt + iElts;
  538. X
  539. X    if (pGrouple &&
  540. X    iElts > 0) {
  541. X
  542. X    if (pGrouple->iElts >= iEndElt) {        /* sane? */
  543. X        
  544. X        
  545. X        /** deallocate specific element data **/
  546. X        
  547. X        iIndex = iStartElt;
  548. X        while (iIndex < iEndElt) {
  549. X        
  550. X        Nancy_DisposeElement(&pGrouple->pEltList[iIndex]);
  551. X        
  552. X        iIndex ++;
  553. X        }    
  554. X        
  555. X        
  556. X        iSuccess = Nancy_DownShift(pGrouple, iStartElt, iElts);
  557. X        }
  558. X    }
  559. X
  560. X    return(iSuccess);
  561. X
  562. X    } /* Nancy_DeleteElementsInGrouple */
  563. X/****************************************************************************************/
  564. X
  565. X
  566. X/****************************************************************************************
  567. X                     Data Conversion
  568. X ****************************************************************************************/
  569. X
  570. X
  571. X/****************************************************************************************
  572. X * Nancy_ElementToStream                                */
  573. X
  574. XTVeosErr Nancy_ElementToStream(pElt, pStream)
  575. X    TPElt        pElt;
  576. X    FILE        *pStream;
  577. X{
  578. X    TVeosErr        iSuccess;
  579. X    FILE        *pSave;
  580. X
  581. X    iSuccess = VEOS_FAILURE;
  582. X
  583. X    if (pElt && pStream) {                /* sane? */
  584. X
  585. X    pSave = GR_STREAM;
  586. X    GR_STREAM = pStream;
  587. X
  588. X    iSuccess = Nancy_ElementToStreamAux(pElt, 0);
  589. X
  590. X    GR_STREAM = pSave;
  591. X    }
  592. X
  593. X    return(iSuccess);
  594. X
  595. X    } /* Nancy_ElementToStream */
  596. X/****************************************************************************************/
  597. X
  598. X
  599. X
  600. X
  601. X/****************************************************************************************
  602. X * Nancy_GroupleToStream                                */
  603. X
  604. XTVeosErr Nancy_GroupleToStream(pGrouple, pStream)
  605. X    TPGrouple        pGrouple;
  606. X    FILE        *pStream;
  607. X{
  608. X    TElt        elt;
  609. X    TVeosErr        iSuccess;
  610. X
  611. X    iSuccess = VEOS_FAILURE;
  612. X
  613. X    if (pGrouple && pStream) {                /* sane? */
  614. X
  615. X    elt = NIL_ELT;
  616. X    elt.iType = GR_grouple;
  617. X    elt.u.pGr = pGrouple;
  618. X    
  619. X    iSuccess = Nancy_ElementToStream(&elt, pStream);
  620. X    }
  621. X
  622. X    return(iSuccess);
  623. X
  624. X    } /* Nancy_GroupleToStream */
  625. X/****************************************************************************************/
  626. X
  627. X
  628. X
  629. X
  630. X/****************************************************************************************
  631. X * Nancy_ElementToStreamWithLevel                            */
  632. X
  633. XTVeosErr Nancy_ElementToStreamWithLevel(pElt, pStream, iLevel)
  634. X    TPElt        pElt;
  635. X    FILE        *pStream;
  636. X    int            iLevel;
  637. X{
  638. X    TVeosErr        iSuccess;
  639. X    FILE        *pSave;
  640. X
  641. X    iSuccess = VEOS_FAILURE;
  642. X
  643. X    if (pElt && pStream) {                /* sane? */
  644. X
  645. X    pSave = GR_STREAM;
  646. X    GR_STREAM = pStream;
  647. X
  648. X    iSuccess = Nancy_ElementToStreamAux(pElt, iLevel);
  649. X
  650. X    GR_STREAM = pSave;
  651. X    }
  652. X
  653. X    return(iSuccess);
  654. X
  655. X    } /* Nancy_ElementToStreamWithLevel */
  656. X/****************************************************************************************/
  657. X
  658. X
  659. X
  660. X
  661. X/****************************************************************************************
  662. X * Nancy_GroupleToStreamWithLevel                            */
  663. X
  664. XTVeosErr Nancy_GroupleToStreamWithLevel(pGrouple, pStream, iLevel)
  665. X    TPGrouple        pGrouple;
  666. X    FILE        *pStream;
  667. X    int            iLevel;
  668. X{
  669. X    TElt        elt;
  670. X    TVeosErr        iSuccess;
  671. X
  672. X    iSuccess = VEOS_FAILURE;
  673. X
  674. X    if (pGrouple && pStream) {                /* sane? */
  675. X
  676. X    elt = NIL_ELT;
  677. X    elt.iType = GR_grouple;
  678. X    elt.u.pGr = pGrouple;
  679. X
  680. X    iSuccess = Nancy_ElementToStreamWithLevel(&elt, pStream, iLevel);
  681. X    }
  682. X
  683. X    return(iSuccess);
  684. X
  685. X    } /* Nancy_GroupleToStreamWithLevel */
  686. X/****************************************************************************************/
  687. X
  688. X
  689. X
  690. X
  691. X/****************************************************************************************
  692. X                   Grouple -> Network Message
  693. X ****************************************************************************************/
  694. X
  695. X
  696. X/****************************************************************************************
  697. X * Nancy_EltToMessage                                    */
  698. X
  699. XTVeosErr Nancy_EltToMessage(pElt, pBuffer, pLen)
  700. X    TPElt        pElt;
  701. X    char        *pBuffer;
  702. X    int            *pLen;
  703. X{
  704. X    int            iLen, iType;
  705. X
  706. X    if (pElt) {                /* sane? */
  707. X
  708. X    iType = pElt->iType;
  709. X
  710. X    /** first part of message element is element type **/
  711. X    /** assume pBuffer is aligned **/
  712. X
  713. X    *(int *) pBuffer = htonl(iType);    
  714. X
  715. X    pBuffer += 4;
  716. X    *pLen += 4;
  717. X
  718. X    switch (iType) {
  719. X
  720. X    case GR_grouple:
  721. X    case GR_vector:
  722. X        iLen = 0;
  723. X        Nancy_GroupleToMessage(pElt->u.pGr, pBuffer, &iLen);
  724. X        break;
  725. X
  726. X    case GR_int:
  727. X    case GR_float:
  728. X        *(long *) pBuffer = htonl(pElt->u.iVal);
  729. X        iLen = 4;
  730. X        break;
  731. X
  732. X    case GR_string:
  733. X    case GR_prim:
  734. X        strcpy(pBuffer, pElt->u.pS);
  735. X        iLen = MEMSIZE(strlen(pElt->u.pS) + 1);
  736. X        break;
  737. X        
  738. X    case GR_unspecified:
  739. X    default:
  740. X        iLen = 0;
  741. X        break;
  742. X        
  743. X        } /* switch */
  744. X
  745. X    *pLen += iLen;
  746. X    }
  747. X
  748. X    return(VEOS_SUCCESS);
  749. X
  750. X    } /* Nancy_EltToMessage */
  751. X/****************************************************************************************/
  752. X
  753. X
  754. X
  755. X/****************************************************************************************
  756. X * Nancy_GroupleToMessage                                */
  757. X
  758. XTVeosErr Nancy_GroupleToMessage(pGrouple, pBuffer, pLen)
  759. X    TPGrouple        pGrouple;
  760. X    char        *pBuffer;
  761. X    int            *pLen;
  762. X{
  763. X    int            iEltIndex, iElts, iLen;
  764. X    TPElt        pEltList;
  765. X    
  766. X    if (pGrouple) {                /* sane? */
  767. X
  768. X
  769. X    /** use stack vars for speed **/
  770. X
  771. X    iElts = pGrouple->iElts;
  772. X    pEltList = pGrouple->pEltList;
  773. X
  774. X
  775. X
  776. X    /** first code of protocol is number of elements **/
  777. X
  778. X    *(int *) pBuffer = htonl(iElts);    /** assume pBuffer is aligned **/
  779. X
  780. X    pBuffer += 4;
  781. X    *pLen += 4;
  782. X
  783. X
  784. X    for (iEltIndex = 0; iEltIndex < iElts; iEltIndex ++) {
  785. X        
  786. X        iLen = 0;
  787. X
  788. X        /** invoke recursive translation **/
  789. X
  790. X        Nancy_EltToMessage(&pEltList[iEltIndex], pBuffer, &iLen);
  791. X
  792. X        pBuffer += iLen;
  793. X        *pLen += iLen;
  794. X        }
  795. X    }
  796. X
  797. X    return(VEOS_SUCCESS);
  798. X
  799. X    } /* Nancy_GroupleToMessage */
  800. X/****************************************************************************************/
  801. X
  802. X
  803. X
  804. X
  805. X/****************************************************************************************
  806. X *                related public utils                    *
  807. X ****************************************************************************************/
  808. X
  809. X
  810. X/****************************************************************************************
  811. X * Nancy_EmptyGrouple                                    */
  812. X
  813. XTVeosErr Nancy_EmptyGrouple(pGrouple)
  814. X    TPGrouple        pGrouple;
  815. X{
  816. X    TVeosErr        iSuccess;
  817. X
  818. X    iSuccess = VEOS_FAILURE;
  819. X
  820. X    if (pGrouple && pGrouple->iElts > 0) {
  821. X
  822. X    iSuccess = Nancy_DeleteElementsInGrouple(pGrouple, 0, pGrouple->iElts);
  823. X    }
  824. X
  825. X    return(iSuccess);
  826. X
  827. X    } /* Nancy_EmptyGrouple */
  828. X/****************************************************************************************/
  829. X
  830. X
  831. X
  832. X
  833. X/****************************************************************************************/
  834. XTVeosErr Nancy_InsertEltList(pSrcList, iSrcElts, pDestGrouple, iStartElt)
  835. X    TPElt        pSrcList;
  836. X    int            iSrcElts, iStartElt;
  837. X    TPGrouple        pDestGrouple;
  838. X{
  839. X    TVeosErr        iSuccess;
  840. X    int            iSrcIndex;
  841. X    TPElt        pDestList;
  842. X
  843. X
  844. X    iSuccess = VEOS_SUCCESS;
  845. X
  846. X    if (pSrcList && pDestGrouple) {        /* sane? */
  847. X    
  848. X    iSuccess = Nancy_NewElementsInGrouple(pDestGrouple,
  849. X                          iStartElt,
  850. X                          iSrcElts,
  851. X                          GR_unspecified, 0);
  852. X    if (iSuccess == VEOS_SUCCESS) {
  853. X
  854. X
  855. X        /** transfer each element from chosen starting locations **/
  856. X        
  857. X        pDestList = &pDestGrouple->pEltList[iStartElt];
  858. X        iSrcIndex = 0;
  859. X        while (iSrcIndex < iSrcElts) {
  860. X        
  861. X        pDestList[iSrcIndex] = pSrcList[iSrcIndex];
  862. X        
  863. X
  864. X        /** set default vals for src elements **/
  865. X        /** in case the caller disposes the src elt list after the call **/
  866. X        
  867. X        pSrcList[iSrcIndex++] = NIL_ELT;
  868. X        }
  869. X        }
  870. X    }
  871. X
  872. X    return(iSuccess);
  873. X
  874. X    } /* Nancy_InsertEltList */
  875. X/****************************************************************************************/
  876. X
  877. X
  878. X
  879. X
  880. X/****************************************************************************************/
  881. XTVeosErr Nancy_CopyEltList(pSrcList, pDestList, iElts)
  882. X    TPElt        pSrcList, pDestList;
  883. X    int            iElts;
  884. X{
  885. X    int            iEltIndex;
  886. X    TVeosErr        iSuccess = VEOS_SUCCESS;
  887. X
  888. X
  889. X    if (pSrcList && pDestList) {        /* sane? */
  890. X
  891. X    /** copy the grouple element list, one elt at a time **/
  892. X    
  893. X    iSuccess = VEOS_SUCCESS;
  894. X    iEltIndex = 0;
  895. X    while (iEltIndex < iElts && iSuccess == VEOS_SUCCESS) {
  896. X
  897. X        pDestList[iEltIndex] = pSrcList[iEltIndex];
  898. X
  899. X        if (pSrcList[iEltIndex].iType != GR_unspecified) {
  900. X
  901. X        iSuccess = Nancy_CreateElement(&pDestList[iEltIndex],
  902. X                           pSrcList[iEltIndex].iType, 0);
  903. X        if (iSuccess == VEOS_SUCCESS)
  904. X            
  905. X            iSuccess = Nancy_CopyElement(&pSrcList[iEltIndex],
  906. X                         &pDestList[iEltIndex]);
  907. X        }
  908. X        
  909. X        iEltIndex ++;
  910. X        }
  911. X    }
  912. X
  913. X    return(iSuccess);
  914. X    
  915. X    } /* Nancy_CopyEltList */
  916. X/****************************************************************************************/
  917. X
  918. X
  919. X
  920. X
  921. X/****************************************************************************************
  922. X * Nancy_ConcatGrouple                                    */
  923. XTVeosErr Nancy_ConcatGrouple(pSrcGrouple, pDestGrouple)
  924. X    TPGrouple        pSrcGrouple;
  925. X    TPGrouple        pDestGrouple;
  926. X{
  927. X    TVeosErr        iSuccess;
  928. X    int            iOldElts;
  929. X
  930. X    iSuccess = VEOS_FAILURE;                          /* pessimism */
  931. X
  932. X    if (pSrcGrouple && pDestGrouple) {                /* sanity check */
  933. X
  934. X
  935. X    /** allocate element list enough for all copied elements **/
  936. X
  937. X    iOldElts = pDestGrouple->iElts;
  938. X    iSuccess = Nancy_ResizeEltList(pDestGrouple,
  939. X                       iOldElts + pSrcGrouple->iElts);
  940. X    if (iSuccess == VEOS_SUCCESS) {
  941. X
  942. X
  943. X        iSuccess = Nancy_CopyEltList(pSrcGrouple->pEltList,
  944. X                     &pDestGrouple->pEltList[iOldElts],
  945. X                     pSrcGrouple->iElts);
  946. X        }
  947. X    }
  948. X
  949. X    return(iSuccess);
  950. X
  951. X    } /* Nancy_ConcatGrouple */
  952. X/****************************************************************************************/
  953. X
  954. X
  955. X
  956. X
  957. X/****************************************************************************************/
  958. XTVeosErr Nancy_EltIdentical(pLeftElt, pRightElt)
  959. X    TPElt        pRightElt, pLeftElt;
  960. X{
  961. X    TVeosErr        iSuccess;
  962. X    int            iType;
  963. X    boolean        bSame;
  964. X    char        *pGenericRight, *pGenericLeft, *pMax;
  965. X    
  966. X
  967. X    iSuccess = VEOS_FAILURE;
  968. X    bSame = FALSE;
  969. X
  970. X    if (pLeftElt == pRightElt)
  971. X    bSame = TRUE;
  972. X
  973. X    else if (pLeftElt &&
  974. X         pRightElt &&
  975. X         pLeftElt->iType == pRightElt->iType) {
  976. X
  977. X    iType = pLeftElt->iType;
  978. X    switch (iType) {
  979. X        
  980. X    case GR_float:
  981. X        if (pLeftElt->u.fVal == pRightElt->u.fVal)
  982. X        bSame = TRUE;
  983. X        break;
  984. X        
  985. X    case GR_int:
  986. X        if (pLeftElt->u.iVal == pRightElt->u.iVal)
  987. X        bSame = TRUE;
  988. X        break;
  989. X        
  990. X    case GR_string:
  991. X    case GR_prim:
  992. X        if (strcmp(pLeftElt->u.pS, pRightElt->u.pS) == 0)
  993. X        bSame = TRUE;
  994. X        break;
  995. X        
  996. X    case GR_unspecified:
  997. X    default:
  998. X        bSame = TRUE;
  999. X        break;
  1000. X        
  1001. X        } /* switch */
  1002. X    }
  1003. X    
  1004. X    if (bSame)
  1005. X    iSuccess = VEOS_SUCCESS;
  1006. X
  1007. X    return(iSuccess);
  1008. X
  1009. X    } /* Nancy_EltIdentical */
  1010. X/****************************************************************************************/
  1011. X
  1012. X
  1013. X
  1014. X
  1015. X/****************************************************************************************
  1016. X * Nancy_TrapErr                                    */
  1017. X
  1018. XTVeosErr Nancy_TrapErr(iErr)
  1019. X    TVeosErr        iErr;
  1020. X{
  1021. X    switch(iErr) {
  1022. X    
  1023. X    case NANCY_EndOfGrouple:
  1024. X    fprintf(stderr, "nancy %s: end of grouple reached\n", WHOAMI);
  1025. X    break;         
  1026. X    
  1027. X    case NANCY_MisplacedLeftBracket:
  1028. X    fprintf(stderr, "nancy %s: misplaced '[', near line: %d\n", WHOAMI, LINE_COUNT);    
  1029. X    break;
  1030. X    
  1031. X    case NANCY_MisplacedRightBracket:
  1032. X    fprintf(stderr, "nancy %s: misplaced ']', near line: %d\n", WHOAMI, LINE_COUNT);    
  1033. X    break;
  1034. X    
  1035. X    case NANCY_MissingRightBracket:
  1036. X    fprintf(stderr, "nancy %s: missing ']', near line: %d\n", WHOAMI, LINE_COUNT);    
  1037. X    break;
  1038. X    
  1039. X    case NANCY_BadType:
  1040. X    fprintf(stderr, "nancy %s: bad element type, near line: %d\n", WHOAMI, LINE_COUNT);    
  1041. X    break;
  1042. X    
  1043. X    case NANCY_NoTypeMatch:
  1044. X    fprintf(stderr, "nancy %s: unknown data type, near line: %d\n", WHOAMI, LINE_COUNT);
  1045. X    break;
  1046. X    
  1047. X    case VEOS_EOF:
  1048. X    fprintf(stderr, "nancy %s: end of stream reached permaturely, near line: %d\n", WHOAMI, LINE_COUNT);
  1049. X    break;
  1050. X    
  1051. X    case VEOS_MEM_ERR:
  1052. X    fprintf(stderr, "nancy %s: memory error\n", WHOAMI);
  1053. X    break;
  1054. X    
  1055. X    case VEOS_FAILURE:
  1056. X    fprintf(stderr, "nancy %s: bad parameters\n", WHOAMI);
  1057. X    break;
  1058. X    
  1059. X    case VEOS_SUCCESS:
  1060. X    fprintf(stderr, "nancy %s: success\n", WHOAMI);
  1061. X    break;
  1062. X    
  1063. X    case NANCY_NoMatch:
  1064. X    fprintf(stderr, "nancy %s: no matches were found\n", WHOAMI);
  1065. X    break;
  1066. X
  1067. X    case NANCY_NotSupported:
  1068. X    fprintf(stderr, "nancy %s: that operation not currently supported\n", WHOAMI);
  1069. X    break;
  1070. X    
  1071. X    case NANCY_SrcTooShort:
  1072. X    fprintf(stderr, "nancy %s: no match - source grouple shorter than pattern\n", WHOAMI);
  1073. X    break;
  1074. X
  1075. X    case NANCY_PatTooShort:
  1076. X    fprintf(stderr, "nancy %s: no match - pattern shorter than source grouple\n", WHOAMI);
  1077. X    break;
  1078. X
  1079. X    default:
  1080. X    fprintf(stderr, "nancy %s: unknown error: %d\n", WHOAMI, iErr);
  1081. X    break;
  1082. X    
  1083. X    } /* switch */
  1084. X    
  1085. X    } /* Nancy_TrapErr */
  1086. X/****************************************************************************************/
  1087. X
  1088. X
  1089. X
  1090. X/****************************************************************************************
  1091. X *                       private routines                    *
  1092. X ****************************************************************************************/
  1093. X
  1094. X
  1095. X/****************************************************************************************
  1096. X * Nancy_ResizeEltList                                    */
  1097. X
  1098. XTVeosErr Nancy_ResizeEltList(pDestGrouple, iNewElts)
  1099. X    TPGrouple        pDestGrouple;
  1100. X    int            iNewElts;
  1101. X{        
  1102. X    TVeosErr        iSuccess;
  1103. X    TPElt        pEltList;
  1104. X    int            iIsLen, iShouldLen;
  1105. X
  1106. X    iSuccess = VEOS_SUCCESS;    
  1107. X
  1108. X    if (pDestGrouple) {                /* sane? */
  1109. X
  1110. X
  1111. X    /** if element ptr array is too long or too short, alter size **/
  1112. X
  1113. X    iShouldLen = ELTS_ALLOCATED(iNewElts);
  1114. X    iIsLen = ELTS_ALLOCATED(pDestGrouple->iElts);
  1115. X
  1116. X    if (iShouldLen != iIsLen) {
  1117. X
  1118. X        iSuccess = VEOS_MEM_ERR;
  1119. X        pEltList = nil;
  1120. X
  1121. X
  1122. X        /**---------------------------------------------------**/
  1123. X        /** use fast in-house memory scheme for element lists **/
  1124. X        /**---------------------------------------------------**/
  1125. X        
  1126. X        if (iShouldLen <= 0) {
  1127. X        
  1128. X        /** want to dispose all elt list memory **/
  1129. X        
  1130. X        if (pDestGrouple->pEltList)
  1131. X            Shell_ReturnBlock(pDestGrouple->pEltList,
  1132. X                      iIsLen * sizeof(TElt), "elt list");
  1133. X        }
  1134. X        
  1135. X        else if (pDestGrouple->pEltList) {
  1136. X        
  1137. X        
  1138. X        /** want to resize elt list array **/
  1139. X        
  1140. X        iSuccess = Shell_NewBlock(iShouldLen * sizeof(TElt),
  1141. X                      &pEltList, "bigger elt list");
  1142. X        if (iSuccess == VEOS_SUCCESS) {
  1143. X            
  1144. X            bcopy(pDestGrouple->pEltList,
  1145. X              pEltList,
  1146. X              (iIsLen < iShouldLen ? iIsLen : iShouldLen) * sizeof(TElt));
  1147. X            
  1148. X            Shell_ReturnBlock(pDestGrouple->pEltList,
  1149. X                      iIsLen * sizeof(TElt), "smaller elt list");
  1150. X            }
  1151. X        }
  1152. X        
  1153. X        
  1154. X        else {
  1155. X        /** want to create elt list for first time **/
  1156. X        
  1157. X        iSuccess = Shell_NewBlock(iShouldLen * sizeof(TElt),
  1158. X                      &pEltList, "elt list");
  1159. X        }
  1160. X
  1161. X        /** attach new element array (contains old contents) **/
  1162. X
  1163. X        if (iSuccess = VEOS_SUCCESS)
  1164. X        pDestGrouple->pEltList = pEltList;
  1165. X        }
  1166. X
  1167. X    pDestGrouple->iElts = iNewElts;
  1168. X    }
  1169. X
  1170. X    return(iSuccess);
  1171. X
  1172. X    } /* Nancy_ResizeEltList */
  1173. X/****************************************************************************************/
  1174. X
  1175. X
  1176. X
  1177. X/****************************************************************************************/
  1178. XTVeosErr Nancy_DownShift(pGrouple, iStartElt, iElts)
  1179. X    TPGrouple        pGrouple;
  1180. X    int            iStartElt, iElts;
  1181. X{
  1182. X    TVeosErr        iSuccess;
  1183. X    TPElt        pEltList;
  1184. X    int            iNewElts, iIndex;
  1185. X
  1186. X    
  1187. X    /** use stack vars for speed **/
  1188. X    
  1189. X    pEltList = pGrouple->pEltList;
  1190. X    iNewElts = pGrouple->iElts - iElts;
  1191. X    
  1192. X    
  1193. X    
  1194. X    iIndex = iStartElt;
  1195. X    while (iIndex < iNewElts) {
  1196. X    
  1197. X    pEltList[iIndex] = pEltList[iIndex + iElts];
  1198. X    
  1199. X    iIndex ++;
  1200. X    }
  1201. X    
  1202. X    iSuccess = Nancy_ResizeEltList(pGrouple, iNewElts);
  1203. X
  1204. X    return(iSuccess);
  1205. X
  1206. X    } /* Nancy_DownShift */
  1207. X/****************************************************************************************/
  1208. X
  1209. X
  1210. X/****************************************************************************************/
  1211. XTVeosErr Nancy_ElementToStreamAux(pElt, iLevel)
  1212. X    TPElt        pElt;
  1213. X    int            iLevel;
  1214. X{
  1215. X    TPElt        pEltList;
  1216. X    int            iElts, iEltIndex;
  1217. X    str63        sHostName;
  1218. X
  1219. X    if (pElt) {                /* sane? */
  1220. X
  1221. X    Nancy_StreamTabs(iLevel, GR_STREAM);
  1222. X
  1223. X    if (TESTFLAG(NANCY_EltMarkMask, pElt->iFlags))
  1224. X        fprintf(stderr, "> ");
  1225. X
  1226. X    PRINT_TIME(pElt->tLastMod, stderr);
  1227. X
  1228. X    
  1229. X    switch (pElt->iType) {
  1230. X        
  1231. X    case GR_vector:
  1232. X        fprintf(GR_STREAM, "#");
  1233. X        
  1234. X    case GR_grouple:
  1235. X        fprintf(GR_STREAM, "[\n");
  1236. X        
  1237. X        pEltList = pElt->u.pGr->pEltList;
  1238. X        iElts = pElt->u.pGr->iElts;
  1239. X        
  1240. X        for (iEltIndex = 0; iEltIndex < iElts; iEltIndex ++) {
  1241. X        
  1242. X        /** recurs */
  1243. X        Nancy_ElementToStreamAux(&pEltList[iEltIndex], iLevel + 1);
  1244. X        }
  1245. X        
  1246. X        Nancy_StreamTabs(iLevel, GR_STREAM);
  1247. X        fprintf(GR_STREAM, "]\n");
  1248. X        break;
  1249. X        
  1250. X    case GR_here:
  1251. X        fprintf(GR_STREAM, "^\n");
  1252. X        break;
  1253. X        
  1254. X    case GR_some:
  1255. X        fprintf(GR_STREAM, "*%d\n", pElt->u.iVal);
  1256. X        break;
  1257. X        
  1258. X    case GR_any:
  1259. X        fprintf(GR_STREAM, "**\n");
  1260. X        break;
  1261. X        
  1262. X    case GR_these:
  1263. X        fprintf(GR_STREAM, "@%d\n", pElt->u.iVal);
  1264. X        break;
  1265. X        
  1266. X    case GR_theseall:
  1267. X        fprintf(GR_STREAM, "@@\n");
  1268. X        break;
  1269. X        
  1270. X    case GR_float:
  1271. X        fprintf(GR_STREAM, "%.2f\n", pElt->u.fVal);
  1272. X        break;
  1273. X        
  1274. X    case GR_int:
  1275. X        fprintf(GR_STREAM, "%d\n", pElt->u.iVal);
  1276. X        break;
  1277. X        
  1278. X    case GR_string:
  1279. X        fprintf(GR_STREAM, "\"%s\"\n", pElt->u.pS);
  1280. X        break;
  1281. X        
  1282. X    case GR_prim:
  1283. X        fprintf(GR_STREAM, "'prim' %s\n", pElt->u.pS);
  1284. X        break;
  1285. X        
  1286. X    case GR_unspecified:
  1287. X        fprintf(GR_STREAM, "()\n");
  1288. X        break;
  1289. X        
  1290. X    default:
  1291. X        break;
  1292. X        
  1293. X        } /* switch */
  1294. X    }
  1295. X
  1296. X    return(VEOS_SUCCESS);
  1297. X
  1298. X    } /* Nancy_ElementToStreamAux */
  1299. X/****************************************************************************************/
  1300. X
  1301. X
  1302. X
  1303. X/****************************************************************************************/
  1304. XTVeosErr Nancy_TypeToString(iType, sName)
  1305. X    int        iType;
  1306. X    char    *sName;
  1307. X{
  1308. X    if (sName) {
  1309. X
  1310. X    switch (iType) {
  1311. X        
  1312. X    case GR_grouple:
  1313. X        strcpy(sName, "grouple");
  1314. X        break;
  1315. X    case GR_vector:
  1316. X        strcpy(sName, "vector");
  1317. X        break;
  1318. X    case GR_float:
  1319. X        strcpy(sName, "float");
  1320. X        break;
  1321. X    case GR_int:
  1322. X        strcpy(sName, "int");
  1323. X        break;
  1324. X    case GR_string:
  1325. X        strcpy(sName, "string");
  1326. X        break;
  1327. X    case GR_prim:
  1328. X        strcpy(sName, "prim");
  1329. X        break;
  1330. X    case GR_unspecified:
  1331. X        strcpy(sName, "unspecified");
  1332. X        break;
  1333. X    case GR_these:
  1334. X        strcpy(sName, "these");
  1335. X        break;
  1336. X    case GR_theseall:
  1337. X        strcpy(sName, "theseall");
  1338. X        break;
  1339. X    case GR_some:
  1340. X        strcpy(sName, "some");
  1341. X        break;
  1342. X    case GR_any:
  1343. X        strcpy(sName, "any");
  1344. X        break;
  1345. X    case GR_here:
  1346. X        strcpy(sName, "here");
  1347. X        break;
  1348. X    case GR_mark:
  1349. X        strcpy(sName, "mark");
  1350. X        break;
  1351. X    case GR_touch:
  1352. X        strcpy(sName, "touch");
  1353. X        break;
  1354. X    default:
  1355. X        break;
  1356. X        
  1357. X        } /* switch */
  1358. X    }
  1359. X
  1360. X    return(VEOS_SUCCESS);
  1361. X    
  1362. X    } /* Nancy_TypeToString */
  1363. X/****************************************************************************************/
  1364. X
  1365. X
  1366. X
  1367. X/****************************************************************************************/
  1368. XTVeosErr Nancy_StreamTabs(iTabs, pStream)
  1369. X    int        iTabs;
  1370. X    FILE    *pStream;
  1371. X{
  1372. X    while (iTabs-- > 0)
  1373. X    fprintf(pStream, "    ");
  1374. X
  1375. X    return(VEOS_SUCCESS);
  1376. X
  1377. X    } /* Nancy_StreamTabs */
  1378. X/****************************************************************************************/
  1379. X
  1380. X
  1381. X
  1382. X
  1383. X/****************************************************************************************/
  1384. XTVeosErr Nancy_SetupFastMem()
  1385. X{
  1386. X    TVeosErr        iSuccess;
  1387. X    int            i;
  1388. X
  1389. X    iSuccess = VEOS_SUCCESS;
  1390. X
  1391. X    TYPE_SIZES[GR_grouple] = TYPE_SIZES[GR_vector] = sizeof(TGrouple);
  1392. X
  1393. X    TYPE_SIZES[GR_prim] = TYPE_SIZES[GR_string] = 0;
  1394. X
  1395. X    TYPE_SIZES[GR_float] = 0;
  1396. X    TYPE_SIZES[GR_int] = 0;
  1397. X    TYPE_SIZES[GR_these] = 0;
  1398. X    TYPE_SIZES[GR_theseall] = 0; 
  1399. X    TYPE_SIZES[GR_some] = 0;
  1400. X    TYPE_SIZES[GR_any] = 0;
  1401. X    TYPE_SIZES[GR_here] = 0;
  1402. X
  1403. X
  1404. X    /* the elt list for the empty grouple is nil */
  1405. X    ALLOC_ELTS[0] = 0;
  1406. X
  1407. X    /* optimize for pair-type grouples coming from lisp */
  1408. X    ALLOC_ELTS[1] = 2;
  1409. X    ALLOC_ELTS[2] = 2;
  1410. X
  1411. X    for (i = 3; i < NANCY_AllocHashMax; i++)
  1412. X    ALLOC_ELTS[i] = ELTS_TO_ALLOCATE(i);
  1413. X
  1414. X    return(iSuccess);
  1415. X
  1416. X    } /* Nancy_SetupFastMem */
  1417. X/****************************************************************************************/
  1418. X
  1419. X
  1420. X                 
  1421. X
  1422. X
  1423. END_OF_FILE
  1424. if test 31245 -ne `wc -c <'src/kernel_current/nancy/nancy_fundamental.c'`; then
  1425.     echo shar: \"'src/kernel_current/nancy/nancy_fundamental.c'\" unpacked with wrong size!
  1426. fi
  1427. # end of 'src/kernel_current/nancy/nancy_fundamental.c'
  1428. fi
  1429. if test -f 'src/xlisp/xcore/c/xlcont.c' -a "${1}" != "-c" ; then 
  1430.   echo shar: Will not clobber existing file \"'src/xlisp/xcore/c/xlcont.c'\"
  1431. else
  1432. echo shar: Extracting \"'src/xlisp/xcore/c/xlcont.c'\" \(30247 characters\)
  1433. sed "s/^X//" >'src/xlisp/xcore/c/xlcont.c' <<'END_OF_FILE'
  1434. X/* -*-C-*-
  1435. X********************************************************************************
  1436. X*
  1437. X* File:         xlcont
  1438. X* RCS:          $Header: xlcont.c,v 1.4 89/11/25 05:14:27 mayer Exp $
  1439. X* Description:  xlisp special forms
  1440. X* Author:       David Michael Betz
  1441. X* Created:      
  1442. X* Modified:     Sat Nov 25 05:14:10 1989 (Niels Mayer) mayer@hplnpm
  1443. X* Language:     C
  1444. X* Package:      N/A
  1445. X* Status:       X11r4 contrib tape release
  1446. X*
  1447. X* WINTERP 1.0 Copyright 1989 Hewlett-Packard Company (by Niels Mayer).
  1448. X* XLISP version 2.1, Copyright (c) 1989, by David Betz.
  1449. X*
  1450. X* Permission to use, copy, modify, distribute, and sell this software and its
  1451. X* documentation for any purpose is hereby granted without fee, provided that
  1452. X* the above copyright notice appear in all copies and that both that
  1453. X* copyright notice and this permission notice appear in supporting
  1454. X* documentation, and that the name of Hewlett-Packard and David Betz not be
  1455. X* used in advertising or publicity pertaining to distribution of the software
  1456. X* without specific, written prior permission.  Hewlett-Packard and David Betz
  1457. X* make no representations about the suitability of this software for any
  1458. X* purpose. It is provided "as is" without express or implied warranty.
  1459. X*
  1460. X* HEWLETT-PACKARD AND DAVID BETZ DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
  1461. X* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
  1462. X* IN NO EVENT SHALL HEWLETT-PACKARD NOR DAVID BETZ BE LIABLE FOR ANY SPECIAL,
  1463. X* INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  1464. X* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
  1465. X* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  1466. X* PERFORMANCE OF THIS SOFTWARE.
  1467. X*
  1468. X* See ./winterp/COPYRIGHT for information on contacting the authors.
  1469. X* 
  1470. X* Please send modifications, improvements and bugfixes to mayer@hplabs.hp.com
  1471. X* Post XLISP-specific questions/information to the newsgroup comp.lang.lisp.x
  1472. X*
  1473. X********************************************************************************
  1474. X*/
  1475. Xstatic char rcs_identity[] = "@(#)$Header: xlcont.c,v 1.4 89/11/25 05:14:27 mayer Exp $";
  1476. X
  1477. X
  1478. X#include "xlisp.h"
  1479. X
  1480. X/* external variables */
  1481. Xextern LVAL xlenv,xlfenv,xldenv,xlvalue;
  1482. Xextern LVAL s_setf,s_car,s_cdr,s_nth,s_aref,s_get;
  1483. Xextern LVAL s_svalue,s_sfunction,s_splist;
  1484. Xextern LVAL s_lambda,s_macro;
  1485. Xextern LVAL s_comma,s_comat;
  1486. Xextern LVAL s_unbound;
  1487. Xextern LVAL true;
  1488. X
  1489. X/* external routines */
  1490. Xextern LVAL makearglist();
  1491. X
  1492. X/* forward declarations */
  1493. XFORWARD LVAL bquote1();
  1494. XFORWARD LVAL let();
  1495. XFORWARD LVAL flet();
  1496. XFORWARD LVAL prog();
  1497. XFORWARD LVAL progx();
  1498. XFORWARD LVAL doloop();
  1499. XFORWARD LVAL evarg();
  1500. XFORWARD LVAL match();
  1501. XFORWARD LVAL evmatch();
  1502. X
  1503. X/* dummy node type for a list */
  1504. X#define LIST    -1
  1505. X
  1506. X/* xquote - special form 'quote' */
  1507. XLVAL xquote()
  1508. X{
  1509. X    LVAL val;
  1510. X    val = xlgetarg();
  1511. X    xllastarg();
  1512. X    return (val);
  1513. X}
  1514. X
  1515. X/* xfunction - special form 'function' */
  1516. XLVAL xfunction()
  1517. X{
  1518. X    LVAL val;
  1519. X
  1520. X    /* get the argument */
  1521. X    val = xlgetarg();
  1522. X    xllastarg();
  1523. X
  1524. X    /* create a closure for lambda expressions */
  1525. X    if (consp(val) && car(val) == s_lambda && consp(cdr(val)))
  1526. X    val = xlclose(NIL,s_lambda,car(cdr(val)),cdr(cdr(val)),xlenv,xlfenv);
  1527. X
  1528. X    /* otherwise, get the value of a symbol */
  1529. X    else if (symbolp(val))
  1530. X    val = xlgetfunction(val);
  1531. X
  1532. X    /* otherwise, its an error */
  1533. X    else
  1534. X    xlerror("not a function",val);
  1535. X
  1536. X    /* return the function */
  1537. X    return (val);
  1538. X}
  1539. X
  1540. X/* xbquote - back quote special form */
  1541. XLVAL xbquote()
  1542. X{
  1543. X    LVAL expr;
  1544. X
  1545. X    /* get the expression */
  1546. X    expr = xlgetarg();
  1547. X    xllastarg();
  1548. X
  1549. X    /* fill in the template */
  1550. X    return (bquote1(expr));
  1551. X}
  1552. X
  1553. X/* bquote1 - back quote helper function */
  1554. XLOCAL LVAL bquote1(expr)
  1555. X  LVAL expr;
  1556. X{
  1557. X    LVAL val,list,last,new;
  1558. X
  1559. X    /* handle atoms */
  1560. X    if (atom(expr))
  1561. X    val = expr;
  1562. X
  1563. X    /* handle (comma <expr>) */
  1564. X    else if (car(expr) == s_comma) {
  1565. X    if (atom(cdr(expr)))
  1566. X        xlfail("bad comma expression");
  1567. X    val = xleval(car(cdr(expr)));
  1568. X    }
  1569. X
  1570. X    /* handle ((comma-at <expr>) ... ) */
  1571. X    else if (consp(car(expr)) && car(car(expr)) == s_comat) {
  1572. X    xlstkcheck(2);
  1573. X    xlsave(list);
  1574. X    xlsave(val);
  1575. X    if (atom(cdr(car(expr))))
  1576. X        xlfail("bad comma-at expression");
  1577. X    list = xleval(car(cdr(car(expr))));
  1578. X    for (last = NIL; consp(list); list = cdr(list)) {
  1579. X        new = consa(car(list));
  1580. X        if (last)
  1581. X        rplacd(last,new);
  1582. X        else
  1583. X        val = new;
  1584. X        last = new;
  1585. X    }
  1586. X    if (last)
  1587. X        rplacd(last,bquote1(cdr(expr)));
  1588. X    else
  1589. X        val = bquote1(cdr(expr));
  1590. X    xlpopn(2);
  1591. X    }
  1592. X
  1593. X    /* handle any other list */
  1594. X    else {
  1595. X    xlsave1(val);
  1596. X    val = consa(NIL);
  1597. X    rplaca(val,bquote1(car(expr)));
  1598. X    rplacd(val,bquote1(cdr(expr)));
  1599. X    xlpop();
  1600. X    }
  1601. X
  1602. X    /* return the result */
  1603. X    return (val);
  1604. X}
  1605. X
  1606. X/* xlambda - special form 'lambda' */
  1607. XLVAL xlambda()
  1608. X{
  1609. X    LVAL fargs,body,val;
  1610. X
  1611. X    /* get the formal argument list and function body */
  1612. X    xlsave1(body);
  1613. X    fargs = xlgalist();
  1614. X    body  = makearglist(xlargc,xlargv);
  1615. X
  1616. X    /* create a new function definition */
  1617. X    val = xlclose(NIL,s_lambda,fargs,body,xlenv,xlfenv);
  1618. X
  1619. X    /* restore the stack and return the closure */
  1620. X    xlpop();
  1621. X    return (val);
  1622. X}
  1623. X
  1624. X/* xgetlambda - get the lambda expression associated with a closure */
  1625. XLVAL xgetlambda()
  1626. X{
  1627. X    LVAL closure;
  1628. X    closure = xlgaclosure();
  1629. X    return (cons(gettype(closure),
  1630. X                 cons(getlambda(closure),getbody(closure))));
  1631. X}
  1632. X
  1633. X/* xsetq - special form 'setq' */
  1634. XLVAL xsetq()
  1635. X{
  1636. X    LVAL sym,val;
  1637. X
  1638. X    /* handle each pair of arguments */
  1639. X    for (val = NIL; moreargs(); ) {
  1640. X    sym = xlgasymbol();
  1641. X    val = xleval(nextarg());
  1642. X    xlsetvalue(sym,val);
  1643. X    }
  1644. X
  1645. X    /* return the result value */
  1646. X    return (val);
  1647. X}
  1648. X
  1649. X/* xpsetq - special form 'psetq' */
  1650. XLVAL xpsetq()
  1651. X{
  1652. X    LVAL plist,sym,val;
  1653. X
  1654. X    /* protect some pointers */
  1655. X    xlsave1(plist);
  1656. X
  1657. X    /* handle each pair of arguments */
  1658. X    for (val = NIL; moreargs(); ) {
  1659. X    sym = xlgasymbol();
  1660. X    val = xleval(nextarg());
  1661. X    plist = cons(cons(sym,val),plist);
  1662. X    }
  1663. X
  1664. X    /* do parallel sets */
  1665. X    for (; plist; plist = cdr(plist))
  1666. X    xlsetvalue(car(car(plist)),cdr(car(plist)));
  1667. X
  1668. X    /* restore the stack */
  1669. X    xlpop();
  1670. X
  1671. X    /* return the result value */
  1672. X    return (val);
  1673. X}
  1674. X
  1675. X/* xsetf - special form 'setf' */
  1676. XLVAL xsetf()
  1677. X{
  1678. X    LVAL place,value;
  1679. X
  1680. X    /* protect some pointers */
  1681. X    xlsave1(value);
  1682. X
  1683. X    /* handle each pair of arguments */
  1684. X    while (moreargs()) {
  1685. X
  1686. X    /* get place and value */
  1687. X    place = xlgetarg();
  1688. X    value = xleval(nextarg());
  1689. X
  1690. X    /* expand macros in the place form */
  1691. X    if (consp(place))
  1692. X        place = xlexpandmacros(place);
  1693. X    
  1694. X    /* check the place form */
  1695. X    if (symbolp(place))
  1696. X        xlsetvalue(place,value);
  1697. X    else if (consp(place))
  1698. X        placeform(place,value);
  1699. X    else
  1700. X        xlfail("bad place form");
  1701. X    }
  1702. X
  1703. X    /* restore the stack */
  1704. X    xlpop();
  1705. X
  1706. X    /* return the value */
  1707. X    return (value);
  1708. X}
  1709. X
  1710. X/* placeform - handle a place form other than a symbol */
  1711. X#ifdef PROVIDE_WINTERP
  1712. Xplaceform(place,value)        /* needed by w_resources.c:Wres_GetValues_ArgList_To_Lisp */
  1713. X#else
  1714. XLOCAL placeform(place,value)
  1715. X#endif
  1716. X  LVAL place,value;
  1717. X{
  1718. X    LVAL fun,arg1,arg2;
  1719. X    int i;
  1720. X
  1721. X    /* check the function name */
  1722. X    if ((fun = match(SYMBOL,&place)) == s_get) {
  1723. X    xlstkcheck(2);
  1724. X    xlsave(arg1);
  1725. X    xlsave(arg2);
  1726. X    arg1 = evmatch(SYMBOL,&place);
  1727. X    arg2 = evmatch(SYMBOL,&place);
  1728. X    if (place) toomany(place);
  1729. X    xlputprop(arg1,value,arg2);
  1730. X    xlpopn(2);
  1731. X    }
  1732. X    else if (fun == s_svalue) {
  1733. X    arg1 = evmatch(SYMBOL,&place);
  1734. X    if (place) toomany(place);
  1735. X    setvalue(arg1,value);
  1736. X    }
  1737. X    else if (fun == s_sfunction) {
  1738. X    arg1 = evmatch(SYMBOL,&place);
  1739. X    if (place) toomany(place);
  1740. X    setfunction(arg1,value);
  1741. X    }
  1742. X    else if (fun == s_splist) {
  1743. X    arg1 = evmatch(SYMBOL,&place);
  1744. X    if (place) toomany(place);
  1745. X    setplist(arg1,value);
  1746. X    }
  1747. X    else if (fun == s_car) {
  1748. X    arg1 = evmatch(CONS,&place);
  1749. X    if (place) toomany(place);
  1750. X    rplaca(arg1,value);
  1751. X    }
  1752. X    else if (fun == s_cdr) {
  1753. X    arg1 = evmatch(CONS,&place);
  1754. X    if (place) toomany(place);
  1755. X    rplacd(arg1,value);
  1756. X    }
  1757. X    else if (fun == s_nth) {
  1758. X    xlsave1(arg1);
  1759. X    arg1 = evmatch(FIXNUM,&place);
  1760. X    arg2 = evmatch(LIST,&place);
  1761. X    if (place) toomany(place);
  1762. X    for (i = (int)getfixnum(arg1); i > 0 && consp(arg2); --i)
  1763. X        arg2 = cdr(arg2);
  1764. X    if (consp(arg2))
  1765. X        rplaca(arg2,value);
  1766. X    xlpop();
  1767. X    }
  1768. X    else if (fun == s_aref) {
  1769. X    xlsave1(arg1);
  1770. X    arg1 = evmatch(VECTOR,&place);
  1771. X    arg2 = evmatch(FIXNUM,&place); i = (int)getfixnum(arg2);
  1772. X    if (place) toomany(place);
  1773. X    if (i < 0 || i >= getsz(arg1))
  1774. X        xlerror("index out of range",arg2);
  1775. X    setelement(arg1,i,value);
  1776. X    xlpop();
  1777. X    }
  1778. X    else if (fun = xlgetprop(fun,s_setf))
  1779. X    setffunction(fun,place,value);
  1780. X    else
  1781. X    xlfail("bad place form");
  1782. X}
  1783. X
  1784. X/* setffunction - call a user defined setf function */
  1785. XLOCAL setffunction(fun,place,value)
  1786. X  LVAL fun,place,value;
  1787. X{
  1788. X    LVAL *newfp;
  1789. X    int argc;
  1790. X
  1791. X    /* create the new call frame */
  1792. X    newfp = xlsp;
  1793. X    pusharg(cvfixnum((FIXTYPE)(newfp - xlfp)));
  1794. X    pusharg(fun);
  1795. X    pusharg(NIL);
  1796. X
  1797. X    /* push the values of all of the place expressions and the new value */
  1798. X    for (argc = 1; consp(place); place = cdr(place), ++argc)
  1799. X    pusharg(xleval(car(place)));
  1800. X    pusharg(value);
  1801. X
  1802. X    /* insert the argument count and establish the call frame */
  1803. X    newfp[2] = cvfixnum((FIXTYPE)argc);
  1804. X    xlfp = newfp;
  1805. X
  1806. X    /* apply the function */
  1807. X    xlapply(argc);
  1808. X}
  1809. X               
  1810. X/* xdefun - special form 'defun' */
  1811. XLVAL xdefun()
  1812. X{
  1813. X    LVAL sym,fargs,arglist;
  1814. X
  1815. X    /* get the function symbol and formal argument list */
  1816. X    xlsave1(arglist);
  1817. X    sym = xlgasymbol();
  1818. X    fargs = xlgalist();
  1819. X    arglist = makearglist(xlargc,xlargv);
  1820. X
  1821. X    /* make the symbol point to a new function definition */
  1822. X    xlsetfunction(sym,xlclose(sym,s_lambda,fargs,arglist,xlenv,xlfenv));
  1823. X
  1824. X    /* restore the stack and return the function symbol */
  1825. X    xlpop();
  1826. X    return (sym);
  1827. X}
  1828. X
  1829. X/* xdefmacro - special form 'defmacro' */
  1830. XLVAL xdefmacro()
  1831. X{
  1832. X    LVAL sym,fargs,arglist;
  1833. X
  1834. X    /* get the function symbol and formal argument list */
  1835. X    xlsave1(arglist);
  1836. X    sym = xlgasymbol();
  1837. X    fargs = xlgalist();
  1838. X    arglist = makearglist(xlargc,xlargv);
  1839. X
  1840. X    /* make the symbol point to a new function definition */
  1841. X    xlsetfunction(sym,xlclose(sym,s_macro,fargs,arglist,NIL,NIL));
  1842. X
  1843. X    /* restore the stack and return the function symbol */
  1844. X    xlpop();
  1845. X    return (sym);
  1846. X}
  1847. X
  1848. X/* xcond - special form 'cond' */
  1849. XLVAL xcond()
  1850. X{
  1851. X    LVAL list,val;
  1852. X
  1853. X    /* find a predicate that is true */
  1854. X    for (val = NIL; moreargs(); ) {
  1855. X
  1856. X    /* get the next conditional */
  1857. X    list = nextarg();
  1858. X
  1859. X    /* evaluate the predicate part */
  1860. X    if (consp(list) && (val = xleval(car(list)))) {
  1861. X
  1862. X        /* evaluate each expression */
  1863. X        for (list = cdr(list); consp(list); list = cdr(list))
  1864. X        val = xleval(car(list));
  1865. X
  1866. X        /* exit the loop */
  1867. X        break;
  1868. X    }
  1869. X    }
  1870. X
  1871. X    /* return the value */
  1872. X    return (val);
  1873. X}
  1874. X
  1875. X/* xwhen - special form 'when' */
  1876. XLVAL xwhen()
  1877. X{
  1878. X    LVAL val;
  1879. X
  1880. X    /* check the test expression */
  1881. X    if (val = xleval(xlgetarg()))
  1882. X    while (moreargs())
  1883. X        val = xleval(nextarg());
  1884. X
  1885. X    /* return the value */
  1886. X    return (val);
  1887. X}
  1888. X
  1889. X/* xunless - special form 'unless' */
  1890. XLVAL xunless()
  1891. X{
  1892. X    LVAL val=NIL;
  1893. X
  1894. X    /* check the test expression */
  1895. X    if (xleval(xlgetarg()) == NIL)
  1896. X    while (moreargs())
  1897. X        val = xleval(nextarg());
  1898. X
  1899. X    /* return the value */
  1900. X    return (val);
  1901. X}
  1902. X
  1903. X/* xcase - special form 'case' */
  1904. XLVAL xcase()
  1905. X{
  1906. X    LVAL key,list,cases,val;
  1907. X
  1908. X    /* protect some pointers */
  1909. X    xlsave1(key);
  1910. X
  1911. X    /* get the key expression */
  1912. X    key = xleval(nextarg());
  1913. X
  1914. X    /* find a case that matches */
  1915. X    for (val = NIL; moreargs(); ) {
  1916. X
  1917. X    /* get the next case clause */
  1918. X    list = nextarg();
  1919. X
  1920. X    /* make sure this is a valid clause */
  1921. X    if (consp(list)) {
  1922. X
  1923. X        /* compare the key list against the key */
  1924. X        if ((cases = car(list)) == true ||
  1925. X                (listp(cases) && keypresent(key,cases)) ||
  1926. X                eql(key,cases)) {
  1927. X
  1928. X        /* evaluate each expression */
  1929. X        for (list = cdr(list); consp(list); list = cdr(list))
  1930. X            val = xleval(car(list));
  1931. X
  1932. X        /* exit the loop */
  1933. X        break;
  1934. X        }
  1935. X    }
  1936. X    else
  1937. X        xlerror("bad case clause",list);
  1938. X    }
  1939. X
  1940. X    /* restore the stack */
  1941. X    xlpop();
  1942. X
  1943. X    /* return the value */
  1944. X    return (val);
  1945. X}
  1946. X
  1947. X/* keypresent - check for the presence of a key in a list */
  1948. XLOCAL int keypresent(key,list)
  1949. X  LVAL key,list;
  1950. X{
  1951. X    for (; consp(list); list = cdr(list))
  1952. X    if (eql(car(list),key))
  1953. X        return (TRUE);
  1954. X    return (FALSE);
  1955. X}
  1956. X
  1957. X/* xand - special form 'and' */
  1958. XLVAL xand()
  1959. X{
  1960. X    LVAL val;
  1961. X
  1962. X    /* evaluate each argument */
  1963. X    for (val = true; moreargs(); )
  1964. X    if ((val = xleval(nextarg())) == NIL)
  1965. X        break;
  1966. X
  1967. X    /* return the result value */
  1968. X    return (val);
  1969. X}
  1970. X
  1971. X/* xor - special form 'or' */
  1972. XLVAL xor()
  1973. X{
  1974. X    LVAL val;
  1975. X
  1976. X    /* evaluate each argument */
  1977. X    for (val = NIL; moreargs(); )
  1978. X    if ((val = xleval(nextarg())))
  1979. X        break;
  1980. X
  1981. X    /* return the result value */
  1982. X    return (val);
  1983. X}
  1984. X
  1985. X/* xif - special form 'if' */
  1986. XLVAL xif()
  1987. X{
  1988. X    LVAL testexpr,thenexpr,elseexpr;
  1989. X
  1990. X    /* get the test expression, then clause and else clause */
  1991. X    testexpr = xlgetarg();
  1992. X    thenexpr = xlgetarg();
  1993. X    elseexpr = (moreargs() ? xlgetarg() : NIL);
  1994. X    xllastarg();
  1995. X
  1996. X    /* evaluate the appropriate clause */
  1997. X    return (xleval(xleval(testexpr) ? thenexpr : elseexpr));
  1998. X}
  1999. X
  2000. X/* xlet - special form 'let' */
  2001. XLVAL xlet()
  2002. X{
  2003. X    return (let(TRUE));
  2004. X}
  2005. X
  2006. X/* xletstar - special form 'let*' */
  2007. XLVAL xletstar()
  2008. X{
  2009. X    return (let(FALSE));
  2010. X}
  2011. X
  2012. X/* let - common let routine */
  2013. XLOCAL LVAL let(pflag)
  2014. X  int pflag;
  2015. X{
  2016. X    LVAL newenv,val;
  2017. X
  2018. X    /* protect some pointers */
  2019. X    xlsave1(newenv);
  2020. X
  2021. X    /* create a new environment frame */
  2022. X    newenv = xlframe(xlenv);
  2023. X
  2024. X    /* get the list of bindings and bind the symbols */
  2025. X    if (!pflag) xlenv = newenv;
  2026. X    dobindings(xlgalist(),newenv);
  2027. X    if (pflag) xlenv = newenv;
  2028. X
  2029. X    /* execute the code */
  2030. X    for (val = NIL; moreargs(); )
  2031. X    val = xleval(nextarg());
  2032. X
  2033. X    /* unbind the arguments */
  2034. X    xlenv = cdr(xlenv);
  2035. X
  2036. X    /* restore the stack */
  2037. X    xlpop();
  2038. X
  2039. X    /* return the result */
  2040. X    return (val);
  2041. X}
  2042. X
  2043. X/* xflet - built-in function 'flet' */
  2044. XLVAL xflet()
  2045. X{
  2046. X    return (flet(s_lambda,TRUE));
  2047. X}
  2048. X
  2049. X/* xlabels - built-in function 'labels' */
  2050. XLVAL xlabels()
  2051. X{
  2052. X    return (flet(s_lambda,FALSE));
  2053. X}
  2054. X
  2055. X/* xmacrolet - built-in function 'macrolet' */
  2056. XLVAL xmacrolet()
  2057. X{
  2058. X    return (flet(s_macro,TRUE));
  2059. X}
  2060. X
  2061. X/* flet - common flet/labels/macrolet routine */
  2062. XLOCAL LVAL flet(type,letflag)
  2063. X  LVAL type; int letflag;
  2064. X{
  2065. X    LVAL list,bnd,sym,fargs,val;
  2066. X
  2067. X    /* create a new environment frame */
  2068. X    xlfenv = xlframe(xlfenv);
  2069. X
  2070. X    /* bind each symbol in the list of bindings */
  2071. X    for (list = xlgalist(); consp(list); list = cdr(list)) {
  2072. X
  2073. X    /* get the next binding */
  2074. X    bnd = car(list);
  2075. X
  2076. X    /* get the symbol and the function definition */
  2077. X    sym = match(SYMBOL,&bnd);
  2078. X    fargs = match(LIST,&bnd);
  2079. X    val = xlclose(sym,type,fargs,bnd,xlenv,(letflag?cdr(xlfenv):xlfenv));
  2080. X
  2081. X    /* bind the value to the symbol */
  2082. X    xlfbind(sym,val);
  2083. X    }
  2084. X
  2085. X    /* execute the code */
  2086. X    for (val = NIL; moreargs(); )
  2087. X    val = xleval(nextarg());
  2088. X
  2089. X    /* unbind the arguments */
  2090. X    xlfenv = cdr(xlfenv);
  2091. X
  2092. X    /* return the result */
  2093. X    return (val);
  2094. X}
  2095. X
  2096. X/* xprog - special form 'prog' */
  2097. XLVAL xprog()
  2098. X{
  2099. X    return (prog(TRUE));
  2100. X}
  2101. X
  2102. X/* xprogstar - special form 'prog*' */
  2103. XLVAL xprogstar()
  2104. X{
  2105. X    return (prog(FALSE));
  2106. X}
  2107. X
  2108. X/* prog - common prog routine */
  2109. XLOCAL LVAL prog(pflag)
  2110. X  int pflag;
  2111. X{
  2112. X    LVAL newenv,val;
  2113. X    CONTEXT cntxt;
  2114. X
  2115. X    /* protect some pointers */
  2116. X    xlsave1(newenv);
  2117. X
  2118. X    /* create a new environment frame */
  2119. X    newenv = xlframe(xlenv);
  2120. X
  2121. X    /* establish a new execution context */
  2122. X    xlbegin(&cntxt,CF_RETURN,NIL);
  2123. X    if (xlsetjmp(cntxt.c_jmpbuf))
  2124. X    val = xlvalue;
  2125. X    else {
  2126. X
  2127. X    /* get the list of bindings and bind the symbols */
  2128. X    if (!pflag) xlenv = newenv;
  2129. X    dobindings(xlgalist(),newenv);
  2130. X    if (pflag) xlenv = newenv;
  2131. X
  2132. X    /* execute the code */
  2133. X    tagbody();
  2134. X    val = NIL;
  2135. X
  2136. X    /* unbind the arguments */
  2137. X    xlenv = cdr(xlenv);
  2138. X    }
  2139. X    xlend(&cntxt);
  2140. X
  2141. X    /* restore the stack */
  2142. X    xlpop();
  2143. X
  2144. X    /* return the result */
  2145. X    return (val);
  2146. X}
  2147. X
  2148. X/* xgo - special form 'go' */
  2149. XLVAL xgo()
  2150. X{
  2151. X    LVAL label;
  2152. X
  2153. X    /* get the target label */
  2154. X    label = xlgetarg();
  2155. X    xllastarg();
  2156. X
  2157. X    /* transfer to the label */
  2158. X    xlgo(label);
  2159. X}
  2160. X
  2161. X/* xreturn - special form 'return' */
  2162. XLVAL xreturn()
  2163. X{
  2164. X    LVAL val;
  2165. X
  2166. X    /* get the return value */
  2167. X    val = (moreargs() ? xleval(nextarg()) : NIL);
  2168. X    xllastarg();
  2169. X
  2170. X    /* return from the inner most block */
  2171. X    xlreturn(NIL,val);
  2172. X}
  2173. X
  2174. X/* xrtnfrom - special form 'return-from' */
  2175. XLVAL xrtnfrom()
  2176. X{
  2177. X    LVAL name,val;
  2178. X
  2179. X    /* get the return value */
  2180. X    name = xlgasymbol();
  2181. X    val = (moreargs() ? xleval(nextarg()) : NIL);
  2182. X    xllastarg();
  2183. X
  2184. X    /* return from the inner most block */
  2185. X    xlreturn(name,val);
  2186. X}
  2187. X
  2188. X/* xprog1 - special form 'prog1' */
  2189. XLVAL xprog1()
  2190. X{
  2191. X    return (progx(1));
  2192. X}
  2193. X
  2194. X/* xprog2 - special form 'prog2' */
  2195. XLVAL xprog2()
  2196. X{
  2197. X    return (progx(2));
  2198. X}
  2199. X
  2200. X/* progx - common progx code */
  2201. XLOCAL LVAL progx(n)
  2202. X  int n;
  2203. X{
  2204. X    LVAL val;
  2205. X
  2206. X    /* protect some pointers */
  2207. X    xlsave1(val);
  2208. X
  2209. X    /* evaluate the first n expressions */
  2210. X    while (moreargs() && --n >= 0)
  2211. X    val = xleval(nextarg());
  2212. X
  2213. X    /* evaluate each remaining argument */
  2214. X    while (moreargs())
  2215. X    xleval(nextarg());
  2216. X
  2217. X    /* restore the stack */
  2218. X    xlpop();
  2219. X
  2220. X    /* return the last test expression value */
  2221. X    return (val);
  2222. X}
  2223. X
  2224. X/* xprogn - special form 'progn' */
  2225. XLVAL xprogn()
  2226. X{
  2227. X    LVAL val;
  2228. X
  2229. X    /* evaluate each expression */
  2230. X    for (val = NIL; moreargs(); )
  2231. X    val = xleval(nextarg());
  2232. X
  2233. X    /* return the last test expression value */
  2234. X    return (val);
  2235. X}
  2236. X
  2237. X/* xprogv - special form 'progv' */
  2238. XLVAL xprogv()
  2239. X{
  2240. X    LVAL olddenv,vars,vals,val;
  2241. X
  2242. X    /* protect some pointers */
  2243. X    xlstkcheck(2);
  2244. X    xlsave(vars);
  2245. X    xlsave(vals);
  2246. X
  2247. X    /* get the list of variables and the list of values */
  2248. X    vars = xlgalist(); vars = xleval(vars);
  2249. X    vals = xlgalist(); vals = xleval(vals);
  2250. X
  2251. X    /* bind the values to the variables */
  2252. X    for (olddenv = xldenv; consp(vars); vars = cdr(vars)) {
  2253. X    if (!symbolp(car(vars)))
  2254. X        xlerror("expecting a symbol",car(vars));
  2255. X    if (consp(vals)) {
  2256. X        xldbind(car(vars),car(vals));
  2257. X        vals = cdr(vals);
  2258. X    }
  2259. X    else
  2260. X        xldbind(car(vars),s_unbound);
  2261. X    }
  2262. X
  2263. X    /* evaluate each expression */
  2264. X    for (val = NIL; moreargs(); )
  2265. X    val = xleval(nextarg());
  2266. X
  2267. X    /* restore the previous environment and the stack */
  2268. X    xlunbind(olddenv);
  2269. X    xlpopn(2);
  2270. X
  2271. X    /* return the last test expression value */
  2272. X    return (val);
  2273. X}
  2274. X
  2275. X/* xloop - special form 'loop' */
  2276. XLVAL xloop()
  2277. X{
  2278. X    LVAL *argv,arg,val;
  2279. X    CONTEXT cntxt;
  2280. X    int argc;
  2281. X
  2282. X    /* protect some pointers */
  2283. X    xlsave1(arg);
  2284. X
  2285. X    /* establish a new execution context */
  2286. X    xlbegin(&cntxt,CF_RETURN,NIL);
  2287. X    if (xlsetjmp(cntxt.c_jmpbuf))
  2288. X    val = xlvalue;
  2289. X    else
  2290. X    for (argv = xlargv, argc = xlargc; ; xlargv = argv, xlargc = argc)
  2291. X        while (moreargs()) {
  2292. X        arg = nextarg();
  2293. X        if (consp(arg))
  2294. X            xleval(arg);
  2295. X        }
  2296. X    xlend(&cntxt);
  2297. X
  2298. X    /* restore the stack */
  2299. X    xlpop();
  2300. X
  2301. X    /* return the result */
  2302. X    return (val);
  2303. X}
  2304. X
  2305. X/* xdo - special form 'do' */
  2306. XLVAL xdo()
  2307. X{
  2308. X    return (doloop(TRUE));
  2309. X}
  2310. X
  2311. X/* xdostar - special form 'do*' */
  2312. XLVAL xdostar()
  2313. X{
  2314. X    return (doloop(FALSE));
  2315. X}
  2316. X
  2317. X/* doloop - common do routine */
  2318. XLOCAL LVAL doloop(pflag)
  2319. X  int pflag;
  2320. X{
  2321. X    LVAL newenv,*argv,blist,clist,test,val;
  2322. X    CONTEXT cntxt;
  2323. X    int argc;
  2324. X
  2325. X    /* protect some pointers */
  2326. X    xlsave1(newenv);
  2327. X
  2328. X    /* get the list of bindings, the exit test and the result forms */
  2329. X    blist = xlgalist();
  2330. X    clist = xlgalist();
  2331. X    test = (consp(clist) ? car(clist) : NIL);
  2332. X    argv = xlargv;
  2333. X    argc = xlargc;
  2334. X
  2335. X    /* create a new environment frame */
  2336. X    newenv = xlframe(xlenv);
  2337. X
  2338. X    /* establish a new execution context */
  2339. X    xlbegin(&cntxt,CF_RETURN,NIL);
  2340. X    if (xlsetjmp(cntxt.c_jmpbuf))
  2341. X    val = xlvalue;
  2342. X    else {
  2343. X
  2344. X    /* bind the symbols */
  2345. X    if (!pflag) xlenv = newenv;
  2346. X    dobindings(blist,newenv);
  2347. X    if (pflag) xlenv = newenv;
  2348. X
  2349. X    /* execute the loop as long as the test is false */
  2350. X    for (val = NIL; xleval(test) == NIL; doupdates(blist,pflag)) {
  2351. X        xlargv = argv;
  2352. X        xlargc = argc;
  2353. X        tagbody();
  2354. X    }
  2355. X
  2356. X    /* evaluate the result expression */
  2357. X    if (consp(clist))
  2358. X        for (clist = cdr(clist); consp(clist); clist = cdr(clist))
  2359. X        val = xleval(car(clist));
  2360. X
  2361. X    /* unbind the arguments */
  2362. X    xlenv = cdr(xlenv);
  2363. X    }
  2364. X    xlend(&cntxt);
  2365. X
  2366. X    /* restore the stack */
  2367. X    xlpop();
  2368. X
  2369. X    /* return the result */
  2370. X    return (val);
  2371. X}
  2372. X
  2373. X/* xdolist - special form 'dolist' */
  2374. XLVAL xdolist()
  2375. X{
  2376. X    LVAL list,*argv,clist,sym,val;
  2377. X    CONTEXT cntxt;
  2378. X    int argc;
  2379. X
  2380. X    /* protect some pointers */
  2381. X    xlsave1(list);
  2382. X
  2383. X    /* get the control list (sym list result-expr) */
  2384. X    clist = xlgalist();
  2385. X    sym = match(SYMBOL,&clist);
  2386. X    list = evmatch(LIST,&clist);
  2387. X    argv = xlargv;
  2388. X    argc = xlargc;
  2389. X
  2390. X    /* initialize the local environment */
  2391. X    xlenv = xlframe(xlenv);
  2392. X    xlbind(sym,NIL);
  2393. X
  2394. X    /* establish a new execution context */
  2395. X    xlbegin(&cntxt,CF_RETURN,NIL);
  2396. X    if (xlsetjmp(cntxt.c_jmpbuf))
  2397. X    val = xlvalue;
  2398. X    else {
  2399. X
  2400. X    /* loop through the list */
  2401. X    for (val = NIL; consp(list); list = cdr(list)) {
  2402. X
  2403. X        /* bind the symbol to the next list element */
  2404. X        xlsetvalue(sym,car(list));
  2405. X
  2406. X        /* execute the loop body */
  2407. X        xlargv = argv;
  2408. X        xlargc = argc;
  2409. X        tagbody();
  2410. X    }
  2411. X
  2412. X    /* evaluate the result expression */
  2413. X    xlsetvalue(sym,NIL);
  2414. X    val = (consp(clist) ? xleval(car(clist)) : NIL);
  2415. X
  2416. X    /* unbind the arguments */
  2417. X    xlenv = cdr(xlenv);
  2418. X    }
  2419. X    xlend(&cntxt);
  2420. X
  2421. X    /* restore the stack */
  2422. X    xlpop();
  2423. X
  2424. X    /* return the result */
  2425. X    return (val);
  2426. X}
  2427. X
  2428. X/* xdotimes - special form 'dotimes' */
  2429. XLVAL xdotimes()
  2430. X{
  2431. X    LVAL *argv,clist,sym,cnt,val;
  2432. X    CONTEXT cntxt;
  2433. X    int argc,n,i;
  2434. X
  2435. X    /* get the control list (sym list result-expr) */
  2436. X    clist = xlgalist();
  2437. X    sym = match(SYMBOL,&clist);
  2438. X    cnt = evmatch(FIXNUM,&clist); n = getfixnum(cnt);
  2439. X    argv = xlargv;
  2440. X    argc = xlargc;
  2441. X
  2442. X    /* initialize the local environment */
  2443. X    xlenv = xlframe(xlenv);
  2444. X    xlbind(sym,NIL);
  2445. X
  2446. X    /* establish a new execution context */
  2447. X    xlbegin(&cntxt,CF_RETURN,NIL);
  2448. X    if (xlsetjmp(cntxt.c_jmpbuf))
  2449. X    val = xlvalue;
  2450. X    else {
  2451. X
  2452. X    /* loop through for each value from zero to n-1 */
  2453. X    for (val = NIL, i = 0; i < n; ++i) {
  2454. X
  2455. X        /* bind the symbol to the next list element */
  2456. X        xlsetvalue(sym,cvfixnum((FIXTYPE)i));
  2457. X
  2458. X        /* execute the loop body */
  2459. X        xlargv = argv;
  2460. X        xlargc = argc;
  2461. X        tagbody();
  2462. X    }
  2463. X
  2464. X    /* evaluate the result expression */
  2465. X    xlsetvalue(sym,cnt);
  2466. X    val = (consp(clist) ? xleval(car(clist)) : NIL);
  2467. X
  2468. X    /* unbind the arguments */
  2469. X    xlenv = cdr(xlenv);
  2470. X    }
  2471. X    xlend(&cntxt);
  2472. X
  2473. X    /* return the result */
  2474. X    return (val);
  2475. X}
  2476. X
  2477. X/* xblock - special form 'block' */
  2478. XLVAL xblock()
  2479. X{
  2480. X    LVAL name,val;
  2481. X    CONTEXT cntxt;
  2482. X
  2483. X    /* get the block name */
  2484. X    name = xlgetarg();
  2485. X    if (name && !symbolp(name))
  2486. X    xlbadtype(name);
  2487. X
  2488. X    /* execute the block */
  2489. X    xlbegin(&cntxt,CF_RETURN,name);
  2490. X    if (xlsetjmp(cntxt.c_jmpbuf))
  2491. X    val = xlvalue;
  2492. X    else
  2493. X    for (val = NIL; moreargs(); )
  2494. X        val = xleval(nextarg());
  2495. X    xlend(&cntxt);
  2496. X
  2497. X    /* return the value of the last expression */
  2498. X    return (val);
  2499. X}
  2500. X
  2501. X/* xtagbody - special form 'tagbody' */
  2502. XLVAL xtagbody()
  2503. X{
  2504. X    tagbody();
  2505. X    return (NIL);
  2506. X}
  2507. X
  2508. X/* xcatch - special form 'catch' */
  2509. XLVAL xcatch()
  2510. X{
  2511. X    CONTEXT cntxt;
  2512. X    LVAL tag,val;
  2513. X
  2514. X    /* protect some pointers */
  2515. X    xlsave1(tag);
  2516. X
  2517. X    /* get the tag */
  2518. X    tag = xleval(nextarg());
  2519. X
  2520. X    /* establish an execution context */
  2521. X    xlbegin(&cntxt,CF_THROW,tag);
  2522. X
  2523. X    /* check for 'throw' */
  2524. X    if (xlsetjmp(cntxt.c_jmpbuf))
  2525. X    val = xlvalue;
  2526. X
  2527. X    /* otherwise, evaluate the remainder of the arguments */
  2528. X    else {
  2529. X    for (val = NIL; moreargs(); )
  2530. X        val = xleval(nextarg());
  2531. X    }
  2532. X    xlend(&cntxt);
  2533. X
  2534. X    /* restore the stack */
  2535. X    xlpop();
  2536. X
  2537. X    /* return the result */
  2538. X    return (val);
  2539. X}
  2540. X
  2541. X/* xthrow - special form 'throw' */
  2542. XLVAL xthrow()
  2543. X{
  2544. X    LVAL tag,val;
  2545. X
  2546. X    /* get the tag and value */
  2547. X    tag = xleval(nextarg());
  2548. X    val = (moreargs() ? xleval(nextarg()) : NIL);
  2549. X    xllastarg();
  2550. X
  2551. X    /* throw the tag */
  2552. X    xlthrow(tag,val);
  2553. X}
  2554. X
  2555. X/* xunwindprotect - special form 'unwind-protect' */
  2556. XLVAL xunwindprotect()
  2557. X{
  2558. X    extern CONTEXT *xltarget;
  2559. X    extern int xlmask;
  2560. X    CONTEXT cntxt,*target;
  2561. X    int mask,sts;
  2562. X    LVAL val;
  2563. X
  2564. X    /* protect some pointers */
  2565. X    xlsave1(val);
  2566. X
  2567. X    /* get the expression to protect */
  2568. X    val = xlgetarg();
  2569. X
  2570. X    /* evaluate the protected expression */
  2571. X    xlbegin(&cntxt,CF_UNWIND,NIL);
  2572. X    if (sts = xlsetjmp(cntxt.c_jmpbuf)) {
  2573. X    target = xltarget;
  2574. X    mask = xlmask;
  2575. X    val = xlvalue;
  2576. X    }
  2577. X    else
  2578. X    val = xleval(val);
  2579. X    xlend(&cntxt);
  2580. X    
  2581. X    /* evaluate the cleanup expressions */
  2582. X    while (moreargs())
  2583. X    xleval(nextarg());
  2584. X
  2585. X    /* if unwinding, continue unwinding */
  2586. X    if (sts)
  2587. X    xljump(target,mask,val);
  2588. X
  2589. X    /* restore the stack */
  2590. X    xlpop();
  2591. X
  2592. X    /* return the value of the protected expression */
  2593. X    return (val);
  2594. X}
  2595. X
  2596. X/* xerrset - special form 'errset' */
  2597. XLVAL xerrset()
  2598. X{
  2599. X    LVAL expr,flag,val;
  2600. X    CONTEXT cntxt;
  2601. X
  2602. X    /* get the expression and the print flag */
  2603. X    expr = xlgetarg();
  2604. X    flag = (moreargs() ? xlgetarg() : true);
  2605. X    xllastarg();
  2606. X
  2607. X    /* establish an execution context */
  2608. X    xlbegin(&cntxt,CF_ERROR,flag);
  2609. X
  2610. X    /* check for error */
  2611. X    if (xlsetjmp(cntxt.c_jmpbuf))
  2612. X    val = NIL;
  2613. X
  2614. X    /* otherwise, evaluate the expression */
  2615. X    else {
  2616. X    expr = xleval(expr);
  2617. X    val = consa(expr);
  2618. X    }
  2619. X    xlend(&cntxt);
  2620. X
  2621. X    /* return the result */
  2622. X    return (val);
  2623. X}
  2624. X
  2625. X/* xtrace - special form 'trace' */
  2626. XLVAL xtrace()
  2627. X{
  2628. X    LVAL sym,fun,this;
  2629. X
  2630. X    /* loop through all of the arguments */
  2631. X    sym = xlenter("*TRACELIST*");
  2632. X    while (moreargs()) {
  2633. X    fun = xlgasymbol();
  2634. X
  2635. X    /* check for the function name already being in the list */
  2636. X    for (this = getvalue(sym); consp(this); this = cdr(this))
  2637. X        if (car(this) == fun)
  2638. X        break;
  2639. X
  2640. X    /* add the function name to the list */
  2641. X    if (null(this))
  2642. X        setvalue(sym,cons(fun,getvalue(sym)));
  2643. X    }
  2644. X    return (getvalue(sym));
  2645. X}
  2646. X
  2647. X/* xuntrace - special form 'untrace' */
  2648. XLVAL xuntrace()
  2649. X{
  2650. X    LVAL sym,fun,this,last;
  2651. X
  2652. X    /* loop through all of the arguments */
  2653. X    sym = xlenter("*TRACELIST*");
  2654. X    while (moreargs()) {
  2655. X    fun = xlgasymbol();
  2656. X
  2657. X    /* remove the function name from the list */
  2658. X    last = NIL;
  2659. X    for (this = getvalue(sym); consp(this); this = cdr(this)) {
  2660. X        if (car(this) == fun) {
  2661. X        if (last)
  2662. X            rplacd(last,cdr(this));
  2663. X        else
  2664. X            setvalue(sym,cdr(this));
  2665. X        break;
  2666. X        }
  2667. X        last = this;
  2668. X    }
  2669. X    }
  2670. X    return (getvalue(sym));
  2671. X}
  2672. X
  2673. X/* dobindings - handle bindings for let/let*, prog/prog*, do/do* */
  2674. XLOCAL dobindings(list,env)
  2675. X  LVAL list,env;
  2676. X{
  2677. X    LVAL bnd,sym,val;
  2678. X
  2679. X    /* protect some pointers */
  2680. X    xlsave1(val);
  2681. X
  2682. X    /* bind each symbol in the list of bindings */
  2683. X    for (; consp(list); list = cdr(list)) {
  2684. X
  2685. X    /* get the next binding */
  2686. X    bnd = car(list);
  2687. X
  2688. X    /* handle a symbol */
  2689. X    if (symbolp(bnd)) {
  2690. X        sym = bnd;
  2691. X        val = NIL;
  2692. X    }
  2693. X
  2694. X    /* handle a list of the form (symbol expr) */
  2695. X    else if (consp(bnd)) {
  2696. X        sym = match(SYMBOL,&bnd);
  2697. X        val = evarg(&bnd);
  2698. X    }
  2699. X    else
  2700. X        xlfail("bad binding");
  2701. X
  2702. X    /* bind the value to the symbol */
  2703. X    xlpbind(sym,val,env);
  2704. X    }
  2705. X
  2706. X    /* restore the stack */
  2707. X    xlpop();
  2708. X}
  2709. X
  2710. X/* doupdates - handle updates for do/do* */
  2711. XLOCAL doupdates(list,pflag)
  2712. X  LVAL list; int pflag;
  2713. X{
  2714. X    LVAL plist,bnd,sym,val;
  2715. X
  2716. X    /* protect some pointers */
  2717. X    xlstkcheck(2);
  2718. X    xlsave(plist);
  2719. X    xlsave(val);
  2720. X
  2721. X    /* bind each symbol in the list of bindings */
  2722. X    for (; consp(list); list = cdr(list)) {
  2723. X
  2724. X    /* get the next binding */
  2725. X    bnd = car(list);
  2726. X
  2727. X    /* handle a list of the form (symbol expr) */
  2728. X    if (consp(bnd)) {
  2729. X        sym = match(SYMBOL,&bnd);
  2730. X        bnd = cdr(bnd);
  2731. X        if (bnd) {
  2732. X        val = evarg(&bnd);
  2733. X        if (pflag)
  2734. X            plist = cons(cons(sym,val),plist);
  2735. X        else
  2736. X            xlsetvalue(sym,val);
  2737. X        }
  2738. X    }
  2739. X    }
  2740. X
  2741. X    /* set the values for parallel updates */
  2742. X    for (; plist; plist = cdr(plist))
  2743. X    xlsetvalue(car(car(plist)),cdr(car(plist)));
  2744. X
  2745. X    /* restore the stack */
  2746. X    xlpopn(2);
  2747. X}
  2748. X
  2749. X/* tagbody - execute code within a block and tagbody */
  2750. XLOCAL tagbody()
  2751. X{
  2752. X    LVAL *argv,arg;
  2753. X    CONTEXT cntxt;
  2754. X    int argc;
  2755. X
  2756. X    /* establish an execution context */
  2757. X    xlbegin(&cntxt,CF_GO,NIL);
  2758. X    argc = xlargc;
  2759. X    argv = xlargv;
  2760. X
  2761. X    /* check for a 'go' */
  2762. X    if (xlsetjmp(cntxt.c_jmpbuf)) {
  2763. X    cntxt.c_xlargc = argc;
  2764. X    cntxt.c_xlargv = argv;
  2765. X    }
  2766. X
  2767. X    /* execute the body */
  2768. X    while (moreargs()) {
  2769. X    arg = nextarg();
  2770. X    if (consp(arg))
  2771. X        xleval(arg);
  2772. X    }
  2773. X    xlend(&cntxt);
  2774. X}
  2775. X
  2776. X/* match - get an argument and match its type */
  2777. XLOCAL LVAL match(type,pargs)
  2778. X  int type; LVAL *pargs;
  2779. X{
  2780. X    LVAL arg;
  2781. X
  2782. X    /* make sure the argument exists */
  2783. X    if (!consp(*pargs))
  2784. X    toofew(*pargs);
  2785. X
  2786. X    /* get the argument value */
  2787. X    arg = car(*pargs);
  2788. X
  2789. X    /* move the argument pointer ahead */
  2790. X    *pargs = cdr(*pargs);
  2791. X
  2792. X    /* check its type */
  2793. X    if (type == LIST) {
  2794. X    if (arg && ntype(arg) != CONS)
  2795. X        xlerror("bad argument type",arg);
  2796. X    }
  2797. X    else {
  2798. X    if (arg == NIL || ntype(arg) != type)
  2799. X        xlerror("bad argument type",arg);
  2800. X    }
  2801. X
  2802. X    /* return the argument */
  2803. X    return (arg);
  2804. X}
  2805. X
  2806. X/* evarg - get the next argument and evaluate it */
  2807. XLOCAL LVAL evarg(pargs)
  2808. X  LVAL *pargs;
  2809. X{
  2810. X    LVAL arg;
  2811. X
  2812. X    /* protect some pointers */
  2813. X    xlsave1(arg);
  2814. X
  2815. X    /* make sure the argument exists */
  2816. X    if (!consp(*pargs))
  2817. X    toofew(*pargs);
  2818. X
  2819. X    /* get the argument value */
  2820. X    arg = car(*pargs);
  2821. X
  2822. X    /* move the argument pointer ahead */
  2823. X    *pargs = cdr(*pargs);
  2824. X
  2825. X    /* evaluate the argument */
  2826. X    arg = xleval(arg);
  2827. X
  2828. X    /* restore the stack */
  2829. X    xlpop();
  2830. X
  2831. X    /* return the argument */
  2832. X    return (arg);
  2833. X}
  2834. X
  2835. X/* evmatch - get an evaluated argument and match its type */
  2836. XLOCAL LVAL evmatch(type,pargs)
  2837. X  int type; LVAL *pargs;
  2838. X{
  2839. X    LVAL arg;
  2840. X
  2841. X    /* protect some pointers */
  2842. X    xlsave1(arg);
  2843. X
  2844. X    /* make sure the argument exists */
  2845. X    if (!consp(*pargs))
  2846. X    toofew(*pargs);
  2847. X
  2848. X    /* get the argument value */
  2849. X    arg = car(*pargs);
  2850. X
  2851. X    /* move the argument pointer ahead */
  2852. X    *pargs = cdr(*pargs);
  2853. X
  2854. X    /* evaluate the argument */
  2855. X    arg = xleval(arg);
  2856. X
  2857. X    /* check its type */
  2858. X    if (type == LIST) {
  2859. X    if (arg && ntype(arg) != CONS)
  2860. X        xlerror("bad argument type",arg);
  2861. X    }
  2862. X    else {
  2863. X    if (arg == NIL || ntype(arg) != type)
  2864. X        xlerror("bad argument type",arg);
  2865. X    }
  2866. X
  2867. X    /* restore the stack */
  2868. X    xlpop();
  2869. X
  2870. X    /* return the argument */
  2871. X    return (arg);
  2872. X}
  2873. X
  2874. X/* toofew - too few arguments */
  2875. XLOCAL toofew(args)
  2876. X  LVAL args;
  2877. X{
  2878. X    xlerror("too few arguments",args);
  2879. X}
  2880. X
  2881. X/* toomany - too many arguments */
  2882. XLOCAL toomany(args)
  2883. X  LVAL args;
  2884. X{
  2885. X    xlerror("too many arguments",args);
  2886. X}
  2887. X
  2888. END_OF_FILE
  2889. if test 30247 -ne `wc -c <'src/xlisp/xcore/c/xlcont.c'`; then
  2890.     echo shar: \"'src/xlisp/xcore/c/xlcont.c'\" unpacked with wrong size!
  2891. fi
  2892. # end of 'src/xlisp/xcore/c/xlcont.c'
  2893. fi
  2894. echo shar: End of archive 12 \(of 16\).
  2895. cp /dev/null ark12isdone
  2896. MISSING=""
  2897. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 ; do
  2898.     if test ! -f ark${I}isdone ; then
  2899.     MISSING="${MISSING} ${I}"
  2900.     fi
  2901. done
  2902. if test "${MISSING}" = "" ; then
  2903.     echo You have unpacked all 16 archives.
  2904.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  2905. else
  2906.     echo You still need to unpack the following archives:
  2907.     echo "        " ${MISSING}
  2908. fi
  2909. ##  End of shell archive.
  2910. exit 0
  2911.