{$optimize 7} {---------------------------------------------------------------} { } { ORCA/C } { } { A C compiler for the Apple IIGS. } { } { Copyright 1989,1990 } { Byte Works, Inc. } { } { Mike Westerfield } { } {---------------------------------------------------------------} {$stacksize $1800} program cc(output); {$LibPrefix '0/obj/'} uses CCommon, CGI, Scanner, Header, Symbol, MM, Expression, Parser, Asm; {$segment 'CC'} var i: 1..maxPath; {loop/index variable} vDCBGS: versionDCBGS; {for checking the version number} procedure DisposeAll (userID: integer); tool($02, $11); procedure SystemQuitFlags (flags: integer); extern; begin {cc} {make sure we quit with restart set} SystemQuitFlags($4000); {initialize file names and parameter strings} includeFileGS.maxSize := maxPath+4; includeFileGS.theString.size := 0; for i := 1 to maxPath do includeFileGS.theString.theString[i] := chr(0); outFileGS := includeFileGS; partialFileGS := includeFileGS; infoStringGS := includeFileGS; {check the version number} vDCBGS.pCount := 1; VersionGS(vDCBGS); if (ToolError <> 0) or (vDCBGS.version[1] < '2') then TermError(10); {get the command line info} with liDCBGS do begin pCount := 11; sFile := @includeFileGS; dFile := @outFileGS; namesList := @partialFileGS; iString := @infoStringGS; end; {with} GetLInfoGS(liDCBGS); if ToolError <> 0 then begin {check for buffTooSmall errors} includeFileGS.theString.size := 0; outFileGS.theString.size := 0; partialFileGS.theString.size := 0; infoStringGS.theString.size := 0; enterEditor := false; TermError(13); end; {if} sourceFileGS := includeFileGS; doingPartial := partialFileGS.theString.size <> 0; with liDCBGS do begin enterEditor := pFlags & flag_e <> 0; {enter editor on terminal errors?} filenamesInErrors := pFlags & flag_f <> 0; {filenames in error messages?} ignoreSymbols := mFlags & flag_i <> 0; {ignore symbol file?} list := pFlags & flag_l <> 0; {list the source file?} memoryCompile := pflags & flag_m <> 0; {memory based compile?} progress := mflags & flag_p = 0; {write progress info?} rebuildSymbols := mflags & flag_r <> 0; {rebuild symbol file?} printSymbols := pflags & flag_s <> 0; {print the symbol table?} terminalErrors := pFlags & flag_t <> 0; {all errors terminal?} wait := pFlags & flag_w <> 0; {wait when an error is found?} cLineOptimize := pFlags & flag_o <> 0; {turn optimizations on?} end; {liDCB} if list then {we don't need both...} progress := false; {write the header} if list or progress then begin writeln('ORCA/C ', versionStr); writeln; end; {if} {read the source file} ReadFile; languageNumber := long(ffDCBGS.auxType).lsw; {set the default language number} {initialize the various modules} LInit; {initialize the memory pools} GInit; useGlobalPool := true; InitCCommon; {initialize the common module} {initialize the scanner} InitScanner(bofPtr,pointer(ord4(bofPtr)+ffDCBGS.fileLength)); InitParser; {initialize the parser} InitExpression; {initialize the expression evaluator} InitSymbol; {initialize the symbol table handler} InitAsm; {initialize the assembler} CodeGenScalarInit; {initialize the code generator} with liDCBGS do {generate debug code?} if pFlags & flag_d <> 0 then begin debugFlag := true; profileFlag := true; end; {if} {compile the program} InitHeader(includeFileGS); {read any precompiled headers} NextToken; {get the first token in the program} while token.kind <> eofsy do begin {compile the program} if doingFunction then DoStatement else if token.kind in topLevelDeclarationStart then DoDeclaration(false) else begin Error(26); NextToken; end; {else} end; {while} if doingFunction then {check for unclosed function} Error(23); {init the code generator (if it needs it)} if not codegenStarted and (liDCBGS.kFlag <> 0) then begin CodeGenInit (@outFileGS, liDCBGS.kFlag, doingPartial); liDCBGS.kFlag := 3; codegenStarted := true; end; {if} DoGlobals; {create the ~GLOBALS and ~ARRAYS segments} {shut down the compiler} TermHeader; {make sure the compiled header file is closed} CheckStaticFunctions; {check for undefined functions} if (lint & lintUnused) <> 0 then {check for unused static vars} CheckUnused(globalTable); ffDCBGS.action := 7; {purge the source file} ffDCBGS.pcount := 14; ffDCBGS.pathName := @includeFileGS.theString; FastFileGS(ffDCBGS); if ToolError <> 0 then begin sourceFileGS := includeFileGS; TermError(2); end; {if} TermScanner; {shut down the scanner} StopSpin; if (numErrors <> 0) or list or progress then begin writeln; {write the number of errors} if numErrors = 1 then writeln('1 error found.') else writeln(numErrors:1, ' errors found.'); end; {if} if list or progress then {leave a blank line} writeln; if codegenStarted then {shut down the code generator} CodeGenFini; TermParser; {shut down the parser} if numErrors = 0 then begin {set up the return parameters} if not switchLanguages then begin if liDCBGS.kFlag = 0 then liDCBGS.lops := 0 else liDCBGS.lops := liDCBGS.lops & $FFFE; liDCBGS.sFile := @outFileGS; end; {if} end {if} else begin liDCBGS.lops := 0; if liDCBGS.merrf = 0 then liDCBGS.merrf := 16; end; {else} MMQuit; {dispose of our memory pools} with liDCBGS do begin {return to the shell} sFile := pointer(ord4(sFile)+2); dFile := pointer(ord4(dFile)+2); namesList := pointer(ord4(namesList)+2); iString := pointer(ord4(iString)+2); end; {with} SetLInfoGS(liDCBGS); StopSpin; end. {cc}