home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Fresh Fish 8
/
FreshFishVol8-CD2.bin
/
bbs
/
dev
/
umbscheme-2.12.lha
/
UMBScheme
/
src
/
io.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-11-29
|
14KB
|
724 lines
/* io.c -- UMB Scheme, I/O package.
UMB Scheme Interpreter $Revision: 2.12 $
Copyright (C) 1988, 1991 William R Campbell
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, or (at your option)
any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
UMB Scheme was written by Bill Campbell with help from Karl Berry,
Barbara Dixey, Ira Gerstein, Mary Glaser, Kathy Hargreaves, Bill McCabe,
Long Nguyen, Susan Quina, Jeyashree Sivasubram, Bela Sohoni and Thang Quoc Tran.
For additional information about UMB Scheme, contact the author:
Bill Campbell
Department of Mathematics and Computer Science
University of Massachusetts at Boston
Harbor Campus
Boston, MA 02125
Telephone: 617-287-6449 Internet: bill@cs.umb.edu
*/
#include "portable.h"
#include "eval.h"
#include "object.h"
#include "architecture.h"
#include "steering.h"
#include "primitive.h"
#include "io.h"
#include "number.h"
Public FILE *The_Standard_Input, *The_Standard_Output;
/* A static variable printing keeps track of whether we want to print or not.*/
Private Boolean printing = TRUE;
Public void Set_Printing(turn_it_on)
Boolean turn_it_on;
{
printing = turn_it_on;
}
Public Boolean Get_Printing_State()
{
return printing;
}
/* The routines that actually print somewhere. |Output| assumes that its
argument will not have a null. */
Public void Output(s)
String s;
{
fprintf(Get_Port_File(Current_Output_Port), "%s", s);
if ( The_Transcript_Port != Nil )
{
fprintf(Get_Port_File(The_Transcript_Port), "%s", s);
}
}
/* |Output_Char| should perhaps do something about control characters.
When printing to the terminal, we certainly don't want to send control
characters, for example. */
Public void Output_Char(c)
Character c;
{
fprintf(Get_Port_File(Current_Output_Port), "%c", c);
if ( The_Transcript_Port != Nil )
{
fprintf(Get_Port_File(The_Transcript_Port), "%c", c);
}
}
Public Integer New_Left_Margin( margin )
Integer margin;
{
Integer in_margin = margin;
Output( "\n" );
while ( margin-- > 0 )
Output( " " );
return( in_margin );
}
Public void Print_Type(t)
Scheme_Type t;
{
if (Boolean_Type == t)
{
Output( "Boolean" );
}
if (Eclectic_Type == t)
{
Output( "Eclectic" );
}
if (Pair_Type == t)
{
Output( "Pair" );
}
if (Empty_List_Type == t)
{
Output( "Empty_List" );
}
if (Symbol_Type == t)
{
Output( "Symbol" );
}
if (Number_Type == t)
{
Output( "Number" );
}
if (Character_Type == t)
{
Output( "Character" );
}
if (String_Type == t)
{
Output( "String" );
}
if (Vector_Type == t)
{
Output( "Vector" );
}
if (Procedure_Type == t)
{
Output( "Procedure" );
}
if (Primitive_Type == t)
{
Output( "Primitive" );
}
if (Continuation_Type == t)
{
Output( "Continuation" );
}
if (Port_Type == t)
{
Output( "Port" );
}
if (Eof_Type == t)
{
Output( "Eof" );
}
if (Variable_Type == t)
{
Output( "Variable" );
}
if (Apply_Type == t)
{
Output( "Apply" );
}
if (Lambda_Type == t)
{
Output( "Lambda" );
}
if (Conditional_Type == t)
{
Output( "Conditional" );
}
if (Assignment_Type == t)
{
Output( "Assignment" );
}
if (Definition_Type == t)
{
Output( "Definition" );
}
if (Macro_Type == t)
{
Output( "Macro" );
}
if (Macro_Call_Type == t)
{
Output( "Macro_Call" );
}
if (Sequence_Type == t)
{
Output( "Sequence" );
}
if (Delay_Type == t)
{
Output( "Delay" );
}
if (Promise_Type == t)
{
Output( "Promise" );
}
if (Error_Type == t)
{
Output( "Error" );
}
if (Environment_Frame_Type == t)
{
Output( "Environment_Frame" );
}
if (State_Frame_Type == t)
{
Output( "State_Frame" );
}
if (Any_Type == t)
{
Output( "Any" );
}
}
/* Reading. */
#define MAX_TOKEN_SIZE 1000
typedef enum
{
Lparen_Token, Rparen_Token, Quote_Token, Backquote_Token,
Dot_Token, Comma_Token, Open_Vec_Token, True_Token,
False_Token, String_Token, Number_Token, Character_Token,
Symbol_Token, Error_Token, Comma_At_Token, Eof_Token
}
Token ;
Private Token The_Token ;
Private String Token_String ;
Private Character Token_Buffer[ MAX_TOKEN_SIZE ] ;
Private Integer Token_Index ;
Private Boolean Transcripting = FALSE;
#define Is_Control_Char iscntrl
#define Is_White_Space isspace
#define Scan_Char(f) (Transcripting?Tscan(f):getc(f))
Private void Read_Number() ;
Private void Read_Symbol() ;
Private int Force_Lower() ;
Private void Read_Token();
Private void Read_List();
/* Auxiliary input routines. */
Private int Tscan( f )
FILE * f;
{
int c;
if ( (c = getc(f)) != EOF ) putc(c , Get_Port_File(The_Transcript_Port));
return( c );
}
Private Boolean Is_Delimiter(c)
int c;
{
return( Is_White_Space(c) || c == '(' || c == ')' || c == '"' ||
c == ';' || c == EOF);
}
/* Force uppercase letters (and only letters) to lowercase. */
Private int Force_Lower( Ch )
int Ch ;
{
return( isupper( Ch ) ? (Ch - 'A' + 'a') : Ch ) ;
}
/* Implement the ANSI routine `toint'. */
Public Integer toint(c)
int c;
{
if (isxdigit(c))
{
c = Force_Lower(c);
if (c >= 'a')
return c - 'a' + 10;
else
return c - '0';
}
else
{
Panic( "Non-hex digit passed to toint" );
return 0;
}
}
/* Read a Scheme object from |Input_File|; leave it in Value_Register. */
Public void Read( Input_File )
FILE* Input_File ;
{
Transcripting = The_Transcript_Port != Nil
&& Input_File == The_Standard_Input;
Read_Token( Input_File ) ;
switch( The_Token )
{
case Symbol_Token :
Value_Register = Intern_Name( Token_String ) ;
break ;
case Lparen_Token :
Read_List( Input_File ) ;
break ;
case Number_Token :
Cstring_To_Number( Token_String , 0 ) ;
break ;
case String_Token :
/* We want to allow nulls in string constants. Hence
|memcpy| instead of |strcpy|. */
Make_String( Token_Index );
memcpy( Get_String_Value(Value_Register), Token_Buffer,
Token_Index );
Get_String_Value( Value_Register ) [ Token_Index ] = '\0';
break ;
case Character_Token :
Make_Character( *Token_String ) ;
break ;
case True_Token :
Value_Register = The_True_Object ;
break ;
case False_Token :
Value_Register = The_False_Object ;
break ;
case Open_Vec_Token :
Read_List( Input_File ) ;
Push( Value_Register ) ;
List_To_Vector() ;
Pop( 1 ) ;
break ;
case Dot_Token :
Value_Register = The_Dot_Object ;
break ;
case Rparen_Token :
Value_Register = The_Rparen_Object ;
break ;
case Quote_Token :
Push( Intern_Name( "quote" ) ) ;
Read( Input_File ) ;
Push( Value_Register ) ;
Push( Nil ) ;
Make_Pair() ;
Push( Value_Register ) ;
Make_Pair() ;
break ;
case Backquote_Token :
Push( Intern_Name( "quasiquote" ) ) ;
Read( Input_File ) ;
Push( Value_Register ) ;
Push( Nil ) ;
Make_Pair() ;
Push( Value_Register ) ;
Make_Pair() ;
break ;
case Comma_Token :
Push( Intern_Name( "unquote" ) ) ;
Read( Input_File ) ;
Push( Value_Register ) ;
Push( Nil ) ;
Make_Pair() ;
Push( Value_Register ) ;
Make_Pair() ;
break ;
case Comma_At_Token :
Push( Intern_Name( "unquote-splicing" ) ) ;
Read( Input_File ) ;
Push( Value_Register ) ;
Push( Nil ) ;
Make_Pair() ;
Push( Value_Register ) ;
Make_Pair() ;
break ;
case Error_Token :
Make_Error( Token_String ) ;
break ;
case Eof_Token :
Value_Register = The_Eof_Object ;
break ;
default :
Panic( "Unidentified token" ) ;
break ;
}
}
/* Read list from Input_File and leave it in Value_Register. This allows
the input `( . x )' (it treats it as equivalent to x), which is not strictly
legal according