📄 opcodes.c
字号:
if (vp->v_type == V_NUM) { if (!qiszero(vp->v_num)) { *dojump = TRUE; return; } if (stack->v_type == V_NUM) qfree(stack->v_num); stack--; return; } if (testvalue(vp)) *dojump = TRUE; else freevalue(stack--);}/*ARGSUSED*/static voido_condandjump(fp, dojump) FUNC *fp; BOOL *dojump;{ VALUE *vp; vp = stack; if (vp->v_type == V_ADDR) vp = vp->v_addr; if (vp->v_type == V_NUM) { if (qiszero(vp->v_num)) { *dojump = TRUE; return; } if (stack->v_type == V_NUM) qfree(stack->v_num); stack--; return; } if (!testvalue(vp)) *dojump = TRUE; else freevalue(stack--);}/* * Compare the top two values on the stack for equality and jump if they are * different, popping off the top element, leaving the first one on the stack. * If they are equal, pop both values and do not jump. *//*ARGSUSED*/static voido_casejump(fp, dojump) FUNC *fp; BOOL *dojump;{ VALUE *v1, *v2; int r; v1 = &stack[-1]; v2 = &stack[0]; if (v1->v_type == V_ADDR) v1 = v1->v_addr; if (v2->v_type == V_ADDR) v2 = v2->v_addr; r = comparevalue(v1, v2); freevalue(stack--); if (r) *dojump = TRUE; else freevalue(stack--);}/*ARGSUSED*/static voido_jump(fp, dojump) FUNC *fp; BOOL *dojump;{ *dojump = TRUE;}static voido_usercall(fp, index, argcount) FUNC *fp; long index, argcount;{ fp = findfunc(index); if (fp == NULL) math_error("Function \"%s\" is undefined", namefunc(index)); calculate(fp, (int) argcount);}/*ARGSUSED*/static voido_call(fp, index, argcount) FUNC *fp; long index, argcount;{ VALUE result; result = builtinfunc(index, (int) argcount, stack); while (--argcount >= 0) freevalue(stack--); stack++; *stack = result;}static voido_getvalue(){ if (stack->v_type == V_ADDR) copyvalue(stack->v_addr, stack);}static voido_cmp(){ VALUE *v1, *v2; int r; v1 = &stack[-1]; v2 = &stack[0]; if (v1->v_type == V_ADDR) v1 = v1->v_addr; if (v2->v_type == V_ADDR) v2 = v2->v_addr; r = relvalue(v1, v2); freevalue(stack--); freevalue(stack); stack->v_num = itoq((long) r); stack->v_type = V_NUM;}static voido_eq(){ VALUE *v1, *v2; int r; v1 = &stack[-1]; v2 = &stack[0]; if (v1->v_type == V_ADDR) v1 = v1->v_addr; if (v2->v_type == V_ADDR) v2 = v2->v_addr; r = comparevalue(v1, v2); freevalue(stack--); freevalue(stack); stack->v_num = itoq((long) (r == 0)); stack->v_type = V_NUM;}static voido_ne(){ VALUE *v1, *v2; int r; v1 = &stack[-1]; v2 = &stack[0]; if (v1->v_type == V_ADDR) v1 = v1->v_addr; if (v2->v_type == V_ADDR) v2 = v2->v_addr; r = comparevalue(v1, v2); freevalue(stack--); freevalue(stack); stack->v_num = itoq((long) (r != 0)); stack->v_type = V_NUM;}static voido_le(){ VALUE *v1, *v2; int r; v1 = &stack[-1]; v2 = &stack[0]; if (v1->v_type == V_ADDR) v1 = v1->v_addr; if (v2->v_type == V_ADDR) v2 = v2->v_addr; r = relvalue(v1, v2); freevalue(stack--); freevalue(stack); stack->v_num = itoq((long) (r <= 0)); stack->v_type = V_NUM;}static voido_ge(){ VALUE *v1, *v2; int r; v1 = &stack[-1]; v2 = &stack[0]; if (v1->v_type == V_ADDR) v1 = v1->v_addr; if (v2->v_type == V_ADDR) v2 = v2->v_addr; r = relvalue(v1, v2); freevalue(stack--); freevalue(stack); stack->v_num = itoq((long) (r >= 0)); stack->v_type = V_NUM;}static voido_lt(){ VALUE *v1, *v2; int r; v1 = &stack[-1]; v2 = &stack[0]; if (v1->v_type == V_ADDR) v1 = v1->v_addr; if (v2->v_type == V_ADDR) v2 = v2->v_addr; r = relvalue(v1, v2); freevalue(stack--); freevalue(stack); stack->v_num = itoq((long) (r < 0)); stack->v_type = V_NUM;}static voido_gt(){ VALUE *v1, *v2; int r; v1 = &stack[-1]; v2 = &stack[0]; if (v1->v_type == V_ADDR) v1 = v1->v_addr; if (v2->v_type == V_ADDR) v2 = v2->v_addr; r = relvalue(v1, v2); freevalue(stack--); freevalue(stack); stack->v_num = itoq((long) (r > 0)); stack->v_type = V_NUM;}static voido_preinc(){ NUMBER *q, **np; VALUE *vp, tmp; if (stack->v_type != V_ADDR) math_error("Preincrementing non-variable"); if (stack->v_addr->v_type == V_NUM) { np = &stack->v_addr->v_num; q = qinc(*np); qfree(*np); *np = q; stack->v_type = V_NUM; stack->v_num = qlink(q); return; } vp = stack->v_addr; incvalue(vp, &tmp); freevalue(vp); *vp = tmp; copyvalue(&tmp, stack);}static voido_predec(){ NUMBER *q, **np; VALUE *vp, tmp; if (stack->v_type != V_ADDR) math_error("Predecrementing non-variable"); if (stack->v_addr->v_type == V_NUM) { np = &stack->v_addr->v_num; q = qdec(*np); qfree(*np); *np = q; stack->v_type = V_NUM; stack->v_num = qlink(q); return; } vp = stack->v_addr; decvalue(vp, &tmp); freevalue(vp); *vp = tmp; copyvalue(&tmp, stack);}static voido_postinc(){ NUMBER *q, **np; VALUE *vp, tmp; if (stack->v_type != V_ADDR) math_error("Postincrementing non-variable"); if (stack->v_addr->v_type == V_NUM) { np = &stack->v_addr->v_num; q = *np; *np = qinc(q); stack->v_type = V_NUM; stack->v_num = q; return; } vp = stack->v_addr; tmp = *vp; incvalue(&tmp, vp); *stack = tmp;}static voido_postdec(){ NUMBER *q, **np; VALUE *vp, tmp; if (stack->v_type != V_ADDR) math_error("Postdecrementing non-variable"); if (stack->v_addr->v_type == V_NUM) { np = &stack->v_addr->v_num; q = *np; *np = qdec(q); stack->v_type = V_NUM; stack->v_num = q; return; } vp = stack->v_addr; tmp = *vp; decvalue(&tmp, vp); *stack = tmp;}static voido_leftshift(){ VALUE *v1, *v2; VALUE tmp; v1 = &stack[-1]; v2 = &stack[0]; if (v1->v_type == V_ADDR) v1 = v1->v_addr; if (v2->v_type == V_ADDR) v2 = v2->v_addr; shiftvalue(v1, v2, FALSE, &tmp); freevalue(stack--); freevalue(stack); *stack = tmp;}static voido_rightshift(){ VALUE *v1, *v2; VALUE tmp; v1 = &stack[-1]; v2 = &stack[0]; if (v1->v_type == V_ADDR) v1 = v1->v_addr; if (v2->v_type == V_ADDR) v2 = v2->v_addr; shiftvalue(v1, v2, TRUE, &tmp); freevalue(stack--); freevalue(stack); *stack = tmp;}/*ARGSUSED*/static voido_debug(fp, line) FUNC *fp; long line;{ funcline = line; if (abortlevel >= ABORT_STATEMENT) math_error("Calculation aborted at statement boundary");}static voido_printresult(){ VALUE *vp; vp = stack; if (vp->v_type == V_ADDR) vp = vp->v_addr; if (vp->v_type != V_NULL) { if (tab_ok) math_chr('\t'); printvalue(vp, PRINT_UNAMBIG); math_chr('\n'); math_flush(); } freevalue(stack--);}/*ARGSUSED*/static voido_print(fp, flags) FUNC *fp; long flags;{ VALUE *vp; vp = stack; if (vp->v_type == V_ADDR) vp = vp->v_addr; printvalue(vp, (int) flags); freevalue(stack--); if (traceflags & TRACE_OPCODES) printf("\n"); math_flush();}static voido_printeol(){ math_chr('\n'); math_flush();}static voido_printspace(){ math_chr(' '); if (traceflags & TRACE_OPCODES) printf("\n");}/*ARGSUSED*/static voido_printstring(fp, cp) FUNC *fp; char *cp;{ math_str(cp); if (traceflags & TRACE_OPCODES) printf("\n"); math_flush();}static voido_zero(){ stack++; stack->v_type = V_NUM; stack->v_num = qlink(&_qzero_);}static voido_one(){ stack++; stack->v_type = V_NUM; stack->v_num = qlink(&_qone_);}static voido_save(fp) FUNC *fp;{ VALUE *vp; vp = stack; if (vp->v_type == V_ADDR) vp = vp->v_addr; freevalue(&fp->f_savedvalue); copyvalue(vp, &fp->f_savedvalue);}static voido_oldvalue(){ copyvalue(&oldvalue, ++stack);}static voido_quit(fp, cp) FUNC *fp; char *cp;{ if ((fp->f_name[0] == '*') && (fp->f_name[1] == '\0')) { if (cp) printf("%s\n", cp); hist_term(); while (stack > stackarray) { freevalue(stack--); } freevalue(stackarray); exit(0); } if (cp) math_error("%s", cp); math_error("quit statement executed");}static voido_getepsilon(){ stack++; stack->v_type = V_NUM; stack->v_num = qlink(_epsilon_);}static voido_setepsilon(){ VALUE *vp; NUMBER *newep; vp = &stack[0]; if (vp->v_type == V_ADDR) vp = vp->v_addr; if (vp->v_type != V_NUM) math_error("Non-numeric for epsilon"); newep = vp->v_num; stack->v_num = qlink(_epsilon_); setepsilon(newep); qfree(newep);}static voido_setconfig(){ int type; VALUE *v1, *v2; VALUE tmp; v1 = &stack[-1]; v2 = &stack[0]; if (v1->v_type == V_ADDR) v1 = v1->v_addr; if (v2->v_type == V_ADDR) v2 = v2->v_addr; if (v1->v_type != V_STR) math_error("Non-string for config"); type = configtype(v1->v_str); if (type < 0) math_error("Unknown config name \"%s\"", v1->v_str); getconfig(type, &tmp); setconfig(type, v2); freevalue(stack--); freevalue(stack); *stack = tmp;}static voido_getconfig(){ int type; VALUE *vp; vp = &stack[0]; if (vp->v_type == V_ADDR) vp = vp->v_addr; if (vp->v_type != V_STR) math_error("Non-string for config"); type = configtype(vp->v_str); if (type < 0) math_error("Unknown config name \"%s\"", vp->v_str); freevalue(stack); getconfig(type, stack);}/* * Set the 'old' value to the last value saved during the calculation. */voidupdateoldvalue(fp) FUNC *fp;{ if (fp->f_savedvalue.v_type == V_NULL) return; freevalue(&oldvalue); oldvalue = fp->f_savedvalue; fp->f_savedvalue.v_type = V_NULL;}/* * Routine called on any runtime error, to complain about it (with possible * arguments), and then longjump back to the top level command scanner. */#ifdef VARARGS# define VA_ALIST fmt, va_alist# define VA_DCL char *fmt; va_dcl#else# if defined(__STDC__) && __STDC__ == 1# define VA_ALIST char *fmt, ...# define VA_DCL# else# define VA_ALIST fmt# define VA_DCL char *fmt;# endif#endif/*VARARGS*/voidmath_error(VA_ALIST) VA_DCL{ va_list ap; char buf[MAXERROR+1]; if (funcname && (*funcname != '*')) fprintf(stderr, "\"%s\": ", funcname); if (funcline && ((funcname && (*funcname != '*')) || !inputisterminal())) fprintf(stderr, "line %ld: ", funcline);#ifdef VARARGS va_start(ap);#else va_start(ap, fmt);#endif vsprintf(buf, fmt, ap); va_end(ap); fprintf(stderr, "%s\n", buf); funcname = NULL; longjmp(jmpbuf, 1);}/* END CODE */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -