[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Request to abstract write operations to stdout and stderr in jitter

From: Mohammad-Reza Nabipoor
Subject: Re: Request to abstract write operations to stdout and stderr in jitter
Date: Thu, 12 Nov 2020 23:17:33 +0330

Hi, Luca.

On Thu, Nov 12, 2020 at 12:58:48PM +0100, Luca Saiu wrote:
> Hello Mohammad.
> On 2020-11-12 at 11:07 +0330, Mohammad-Reza Nabipoor wrote:
> > What about a callback printer:
> >
> > ```c
> > jitter_print_context ctx = jitter_print_context_make_callback (clbk, 
> > clbkdata);
> > ```
> >
> > Every time jitter wants to print something, the callback `clbk` gets called.
> > For example, after calling `jitter_print_int (ctx, 10, 0)`, the `clbk` will
> > be called like this:
> >
> > ```c
> > clbk(JITTER_PRINT_TOKEN_INT, "10", clbkdata);
> > ```
> > [...]
> I am not fond of this specific API, the reason being that in practice it
> is not mandatory to print by specifying a token name (actually class or
> URL).
> Think for example of JitterLisp, which should be a typical use case:
> JitterLisp is an interactive Lisp system, distributed along with Jitter
> as an advanced example.  Even if JitterLisp has a few interesting ideas
> from the point of view of output it is very ordinary: it will print a
> large amount of ordinary text (banners, prompts, warning, time
> measurements, maybe in the future interactive help, lone newline
> characters, "Goodbye" at the end), some Lisp objects (for example when
> showing the result of an expression typed by the user at the REPL), and
> occasionally also VM routines and disassemblies.  Once the transition is
> over the entire output of JitterLisp will be printed out through print
> contexts.
> What I want to stress is that a large part of the output is *not*
> explicitly styled, and I believe that should remain the case.

I just wnated to push all the burden to the user, and keep jitter as
simple and unaware of styling stuff.  Jitter can define "big token" (e.g.,
_TEXT (whitespace, string, number)) to make things simpler.
But this was just an example.

> However your example raises an important point that I will deal with: a
> user-specified function should have access to the current class and URL.
> This is currently not the case but the feature would be useful, and easy
> to support in a clean way.  Already at the present time any Jitter print
> context internally keeps track of the current class (maintaining its own
> stack of nested class activations) and URL.  Apart from the fact that
> either can be NULL at any point during printing, user functions should
> have access to this information, as in your example.
> What I am planning in practice is simply to add parameters (and possibly
> to require a longer lifetime from user-supplied URL data compared to
> what the comments are saying now; but I might also copy strings into my
> own memory) to the functions supplied by the user within struct
> jitter_print_context_kind_private , which is similar to poke's struct
> pk_term_if .  Predefined functions intended for the user to call such as
> jitter_print_int or jitter_print_char_star would call user-supplied
> functions passing these new parameters as well.
> You have convinced me about this, and I will tentatively implement this
> change in the branch.  Of course a user will always be able to ignore
> any parameter she is not interested in, in her own functions.  No
> particular action is needed for ensuring that those parameters have the
> right values, other than correctly nesting calls to
> jitter_print_begin_class , jitter_print_end_class ,
> jitter_print_begin_hyperlink , jitter_print_end_hyperlink .


> Now a question for you.  Would it be useful to add, in addition to
> classes and URLs, other user-specified data, which might nest in a stack
> fashion like classes do?  This can be done, again, with the caveat that
> not all text will always be decorated -- some user code, such as a Poke
> object printer, may tirelessly style and annotate every single character
> in the output, but even that might break once the Poke object printer
> prints, for example, a closure containing PVM code: if you call a VM
> routine printer you pass control to my functions, which may leave holes
> in the otherwise uninterrupted sequence of metadata you desire.
> I would also add functions to inquire, giving a print context, about the
> current class and URL -- and user data as well, if added.  Those
> function would be callable by the user at any time when a print context
> exists.
> In fact it would be possible, if the user could choose multiple data
> kinds of her own (with user-specified nestability: for example classes
> are nestable, URLs are not), to have classes and URLs just implemented
> as instances of user data, possibly predefined.  Let us call all of
> those decorations just "metadata".
> What do you think?  Now for the first time since starting this task I am
> having a definite impression of a "good design", instead of the
> instinctive dislike I feel for a trivial wrapper.  Each metadata kind
> would nest, or not be allowed to nest, independently from the others.
> Libtextstyle classes and URLs would fit this design.  Your token
> enumerate would fit.  Indentation would fit as well.

Can you explain "metadata" further?
Do you mean adding new entries to the `struct 


struct jitter_print_context_kind_private
  /* ... */
  int (* indent) (jitter_print_context_data d);
  int (* unindent) (jitter_print_context_data d);
  /* ... */

To increase the indentation level?

Or, something for tokens?

struct jitter_print_context_kind_private
  /* ... */
  int (* token) (jitter_print_context_data d, enum jitter_print_token tk);
  /* ... */

Can you give some concrete examples (code snippets)?


reply via email to

[Prev in Thread] Current Thread [Next in Thread]