📄 fns.c
字号:
else seq = wrong_type_argument (Qsequencep, seq); }}DEFUN ("memq", Fmemq, Smemq, 2, 2, 0, "Returns non-nil if ELT is an element of LIST. Comparison done with EQ.\n\The value is actually the tail of LIST whose car is ELT.") (elt, list) register Lisp_Object elt; Lisp_Object list;{ register Lisp_Object tail; for (tail = list; !NULL (tail); tail = Fcdr (tail)) { register Lisp_Object tem; tem = Fcar (tail); if (EQ (elt, tem)) return tail; QUIT; } return Qnil;}DEFUN ("assq", Fassq, Sassq, 2, 2, 0, "Returns non-nil if ELT is the car of an element of LIST. Comparison done with eq.\n\The value is actually the element of LIST whose car is ELT.") (key, list) register Lisp_Object key; Lisp_Object list;{ register Lisp_Object tail; for (tail = list; !NULL (tail); tail = Fcdr (tail)) { register Lisp_Object elt, tem; elt = Fcar (tail); if (!CONSP (elt)) continue; tem = Fcar (elt); if (EQ (key, tem)) return elt; QUIT; } return Qnil;}/* Like Fassq but never report an error and do not allow quits. Use only on lists known never to be circular. */Lisp_Objectassq_no_quit (key, list) register Lisp_Object key; Lisp_Object list;{ register Lisp_Object tail; for (tail = list; CONSP (tail); tail = Fcdr (tail)) { register Lisp_Object elt, tem; elt = Fcar (tail); if (!CONSP (elt)) continue; tem = Fcar (elt); if (EQ (key, tem)) return elt; } return Qnil;}DEFUN ("assoc", Fassoc, Sassoc, 2, 2, 0, "Returns non-nil if ELT is the car of an element of LIST. Comparison done with equal.\n\The value is actually the element of LIST whose car is ELT.") (key, list) register Lisp_Object key; Lisp_Object list;{ register Lisp_Object tail; for (tail = list; !NULL (tail); tail = Fcdr (tail)) { register Lisp_Object elt, tem; elt = Fcar (tail); if (!CONSP (elt)) continue; tem = Fequal (Fcar (elt), key); if (!NULL (tem)) return elt; QUIT; } return Qnil;}DEFUN ("rassq", Frassq, Srassq, 2, 2, 0, "Returns non-nil if ELT is the cdr of an element of LIST. Comparison done with EQ.\n\The value is actually the element of LIST whose cdr is ELT.") (key, list) register Lisp_Object key; Lisp_Object list;{ register Lisp_Object tail; for (tail = list; !NULL (tail); tail = Fcdr (tail)) { register Lisp_Object elt, tem; elt = Fcar (tail); if (!CONSP (elt)) continue; tem = Fcdr (elt); if (EQ (key, tem)) return elt; QUIT; } return Qnil;}DEFUN ("delq", Fdelq, Sdelq, 2, 2, 0, "Deletes by side effect any occurrences of ELT as a member of LIST.\n\The modified LIST is returned.\n\If the first member of LIST is ELT, there is no way to remove it by side effect;\n\therefore, write (setq foo (delq element foo)) to be sure of changing foo.") (elt, list) register Lisp_Object elt; Lisp_Object list;{ register Lisp_Object tail, prev; register Lisp_Object tem; tail = list; prev = Qnil; while (!NULL (tail)) { tem = Fcar (tail); if (EQ (elt, tem)) { if (NULL (prev)) list = Fcdr (tail); else Fsetcdr (prev, Fcdr (tail)); } else prev = tail; tail = Fcdr (tail); QUIT; } return list;}DEFUN ("nreverse", Fnreverse, Snreverse, 1, 1, 0, "Reverses LIST by modifying cdr pointers. Returns the beginning of the reversed list.") (list) Lisp_Object list;{ register Lisp_Object prev, tail, next; if (NULL (list)) return list; prev = Qnil; tail = list; while (!NULL (tail)) { QUIT; next = Fcdr (tail); Fsetcdr (tail, prev); prev = tail; tail = next; } return prev;}DEFUN ("reverse", Freverse, Sreverse, 1, 1, 0, "Reverses LIST, copying. Returns the beginning of the reversed list.\n\See also the function nreverse, which is used more often.") (list) Lisp_Object list;{ Lisp_Object length; register Lisp_Object *vec; register Lisp_Object tail; register int i; length = Flength (list); vec = (Lisp_Object *) alloca (XINT (length) * sizeof (Lisp_Object)); for (i = XINT (length) - 1, tail = list; i >= 0; i--, tail = Fcdr (tail)) vec[i] = Fcar (tail); return Flist (XINT (length), vec);}Lisp_Object merge ();DEFUN ("sort", Fsort, Ssort, 2, 2, 0, "Sort LIST, stably, comparing elements using PREDICATE.\n\Returns the sorted list. LIST is modified by side effects.\n\PREDICATE is called with two elements of LIST, and should return T\n\if the first element is \"less\" than the second.") (list, pred) Lisp_Object list, pred;{ Lisp_Object front, back; register Lisp_Object len, tem; struct gcpro gcpro1, gcpro2; register int length; front = list; len = Flength (list); length = XINT (len); if (length < 2) return list; XSETINT (len, (length / 2) - 1); tem = Fnthcdr (len, list); back = Fcdr (tem); Fsetcdr (tem, Qnil); GCPRO2 (front, back); front = Fsort (front, pred); back = Fsort (back, pred); UNGCPRO; return merge (front, back, pred);}Lisp_Objectmerge (org_l1, org_l2, pred) Lisp_Object org_l1, org_l2; Lisp_Object pred;{ Lisp_Object value; register Lisp_Object tail; Lisp_Object tem; register Lisp_Object l1, l2; struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; l1 = org_l1; l2 = org_l2; tail = Qnil; value = Qnil; /* It is sufficient to protect org_l1 and org_l2. When l1 and l2 are updated, we copy the new values back into the org_ vars. */ GCPRO4 (org_l1, org_l2, pred, value); while (1) { if (NULL (l1)) { UNGCPRO; if (NULL (tail)) return l2; Fsetcdr (tail, l2); return value; } if (NULL (l2)) { UNGCPRO; if (NULL (tail)) return l1; Fsetcdr (tail, l1); return value; } tem = call2 (pred, Fcar (l2), Fcar (l1)); if (NULL (tem)) { tem = l1; l1 = Fcdr (l1); org_l1 = l1; } else { tem = l2; l2 = Fcdr (l2); org_l2 = l2; } if (NULL (tail)) value = tem; else Fsetcdr (tail, tem); tail = tem; }}DEFUN ("get", Fget, Sget, 2, 2, 0, "Return the value of SYMBOL's PROPNAME property.\n\This is the last VALUE stored with (put SYMBOL PROPNAME VALUE).") (sym, prop) Lisp_Object sym; register Lisp_Object prop;{ register Lisp_Object tail; for (tail = Fsymbol_plist (sym); !NULL (tail); tail = Fcdr (Fcdr (tail))) { register Lisp_Object tem; tem = Fcar (tail); if (EQ (prop, tem)) return Fcar (Fcdr (tail)); } return Qnil;}DEFUN ("put", Fput, Sput, 3, 3, 0, "Store SYMBOL's PROPNAME property with value VALUE.\n\It can be retrieved with (get SYMBOL PROPNAME).") (sym, prop, val) Lisp_Object sym; register Lisp_Object prop; Lisp_Object val;{ register Lisp_Object tail, prev; Lisp_Object newcell; prev = Qnil; for (tail = Fsymbol_plist (sym); !NULL (tail); tail = Fcdr (Fcdr (tail))) { register Lisp_Object tem; tem = Fcar (tail); if (EQ (prop, tem)) return Fsetcar (Fcdr (tail), val); prev = tail; } newcell = Fcons (prop, Fcons (val, Qnil)); if (NULL (prev)) Fsetplist (sym, newcell); else Fsetcdr (Fcdr (prev), newcell); return val;}DEFUN ("equal", Fequal, Sequal, 2, 2, 0, "T if two Lisp objects have similar structure and contents.\n\They must have the same data type.\n\Conses are compared by comparing the cars and the cdrs.\n\Vectors and strings are compared element by element.\n\Numbers are compared by value. Symbols must match exactly.") (o1, o2) register Lisp_Object o1, o2;{do_cdr: QUIT; if (XTYPE (o1) != XTYPE (o2)) return Qnil; if (XINT (o1) == XINT (o2)) return Qt; if (XTYPE (o1) == Lisp_Cons) { Lisp_Object v1; v1 = Fequal (Fcar (o1), Fcar (o2)); if (NULL (v1)) return v1; o1 = Fcdr (o1), o2 = Fcdr (o2); goto do_cdr; } if (XTYPE (o1) == Lisp_Marker) { return (XMARKER (o1)->buffer == XMARKER (o2)->buffer && XMARKER (o1)->bufpos == XMARKER (o2)->bufpos) ? Qt : Qnil; } if (XTYPE (o1) == Lisp_Vector) { register int index; if (XVECTOR (o1)->size != XVECTOR (o2)->size) return Qnil; for (index = 0; index < XVECTOR (o1)->size; index++) { Lisp_Object v, v1, v2; v1 = XVECTOR (o1)->contents [index]; v2 = XVECTOR (o2)->contents [index]; v = Fequal (v1, v2); if (NULL (v)) return v; } return Qt; } if (XTYPE (o1) == Lisp_String) { if (XSTRING (o1)->size != XSTRING (o2)->size) return Qnil; if (bcmp (XSTRING (o1)->data, XSTRING (o2)->data, XSTRING (o1)->size)) return Qnil; return Qt; } return Qnil;}DEFUN ("fillarray", Ffillarray, Sfillarray, 2, 2, 0, "Store each element of ARRAY with ITEM. ARRAY is a vector or string.") (array, item) Lisp_Object array, item;{ register int size, index, charval; retry: if (XTYPE (array) == Lisp_Vector) { register Lisp_Object *p = XVECTOR (array)->contents; size = XVECTOR (array)->size; for (index = 0; index < size; index++) p[index] = item; } else if (XTYPE (array) == Lisp_String) { register unsigned char *p = XSTRING (array)->data; CHECK_NUMBER (item, 1); charval = XINT (item); size = XSTRING (array)->size; for (index = 0; index < size; index++) p[index] = charval; } else { array = wrong_type_argument (Qarrayp, array); goto retry; } return array;}/* ARGSUSED */Lisp_Objectnconc2 (s1, s2) Lisp_Object s1, s2;{#ifdef NO_ARG_ARRAY Lisp_Object args[2]; args[0] = s1; args[1] = s2; return Fnconc (2, args);#else return Fnconc (2, &s1);#endif /* NO_ARG_ARRAY */}DEFUN ("nconc", Fnconc, Snconc, 0, MANY, 0, "Concatenate any number of lists by altering them.\n\Only the last argument is not altered, and need not be a list.") (nargs, args) int nargs; Lisp_Object *args;{ register int argnum; register Lisp_Object tail, tem, val; val = Qnil; for (argnum = 0; argnum < nargs; argnum++) { tem = args[argnum]; if (NULL (tem)) continue; if (NULL (val)) val = tem; if (argnum + 1 == nargs) break; if (!CONSP (tem)) tem = wrong_type_argument (Qlistp, tem); while (CONSP (tem)) { tail = tem; tem = Fcdr (tail); QUIT; } tem = args[argnum + 1]; Fsetcdr (tail, tem); if (NULL (tem)) args[argnum + 1] = tail; } return val;}/* This is the guts of all mapping functions. Apply fn to each element of seq, one by one, storing the results into elements of vals, a C vector of Lisp_Objects. leni is the length of vals, which should also be the length of seq. */static voidmapcar1 (leni, vals, fn, seq) int leni; Lisp_Object *vals;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -