Feeds are conduits for arbitrary text to flow into the lexer, and to be converted into wordings.
§1. Feed sessions. Each feed has a unique ID. At present only one is ever open at a time, but we don't want to assume that.
define feed_t int (not a typedef only because it makes trouble for inweb)
§2. There are two ways to make a feed. One is simply to call one of the feed_text routines below and use its output. The other is for a multi-stage process, that is, for when multiple pieces of text need to go into the same feed: to start such, call Feeds::begin and get an ID; to end, call Feeds::end with the corresponding ID back again.
feed_t Feeds::begin(void) { return (feed_t) lexer_wordcount; } wording Feeds::end(feed_t id) { return Wordings::new((int) id, lexer_wordcount-1); }
§3. Feeding a feed. Some variations on a theme:
wording Feeds::feed_C_string(inchar32_t *text) { return Feeds::feed_C_string_full(text, FALSE, NULL, FALSE); } wording Feeds::feed_text(text_stream *text) { return Feeds::feed_text_full(text, FALSE, NULL); } wording Feeds::feed_C_string_expanding_strings(inchar32_t *text) { return Feeds::feed_C_string_full(text, TRUE, NULL, FALSE); } wording Feeds::feed_text_expanding_strings(text_stream *text) { return Feeds::feed_text_full(text, TRUE, NULL); } wording Feeds::feed_text_punctuated(text_stream *text, inchar32_t *pmarks) { wording W = Feeds::feed_text_full(text, FALSE, pmarks); return W; }
§4. ...all of which result in calls to these two, which are really the same function, written two ways:
wording Feeds::feed_C_string_full(inchar32_t *text, int expand, inchar32_t *nonstandard, int break_at_slashes) { Set up the lexer4.1; lexer_break_at_slashes = break_at_slashes; for (int i=0; text[i] != 0; i++) { inchar32_t last_cr, cr, next_cr; if (i > 0) last_cr = text[i-1]; else last_cr = CH32EOF; cr = text[i]; if (cr != 0) next_cr = text[i+1]; else next_cr = CH32EOF; Lexer::feed_triplet(last_cr, cr, next_cr); } Extract results from the lexer4.2; } wording Feeds::feed_text_full(text_stream *text, int expand, inchar32_t *nonstandard) { Set up the lexer4.1; for (int i=0, L=Str::len(text); i<L; i++) { inchar32_t last_cr, cr, next_cr; if (i > 0) last_cr = Str::get_at(text, i-1); else last_cr = CH32EOF; cr = Str::get_at(text, i); if (cr != 0) next_cr = Str::get_at(text, i+1); else next_cr = CH32EOF; Lexer::feed_triplet(last_cr, cr, next_cr); } Extract results from the lexer4.2; }
Lexer::feed_begins(Lexer::as_if_from_nowhere()); lexer_divide_strings_at_text_substitutions = expand; lexer_allow_I6_escapes = TRUE; if (nonstandard) { lexer_punctuation_marks = nonstandard; lexer_allow_I6_escapes = FALSE; } else lexer_punctuation_marks = STANDARD_PUNCTUATION_MARKS;
- This code is used in §4 (twice).
§4.2. Extract results from the lexer4.2 =
wording LEXW = Lexer::feed_ends(FALSE, NULL); Vocabulary::identify_word_range(LEXW); return LEXW;
- This code is used in §4 (twice).
§5. If we want to feed a wording, we could do that by printing it out to a text stream, then feeding this text; but that would be slow and rather circular, and would also lose the origin. Much quicker is to splice, and then there's no need for a feed at all:
wording Feeds::feed_wording(wording W) { return Lexer::splice_words(W); }