home *** CD-ROM | disk | FTP | other *** search
/ NeXT Education Software Sampler 1992 Fall / NeXT Education Software Sampler 1992 Fall.iso / Programming / Source / winterp-1.13 / src-server / xlisp / xljump.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-10-04  |  5.7 KB  |  209 lines

  1. /* -*-C-*-
  2. ********************************************************************************
  3. *
  4. * File:         xljump.c
  5. * RCS:          $Header: xljump.c,v 1.4 91/03/24 22:25:06 mayer Exp $
  6. * Description:  execution context routines
  7. * Author:       David Michael Betz
  8. * Created:      
  9. * Modified:     Fri Oct  4 04:05:25 1991 (Niels Mayer) mayer@hplnpm
  10. * Language:     C
  11. * Package:      N/A
  12. * Status:       X11r5 contrib tape release
  13. *
  14. * WINTERP Copyright 1989, 1990, 1991 Hewlett-Packard Company (by Niels Mayer).
  15. * XLISP version 2.1, Copyright (c) 1989, by David Betz.
  16. *
  17. * Permission to use, copy, modify, distribute, and sell this software and its
  18. * documentation for any purpose is hereby granted without fee, provided that
  19. * the above copyright notice appear in all copies and that both that
  20. * copyright notice and this permission notice appear in supporting
  21. * documentation, and that the name of Hewlett-Packard and David Betz not be
  22. * used in advertising or publicity pertaining to distribution of the software
  23. * without specific, written prior permission.  Hewlett-Packard and David Betz
  24. * make no representations about the suitability of this software for any
  25. * purpose. It is provided "as is" without express or implied warranty.
  26. *
  27. * HEWLETT-PACKARD AND DAVID BETZ DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
  28. * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
  29. * IN NO EVENT SHALL HEWLETT-PACKARD NOR DAVID BETZ BE LIABLE FOR ANY SPECIAL,
  30. * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  31. * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
  32. * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  33. * PERFORMANCE OF THIS SOFTWARE.
  34. *
  35. * See ./winterp/COPYRIGHT for information on contacting the authors.
  36. * Please send modifications, improvements and bugfixes to mayer@hplabs.hp.com
  37. * Post XLISP-specific questions/information to the newsgroup comp.lang.lisp.x
  38. *
  39. ********************************************************************************
  40. */
  41. static char rcs_identity[] = "@(#)$Header: xljump.c,v 1.4 91/03/24 22:25:06 mayer Exp $";
  42.  
  43.  
  44. #include "xlisp.h"
  45.  
  46. /* external variables */
  47. extern CONTEXT *xlcontext,*xltarget;
  48. extern LVAL xlvalue,xlenv,xlfenv,xldenv;
  49. extern int xlmask;
  50.  
  51. /* xlbegin - beginning of an execution context */
  52. xlbegin(cptr,flags,expr)
  53.   CONTEXT *cptr; int flags; LVAL expr;
  54. {
  55.     cptr->c_flags = flags;
  56.     cptr->c_expr = expr;
  57.     cptr->c_xlstack = xlstack;
  58.     cptr->c_xlenv = xlenv;
  59.     cptr->c_xlfenv = xlfenv;
  60.     cptr->c_xldenv = xldenv;
  61.     cptr->c_xlcontext = xlcontext;
  62.     cptr->c_xlargv = xlargv;
  63.     cptr->c_xlargc = xlargc;
  64.     cptr->c_xlfp = xlfp;
  65.     cptr->c_xlsp = xlsp;
  66.     xlcontext = cptr;
  67. }
  68.  
  69. /* xlend - end of an execution context */
  70. xlend(cptr)
  71.   CONTEXT *cptr;
  72. {
  73.     xlcontext = cptr->c_xlcontext;
  74. }
  75.  
  76. /* xlgo - go to a label */
  77. xlgo(label)
  78.   LVAL label;
  79. {
  80.     CONTEXT *cptr;
  81.     LVAL *argv;
  82.     int argc;
  83.  
  84.     /* find a tagbody context */
  85.     for (cptr = xlcontext; cptr; cptr = cptr->c_xlcontext)
  86.     if (cptr->c_flags & CF_GO) {
  87.         argc = cptr->c_xlargc;
  88.         argv = cptr->c_xlargv;
  89.         while (--argc >= 0)
  90.         if (*argv++ == label) {
  91.             cptr->c_xlargc = argc;
  92.             cptr->c_xlargv = argv;
  93.             xljump(cptr,CF_GO,NIL);
  94.         }
  95.     }
  96.     xlfail("no target for GO");
  97. }
  98.  
  99. /* xlreturn - return from a block */
  100. xlreturn(name,val)
  101.   LVAL name,val;
  102. {
  103.     CONTEXT *cptr;
  104.  
  105.     /* find a block context */
  106.     for (cptr = xlcontext; cptr; cptr = cptr->c_xlcontext)
  107.     if (cptr->c_flags & CF_RETURN && cptr->c_expr == name)
  108.         xljump(cptr,CF_RETURN,val);
  109.     xlfail("no target for RETURN");
  110. }
  111.  
  112. /* xlthrow - throw to a catch */
  113. xlthrow(tag,val)
  114.   LVAL tag,val;
  115. {
  116.     CONTEXT *cptr;
  117.  
  118.     /* find a catch context */
  119.     for (cptr = xlcontext; cptr; cptr = cptr->c_xlcontext)
  120.     if ((cptr->c_flags & CF_THROW) && cptr->c_expr == tag)
  121.         xljump(cptr,CF_THROW,val);
  122.     xlfail("no target for THROW");
  123. }
  124.  
  125. /* xlsignal - signal an error */
  126. xlsignal(emsg,arg)
  127.   char *emsg; LVAL arg;
  128. {
  129.     CONTEXT *cptr;
  130.  
  131.     /* find an error catcher */
  132.     for (cptr = xlcontext; cptr; cptr = cptr->c_xlcontext)
  133.     if (cptr->c_flags & CF_ERROR) {
  134.         if (cptr->c_expr && emsg)
  135.         xlerrprint("error",NULL,emsg,arg);
  136.         xljump(cptr,CF_ERROR,NIL);
  137.     }
  138. }
  139.  
  140. /* xltoplevel - go back to the top level */
  141. xltoplevel()
  142. {
  143.     stdputstr("[ back to top level ]\n");
  144.     findandjump(CF_TOPLEVEL,"no top level");
  145. }
  146.  
  147. /* xlbrklevel - go back to the previous break level */
  148. xlbrklevel()
  149. {
  150.     findandjump(CF_BRKLEVEL,"no previous break level");
  151. }
  152.  
  153. /* xlcleanup - clean-up after an error */
  154. xlcleanup()
  155. {
  156.     stdputstr("[ back to previous break level ]\n");
  157.     findandjump(CF_CLEANUP,"not in a break loop");
  158. }
  159.  
  160. /* xlcontinue - continue from an error */
  161. xlcontinue()
  162. {
  163.     findandjump(CF_CONTINUE,"not in a break loop");
  164. }
  165.  
  166. /* xljump - jump to a saved execution context */
  167. xljump(target,mask,val)
  168.   CONTEXT *target; int mask; LVAL val;
  169. {
  170.     /* unwind the execution stack */
  171.     for (; xlcontext != target; xlcontext = xlcontext->c_xlcontext)
  172.  
  173.     /* check for an UNWIND-PROTECT */
  174.     if ((xlcontext->c_flags & CF_UNWIND)) {
  175.         xltarget = target;
  176.         xlmask = mask;
  177.         break;
  178.     }
  179.        
  180.     /* restore the state */
  181.     xlstack = xlcontext->c_xlstack;
  182.     xlenv = xlcontext->c_xlenv;
  183.     xlfenv = xlcontext->c_xlfenv;
  184.     xlunbind(xlcontext->c_xldenv);
  185.     xlargv = xlcontext->c_xlargv;
  186.     xlargc = xlcontext->c_xlargc;
  187.     xlfp = xlcontext->c_xlfp;
  188.     xlsp = xlcontext->c_xlsp;
  189.     xlvalue = val;
  190.  
  191.     /* call the handler */
  192.     longjmp(xlcontext->c_jmpbuf,mask);
  193. }
  194.  
  195. /* findandjump - find a target context frame and jump to it */
  196. LOCAL findandjump(mask,error)
  197.   int mask; char *error;
  198. {
  199.     CONTEXT *cptr;
  200.  
  201.     /* find a block context */
  202.     for (cptr = xlcontext; cptr; cptr = cptr->c_xlcontext)
  203.     if (cptr->c_flags & mask)
  204.         xljump(cptr,mask,NIL);
  205.     xlabort(error);
  206. }
  207.  
  208.