📄 exec.c
字号:
lvarp[llvari].m = Mpushmark((lvarp[llvari].o = vo)); llvari++; di1 = TCgetnext(fdo, di1); } if (di1 != C_NULL || ai != C_NULL) { err(ERRARGMIS, ERR2, co, ci); Mpopmark(m); llvari = sinfop[ownsinfoi].llvari; sinfoi = ownsinfoi; return NULL; } for (; i < ln; i++, llvari++) lvarp[llvari].m = Mpushmark((lvarp[llvari].o = NULL)); flvari = sinfop[ownsinfoi].llvari; PUSHJMP(opljbufp2, pljbufp2, pljbuf); opljbufp1 = (volatile jmp_buf *) pljbufp1; if (setjmp(*pljbufp2)) { ; } else { sinfop[ownsinfoi].fco = fdo; for (; bi != C_NULL; bi = TCgetnext(fdo, bi)) { sinfop[ownsinfoi].fci = bi; if (TCgettype(fdo, bi) != C_DECL) eeval((Tobj) fdo, bi); } } POPJMP(opljbufp2, pljbufp2); pljbufp1 = (jmp_buf *) opljbufp1; } flvari = sinfop[ownsinfoi].flvari; llvari = sinfop[ownsinfoi].llvari; sinfoi = ownsinfoi; Mpopmark(m); lrtno = rtno, rtno = NULL; errdo = TRUE; return lrtno;}static void ewhilest(Tobj co, int ci){ volatile jmp_buf *opljbufp; volatile jmp_buf pljbuf; volatile Tobj c1o; volatile int ei, si; Tobj v1o; c1o = (volatile Tobj) co; /* protect argument from longjmp */ ei = TCgetfp(c1o, ci); si = TCgetnext(c1o, ei); PUSHJMP(opljbufp, pljbufp1, pljbuf); for (;;) { if (!(v1o = eeval((Tobj) c1o, ei))) err(ERRNORHS, ERR5, c1o, ei); if (boolop(v1o) == FALSE) break; if (setjmp(*pljbufp1)) { if (pljtype == PLJ_CONTINUE) continue; else if (pljtype == PLJ_BREAK) break; } eeval((Tobj) c1o, si); } POPJMP(opljbufp, pljbufp1);}static void eforst(Tobj co, int ci){ volatile jmp_buf *opljbufp; volatile jmp_buf pljbuf; volatile Tobj c1o; volatile int ei1, ei2, ei3, si, eisnop1, eisnop2, eisnop3; Tobj v1o; c1o = (volatile Tobj) co; /* protect argument from longjmp */ ei1 = TCgetfp(c1o, ci); ei2 = TCgetnext(c1o, ei1); ei3 = TCgetnext(c1o, ei2); si = TCgetnext(c1o, ei3); eisnop1 = (TCgettype(c1o, ei1) == C_NOP); eisnop2 = (TCgettype(c1o, ei2) == C_NOP); eisnop3 = (TCgettype(c1o, ei3) == C_NOP); PUSHJMP(opljbufp, pljbufp1, pljbuf); if (!eisnop1) eeval((Tobj) c1o, ei1); for (;;) { if (!eisnop2) { if (!(v1o = eeval((Tobj) c1o, ei2))) err(ERRNORHS, ERR5, c1o, ei2); if (boolop(v1o) == FALSE) break; } if (setjmp(*pljbufp1) != 0) { if (pljtype == PLJ_CONTINUE); else if (pljtype == PLJ_BREAK) break; } else { eeval((Tobj) c1o, si); } if (!eisnop3) eeval((Tobj) c1o, ei3); } POPJMP(opljbufp, pljbufp1);}static void eforinst(Tobj co, int ci){ volatile jmp_buf *opljbufp; volatile jmp_buf pljbuf; volatile Tobj tblo, c1o; volatile Tkvindex_t tkvi; volatile tnk_t tnk; volatile long km, t; volatile int ei1, ei2, si; c1o = (volatile Tobj) co; /* protect argument from longjmp */ ei1 = TCgetfp(c1o, ci); ei2 = TCgetnext(c1o, ei1); si = TCgetnext(c1o, ei2); if (getvar((Tobj) c1o, ei1, (tnk_t *) & tnk) == -1) { err(ERRNOLHS, ERR3, c1o, ei1); return; } if (tnk.type == TNK_O) km = Mpushmark(tnk.u.tnko.ko); if (!(tblo = (volatile Tobj) eeval((Tobj) c1o, ei2))) { if (tnk.type == TNK_O) Mpopmark(km); err(ERRNORHS, ERR4, c1o, ei2); return; } if (Tgettype(tblo) != T_TABLE) { err(ERRNOTATABLE, ERR1, c1o, ei2); return; } PUSHJMP(opljbufp, pljbufp1, pljbuf); t = Tgettime(tblo); for (Tgetfirst((Tobj) tblo, (Tkvindex_t *) & tkvi); tkvi.kvp; Tgetnext((Tkvindex_t *) & tkvi)) { setvar(tnk, tkvi.kvp->ko); if (setjmp(*pljbufp1) != 0) { if (pljtype == PLJ_CONTINUE) continue; else if (pljtype == PLJ_BREAK) break; } eeval((Tobj) c1o, si); if (t != Tgettime(tblo)) { err(ERRTABLECHANGED, ERR1, c1o, ei2); break; } } POPJMP(opljbufp, pljbufp1); if (tnk.type == TNK_O) Mpopmark(km);}static Tobj getval(Tobj co, int ci){ Tobj cvo, cko, cto; Ctype_t ct, vt; int vi, ni, nn; if ((ct = TCgettype(co, ci)) == C_LVAR) { nn = (int) TCgetinteger(co, (ni = TCgetnext(co, TCgetfp(co, ci)))); cto = cvo = lvarp[flvari + nn].o; if (!cto) return NULL; vi = TCgetnext(co, ni); } else if (ct == C_GVAR) { cto = root; vi = TCgetfp(co, ci); } else if (ct == C_PVAR) return TCgetobject(co, ci); else return NULL; while (vi != C_NULL) { if (Tgettype(cto) != T_TABLE) return NULL; if ((vt = TCgettype(co, vi)) == C_STRING) { if (!(cvo = Tfinds(cto, TCgetstring(co, vi)))) return NULL; } else if (vt == C_INTEGER) { if (!(cvo = Tfindi(cto, TCgetinteger(co, vi)))) return NULL; } else if (vt == C_REAL) { if (!(cvo = Tfindr(cto, TCgetreal(co, vi)))) return NULL; } else { if (!(cko = eeval(co, vi)) || !(cvo = Tfindo(cto, cko))) return NULL; } cto = cvo; vi = TCgetnext(co, vi); } return cvo;}static int getvar(Tobj co, int ci, tnk_t * tnkp){ Tobj cvo, cko, cto; Ctype_t ct, vt; long m; int vi, ovi, nn, ni; if ((ct = TCgettype(co, ci)) == C_LVAR) { nn = (int) TCgetinteger(co, (ni = TCgetnext(co, TCgetfp(co, ci)))); cvo = cto = lvarp[flvari + nn].o; vi = TCgetnext(co, ni); if (vi != C_NULL && (!cvo || Tgettype(cvo) != T_TABLE)) Mresetmark(lvarp[flvari + nn].m, (lvarp[flvari + nn].o = cvo = cto = Ttable(0))); } else if (ct == C_GVAR) { /* else it's a global variable */ cvo = root; vi = TCgetfp(co, ci); } else { return -1; } ovi = -1; while (vi != C_NULL) { cto = cvo; if ((vt = TCgettype(co, vi)) == C_STRING) { cvo = Tfinds(cto, TCgetstring(co, vi)); } else if (vt == C_INTEGER) { cvo = Tfindi(cto, TCgetinteger(co, vi)); } else if (vt == C_REAL) { cvo = Tfindr(cto, TCgetreal(co, vi)); } else { if (!(cko = eeval(co, vi)) || !(T_ISSTRING(cko) || T_ISNUMBER(cko))) return -1; cvo = Tfindo(cto, cko); } ovi = vi, vi = TCgetnext(co, vi); if (vi != C_NULL && (!cvo || Tgettype(cvo) != T_TABLE)) { if (vt == C_STRING) Tinss(cto, TCgetstring(co, ovi), (cvo = Ttable(0))); else if (vt == C_INTEGER) Tinsi(cto, TCgetinteger(co, ovi), (cvo = Ttable(0))); else if (vt == C_REAL) Tinsr(cto, TCgetreal(co, ovi), (cvo = Ttable(0))); else m = Mpushmark(cko), Tinso(cto, cko, (cvo = Ttable(0))), Mpopmark(m); } } if (ct == C_LVAR && ovi == -1) { tnkp->type = TNK_LI; tnkp->u.li = nn; } else { switch (vt) { case C_STRING: case C_INTEGER: case C_REAL: tnkp->type = TNK_S; tnkp->u.tnks.kt = vt; tnkp->u.tnks.to = cto; tnkp->u.tnks.co = co; tnkp->u.tnks.vi = ovi; break; default: tnkp->type = TNK_O; tnkp->u.tnko.to = cto; tnkp->u.tnko.ko = cko; break; } } return 0;}static void setvar(tnk_t tnk, Tobj vo){ switch (tnk.type) { case TNK_LI: Mresetmark(lvarp[flvari + tnk.u.li].m, (lvarp[flvari + tnk.u.li].o = vo)); break; case TNK_O: Tinso(tnk.u.tnko.to, tnk.u.tnko.ko, vo); break; default: switch (tnk.u.tnks.kt) { case C_STRING: Tinss(tnk.u.tnks.to, TCgetstring(tnk.u.tnks.co, tnk.u.tnks.vi), vo); break; case C_INTEGER: Tinsi(tnk.u.tnks.to, TCgetinteger(tnk.u.tnks.co, tnk.u.tnks.vi), vo); break; case C_REAL: Tinsr(tnk.u.tnks.to, TCgetreal(tnk.u.tnks.co, tnk.u.tnks.vi), vo); break; } break; }}static int boolop(Tobj vo){ long i; double d; if (!vo) return FALSE; switch (Tgettype(vo)) { case T_INTEGER: i = Tgetinteger(vo); return (i == 0) ? FALSE : TRUE; case T_REAL: d = Tgetreal(vo); return (d == 0.0) ? FALSE : TRUE; case T_TABLE: if (vo == null) return FALSE; return TRUE; default: return TRUE; }}static int orderop(Tobj v1o, Ctype_t op, Tobj v2o){ Ctype_t t1, t2; long i1, i2; int r; double d1, d2; if (!v1o || !v2o) { if ((v1o || v2o) && op == C_NE) return TRUE; return FALSE; } t1 = Tgettype(v1o), t2 = Tgettype(v2o); if (t1 == T_STRING && t2 == T_STRING) { r = Strcmp(Tgetstring(v1o), Tgetstring(v2o)); } else if (t1 == T_INTEGER && t2 == T_INTEGER) { i1 = Tgetinteger(v1o), i2 = Tgetinteger(v2o); r = (i1 == i2) ? 0 : ((i1 < i2) ? -1 : 1); } else if (t1 == T_INTEGER && t2 == T_REAL) { i1 = Tgetinteger(v1o), d2 = Tgetreal(v2o); r = (i1 == d2) ? 0 : ((i1 < d2) ? -1 : 1); } else if (t1 == T_REAL && t2 == T_INTEGER) { d1 = Tgetreal(v1o), i2 = Tgetinteger(v2o); r = (d1 == i2) ? 0 : ((d1 < i2) ? -1 : 1); } else if (t1 == T_REAL && t2 == T_REAL) { d1 = Tgetreal(v1o), d2 = Tgetreal(v2o); r = (d1 == d2) ? 0 : ((d1 < d2) ? -1 : 1); } else if (t1 == t2) { if (op != C_EQ && op != C_NE) return FALSE; r = (v1o == v2o) ? 0 : 1; } else { return FALSE; } switch (op) { case C_EQ: return (r == 0) ? TRUE : FALSE; case C_NE: return (r != 0) ? TRUE : FALSE; case C_LT: return (r < 0) ? TRUE : FALSE; case C_LE: return (r <= 0) ? TRUE : FALSE; case C_GT: return (r > 0) ? TRUE : FALSE; case C_GE: return (r >= 0) ? TRUE : FALSE; } panic1(POS, "orderop", "bad op code"); return FALSE; /* NOT REACHED */}static Tobj arithop(num_tt * lnum, Ctype_t op, num_tt * rnum){ double d1, d2, d3; if (!rnum && op != C_UMINUS) return NULL; if (lnum->type == C_INTEGER) d1 = lnum->u.i; else if (lnum->type == C_REAL) d1 = lnum->u.d; else if (!lnum->u.no) return NULL; else if (Tgettype(lnum->u.no) == T_INTEGER) d1 = Tgetinteger(lnum->u.no); else if (Tgettype(lnum->u.no) == T_REAL) d1 = Tgetreal(lnum->u.no); else return NULL; if (op == C_UMINUS) { d3 = -d1; goto result; } if (rnum->type == C_INTEGER) d2 = rnum->u.i; else if (rnum->type == C_REAL) d2 = rnum->u.d; else if (!rnum->u.no) return NULL; else if (Tgettype(rnum->u.no) == T_INTEGER) d2 = Tgetinteger(rnum->u.no); else if (Tgettype(rnum->u.no) == T_REAL) d2 = Tgetreal(rnum->u.no); else return NULL; switch (op) { case C_PLUS: d3 = d1 + d2; break; case C_MINUS: d3 = d1 - d2; break; case C_MUL: d3 = d1 * d2; break; case C_DIV: d3 = d1 / d2; break; case C_MOD: d3 = (long) d1 % (long) d2; break; } result: if (d3 == (double) (long) d3) return Tinteger((long) d3); return Treal(d3);}static void err(int errnum, int level, Tobj co, int ci){ char *s; int si, i; if (level > Eerrlevel || !errdo) return; s = ""; fprintf(stderr, "runtime error: %s\n", errnam[errnum]); if (!co) return; if (Estackdepth < 1) return; if (!sinfop[(si = sinfoi - 1)].fco && si > 0) si--; if (Eshowbody > 0) { if (co == sinfop[si].fco) s = Scfull(co, 0, ci); else if (co == sinfop[si].co) s = Scfull(co, TCgetfp(co, 0), ci); printbody(s, Eshowbody), free(s); if (Estackdepth == 1) { fprintf(stderr, "\n"); errdo = FALSE; } for (i = si; i >= 0; i--) { if (sinfop[i].fco) { s = Scfull(sinfop[i].fco, 0, sinfop[i].fci); printbody(s, Eshowbody), free(s); } } s = Scfull(sinfop[0].co, TCgetfp(sinfop[0].co, 0), sinfop[0].ci); printbody(s, Eshowbody), free(s); } fprintf(stderr, "\n"); errdo = FALSE;}static void printbody(char *s, int mode){ char *s1, *s2; char c; if (mode == 2) { fprintf(stderr, "%s\n", s); return; } c = '\000'; for (s1 = s; *s1; s1++) if (*s1 == '>' && *(s1 + 1) && *(s1 + 1) == '>') break; if (!*s1) return; for (; s1 != s; s1--) if (*(s1 - 1) == '\n') break; for (s2 = s1; *s2; s2++) if (*s2 == '\n') break; if (*s2) c = *s2, *s2 = '\000'; fprintf(stderr, "%s\n", s1); if (c) *s2 = c;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -