X-Git-Url: https://jxself.org/git/?p=muddle.git;a=blobdiff_plain;f=stdlib%2Fparser%2Fparse.mud;fp=stdlib%2Fparser%2Fparse.mud;h=6268d7d382b019c63922de58d37df51fcdcd8070;hp=0000000000000000000000000000000000000000;hb=da54afbd677beaaf96bb019858502d77b182ddd4;hpb=27dda0374b2e9375d12589345b9117b40d9f312f diff --git a/stdlib/parser/parse.mud b/stdlib/parser/parse.mud new file mode 100644 index 0000000..6268d7d --- /dev/null +++ b/stdlib/parser/parse.mud @@ -0,0 +1,322 @@ +;"Copyright (C) 2018 Keziah Wesley + +You can redistribute and/or modify this file under the terms of the +GNU Affero General Public License as published by the Free Software +Foundation, either version 3 of the License, or (at your option) any +later version. + +This file is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public +License along with this file. If not, see +." + + + + + +parse!- +PARSE-TABLE!- + +DEFAULT-TABLE!-PARSER + +read-all!-PARSER + +% )> <>> + +;"Operation: + Input string is provided to parser. Parser consumes from input and updates state. + Beginning and end of input will be treated as token boundaries. + Parser will return producing a value after reading 1 complete expression + (possibly leaving some input leftover)." + +;"If PARSE receives a partial input, it emits an ERROR. READ installs a + handler for the ERROR INTERRUPT that attempts to get more data and + ERRET." + + +> +> > >> +>> > + <3 .x>)> +>> >>> +>>> +)) + + >> )> + .c> +;"TODO: eliminate this and rely on peeking" + <1 >>> 1>>)> + >>> + +> )> + > + > + ) + (ELSE .t .c .s .a>)>> + +;"BLOCK is documented as modifying the value of .OBLIST, so I'm + assuming passing a lookup param to READ has a similar effect rather + than setting an internal variable." + +>> + +> + > ) + (ELSE > + ) (ELSE .res)>)>>>> + +;"Don't try to READ in objects of these types." + + +;"TODO: set appropriate ERROR as closer's EVALTYPE." + +>> +>> +>> + >) (ELSE )>> + +;"Create the appropriate ERROR if there's a brace mismatch." +;"Otherwise do nothing. Return value is ignored." + + .closers>) + ;"TODO: position info" + (ELSE + EXPECTED + FOUND >)>)>) + (<==? .c EOF> .pos>)>> + +;"TODO: accept radix in PARSE" + + +;"Create a standard Muddle CHARTABLE." +)) + >> ;"HT" + >> ;"LF" + >> ;"VT" + >> ;"FF" + >> ;"CR" + >> ;"space" + <> >>> + T >>> + > <> > SEGMENT>>> + > T > SEGMENT>>> + T >>> + T >> + T > > )> + >>> + T )) .type>>> + > T >> + <> >> + + T )) + > CHARACTER>>) + ( CHARACTER>>) + (<==? .c %> ) + (<==? .c 10> >) + (ELSE >)>>>>> + + ;"TODO: macros for reducing the redundancy of all these openers and closers." + + ;"A closer is an illegal object for anything except the corresponding opener." + > T > closer>>> + T closer>>> + T closer>>> + T closer>>> + >> T >> closer>>> + > T > closer>>> + > T > closer>>> + > T > closer>>> + + T > + )) + .s > ) + (ELSE )>>>>> + + T > + )) + .s >> ) + (ELSE )>>>>> + + T > + )) + .s > ) + (ELSE )>>>>> + + > T > + )) + > .s > > ) + (ELSE )>>>>> + + > T > + )) + > .s >> >> ) + (ELSE )>>> SEGMENT>>> + + ;"The prototemplate returned is an illegal object for anything except #-syntax." + T > + )) + .s > ) + (ELSE )>>> prototemplate>>> + + ;"Plain backslash just gets default handling in the lexer. It's only + special to the scalar sublexer." + + >> + +;"Lookup a string in an OBLIST / OBLIST list. If it isn't found, + insert it into the OBLIST / head of the OBLIST list." + >) + (ELSE )) + )>> .os> + >>)>> + +;"TODO: BLOCK..." +> + )) + ) + (<==? .k %>> ) + ( CHARACTER>>) + (ELSE >)>>>> + ;"Gather trailer-separated PNAMEs into a stack." + )> + ;"Now we have a LIST of STRINGs containing our trailed PNAMEs, with + the last still in .pn. The final PNAME is special: because it has + no trailer, we look it up in our oblist list." + + ;"Special case: we have an OBLIST, not an ATOM identifying an OBLIST." + .atm> .atm>>> + >) + (ELSE >)> + )> + ;"Lookup each atom in the oblist denoted the previous (trailer)," + ;"except the last, which is our ATOM." + + > + >>> + .atoms>> + +) c (n 0) (havedigits <>) "NAME" oct) + > + ) + ;"Made it to *?" + (<==? .c %> + .a>) + (ELSE )>) + ;"Got another octit?" + ( .c> >> + > >> + + ) + ;"Not octal after all." + (ELSE )>> + +;"If current radix isn't 10, pre-scan to see whether there's a decimal point." + 10) + (ELSE + ) "NAME" rdx) + > + ) + ;"Docs aren't clear on exponent-notation fixes without decimal points." + ;"Decimal makes more sense..." + (<==? % .c> ) + (<==? % .c> ) + (<==? % .c> )>>)>> + +) (n 0) (sgn 1) (z ) (rad )) + > ) + (ELSE )> + > + + .a>) + (ELSE .a>)>) + ;"Got a digit?" + ( .c> .rad>>> + <- .c %>>> + ) + ;".?" + ;"[eE]?" + ;"Not a decimal." + (ELSE .a>)>>> + +;"The Scalar Sublexer." +;"Parse an object that begins with a non-special character: FIX/FLOAT/ATOM." +> .c> >>> + ) + (ELSE )>> + +;"Fallback to use if PARSE-TABLE!- is empty and no argument is provided." +> + + +% <>> + +;"Like MAPF ,AND with early termination." + > .all>)>> !.argses> + T> + +;"This belongs in a PRINT module. Here for testing." + > ) + ( <==? <1 .x> LVAL> <==? <1 .x> GVAL>>>> + > >) + (ELSE )>> +) + ;"TODO: more aggressive single-lining" + (> + + <==? <1 .y> LVAL> + <==? <1 .y> GVAL>>> .x> + > + > >) + (ELSE + .lvl> + > >)>> +>> + +> + >>> + > + > + +