From: Lars Brinkhoff <lars@nocrew.org>
To: emacs-devel@gnu.org
Subject: Re: RFC: User-defined pseudovectors
Date: Thu, 10 Oct 2013 13:29:31 +0200 [thread overview]
Message-ID: <85fvs9cqjo.fsf@junk.nocrew.org> (raw)
In-Reply-To: 85k3hlcqvm.fsf@junk.nocrew.org
I wrote:
> With the current FFI discussion, this may be a good time to ask for
> input on a Lisp extension I have lying around.
Here is the patch in its current (unfinished) state. Suggestions are
welcome. Would something like this be useful for inclusion in Emacs?
diff a/src/alloc.c b/src/alloc.c
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -3048,6 +3048,12 @@ allocate_hash_table (void)
return ALLOCATE_PSEUDOVECTOR (struct Lisp_Hash_Table, count, PVEC_HASH_TABLE);
}
+struct Lisp_Vector *
+allocate_typed_pseudovector (int count)
+{
+ return allocate_pseudovector (count, count, PVEC_TYPED_PSEUDOVECTOR);
+}
+
struct window *
allocate_window (void)
{
@@ -3096,6 +3102,30 @@ allocate_process (void)
return p;
}
+DEFUN ("make-typed-pseudovector", Fmake_typed_pseudovector, Smake_typed_pseudovector, 3, 3, 0,
+ doc: /* Create a new vector-like object of type TYPE with SLOTS elements, each initialized to INIT. */)
+ (register Lisp_Object slots, Lisp_Object type, Lisp_Object init)
+{
+ Lisp_Object vector;
+ register ptrdiff_t size;
+ register ptrdiff_t i;
+ register struct Lisp_Vector *p;
+
+ CHECK_NATNUM (slots);
+ if (!SYMBOLP(type))
+ signal_error ("Invalid type; must be symbol", type);
+
+ size = XFASTINT (slots) + 1;
+ p = allocate_typed_pseudovector (size);
+ p->u.contents[0] = type;
+ for (i = 1; i < size; i++)
+ p->u.contents[i] = init;
+
+ XSETVECTOR (vector, p);
+ return vector;
+}
+
+
DEFUN ("make-vector", Fmake_vector, Smake_vector, 2, 2, 0,
doc: /* Return a newly created vector of length LENGTH, with each element being INIT.
See also the function `vector'. */)
@@ -6755,6 +6785,7 @@ The time is in seconds as a floating point value. */);
defsubr (&Smake_byte_code);
defsubr (&Smake_list);
defsubr (&Smake_vector);
+ defsubr (&Smake_typed_pseudovector);
defsubr (&Smake_string);
defsubr (&Smake_bool_vector);
defsubr (&Smake_symbol);
diff a/src/data.c b/src/data.c
--- a/src/data.c
+++ b/src/data.c
@@ -290,6 +290,9 @@ for example, (type-of 1) returns `integer'. */)
return Qfont_entity;
if (FONT_OBJECT_P (object))
return Qfont_object;
+ if (TYPED_PSEUDOVECTOR_P (object))
+ return AREF (object, 0);
+
return Qvector;
case Lisp_Float:
@@ -370,6 +373,15 @@ DEFUN ("vectorp", Fvectorp, Svectorp, 1, 1, 0,
return Qnil;
}
+DEFUN ("typed-pseudovector-p", Ftyped_pseudovector_p, Styped_pseudovector_p, 1, 1, 0,
+ doc: /* Return t if OBJECT is a typed pseudovector. */)
+ (Lisp_Object object)
+{
+ if (TYPED_PSEUDOVECTOR_P (object))
+ return Qt;
+ return Qnil;
+}
+
DEFUN ("stringp", Fstringp, Sstringp, 1, 1, 0,
doc: /* Return t if OBJECT is a string. */)
(Lisp_Object object)
@@ -2146,7 +2158,7 @@ or a byte-code object. IDX starts at 0. */)
ptrdiff_t size = 0;
if (VECTORP (array))
size = ASIZE (array);
- else if (COMPILEDP (array))
+ else if (COMPILEDP (array) || TYPED_PSEUDOVECTOR_P (array))
size = ASIZE (array) & PSEUDOVECTOR_SIZE_MASK;
else
wrong_type_argument (Qarrayp, array);
@@ -2167,7 +2179,8 @@ bool-vector. IDX starts at 0. */)
CHECK_NUMBER (idx);
idxval = XINT (idx);
- CHECK_ARRAY (array, Qarrayp);
+ if (! TYPED_PSEUDOVECTOR_P (array))
+ CHECK_ARRAY (array, Qarrayp);
CHECK_IMPURE (array);
if (VECTORP (array))
@@ -2196,7 +2209,14 @@ bool-vector. IDX starts at 0. */)
CHECK_CHARACTER (idx);
CHAR_TABLE_SET (array, idxval, newelt);
}
- else
+ else if (TYPED_PSEUDOVECTOR_P (array))
+ {
+ ptrdiff_t size = ASIZE (array) & PSEUDOVECTOR_SIZE_MASK;
+ if (idxval < 0 || idxval >= size)
+ args_out_of_range (array, idx);
+ ASET (array, idxval, newelt);
+ }
+ else /* STRINGP */
{
int c;
@@ -3506,6 +3526,7 @@ syms_of_data (void)
defsubr (&Sstringp);
defsubr (&Smultibyte_string_p);
defsubr (&Svectorp);
+ defsubr (&Styped_pseudovector_p);
defsubr (&Schar_table_p);
defsubr (&Svector_or_char_table_p);
defsubr (&Sbool_vector_p);
diff a/src/fns.c b/src/fns.c
--- a/src/fns.c
+++ b/src/fns.c
@@ -115,7 +115,7 @@ To get the number of bytes, use `string-bytes'. */)
XSETFASTINT (val, MAX_CHAR);
else if (BOOL_VECTOR_P (sequence))
XSETFASTINT (val, XBOOL_VECTOR (sequence)->size);
- else if (COMPILEDP (sequence))
+ else if (COMPILEDP (sequence) || TYPED_PSEUDOVECTOR_P (sequence))
XSETFASTINT (val, ASIZE (sequence) & PSEUDOVECTOR_SIZE_MASK);
else if (CONSP (sequence))
{
diff a/src/lisp.h b/src/lisp.h
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -538,6 +538,7 @@ enum pvec_type
PVEC_TERMINAL,
PVEC_WINDOW_CONFIGURATION,
PVEC_SUBR,
+ PVEC_TYPED_PSEUDOVECTOR,
PVEC_OTHER,
/* These should be last, check internal_equal to see why. */
PVEC_COMPILED,
@@ -2328,6 +2329,12 @@ FRAMEP (Lisp_Object a)
return PSEUDOVECTORP (a, PVEC_FRAME);
}
+INLINE bool
+TYPED_PSEUDOVECTOR_P (Lisp_Object a)
+{
+ return PSEUDOVECTORP (a, PVEC_TYPED_PSEUDOVECTOR);
+}
+
/* Test for image (image . spec) */
INLINE bool
IMAGEP (Lisp_Object x)
diff a/src/lread.c b/src/lread.c
--- a/src/lread.c
+++ b/src/lread.c
@@ -2603,6 +2603,19 @@ read1 (Lisp_Object readcharfun, int *pch, bool first_in_list)
make_byte_code (vec);
return tmp;
}
+ if (c == '%')
+ {
+ c = READCHAR;
+ if (c == '[')
+ {
+ Lisp_Object tmp;
+ tmp = read_vector (readcharfun, 1);
+ XSETPVECTYPE (XVECTOR(tmp), PVEC_TYPED_PSEUDOVECTOR);
+ return tmp;
+ }
+ UNREAD (c);
+ invalid_syntax ("#");
+ }
if (c == '(')
{
Lisp_Object tmp;
diff a/src/print.c b/src/print.c
--- a/src/print.c
+++ b/src/print.c
@@ -1945,6 +1945,12 @@ print_object (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag)
PRINTCHAR ('#');
size &= PSEUDOVECTOR_SIZE_MASK;
}
+ if (TYPED_PSEUDOVECTOR_P (obj))
+ {
+ PRINTCHAR ('#');
+ PRINTCHAR ('%');
+ size &= PSEUDOVECTOR_SIZE_MASK;
+ }
if (CHAR_TABLE_P (obj) || SUB_CHAR_TABLE_P (obj))
{
/* We print a char-table as if it were a vector,
next prev parent reply other threads:[~2013-10-10 11:29 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-10-10 11:22 RFC: User-defined pseudovectors Lars Brinkhoff
2013-10-10 11:29 ` Lars Brinkhoff [this message]
2013-10-10 11:40 ` Lars Brinkhoff
2013-10-10 12:52 ` Dmitry Antipov
2013-10-10 13:41 ` Dmitry Antipov
2013-10-10 16:40 ` Lars Brinkhoff
2013-10-10 14:00 ` Stefan Monnier
2013-10-10 16:30 ` Lars Brinkhoff
2013-10-10 20:42 ` Stefan Monnier
2013-10-11 6:00 ` Lars Brinkhoff
2013-10-11 12:22 ` Stefan Monnier
2013-10-12 16:01 ` User-defined record types Lars Brinkhoff
2013-10-12 18:58 ` Stefan Monnier
2013-10-18 13:39 ` Ted Zlatanov
2013-10-18 15:28 ` Stefan Monnier
2013-10-18 23:24 ` Ted Zlatanov
2013-10-19 2:09 ` Stefan Monnier
2013-10-19 2:30 ` Drew Adams
2013-10-19 11:48 ` Ted Zlatanov
2013-10-19 14:37 ` Stefan Monnier
2013-10-19 20:11 ` Ted Zlatanov
2013-10-19 21:48 ` Stefan Monnier
2013-10-10 20:43 ` RFC: User-defined pseudovectors Stefan Monnier
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=85fvs9cqjo.fsf@junk.nocrew.org \
--to=lars@nocrew.org \
--cc=emacs-devel@gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this external index
https://git.savannah.gnu.org/cgit/emacs.git
https://git.savannah.gnu.org/cgit/emacs/org-mode.git
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.