diff options
| author | Lars Brinkhoff | 2013-01-06 14:27:44 +0100 |
|---|---|---|
| committer | Lars Brinkhoff | 2017-04-04 08:23:46 +0200 |
| commit | a2c33430292c79ac520100b1d0e8e7c04dfe426a (patch) | |
| tree | c14abd179a8646449c1430f24762db3e2359886a /doc | |
| parent | 19b92cdfb04a025037d7388954b64468d6f54462 (diff) | |
| download | emacs-a2c33430292c79ac520100b1d0e8e7c04dfe426a.tar.gz emacs-a2c33430292c79ac520100b1d0e8e7c04dfe426a.zip | |
Add record objects with user-defined types.
* src/alloc.c (allocate_record): New function.
(Fmake_record, Frecord, Fcopy_record): New functions.
(syms_of_alloc): defsubr them.
(purecopy): Work with records.
* src/data.c (Ftype_of): Return slot 0 for record objects, or type
name if record's type holds class.
(Frecordp): New function.
(syms_of_data): defsubr it. Define `Qrecordp'.
(Faref, Faset): Work with records.
* src/fns.c (Flength): Work with records.
* src/lisp.h (prec_type): Add PVEC_RECORD.
(RECORDP, CHECK_RECORD, CHECK_RECORD_TYPE): New functions.
* src/lread.c (read1): Add syntax for records.
* src/print.c (PRINT_CIRCLE_CANDIDATE_P): Add RECORDP.
(print_object): Add syntax for records.
* test/lisp/emacs-lisp/cl-print-tests.el (cl-print-tests-2):
New test.
* test/src/alloc-tests.el (record-1, record-2, record-3):
New tests.
* doc/lispref/elisp.texi, doc/lispref/objects.texi,
doc/lispref/records.texi: Add documentation for records.
Diffstat (limited to 'doc')
| -rw-r--r-- | doc/lispref/elisp.texi | 7 | ||||
| -rw-r--r-- | doc/lispref/objects.texi | 24 | ||||
| -rw-r--r-- | doc/lispref/records.texi | 98 |
3 files changed, 126 insertions, 3 deletions
diff --git a/doc/lispref/elisp.texi b/doc/lispref/elisp.texi index e0bd337e53b..0f7efb6f187 100644 --- a/doc/lispref/elisp.texi +++ b/doc/lispref/elisp.texi | |||
| @@ -180,6 +180,7 @@ To view this manual in other formats, click | |||
| 180 | * Sequences Arrays Vectors:: Lists, strings and vectors are called sequences. | 180 | * Sequences Arrays Vectors:: Lists, strings and vectors are called sequences. |
| 181 | Certain functions act on any kind of sequence. | 181 | Certain functions act on any kind of sequence. |
| 182 | The description of vectors is here as well. | 182 | The description of vectors is here as well. |
| 183 | * Records:: Compound objects with programmer-defined types. | ||
| 183 | * Hash Tables:: Very fast lookup-tables. | 184 | * Hash Tables:: Very fast lookup-tables. |
| 184 | * Symbols:: Symbols represent names, uniquely. | 185 | * Symbols:: Symbols represent names, uniquely. |
| 185 | 186 | ||
| @@ -314,6 +315,7 @@ Programming Types | |||
| 314 | expression, more fundamental but less pretty. | 315 | expression, more fundamental but less pretty. |
| 315 | * Primitive Function Type:: A function written in C, callable from Lisp. | 316 | * Primitive Function Type:: A function written in C, callable from Lisp. |
| 316 | * Byte-Code Type:: A function written in Lisp, then compiled. | 317 | * Byte-Code Type:: A function written in Lisp, then compiled. |
| 318 | * Record Type:: Compound objects with programmer-defined types. | ||
| 317 | * Autoload Type:: A type used for automatically loading seldom-used | 319 | * Autoload Type:: A type used for automatically loading seldom-used |
| 318 | functions. | 320 | functions. |
| 319 | * Finalizer Type:: Runs code when no longer reachable. | 321 | * Finalizer Type:: Runs code when no longer reachable. |
| @@ -418,6 +420,10 @@ Sequences, Arrays, and Vectors | |||
| 418 | * Bool-Vectors:: How to work with bool-vectors. | 420 | * Bool-Vectors:: How to work with bool-vectors. |
| 419 | * Rings:: Managing a fixed-size ring of objects. | 421 | * Rings:: Managing a fixed-size ring of objects. |
| 420 | 422 | ||
| 423 | Records | ||
| 424 | |||
| 425 | * Record Functions:: Functions for records. | ||
| 426 | |||
| 421 | Hash Tables | 427 | Hash Tables |
| 422 | 428 | ||
| 423 | * Creating Hash:: Functions to create hash tables. | 429 | * Creating Hash:: Functions to create hash tables. |
| @@ -1594,6 +1600,7 @@ Object Internals | |||
| 1594 | 1600 | ||
| 1595 | @include lists.texi | 1601 | @include lists.texi |
| 1596 | @include sequences.texi | 1602 | @include sequences.texi |
| 1603 | @include records.texi | ||
| 1597 | @include hash.texi | 1604 | @include hash.texi |
| 1598 | @include symbols.texi | 1605 | @include symbols.texi |
| 1599 | @include eval.texi | 1606 | @include eval.texi |
diff --git a/doc/lispref/objects.texi b/doc/lispref/objects.texi index 56049af60a1..90cafbef642 100644 --- a/doc/lispref/objects.texi +++ b/doc/lispref/objects.texi | |||
| @@ -25,9 +25,10 @@ but not for @emph{the} type of an object. | |||
| 25 | which all other types are constructed, are called @dfn{primitive types}. | 25 | which all other types are constructed, are called @dfn{primitive types}. |
| 26 | Each object belongs to one and only one primitive type. These types | 26 | Each object belongs to one and only one primitive type. These types |
| 27 | include @dfn{integer}, @dfn{float}, @dfn{cons}, @dfn{symbol}, | 27 | include @dfn{integer}, @dfn{float}, @dfn{cons}, @dfn{symbol}, |
| 28 | @dfn{string}, @dfn{vector}, @dfn{hash-table}, @dfn{subr}, and | 28 | @dfn{string}, @dfn{vector}, @dfn{hash-table}, @dfn{subr}, |
| 29 | @dfn{byte-code function}, plus several special types, such as | 29 | @dfn{byte-code function}, and @dfn{record}, plus several special |
| 30 | @dfn{buffer}, that are related to editing. (@xref{Editing Types}.) | 30 | types, such as @dfn{buffer}, that are related to editing. |
| 31 | (@xref{Editing Types}.) | ||
| 31 | 32 | ||
| 32 | Each primitive type has a corresponding Lisp function that checks | 33 | Each primitive type has a corresponding Lisp function that checks |
| 33 | whether an object is a member of that type. | 34 | whether an object is a member of that type. |
| @@ -154,6 +155,7 @@ latter are unique to Emacs Lisp. | |||
| 154 | expression, more fundamental but less pretty. | 155 | expression, more fundamental but less pretty. |
| 155 | * Primitive Function Type:: A function written in C, callable from Lisp. | 156 | * Primitive Function Type:: A function written in C, callable from Lisp. |
| 156 | * Byte-Code Type:: A function written in Lisp, then compiled. | 157 | * Byte-Code Type:: A function written in Lisp, then compiled. |
| 158 | * Record Type:: Compound objects with programmer-defined types. | ||
| 157 | * Autoload Type:: A type used for automatically loading seldom-used | 159 | * Autoload Type:: A type used for automatically loading seldom-used |
| 158 | functions. | 160 | functions. |
| 159 | * Finalizer Type:: Runs code when no longer reachable. | 161 | * Finalizer Type:: Runs code when no longer reachable. |
| @@ -1347,6 +1349,16 @@ The printed representation and read syntax for a byte-code function | |||
| 1347 | object is like that for a vector, with an additional @samp{#} before the | 1349 | object is like that for a vector, with an additional @samp{#} before the |
| 1348 | opening @samp{[}. | 1350 | opening @samp{[}. |
| 1349 | 1351 | ||
| 1352 | @node Record Type | ||
| 1353 | @subsection Record Type | ||
| 1354 | |||
| 1355 | A @dfn{record} is much like a @code{vector}. However, the first | ||
| 1356 | element is used to hold its type as returned by @code{type-of}. The | ||
| 1357 | purpose of records is to allow programmers to create objects with new | ||
| 1358 | types that are not built into Emacs. | ||
| 1359 | |||
| 1360 | @xref{Records}, for functions that work with records. | ||
| 1361 | |||
| 1350 | @node Autoload Type | 1362 | @node Autoload Type |
| 1351 | @subsection Autoload Type | 1363 | @subsection Autoload Type |
| 1352 | 1364 | ||
| @@ -1959,6 +1971,9 @@ with references to further information. | |||
| 1959 | @item processp | 1971 | @item processp |
| 1960 | @xref{Processes, processp}. | 1972 | @xref{Processes, processp}. |
| 1961 | 1973 | ||
| 1974 | @item recordp | ||
| 1975 | @xref{Record Type, recordp}. | ||
| 1976 | |||
| 1962 | @item sequencep | 1977 | @item sequencep |
| 1963 | @xref{Sequence Functions, sequencep}. | 1978 | @xref{Sequence Functions, sequencep}. |
| 1964 | 1979 | ||
| @@ -2022,6 +2037,7 @@ This function returns a symbol naming the primitive type of | |||
| 2022 | @code{marker}, @code{mutex}, @code{overlay}, @code{process}, | 2037 | @code{marker}, @code{mutex}, @code{overlay}, @code{process}, |
| 2023 | @code{string}, @code{subr}, @code{symbol}, @code{thread}, | 2038 | @code{string}, @code{subr}, @code{symbol}, @code{thread}, |
| 2024 | @code{vector}, @code{window}, or @code{window-configuration}. | 2039 | @code{vector}, @code{window}, or @code{window-configuration}. |
| 2040 | However, if @var{object} is a record, its first slot is returned. | ||
| 2025 | 2041 | ||
| 2026 | @example | 2042 | @example |
| 2027 | (type-of 1) | 2043 | (type-of 1) |
| @@ -2033,6 +2049,8 @@ This function returns a symbol naming the primitive type of | |||
| 2033 | @result{} symbol | 2049 | @result{} symbol |
| 2034 | (type-of '(x)) | 2050 | (type-of '(x)) |
| 2035 | @result{} cons | 2051 | @result{} cons |
| 2052 | (type-of (record 'foo)) | ||
| 2053 | @result{} foo | ||
| 2036 | @end group | 2054 | @end group |
| 2037 | @end example | 2055 | @end example |
| 2038 | @end defun | 2056 | @end defun |
diff --git a/doc/lispref/records.texi b/doc/lispref/records.texi new file mode 100644 index 00000000000..aeba77a70e7 --- /dev/null +++ b/doc/lispref/records.texi | |||
| @@ -0,0 +1,98 @@ | |||
| 1 | @c -*-texinfo-*- | ||
| 2 | @c This is part of the GNU Emacs Lisp Reference Manual. | ||
| 3 | @c Copyright (C) 2017 Free Software | ||
| 4 | @c Foundation, Inc. | ||
| 5 | @c See the file elisp.texi for copying conditions. | ||
| 6 | @node Records | ||
| 7 | @chapter Records | ||
| 8 | @cindex record | ||
| 9 | |||
| 10 | The purpose of records is to allow programmers to create objects | ||
| 11 | with new types that are not built into Emacs. | ||
| 12 | |||
| 13 | Internally, a record object is much like a vector; its slots can be | ||
| 14 | accessed using @code{aref}. However, the first slot is used to hold | ||
| 15 | its type as returned by @code{type-of}. Like arrays, records use | ||
| 16 | zero-origin indexing: the first slot has index 0. | ||
| 17 | |||
| 18 | The printed representation of records is @samp{#s} followed by a | ||
| 19 | list specifying the contents. The first list element must be the | ||
| 20 | record type. The following elements are the record slots. | ||
| 21 | |||
| 22 | A record is considered a constant for evaluation: the result of | ||
| 23 | evaluating it is the same record. This does not evaluate or even | ||
| 24 | examine the slots. @xref{Self-Evaluating Forms}. | ||
| 25 | |||
| 26 | @menu | ||
| 27 | * Record Functions:: Functions for records. | ||
| 28 | @end menu | ||
| 29 | |||
| 30 | @node Record Functions | ||
| 31 | @section Record Functions | ||
| 32 | |||
| 33 | @defun recordp object | ||
| 34 | This function returns @code{t} if @var{object} is a record. | ||
| 35 | |||
| 36 | @example | ||
| 37 | @group | ||
| 38 | (recordp #s(a)) | ||
| 39 | @result{} t | ||
| 40 | @end group | ||
| 41 | @end example | ||
| 42 | @end defun | ||
| 43 | |||
| 44 | @defun record type &rest objects | ||
| 45 | This function creates and returns a record whose type is @var{type} | ||
| 46 | and remaining slots are the rest of the arguments, @var{objects}. | ||
| 47 | |||
| 48 | @example | ||
| 49 | @group | ||
| 50 | (vector 'foo 23 [bar baz] "rats") | ||
| 51 | @result{} #s(foo 23 [bar baz] "rats") | ||
| 52 | @end group | ||
| 53 | @end example | ||
| 54 | @end defun | ||
| 55 | |||
| 56 | @defun make-record type length object | ||
| 57 | This function returns a new record with type @var{type} and | ||
| 58 | @var{length} more slots, each initialized to @var{object}. | ||
| 59 | |||
| 60 | @example | ||
| 61 | @group | ||
| 62 | (setq sleepy (make-record 'foo 9 'Z)) | ||
| 63 | @result{} #s(foo Z Z Z Z Z Z Z Z Z) | ||
| 64 | @end group | ||
| 65 | @end example | ||
| 66 | @end defun | ||
| 67 | |||
| 68 | @defun copy-record record | ||
| 69 | This function returns a shallow copy of @var{record}. The copy is the | ||
| 70 | same type as the original record, and it has the same slots in the | ||
| 71 | same order. | ||
| 72 | |||
| 73 | Storing a new slot into the copy does not affect the original | ||
| 74 | @var{record}, and vice versa. However, the slots of the new record | ||
| 75 | are not copies; they are identical (@code{eq}) to the slots of the | ||
| 76 | original. Therefore, changes made within these slots, as found via | ||
| 77 | the copied record, are also visible in the original record. | ||
| 78 | |||
| 79 | @example | ||
| 80 | @group | ||
| 81 | (setq x (record 'foo 1 2)) | ||
| 82 | @result{} #s(foo 1 2) | ||
| 83 | @end group | ||
| 84 | @group | ||
| 85 | (setq y (copy-record x)) | ||
| 86 | @result{} #s(foo 1 2) | ||
| 87 | @end group | ||
| 88 | |||
| 89 | @group | ||
| 90 | (eq x y) | ||
| 91 | @result{} nil | ||
| 92 | @end group | ||
| 93 | @group | ||
| 94 | (equal x y) | ||
| 95 | @result{} t | ||
| 96 | @end group | ||
| 97 | @end example | ||
| 98 | @end defun | ||