📄 data.c
字号:
/* Primitive operations on Lisp data types for GNU Emacs Lisp interpreter. Copyright (C) 1985, 1986 Free Software Foundation, Inc.This file is part of GNU Emacs.GNU Emacs is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation; either version 1, or (at your option)any later version.GNU Emacs is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with GNU Emacs; see the file COPYING. If not, write tothe Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */#include <signal.h>#include "config.h"#include "lisp.h"#ifndef standalone#include "buffer.h"#endifLisp_Object Qnil, Qt, Qquote, Qlambda, Qsubr, Qunbound;Lisp_Object Qerror_conditions, Qerror_message, Qtop_level;Lisp_Object Qerror, Qquit, Qwrong_type_argument, Qargs_out_of_range;Lisp_Object Qvoid_variable, Qvoid_function;Lisp_Object Qsetting_constant, Qinvalid_read_syntax;Lisp_Object Qinvalid_function, Qwrong_number_of_arguments, Qno_catch;Lisp_Object Qend_of_file, Qarith_error;Lisp_Object Qbeginning_of_buffer, Qend_of_buffer, Qbuffer_read_only;Lisp_Object Qintegerp, Qnatnump, Qsymbolp, Qlistp, Qconsp;Lisp_Object Qstringp, Qarrayp, Qsequencep, Qbufferp;Lisp_Object Qchar_or_string_p, Qmarkerp, Qinteger_or_marker_p, Qvectorp;Lisp_Object Qboundp, Qfboundp;Lisp_Object Qcdr;Lisp_Objectwrong_type_argument (predicate, value) register Lisp_Object predicate, value;{ register Lisp_Object tem; do { if (!EQ (Vmocklisp_arguments, Qt)) { if (XTYPE (value) == Lisp_String && (EQ (predicate, Qintegerp) || EQ (predicate, Qinteger_or_marker_p))) return Fstring_to_int (value, Qt); if (XTYPE (value) == Lisp_Int && EQ (predicate, Qstringp)) return Fint_to_string (value); } value = Fsignal (Qwrong_type_argument, Fcons (predicate, Fcons (value, Qnil))); tem = call1 (predicate, value); } while (NULL (tem)); return value;}pure_write_error (){ error ("Attempt to modify read-only object");}voidargs_out_of_range (a1, a2) Lisp_Object a1, a2;{ while (1) Fsignal (Qargs_out_of_range, Fcons (a1, Fcons (a2, Qnil)));}voidargs_out_of_range_3 (a1, a2, a3) Lisp_Object a1, a2, a3;{ while (1) Fsignal (Qargs_out_of_range, Fcons (a1, Fcons (a2, Fcons (a3, Qnil))));}Lisp_Objectmake_number (num) int num;{ register Lisp_Object val; XSET (val, Lisp_Int, num); return val;}/* On some machines, XINT needs a temporary location. Here it is, in case it is needed. */int sign_extend_temp;/* On a few machines, XINT can only be done by calling this. */intsign_extend_lisp_int (num) int num;{ if (num & (1 << (VALBITS - 1))) return num | ((-1) << VALBITS); else return num & ((1 << VALBITS) - 1);}/* Data type predicates */DEFUN ("eq", Feq, Seq, 2, 2, 0, "T if the two args are the same Lisp object.") (obj1, obj2) Lisp_Object obj1, obj2;{ if (EQ (obj1, obj2)) return Qt; return Qnil;}DEFUN ("null", Fnull, Snull, 1, 1, 0, "T if OBJECT is nil.") (obj) Lisp_Object obj;{ if (NULL (obj)) return Qt; return Qnil;}DEFUN ("consp", Fconsp, Sconsp, 1, 1, 0, "T if OBJECT is a cons cell.") (obj) Lisp_Object obj;{ if (XTYPE (obj) == Lisp_Cons) return Qt; return Qnil;}DEFUN ("atom", Fatom, Satom, 1, 1, 0, "T if OBJECT is not a cons cell. This includes nil.") (obj) Lisp_Object obj;{ if (XTYPE (obj) == Lisp_Cons) return Qnil; return Qt;}DEFUN ("listp", Flistp, Slistp, 1, 1, 0, "T if OBJECT is a list. This includes nil.") (obj) Lisp_Object obj;{ if (XTYPE (obj) == Lisp_Cons || NULL (obj)) return Qt; return Qnil;}DEFUN ("nlistp", Fnlistp, Snlistp, 1, 1, 0, "T if OBJECT is not a list. Lists include nil.") (obj) Lisp_Object obj;{ if (XTYPE (obj) == Lisp_Cons || NULL (obj)) return Qnil; return Qt;}DEFUN ("integerp", Fintegerp, Sintegerp, 1, 1, 0, "T if OBJECT is a number.") (obj) Lisp_Object obj;{ if (XTYPE (obj) == Lisp_Int) return Qt; return Qnil;}DEFUN ("natnump", Fnatnump, Snatnump, 1, 1, 0, "T if OBJECT is a nonnegative number.") (obj) Lisp_Object obj;{ if (XTYPE (obj) == Lisp_Int && XINT (obj) >= 0) return Qt; return Qnil;}DEFUN ("symbolp", Fsymbolp, Ssymbolp, 1, 1, 0, "T if OBJECT is a symbol.") (obj) Lisp_Object obj;{ if (XTYPE (obj) == Lisp_Symbol) return Qt; return Qnil;}DEFUN ("vectorp", Fvectorp, Svectorp, 1, 1, 0, "T if OBJECT is a vector.") (obj) Lisp_Object obj;{ if (XTYPE (obj) == Lisp_Vector) return Qt; return Qnil;}DEFUN ("stringp", Fstringp, Sstringp, 1, 1, 0, "T if OBJECT is a string.") (obj) Lisp_Object obj;{ if (XTYPE (obj) == Lisp_String) return Qt; return Qnil;}DEFUN ("arrayp", Farrayp, Sarrayp, 1, 1, 0, "T if OBJECT is an array (string or vector).") (obj) Lisp_Object obj;{ if (XTYPE (obj) == Lisp_Vector || XTYPE (obj) == Lisp_String) return Qt; return Qnil;}DEFUN ("sequencep", Fsequencep, Ssequencep, 1, 1, 0, "T if OBJECT is a sequence (list or array).") (obj) register Lisp_Object obj;{ if (CONSP (obj) || NULL (obj) || XTYPE (obj) == Lisp_Vector || XTYPE (obj) == Lisp_String) return Qt; return Qnil;}DEFUN ("bufferp", Fbufferp, Sbufferp, 1, 1, 0, "T if OBJECT is an editor buffer.") (obj) Lisp_Object obj;{ if (XTYPE (obj) == Lisp_Buffer) return Qt; return Qnil;}DEFUN ("markerp", Fmarkerp, Smarkerp, 1, 1, 0, "T if OBJECT is a marker (editor pointer).") (obj) Lisp_Object obj;{ if (XTYPE (obj) == Lisp_Marker) return Qt; return Qnil;}DEFUN ("integer-or-marker-p", Finteger_or_marker_p, Sinteger_or_marker_p, 1, 1, 0, "T if OBJECT is an integer or a marker (editor pointer).") (obj) register Lisp_Object obj;{ if (XTYPE (obj) == Lisp_Marker || XTYPE (obj) == Lisp_Int) return Qt; return Qnil;}DEFUN ("subrp", Fsubrp, Ssubrp, 1, 1, 0, "T if OBJECT is a built-in function.") (obj) Lisp_Object obj;{ if (XTYPE (obj) == Lisp_Subr) return Qt; return Qnil;}DEFUN ("char-or-string-p", Fchar_or_string_p, Schar_or_string_p, 1, 1, 0, "T if OBJECT is a character (a number) or a string.") (obj) register Lisp_Object obj;{ if (XTYPE (obj) == Lisp_Int || XTYPE (obj) == Lisp_String) return Qt; return Qnil;}/* Extract and set components of lists */DEFUN ("car", Fcar, Scar, 1, 1, 0, "Return the car of CONSCELL. If arg is nil, return nil.") (list) register Lisp_Object list;{ while (1) { if (XTYPE (list) == Lisp_Cons) return XCONS (list)->car; else if (EQ (list, Qnil)) return Qnil; else list = wrong_type_argument (Qlistp, list); }}DEFUN ("car-safe", Fcar_safe, Scar_safe, 1, 1, 0, "Return the car of OBJECT if it is a cons cell, or else nil.") (object) Lisp_Object object;{ if (XTYPE (object) == Lisp_Cons) return XCONS (object)->car; else return Qnil;}DEFUN ("cdr", Fcdr, Scdr, 1, 1, 0, "Return the cdr of CONSCELL. If arg is nil, return nil.") (list) register Lisp_Object list;{ while (1) { if (XTYPE (list) == Lisp_Cons) return XCONS (list)->cdr; else if (EQ (list, Qnil)) return Qnil; else list = wrong_type_argument (Qlistp, list); }}DEFUN ("cdr-safe", Fcdr_safe, Scdr_safe, 1, 1, 0, "Return the cdr of OBJECT if it is a cons cell, or else nil.") (object) Lisp_Object object;{ if (XTYPE (object) == Lisp_Cons) return XCONS (object)->cdr; else return Qnil;}DEFUN ("setcar", Fsetcar, Ssetcar, 2, 2, 0, "Set the car of CONSCELL to be NEWCAR. Returns NEWCAR.") (cell, newcar) register Lisp_Object cell, newcar;{ if (XTYPE (cell) != Lisp_Cons) cell = wrong_type_argument (Qconsp, cell); CHECK_IMPURE (cell); XCONS (cell)->car = newcar; return newcar;}DEFUN ("setcdr", Fsetcdr, Ssetcdr, 2, 2, 0, "Set the cdr of CONSCELL to be NEWCDR. Returns NEWCDR.") (cell, newcdr) register Lisp_Object cell, newcdr;{ if (XTYPE (cell) != Lisp_Cons) cell = wrong_type_argument (Qconsp, cell); CHECK_IMPURE (cell); XCONS (cell)->cdr = newcdr; return newcdr;}/* Extract and set components of symbols */DEFUN ("boundp", Fboundp, Sboundp, 1, 1, 0, "T if SYMBOL's value is not void.") (sym) register Lisp_Object sym;{ CHECK_SYMBOL (sym, 0); return (XTYPE (XSYMBOL (sym)->value) == Lisp_Void || EQ (XSYMBOL (sym)->value, Qunbound)) ? Qnil : Qt;}DEFUN ("fboundp", Ffboundp, Sfboundp, 1, 1, 0, "T if SYMBOL's function definition is not void.") (sym) register Lisp_Object sym;{ CHECK_SYMBOL (sym, 0); return (XTYPE (XSYMBOL (sym)->function) == Lisp_Void || EQ (XSYMBOL (sym)->function, Qunbound)) ? Qnil : Qt;}DEFUN ("makunbound", Fmakunbound, Smakunbound, 1, 1, 0, "Make SYMBOL's value be void.") (sym) register Lisp_Object sym;{ CHECK_SYMBOL (sym, 0); XSYMBOL (sym)->value = Qunbound; return sym;}DEFUN ("fmakunbound", Ffmakunbound, Sfmakunbound, 1, 1, 0, "Make SYMBOL's function definition be void.") (sym) register Lisp_Object sym;{ CHECK_SYMBOL (sym, 0); XSYMBOL (sym)->function = Qunbound; return sym;}DEFUN ("symbol-function", Fsymbol_function, Ssymbol_function, 1, 1, 0, "Return SYMBOL's function definition.") (sym) register Lisp_Object sym;{ CHECK_SYMBOL (sym, 0); if (EQ (XSYMBOL (sym)->function, Qunbound)) return Fsignal (Qvoid_function, Fcons (sym, Qnil)); return XSYMBOL (sym)->function;}DEFUN ("symbol-plist", Fsymbol_plist, Ssymbol_plist, 1, 1, 0, "Return SYMBOL's property list.") (sym) register Lisp_Object sym;{ CHECK_SYMBOL (sym, 0); return XSYMBOL (sym)->plist;}DEFUN ("symbol-name", Fsymbol_name, Ssymbol_name, 1, 1, 0, "Return SYMBOL's name, a string.") (sym) register Lisp_Object sym;{ register Lisp_Object name; CHECK_SYMBOL (sym, 0); XSET (name, Lisp_String, XSYMBOL (sym)->name); return name;}DEFUN ("fset", Ffset, Sfset, 2, 2, 0, "Set SYMBOL's function definition to NEWVAL, and return NEWVAL.") (sym, newdef) register Lisp_Object sym, newdef;{ CHECK_SYMBOL (sym, 0); if (!NULL (Vautoload_queue) && !EQ (XSYMBOL (sym)->function, Qunbound)) Vautoload_queue = Fcons (Fcons (sym, XSYMBOL (sym)->function), Vautoload_queue); XSYMBOL (sym)->function = newdef; return newdef;}DEFUN ("setplist", Fsetplist, Ssetplist, 2, 2, 0, "Set SYMBOL's property list to NEWVAL, and return NEWVAL.") (sym, newplist) register Lisp_Object sym, newplist;{ CHECK_SYMBOL (sym, 0); XSYMBOL (sym)->plist = newplist; return newplist;}/* Getting and setting values of symbols *//* Given the raw contents of a symbol value cell, return the Lisp value of the symbol. */Lisp_Objectdo_symval_forwarding (valcontents) register Lisp_Object valcontents;{ register Lisp_Object val;#ifdef SWITCH_ENUM_BUG switch ((int) XTYPE (valcontents))#else switch (XTYPE (valcontents))#endif { case Lisp_Intfwd: XSET (val, Lisp_Int, *XINTPTR (valcontents)); return val; case Lisp_Boolfwd: if (*XINTPTR (valcontents)) return Qt; return Qnil; case Lisp_Objfwd: return *XOBJFWD (valcontents); case Lisp_Buffer_Objfwd: return *(Lisp_Object *)(XUINT (valcontents) + (char *)current_buffer); } return valcontents;}voidstore_symval_forwarding (sym, valcontents, newval) Lisp_Object sym; register Lisp_Object valcontents, newval;{#ifdef SWITCH_ENUM_BUG switch ((int) XTYPE (valcontents))#else switch (XTYPE (valcontents))#endif { case Lisp_Intfwd: CHECK_NUMBER (newval, 1); *XINTPTR (valcontents) = XINT (newval); break; case Lisp_Boolfwd: *XINTPTR (valcontents) = NULL(newval) ? 0 : 1; break; case Lisp_Objfwd: *XOBJFWD (valcontents) = newval; break; case Lisp_Buffer_Objfwd: *(Lisp_Object *)(XUINT (valcontents) + (char *)current_buffer) = newval; break; default: valcontents = XSYMBOL (sym)->value; if (XTYPE (valcontents) == Lisp_Buffer_Local_Value || XTYPE (valcontents) == Lisp_Some_Buffer_Local_Value) XCONS (XSYMBOL (sym)->value)->car = newval; else XSYMBOL (sym)->value = newval; }}/* Note that it must not be possible to quit within this function. Great care is required for this. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -