123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131 |
- %
- % READ.RED - S-expression parser
- %
- % Author: Eric Benson
- % Symbolic Computation Group
- % Computer Science Dept.
- % University of Utah
- % Date: 28 August 1981
- % Copyright (c) 1981 University of Utah
- %
- % <PSL.KERNEL>READ.RED.6, 20-Oct-82 11:07:28, Edit by BENSON
- % Extra right paren in file only prints warning, not error
- % <PSL.KERNEL>READ.RED.5, 6-Oct-82 11:37:33, Edit by BENSON
- % Took away CATCH in READ, EOF error binds *InsideStructureRead to NIL
- % <PSL.KERNEL>READ.RED.2, 20-Sep-82 11:24:32, Edit by BENSON
- % Right parens at top level cause an error in a file
- % <PSL.INTERP>READ.RED.6, 2-Sep-82 14:07:37, Edit by BENSON
- % Right parens are ignored at the top level
- fluid '(CurrentReadMacroIndicator!* % Get to find read macro function
- CurrentScanTable!* % vector of character types
- !*InsideStructureRead); % indicates within compound read
- global '(TokType!* % Set by token scanner, type of token
- LispScanTable!* % CurrentScanTable!* when READing
- IN!* % Current input channel
- !$EOF!$); % has value returned when EOF is read
-
- CurrentReadMacroIndicator!* := 'LispReadMacro;
- CompileTime flag('(DotContextError), 'InternalFunction);
- lisp procedure ChannelReadTokenWithHooks Channel; % Scan token w/read macros
- %
- % This is ReadToken with hooks for read macros
- %
- begin scalar Tkn, Fn;
- Tkn := ChannelReadToken Channel;
- if TokType!* eq 3 and (Fn := get(Tkn, CurrentReadMacroIndicator!*)) then
- return IDApply2(Channel, Tkn, Fn);
- return Tkn;
- end;
- lisp procedure ChannelRead Channel; %. Parse S-expression from channel
- begin scalar CurrentScanTable!*, CurrentReadMacroIndicator!*;
- CurrentScanTable!* := LispScanTable!*;
- CurrentReadMacroIndicator!* := 'LispReadMacro;
- return ChannelReadTokenWithHooks Channel;
- end;
- lisp procedure Read(); %. Parse S-expr from current input
- << MakeInputAvailable();
- ChannelRead IN!* >>;
- lisp procedure ChannelReadEof(Channel, Ef); % Handle end-of-file in Read
- if !*InsideStructureRead then return
- begin scalar !*InsideStructureRead;
- return
- StdError BldMsg("Unexpected EOF while reading on channel %r",
- Channel);
- end else !$EOF!$;
- lisp procedure ChannelReadQuotedExpression(Channel, Qt); % read macro '
- MkQuote ChannelReadTokenWithHooks Channel;
- lisp procedure ChannelReadListOrDottedPair(Channel, Pa); % read macro (
- %
- % Read list or dotted pair. Collect items until closing right paren.
- % Check for dot context errors.
- %
- begin scalar Elem, StartPointer, EndPointer, !*InsideStructureRead;
- !*InsideStructureRead := T;
- Elem := ChannelReadTokenWithHooks Channel;
- if TokType!* eq 3 then
- if Elem eq '!. then return DotContextError()
- else if Elem eq '!) then return NIL;
- StartPointer := EndPointer := list Elem;
- LoopBegin:
- Elem := ChannelReadTokenWithHooks Channel;
- if TokType!* eq 3 then
- if Elem eq '!) then return StartPointer
- else if Elem eq '!. then
- << Elem := ChannelReadTokenWithHooks Channel;
- if TokType!* eq 3 and (Elem eq '!) or Elem eq '!.) then
- return DotContextError()
- else
- << RplacD(EndPointer, Elem);
- Elem := ChannelReadTokenWithHooks Channel;
- if TokType!* eq 3 and Elem eq '!) then return StartPointer
- else return DotContextError() >> >>;
- % If we had splice macros, I think they would be checked here
- RplacD(EndPointer, list Elem);
- EndPointer := cdr EndPointer;
- goto LoopBegin;
- end;
- lisp procedure ChannelReadRightParen(Channel, Tok);
- % Ignore right parens at the top
- if !*InsideStructureRead then Tok
- else
- << if not (Channel eq StdIN!*) then % if not reading from the terminal
- ErrorPrintF "*** Unmatched right parenthesis";
- ChannelReadTokenWithHooks Channel >>;
- lisp procedure DotContextError(); % Parsing error
- IOError "Dot context error";
- % List2Vector is found in TYPE-CONVERSIONS.RED
- lisp procedure ChannelReadVector Channel; % read macro [
- begin scalar Elem, StartPointer, EndPointer, !*InsideStructureRead;
- !*InsideStructureRead := T;
- StartPointer := EndPointer := (NIL . NIL);
- while << Elem := ChannelReadTokenWithHooks Channel;
- TokType!* neq 3 or Elem neq '!] >> do
- << RplacD(EndPointer, list Elem);
- EndPointer := cdr EndPointer >>;
- return List2Vector cdr StartPointer;
- end;
- StartupTime <<
- put('!', 'LispReadMacro, function ChannelReadQuotedExpression);
- put('!( , 'LispReadMacro, function ChannelReadListOrDottedPair);
- put('!) , 'LispReadMacro, function ChannelReadRightParen);
- put('![, 'LispReadMacro, function ChannelReadVector);
- put(MkID char EOF, 'LispReadMacro, function ChannelReadEOF);
- >>;
- END;
|