;"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."