📄 tbl.c
字号:
long m; switch (M_TYPEOF(fmvo)) { case T_INTEGER: case T_REAL: case T_STRING: case T_CODE: tovo = fmvo; break; case T_TABLE: mapinit(); m = Mpushmark(fmvo); tovo = Mnew(T_TABLESIZE, T_TABLE); mapinsert(fmvo, tovo); reccopytable(fmvo, tovo); Mpopmark(m); mapterm(); break; } return tovo;}void Tgetfirst(Tobj to, Tkvindex_t * p){ if (!to || !T_ISTABLE(to)) return; p->tp = to, p->kvp = NULL, p->i = 0, p->j = 0; for (; p->i < p->tp->ln; p->i++) { if (!p->tp->lp[p->i]) continue; for (; p->j < p->tp->lp[p->i]->i; p->j++) { if ((p->kvp = &p->tp->lp[p->i]->kv[p->j])) return; } p->j = 0; }}void Tgetnext(Tkvindex_t * p){ p->kvp = NULL; p->j++; for (; p->i < p->tp->ln; p->i++) { if (!p->tp->lp[p->i]) continue; for (; p->j < p->tp->lp[p->i]->i; p->j++) { if ((p->kvp = &p->tp->lp[p->i]->kv[p->j])) return; } p->j = 0; }}static void insert(Ttable_t * tp, Tobj ko, char *sk, Tobj vo){ Tkvlist_t *kvlp, *nkvlp; Tkv_t *kvp; Ttype_t kt; long ik, i, ind, nln; double rk; switch ((kt = M_TYPEOF(ko))) { case T_INTEGER: ik = ((Tinteger_t *) ko)->i; if ((kvlp = tp->lp[(ind = GETIKINDEX(tp, ik))])) for (i = 0, kvp = &kvlp->kv[0]; i < kvlp->i; i++) if (ISEQIK(ik, kvp[i].ko)) goto found; break; case T_REAL: rk = ((Treal_t *) ko)->d; if ((kvlp = tp->lp[(ind = GETRKINDEX(tp, rk))])) for (i = 0, kvp = &kvlp->kv[0]; i < kvlp->i; i++) if (ISEQRK(rk, kvp[i].ko)) goto found; break; case T_STRING: if (M_AREAOF(ko) != 0) sk = ((Tstring_t *) ko)->s; if ((kvlp = tp->lp[(ind = GETSKINDEX(tp, sk))])) for (i = 0, kvp = &kvlp->kv[0]; i < kvlp->i; i++) if (ISEQSK(sk, kvp[i].ko)) goto found; break; } if ((nln = tp->n + 1) > 4 * tp->ln && nln < SHRT_MAX) { copytable(tp, nln); switch (kt) { case T_INTEGER: ind = GETIKINDEX(tp, ik); break; case T_REAL: ind = GETRKINDEX(tp, rk); break; case T_STRING: ind = GETSKINDEX(tp, sk); break; } kvlp = tp->lp[ind]; } if (!kvlp) { tp->lp[ind] = kvlp = Mallocate((long) T_KVLISTSIZE(1)); kvlp->i = 0, kvlp->n = 1; } else if (kvlp->i == kvlp->n) { tp->lp[ind] = nkvlp = Mallocate((long) T_KVLISTSIZE(kvlp->n * 2)); nkvlp->n = kvlp->n * 2; for (i = 0; i < kvlp->n; i++) nkvlp->kv[i] = kvlp->kv[i]; nkvlp->i = kvlp->i; Mfree(kvlp, M_BYTE2SIZE(T_KVLISTSIZE(kvlp->n))), kvlp = nkvlp; } if (M_AREAOF(ko) == 0) { /* ko must be allocated */ switch (kt) { case T_INTEGER: ko = Tinteger(ik); break; case T_REAL: ko = Treal(rk); break; case T_STRING: ko = Tstring(sk); break; } } kvlp->kv[kvlp->i].ko = ko, kvlp->kv[kvlp->i++].vo = vo; tp->n++; tp->time = Ttime; return; found: kvp[i].vo = vo; tp->time = Ttime;}static Tobj find(Ttable_t * tp, Tobj ko, char *sk){ Tkvlist_t *kvlp; Tkv_t *kvp; long ik, i; double rk; switch (M_TYPEOF(ko)) { case T_INTEGER: ik = ((Tinteger_t *) ko)->i; if ((kvlp = tp->lp[GETIKINDEX(tp, ik)])) for (i = 0, kvp = &kvlp->kv[0]; i < kvlp->i; i++) if (ISEQIK(ik, kvp[i].ko)) goto found; break; case T_REAL: rk = ((Treal_t *) ko)->d; if ((kvlp = tp->lp[GETRKINDEX(tp, rk)])) for (i = 0, kvp = &kvlp->kv[0]; i < kvlp->i; i++) if (ISEQRK(rk, kvp[i].ko)) goto found; break; case T_STRING: if (M_AREAOF(ko) != 0) sk = ((Tstring_t *) ko)->s; if ((kvlp = tp->lp[GETSKINDEX(tp, sk)])) for (i = 0, kvp = &kvlp->kv[0]; i < kvlp->i; i++) if (ISEQSK(sk, kvp[i].ko)) goto found; break; } return NULL; found: return kvp[i].vo;}static void delete(Ttable_t * tp, Tobj ko, char *sk){ Tkvlist_t *kvlp; Tkv_t *kvp; long ik, i, j; double rk; switch (M_TYPEOF(ko)) { case T_INTEGER: ik = ((Tinteger_t *) ko)->i; if ((kvlp = tp->lp[GETIKINDEX(tp, ik)])) for (i = 0, kvp = &kvlp->kv[0]; i < kvlp->i; i++) if (ISEQIK(ik, kvp[i].ko)) goto found; break; case T_REAL: rk = ((Treal_t *) ko)->d; if ((kvlp = tp->lp[GETRKINDEX(tp, rk)])) for (i = 0, kvp = &kvlp->kv[0]; i < kvlp->i; i++) if (ISEQRK(rk, kvp[i].ko)) goto found; break; case T_STRING: if (M_AREAOF(ko) != 0) sk = ((Tstring_t *) ko)->s; if ((kvlp = tp->lp[GETSKINDEX(tp, sk)])) for (i = 0, kvp = &kvlp->kv[0]; i < kvlp->i; i++) if (ISEQSK(sk, kvp[i].ko)) goto found; break; } return; found: for (j = i, kvp = &kvlp->kv[0]; j < kvlp->i - 1; j++) kvp[j] = kvp[j + 1]; kvlp->i--; tp->n--; tp->time = Ttime;}static void copytable(Ttable_t * tp, long ln){ Tkvlist_t **olp, **lp; Tkvlist_t *okvlp, *kvlp, *nkvlp; Tkv_t *kvp; long ik, oln, i, j, k, ind; double rk; char *sk; lp = Mallocate((long) (ln * T_KVLISTPTRSIZE)); oln = tp->ln, tp->ln = ln; olp = tp->lp, tp->lp = lp; for (i = 0; i < ln; i++) lp[i] = NULL; for (i = 0; i < oln; i++) { if (!(okvlp = olp[i])) continue; for (j = 0; j < okvlp->i; j++) { kvp = &okvlp->kv[j]; switch (M_TYPEOF(kvp->ko)) { case T_INTEGER: ik = ((Tinteger_t *) kvp->ko)->i; kvlp = lp[(ind = GETIKINDEX(tp, ik))]; break; case T_REAL: rk = ((Treal_t *) kvp->ko)->d; kvlp = lp[(ind = GETRKINDEX(tp, rk))]; break; case T_STRING: sk = ((Tstring_t *) kvp->ko)->s; kvlp = lp[(ind = GETSKINDEX(tp, sk))]; break; } if (!kvlp) { lp[ind] = kvlp = Mallocate((long) T_KVLISTSIZE(1)); kvlp->i = 0, kvlp->n = 1; } else if (kvlp->i == kvlp->n) { lp[ind] = nkvlp = Mallocate((long) T_KVLISTSIZE(kvlp->n * 2)); nkvlp->n = kvlp->n * 2; for (k = 0; k < kvlp->i; k++) nkvlp->kv[k] = kvlp->kv[k]; nkvlp->i = kvlp->i; Mfree(kvlp, M_BYTE2SIZE(T_KVLISTSIZE(kvlp->n))); kvlp = nkvlp; } kvlp->kv[kvlp->i].ko = kvp->ko, kvlp->kv[kvlp->i++].vo = kvp->vo; } Mfree(okvlp, M_BYTE2SIZE(T_KVLISTSIZE(okvlp->n))); } Mfree(olp, M_BYTE2SIZE(oln * T_KVLISTPTRSIZE));}static void reccopytable(Ttable_t * fmtp, Ttable_t * totp){ Tkv_t *fmkvp, *tokvp; long i, j, m; totp->lp = Mallocate((long) (fmtp->ln * T_KVLISTPTRSIZE)); totp->ln = fmtp->ln; totp->n = fmtp->n; totp->time = Ttime; for (i = 0; i < totp->ln; i++) { if (!fmtp->lp[i]) { totp->lp[i] = NULL; continue; } totp->lp[i] = Mallocate((long) T_KVLISTSIZE(fmtp->lp[i]->n)); totp->lp[i]->n = fmtp->lp[i]->n; totp->lp[i]->i = 0; } m = Mpushmark(totp); for (i = 0; i < totp->ln; i++) { if (!totp->lp[i]) continue; for (j = 0; j < fmtp->lp[i]->i; j++) { fmkvp = &fmtp->lp[i]->kv[j], tokvp = &totp->lp[i]->kv[j]; tokvp->ko = fmkvp->ko; switch (M_TYPEOF(fmkvp->vo)) { case T_INTEGER: case T_REAL: case T_STRING: case T_CODE: tokvp->vo = fmkvp->vo; break; case T_TABLE: if (!(tokvp->vo = mapfind(fmkvp->vo))) { tokvp->vo = Mnew(T_TABLESIZE, T_TABLE); mapinsert(fmkvp->vo, tokvp->vo); reccopytable(fmkvp->vo, tokvp->vo); } break; } totp->lp[i]->i++; } } Mpopmark(m);}static void mapinit(void){ long li; for (li = 0; li < MAPLISTN; li++) map.list[li] = NULL;}static void mapterm(void){ mapentry_t **lp; mapentry_t *cep, *nep; long li; for (li = 0; li < MAPLISTN; li++) { lp = &map.list[li]; for (cep = *lp; cep; cep = nep) { nep = cep->next; Mfree(cep, mapentrybyte2size); } *lp = NULL; }}static void mapinsert(Tobj fmo, Tobj too){ mapentry_t **lp; mapentry_t *cep; lp = &map.list[(unsigned long) fmo % MAPLISTN]; if (!(cep = Mallocate(MAPENTRYSIZE))) panic1(POS, "mapinsert", "cannot allocate mapentry"); cep->fmo = fmo, cep->too = too; cep->next = *lp, *lp = cep;}static Tobj mapfind(Tobj fmo){ mapentry_t **lp; mapentry_t *cep; lp = &map.list[(unsigned long) fmo % MAPLISTN]; for (cep = *lp; cep; cep = cep->next) if (cep->fmo == fmo) return cep->too; return NULL;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -