📄 xljump.c
字号:
/* xljump - execution context routines *//* Copyright (c) 1985, by David Michael Betz All Rights Reserved Permission is granted for unrestricted non-commercial use */#include "xlisp.h"/* external variables */extern XLCONTEXT *xlcontext,*xltarget;extern LVAL xlvalue,xlenv,xlfenv,xldenv;extern int xlmask;LOCAL void findandjump(int mask, char *error);/* xlbegin - beginning of an execution context */void xlbegin(XLCONTEXT *cptr, int flags, LVAL expr){ cptr->c_flags = flags; cptr->c_expr = expr; cptr->c_xlstack = xlstack; cptr->c_xlenv = xlenv; cptr->c_xlfenv = xlfenv; cptr->c_xldenv = xldenv; cptr->c_xlcontext = xlcontext; cptr->c_xlargv = xlargv; cptr->c_xlargc = xlargc; cptr->c_xlfp = xlfp; cptr->c_xlsp = xlsp; xlcontext = cptr;}/* xlend - end of an execution context */void xlend(XLCONTEXT *cptr){ xlcontext = cptr->c_xlcontext;}/* xlgo - go to a label */void xlgo(LVAL label){ XLCONTEXT *cptr; LVAL *argv; int argc; /* find a tagbody context */ for (cptr = xlcontext; cptr; cptr = cptr->c_xlcontext) if (cptr->c_flags & CF_GO) { argc = cptr->c_xlargc; argv = cptr->c_xlargv; while (--argc >= 0) if (*argv++ == label) { cptr->c_xlargc = argc; cptr->c_xlargv = argv; xljump(cptr,CF_GO,NIL); } } xlfail("no target for GO");}/* xlreturn - return from a block */void xlreturn(LVAL name, LVAL val){ XLCONTEXT *cptr; /* find a block context */ for (cptr = xlcontext; cptr; cptr = cptr->c_xlcontext) if (cptr->c_flags & CF_RETURN && cptr->c_expr == name) xljump(cptr,CF_RETURN,val); xlfail("no target for RETURN");}/* xlthrow - throw to a catch */void xlthrow(LVAL tag, LVAL val){ XLCONTEXT *cptr; /* find a catch context */ for (cptr = xlcontext; cptr; cptr = cptr->c_xlcontext) if ((cptr->c_flags & CF_THROW) && cptr->c_expr == tag) xljump(cptr,CF_THROW,val); xlfail("no target for THROW");}/* xlsignal - signal an error */void xlsignal(char *emsg, LVAL arg){ XLCONTEXT *cptr; /* find an error catcher */ for (cptr = xlcontext; cptr; cptr = cptr->c_xlcontext) if (cptr->c_flags & CF_ERROR) { if (cptr->c_expr && emsg) xlerrprint("error",NULL,emsg,arg); xljump(cptr,CF_ERROR,NIL); }}/* xltoplevel - go back to the top level */void xltoplevel(void){ close_loadingfiles(); stdputstr("[ back to top level ]\n"); findandjump(CF_TOPLEVEL,"no top level");}/* xlbrklevel - go back to the previous break level */void xlbrklevel(void){ findandjump(CF_BRKLEVEL,"no previous break level");}/* xlcleanup - clean-up after an error */void xlcleanup(void){ stdputstr("[ back to previous break level ]\n"); findandjump(CF_CLEANUP,"not in a break loop");}/* xlcontinue - continue from an error */void xlcontinue(void){ findandjump(CF_CONTINUE,"not in a break loop");}/* xljump - jump to a saved execution context */void xljump(XLCONTEXT *target, int mask, LVAL val){ /* unwind the execution stack */ for (; xlcontext != target; xlcontext = xlcontext->c_xlcontext) /* check for an UNWIND-PROTECT */ if ((xlcontext->c_flags & CF_UNWIND)) { xltarget = target; xlmask = mask; break; } /* restore the state */ xlstack = xlcontext->c_xlstack; xlenv = xlcontext->c_xlenv; xlfenv = xlcontext->c_xlfenv; xlunbind(xlcontext->c_xldenv); xlargv = xlcontext->c_xlargv; xlargc = xlcontext->c_xlargc; xlfp = xlcontext->c_xlfp; xlsp = xlcontext->c_xlsp; xlvalue = val; /* call the handler */ longjmp(xlcontext->c_jmpbuf,mask);}/* findandjump - find a target context frame and jump to it */LOCAL void findandjump(int mask, char *error){ XLCONTEXT *cptr; /* find a block context */ for (cptr = xlcontext; cptr; cptr = cptr->c_xlcontext) if (cptr->c_flags & mask) xljump(cptr,mask,NIL); xlabort(error);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -