aboutsummaryrefslogtreecommitdiffstats
path: root/src/alloc.c
diff options
context:
space:
mode:
authorLars Brinkhoff2013-01-06 14:27:44 +0100
committerLars Brinkhoff2017-04-04 08:23:46 +0200
commita2c33430292c79ac520100b1d0e8e7c04dfe426a (patch)
treec14abd179a8646449c1430f24762db3e2359886a /src/alloc.c
parent19b92cdfb04a025037d7388954b64468d6f54462 (diff)
downloademacs-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 'src/alloc.c')
-rw-r--r--src/alloc.c93
1 files changed, 92 insertions, 1 deletions
diff --git a/src/alloc.c b/src/alloc.c
index ae3e1519c04..fe631f2e4d8 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -3392,6 +3392,94 @@ allocate_buffer (void)
3392 return b; 3392 return b;
3393} 3393}
3394 3394
3395
3396/* Allocate a new record with COUNT slots. Return NULL if COUNT is
3397 too large. */
3398
3399static struct Lisp_Vector *
3400allocate_record (int count)
3401{
3402 if (count >= (1 << PSEUDOVECTOR_SIZE_BITS))
3403 return NULL;
3404
3405 struct Lisp_Vector *p = allocate_vector (count);
3406 XSETPVECTYPE (p, PVEC_RECORD);
3407 return p;
3408}
3409
3410
3411DEFUN ("make-record", Fmake_record, Smake_record, 3, 3, 0,
3412 doc: /* Create a new record.
3413TYPE is its type as returned by `type-of'. SLOTS is the number of
3414slots, each initialized to INIT. The number of slots, including the
3415type slot, must fit in PSEUDOVECTOR_SIZE_BITS. */)
3416 (Lisp_Object type, Lisp_Object slots, Lisp_Object init)
3417{
3418 Lisp_Object record;
3419 ptrdiff_t size, i;
3420 struct Lisp_Vector *p;
3421
3422 CHECK_NATNUM (slots);
3423
3424 size = XFASTINT (slots) + 1;
3425 p = allocate_record (size);
3426 if (p == NULL)
3427 error ("Attempt to allocate a record of %ld slots; max is %d",
3428 size, (1 << PSEUDOVECTOR_SIZE_BITS) - 1);
3429
3430 p->contents[0] = type;
3431 for (i = 1; i < size; i++)
3432 p->contents[i] = init;
3433
3434 XSETVECTOR (record, p);
3435 return record;
3436}
3437
3438
3439DEFUN ("record", Frecord, Srecord, 1, MANY, 0,
3440 doc: /* Create a new record.
3441TYPE is its type as returned by `type-of'. SLOTS is used to
3442initialize the record slots with shallow copies of the arguments. The
3443number of slots, including the type slot, must fit in
3444PSEUDOVECTOR_SIZE_BITS.
3445usage: (record TYPE &rest SLOTS) */)
3446 (ptrdiff_t nargs, Lisp_Object *args)
3447{
3448 struct Lisp_Vector *p = allocate_record (nargs);
3449 if (p == NULL)
3450 error ("Attempt to allocate a record of %ld slots; max is %d",
3451 nargs, (1 << PSEUDOVECTOR_SIZE_BITS) - 1);
3452
3453 Lisp_Object type = args[0];
3454 Lisp_Object record;
3455
3456 p->contents[0] = type;
3457 memcpy (p->contents + 1, args + 1, (nargs - 1) * sizeof *args);
3458
3459 XSETVECTOR (record, p);
3460 return record;
3461}
3462
3463
3464DEFUN ("copy-record", Fcopy_record, Scopy_record, 1, 1, 0,
3465 doc: /* Return a new record that is a shallow copy of the argument RECORD. */)
3466 (Lisp_Object record)
3467{
3468 CHECK_RECORD (record);
3469 struct Lisp_Vector *src = XVECTOR (record);
3470 ptrdiff_t size = ASIZE (record) & PSEUDOVECTOR_SIZE_MASK;
3471 struct Lisp_Vector *new = allocate_record (size);
3472 if (new == NULL)
3473 error ("Attempt to allocate a record of %ld slots; max is %d",
3474 size, (1 << PSEUDOVECTOR_SIZE_BITS) - 1);
3475
3476 memcpy (&(new->contents[0]), &(src->contents[0]),
3477 size * sizeof (Lisp_Object));
3478 XSETVECTOR (record, new);
3479 return record;
3480}
3481
3482
3395DEFUN ("make-vector", Fmake_vector, Smake_vector, 2, 2, 0, 3483DEFUN ("make-vector", Fmake_vector, Smake_vector, 2, 2, 0,
3396 doc: /* Return a newly created vector of length LENGTH, with each element being INIT. 3484 doc: /* Return a newly created vector of length LENGTH, with each element being INIT.
3397See also the function `vector'. */) 3485See also the function `vector'. */)
@@ -5532,7 +5620,7 @@ purecopy (Lisp_Object obj)
5532 struct Lisp_Hash_Table *h = purecopy_hash_table (table); 5620 struct Lisp_Hash_Table *h = purecopy_hash_table (table);
5533 XSET_HASH_TABLE (obj, h); 5621 XSET_HASH_TABLE (obj, h);
5534 } 5622 }
5535 else if (COMPILEDP (obj) || VECTORP (obj)) 5623 else if (COMPILEDP (obj) || VECTORP (obj) || RECORDP (obj))
5536 { 5624 {
5537 struct Lisp_Vector *objp = XVECTOR (obj); 5625 struct Lisp_Vector *objp = XVECTOR (obj);
5538 ptrdiff_t nbytes = vector_nbytes (objp); 5626 ptrdiff_t nbytes = vector_nbytes (objp);
@@ -7461,10 +7549,13 @@ The time is in seconds as a floating point value. */);
7461 defsubr (&Scons); 7549 defsubr (&Scons);
7462 defsubr (&Slist); 7550 defsubr (&Slist);
7463 defsubr (&Svector); 7551 defsubr (&Svector);
7552 defsubr (&Srecord);
7553 defsubr (&Scopy_record);
7464 defsubr (&Sbool_vector); 7554 defsubr (&Sbool_vector);
7465 defsubr (&Smake_byte_code); 7555 defsubr (&Smake_byte_code);
7466 defsubr (&Smake_list); 7556 defsubr (&Smake_list);
7467 defsubr (&Smake_vector); 7557 defsubr (&Smake_vector);
7558 defsubr (&Smake_record);
7468 defsubr (&Smake_string); 7559 defsubr (&Smake_string);
7469 defsubr (&Smake_bool_vector); 7560 defsubr (&Smake_bool_vector);
7470 defsubr (&Smake_symbol); 7561 defsubr (&Smake_symbol);