DIRECTORY
	Exec USING [AddCommand, ExecProc, FreeTokenString, GetToken,
		OutputProc],
	Format USING [StringProc, Text, CR],
	MStream USING [Handle, ReadOnly, WriteOnly, Error],
	Stream USING [Delete, PutString],
	PrintingDefs USING [],
	SymbolTableDefs USING [InitializeSymbolTable, FinalizeSymbolTable,
	    echoSymbolTables],
	ParseDefs USING [Parse];
	
Main: PROGRAM
	IMPORTS Exec, Format, MStream, Stream, ParseDefs, SymbolTableDefs
	EXPORTS PrintingDefs =
BEGIN
inStream, outStream: MStream.Handle;
ExecOutProc: Format.StringProc;
outProc: PUBLIC POINTER TO Format.StringProc;
inFile: LONG STRING ← NIL;
outFile: LONG STRING ← [60];

echoSource: PUBLIC BOOLEAN;	-- echo input as Mesa comments
echoOutput: PUBLIC BOOLEAN;	-- echo output to executive


ParseIt: Exec.ExecProc =	-- PROC [h: Exec.Handle]
BEGIN
    i: CARDINAL;
    switches: LONG STRING;
    reverse: BOOLEAN;
    
    FileOutputProc: Format.StringProc ←
    BEGIN
	IF echoOutput THEN Format.Text[ExecOutProc, s];
	Stream.PutString[outStream, s];
    END;
    
    outProc ← @FileOutputProc;
    ExecOutProc ← Exec.OutputProc[h];
    SymbolTableDefs.InitializeSymbolTable[];
    
    -- get input file name
    [token: inFile, switches: switches] ← Exec.GetToken[h];
    IF inFile = NIL THEN RETURN;
    
    -- process the switches
    echoSource ← FALSE;
    echoOutput ← FALSE;
    SymbolTableDefs.echoSymbolTables ← FALSE;
    reverse ← TRUE;
    IF switches # NIL THEN
        FOR i IN [0..switches.length) DO
            SELECT switches.text[i] FROM
	        '~ => reverse ← FALSE;
	        'c, 's => {
		    echoSource ← reverse;
		    reverse ← TRUE; };
	        'e => {
		    echoOutput ← reverse;
		    reverse ← TRUE; };
	        't => {
		    SymbolTableDefs.echoSymbolTables ← reverse;
		    reverse ← TRUE; };
	        ENDCASE => NULL;
            ENDLOOP;
		
    -- construct output file name from input file name,
    -- change sufix to ".mesa"
    i ← 0;
    DO
        outFile.text[i] ← inFile.text[i];
	i ← i + 1;
	-- look for the end of string or a period ('.)
	IF i >= inFile.length OR inFile.text[i] = '. THEN EXIT
    ENDLOOP;
    outFile.text[i] ← '.; outFile.text[i+1] ← 'm; outFile.text[i+2] ← 'e;
    outFile.text[i+3] ← 's; outFile.text[i+4] ← 'a; outFile.length ← i + 5;
    
    -- open the input and output files
    inStream ← MStream.ReadOnly[name: inFile, release: [] !
        MStream.Error => {
            Format.Text[ExecOutProc, "Error opening input file: "L];
    	    Format.Text[ExecOutProc, inFile];
            Format.CR[ExecOutProc];
            GO TO BadFile; }; ];
    outStream ← MStream.WriteOnly[name: outFile, release: [], type: text !
        MStream.Error => {
            Format.Text[ExecOutProc, "Error opening output file: "L];
            Format.Text[ExecOutProc, outFile];
            Format.CR[ExecOutProc];
            GO TO BadFile; }; ];
    ParseDefs.Parse[inStream];
    Stream.Delete[inStream];
    Stream.Delete[outStream];
    SymbolTableDefs.FinalizeSymbolTable[];
    inFile ← Exec.FreeTokenString[inFile];
    switches ← Exec.FreeTokenString[switches];
EXITS
    BadFile => NULL;
END;

Exec.AddCommand["CToMesa.~", ParseIt];

END.