[sicsh-develop] Syntax hooks
Status: Alpha
Brought to you by:
gvv
|
From: Gary V. V. <ga...@or...> - 2000-04-08 20:15:28
|
On Thu, Apr 06, 2000 at 12:54:02PM -0400, Ezra Peisach wrote:
>
> We need a way to say - recognize, but don't execute. The same with
> $(eval).
I wonder whether we also need to provide hooks at various points in
the code between building the input buffer and passing parts of the
Tokens* array into the evaluator...
A cleaner way to implement `$' substitution would be let the dollar
module register a hook function after tokenisation that rewrites any
token that begins with a `$'. The module would still need to provide
a syntax handler to keep all of $(foo bar baz) in a single token (or
maybe just a flag like we do for strings?).
The only sane way I can think of to implement globbing is to register
a hook function that rewrites the buffer contents with any glob
expansions done. In this case the function would need to be called
before the syntax pass in tokenize().
I haven't tried this... just playing for the moment:
typedef struct init_hook {
struct init_hook *next;
int (*func) (BufferIn *pin);
} Init_Hook;
typedef struct syntax_hook {
struct syntax_hook *next;
int (*func) (BufferOut *pout);
} Syntax_Hook;
typedef struct tokenize_hook {
struct tokenize_hook *next;
int (*func) (Tokens **ptokens);
} Tokenize_Hook;
typedef struct sic {
char *result; /* result string */
size_t len; /* bytes used by result field */
size_t lim; /* bytes allocated to result field */
struct builtintab *builtins; /* tables of builtin functions */
SyntaxTable **syntax; /* dispatch table for syntax of input */
List *syntax_init; /* stack of syntax state initialisers */
List *syntax_finish; /* stack of syntax state cleanup funcs */
List *init_hooks; /* pre-syntax hook functions */
List *syntax_hooks; /* post-syntax hook functions */
List *tokenize_hooks; /* post-tokenization hook functions */
SicState *state; /* state data from syntax extensions */
} Sic;
int
tokenize (sic, ptokens, pcommand)
Sic *sic;
Tokens **ptokens;
char **pcommand;
{
BufferIn in;
BufferOut out;
List *head;
int status = SIC_CONTINUE;
SIC_ASSERT (sic->syntax);
bufferin_init (&in, *pcommand);
bufferout_init (&out, in.buf.lim);
/* Run any registered pre-syntax pass hooks. */
for (head = (List *) sic->init_hooks; head; head = head->next)
if ((*((Init_Hook *) head)->func) (&in) != SIC_OKAY)
break;
/* Perform any user initialisation for syntax readers. */
for (head = sic->syntax_init; head; head = head->next)
(*(SyntaxInit *) head->userdata) (sic);
/* Dispatch to handlers by syntax class of character, or
simply copy from input to output by default. */
while (status == SIC_CONTINUE)
{
SyntaxHandler *handler = syntax_handler (sic, in.buf.start[in.buf.i]);
if (handler)
status = (*handler) (sic, &in, &out);
else
bufferout_append (&out, in.buf.start + in.buf.i++, 1);
}
/* Perform any client finalisation for syntax reader. */
for (head = sic->syntax_finish; head; head = head->next)
(*(SyntaxFinish *) head->userdata) (sic, &in, &out);
/* Run any registered post-syntax pass hooks. */
for (head = (List *) sic->syntax_hooks; head; head = head->next)
if ((*((Syntax_Hook *) head)->func) (&out) != SIC_OKAY)
break;
{
/* Can't fill ARGV on the fly incase BUF moved during realloc. */
Tokens *tokens = XMALLOC (Tokens, 1);
tokens->argv = XMALLOC (char *, 1+ out.offc);
for (tokens->argc = 0; tokens->argc < out.offc; ++tokens->argc)
tokens->argv[tokens->argc] = out.buf.start + out.offv[tokens->argc];
tokens->argv[tokens->argc] = NULL;
tokens->lim = out.buf.lim;
if (!*tokens->argv)
XFREE(out.buf.start);
XFREE (out.offv);
*pcommand += in.buf.i;
*ptokens = tokens;
}
/* Run any registered post-tokenisation pass hooks. */
for (head = (List *) sic->tokenize_hooks; head; head = head->next)
if ((*((Tokenize_Hook *) head)->func) (ptokens) != SIC_OKAY)
break;
return status;
}
Thoughts?
Cheers,
Gary.
--
___ _ ___ __ _ mailto:ga...@or...
/ __|__ _ _ ___ _| | / / | / /_ _ _ _ __ _| |_ __ _ ___ ga...@gn...
| (_ / _` | '_|// / |/ /| |/ / _` | || / _` | ' \/ _` | _ \
\___\__,_|_|\_, /|___(_)___/\__,_|\_,_\__, |_||_\__,_|//_/
home page: /___/ /___/ gpg public key:
http://www.oranda.demon.co.uk http://www.oranda.demon.co.uk/key.asc
|