[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 |