X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=src%2Fcc65%2Fcompile.c;h=7edd3ae1786df2d5ca7212a4329af3af498adfab;hb=1b81dcc64fbb66da569ea5f827a6622cdfdbc743;hp=4d62aefe55f34a59b8c757bb6dd720b51c2e1711;hpb=aa8737733fe51d2941f434c10ca028ac5ab2986c;p=cc65 diff --git a/src/cc65/compile.c b/src/cc65/compile.c index 4d62aefe5..7edd3ae17 100644 --- a/src/cc65/compile.c +++ b/src/cc65/compile.c @@ -6,10 +6,10 @@ /* */ /* */ /* */ -/* (C) 2000 Ullrich von Bassewitz */ -/* Wacholderweg 14 */ -/* D-70597 Stuttgart */ -/* EMail: uz@musoftware.de */ +/* (C) 2000-2004 Ullrich von Bassewitz */ +/* Römerstrasse 52 */ +/* D-70794 Filderstadt */ +/* EMail: uz@cc65.org */ /* */ /* */ /* This software is provided 'as-is', without any expressed or implied */ @@ -34,18 +34,24 @@ #include +#include -#include "../common/version.h" +/* common */ +#include "debugflag.h" +#include "version.h" +#include "xmalloc.h" +#include "xsprintf.h" +/* cc65 */ #include "asmlabel.h" +#include "asmstmt.h" #include "codegen.h" #include "declare.h" #include "error.h" #include "expr.h" #include "function.h" #include "global.h" -#include "incpath.h" -#include "io.h" +#include "input.h" #include "litpool.h" #include "macrotab.h" #include "pragma.h" @@ -55,7 +61,7 @@ /*****************************************************************************/ -/* Code */ +/* Code */ /*****************************************************************************/ @@ -66,30 +72,32 @@ static void Parse (void) int comma; SymEntry* Entry; - kill (); - NextToken (); /* "prime" the pump */ + /* Go... */ NextToken (); - while (curtok != TOK_CEOF) { + NextToken (); + + /* Parse until end of input */ + while (CurTok.Tok != TOK_CEOF) { - DeclSpec Spec; + DeclSpec Spec; Declaration Decl; - int NeedStorage; + int NeedStorage; /* Check for empty statements */ - if (curtok == TOK_SEMI) { + if (CurTok.Tok == TOK_SEMI) { NextToken (); continue; } /* Check for an ASM statement (which is allowed also on global level) */ - if (curtok == TOK_ASM) { - doasm (); + if (CurTok.Tok == TOK_ASM) { + AsmStatement (); ConsumeSemi (); continue; } /* Check for a #pragma */ - if (curtok == TOK_PRAGMA) { + if (CurTok.Tok == TOK_PRAGMA) { DoPragma (); continue; } @@ -98,13 +106,16 @@ static void Parse (void) ParseDeclSpec (&Spec, SC_EXTERN | SC_STATIC, T_INT); /* Don't accept illegal storage classes */ - if (Spec.StorageClass == SC_AUTO || Spec.StorageClass == SC_REGISTER) { - Error (ERR_ILLEGAL_STORAGE_CLASS); - Spec.StorageClass = SC_EXTERN | SC_STATIC; - } + if ((Spec.StorageClass & SC_TYPE) == 0) { + if ((Spec.StorageClass & SC_AUTO) != 0 || + (Spec.StorageClass & SC_REGISTER) != 0) { + Error ("Illegal storage class"); + Spec.StorageClass = SC_EXTERN | SC_STATIC; + } + } /* Check if this is only a type declaration */ - if (curtok == TOK_SEMI) { + if (CurTok.Tok == TOK_SEMI) { CheckEmptyDecl (&Spec); NextToken (); continue; @@ -136,7 +147,7 @@ static void Parse (void) /* Get the symbol flags */ SymFlags = Spec.StorageClass; - if (IsFunc (Decl.Type)) { + if (IsTypeFunc (Decl.Type)) { SymFlags |= SC_FUNC; } else { if (NeedStorage) { @@ -155,25 +166,29 @@ static void Parse (void) unsigned Size = SizeOf (Decl.Type); /* Allow initialization */ - if (curtok == TOK_ASSIGN) { + if (CurTok.Tok == TOK_ASSIGN) { /* We cannot initialize types of unknown size, or * void types in non ANSI mode. */ if (Size == 0) { - if (!IsVoid (Decl.Type)) { - if (!IsArray (Decl.Type)) { - /* Size is unknown and not an array */ - Error (ERR_UNKNOWN_SIZE); - } - } else if (ANSI) { - /* We cannot declare variables of type void */ - Error (ERR_ILLEGAL_TYPE); - } + if (!IsTypeVoid (Decl.Type)) { + if (!IsTypeArray (Decl.Type)) { + /* Size is unknown and not an array */ + Error ("Variable `%s' has unknown size", Decl.Ident); + } + } else if (ANSI) { + /* We cannot declare variables of type void */ + Error ("Illegal type for variable `%s'", Decl.Ident); + } } - /* Switch to the data segment */ - g_usedata (); + /* Switch to the data or rodata segment */ + if (IsQualConst (Decl.Type)) { + g_userodata (); + } else { + g_usedata (); + } /* Define a label */ g_defgloblabel (Entry->Name); @@ -185,28 +200,36 @@ static void Parse (void) ParseInit (Entry->Type); } else { - if (IsVoid (Decl.Type)) { + if (IsTypeVoid (Decl.Type)) { /* We cannot declare variables of type void */ - Error (ERR_ILLEGAL_TYPE); - } else if (Size == 0) { - /* Size is unknown */ - Error (ERR_UNKNOWN_SIZE); + Error ("Illegal type for variable `%s'", Decl.Ident); + Entry->Flags &= ~(SC_STORAGE | SC_DEF); + } else if (Size == 0) { + /* Size is unknown. Is it an array? */ + if (!IsTypeArray (Decl.Type)) { + Error ("Variable `%s' has unknown size", Decl.Ident); + } + Entry->Flags &= ~(SC_STORAGE | SC_DEF); } - /* Switch to the BSS segment */ - g_usebss (); + /* Allocate storage if it is still needed */ + if (Entry->Flags & SC_STORAGE) { - /* Define a label */ - g_defgloblabel (Entry->Name); + /* Switch to the BSS segment */ + g_usebss (); + + /* Define a label */ + g_defgloblabel (Entry->Name); - /* Allocate space for uninitialized variable */ - g_res (SizeOf (Entry->Type)); + /* Allocate space for uninitialized variable */ + g_res (Size); + } } } /* Check for end of declaration list */ - if (curtok == TOK_COMMA) { + if (CurTok.Tok == TOK_COMMA) { NextToken (); comma = 1; } else { @@ -215,20 +238,20 @@ static void Parse (void) } /* Function declaration? */ - if (IsFunc (Decl.Type)) { + if (Entry && IsTypeFunc (Entry->Type)) { /* Function */ if (!comma) { - - if (curtok == TOK_SEMI) { - + if (CurTok.Tok == TOK_SEMI) { /* Prototype only */ NextToken (); - - } else { - if (Entry) { - NewFunc (Entry); - } + } else if (Entry) { + /* Function body definition */ + if (SymIsDef (Entry)) { + Error ("Body for function `%s' has already been defined", + Entry->Name); + } + NewFunc (Entry); } } @@ -243,67 +266,80 @@ static void Parse (void) -void Compile (void) +void Compile (const char* FileName) /* Top level compile routine. Will setup things and call the parser. */ { - char* Path; - - - /* Setup variables */ - LiteralLabel = GetLabel (); - - /* Add some standard paths to the include search path */ - AddIncludePath ("", INC_USER); /* Current directory */ - AddIncludePath ("include", INC_SYS); -#ifdef CC65_INC - AddIncludePath (CC65_INC, INC_SYS); -#else - AddIncludePath ("/usr/lib/cc65/include", INC_SYS); -#endif - Path = getenv ("CC65_INC"); - if (Path) { - AddIncludePath (Path, INC_SYS | INC_USER); - } + char Buf[20]; + char DateStr[20]; + char TimeStr[20]; + time_t Time; + struct tm* TM; + + /* Since strftime is locale dependent, we need the abbreviated month names + * in english. + */ + static const char MonthNames[12][4] = { + "Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" + }; /* Add macros that are always defined */ - AddNumericMacro ("__CC65__", (VER_MAJOR * 0x100) + (VER_MINOR * 0x10) + VER_PATCH); + DefineNumericMacro ("__CC65__", VERSION); /* Strict ANSI macro */ if (ANSI) { - AddNumericMacro ("__STRICT_ANSI__", 1); + DefineNumericMacro ("__STRICT_ANSI__", 1); } - /* Optimization macros */ + /* Optimization macros. Since no source code has been parsed for now, the + * IS_Get functions access the values in effect now, regardless of any + * changes using #pragma later. + */ if (Optimize) { - AddNumericMacro ("__OPT__", 1); + DefineNumericMacro ("__OPT__", 1); if (FavourSize == 0) { - AddNumericMacro ("__OPT_i__", 1); + DefineNumericMacro ("__OPT_i__", 1); } - if (EnableRegVars) { - AddNumericMacro ("__OPT_r__", 1); + if (IS_Get (&EnableRegVars)) { + DefineNumericMacro ("__OPT_r__", 1); } - if (InlineStdFuncs) { - AddNumericMacro ("__OPT_s__", 1); + if (IS_Get (&InlineStdFuncs)) { + DefineNumericMacro ("__OPT_s__", 1); } } + /* __TIME__ and __DATE__ macros */ + Time = time (0); + TM = localtime (&Time); + strftime (Buf, sizeof (Buf), "%e %Y", TM); + xsprintf (DateStr, sizeof (DateStr), "\"%s %s\"", MonthNames[TM->tm_mon], Buf); + strftime (TimeStr, sizeof (TimeStr), "\"%H:%M:%S\"", TM); + DefineTextMacro ("__DATE__", DateStr); + DefineTextMacro ("__TIME__", TimeStr); + + /* Initialize the literal pool */ + InitLiteralPool (); + /* Create the base lexical level */ EnterGlobalLevel (); /* Generate the code generator preamble */ g_preamble (); + /* Open the input file */ + OpenMainFile (FileName); + /* Ok, start the ball rolling... */ Parse (); - /* Dump literal pool. */ + /* Dump the literal pool. */ DumpLiteralPool (); /* Write imported/exported symbols */ EmitExternals (); if (Debug) { - PrintLiteralStats (stdout); + PrintLiteralPoolStats (stdout); PrintMacroStats (stdout); } @@ -316,3 +352,4 @@ void Compile (void) +