fpc/compiler/parser.pas
1998-09-04 08:41:36 +00:00

567 lines
18 KiB
ObjectPascal

{
$Id$
Copyright (c) 1993-98 by Florian Klaempfl
This unit does the parsing process
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 2 of the License, 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.
****************************************************************************
}
{$ifdef tp}
{$E+,N+,D+,F+}
{$endif}
unit parser;
interface
procedure compile(const filename:string;compile_system:boolean);
procedure initparser;
implementation
uses
cobjects,comphook,systems,globals,
hcodegen,verbose, { leave this order, else hcodegen.message will be used !! }
symtable,files,aasm,
assemble,link,script,gendef,
{$ifdef UseBrowser}
browser,
{$endif UseBrowser}
scanner,pbase,pdecl,psystem,pmodules;
procedure initparser;
begin
forwardsallowed:=false;
{ ^M means a string or a char, because we don't parse a }
{ type declaration }
ignore_equal:=false;
{ we didn't parse a object or class declaration }
{ and no function header }
testcurobject:=0;
{ a long time, this was forgotten }
aktprocsym:=nil;
current_module:=nil;
loaded_units.init;
usedunits.init;
{ global switches }
aktglobalswitches:=initglobalswitches;
{ memory sizes }
if heapsize=0 then
heapsize:=target_info.heapsize;
if stacksize=0 then
stacksize:=target_info.stacksize;
end;
procedure default_macros;
var
hp : pstring_item;
begin
{ commandline }
hp:=pstring_item(initdefines.first);
while assigned(hp) do
begin
def_macro(hp^.str^);
hp:=pstring_item(hp^.next);
end;
{ set macros for version checking }
set_macro('FPC_VERSION',version_nr);
set_macro('FPC_RELEASE',release_nr);
set_macro('FPC_PATCH',patch_nr);
end;
procedure compile(const filename:string;compile_system:boolean);
var
{ scanner }
oldtoken : ttoken;
oldtokenpos : tfileposinfo;
oldc : char;
oldpattern,
oldorgpattern : string;
old_block_type : tblock_type;
oldcurrent_scanner : pscannerfile;
{ symtable }
oldmacros,
oldrefsymtable,
oldsymtablestack : psymtable;
oldprocprefix : string;
oldaktprocsym : pprocsym;
{ cg }
oldnextlabelnr : longint;
oldparse_only : boolean;
{ asmlists }
oldimports,
oldexports,
oldresource,
oldrttilist,
oldbsssegment,
olddatasegment,
oldcodesegment,
oldexprasmlist,
olddebuglist,
oldinternals,
oldexternals,
oldconsts : paasmoutput;
{ akt.. things }
oldaktlocalswitches : tlocalswitches;
oldaktmoduleswitches : tmoduleswitches;
oldaktfilepos : tfileposinfo;
oldaktpackrecords : word;
oldaktoutputformat : tasm;
oldaktoptprocessor : tprocessors;
oldaktasmmode : tasmmode;
begin
inc(compile_level);
{ save symtable state }
oldsymtablestack:=symtablestack;
oldrefsymtable:=refsymtable;
oldmacros:=macros;
oldprocprefix:=procprefix;
oldaktprocsym:=aktprocsym;
{ save scanner state }
oldc:=c;
oldpattern:=pattern;
oldorgpattern:=orgpattern;
oldtoken:=token;
old_block_type:=block_type;
oldtokenpos:=tokenpos;
oldcurrent_scanner:=current_scanner;
{ save cg }
oldnextlabelnr:=nextlabelnr;
oldparse_only:=parse_only;
{ save assembler lists }
olddatasegment:=datasegment;
oldbsssegment:=bsssegment;
oldcodesegment:=codesegment;
olddebuglist:=debuglist;
oldexternals:=externals;
oldinternals:=internals;
oldconsts:=consts;
oldrttilist:=rttilist;
oldexprasmlist:=exprasmlist;
oldimports:=importssection;
oldexports:=exportssection;
oldresource:=resourcesection;
{ save akt... state }
oldaktlocalswitches:=aktlocalswitches;
oldaktmoduleswitches:=aktmoduleswitches;
oldaktpackrecords:=aktpackrecords;
oldaktoutputformat:=aktoutputformat;
oldaktoptprocessor:=aktoptprocessor;
oldaktasmmode:=aktasmmode;
oldaktfilepos:=aktfilepos;
{ show info }
Message1(parser_i_compiling,filename);
{ reset symtable }
symtablestack:=nil;
refsymtable:=nil;
procprefix:='';
aktprocsym:=nil;
{ macros }
macros:=new(psymtable,init(macrosymtable));
macros^.name:=stringdup('Conditionals for '+filename);
default_macros;
{ reset the unit or create a new program }
if assigned(current_module) then
begin
current_module^.sourcefiles.done;
current_module^.sourcefiles.init;
current_module^.used_units.done;
current_module^.used_units.init;
current_module^.linkofiles.done;
current_module^.linkofiles.init;
current_module^.linkstaticlibs.done;
current_module^.linkstaticlibs.init;
current_module^.linksharedlibs.done;
current_module^.linksharedlibs.init;
end
else
begin
current_module:=new(pmodule,init(filename,false));
main_module:=current_module;
end;
{ Load current state from the init values }
aktlocalswitches:=initlocalswitches;
aktmoduleswitches:=initmoduleswitches;
aktpackrecords:=initpackrecords;
aktpackenum:=initpackenum;
aktoutputformat:=initoutputformat;
aktoptprocessor:=initoptprocessor;
aktasmmode:=initasmmode;
{ we need this to make the system unit }
if compile_system then
aktmoduleswitches:=aktmoduleswitches+[cs_compilesystem];
{ startup scanner }
current_scanner:=new(pscannerfile,Init(filename));
token:=current_scanner^.yylex;
{ global switches are read, so further changes aren't allowed }
current_module^.in_global:=false;
{ init code generator for a new module }
codegen_newmodule;
{$ifdef GDB}
reset_gdb_info;
{$endif GDB}
{ Handle things which need to be once }
if (compile_level=1) then
begin
{ open assembler response }
AsmRes.Init('ppas');
end;
{ load system unit always }
loadsystemunit;
registerdef:=true;
make_ref:=true;
{ current return type is void }
procinfo.retdef:=voiddef;
{ reset lexical level }
lexlevel:=0;
{ If the compile level > 1 we get a nice "unit expected" error
message if we are trying to use a program as unit.}
if (token=_UNIT) or (compile_level>1) then
begin
current_module^.is_unit:=true;
proc_unit;
end
else
proc_program(token=_LIBRARY);
if status.errorcount>0 then
Message1(unit_f_errors_in_unit,tostr(status.errorcount));
{ clear memory }
{$ifdef Splitheap}
if testsplit then
begin
{ temp heap should be empty after that !!!}
codegen_donemodule;
Releasetempheap;
end;
{$endif Splitheap}
{ restore old state, close trees, > 0.99.5 has heapblocks, so
it's the default to release the trees }
{$ifdef VER0_99_5}
if dispose_asm_lists then
codegen_donemodule;
{$else}
{$ifdef TP}
if dispose_asm_lists then
{$endif}
codegen_donemodule;
{$endif}
{$ifdef GDB}
reset_gdb_info;
{$endif GDB}
{ free ppu }
if assigned(current_module^.ppufile) then
begin
dispose(current_module^.ppufile,done);
current_module^.ppufile:=nil;
end;
{ free scanner }
dispose(current_scanner,done);
{ free macros }
{!!! No check for unused macros yet !!! }
dispose(macros,done);
{ restore scanner }
c:=oldc;
pattern:=oldpattern;
orgpattern:=oldorgpattern;
token:=oldtoken;
tokenpos:=oldtokenpos;
block_type:=old_block_type;
current_scanner:=oldcurrent_scanner;
{ restore cg }
nextlabelnr:=oldnextlabelnr;
parse_only:=oldparse_only;
{ restore asmlists }
exprasmlist:=oldexprasmlist;
datasegment:=olddatasegment;
bsssegment:=oldbsssegment;
codesegment:=oldcodesegment;
consts:=oldconsts;
debuglist:=olddebuglist;
externals:=oldexternals;
internals:=oldinternals;
importssection:=oldimports;
exportssection:=oldexports;
resourcesection:=oldresource;
rttilist:=oldrttilist;
{ restore symtable state }
if (compile_level>1) then
begin
refsymtable:=oldrefsymtable;
symtablestack:=oldsymtablestack;
end;
macros:=oldmacros;
aktprocsym:=oldaktprocsym;
procprefix:=oldprocprefix;
{ restore current state }
aktlocalswitches:=oldaktlocalswitches;
aktmoduleswitches:=oldaktmoduleswitches;
aktpackrecords:=oldaktpackrecords;
aktoutputformat:=oldaktoutputformat;
aktoptprocessor:=oldaktoptprocessor;
aktasmmode:=oldaktasmmode;
aktfilepos:=oldaktfilepos;
{ Shut down things when the last file is compiled }
if (compile_level=1) then
begin
{ Close script }
if (not AsmRes.Empty) then
begin
Message1(exec_i_closing_script,AsmRes.Fn);
AsmRes.WriteToDisk;
end;
{$ifdef UseBrowser}
{ Write Browser }
if cs_browser in aktmoduleswitches then
begin
Message1(parser_i_writing_browser_log,Browse.Fname);
Browse.CreateLog;
write_browser_log;
Browse.CloseLog;
end;
{$endif UseBrowser}
end;
dec(compile_level);
end;
end.
{
$Log$
Revision 1.42 1998-09-04 08:41:59 peter
* updated some error messages
Revision 1.41 1998/09/01 12:53:24 peter
+ aktpackenum
Revision 1.40 1998/09/01 07:54:19 pierre
* UseBrowser a little updated (might still be buggy !!)
* bug in psub.pas in function specifier removed
* stdcall allowed in interface and in implementation
(FPC will not yet complain if it is missing in either part
because stdcall is only a dummy !!)
Revision 1.39 1998/08/26 10:07:09 peter
* dispose trees is now default for all > 0.99.5 compiles
Revision 1.38 1998/08/18 20:52:20 peter
* renamed in_main to in_global which is more logical
Revision 1.37 1998/08/17 09:17:49 peter
* static/shared linking updates
Revision 1.36 1998/08/14 21:56:36 peter
* setting the outputfile using -o works now to create static libs
Revision 1.35 1998/08/12 19:22:09 peter
* reset also the link* lists when recompiling an existing unit
Revision 1.34 1998/08/10 23:58:56 peter
* fixed asmlist dispose for 0.99.5
Revision 1.33 1998/08/10 14:50:07 peter
+ localswitches, moduleswitches, globalswitches splitting
Revision 1.32 1998/08/10 10:18:28 peter
+ Compiler,Comphook unit which are the new interface units to the
compiler
Revision 1.31 1998/07/14 21:46:46 peter
* updated messages file
Revision 1.30 1998/07/14 14:46:49 peter
* released NEWINPUT
Revision 1.29 1998/07/07 11:19:59 peter
+ NEWINPUT for a better inputfile and scanner object
Revision 1.28 1998/06/25 11:15:33 pierre
* ppu files where not closed in newppu !!
second compilation was impossible due to too many opened files
(not visible in 'make cycle' as we remove all the ppu files)
Revision 1.27 1998/06/17 14:10:15 peter
* small os2 fixes
* fixed interdependent units with newppu (remake3 under linux works now)
Revision 1.26 1998/06/16 08:56:23 peter
+ targetcpu
* cleaner pmodules for newppu
Revision 1.25 1998/06/15 15:38:07 pierre
* small bug in systems.pas corrected
+ operators in different units better hanlded
Revision 1.24 1998/06/13 00:10:08 peter
* working browser and newppu
* some small fixes against crashes which occured in bp7 (but not in
fpc?!)
Revision 1.23 1998/06/08 22:59:48 peter
* smartlinking works for win32
* some defines to exclude some compiler parts
Revision 1.22 1998/06/05 17:47:28 peter
* some better uses clauses
Revision 1.21 1998/06/04 23:51:49 peter
* m68k compiles
+ .def file creation moved to gendef.pas so it could also be used
for win32
Revision 1.20 1998/06/03 22:48:55 peter
+ wordbool,longbool
* rename bis,von -> high,low
* moved some systemunit loading/creating to psystem.pas
Revision 1.19 1998/05/27 19:45:04 peter
* symtable.pas splitted into includefiles
* symtable adapted for $ifdef NEWPPU
Revision 1.18 1998/05/23 01:21:15 peter
+ aktasmmode, aktoptprocessor, aktoutputformat
+ smartlink per module $SMARTLINK-/+ (like MMX) and moved to aktswitches
+ $LIBNAME to set the library name where the unit will be put in
* splitted cgi386 a bit (codeseg to large for bp7)
* nasm, tasm works again. nasm moved to ag386nsm.pas
Revision 1.17 1998/05/20 09:42:34 pierre
+ UseTokenInfo now default
* unit in interface uses and implementation uses gives error now
* only one error for unknown symbol (uses lastsymknown boolean)
the problem came from the label code !
+ first inlined procedures and function work
(warning there might be allowed cases were the result is still wrong !!)
* UseBrower updated gives a global list of all position of all used symbols
with switch -gb
Revision 1.16 1998/05/12 10:47:00 peter
* moved printstatus to verb_def
+ V_Normal which is between V_Error and V_Warning and doesn't have a
prefix like error: warning: and is included in V_Default
* fixed some messages
* first time parameter scan is only for -v and -T
- removed old style messages
Revision 1.15 1998/05/11 13:07:54 peter
+ $ifdef NEWPPU for the new ppuformat
+ $define GDB not longer required
* removed all warnings and stripped some log comments
* no findfirst/findnext anymore to remove smartlink *.o files
Revision 1.14 1998/05/06 18:36:53 peter
* tai_section extended with code,data,bss sections and enumerated type
* ident 'compiled by FPC' moved to pmodules
* small fix for smartlink
Revision 1.13 1998/05/06 08:38:42 pierre
* better position info with UseTokenInfo
UseTokenInfo greatly simplified
+ added check for changed tree after first time firstpass
(if we could remove all the cases were it happen
we could skip all firstpass if firstpasscount > 1)
Only with ExtDebug
Revision 1.12 1998/05/04 17:54:28 peter
+ smartlinking works (only case jumptable left todo)
* redesign of systems.pas to support assemblers and linkers
+ Unitname is now also in the PPU-file, increased version to 14
Revision 1.11 1998/05/01 16:38:45 florian
* handling of private and protected fixed
+ change_keywords_to_tp implemented to remove
keywords which aren't supported by tp
* break and continue are now symbols of the system unit
+ widestring, longstring and ansistring type released
Revision 1.10 1998/05/01 07:43:56 florian
+ basics for rtti implemented
+ switch $m (generate rtti for published sections)
Revision 1.9 1998/04/30 15:59:40 pierre
* GDB works again better :
correct type info in one pass
+ UseTokenInfo for better source position
* fixed one remaining bug in scanner for line counts
* several little fixes
Revision 1.8 1998/04/29 10:33:55 pierre
+ added some code for ansistring (not complete nor working yet)
* corrected operator overloading
* corrected nasm output
+ started inline procedures
+ added starstarn : use ** for exponentiation (^ gave problems)
+ started UseTokenInfo cond to get accurate positions
Revision 1.7 1998/04/27 23:10:28 peter
+ new scanner
* $makelib -> if smartlink
* small filename fixes pmodule.setfilename
* moved import from files.pas -> import.pas
Revision 1.6 1998/04/21 10:16:48 peter
* patches from strasbourg
* objects is not used anymore in the fpc compiled version
Revision 1.5 1998/04/10 14:41:43 peter
* removed some Hints
* small speed optimization for AsmLn
Revision 1.4 1998/04/08 16:58:03 pierre
* several bugfixes
ADD ADC and AND are also sign extended
nasm output OK (program still crashes at end
and creates wrong assembler files !!)
procsym types sym in tdef removed !!
Revision 1.3 1998/04/07 22:45:04 florian
* bug0092, bug0115 and bug0121 fixed
+ packed object/class/array
}