unofficial mirror of guile-devel@gnu.org 
 help / color / mirror / Atom feed
* Scheme-defined smobs
@ 2003-11-03 17:39 Paul Jarc
  2003-11-03 23:58 ` Rob Browning
  2003-11-05 17:13 ` Marius Vollmer
  0 siblings, 2 replies; 6+ messages in thread
From: Paul Jarc @ 2003-11-03 17:39 UTC (permalink / raw)


[-- Attachment #1: Type: TEXT/PLAIN, Size: 1027 bytes --]

It seems pointless at first, but I think it might be useful.  The
attached file (tested as an extension with 1.6.4) provides Scheme
bindings for defining smobs - i.e., the "print" and "equalp" functions
can be defined in Scheme.  This might be useful for adding
user-defined cases to equal?.  But I admit my real motivation for
writing this was to enable this gruesome hack:

guile> (define (printer smob-data port state) (system smob-data))
guile> (define generator (make-smob-type "smob-name" printer #f))
guile> (define ls (generator "ls"))
guile> (ls)
"ls"
guile> (ls "ls -a")
guile> (ls)
"ls -a"
guile> ls

... which shows me the output of "ls -a".  So I can use Guile as a
shell with a bit less typing.

Is there interest in adding this to libguile?  (Regardless, I think
the three snarfing macros at the top (along with corresponding
SCM_SMOB_FREE, SCM_SMOB_PRINT, and SCM_SMOB_EQUALP) would be useful
additions to smob.h, though perhaps the name SCM_ SMOB_APPLY is too
similar to the existing SCM_SMOB_APPLY_*.)


paul

[-- Attachment #2: dynsmob.c --]
[-- Type: TEXT/PLAIN, Size: 3096 bytes --]

#include <libguile.h>

#define SCM_SMOB(c_name, scheme_name, size) \
  SCM_SNARF_HERE(static scm_t_bits scm_##c_name##_tag) \
  SCM_SNARF_INIT(scm_##c_name##_tag=scm_make_smob_type((scheme_name), size);)
#define SCM_SMOB_MARK(c_name, arg) \
  SCM_SNARF_HERE(static SCM scm_##c_name##_mark(SCM arg)) \
  SCM_SNARF_INIT(scm_set_smob_mark(scm_##c_name##_tag, scm_##c_name##_mark);)
#define SCM_SMOB_APPLY(c_name, args, req, opt, rest) \
  SCM_SNARF_HERE(static SCM scm_##c_name##_apply args) \
  SCM_SNARF_INIT(scm_set_smob_apply(scm_##c_name##_tag, scm_##c_name##_apply, \
                                    req, opt, rest);)

/* define one static smob, to be used as a generator */

SCM_SMOB(dynsmob_static, "dynsmob", 0);

SCM_SMOB_MARK(dynsmob_static, s_smob)
{
  scm_gc_mark(SCM_CELL_OBJECT_2(s_smob));
  return SCM_CELL_OBJECT_3(s_smob);
}

SCM_SMOB_APPLY(dynsmob_static, (SCM s_smob, SCM s_data), 1, 0, 0)
{
  SCM_RETURN_NEWSMOB2(SCM_CELL_WORD_1(s_smob), s_smob, SCM_UNPACK(s_data));
}

/* these are for Scheme-defined smobs */

static SCM mark_dynsmob(SCM s_smob) {
  SCM const s_type=SCM_CELL_OBJECT_1(s_smob);
  SCM const s_data=SCM_CELL_OBJECT_2(s_smob);
  scm_gc_mark(s_type);
  return s_data;
}

static int print_dynsmob(SCM s_smob, SCM s_port, scm_print_state* pstate) {
  SCM const s_type   =SCM_CELL_OBJECT_1(s_smob);
  SCM const s_printer=SCM_CELL_OBJECT_2(s_type);
  SCM const s_data   =SCM_CELL_OBJECT_2(s_smob);
  (void)pstate; /* silence "unused parameter" warning */
  scm_call_3(s_printer, s_data, s_port, SCM_UNSPECIFIED/*pstate*/);
  return 1;
}

static SCM equalp_dynsmob(SCM s_smob1, SCM s_smob2) {
  SCM const s_type  =SCM_CELL_OBJECT_1(s_smob1);
  SCM const s_equalp=SCM_CELL_OBJECT_3(s_type);
  SCM const s_data1 =SCM_CELL_OBJECT_2(s_smob1);
  SCM const s_data2 =SCM_CELL_OBJECT_2(s_smob2);
  return scm_call_2(s_equalp, s_data1, s_data2);
}

static SCM apply_dynsmob(SCM s_smob, SCM s_newdata) {
  if (SCM_UNBNDP(s_newdata)) {
    SCM const s_data=SCM_CELL_OBJECT_2(s_smob);
    return s_data;
  }
  SCM_SET_CELL_OBJECT_2(s_smob, s_newdata);
  return SCM_UNSPECIFIED;
}

#define FUNC_NAME s_scm_dynsmob_make_smob_type
SCM_DEFINE(scm_dynsmob_make_smob_type, "make-smob-type", 3, 0, 0,
           (SCM s_name, SCM s_printer, SCM s_equalp),
           "Define a new smob type and return a generator for it.")
{
  scm_t_bits tag;
  SCM_VALIDATE_STRING(SCM_ARG1, s_name);
  if (!SCM_FALSEP(s_printer)) SCM_VALIDATE_PROC(SCM_ARG2, s_printer);
  if (!SCM_FALSEP(s_equalp )) SCM_VALIDATE_PROC(SCM_ARG3, s_equalp);
  SCM_STRING_COERCE_0TERMINATION_X(s_name);
  tag=scm_make_smob_type(SCM_STRING_CHARS(s_name), 0);
  scm_set_smob_mark(tag, mark_dynsmob);
  if (!SCM_FALSEP(s_printer)) scm_set_smob_print (tag, print_dynsmob);
  if (!SCM_FALSEP(s_equalp )) scm_set_smob_equalp(tag, equalp_dynsmob);
  scm_set_smob_apply(tag, apply_dynsmob, 0, 1, 0);
  SCM_RETURN_NEWSMOB3(scm_dynsmob_static_tag, tag, SCM_UNPACK(s_printer),
                      SCM_UNPACK(s_equalp));
}
#undef FUNC_NAME

void dynsmob__load__init(void) {
#ifndef SCM_MAGIC_SNARFER
#include "dynsmob.x"
#endif
}

[-- Attachment #3: Type: text/plain, Size: 142 bytes --]

_______________________________________________
Guile-devel mailing list
Guile-devel@gnu.org
http://mail.gnu.org/mailman/listinfo/guile-devel

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Scheme-defined smobs
  2003-11-03 17:39 Scheme-defined smobs Paul Jarc
@ 2003-11-03 23:58 ` Rob Browning
  2003-11-04  0:16   ` Paul Jarc
  2003-11-05 17:13 ` Marius Vollmer
  1 sibling, 1 reply; 6+ messages in thread
From: Rob Browning @ 2003-11-03 23:58 UTC (permalink / raw)


prj@po.cwru.edu (Paul Jarc) writes:

> ... which shows me the output of "ls -a".  So I can use Guile as a
> shell with a bit less typing.

Wow, that's really scary.

An alternative might be to define your own repl that allows you do
define items that should be handled specially, and pass everything
else to a normal eval, i.e. very roughly:

  (let ((next (read)))
    (if (special-value? next)
        (lookup-and-do-special-thing-for next)
        (print (eval next (current-module)))))

and then have a little function that lets you register the special
symbols.

-- 
Rob Browning
rlb @defaultvalue.org and @debian.org; previously @cs.utexas.edu
GPG starting 2002-11-03 = 14DD 432F AE39 534D B592  F9A0 25C8 D377 8C7E 73A4


_______________________________________________
Guile-devel mailing list
Guile-devel@gnu.org
http://mail.gnu.org/mailman/listinfo/guile-devel


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Scheme-defined smobs
  2003-11-03 23:58 ` Rob Browning
@ 2003-11-04  0:16   ` Paul Jarc
  0 siblings, 0 replies; 6+ messages in thread
From: Paul Jarc @ 2003-11-04  0:16 UTC (permalink / raw)
  Cc: guile-devel

Rob Browning <rlb@defaultvalue.org> wrote:
> prj@po.cwru.edu (Paul Jarc) writes:
>> ... which shows me the output of "ls -a".  So I can use Guile as a
>> shell with a bit less typing.
>
> Wow, that's really scary.

Quite.  I do not claim that this was a good way to reach this goal.
It was just fun to do, and I can imagine that it might be genuinely
useful for other things, mostly for the user-defined equal?-ness.

Side note: my make-smob-type subr returns an applicable instance of a
statically-defined smob, because I didn't know how to create a lambda
in C, except in the top-level environment.  Is there a way to do it
that would follow scope rules as if the lambda appeared in the
surrounding Scheme code?  I suppose it shouldn't need to look up
anything in surrounding local scopes anyway, though.

>   (let ((next (read)))
>     (if (special-value? next)
>         (lookup-and-do-special-thing-for next)
>         (print (eval next (current-module)))))

That would certainly be cleaner.  What would probably be more useful,
though, is some kind of read syntax, so I could say "ls -a", with the
space, and have it all read as one line, and constructed into the
appropriate Scheme code.  Then, of course, I'd want to have some way
to pre-seed the readline buffer with the read-syntax prefix, so I
wouldn't have to type it manually. :)


paul


_______________________________________________
Guile-devel mailing list
Guile-devel@gnu.org
http://mail.gnu.org/mailman/listinfo/guile-devel


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Scheme-defined smobs
  2003-11-03 17:39 Scheme-defined smobs Paul Jarc
  2003-11-03 23:58 ` Rob Browning
@ 2003-11-05 17:13 ` Marius Vollmer
  2003-11-06 16:25   ` Paul Jarc
  1 sibling, 1 reply; 6+ messages in thread
From: Marius Vollmer @ 2003-11-05 17:13 UTC (permalink / raw)


prj@po.cwru.edu (Paul Jarc) writes:

> Is there interest in adding this to libguile?

I hope not... ;-)

New data types in Scheme should be created with GOOPS.  Is there
something missing in GOOPS that keeps you from implementing this with
define-class, etc?

-- 
GPG: D5D4E405 - 2F9B BCCC 8527 692A 04E3  331E FAF8 226A D5D4 E405


_______________________________________________
Guile-devel mailing list
Guile-devel@gnu.org
http://mail.gnu.org/mailman/listinfo/guile-devel


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Scheme-defined smobs
  2003-11-05 17:13 ` Marius Vollmer
@ 2003-11-06 16:25   ` Paul Jarc
  2003-11-13 19:24     ` Marius Vollmer
  0 siblings, 1 reply; 6+ messages in thread
From: Paul Jarc @ 2003-11-06 16:25 UTC (permalink / raw)
  Cc: guile-devel

Marius Vollmer <mvo@zagadka.de> wrote:
> New data types in Scheme should be created with GOOPS.  Is there
> something missing in GOOPS that keeps you from implementing this with
> define-class, etc?

Ah - only that I wasn't familiar with GOOPS.

How about these snarfing macros, though?

	* snarf.h (SCM_SMOB, SCM_GLOBAL_SMOB, SCM_SMOB_MARK,
	SCM_GLOBAL_SMOB_MARK, SCM_SMOB_FREE, SCM_GLOBAL_SMOB_FREE,
	SCM_SMOB_PRINT, SCM_GLOBAL_SMOB_PRINT, SCM_SMOB_EQUALP,
	SCM_GLOBAL_SMOB_EQUALP, SCM_SMOB_APPLY,
	SCM_GLOBAL_SMOB_APPLY): New macros.

Index: guile-core/libguile/snarf.h
===================================================================
RCS file: /cvsroot/guile/guile/guile-core/libguile/snarf.h,v
retrieving revision 1.61
diff -u -r1.61 snarf.h
--- guile-core/libguile/snarf.h	5 Apr 2003 19:10:22 -0000	1.61
+++ guile-core/libguile/snarf.h	6 Nov 2003 16:12:02 -0000
@@ -221,6 +221,54 @@
 SCM_SNARF_HERE(scm_t_rec_mutex c_name) \
 SCM_SNARF_INIT(scm_i_plugin_rec_mutex_init (&c_name, &scm_i_plugin_rec_mutex))
 
+#define SCM_SMOB(tag, scheme_name, size) \
+SCM_SNARF_HERE(static scm_t_bits tag) \
+SCM_SNARF_INIT((tag)=scm_make_smob_type((scheme_name), (size));)
+
+#define SCM_GLOBAL_SMOB(tag, scheme_name, size) \
+SCM_SNARF_HERE(scm_t_bits tag) \
+SCM_SNARF_INIT((tag)=scm_make_smob_type((scheme_name), (size));)
+
+#define SCM_SMOB_MARK(tag, c_name, arg) \
+SCM_SNARF_HERE(static SCM c_name(SCM arg)) \
+SCM_SNARF_INIT(scm_set_smob_mark((tag), (c_name));)
+
+#define SCM_GLOBAL_SMOB_MARK(tag, c_name, arg) \
+SCM_SNARF_HERE(SCM c_name(SCM arg)) \
+SCM_SNARF_INIT(scm_set_smob_mark((tag), (c_name));)
+
+#define SCM_SMOB_FREE(tag, c_name, arg) \
+SCM_SNARF_HERE(static size_t c_name(SCM arg)) \
+SCM_SNARF_INIT(scm_set_smob_free((tag), (c_name));)
+
+#define SCM_GLOBAL_SMOB_FREE(tag, c_name, arg) \
+SCM_SNARF_HERE(size_t c_name(SCM arg)) \
+SCM_SNARF_INIT(scm_set_smob_free((tag), (c_name));)
+
+#define SCM_SMOB_PRINT(tag, c_name, obj, port, pstate) \
+SCM_SNARF_HERE(static int c_name(SCM obj, SCM port, scm_print_state* pstate)) \
+SCM_SNARF_INIT(scm_set_smob_print((tag), (c_name));)
+
+#define SCM_GLOBAL_SMOB_PRINT(tag, c_name, obj, port, pstate) \
+SCM_SNARF_HERE(int c_name(SCM obj, SCM port, scm_print_state* pstate)) \
+SCM_SNARF_INIT(scm_set_smob_print((tag), (c_name));)
+
+#define SCM_SMOB_EQUALP(tag, c_name, obj1, obj2) \
+SCM_SNARF_HERE(static SCM c_name(SCM obj1, SCM obj2)) \
+SCM_SNARF_INIT(scm_set_smob_equalp((tag), (c_name));)
+
+#define SCM_GLOBAL_SMOB_EQUALP(tag, c_name, obj1, obj2) \
+SCM_SNARF_HERE(SCM c_name(SCM obj1, SCM obj2)) \
+SCM_SNARF_INIT(scm_set_smob_equalp((tag), (c_name));)
+
+#define SCM_SMOB_APPLY(tag, c_name, req, opt, rest, arglist) \
+SCM_SNARF_HERE(static SCM c_name arglist) \
+SCM_SNARF_INIT(scm_set_smob_apply((tag), (c_name), (req), (opt), (rest));)
+
+#define SCM_GLOBAL_SMOB_APPLY(tag, c_name, req, opt, rest, arglist) \
+SCM_SNARF_HERE(SCM c_name arglist) \
+SCM_SNARF_INIT(scm_set_smob_apply((tag), (c_name), (req), (opt), (rest));)
+
 #ifdef SCM_MAGIC_SNARF_DOCS
 #undef SCM_ASSERT
 #define SCM_ASSERT(_cond, _arg, _pos, _subr) ^^ argpos _arg _pos __LINE__ ^^


paul


_______________________________________________
Guile-devel mailing list
Guile-devel@gnu.org
http://mail.gnu.org/mailman/listinfo/guile-devel


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Scheme-defined smobs
  2003-11-06 16:25   ` Paul Jarc
@ 2003-11-13 19:24     ` Marius Vollmer
  0 siblings, 0 replies; 6+ messages in thread
From: Marius Vollmer @ 2003-11-13 19:24 UTC (permalink / raw)


prj@po.cwru.edu (Paul Jarc) writes:

> How about these snarfing macros, though?

Can't hurt.  I'll add them.  Thanks!

-- 
GPG: D5D4E405 - 2F9B BCCC 8527 692A 04E3  331E FAF8 226A D5D4 E405


_______________________________________________
Guile-devel mailing list
Guile-devel@gnu.org
http://mail.gnu.org/mailman/listinfo/guile-devel


^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2003-11-13 19:24 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2003-11-03 17:39 Scheme-defined smobs Paul Jarc
2003-11-03 23:58 ` Rob Browning
2003-11-04  0:16   ` Paul Jarc
2003-11-05 17:13 ` Marius Vollmer
2003-11-06 16:25   ` Paul Jarc
2003-11-13 19:24     ` Marius Vollmer

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).