Added support for old style (K&R) function declarations.

Several renames for better readibility.
Removed separate struct and enum symbol tables in favour of one tag table.
Check for some more error conditions or dubious constructs.


git-svn-id: svn://svn.cc65.org/cc65/trunk@62 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
cuz
2000-06-12 18:31:40 +00:00
parent 04dee08f58
commit 9cc25f13b6
23 changed files with 1269 additions and 976 deletions

322
src/cc65/compile.c Normal file
View File

@@ -0,0 +1,322 @@
/*****************************************************************************/
/* */
/* compile.c */
/* */
/* Top level compiler subroutine */
/* */
/* */
/* */
/* (C) 2000 Ullrich von Bassewitz */
/* Wacholderweg 14 */
/* D-70597 Stuttgart */
/* EMail: uz@musoftware.de */
/* */
/* */
/* This software is provided 'as-is', without any expressed or implied */
/* warranty. In no event will the authors be held liable for any damages */
/* arising from the use of this software. */
/* */
/* Permission is granted to anyone to use this software for any purpose, */
/* including commercial applications, and to alter it and redistribute it */
/* freely, subject to the following restrictions: */
/* */
/* 1. The origin of this software must not be misrepresented; you must not */
/* claim that you wrote the original software. If you use this software */
/* in a product, an acknowledgment in the product documentation would be */
/* appreciated but is not required. */
/* 2. Altered source versions must be plainly marked as such, and must not */
/* be misrepresented as being the original software. */
/* 3. This notice may not be removed or altered from any source */
/* distribution. */
/* */
/*****************************************************************************/
#include <stdlib.h>
#include "../common/version.h"
#include "asmlabel.h"
#include "codegen.h"
#include "declare.h"
#include "error.h"
#include "expr.h"
#include "function.h"
#include "global.h"
#include "include.h"
#include "io.h"
#include "litpool.h"
#include "macrotab.h"
#include "pragma.h"
#include "symtab.h"
#include "compile.h"
/*****************************************************************************/
/* Code */
/*****************************************************************************/
static void Parse (void)
/* Process all input text.
* At this level, only static declarations, defines, includes, and function
* definitions are legal....
*/
{
int comma;
SymEntry* Entry;
kill ();
NextToken (); /* "prime" the pump */
NextToken ();
while (curtok != TOK_CEOF) {
DeclSpec Spec;
Declaration Decl;
int NeedStorage;
/* Check for empty statements */
if (curtok == TOK_SEMI) {
NextToken ();
continue;
}
/* Check for an ASM statement (which is allowed also on global level) */
if (curtok == TOK_ASM) {
doasm ();
ConsumeSemi ();
continue;
}
/* Check for a #pragma */
if (curtok == TOK_PRAGMA) {
DoPragma ();
continue;
}
/* Read variable defs and functions */
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;
}
/* Check if this is only a type declaration */
if (curtok == TOK_SEMI) {
CheckEmptyDecl (&Spec);
NextToken ();
continue;
}
/* Check if we must reserve storage for the variable. We do
* this if we don't had a storage class given ("int i") or
* if the storage class is explicitly specified as static.
* This means that "extern int i" will not get storage
* allocated.
*/
NeedStorage = (Spec.StorageClass & SC_TYPEDEF) == 0 &&
((Spec.Flags & DS_DEF_STORAGE) != 0 ||
(Spec.StorageClass & (SC_STATIC | SC_EXTERN)) == SC_STATIC);
/* Read declarations for this type */
Entry = 0;
comma = 0;
while (1) {
unsigned SymFlags;
/* Read the next declaration */
ParseDecl (&Spec, &Decl, DM_NEED_IDENT);
if (Decl.Ident[0] == '\0') {
NextToken ();
break;
}
/* Get the symbol flags */
SymFlags = Spec.StorageClass;
if (IsFunc (Decl.Type)) {
SymFlags |= SC_FUNC;
} else {
if (NeedStorage) {
/* We will allocate storage, variable is defined */
SymFlags |= SC_STORAGE | SC_DEF;
}
}
/* Add an entry to the symbol table */
Entry = AddGlobalSym (Decl.Ident, Decl.Type, SymFlags);
/* Reserve storage for the variable if we need to */
if (SymFlags & SC_STORAGE) {
/* Get the size of the variable */
unsigned Size = SizeOf (Decl.Type);
/* Allow initialization */
if (curtok == 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);
}
}
/* Switch to the data segment */
g_usedata ();
/* Define a label */
g_defgloblabel (Entry->Name);
/* Skip the '=' */
NextToken ();
/* Parse the initialization */
ParseInit (Entry->Type);
} else {
if (IsVoid (Decl.Type)) {
/* We cannot declare variables of type void */
Error (ERR_ILLEGAL_TYPE);
} else if (Size == 0) {
/* Size is unknown */
Error (ERR_UNKNOWN_SIZE);
}
/* Switch to the BSS segment */
g_usebss ();
/* Define a label */
g_defgloblabel (Entry->Name);
/* Allocate space for uninitialized variable */
g_res (SizeOf (Entry->Type));
}
}
/* Check for end of declaration list */
if (curtok == TOK_COMMA) {
NextToken ();
comma = 1;
} else {
break;
}
}
/* Function declaration? */
if (IsFunc (Decl.Type)) {
/* Function */
if (!comma) {
if (curtok == TOK_SEMI) {
/* Prototype only */
NextToken ();
} else {
if (Entry) {
NewFunc (Entry);
}
}
}
} else {
/* Must be followed by a semicolon */
ConsumeSemi ();
}
}
}
void Compile (void)
/* Top level compile routine. Will setup things and call the parser. */
{
char* Path;
/* Setup variables */
filetab[0].f_iocb = inp;
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);
}
/* Add macros that are always defined */
AddNumericMacro ("__CC65__", (VER_MAJOR * 0x100) + (VER_MINOR * 0x10) + VER_PATCH);
/* Strict ANSI macro */
if (ANSI) {
AddNumericMacro ("__STRICT_ANSI__", 1);
}
/* Optimization macros */
if (Optimize) {
AddNumericMacro ("__OPT__", 1);
if (FavourSize == 0) {
AddNumericMacro ("__OPT_i__", 1);
}
if (EnableRegVars) {
AddNumericMacro ("__OPT_r__", 1);
}
if (InlineStdFuncs) {
AddNumericMacro ("__OPT_s__", 1);
}
}
/* Create the base lexical level */
EnterGlobalLevel ();
/* Generate the code generator preamble */
g_preamble ();
/* Ok, start the ball rolling... */
Parse ();
/* Dump literal pool. */
DumpLiteralPool ();
/* Write imported/exported symbols */
EmitExternals ();
if (Debug) {
PrintLiteralStats (stdout);
PrintMacroStats (stdout);
}
/* Leave the main lexical level */
LeaveGlobalLevel ();
/* Print an error report */
ErrorReport ();
}

57
src/cc65/compile.h Normal file
View File

@@ -0,0 +1,57 @@
/*****************************************************************************/
/* */
/* compile.h */
/* */
/* Top level compiler subroutine */
/* */
/* */
/* */
/* (C) 2000 Ullrich von Bassewitz */
/* Wacholderweg 14 */
/* D-70597 Stuttgart */
/* EMail: uz@musoftware.de */
/* */
/* */
/* This software is provided 'as-is', without any expressed or implied */
/* warranty. In no event will the authors be held liable for any damages */
/* arising from the use of this software. */
/* */
/* Permission is granted to anyone to use this software for any purpose, */
/* including commercial applications, and to alter it and redistribute it */
/* freely, subject to the following restrictions: */
/* */
/* 1. The origin of this software must not be misrepresented; you must not */
/* claim that you wrote the original software. If you use this software */
/* in a product, an acknowledgment in the product documentation would be */
/* appreciated but is not required. */
/* 2. Altered source versions must be plainly marked as such, and must not */
/* be misrepresented as being the original software. */
/* 3. This notice may not be removed or altered from any source */
/* distribution. */
/* */
/*****************************************************************************/
#ifndef COMPILE_H
#define COMPILE_H
/*****************************************************************************/
/* Code */
/*****************************************************************************/
void Compile (void);
/* Top level compile routine. Will setup things and call the parser. */
/* End of compile.h */
#endif

View File

@@ -184,10 +184,9 @@ type* GetImplicitFuncType (void)
type* T = TypeAlloc (1 + DECODE_SIZE + 2); type* T = TypeAlloc (1 + DECODE_SIZE + 2);
/* Prepare the function descriptor */ /* Prepare the function descriptor */
F->Flags = FD_IMPLICIT | FD_ELLIPSIS; F->Flags = FD_IMPLICIT | FD_EMPTY | FD_ELLIPSIS;
F->SymTab = &EmptySymTab; F->SymTab = &EmptySymTab;
F->StructTab = &EmptySymTab; F->TagTab = &EmptySymTab;
F->EnumTab = &EmptySymTab;
/* Fill the type string */ /* Fill the type string */
T [0] = T_FUNC; T [0] = T_FUNC;

View File

@@ -48,9 +48,9 @@ static void ParseTypeSpec (DeclSpec* D, int Default);
static void optional_modifiers (void) static void optional_modifiers (void)
/* Eat optional "const" or "volatile" tokens */ /* Eat optional "const" or "volatile" tokens */
{ {
while (curtok == CONST || curtok == VOLATILE) { while (curtok == TOK_CONST || curtok == TOK_VOLATILE) {
/* Skip it */ /* Skip it */
gettok (); NextToken ();
} }
} }
@@ -59,9 +59,9 @@ static void optional_modifiers (void)
static void optionalint (void) static void optionalint (void)
/* Eat an optional "int" token */ /* Eat an optional "int" token */
{ {
if (curtok == INT) { if (curtok == TOK_INT) {
/* Skip it */ /* Skip it */
gettok (); NextToken ();
} }
} }
@@ -70,9 +70,9 @@ static void optionalint (void)
static void optionalsigned (void) static void optionalsigned (void)
/* Eat an optional "signed" token */ /* Eat an optional "signed" token */
{ {
if (curtok == SIGNED) { if (curtok == TOK_SIGNED) {
/* Skip it */ /* Skip it */
gettok (); NextToken ();
} }
} }
@@ -107,29 +107,29 @@ static void ParseStorageClass (DeclSpec* D, unsigned DefStorage)
/* Check the storage class given */ /* Check the storage class given */
switch (curtok) { switch (curtok) {
case EXTERN: case TOK_EXTERN:
D->StorageClass = SC_EXTERN | SC_STATIC; D->StorageClass = SC_EXTERN | SC_STATIC;
gettok (); NextToken ();
break; break;
case STATIC: case TOK_STATIC:
D->StorageClass = SC_STATIC; D->StorageClass = SC_STATIC;
gettok (); NextToken ();
break; break;
case REGISTER: case TOK_REGISTER:
D->StorageClass = SC_REGISTER | SC_STATIC; D->StorageClass = SC_REGISTER | SC_STATIC;
gettok (); NextToken ();
break; break;
case AUTO: case TOK_AUTO:
D->StorageClass = SC_AUTO; D->StorageClass = SC_AUTO;
gettok (); NextToken ();
break; break;
case TYPEDEF: case TOK_TYPEDEF:
D->StorageClass = SC_TYPEDEF; D->StorageClass = SC_TYPEDEF;
gettok (); NextToken ();
break; break;
default: default:
@@ -149,31 +149,31 @@ static void ParseEnumDecl (void)
ident Ident; ident Ident;
/* Accept forward definitions */ /* Accept forward definitions */
if (curtok != LCURLY) { if (curtok != TOK_LCURLY) {
return; return;
} }
/* Skip the opening curly brace */ /* Skip the opening curly brace */
gettok (); NextToken ();
/* Read the enum tags */ /* Read the enum tags */
EnumVal = 0; EnumVal = 0;
while (curtok != RCURLY) { while (curtok != TOK_RCURLY) {
/* We expect an identifier */ /* We expect an identifier */
if (curtok != IDENT) { if (curtok != TOK_IDENT) {
Error (ERR_IDENT_EXPECTED); Error (ERR_IDENT_EXPECTED);
continue; continue;
} }
/* Remember the identifier and skip it */ /* Remember the identifier and skip it */
strcpy (Ident, CurTok.Ident); strcpy (Ident, CurTok.Ident);
gettok (); NextToken ();
/* Check for an assigned value */ /* Check for an assigned value */
if (curtok == ASGN) { if (curtok == TOK_ASSIGN) {
struct expent lval; struct expent lval;
gettok (); NextToken ();
constexpr (&lval); constexpr (&lval);
EnumVal = lval.e_const; EnumVal = lval.e_const;
} }
@@ -182,9 +182,9 @@ static void ParseEnumDecl (void)
AddEnumSym (Ident, EnumVal++); AddEnumSym (Ident, EnumVal++);
/* Check for end of definition */ /* Check for end of definition */
if (curtok != COMMA) if (curtok != TOK_COMMA)
break; break;
gettok (); NextToken ();
} }
ConsumeRCurly (); ConsumeRCurly ();
} }
@@ -201,14 +201,17 @@ static SymEntry* ParseStructDecl (const char* Name, type StructType)
SymEntry* Entry; SymEntry* Entry;
if (curtok != LCURLY) { if (curtok != TOK_LCURLY) {
/* Just a forward declaration. Try to find a struct with the given /* Just a forward declaration. Try to find a struct with the given
* name. If there is none, insert a forward declaration into the * name. If there is none, insert a forward declaration into the
* current lexical level. * current lexical level.
*/ */
Entry = FindStructSym (Name); Entry = FindTagSym (Name);
if (Entry == 0 || Entry->Flags != SC_STRUCT) { if (Entry == 0) {
Entry = AddStructSym (Name, 0, 0); Entry = AddStructSym (Name, 0, 0);
} else if (SymIsLocal (Entry) && (Entry->Flags & SC_STRUCT) == 0) {
/* Already defined in the level but no struct */
Error (ERR_SYMBOL_KIND);
} }
return Entry; return Entry;
} }
@@ -217,14 +220,14 @@ static SymEntry* ParseStructDecl (const char* Name, type StructType)
Entry = AddStructSym (Name, 0, 0); Entry = AddStructSym (Name, 0, 0);
/* Skip the curly brace */ /* Skip the curly brace */
gettok (); NextToken ();
/* Enter a new lexical level for the struct */ /* Enter a new lexical level for the struct */
EnterStructLevel (); EnterStructLevel ();
/* Parse struct fields */ /* Parse struct fields */
Size = 0; Size = 0;
while (curtok != RCURLY) { while (curtok != TOK_RCURLY) {
/* Get the type of the entry */ /* Get the type of the entry */
DeclSpec Spec; DeclSpec Spec;
@@ -251,15 +254,15 @@ static SymEntry* ParseStructDecl (const char* Name, type StructType)
} }
} }
if (curtok != COMMA) if (curtok != TOK_COMMA)
break; break;
gettok (); NextToken ();
} }
ConsumeSemi (); ConsumeSemi ();
} }
/* Skip the closing brace */ /* Skip the closing brace */
gettok (); NextToken ();
/* Remember the symbol table and leave the struct level */ /* Remember the symbol table and leave the struct level */
FieldTab = GetSymTab (); FieldTab = GetSymTab ();
@@ -274,9 +277,9 @@ static SymEntry* ParseStructDecl (const char* Name, type StructType)
static void ParseTypeSpec (DeclSpec* D, int Default) static void ParseTypeSpec (DeclSpec* D, int Default)
/* Parse a type specificier */ /* Parse a type specificier */
{ {
ident Ident; ident Ident;
SymEntry* Entry; SymEntry* Entry;
type StructType; type StructType;
/* Assume have an explicit type */ /* Assume have an explicit type */
D->Flags &= ~DS_DEF_TYPE; D->Flags &= ~DS_DEF_TYPE;
@@ -287,22 +290,22 @@ static void ParseTypeSpec (DeclSpec* D, int Default)
/* Look at the data type */ /* Look at the data type */
switch (curtok) { switch (curtok) {
case VOID: case TOK_VOID:
gettok (); NextToken ();
D->Type[0] = T_VOID; D->Type[0] = T_VOID;
D->Type[1] = T_END; D->Type[1] = T_END;
break; break;
case CHAR: case TOK_CHAR:
gettok (); NextToken ();
D->Type[0] = GetDefaultChar(); D->Type[0] = GetDefaultChar();
D->Type[1] = T_END; D->Type[1] = T_END;
break; break;
case LONG: case TOK_LONG:
gettok (); NextToken ();
if (curtok == UNSIGNED) { if (curtok == TOK_UNSIGNED) {
gettok (); NextToken ();
optionalint (); optionalint ();
D->Type[0] = T_ULONG; D->Type[0] = T_ULONG;
D->Type[1] = T_END; D->Type[1] = T_END;
@@ -314,10 +317,10 @@ static void ParseTypeSpec (DeclSpec* D, int Default)
} }
break; break;
case SHORT: case TOK_SHORT:
gettok (); NextToken ();
if (curtok == UNSIGNED) { if (curtok == TOK_UNSIGNED) {
gettok (); NextToken ();
optionalint (); optionalint ();
D->Type[0] = T_USHORT; D->Type[0] = T_USHORT;
D->Type[1] = T_END; D->Type[1] = T_END;
@@ -329,38 +332,38 @@ static void ParseTypeSpec (DeclSpec* D, int Default)
} }
break; break;
case INT: case TOK_INT:
gettok (); NextToken ();
D->Type[0] = T_INT; D->Type[0] = T_INT;
D->Type[1] = T_END; D->Type[1] = T_END;
break; break;
case SIGNED: case TOK_SIGNED:
gettok (); NextToken ();
switch (curtok) { switch (curtok) {
case CHAR: case TOK_CHAR:
gettok (); NextToken ();
D->Type[0] = T_CHAR; D->Type[0] = T_CHAR;
D->Type[1] = T_END; D->Type[1] = T_END;
break; break;
case SHORT: case TOK_SHORT:
gettok (); NextToken ();
optionalint (); optionalint ();
D->Type[0] = T_SHORT; D->Type[0] = T_SHORT;
D->Type[1] = T_END; D->Type[1] = T_END;
break; break;
case LONG: case TOK_LONG:
gettok (); NextToken ();
optionalint (); optionalint ();
D->Type[0] = T_LONG; D->Type[0] = T_LONG;
D->Type[1] = T_END; D->Type[1] = T_END;
break; break;
case INT: case TOK_INT:
gettok (); NextToken ();
/* FALL THROUGH */ /* FALL THROUGH */
default: default:
@@ -370,32 +373,32 @@ static void ParseTypeSpec (DeclSpec* D, int Default)
} }
break; break;
case UNSIGNED: case TOK_UNSIGNED:
gettok (); NextToken ();
switch (curtok) { switch (curtok) {
case CHAR: case TOK_CHAR:
gettok (); NextToken ();
D->Type[0] = T_UCHAR; D->Type[0] = T_UCHAR;
D->Type[1] = T_END; D->Type[1] = T_END;
break; break;
case SHORT: case TOK_SHORT:
gettok (); NextToken ();
optionalint (); optionalint ();
D->Type[0] = T_USHORT; D->Type[0] = T_USHORT;
D->Type[1] = T_END; D->Type[1] = T_END;
break; break;
case LONG: case TOK_LONG:
gettok (); NextToken ();
optionalint (); optionalint ();
D->Type[0] = T_ULONG; D->Type[0] = T_ULONG;
D->Type[1] = T_END; D->Type[1] = T_END;
break; break;
case INT: case TOK_INT:
gettok (); NextToken ();
/* FALL THROUGH */ /* FALL THROUGH */
default: default:
@@ -405,16 +408,19 @@ static void ParseTypeSpec (DeclSpec* D, int Default)
} }
break; break;
case STRUCT: case TOK_STRUCT:
case UNION: case TOK_UNION:
StructType = (curtok == STRUCT)? T_STRUCT : T_UNION; StructType = (curtok == TOK_STRUCT)? T_STRUCT : T_UNION;
gettok (); NextToken ();
if (curtok == IDENT) { /* */
if (curtok == TOK_IDENT) {
strcpy (Ident, CurTok.Ident); strcpy (Ident, CurTok.Ident);
gettok (); NextToken ();
} else { } else {
AnonName (Ident, (StructType == T_STRUCT)? "struct" : "union"); AnonName (Ident, (StructType == T_STRUCT)? "struct" : "union");
} }
/* Remember we have an extra type decl */
D->Flags |= DS_EXTRA_TYPE;
/* Declare the struct in the current scope */ /* Declare the struct in the current scope */
Entry = ParseStructDecl (Ident, StructType); Entry = ParseStructDecl (Ident, StructType);
/* Encode the struct entry into the type */ /* Encode the struct entry into the type */
@@ -423,22 +429,39 @@ static void ParseTypeSpec (DeclSpec* D, int Default)
D->Type[DECODE_SIZE+1] = T_END; D->Type[DECODE_SIZE+1] = T_END;
break; break;
case ENUM: case TOK_ENUM:
gettok (); NextToken ();
if (curtok != LCURLY) { if (curtok != TOK_LCURLY) {
/* Named enum */ /* Named enum */
Consume (IDENT, ERR_IDENT_EXPECTED); if (curtok == TOK_IDENT) {
/* Find an entry with this name */
Entry = FindTagSym (CurTok.Ident);
if (Entry) {
if (SymIsLocal (Entry) && (Entry->Flags & SC_ENUM) == 0) {
Error (ERR_SYMBOL_KIND);
}
} else {
/* Insert entry into table ### */
}
/* Skip the identifier */
NextToken ();
} else {
Error (ERR_IDENT_EXPECTED);
}
} }
/* Remember we have an extra type decl */
D->Flags |= DS_EXTRA_TYPE;
/* Parse the enum decl */
ParseEnumDecl (); ParseEnumDecl ();
D->Type[0] = T_INT; D->Type[0] = T_INT;
D->Type[1] = T_END; D->Type[1] = T_END;
break; break;
case IDENT: case TOK_IDENT:
Entry = FindSym (CurTok.Ident); Entry = FindSym (CurTok.Ident);
if (Entry && IsTypeDef (Entry)) { if (Entry && IsTypeDef (Entry)) {
/* It's a typedef */ /* It's a typedef */
gettok (); NextToken ();
TypeCpy (D->Type, Entry->Type); TypeCpy (D->Type, Entry->Type);
break; break;
} }
@@ -460,39 +483,116 @@ static void ParseTypeSpec (DeclSpec* D, int Default)
static FuncDesc* ParseFuncDecl (void) static type* ParamTypeCvt (type* T)
/* Parse the argument list of a function. */ /* If T is an array, convert it to a pointer else do nothing. Return the
* resulting type.
*/
{ {
unsigned UnnamedCount = 0; if (IsArray (T)) {
unsigned Offs; T += DECODE_SIZE;
SymEntry* Sym; T[0] = T_PTR;
type* Type; }
return T;
}
/* Create a new function descriptor */
FuncDesc* F = NewFuncDesc ();
/* Enter a new lexical level */
EnterFunctionLevel ();
/* Check for an empty or void parameter list */ static void ParseOldStyleParamList (FuncDesc* F)
if (curtok == RPAREN) { /* Parse an old style (K&R) parameter list */
/* Parameter list is empty */ {
F->Flags |= (FD_EMPTY | FD_ELLIPSIS); /* Parse params */
} else if (curtok == VOID && nxttok == RPAREN) { while (curtok != TOK_RPAREN) {
/* Parameter list declared as void */
gettok (); /* List of identifiers expected */
F->Flags |= FD_VOID_PARAM; if (curtok != TOK_IDENT) {
Error (ERR_IDENT_EXPECTED);
}
/* Create a symbol table entry with type int */
AddLocalSym (CurTok.Ident, type_int, SC_AUTO | SC_PARAM | SC_DEF, 0);
/* Count arguments */
++F->ParamCount;
/* Skip the identifier */
NextToken ();
/* Check for more parameters */
if (curtok == TOK_COMMA) {
NextToken ();
} else {
break;
}
} }
/* Parse params */ /* Skip right paren. We must explicitly check for one here, since some of
while (curtok != RPAREN) { * the breaks above bail out without checking.
*/
ConsumeRParen ();
/* An optional list of type specifications follows */
while (curtok != TOK_LCURLY) {
DeclSpec Spec;
/* Read the declaration specifier */
ParseDeclSpec (&Spec, SC_AUTO, T_INT);
/* We accept only auto and register as storage class specifiers, but
* we ignore all this, since we use auto anyway.
*/
if ((Spec.StorageClass & SC_AUTO) == 0 &&
(Spec.StorageClass & SC_REGISTER) == 0) {
Error (ERR_ILLEGAL_STORAGE_CLASS);
}
/* Parse a comma separated variable list */
while (1) {
Declaration Decl;
/* Read the parameter */
ParseDecl (&Spec, &Decl, DM_NEED_IDENT);
if (Decl.Ident[0] != '\0') {
/* We have a name given. Search for the symbol */
SymEntry* Sym = FindLocalSym (Decl.Ident);
if (Sym) {
/* Found it, change the default type to the one given */
ChangeSymType (Sym, ParamTypeCvt (Decl.Type));
} else {
Error (ERR_UNKNOWN_IDENT, Decl.Ident);
}
}
if (curtok == TOK_COMMA) {
NextToken ();
} else {
break;
}
}
/* Variable list must be semicolon terminated */
ConsumeSemi ();
}
}
static void ParseAnsiParamList (FuncDesc* F)
/* Parse a new style (ANSI) parameter list */
{
/* Parse params */
while (curtok != TOK_RPAREN) {
DeclSpec Spec;
Declaration Decl;
DeclSpec Spec;
Declaration Decl;
/* Allow an ellipsis as last parameter */ /* Allow an ellipsis as last parameter */
if (curtok == ELLIPSIS) { if (curtok == TOK_ELLIPSIS) {
gettok (); NextToken ();
F->Flags |= FD_ELLIPSIS; F->Flags |= FD_ELLIPSIS;
break; break;
} }
@@ -518,30 +618,22 @@ static FuncDesc* ParseFuncDecl (void)
/* Unnamed symbol. Generate a name that is not user accessible, /* Unnamed symbol. Generate a name that is not user accessible,
* then handle the symbol normal. * then handle the symbol normal.
*/ */
AnonName (Decl.Ident, "param"); AnonName (Decl.Ident, "param");
++UnnamedCount; F->Flags |= FD_UNNAMED_PARAMS;
/* Clear defined bit on nonames */ /* Clear defined bit on nonames */
Spec.StorageClass &= ~SC_DEF; Spec.StorageClass &= ~SC_DEF;
} }
/* If the parameter is an array, convert it to a pointer */
Type = Decl.Type;
if (IsArray (Type)) {
Type += DECODE_SIZE;
Type[0] = T_PTR;
}
/* Create a symbol table entry */ /* Create a symbol table entry */
AddLocalSym (Decl.Ident, Type, Spec.StorageClass, 0); AddLocalSym (Decl.Ident, ParamTypeCvt (Decl.Type), Spec.StorageClass, 0);
/* Count arguments */ /* Count arguments */
++F->ParamCount; ++F->ParamCount;
F->ParamSize += SizeOf (Type);
/* Check for more parameters */ /* Check for more parameters */
if (curtok == COMMA) { if (curtok == TOK_COMMA) {
gettok (); NextToken ();
} else { } else {
break; break;
} }
@@ -552,25 +644,64 @@ static FuncDesc* ParseFuncDecl (void)
*/ */
ConsumeRParen (); ConsumeRParen ();
/* Check if this is a function definition */
if (curtok == TOK_LCURLY) {
/* Print an error if in strict ANSI mode and we have unnamed
* parameters.
*/
if (ANSI && (F->Flags & FD_UNNAMED_PARAMS) != 0) {
Error (ERR_MISSING_PARAM_NAME);
}
}
}
static FuncDesc* ParseFuncDecl (void)
/* Parse the argument list of a function. */
{
unsigned Offs;
SymEntry* Sym;
/* Create a new function descriptor */
FuncDesc* F = NewFuncDesc ();
/* Enter a new lexical level */
EnterFunctionLevel ();
/* Check for several special parameter lists */
if (curtok == TOK_RPAREN) {
/* Parameter list is empty */
F->Flags |= (FD_EMPTY | FD_ELLIPSIS);
} else if (curtok == TOK_VOID && nxttok == TOK_RPAREN) {
/* Parameter list declared as void */
NextToken ();
F->Flags |= FD_VOID_PARAM;
} else if (curtok == TOK_IDENT && (nxttok == TOK_COMMA || nxttok == TOK_RPAREN)) {
/* Old style (K&R) function. Assume variable param list. */
F->Flags |= (FD_OLDSTYLE | FD_ELLIPSIS);
}
/* Parse params */
if ((F->Flags & FD_OLDSTYLE) == 0) {
/* New style function */
ParseAnsiParamList (F);
} else {
/* Old style function */
ParseOldStyleParamList (F);
}
/* Assign offsets. If the function has a variable parameter list, /* Assign offsets. If the function has a variable parameter list,
* there's one additional byte (the arg size). * there's one additional byte (the arg size).
*/ */
Offs = (F->Flags & FD_ELLIPSIS)? 1 : 0; Offs = (F->Flags & FD_ELLIPSIS)? 1 : 0;
Sym = GetSymTab()->SymTail; Sym = GetSymTab()->SymTail;
while (Sym) { while (Sym) {
unsigned Size = SizeOf (Sym->Type);
Sym->V.Offs = Offs; Sym->V.Offs = Offs;
Offs += SizeOf (Sym->Type); Offs += Size;
Sym = Sym->PrevSym; F->ParamSize += Size;
} Sym = Sym->PrevSym;
/* Check if this is a function definition */
if (curtok == LCURLY) {
/* Print an error if in strict ANSI mode and we have unnamed
* parameters.
*/
if (ANSI && UnnamedCount > 0) {
Error (ERR_MISSING_PARAM_NAME);
}
} }
/* Leave the lexical level remembering the symbol tables */ /* Leave the lexical level remembering the symbol tables */
@@ -585,22 +716,22 @@ static FuncDesc* ParseFuncDecl (void)
static void Decl (Declaration* D, unsigned Mode) static void Decl (Declaration* D, unsigned Mode)
/* Recursively process declarators. Build a type array in reverse order. */ /* Recursively process declarators. Build a type array in reverse order. */
{ {
if (curtok == STAR) { if (curtok == TOK_STAR) {
gettok (); NextToken ();
/* Allow optional const or volatile modifiers */ /* Allow optional const or volatile modifiers */
optional_modifiers (); optional_modifiers ();
Decl (D, Mode); Decl (D, Mode);
*D->T++ = T_PTR; *D->T++ = T_PTR;
return; return;
} else if (curtok == LPAREN) { } else if (curtok == TOK_LPAREN) {
gettok (); NextToken ();
Decl (D, Mode); Decl (D, Mode);
ConsumeRParen (); ConsumeRParen ();
} else if (curtok == FASTCALL) { } else if (curtok == TOK_FASTCALL) {
/* Remember the current type pointer */ /* Remember the current type pointer */
type* T = D->T; type* T = D->T;
/* Skip the fastcall token */ /* Skip the fastcall token */
gettok (); NextToken ();
/* Parse the function */ /* Parse the function */
Decl (D, Mode); Decl (D, Mode);
/* Set the fastcall flag */ /* Set the fastcall flag */
@@ -612,35 +743,35 @@ static void Decl (Declaration* D, unsigned Mode)
} }
return; return;
} else { } else {
/* Things depend on Mode now: /* Things depend on Mode now:
* - Mode == DM_NEED_IDENT means: * - Mode == DM_NEED_IDENT means:
* we *must* have a type and a variable identifer. * we *must* have a type and a variable identifer.
* - Mode == DM_NO_IDENT means: * - Mode == DM_NO_IDENT means:
* we must have a type but no variable identifer * we must have a type but no variable identifer
* (if there is one, it's not read). * (if there is one, it's not read).
* - Mode == DM_ACCEPT_IDENT means: * - Mode == DM_ACCEPT_IDENT means:
* we *may* have an identifier. If there is an identifier, * we *may* have an identifier. If there is an identifier,
* it is read, but it is no error, if there is none. * it is read, but it is no error, if there is none.
*/ */
if (Mode == DM_NO_IDENT) { if (Mode == DM_NO_IDENT) {
D->Ident[0] = '\0'; D->Ident[0] = '\0';
} else if (curtok == IDENT) { } else if (curtok == TOK_IDENT) {
strcpy (D->Ident, CurTok.Ident); strcpy (D->Ident, CurTok.Ident);
gettok (); NextToken ();
} else { } else {
if (Mode == DM_NEED_IDENT) { if (Mode == DM_NEED_IDENT) {
Error (ERR_IDENT_EXPECTED); Error (ERR_IDENT_EXPECTED);
} }
D->Ident[0] = '\0'; D->Ident[0] = '\0';
return; return;
} }
} }
while (curtok == LBRACK || curtok == LPAREN) { while (curtok == TOK_LBRACK || curtok == TOK_LPAREN) {
if (curtok == LPAREN) { if (curtok == TOK_LPAREN) {
/* Function declaration */ /* Function declaration */
FuncDesc* F; FuncDesc* F;
gettok (); NextToken ();
/* Parse the function declaration */ /* Parse the function declaration */
F = ParseFuncDecl (); F = ParseFuncDecl ();
*D->T++ = T_FUNC; *D->T++ = T_FUNC;
@@ -649,9 +780,9 @@ static void Decl (Declaration* D, unsigned Mode)
} else { } else {
/* Array declaration */ /* Array declaration */
unsigned long Size = 0; unsigned long Size = 0;
gettok (); NextToken ();
/* Read the size if it is given */ /* Read the size if it is given */
if (curtok != RBRACK) { if (curtok != TOK_RBRACK) {
struct expent lval; struct expent lval;
constexpr (&lval); constexpr (&lval);
Size = lval.e_const; Size = lval.e_const;
@@ -730,6 +861,19 @@ void ParseDeclSpec (DeclSpec* D, unsigned DefStorage, int DefType)
void CheckEmptyDecl (const DeclSpec* D)
/* Called after an empty type declaration (that is, a type declaration without
* a variable). Checks if the declaration does really make sense and issues a
* warning if not.
*/
{
if ((D->Flags & DS_EXTRA_TYPE) == 0) {
Warning (WARN_USELESS_DECL);
}
}
static void ParseVoidInit (void) static void ParseVoidInit (void)
/* Parse an initialization of a void variable (special cc65 extension) */ /* Parse an initialization of a void variable (special cc65 extension) */
{ {
@@ -757,7 +901,7 @@ static void ParseVoidInit (void)
case T_PTR: case T_PTR:
case T_ARRAY: case T_ARRAY:
if ((lval.e_flags & E_MCTYPE) == E_TCONST) { if ((lval.e_flags & E_MCTYPE) == E_TCONST) {
/* Make it word sized */ /* Make it word sized */
lval.e_const &= 0xFFFF; lval.e_const &= 0xFFFF;
} }
DefineData (&lval); DefineData (&lval);
@@ -774,12 +918,12 @@ static void ParseVoidInit (void)
} }
if (curtok != COMMA) { if (curtok != TOK_COMMA) {
break; break;
} }
gettok (); NextToken ();
} while (curtok != RCURLY); } while (curtok != TOK_RCURLY);
ConsumeRCurly (); ConsumeRCurly ();
} }
@@ -810,16 +954,16 @@ static void ParseStructInit (type* Type)
/* Get a pointer to the list of symbols */ /* Get a pointer to the list of symbols */
Entry = Tab->SymHead; Entry = Tab->SymHead;
while (curtok != RCURLY) { while (curtok != TOK_RCURLY) {
if (Entry == NULL) { if (Entry == 0) {
Error (ERR_TOO_MANY_INITIALIZERS); Error (ERR_TOO_MANY_INITIALIZERS);
return; return;
} }
ParseInit (Entry->Type); ParseInit (Entry->Type);
Entry = Entry->NextSym; Entry = Entry->NextSym;
if (curtok != COMMA) if (curtok != TOK_COMMA)
break; break;
gettok (); NextToken ();
} }
/* Consume the closing curly brace */ /* Consume the closing curly brace */
@@ -886,22 +1030,22 @@ void ParseInit (type *tptr)
case T_ARRAY: case T_ARRAY:
sz = Decode (tptr + 1); sz = Decode (tptr + 1);
t = tptr + DECODE_SIZE + 1; t = tptr + DECODE_SIZE + 1;
if ((t [0] == T_CHAR || t [0] == T_UCHAR) && curtok == SCONST) { if ((t [0] == T_CHAR || t [0] == T_UCHAR) && curtok == TOK_SCONST) {
str = GetLiteral (curval); str = GetLiteral (curval);
count = strlen (str) + 1; count = strlen (str) + 1;
TranslateLiteralPool (curval); /* Translate into target charset */ TranslateLiteralPool (curval); /* Translate into target charset */
g_defbytes (str, count); g_defbytes (str, count);
ResetLiteralOffs (curval); /* Remove string from pool */ ResetLiteralOffs (curval); /* Remove string from pool */
gettok (); NextToken ();
} else { } else {
ConsumeLCurly (); ConsumeLCurly ();
count = 0; count = 0;
while (curtok != RCURLY) { while (curtok != TOK_RCURLY) {
ParseInit (tptr + DECODE_SIZE + 1); ParseInit (tptr + DECODE_SIZE + 1);
++count; ++count;
if (curtok != COMMA) if (curtok != TOK_COMMA)
break; break;
gettok (); NextToken ();
} }
ConsumeRCurly (); ConsumeRCurly ();
} }

View File

@@ -23,15 +23,16 @@
/* Masks for the Flags field in DeclSpec */ /* Masks for the Flags field in DeclSpec */
#define DS_DEF_STORAGE 0x0001U /* Default storage class used */ #define DS_DEF_STORAGE 0x0001U /* Default storage class used */
#define DS_DEF_TYPE 0x0002U /* Default type used */ #define DS_DEF_TYPE 0x0002U /* Default type used */
#define DS_EXTRA_TYPE 0x0004U /* Extra type declared */
/* Result of ParseDeclSpec */ /* Result of ParseDeclSpec */
typedef struct DeclSpec DeclSpec; typedef struct DeclSpec DeclSpec;
struct DeclSpec { struct DeclSpec {
unsigned StorageClass; /* One of the SC_xxx flags */ unsigned StorageClass; /* One of the SC_xxx flags */
type Type [MAXTYPELEN]; /* Type of the declaration spec */ type Type [MAXTYPELEN]; /* Type of the declaration spec */
unsigned Flags; /* Bitmapped flags */ unsigned Flags; /* Bitmapped flags */
}; };
/* Result of ParseDecl */ /* Result of ParseDecl */
@@ -66,6 +67,12 @@ void ParseDecl (const DeclSpec* Spec, Declaration* D, unsigned Mode);
void ParseDeclSpec (DeclSpec* D, unsigned DefStorage, int DefType); void ParseDeclSpec (DeclSpec* D, unsigned DefStorage, int DefType);
/* Parse a declaration specification */ /* Parse a declaration specification */
void CheckEmptyDecl (const DeclSpec* D);
/* Called after an empty type declaration (that is, a type declaration without
* a variable). Checks if the declaration does really make sense and issues a
* warning if not.
*/
void ParseInit (type* tptr); void ParseInit (type* tptr);
/* Parse initialization of variables */ /* Parse initialization of variables */

View File

@@ -65,6 +65,7 @@ static char* WarnMsg [WARN_COUNT-1] = {
"`%s' is defined but never used", "`%s' is defined but never used",
"Constant is long", "Constant is long",
"`/*' found inside a comment", "`/*' found inside a comment",
"Useless declaration",
}; };
@@ -147,6 +148,7 @@ static char* ErrMsg [ERR_COUNT-1] = {
"Illegal size of data type", "Illegal size of data type",
"__fastcall__ is not allowed for C functions", "__fastcall__ is not allowed for C functions",
"Variable has unknown size", "Variable has unknown size",
"Unknown identifier: `%s'",
}; };

View File

@@ -60,7 +60,8 @@ enum Warnings {
WARN_UNUSED_ITEM, WARN_UNUSED_ITEM,
WARN_CONSTANT_IS_LONG, WARN_CONSTANT_IS_LONG,
WARN_NESTED_COMMENT, WARN_NESTED_COMMENT,
WARN_COUNT /* Warning count */ WARN_USELESS_DECL,
WARN_COUNT /* Warning count */
}; };
/* Error numbers */ /* Error numbers */
@@ -142,6 +143,7 @@ enum Errors {
ERR_ILLEGAL_SIZE, ERR_ILLEGAL_SIZE,
ERR_FASTCALL, ERR_FASTCALL,
ERR_UNKNOWN_SIZE, ERR_UNKNOWN_SIZE,
ERR_UNKNOWN_IDENT,
ERR_COUNT /* Error count */ ERR_COUNT /* Error count */
}; };

View File

@@ -49,30 +49,30 @@ typedef struct {
} GenDesc; } GenDesc;
/* Descriptors for the operations */ /* Descriptors for the operations */
static GenDesc GenMUL = { STAR, GEN_NOPUSH, g_mul }; static GenDesc GenMUL = { TOK_STAR, GEN_NOPUSH, g_mul };
static GenDesc GenDIV = { DIV, GEN_NOPUSH, g_div }; static GenDesc GenDIV = { TOK_DIV, GEN_NOPUSH, g_div };
static GenDesc GenMOD = { MOD, GEN_NOPUSH, g_mod }; static GenDesc GenMOD = { TOK_MOD, GEN_NOPUSH, g_mod };
static GenDesc GenASL = { ASL, GEN_NOPUSH, g_asl }; static GenDesc GenASL = { TOK_SHL, GEN_NOPUSH, g_asl };
static GenDesc GenASR = { ASR, GEN_NOPUSH, g_asr }; static GenDesc GenASR = { TOK_SHR, GEN_NOPUSH, g_asr };
static GenDesc GenLT = { LT, GEN_NOPUSH, g_lt }; static GenDesc GenLT = { TOK_LT, GEN_NOPUSH, g_lt };
static GenDesc GenLE = { LE, GEN_NOPUSH, g_le }; static GenDesc GenLE = { TOK_LE, GEN_NOPUSH, g_le };
static GenDesc GenGE = { GE, GEN_NOPUSH, g_ge }; static GenDesc GenGE = { TOK_GE, GEN_NOPUSH, g_ge };
static GenDesc GenGT = { GT, GEN_NOPUSH, g_gt }; static GenDesc GenGT = { TOK_GT, GEN_NOPUSH, g_gt };
static GenDesc GenEQ = { EQ, GEN_NOPUSH, g_eq }; static GenDesc GenEQ = { TOK_EQ, GEN_NOPUSH, g_eq };
static GenDesc GenNE = { NE, GEN_NOPUSH, g_ne }; static GenDesc GenNE = { TOK_NE, GEN_NOPUSH, g_ne };
static GenDesc GenAND = { AMP, GEN_NOPUSH, g_and }; static GenDesc GenAND = { TOK_AND, GEN_NOPUSH, g_and };
static GenDesc GenXOR = { XOR, GEN_NOPUSH, g_xor }; static GenDesc GenXOR = { TOK_XOR, GEN_NOPUSH, g_xor };
static GenDesc GenOR = { BAR, GEN_NOPUSH, g_or }; static GenDesc GenOR = { TOK_OR, GEN_NOPUSH, g_or };
static GenDesc GenPASGN = { PASGN, GEN_NOPUSH, g_add }; static GenDesc GenPASGN = { TOK_PLUS_ASSIGN, GEN_NOPUSH, g_add };
static GenDesc GenSASGN = { SASGN, GEN_NOPUSH, g_sub }; static GenDesc GenSASGN = { TOK_MINUS_ASSIGN, GEN_NOPUSH, g_sub };
static GenDesc GenMASGN = { MASGN, GEN_NOPUSH, g_mul }; static GenDesc GenMASGN = { TOK_MUL_ASSIGN, GEN_NOPUSH, g_mul };
static GenDesc GenDASGN = { DASGN, GEN_NOPUSH, g_div }; static GenDesc GenDASGN = { TOK_DIV_ASSIGN, GEN_NOPUSH, g_div };
static GenDesc GenMOASGN = { MOASGN, GEN_NOPUSH, g_mod }; static GenDesc GenMOASGN = { TOK_MOD_ASSIGN, GEN_NOPUSH, g_mod };
static GenDesc GenSLASGN = { SLASGN, GEN_NOPUSH, g_asl }; static GenDesc GenSLASGN = { TOK_SHL_ASSIGN, GEN_NOPUSH, g_asl };
static GenDesc GenSRASGN = { SRASGN, GEN_NOPUSH, g_asr }; static GenDesc GenSRASGN = { TOK_SHR_ASSIGN, GEN_NOPUSH, g_asr };
static GenDesc GenAASGN = { AASGN, GEN_NOPUSH, g_and }; static GenDesc GenAASGN = { TOK_AND_ASSIGN, GEN_NOPUSH, g_and };
static GenDesc GenXOASGN = { XOASGN, GEN_NOPUSH, g_xor }; static GenDesc GenXOASGN = { TOK_XOR_ASSIGN, GEN_NOPUSH, g_xor };
static GenDesc GenOASGN = { OASGN, GEN_NOPUSH, g_or }; static GenDesc GenOASGN = { TOK_OR_ASSIGN, GEN_NOPUSH, g_or };
@@ -346,37 +346,37 @@ static int kcalc (int tok, long val1, long val2)
/* Calculate an operation with left and right operand constant. */ /* Calculate an operation with left and right operand constant. */
{ {
switch (tok) { switch (tok) {
case EQ: case TOK_EQ:
return (val1 == val2); return (val1 == val2);
case NE: case TOK_NE:
return (val1 != val2); return (val1 != val2);
case LT: case TOK_LT:
return (val1 < val2); return (val1 < val2);
case LE: case TOK_LE:
return (val1 <= val2); return (val1 <= val2);
case GE: case TOK_GE:
return (val1 >= val2); return (val1 >= val2);
case GT: case TOK_GT:
return (val1 > val2); return (val1 > val2);
case BAR: case TOK_OR:
return (val1 | val2); return (val1 | val2);
case XOR: case TOK_XOR:
return (val1 ^ val2); return (val1 ^ val2);
case AMP: case TOK_AND:
return (val1 & val2); return (val1 & val2);
case ASR: case TOK_SHR:
return (val1 >> val2); return (val1 >> val2);
case ASL: case TOK_SHL:
return (val1 << val2); return (val1 << val2);
case STAR: case TOK_STAR:
return (val1 * val2); return (val1 * val2);
case DIV: case TOK_DIV:
if (val2 == 0) { if (val2 == 0) {
Error (ERR_DIV_BY_ZERO); Error (ERR_DIV_BY_ZERO);
return 0x7FFFFFFF; return 0x7FFFFFFF;
} }
return (val1 / val2); return (val1 / val2);
case MOD: case TOK_MOD:
if (val2 == 0) { if (val2 == 0) {
Error (ERR_MOD_BY_ZERO); Error (ERR_MOD_BY_ZERO);
return 0; return 0;
@@ -411,11 +411,11 @@ static int istypeexpr (void)
{ {
SymEntry* Entry; SymEntry* Entry;
return curtok == LPAREN && ( return curtok == TOK_LPAREN && (
(nxttok >= FIRSTTYPE && nxttok <= LASTTYPE) || (nxttok >= TOK_FIRSTTYPE && nxttok <= TOK_LASTTYPE) ||
(nxttok == CONST) || (nxttok == TOK_CONST) ||
(nxttok == IDENT && (nxttok == TOK_IDENT &&
(Entry = FindSym (NextTok.Ident)) != 0 && (Entry = FindSym (NextTok.Ident)) != 0 &&
IsTypeDef (Entry)) IsTypeDef (Entry))
); );
} }
@@ -531,7 +531,7 @@ static void callfunction (struct expent* lval)
ParamSize = 0; ParamSize = 0;
ParamCount = 0; ParamCount = 0;
Ellipsis = 0; Ellipsis = 0;
while (curtok != RPAREN) { while (curtok != TOK_RPAREN) {
/* Add a hint for the optimizer */ /* Add a hint for the optimizer */
AddCodeHint ("param:start"); AddCodeHint ("param:start");
@@ -606,10 +606,10 @@ static void callfunction (struct expent* lval)
AddCodeHint ("param:end"); AddCodeHint ("param:end");
/* Check for end of argument list */ /* Check for end of argument list */
if (curtok != COMMA) { if (curtok != TOK_COMMA) {
break; break;
} }
gettok (); NextToken ();
} }
/* We need the closing bracket here */ /* We need the closing bracket here */
@@ -644,13 +644,13 @@ void doasm (void)
*/ */
{ {
/* Skip the ASM */ /* Skip the ASM */
gettok (); NextToken ();
/* Need left parenthesis */ /* Need left parenthesis */
ConsumeLParen (); ConsumeLParen ();
/* String literal */ /* String literal */
if (curtok != SCONST) { if (curtok != TOK_SCONST) {
Error (ERR_STRLIT_EXPECTED); Error (ERR_STRLIT_EXPECTED);
} else { } else {
/* Write the string directly into the output, followed by a newline */ /* Write the string directly into the output, followed by a newline */
@@ -665,7 +665,7 @@ void doasm (void)
} }
/* Skip the string token */ /* Skip the string token */
gettok (); NextToken ();
/* Closing paren needed */ /* Closing paren needed */
ConsumeRParen (); ConsumeRParen ();
@@ -682,19 +682,19 @@ static int primary (struct expent* lval)
lval->e_test = 0; lval->e_test = 0;
/* Character and integer constants. */ /* Character and integer constants. */
if (curtok == ICONST || curtok == CCONST) { if (curtok == TOK_ICONST || curtok == TOK_CCONST) {
lval->e_flags = E_MCONST | E_TCONST; lval->e_flags = E_MCONST | E_TCONST;
lval->e_tptr = curtype; lval->e_tptr = curtype;
lval->e_const = curval; lval->e_const = curval;
gettok (); NextToken ();
return 0; return 0;
} }
/* Process parenthesized subexpression by calling the whole parser /* Process parenthesized subexpression by calling the whole parser
* recursively. * recursively.
*/ */
if (curtok == LPAREN) { if (curtok == TOK_LPAREN) {
gettok (); NextToken ();
memset (lval, 0, sizeof (*lval)); /* Remove any attributes */ memset (lval, 0, sizeof (*lval)); /* Remove any attributes */
k = hie0 (lval); k = hie0 (lval);
ConsumeRParen (); ConsumeRParen ();
@@ -713,7 +713,7 @@ static int primary (struct expent* lval)
} }
/* Identifier? */ /* Identifier? */
if (curtok == IDENT) { if (curtok == TOK_IDENT) {
SymEntry* Sym; SymEntry* Sym;
ident Ident; ident Ident;
@@ -725,7 +725,7 @@ static int primary (struct expent* lval)
if (Sym) { if (Sym) {
/* We found the symbol - skip the name token */ /* We found the symbol - skip the name token */
gettok (); NextToken ();
/* The expression type is the symbol type */ /* The expression type is the symbol type */
lval->e_tptr = Sym->Type; lval->e_tptr = Sym->Type;
@@ -791,10 +791,10 @@ static int primary (struct expent* lval)
/* We did not find the symbol. Remember the name, then skip it */ /* We did not find the symbol. Remember the name, then skip it */
strcpy (Ident, CurTok.Ident); strcpy (Ident, CurTok.Ident);
gettok (); NextToken ();
/* IDENT is either an auto-declared function or an undefined variable. */ /* IDENT is either an auto-declared function or an undefined variable. */
if (curtok == LPAREN) { if (curtok == TOK_LPAREN) {
/* Declare a function returning int. For that purpose, prepare a /* Declare a function returning int. For that purpose, prepare a
* function signature for a function having an empty param list * function signature for a function having an empty param list
* and returning int. * and returning int.
@@ -821,16 +821,16 @@ static int primary (struct expent* lval)
} }
/* String literal? */ /* String literal? */
if (curtok == SCONST) { if (curtok == TOK_SCONST) {
lval->e_flags = E_MCONST | E_TLIT; lval->e_flags = E_MCONST | E_TLIT;
lval->e_const = curval; lval->e_const = curval;
lval->e_tptr = GetCharArrayType (strlen (GetLiteral (curval))); lval->e_tptr = GetCharArrayType (strlen (GetLiteral (curval)));
gettok (); NextToken ();
return 0; return 0;
} }
/* ASM statement? */ /* ASM statement? */
if (curtok == ASM) { if (curtok == TOK_ASM) {
doasm (); doasm ();
lval->e_tptr = type_void; lval->e_tptr = type_void;
lval->e_flags = E_MEXPR; lval->e_flags = E_MEXPR;
@@ -839,12 +839,12 @@ static int primary (struct expent* lval)
} }
/* __AX__ and __EAX__ pseudo values? */ /* __AX__ and __EAX__ pseudo values? */
if (curtok == AX || curtok == EAX) { if (curtok == TOK_AX || curtok == TOK_EAX) {
lval->e_tptr = (curtok == AX)? type_uint : type_ulong; lval->e_tptr = (curtok == TOK_AX)? type_uint : type_ulong;
lval->e_flags = E_MREG; lval->e_flags = E_MREG;
lval->e_test &= ~E_CC; lval->e_test &= ~E_CC;
lval->e_const = 0; lval->e_const = 0;
gettok (); NextToken ();
return 1; /* May be used as lvalue */ return 1; /* May be used as lvalue */
} }
@@ -873,7 +873,7 @@ static int arrayref (int k, struct expent* lval)
/* Skip the bracket */ /* Skip the bracket */
gettok (); NextToken ();
/* Get the type of left side */ /* Get the type of left side */
tptr1 = lval->e_tptr; tptr1 = lval->e_tptr;
@@ -1098,8 +1098,8 @@ static int structref (int k, struct expent* lval)
int flags; int flags;
/* Skip the token and check for an identifier */ /* Skip the token and check for an identifier */
gettok (); NextToken ();
if (curtok != IDENT) { if (curtok != TOK_IDENT) {
Error (ERR_IDENT_EXPECTED); Error (ERR_IDENT_EXPECTED);
lval->e_tptr = type_int; lval->e_tptr = type_int;
return 0; return 0;
@@ -1107,7 +1107,7 @@ static int structref (int k, struct expent* lval)
/* Get the symbol table entry and check for a struct field */ /* Get the symbol table entry and check for a struct field */
strcpy (Ident, CurTok.Ident); strcpy (Ident, CurTok.Ident);
gettok (); NextToken ();
Field = FindStructField (lval->e_tptr, Ident); Field = FindStructField (lval->e_tptr, Ident);
if (Field == 0) { if (Field == 0) {
Error (ERR_STRUCT_FIELD_MISMATCH, Ident); Error (ERR_STRUCT_FIELD_MISMATCH, Ident);
@@ -1143,22 +1143,22 @@ static int hie11 (struct expent *lval)
k = primary (lval); k = primary (lval);
if (curtok < LBRACK || curtok > PREF) { if (curtok < TOK_LBRACK || curtok > TOK_PTR_REF) {
/* Not for us */ /* Not for us */
return k; return k;
} }
while (1) { while (1) {
if (curtok == LBRACK) { if (curtok == TOK_LBRACK) {
/* Array reference */ /* Array reference */
k = arrayref (k, lval); k = arrayref (k, lval);
} else if (curtok == LPAREN) { } else if (curtok == TOK_LPAREN) {
/* Function call. Skip the opening parenthesis */ /* Function call. Skip the opening parenthesis */
gettok (); NextToken ();
tptr = lval->e_tptr; tptr = lval->e_tptr;
if (IsFunc (tptr) || IsFuncPtr (tptr)) { if (IsFunc (tptr) || IsFuncPtr (tptr)) {
if (IsFuncPtr (tptr)) { if (IsFuncPtr (tptr)) {
@@ -1175,14 +1175,14 @@ static int hie11 (struct expent *lval)
} }
k = 0; k = 0;
} else if (curtok == DOT) { } else if (curtok == TOK_DOT) {
if (!IsStruct (lval->e_tptr)) { if (!IsStruct (lval->e_tptr)) {
Error (ERR_STRUCT_EXPECTED); Error (ERR_STRUCT_EXPECTED);
} }
k = structref (0, lval); k = structref (0, lval);
} else if (curtok == PREF) { } else if (curtok == TOK_PTR_REF) {
tptr = lval->e_tptr; tptr = lval->e_tptr;
if (tptr[0] != T_PTR || (tptr[1] & T_STRUCT) == 0) { if (tptr[0] != T_PTR || (tptr[1] & T_STRUCT) == 0) {
@@ -1242,7 +1242,7 @@ static void pre_incdec (struct expent* lval, void (*inc) (unsigned, unsigned lon
unsigned flags; unsigned flags;
unsigned long val; unsigned long val;
gettok (); NextToken ();
if ((k = hie10 (lval)) == 0) { if ((k = hie10 (lval)) == 0) {
Error (ERR_LVALUE_EXPECTED); Error (ERR_LVALUE_EXPECTED);
return; return;
@@ -1321,7 +1321,7 @@ static void post_incdec (struct expent *lval, int k, void (*inc) (unsigned, unsi
{ {
unsigned flags; unsigned flags;
gettok (); NextToken ();
if (k == 0) { if (k == 0) {
Error (ERR_LVALUE_EXPECTED); Error (ERR_LVALUE_EXPECTED);
return; return;
@@ -1360,15 +1360,15 @@ static void unaryop (int tok, struct expent* lval)
int k; int k;
unsigned flags; unsigned flags;
gettok (); NextToken ();
k = hie10 (lval); k = hie10 (lval);
if (k == 0 && lval->e_flags & E_MCONST) { if (k == 0 && lval->e_flags & E_MCONST) {
/* Value is constant */ /* Value is constant */
switch (tok) { switch (tok) {
case MINUS: lval->e_const = -lval->e_const; break; case TOK_MINUS: lval->e_const = -lval->e_const; break;
case PLUS: break; case TOK_PLUS: break;
case COMP: lval->e_const = ~lval->e_const; break; case TOK_COMP: lval->e_const = ~lval->e_const; break;
default: Internal ("Unexpected token: %d", tok); default: Internal ("Unexpected token: %d", tok);
} }
} else { } else {
/* Value is not constant */ /* Value is not constant */
@@ -1379,9 +1379,9 @@ static void unaryop (int tok, struct expent* lval)
/* Handle the operation */ /* Handle the operation */
switch (tok) { switch (tok) {
case MINUS: g_neg (flags); break; case TOK_MINUS: g_neg (flags); break;
case PLUS: break; case TOK_PLUS: break;
case COMP: g_com (flags); break; case TOK_COMP: g_com (flags); break;
default: Internal ("Unexpected token: %d", tok); default: Internal ("Unexpected token: %d", tok);
} }
lval->e_flags = E_MEXPR; lval->e_flags = E_MEXPR;
@@ -1398,7 +1398,7 @@ static int typecast (struct expent* lval)
unsigned rflags; unsigned rflags;
/* Skip the left paren */ /* Skip the left paren */
gettok (); NextToken ();
/* Read the type */ /* Read the type */
ParseType (Type); ParseType (Type);
@@ -1438,22 +1438,22 @@ static int hie10 (struct expent* lval)
switch (curtok) { switch (curtok) {
case INC: case TOK_INC:
pre_incdec (lval, g_inc); pre_incdec (lval, g_inc);
return 0; return 0;
case DEC: case TOK_DEC:
pre_incdec (lval, g_dec); pre_incdec (lval, g_dec);
return 0; return 0;
case PLUS: case TOK_PLUS:
case MINUS: case TOK_MINUS:
case COMP: case TOK_COMP:
unaryop (curtok, lval); unaryop (curtok, lval);
return 0; return 0;
case BANG: case TOK_BOOL_NOT:
gettok (); NextToken ();
if (evalexpr (CF_NONE, hie10, lval) == 0) { if (evalexpr (CF_NONE, hie10, lval) == 0) {
/* Constant expression */ /* Constant expression */
lval->e_const = !lval->e_const; lval->e_const = !lval->e_const;
@@ -1464,8 +1464,8 @@ static int hie10 (struct expent* lval)
} }
return 0; /* expr not storable */ return 0; /* expr not storable */
case STAR: case TOK_STAR:
gettok (); NextToken ();
if (evalexpr (CF_NONE, hie10, lval) != 0) { if (evalexpr (CF_NONE, hie10, lval) != 0) {
/* Expression is not const, indirect value loaded into primary */ /* Expression is not const, indirect value loaded into primary */
lval->e_flags = E_MEXPR; lval->e_flags = E_MEXPR;
@@ -1479,11 +1479,11 @@ static int hie10 (struct expent* lval)
} }
return 1; return 1;
case AMP: case TOK_AND:
gettok (); NextToken ();
k = hie10 (lval); k = hie10 (lval);
if (k == 0) { if (k == 0) {
/* Allow the & operator with an array */ /* Allow the & operator with an array */
if (!IsArray (lval->e_tptr)) { if (!IsArray (lval->e_tptr)) {
Error (ERR_ILLEGAL_ADDRESS); Error (ERR_ILLEGAL_ADDRESS);
} }
@@ -1495,11 +1495,11 @@ static int hie10 (struct expent* lval)
} }
return 0; return 0;
case SIZEOF: case TOK_SIZEOF:
gettok (); NextToken ();
if (istypeexpr ()) { if (istypeexpr ()) {
type Type[MAXTYPELEN]; type Type[MAXTYPELEN];
gettok (); NextToken ();
lval->e_const = SizeOf (ParseType (Type)); lval->e_const = SizeOf (ParseType (Type));
ConsumeRParen (); ConsumeRParen ();
} else { } else {
@@ -1524,11 +1524,11 @@ static int hie10 (struct expent* lval)
k = hie11 (lval); k = hie11 (lval);
switch (curtok) { switch (curtok) {
case INC: case TOK_INC:
post_incdec (lval, k, g_inc); post_incdec (lval, k, g_inc);
return 0; return 0;
case DEC: case TOK_DEC:
post_incdec (lval, k, g_dec); post_incdec (lval, k, g_dec);
return 0; return 0;
@@ -1550,7 +1550,7 @@ static int hie_internal (GenDesc** ops, /* List of generators */
CodeMark Mark1; CodeMark Mark1;
CodeMark Mark2; CodeMark Mark2;
GenDesc* Gen; GenDesc* Gen;
int tok; /* The operator token */ token_t tok; /* The operator token */
unsigned ltype, type; unsigned ltype, type;
int rconst; /* Operand is a constant */ int rconst; /* Operand is a constant */
@@ -1570,7 +1570,7 @@ static int hie_internal (GenDesc** ops, /* List of generators */
/* Remember the operator token, then skip it */ /* Remember the operator token, then skip it */
tok = curtok; tok = curtok;
gettok (); NextToken ();
/* Get the lhs on stack */ /* Get the lhs on stack */
Mark1 = GetCodePos (); Mark1 = GetCodePos ();
@@ -1619,9 +1619,9 @@ static int hie_internal (GenDesc** ops, /* List of generators */
/* Second value is constant - check for div */ /* Second value is constant - check for div */
type |= CF_CONST; type |= CF_CONST;
rtype |= CF_CONST; rtype |= CF_CONST;
if (tok == DIV && lval2.e_const == 0) { if (tok == TOK_DIV && lval2.e_const == 0) {
Error (ERR_DIV_BY_ZERO); Error (ERR_DIV_BY_ZERO);
} else if (tok == MOD && lval2.e_const == 0) { } else if (tok == TOK_MOD && lval2.e_const == 0) {
Error (ERR_MOD_BY_ZERO); Error (ERR_MOD_BY_ZERO);
} }
if ((Gen->Flags & GEN_NOPUSH) != 0) { if ((Gen->Flags & GEN_NOPUSH) != 0) {
@@ -1659,7 +1659,7 @@ static int hie_compare (GenDesc** ops, /* List of generators */
CodeMark Mark1; CodeMark Mark1;
CodeMark Mark2; CodeMark Mark2;
GenDesc* Gen; GenDesc* Gen;
int tok; /* The operator token */ token_t tok; /* The operator token */
unsigned ltype; unsigned ltype;
int rconst; /* Operand is a constant */ int rconst; /* Operand is a constant */
@@ -1670,7 +1670,7 @@ static int hie_compare (GenDesc** ops, /* List of generators */
/* Remember the operator token, then skip it */ /* Remember the operator token, then skip it */
tok = curtok; tok = curtok;
gettok (); NextToken ();
/* Get the lhs on stack */ /* Get the lhs on stack */
Mark1 = GetCodePos (); Mark1 = GetCodePos ();
@@ -1800,7 +1800,7 @@ static void parseadd (int k, struct expent* lval)
/* Skip the PLUS token */ /* Skip the PLUS token */
gettok (); NextToken ();
/* Get the left hand side type, initialize operation flags */ /* Get the left hand side type, initialize operation flags */
lhst = lval->e_tptr; lhst = lval->e_tptr;
@@ -1972,7 +1972,7 @@ static void parsesub (int k, struct expent* lval)
/* Skip the MINUS token */ /* Skip the MINUS token */
gettok (); NextToken ();
/* Get the left hand side type, initialize operation flags */ /* Get the left hand side type, initialize operation flags */
lhst = lval->e_tptr; lhst = lval->e_tptr;
@@ -2126,9 +2126,9 @@ static int hie8 (struct expent* lval)
/* Process + and - binary operators. */ /* Process + and - binary operators. */
{ {
int k = hie9 (lval); int k = hie9 (lval);
while (curtok == PLUS || curtok == MINUS) { while (curtok == TOK_PLUS || curtok == TOK_MINUS) {
if (curtok == PLUS) { if (curtok == TOK_PLUS) {
parseadd (k, lval); parseadd (k, lval);
} else { } else {
parsesub (k, lval); parsesub (k, lval);
@@ -2222,7 +2222,7 @@ static int hieAnd (struct expent* lval, unsigned TrueLab, int* BoolOp)
struct expent lval2; struct expent lval2;
k = hie2 (lval); k = hie2 (lval);
if (curtok == DAMP) { if (curtok == TOK_BOOL_AND) {
/* Tell our caller that we're evaluating a boolean */ /* Tell our caller that we're evaluating a boolean */
*BoolOp = 1; *BoolOp = 1;
@@ -2242,10 +2242,10 @@ static int hieAnd (struct expent* lval, unsigned TrueLab, int* BoolOp)
g_falsejump (CF_NONE, lab); g_falsejump (CF_NONE, lab);
/* Parse more boolean and's */ /* Parse more boolean and's */
while (curtok == DAMP) { while (curtok == TOK_BOOL_AND) {
/* Skip the && */ /* Skip the && */
gettok (); NextToken ();
/* Get rhs */ /* Get rhs */
k = hie2 (&lval2); k = hie2 (&lval2);
@@ -2255,7 +2255,7 @@ static int hieAnd (struct expent* lval, unsigned TrueLab, int* BoolOp)
exprhs (CF_FORCECHAR, k, &lval2); exprhs (CF_FORCECHAR, k, &lval2);
/* Do short circuit evaluation */ /* Do short circuit evaluation */
if (curtok == DAMP) { if (curtok == TOK_BOOL_AND) {
g_falsejump (CF_NONE, lab); g_falsejump (CF_NONE, lab);
} else { } else {
/* Last expression - will evaluate to true */ /* Last expression - will evaluate to true */
@@ -2293,7 +2293,7 @@ static int hieOr (struct expent *lval)
k = hieAnd (lval, TrueLab, &BoolOp); k = hieAnd (lval, TrueLab, &BoolOp);
/* Any boolean or's? */ /* Any boolean or's? */
if (curtok == DBAR) { if (curtok == TOK_BOOL_OR) {
/* If the expr hasn't set condition codes, set the force-test flag */ /* If the expr hasn't set condition codes, set the force-test flag */
if ((lval->e_test & E_CC) == 0) { if ((lval->e_test & E_CC) == 0) {
@@ -2314,10 +2314,10 @@ static int hieOr (struct expent *lval)
BoolOp = 1; BoolOp = 1;
/* while there's more expr */ /* while there's more expr */
while (curtok == DBAR) { while (curtok == TOK_BOOL_OR) {
/* skip the || */ /* skip the || */
gettok (); NextToken ();
/* Get a subexpr */ /* Get a subexpr */
AndOp = 0; AndOp = 0;
@@ -2333,7 +2333,7 @@ static int hieOr (struct expent *lval)
*/ */
#if 0 #if 0
/* Seems this sometimes generates wrong code */ /* Seems this sometimes generates wrong code */
if (curtok == DBAR && !AndOp) { if (curtok == TOK_BOOL_OR && !AndOp) {
g_truejump (CF_NONE, TrueLab); g_truejump (CF_NONE, TrueLab);
} }
#else #else
@@ -2376,8 +2376,8 @@ static int hieQuest (struct expent *lval)
k = hieOr (lval); k = hieOr (lval);
if (curtok == QUEST) { if (curtok == TOK_QUEST) {
gettok (); NextToken ();
if ((lval->e_test & E_CC) == 0) { if ((lval->e_test & E_CC) == 0) {
/* Condition codes not set, force a test */ /* Condition codes not set, force a test */
lval->e_test |= E_FORCETEST; lval->e_test |= E_FORCETEST;
@@ -2481,7 +2481,7 @@ static void opeq (GenDesc* Gen, struct expent *lval, int k)
CodeMark Mark; CodeMark Mark;
int MustScale; int MustScale;
gettok (); NextToken ();
if (k == 0) { if (k == 0) {
Error (ERR_LVALUE_EXPECTED); Error (ERR_LVALUE_EXPECTED);
return; return;
@@ -2578,7 +2578,7 @@ static void addsubeq (GenDesc* Gen, struct expent *lval, int k)
} }
/* Skip the operator */ /* Skip the operator */
gettok (); NextToken ();
/* Check if we have a pointer expression and must scale rhs */ /* Check if we have a pointer expression and must scale rhs */
MustScale = (lval->e_tptr [0] == T_PTR); MustScale = (lval->e_tptr [0] == T_PTR);
@@ -2609,14 +2609,14 @@ static void addsubeq (GenDesc* Gen, struct expent *lval, int k)
if (lval->e_flags & E_MGLOBAL) { if (lval->e_flags & E_MGLOBAL) {
/* Static variable */ /* Static variable */
flags |= GlobalModeFlags (lval->e_flags); flags |= GlobalModeFlags (lval->e_flags);
if (Gen->Tok == PASGN) { if (Gen->Tok == TOK_PLUS_ASSIGN) {
g_addeqstatic (flags, lval->e_name, lval->e_const, lval2.e_const); g_addeqstatic (flags, lval->e_name, lval->e_const, lval2.e_const);
} else { } else {
g_subeqstatic (flags, lval->e_name, lval->e_const, lval2.e_const); g_subeqstatic (flags, lval->e_name, lval->e_const, lval2.e_const);
} }
} else if (lval->e_flags & E_MLOCAL) { } else if (lval->e_flags & E_MLOCAL) {
/* ref to localvar */ /* ref to localvar */
if (Gen->Tok == PASGN) { if (Gen->Tok == TOK_PLUS_ASSIGN) {
g_addeqlocal (flags, lval->e_const, lval2.e_const); g_addeqlocal (flags, lval->e_const, lval2.e_const);
} else { } else {
g_subeqlocal (flags, lval->e_const, lval2.e_const); g_subeqlocal (flags, lval->e_const, lval2.e_const);
@@ -2624,14 +2624,14 @@ static void addsubeq (GenDesc* Gen, struct expent *lval, int k)
} else if (lval->e_flags & E_MCONST) { } else if (lval->e_flags & E_MCONST) {
/* ref to absolute address */ /* ref to absolute address */
flags |= CF_ABSOLUTE; flags |= CF_ABSOLUTE;
if (Gen->Tok == PASGN) { if (Gen->Tok == TOK_PLUS_ASSIGN) {
g_addeqstatic (flags, lval->e_const, 0, lval2.e_const); g_addeqstatic (flags, lval->e_const, 0, lval2.e_const);
} else { } else {
g_subeqstatic (flags, lval->e_const, 0, lval2.e_const); g_subeqstatic (flags, lval->e_const, 0, lval2.e_const);
} }
} else if (lval->e_flags & E_MEXPR) { } else if (lval->e_flags & E_MEXPR) {
/* Address in a/x. */ /* Address in a/x. */
if (Gen->Tok == PASGN) { if (Gen->Tok == TOK_PLUS_ASSIGN) {
g_addeqind (flags, lval->e_const, lval2.e_const); g_addeqind (flags, lval->e_const, lval2.e_const);
} else { } else {
g_subeqind (flags, lval->e_const, lval2.e_const); g_subeqind (flags, lval->e_const, lval2.e_const);
@@ -2726,12 +2726,12 @@ int hie1 (struct expent* lval)
k = hieQuest (lval); k = hieQuest (lval);
switch (curtok) { switch (curtok) {
case RPAREN: case TOK_RPAREN:
case SEMI: case TOK_SEMI:
return k; return k;
case ASGN: case TOK_ASSIGN:
gettok (); NextToken ();
if (k == 0) { if (k == 0) {
Error (ERR_LVALUE_EXPECTED); Error (ERR_LVALUE_EXPECTED);
} else { } else {
@@ -2739,43 +2739,43 @@ int hie1 (struct expent* lval)
} }
break; break;
case PASGN: case TOK_PLUS_ASSIGN:
addsubeq (&GenPASGN, lval, k); addsubeq (&GenPASGN, lval, k);
break; break;
case SASGN: case TOK_MINUS_ASSIGN:
addsubeq (&GenSASGN, lval, k); addsubeq (&GenSASGN, lval, k);
break; break;
case MASGN: case TOK_MUL_ASSIGN:
opeq (&GenMASGN, lval, k); opeq (&GenMASGN, lval, k);
break; break;
case DASGN: case TOK_DIV_ASSIGN:
opeq (&GenDASGN, lval, k); opeq (&GenDASGN, lval, k);
break; break;
case MOASGN: case TOK_MOD_ASSIGN:
opeq (&GenMOASGN, lval, k); opeq (&GenMOASGN, lval, k);
break; break;
case SLASGN: case TOK_SHL_ASSIGN:
opeq (&GenSLASGN, lval, k); opeq (&GenSLASGN, lval, k);
break; break;
case SRASGN: case TOK_SHR_ASSIGN:
opeq (&GenSRASGN, lval, k); opeq (&GenSRASGN, lval, k);
break; break;
case AASGN: case TOK_AND_ASSIGN:
opeq (&GenAASGN, lval, k); opeq (&GenAASGN, lval, k);
break; break;
case XOASGN: case TOK_XOR_ASSIGN:
opeq (&GenXOASGN, lval, k); opeq (&GenXOASGN, lval, k);
break; break;
case OASGN: case TOK_OR_ASSIGN:
opeq (&GenOASGN, lval, k); opeq (&GenOASGN, lval, k);
break; break;
@@ -2793,8 +2793,8 @@ int hie0 (struct expent *lval)
int k; int k;
k = hie1 (lval); k = hie1 (lval);
while (curtok == COMMA) { while (curtok == TOK_COMMA) {
gettok (); NextToken ();
k = hie1 (lval); k = hie1 (lval);
} }
return k; return k;
@@ -2965,7 +2965,7 @@ void test (unsigned label, int cond)
* compiler itself is one big hack...): If a semicolon follows, we * compiler itself is one big hack...): If a semicolon follows, we
* don't have a statement and may omit the jump. * don't have a statement and may omit the jump.
*/ */
if (curtok != SEMI) { if (curtok != TOK_SEMI) {
g_falsejump (CF_NONE, label); g_falsejump (CF_NONE, label);
} }
} }

View File

@@ -51,10 +51,9 @@ FuncDesc* NewFuncDesc (void)
FuncDesc* F = xmalloc (sizeof (FuncDesc)); FuncDesc* F = xmalloc (sizeof (FuncDesc));
/* Nullify the fields */ /* Nullify the fields */
F->Flags = 0; F->Flags = 0;
F->SymTab = 0; F->SymTab = 0;
F->StructTab = 0; F->TagTab = 0;
F->EnumTab = 0;
F->ParamCount = 0; F->ParamCount = 0;
F->ParamSize = 0; F->ParamSize = 0;

View File

@@ -45,21 +45,27 @@
/* Masks for the Flags field in FuncDesc */ /* Masks for the Flags field in FuncDesc */
#define FD_IMPLICIT 0x0001U /* Implicitly declared function */ #define FD_IMPLICIT 0x0001U /* Implicitly declared function */
#define FD_EMPTY 0x0002U /* Function with empty param list */ #define FD_EMPTY 0x0002U /* Function with empty param list */
#define FD_VOID_PARAM 0x0004U /* Function with a void param list */ #define FD_VOID_PARAM 0x0004U /* Function with a void param list */
#define FD_ELLIPSIS 0x0008U /* Function with variable param list */ #define FD_ELLIPSIS 0x0008U /* Function with variable param list */
#define FD_FASTCALL 0x0010U /* __fastcall__ function */ #define FD_FASTCALL 0x0010U /* __fastcall__ function */
#define FD_OLDSTYLE 0x0020U /* Old style (K&R) function */
#define FD_UNNAMED_PARAMS 0x0040U /* Function has unnamed params */
/* Bits that must be ignored when comparing funcs */
#define FD_IGNORE (FD_IMPLICIT | FD_UNNAMED_PARAMS)
/* Function descriptor */ /* Function descriptor */
typedef struct FuncDesc FuncDesc; typedef struct FuncDesc FuncDesc;
struct FuncDesc { struct FuncDesc {
unsigned Flags; /* Bitmapped flags FD_... */ unsigned Flags; /* Bitmapped flags FD_... */
struct SymTable* SymTab; /* Symbol table */ struct SymTable* SymTab; /* Symbol table */
struct SymTable* StructTab; /* Struct table */ struct SymTable* TagTab; /* Symbol table for structs/enums */
struct SymTable* EnumTab; /* Enum table */ unsigned ParamCount; /* Number of parameters */
unsigned ParamCount; /* Number of parameters */ unsigned ParamSize; /* Size of the parameters */
unsigned ParamSize; /* Size of the parameters */
}; };

View File

@@ -213,7 +213,7 @@ void NewFunc (SymEntry* Func)
} }
/* Need a starting curly brace */ /* Need a starting curly brace */
if (curtok != LCURLY) { if (curtok != TOK_LCURLY) {
Error (ERR_LCURLY_EXPECTED); Error (ERR_LCURLY_EXPECTED);
} }

View File

@@ -51,10 +51,10 @@ void DoGoto (void)
/* Process a goto statement. */ /* Process a goto statement. */
{ {
/* Eat the "goto" */ /* Eat the "goto" */
gettok (); NextToken ();
/* Label name must follow */ /* Label name must follow */
if (curtok != IDENT) { if (curtok != TOK_IDENT) {
Error (ERR_IDENT_EXPECTED); Error (ERR_IDENT_EXPECTED);
@@ -68,7 +68,7 @@ void DoGoto (void)
} }
/* Eat the label name */ /* Eat the label name */
gettok (); NextToken ();
} }
@@ -83,8 +83,8 @@ void DoLabel (void)
g_defloclabel (Entry->V.Label); g_defloclabel (Entry->V.Label);
/* Eat the ident and colon */ /* Eat the ident and colon */
gettok (); NextToken ();
gettok (); NextToken ();
} }

View File

@@ -38,7 +38,7 @@
#include "codegen.h" #include "codegen.h"
#include "declare.h" #include "declare.h"
#include "expr.h" #include "expr.h"
#include "function.h" /* ## */ #include "function.h"
#include "global.h" #include "global.h"
#include "mem.h" #include "mem.h"
#include "symtab.h" #include "symtab.h"
@@ -131,10 +131,10 @@ static int AllocRegVar (const SymEntry* Sym, const type* tarray)
void DeclareLocals (void) void DeclareLocals (void)
/* Declare local variables and types. */ /* Declare local variables and types. */
{ {
int offs = oursp; /* Current stack offset for variable */ int offs = oursp; /* Current stack offset for variable */
int AutoSpace = 0; /* Unallocated space on the stack */ int AutoSpace = 0; /* Unallocated space on the stack */
int Size; /* Size of an auto variable */ int Size; /* Size of an auto variable */
int Reg; /* Register variable offset */ int Reg; /* Register variable offset */
unsigned flags = 0; /* Code generator flags */ unsigned flags = 0; /* Code generator flags */
int SymbolSC; /* Storage class for symbol */ int SymbolSC; /* Storage class for symbol */
int ldata = 0; /* Local symbol data temp storage */ int ldata = 0; /* Local symbol data temp storage */
@@ -155,9 +155,10 @@ void DeclareLocals (void)
} }
/* Accept type only declarations */ /* Accept type only declarations */
if (curtok == SEMI) { if (curtok == TOK_SEMI) {
/* Type declaration only ### Check struct/union here */ /* Type declaration only */
gettok (); CheckEmptyDecl (&Spec);
NextToken ();
continue; continue;
} }
@@ -205,12 +206,12 @@ void DeclareLocals (void)
g_save_regvars (Reg, Size); g_save_regvars (Reg, Size);
/* Allow variable initialization */ /* Allow variable initialization */
if (curtok == ASGN) { if (curtok == TOK_ASSIGN) {
struct expent lval; struct expent lval;
/* Skip the '=' */ /* Skip the '=' */
gettok (); NextToken ();
/* Get the expression into the primary */ /* Get the expression into the primary */
expression1 (&lval); expression1 (&lval);
@@ -247,7 +248,7 @@ void DeclareLocals (void)
/* Change SC in case it was register */ /* Change SC in case it was register */
SymbolSC = (SymbolSC & ~SC_REGISTER) | SC_AUTO; SymbolSC = (SymbolSC & ~SC_REGISTER) | SC_AUTO;
if (curtok == ASGN) { if (curtok == TOK_ASSIGN) {
struct expent lval; struct expent lval;
@@ -260,7 +261,7 @@ void DeclareLocals (void)
AutoSpace = 0; AutoSpace = 0;
/* Skip the '=' */ /* Skip the '=' */
gettok (); NextToken ();
/* Setup the type flags for the assignment */ /* Setup the type flags for the assignment */
flags = Size == 1? CF_FORCECHAR : CF_NONE; flags = Size == 1? CF_FORCECHAR : CF_NONE;
@@ -307,7 +308,7 @@ void DeclareLocals (void)
g_res (Size); g_res (Size);
/* Allow assignments */ /* Allow assignments */
if (curtok == ASGN) { if (curtok == TOK_ASSIGN) {
struct expent lval; struct expent lval;
@@ -315,7 +316,7 @@ void DeclareLocals (void)
g_usecode (); g_usecode ();
/* Skip the '=' */ /* Skip the '=' */
gettok (); NextToken ();
/* Get the expression into the primary */ /* Get the expression into the primary */
expression1 (&lval); expression1 (&lval);
@@ -340,7 +341,7 @@ void DeclareLocals (void)
} else if ((SymbolSC & SC_STATIC) == SC_STATIC) { } else if ((SymbolSC & SC_STATIC) == SC_STATIC) {
/* Static data */ /* Static data */
if (curtok == ASGN) { if (curtok == TOK_ASSIGN) {
/* Initialization ahead, switch to data segment */ /* Initialization ahead, switch to data segment */
g_usedata (); g_usedata ();
@@ -349,7 +350,7 @@ void DeclareLocals (void)
g_defloclabel (ldata = GetLabel ()); g_defloclabel (ldata = GetLabel ());
/* Skip the '=' */ /* Skip the '=' */
gettok (); NextToken ();
/* Allow initialization of static vars */ /* Allow initialization of static vars */
ParseInit (Decl.Type); ParseInit (Decl.Type);
@@ -381,13 +382,13 @@ void DeclareLocals (void)
/* Add the symbol to the symbol table */ /* Add the symbol to the symbol table */
AddLocalSym (Decl.Ident, Decl.Type, SymbolSC, ldata); AddLocalSym (Decl.Ident, Decl.Type, SymbolSC, ldata);
if (curtok != COMMA) { if (curtok != TOK_COMMA) {
break; break;
} }
gettok (); NextToken ();
} }
if (curtok == SEMI) { if (curtok == TOK_SEMI) {
gettok (); NextToken ();
} }
} }

View File

@@ -9,24 +9,15 @@
#include "../common/version.h" #include "../common/version.h"
#include "asmcode.h" #include "asmcode.h"
#include "asmlabel.h" #include "compile.h"
#include "codegen.h"
#include "datatype.h"
#include "declare.h"
#include "error.h" #include "error.h"
#include "expr.h"
#include "function.h"
#include "global.h" #include "global.h"
#include "include.h" #include "include.h"
#include "io.h" #include "io.h"
#include "litpool.h"
#include "macrotab.h" #include "macrotab.h"
#include "mem.h" #include "mem.h"
#include "optimize.h" #include "optimize.h"
#include "pragma.h"
#include "scanner.h" #include "scanner.h"
#include "stmt.h"
#include "symtab.h"
@@ -54,7 +45,7 @@ static const char* TargetNames [] = {
/*****************************************************************************/ /*****************************************************************************/
/* code */ /* Code */
/*****************************************************************************/ /*****************************************************************************/
@@ -252,259 +243,6 @@ static void DefineSym (const char* Def)
static void Parse (void)
/* Process all input text.
* At this level, only static declarations, defines, includes, and function
* definitions are legal....
*/
{
int comma;
SymEntry* Entry;
kill ();
gettok (); /* "prime" the pump */
gettok ();
while (curtok != CEOF) {
DeclSpec Spec;
Declaration Decl;
int NeedStorage;
/* Check for an ASM statement (which is allowed also on global level) */
if (curtok == ASM) {
doasm ();
ConsumeSemi ();
continue;
}
/* Check for a #pragma */
if (curtok == PRAGMA) {
DoPragma ();
continue;
}
/* Read variable defs and functions */
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;
}
/* Check if this is only a type declaration */
if (curtok == SEMI) {
gettok ();
continue;
}
/* Check if we must reserve storage for the variable. We do
* this if we don't had a storage class given ("int i") or
* if the storage class is explicitly specified as static.
* This means that "extern int i" will not get storage
* allocated.
*/
NeedStorage = (Spec.StorageClass & SC_TYPEDEF) == 0 &&
((Spec.Flags & DS_DEF_STORAGE) != 0 ||
(Spec.StorageClass & (SC_STATIC | SC_EXTERN)) == SC_STATIC);
/* Read declarations for this type */
Entry = 0;
comma = 0;
while (1) {
unsigned SymFlags;
/* Read the next declaration */
ParseDecl (&Spec, &Decl, DM_NEED_IDENT);
if (Decl.Ident[0] == '\0') {
gettok ();
break;
}
/* Get the symbol flags */
SymFlags = Spec.StorageClass;
if (IsFunc (Decl.Type)) {
SymFlags |= SC_FUNC;
} else {
if (NeedStorage) {
/* We will allocate storage, variable is defined */
SymFlags |= SC_STORAGE | SC_DEF;
}
}
/* Add an entry to the symbol table */
Entry = AddGlobalSym (Decl.Ident, Decl.Type, SymFlags);
/* Reserve storage for the variable if we need to */
if (SymFlags & SC_STORAGE) {
/* Get the size of the variable */
unsigned Size = SizeOf (Decl.Type);
/* Allow initialization */
if (curtok == ASGN) {
/* 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);
}
}
/* Switch to the data segment */
g_usedata ();
/* Define a label */
g_defgloblabel (Entry->Name);
/* Skip the '=' */
gettok ();
/* Parse the initialization */
ParseInit (Entry->Type);
} else {
if (IsVoid (Decl.Type)) {
/* We cannot declare variables of type void */
Error (ERR_ILLEGAL_TYPE);
} else if (Size == 0) {
/* Size is unknown */
Error (ERR_UNKNOWN_SIZE);
}
/* Switch to the BSS segment */
g_usebss ();
/* Define a label */
g_defgloblabel (Entry->Name);
/* Allocate space for uninitialized variable */
g_res (SizeOf (Entry->Type));
}
}
/* Check for end of declaration list */
if (curtok == COMMA) {
gettok ();
comma = 1;
} else {
break;
}
}
/* Function declaration? */
if (IsFunc (Decl.Type)) {
/* Function */
if (!comma) {
if (curtok == SEMI) {
/* Prototype only */
gettok ();
} else {
if (Entry) {
NewFunc (Entry);
}
}
}
} else {
/* Must be followed by a semicolon */
ConsumeSemi ();
}
}
}
static void Compile (void)
/* Compiler begins execution here. inp is input fd, output is output fd. */
{
char* Path;
/* Setup variables */
filetab[0].f_iocb = inp;
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);
}
/* Add macros that are always defined */
AddNumericMacro ("__CC65__", (VER_MAJOR * 0x100) + (VER_MINOR * 0x10) + VER_PATCH);
/* Strict ANSI macro */
if (ANSI) {
AddNumericMacro ("__STRICT_ANSI__", 1);
}
/* Optimization macros */
if (Optimize) {
AddNumericMacro ("__OPT__", 1);
if (FavourSize == 0) {
AddNumericMacro ("__OPT_i__", 1);
}
if (EnableRegVars) {
AddNumericMacro ("__OPT_r__", 1);
}
if (InlineStdFuncs) {
AddNumericMacro ("__OPT_s__", 1);
}
}
/* Create the base lexical level */
EnterGlobalLevel ();
/* Generate the code generator preamble */
g_preamble ();
/* Ok, start the ball rolling... */
Parse ();
/* Dump literal pool. */
DumpLiteralPool ();
/* Write imported/exported symbols */
EmitExternals ();
if (Debug) {
PrintLiteralStats (stdout);
PrintMacroStats (stdout);
}
/* Leave the main lexical level */
LeaveGlobalLevel ();
/* Print an error report */
ErrorReport ();
}
int main (int argc, char **argv) int main (int argc, char **argv)
{ {
int i; int i;

View File

@@ -15,6 +15,7 @@ OBJS = anonname.o \
asmline.o \ asmline.o \
check.o \ check.o \
codegen.o \ codegen.o \
compile.o \
ctrans.o \ ctrans.o \
datatype.o \ datatype.o \
declare.o \ declare.o \

View File

@@ -69,6 +69,7 @@ OBJS = anonname.obj \
asmline.obj \ asmline.obj \
check.obj \ check.obj \
codegen.obj \ codegen.obj \
compile.obj \
ctrans.obj \ ctrans.obj \
datatype.obj \ datatype.obj \
declare.obj \ declare.obj \
@@ -124,6 +125,7 @@ FILE asmlabel.obj
FILE asmline.obj FILE asmline.obj
FILE check.obj FILE check.obj
FILE codegen.obj FILE codegen.obj
FILE compile.obj
FILE ctrans.obj FILE ctrans.obj
FILE datatype.obj FILE datatype.obj
FILE declare.obj FILE declare.obj

View File

@@ -79,7 +79,7 @@ enum {
static void StringPragma (void (*Func) (const char*)) static void StringPragma (void (*Func) (const char*))
/* Handle a pragma that expects a string parameter */ /* Handle a pragma that expects a string parameter */
{ {
if (curtok != SCONST) { if (curtok != TOK_SCONST) {
Error (ERR_STRLIT_EXPECTED); Error (ERR_STRLIT_EXPECTED);
} else { } else {
/* Get the string */ /* Get the string */
@@ -93,7 +93,7 @@ static void StringPragma (void (*Func) (const char*))
} }
/* Skip the string (or error) token */ /* Skip the string (or error) token */
gettok (); NextToken ();
} }
@@ -129,10 +129,10 @@ void DoPragma (void)
int Pragma; int Pragma;
/* Skip the token itself */ /* Skip the token itself */
gettok (); NextToken ();
/* Identifier must follow */ /* Identifier must follow */
if (curtok != IDENT) { if (curtok != TOK_IDENT) {
Error (ERR_IDENT_EXPECTED); Error (ERR_IDENT_EXPECTED);
return; return;
} }
@@ -149,7 +149,7 @@ void DoPragma (void)
} }
/* Skip the identifier and check for an open paren */ /* Skip the identifier and check for an open paren */
gettok (); NextToken ();
ConsumeLParen (); ConsumeLParen ();
/* Switch for the different pragmas */ /* Switch for the different pragmas */

View File

@@ -586,8 +586,8 @@ static int doiff (int skip)
xlateline (); xlateline ();
/* Prime the token pump (remove old tokens from the stream) */ /* Prime the token pump (remove old tokens from the stream) */
gettok (); NextToken ();
gettok (); NextToken ();
/* Call the expression parser */ /* Call the expression parser */
constexpr (&lval); constexpr (&lval);

View File

@@ -48,44 +48,45 @@ static struct Keyword {
unsigned char Tok; /* The token */ unsigned char Tok; /* The token */
unsigned char Type; /* Token type */ unsigned char Type; /* Token type */
} Keywords [] = { } Keywords [] = {
{ "__AX__", AX, TT_C }, { "__AX__", TOK_AX, TT_C },
{ "__EAX__", EAX, TT_C }, { "__EAX__", TOK_EAX, TT_C },
{ "__asm__", ASM, TT_C }, { "__asm__", TOK_ASM, TT_C },
{ "__fastcall__", FASTCALL, TT_C }, { "__attribute__", TOK_ATTRIBUTE, TT_C },
{ "asm", ASM, TT_EXT }, { "__fastcall__", TOK_FASTCALL, TT_C },
{ "auto", AUTO, TT_C }, { "asm", TOK_ASM, TT_EXT },
{ "break", BREAK, TT_C }, { "auto", TOK_AUTO, TT_C },
{ "case", CASE, TT_C }, { "break", TOK_BREAK, TT_C },
{ "char", CHAR, TT_C }, { "case", TOK_CASE, TT_C },
{ "const", CONST, TT_C }, { "char", TOK_CHAR, TT_C },
{ "continue", CONTINUE, TT_C }, { "const", TOK_CONST, TT_C },
{ "default", DEFAULT, TT_C }, { "continue", TOK_CONTINUE, TT_C },
{ "do", DO, TT_C }, { "default", TOK_DEFAULT, TT_C },
{ "double", DOUBLE, TT_C }, { "do", TOK_DO, TT_C },
{ "else", ELSE, TT_C }, { "double", TOK_DOUBLE, TT_C },
{ "enum", ENUM, TT_C }, { "else", TOK_ELSE, TT_C },
{ "extern", EXTERN, TT_C }, { "enum", TOK_ENUM, TT_C },
{ "fastcall", FASTCALL, TT_EXT }, { "extern", TOK_EXTERN, TT_C },
{ "float", FLOAT, TT_C }, { "fastcall", TOK_FASTCALL, TT_EXT },
{ "for", FOR, TT_C }, { "float", TOK_FLOAT, TT_C },
{ "goto", GOTO, TT_C }, { "for", TOK_FOR, TT_C },
{ "if", IF, TT_C }, { "goto", TOK_GOTO, TT_C },
{ "int", INT, TT_C }, { "if", TOK_IF, TT_C },
{ "long", LONG, TT_C }, { "int", TOK_INT, TT_C },
{ "register", REGISTER, TT_C }, { "long", TOK_LONG, TT_C },
{ "return", RETURN, TT_C }, { "register", TOK_REGISTER, TT_C },
{ "short", SHORT, TT_C }, { "return", TOK_RETURN, TT_C },
{ "signed", SIGNED, TT_C }, { "short", TOK_SHORT, TT_C },
{ "sizeof", SIZEOF, TT_C }, { "signed", TOK_SIGNED, TT_C },
{ "static", STATIC, TT_C }, { "sizeof", TOK_SIZEOF, TT_C },
{ "struct", STRUCT, TT_C }, { "static", TOK_STATIC, TT_C },
{ "switch", SWITCH, TT_C }, { "struct", TOK_STRUCT, TT_C },
{ "typedef", TYPEDEF, TT_C }, { "switch", TOK_SWITCH, TT_C },
{ "union", UNION, TT_C }, { "typedef", TOK_TYPEDEF, TT_C },
{ "unsigned", UNSIGNED, TT_C }, { "union", TOK_UNION, TT_C },
{ "void", VOID, TT_C }, { "unsigned", TOK_UNSIGNED, TT_C },
{ "volatile", VOLATILE, TT_C }, { "void", TOK_VOID, TT_C },
{ "while", WHILE, TT_C }, { "volatile", TOK_VOLATILE, TT_C },
{ "while", TOK_WHILE, TT_C },
}; };
#define KEY_COUNT (sizeof (Keywords) / sizeof (Keywords [0])) #define KEY_COUNT (sizeof (Keywords) / sizeof (Keywords [0]))
@@ -123,7 +124,7 @@ static int FindKey (char* Key)
if (K && (K->Type != TT_EXT || ANSI == 0)) { if (K && (K->Type != TT_EXT || ANSI == 0)) {
return K->Tok; return K->Tok;
} else { } else {
return IDENT; return TOK_IDENT;
} }
} }
@@ -303,7 +304,7 @@ static void CharConst (void)
} }
/* Setup values and attributes */ /* Setup values and attributes */
nxttok = CCONST; nxttok = TOK_CCONST;
nxtval = SignExtendChar (ctrans (c)); /* Translate into target charset */ nxtval = SignExtendChar (ctrans (c)); /* Translate into target charset */
nxttype = type_int; /* Character constants have type int */ nxttype = type_int; /* Character constants have type int */
} }
@@ -314,7 +315,7 @@ static void StringConst (void)
/* Parse a quoted string */ /* Parse a quoted string */
{ {
nxtval = GetLiteralOffs (); nxtval = GetLiteralOffs ();
nxttok = SCONST; nxttok = TOK_SCONST;
/* Be sure to concatenate strings */ /* Be sure to concatenate strings */
while (*lptr == '\"') { while (*lptr == '\"') {
@@ -344,7 +345,7 @@ static void StringConst (void)
void gettok (void) void NextToken (void)
/* Get next token from input stream */ /* Get next token from input stream */
{ {
char c; char c;
@@ -359,7 +360,7 @@ void gettok (void)
/* Skip spaces and read the next line if needed */ /* Skip spaces and read the next line if needed */
if (skipwhite () == 0) { if (skipwhite () == 0) {
/* End of file reached */ /* End of file reached */
nxttok = CEOF; nxttok = TOK_CEOF;
return; return;
} }
@@ -460,14 +461,14 @@ void gettok (void)
/* Set the value and the token */ /* Set the value and the token */
nxtval = k; nxtval = k;
nxttok = ICONST; nxttok = TOK_ICONST;
return; return;
} }
if (issym (token)) { if (issym (token)) {
/* Check for a keyword */ /* Check for a keyword */
if ((nxttok = FindKey (token)) != IDENT) { if ((nxttok = FindKey (token)) != TOK_IDENT) {
/* Reserved word found */ /* Reserved word found */
return; return;
} }
@@ -476,15 +477,15 @@ void gettok (void)
/* Special symbols */ /* Special symbols */
if (strcmp (token, "__FILE__") == 0) { if (strcmp (token, "__FILE__") == 0) {
nxtval = AddLiteral (fin); nxtval = AddLiteral (fin);
nxttok = SCONST; nxttok = TOK_SCONST;
return; return;
} else if (strcmp (token, "__LINE__") == 0) { } else if (strcmp (token, "__LINE__") == 0) {
nxttok = ICONST; nxttok = TOK_ICONST;
nxtval = ln; nxtval = ln;
nxttype = type_int; nxttype = type_int;
return; return;
} else if (strcmp (token, "__fixargs__") == 0) { } else if (strcmp (token, "__fixargs__") == 0) {
nxttok = ICONST; nxttok = TOK_ICONST;
nxtval = GetParamSize (CurrentFunc); nxtval = GetParamSize (CurrentFunc);
nxttype = type_uint; nxttype = type_uint;
return; return;
@@ -492,7 +493,7 @@ void gettok (void)
/* __func__ is only defined in functions */ /* __func__ is only defined in functions */
if (CurrentFunc) { if (CurrentFunc) {
nxtval = AddLiteral (GetFuncName (CurrentFunc)); nxtval = AddLiteral (GetFuncName (CurrentFunc));
nxttok = SCONST; nxttok = TOK_SCONST;
return; return;
} }
} }
@@ -500,7 +501,7 @@ void gettok (void)
/* No reserved word but identifier */ /* No reserved word but identifier */
strcpy (NextTok.Ident, token); strcpy (NextTok.Ident, token);
NextTok.Tok = IDENT; NextTok.Tok = TOK_IDENT;
return; return;
} }
@@ -509,9 +510,9 @@ void gettok (void)
case '!': case '!':
if (*++lptr == '=') { if (*++lptr == '=') {
SetTok (NE); SetTok (TOK_NE);
} else { } else {
nxttok = BANG; nxttok = TOK_BOOL_NOT;
} }
break; break;
@@ -521,22 +522,22 @@ void gettok (void)
case '%': case '%':
if (*++lptr == '=') { if (*++lptr == '=') {
SetTok (MOASGN); SetTok (TOK_MOD_ASSIGN);
} else { } else {
nxttok = MOD; nxttok = TOK_MOD;
} }
break; break;
case '&': case '&':
switch (*++lptr) { switch (*++lptr) {
case '&': case '&':
SetTok (DAMP); SetTok (TOK_BOOL_AND);
break; break;
case '=': case '=':
SetTok (AASGN); SetTok (TOK_AND_ASSIGN);
break; break;
default: default:
nxttok = AMP; nxttok = TOK_AND;
} }
break; break;
@@ -545,167 +546,167 @@ void gettok (void)
break; break;
case '(': case '(':
SetTok (LPAREN); SetTok (TOK_LPAREN);
break; break;
case ')': case ')':
SetTok (RPAREN); SetTok (TOK_RPAREN);
break; break;
case '*': case '*':
if (*++lptr == '=') { if (*++lptr == '=') {
SetTok (MASGN); SetTok (TOK_MUL_ASSIGN);
} else { } else {
nxttok = STAR; nxttok = TOK_STAR;
} }
break; break;
case '+': case '+':
switch (*++lptr) { switch (*++lptr) {
case '+': case '+':
SetTok (INC); SetTok (TOK_INC);
break; break;
case '=': case '=':
SetTok (PASGN); SetTok (TOK_PLUS_ASSIGN);
break; break;
default: default:
nxttok = PLUS; nxttok = TOK_PLUS;
} }
break; break;
case ',': case ',':
SetTok (COMMA); SetTok (TOK_COMMA);
break; break;
case '-': case '-':
switch (*++lptr) { switch (*++lptr) {
case '-': case '-':
SetTok (DEC); SetTok (TOK_DEC);
break; break;
case '=': case '=':
SetTok (SASGN); SetTok (TOK_MINUS_ASSIGN);
break; break;
case '>': case '>':
SetTok (PREF); SetTok (TOK_PTR_REF);
break; break;
default: default:
nxttok = MINUS; nxttok = TOK_MINUS;
} }
break; break;
case '.': case '.':
if (*++lptr == '.') { if (*++lptr == '.') {
if (*++lptr == '.') { if (*++lptr == '.') {
SetTok (ELLIPSIS); SetTok (TOK_ELLIPSIS);
} else { } else {
unknown (*lptr); unknown (*lptr);
} }
} else { } else {
nxttok = DOT; nxttok = TOK_DOT;
} }
break; break;
case '/': case '/':
if (*++lptr == '=') { if (*++lptr == '=') {
SetTok (DASGN); SetTok (TOK_DIV_ASSIGN);
} else { } else {
nxttok = DIV; nxttok = TOK_DIV;
} }
break; break;
case ':': case ':':
SetTok (COLON); SetTok (TOK_COLON);
break; break;
case ';': case ';':
SetTok (SEMI); SetTok (TOK_SEMI);
break; break;
case '<': case '<':
switch (*++lptr) { switch (*++lptr) {
case '=': case '=':
SetTok (LE); SetTok (TOK_LE);
break; break;
case '<': case '<':
if (*++lptr == '=') { if (*++lptr == '=') {
SetTok (SLASGN); SetTok (TOK_SHL_ASSIGN);
} else { } else {
nxttok = ASL; nxttok = TOK_SHL;
} }
break; break;
default: default:
nxttok = LT; nxttok = TOK_LT;
} }
break; break;
case '=': case '=':
if (*++lptr == '=') { if (*++lptr == '=') {
SetTok (EQ); SetTok (TOK_EQ);
} else { } else {
nxttok = ASGN; nxttok = TOK_ASSIGN;
} }
break; break;
case '>': case '>':
switch (*++lptr) { switch (*++lptr) {
case '=': case '=':
SetTok (GE); SetTok (TOK_GE);
break; break;
case '>': case '>':
if (*++lptr == '=') { if (*++lptr == '=') {
SetTok (SRASGN); SetTok (TOK_SHR_ASSIGN);
} else { } else {
nxttok = ASR; nxttok = TOK_SHR;
} }
break; break;
default: default:
nxttok = GT; nxttok = TOK_GT;
} }
break; break;
case '?': case '?':
SetTok (QUEST); SetTok (TOK_QUEST);
break; break;
case '[': case '[':
SetTok (LBRACK); SetTok (TOK_LBRACK);
break; break;
case ']': case ']':
SetTok (RBRACK); SetTok (TOK_RBRACK);
break; break;
case '^': case '^':
if (*++lptr == '=') { if (*++lptr == '=') {
SetTok (XOASGN); SetTok (TOK_XOR_ASSIGN);
} else { } else {
nxttok = XOR; nxttok = TOK_XOR;
} }
break; break;
case '{': case '{':
SetTok (LCURLY); SetTok (TOK_LCURLY);
break; break;
case '|': case '|':
switch (*++lptr) { switch (*++lptr) {
case '|': case '|':
SetTok (DBAR); SetTok (TOK_BOOL_OR);
break; break;
case '=': case '=':
SetTok (OASGN); SetTok (TOK_OR_ASSIGN);
break; break;
default: default:
nxttok = BAR; nxttok = TOK_OR;
} }
break; break;
case '}': case '}':
SetTok (RCURLY); SetTok (TOK_RCURLY);
break; break;
case '~': case '~':
SetTok (COMP); SetTok (TOK_COMP);
break; break;
case '#': case '#':
@@ -714,7 +715,7 @@ void gettok (void)
/* OOPS - should not happen */ /* OOPS - should not happen */
Error (ERR_CPP_DIRECTIVE_EXPECTED); Error (ERR_CPP_DIRECTIVE_EXPECTED);
} }
nxttok = PRAGMA; nxttok = TOK_PRAGMA;
break; break;
default: default:
@@ -726,13 +727,13 @@ void gettok (void)
void Consume (unsigned Token, unsigned char ErrNum) void Consume (token_t Token, unsigned ErrNum)
/* Eat token if it is the next in the input stream, otherwise print an error /* Eat token if it is the next in the input stream, otherwise print an error
* message. * message.
*/ */
{ {
if (curtok == Token) { if (curtok == Token) {
gettok (); NextToken ();
} else { } else {
Error (ErrNum); Error (ErrNum);
} }
@@ -743,7 +744,7 @@ void Consume (unsigned Token, unsigned char ErrNum)
void ConsumeColon (void) void ConsumeColon (void)
/* Check for a colon and skip it. */ /* Check for a colon and skip it. */
{ {
Consume (COLON, ERR_COLON_EXPECTED); Consume (TOK_COLON, ERR_COLON_EXPECTED);
} }
@@ -752,12 +753,12 @@ void ConsumeSemi (void)
/* Check for a semicolon and skip it. */ /* Check for a semicolon and skip it. */
{ {
/* Try do be smart about typos... */ /* Try do be smart about typos... */
if (curtok == SEMI) { if (curtok == TOK_SEMI) {
gettok (); NextToken ();
} else { } else {
Error (ERR_SEMICOLON_EXPECTED); Error (ERR_SEMICOLON_EXPECTED);
if (curtok == COLON || curtok == COMMA) { if (curtok == TOK_COLON || curtok == TOK_COMMA) {
gettok (); NextToken ();
} }
} }
} }
@@ -767,7 +768,7 @@ void ConsumeSemi (void)
void ConsumeLParen (void) void ConsumeLParen (void)
/* Check for a left parenthesis and skip it */ /* Check for a left parenthesis and skip it */
{ {
Consume (LPAREN, ERR_LPAREN_EXPECTED); Consume (TOK_LPAREN, ERR_LPAREN_EXPECTED);
} }
@@ -775,7 +776,7 @@ void ConsumeLParen (void)
void ConsumeRParen (void) void ConsumeRParen (void)
/* Check for a right parenthesis and skip it */ /* Check for a right parenthesis and skip it */
{ {
Consume (RPAREN, ERR_RPAREN_EXPECTED); Consume (TOK_RPAREN, ERR_RPAREN_EXPECTED);
} }
@@ -783,7 +784,7 @@ void ConsumeRParen (void)
void ConsumeLBrack (void) void ConsumeLBrack (void)
/* Check for a left bracket and skip it */ /* Check for a left bracket and skip it */
{ {
Consume (LBRACK, ERR_LBRACK_EXPECTED); Consume (TOK_LBRACK, ERR_LBRACK_EXPECTED);
} }
@@ -791,7 +792,7 @@ void ConsumeLBrack (void)
void ConsumeRBrack (void) void ConsumeRBrack (void)
/* Check for a right bracket and skip it */ /* Check for a right bracket and skip it */
{ {
Consume (RBRACK, ERR_RBRACK_EXPECTED); Consume (TOK_RBRACK, ERR_RBRACK_EXPECTED);
} }
@@ -799,7 +800,7 @@ void ConsumeRBrack (void)
void ConsumeLCurly (void) void ConsumeLCurly (void)
/* Check for a left curly brace and skip it */ /* Check for a left curly brace and skip it */
{ {
Consume (LCURLY, ERR_LCURLY_EXPECTED); Consume (TOK_LCURLY, ERR_LCURLY_EXPECTED);
} }
@@ -807,7 +808,7 @@ void ConsumeLCurly (void)
void ConsumeRCurly (void) void ConsumeRCurly (void)
/* Check for a right curly brace and skip it */ /* Check for a right curly brace and skip it */
{ {
Consume (RCURLY, ERR_RCURLY_EXPECTED); Consume (TOK_RCURLY, ERR_RCURLY_EXPECTED);
} }

View File

@@ -17,115 +17,120 @@
/*****************************************************************************/ /*****************************************************************************/
/* token definitions */ /* Token definitions */
/*****************************************************************************/ /*****************************************************************************/
#define CEOF 0 typedef enum token_t {
TOK_CEOF,
#define AUTO 10 TOK_AUTO,
#define EXTERN 11 TOK_EXTERN,
#define REGISTER 12 TOK_REGISTER,
#define STATIC 13 TOK_STATIC,
#define TYPEDEF 14 TOK_TYPEDEF,
#define ENUM 15 TOK_ENUM,
#define CONST 16 TOK_CONST,
#define VOLATILE 17 TOK_VOLATILE,
#define FIRSTTYPE 19 /* Tokens denoting types */
#define CHAR 19 TOK_FIRSTTYPE,
#define INT 20 TOK_CHAR = TOK_FIRSTTYPE,
#define DOUBLE 21 TOK_INT,
#define FLOAT 22 TOK_DOUBLE,
#define LONG 23 TOK_FLOAT,
#define UNSIGNED 24 TOK_LONG,
#define SIGNED 25 TOK_UNSIGNED,
#define SHORT 26 TOK_SIGNED,
#define STRUCT 27 TOK_SHORT,
#define UNION 28 TOK_STRUCT,
#define VOID 29 TOK_UNION,
#define LASTTYPE 29 TOK_VOID,
TOK_LASTTYPE = TOK_VOID,
#define DO 30 /* Control statements */
#define FOR 31 TOK_DO,
#define GOTO 32 TOK_FOR,
#define IF 33 TOK_GOTO,
#define RETURN 34 TOK_IF,
#define SWITCH 35 TOK_RETURN,
#define WHILE 36 TOK_SWITCH,
TOK_WHILE,
#define ASM 40 TOK_ASM,
#define CASE 41 TOK_CASE,
#define DEFAULT 42 TOK_DEFAULT,
#define BREAK 43 TOK_BREAK,
#define CONTINUE 44 TOK_CONTINUE,
#define ELSE 45 TOK_ELSE,
#define ELLIPSIS 46 TOK_ELLIPSIS,
#define SIZEOF 47 TOK_SIZEOF,
#define IDENT 50 TOK_IDENT,
#define SEMI 51 TOK_SEMI,
/* primary operators */ /* Primary operators */
#define LBRACK 52 TOK_LBRACK,
#define LPAREN 53 TOK_LPAREN,
#define DOT 54 TOK_DOT,
#define PREF 55 TOK_PTR_REF,
#define LCURLY 56 TOK_LCURLY,
#define RBRACK 57 TOK_RBRACK,
#define COMP 58 TOK_COMP,
#define INC 59 TOK_INC,
#define PASGN 60 TOK_PLUS_ASSIGN,
#define PLUS 61 TOK_PLUS,
#define COMMA 62 TOK_COMMA,
#define DEC 63 TOK_DEC,
#define SASGN 64 TOK_MINUS_ASSIGN,
#define RCURLY 65 TOK_RCURLY,
#define MINUS 66 TOK_MINUS,
#define MASGN 67 TOK_MUL_ASSIGN,
#define STAR 68 TOK_STAR,
#define DASGN 69 TOK_DIV_ASSIGN,
#define DIV 70 TOK_DIV,
#define DAMP 71 TOK_BOOL_AND,
#define AASGN 72 TOK_AND_ASSIGN,
#define AMP 73 TOK_AND,
#define NE 74 TOK_NE,
#define BANG 75 TOK_BOOL_NOT,
#define DBAR 76 TOK_BOOL_OR,
#define OASGN 77 TOK_OR_ASSIGN,
#define BAR 78 TOK_OR,
#define EQ 79 TOK_EQ,
#define ASGN 80 TOK_ASSIGN,
#define SLASGN 81 TOK_SHL_ASSIGN,
#define ASL 82 TOK_SHL,
/* inequalities */ /* Inequalities */
#define LE 83 TOK_LE,
#define LT 84 TOK_LT,
#define GE 85 TOK_GE,
#define GT 86 TOK_GT,
#define SRASGN 87 TOK_SHR_ASSIGN,
#define ASR 88 TOK_SHR,
#define XOASGN 89 TOK_XOR_ASSIGN,
#define XOR 90 TOK_XOR,
#define MOASGN 91 TOK_MOD_ASSIGN,
#define MOD 92 TOK_MOD,
#define QUEST 93 TOK_QUEST,
#define COLON 94 TOK_COLON,
#define RPAREN 95 TOK_RPAREN,
#define SCONST 96 TOK_SCONST,
#define ICONST 97 TOK_ICONST,
#define CCONST 98 TOK_CCONST,
#define FCONST 99 TOK_FCONST,
#define FASTCALL 100 TOK_ATTRIBUTE,
#define AX 101 TOK_FASTCALL,
#define EAX 102 TOK_AX,
TOK_EAX,
#define PRAGMA 110 TOK_PRAGMA
} token_t;
@@ -138,7 +143,7 @@
/* Token stuff */ /* Token stuff */
typedef struct Token_ Token; typedef struct Token_ Token;
struct Token_ { struct Token_ {
unsigned Tok; /* The token itself */ token_t Tok; /* The token itself */
long IVal; /* The integer attribute */ long IVal; /* The integer attribute */
ident Ident; /* Identifier if IDENT */ ident Ident; /* Identifier if IDENT */
unsigned Pos; /* Source line where the token comes from */ unsigned Pos; /* Source line where the token comes from */
@@ -173,10 +178,10 @@ void symname (char* s);
int issym (char* s); int issym (char* s);
/* Get symbol from input stream or return 0 if not a symbol. */ /* Get symbol from input stream or return 0 if not a symbol. */
void gettok (void); void NextToken (void);
/* Get next token from input stream */ /* Get next token from input stream */
void Consume (unsigned Token, unsigned char ErrNum); void Consume (token_t Token, unsigned ErrNum);
/* Eat token if it is the next in the input stream, otherwise print an error /* Eat token if it is the next in the input stream, otherwise print an error
* message. * message.
*/ */

View File

@@ -61,7 +61,7 @@ static int doif (void)
int gotbreak; int gotbreak;
/* Skip the if */ /* Skip the if */
gettok (); NextToken ();
/* Generate a jump label and parse the condition */ /* Generate a jump label and parse the condition */
flab1 = GetLabel (); flab1 = GetLabel ();
@@ -71,7 +71,7 @@ static int doif (void)
gotbreak = statement (); gotbreak = statement ();
/* Else clause present? */ /* Else clause present? */
if (curtok != ELSE) { if (curtok != TOK_ELSE) {
g_defloclabel (flab1); g_defloclabel (flab1);
/* Since there's no else clause, we're not sure, if the a break /* Since there's no else clause, we're not sure, if the a break
@@ -82,7 +82,7 @@ static int doif (void)
} else { } else {
/* Skip the else */ /* Skip the else */
gettok (); NextToken ();
/* If we had some sort of break statement at the end of the if clause, /* If we had some sort of break statement at the end of the if clause,
* there's no need to generate an additional jump around the else * there's no need to generate an additional jump around the else
@@ -116,7 +116,7 @@ static void dowhile (char wtype)
int loop; int loop;
int lab; int lab;
gettok (); NextToken ();
loop = GetLabel (); loop = GetLabel ();
lab = GetLabel (); lab = GetLabel ();
addloop (oursp, loop, lab, 0, 0); addloop (oursp, loop, lab, 0, 0);
@@ -132,9 +132,9 @@ static void dowhile (char wtype)
* do another small optimization here, and use a conditional jump * do another small optimization here, and use a conditional jump
* instead an absolute one. * instead an absolute one.
*/ */
if (curtok == SEMI) { if (curtok == TOK_SEMI) {
/* Shortcut */ /* Shortcut */
gettok (); NextToken ();
/* Use a conditional jump */ /* Use a conditional jump */
g_truejump (CF_NONE, loop); g_truejump (CF_NONE, loop);
} else { } else {
@@ -148,7 +148,7 @@ static void dowhile (char wtype)
/* Do loop */ /* Do loop */
statement (); statement ();
Consume (WHILE, ERR_WHILE_EXPECTED); Consume (TOK_WHILE, ERR_WHILE_EXPECTED);
test (loop, 1); test (loop, 1);
ConsumeSemi (); ConsumeSemi ();
g_defloclabel (lab); g_defloclabel (lab);
@@ -167,8 +167,8 @@ static void doreturn (void)
int HaveVal = 0; /* Do we have a return value in ax? */ int HaveVal = 0; /* Do we have a return value in ax? */
gettok (); NextToken ();
if (curtok != SEMI) { if (curtok != TOK_SEMI) {
if (HasVoidReturn (CurrentFunc)) { if (HasVoidReturn (CurrentFunc)) {
Error (ERR_CANNOT_RETURN_VALUE); Error (ERR_CANNOT_RETURN_VALUE);
} }
@@ -198,7 +198,7 @@ static void dobreak (void)
{ {
struct loopdesc* l; struct loopdesc* l;
gettok (); NextToken ();
if ((l = currentloop ()) == 0) { if ((l = currentloop ()) == 0) {
/* Error: No current loop */ /* Error: No current loop */
return; return;
@@ -214,7 +214,7 @@ static void docontinue (void)
{ {
struct loopdesc* l; struct loopdesc* l;
gettok (); NextToken ();
if ((l = currentloop ()) == 0) { if ((l = currentloop ()) == 0) {
/* Error: Not in loop */ /* Error: Not in loop */
return; return;
@@ -263,9 +263,9 @@ static void cascadeswitch (struct expent* eval)
/* Parse the labels */ /* Parse the labels */
lcount = 0; lcount = 0;
while (curtok != RCURLY) { while (curtok != TOK_RCURLY) {
if (curtok == CASE || curtok == DEFAULT) { if (curtok == TOK_CASE || curtok == TOK_DEFAULT) {
/* If the code for the previous selector did not end with a /* If the code for the previous selector did not end with a
* break statement, we must jump over the next selector test. * break statement, we must jump over the next selector test.
@@ -284,16 +284,16 @@ static void cascadeswitch (struct expent* eval)
nextlab = 0; nextlab = 0;
} }
while (curtok == CASE || curtok == DEFAULT) { while (curtok == TOK_CASE || curtok == TOK_DEFAULT) {
/* Parse the selector */ /* Parse the selector */
if (curtok == CASE) { if (curtok == TOK_CASE) {
/* Count labels */ /* Count labels */
++lcount; ++lcount;
/* Skip the "case" token */ /* Skip the "case" token */
gettok (); NextToken ();
/* Read the selector expression */ /* Read the selector expression */
constexpr (&lval); constexpr (&lval);
@@ -343,13 +343,13 @@ static void cascadeswitch (struct expent* eval)
/* If another case follows, we will jump to the code if /* If another case follows, we will jump to the code if
* the condition is true. * the condition is true.
*/ */
if (curtok == CASE) { if (curtok == TOK_CASE) {
/* Create a code label if needed */ /* Create a code label if needed */
if (codelab == 0) { if (codelab == 0) {
codelab = GetLabel (); codelab = GetLabel ();
} }
g_falsejump (CF_NONE, codelab); g_falsejump (CF_NONE, codelab);
} else if (curtok != DEFAULT) { } else if (curtok != TOK_DEFAULT) {
/* No case follows, jump to next selector */ /* No case follows, jump to next selector */
if (nextlab == 0) { if (nextlab == 0) {
nextlab = GetLabel (); nextlab = GetLabel ();
@@ -360,13 +360,13 @@ static void cascadeswitch (struct expent* eval)
} else { } else {
/* Default case */ /* Default case */
gettok (); NextToken ();
/* Skip the colon */ /* Skip the colon */
ConsumeColon (); ConsumeColon ();
/* Handle the pathologic case: DEFAULT followed by CASE */ /* Handle the pathologic case: DEFAULT followed by CASE */
if (curtok == CASE) { if (curtok == TOK_CASE) {
if (codelab == 0) { if (codelab == 0) {
codelab = GetLabel (); codelab = GetLabel ();
} }
@@ -385,7 +385,7 @@ static void cascadeswitch (struct expent* eval)
} }
/* Parse statements */ /* Parse statements */
if (curtok != RCURLY) { if (curtok != TOK_RCURLY) {
havebreak = statement (); havebreak = statement ();
} }
} }
@@ -396,7 +396,7 @@ static void cascadeswitch (struct expent* eval)
} }
/* Eat the closing curly brace */ /* Eat the closing curly brace */
gettok (); NextToken ();
/* Define the exit label and, if there's a next label left, create this /* Define the exit label and, if there's a next label left, create this
* one, too. * one, too.
@@ -445,15 +445,15 @@ static void tableswitch (struct expent* eval)
/* Jump behind the code for the CASE labels */ /* Jump behind the code for the CASE labels */
g_jump (lcase = GetLabel ()); g_jump (lcase = GetLabel ());
lcount = 0; lcount = 0;
while (curtok != RCURLY) { while (curtok != TOK_RCURLY) {
if (curtok == CASE || curtok == DEFAULT) { if (curtok == TOK_CASE || curtok == TOK_DEFAULT) {
if (lcount >= CASE_MAX) { if (lcount >= CASE_MAX) {
Fatal (FAT_TOO_MANY_CASE_LABELS); Fatal (FAT_TOO_MANY_CASE_LABELS);
} }
label = GetLabel (); label = GetLabel ();
do { do {
if (curtok == CASE) { if (curtok == TOK_CASE) {
gettok (); NextToken ();
constexpr (&lval); constexpr (&lval);
if (!IsInt (lval.e_tptr)) { if (!IsInt (lval.e_tptr)) {
Error (ERR_ILLEGAL_TYPE); Error (ERR_ILLEGAL_TYPE);
@@ -463,15 +463,15 @@ static void tableswitch (struct expent* eval)
++p; ++p;
++lcount; ++lcount;
} else { } else {
gettok (); NextToken ();
dlabel = label; dlabel = label;
} }
ConsumeColon (); ConsumeColon ();
} while (curtok == CASE || curtok == DEFAULT); } while (curtok == TOK_CASE || curtok == TOK_DEFAULT);
g_defloclabel (label); g_defloclabel (label);
havebreak = 0; havebreak = 0;
} }
if (curtok != RCURLY) { if (curtok != TOK_RCURLY) {
havebreak = statement (); havebreak = statement ();
} }
} }
@@ -482,7 +482,7 @@ static void tableswitch (struct expent* eval)
} }
/* Eat the closing curly brace */ /* Eat the closing curly brace */
gettok (); NextToken ();
/* If the last statement doesn't have a break or return, add one */ /* If the last statement doesn't have a break or return, add one */
if (!havebreak) { if (!havebreak) {
@@ -526,7 +526,7 @@ static void doswitch (void)
struct expent eval; /* Switch statement expression */ struct expent eval; /* Switch statement expression */
/* Eat the "switch" */ /* Eat the "switch" */
gettok (); NextToken ();
/* Read the switch expression */ /* Read the switch expression */
ConsumeLParen (); ConsumeLParen ();
@@ -557,19 +557,19 @@ static void dofor (void)
struct expent lval2; struct expent lval2;
struct expent lval3; struct expent lval3;
gettok (); NextToken ();
loop = GetLabel (); loop = GetLabel ();
lab = GetLabel (); lab = GetLabel ();
linc = GetLabel (); linc = GetLabel ();
lstat = GetLabel (); lstat = GetLabel ();
addloop (oursp, loop, lab, linc, lstat); addloop (oursp, loop, lab, linc, lstat);
ConsumeLParen (); ConsumeLParen ();
if (curtok != SEMI) { /* exp1 */ if (curtok != TOK_SEMI) { /* exp1 */
expression (&lval1); expression (&lval1);
} }
ConsumeSemi (); ConsumeSemi ();
g_defloclabel (loop); g_defloclabel (loop);
if (curtok != SEMI) { /* exp2 */ if (curtok != TOK_SEMI) { /* exp2 */
boolexpr (&lval2); boolexpr (&lval2);
g_truejump (CF_NONE, lstat); g_truejump (CF_NONE, lstat);
g_jump (lab); g_jump (lab);
@@ -578,7 +578,7 @@ static void dofor (void)
} }
ConsumeSemi (); ConsumeSemi ();
g_defloclabel (linc); g_defloclabel (linc);
if (curtok != RPAREN) { /* exp3 */ if (curtok != TOK_RPAREN) { /* exp3 */
expression (&lval3); expression (&lval3);
} }
ConsumeRParen (); ConsumeRParen ();
@@ -601,7 +601,7 @@ static int statement (void)
struct expent lval; struct expent lval;
/* */ /* */
if (curtok == IDENT && nxttok == COLON) { if (curtok == TOK_IDENT && nxttok == TOK_COLON) {
/* Special handling for a label */ /* Special handling for a label */
DoLabel (); DoLabel ();
@@ -610,54 +610,54 @@ static int statement (void)
switch (curtok) { switch (curtok) {
case LCURLY: case TOK_LCURLY:
return compound (); return compound ();
case IF: case TOK_IF:
return doif (); return doif ();
case WHILE: case TOK_WHILE:
dowhile ('w'); dowhile ('w');
break; break;
case DO: case TOK_DO:
dowhile ('d'); dowhile ('d');
break; break;
case SWITCH: case TOK_SWITCH:
doswitch (); doswitch ();
break; break;
case RETURN: case TOK_RETURN:
doreturn (); doreturn ();
ConsumeSemi (); ConsumeSemi ();
return 1; return 1;
case BREAK: case TOK_BREAK:
dobreak (); dobreak ();
ConsumeSemi (); ConsumeSemi ();
return 1; return 1;
case CONTINUE: case TOK_CONTINUE:
docontinue (); docontinue ();
ConsumeSemi (); ConsumeSemi ();
return 1; return 1;
case FOR: case TOK_FOR:
dofor (); dofor ();
break; break;
case GOTO: case TOK_GOTO:
DoGoto (); DoGoto ();
ConsumeSemi (); ConsumeSemi ();
return 1; return 1;
case SEMI: case TOK_SEMI:
/* ignore it. */ /* ignore it. */
gettok (); NextToken ();
break; break;
case PRAGMA: case TOK_PRAGMA:
DoPragma (); DoPragma ();
break; break;
@@ -682,7 +682,7 @@ int compound (void)
int oldsp; int oldsp;
/* eat LCURLY */ /* eat LCURLY */
gettok (); NextToken ();
/* Remember the stack at block entry */ /* Remember the stack at block entry */
oldsp = oursp; oldsp = oursp;
@@ -698,8 +698,8 @@ int compound (void)
/* Now process statements in the function body */ /* Now process statements in the function body */
isbrk = 0; isbrk = 0;
while (curtok != RCURLY) { while (curtok != TOK_RCURLY) {
if (curtok == CEOF) if (curtok == TOK_CEOF)
break; break;
else { else {
isbrk = statement (); isbrk = statement ();

View File

@@ -86,10 +86,8 @@ SymTable EmptySymTab = {
static unsigned LexicalLevel = 0; /* For safety checks */ static unsigned LexicalLevel = 0; /* For safety checks */
static SymTable* SymTab0 = 0; static SymTable* SymTab0 = 0;
static SymTable* SymTab = 0; static SymTable* SymTab = 0;
static SymTable* StructTab0 = 0; static SymTable* TagTab0 = 0;
static SymTable* StructTab = 0; static SymTable* TagTab = 0;
static SymTable* EnumTab0 = 0;
static SymTable* EnumTab = 0;
static SymTable* LabelTab = 0; static SymTable* LabelTab = 0;
@@ -207,11 +205,8 @@ void EnterGlobalLevel (void)
/* Create and assign the symbol table */ /* Create and assign the symbol table */
SymTab0 = SymTab = NewSymTable (SYMTAB_SIZE_GLOBAL); SymTab0 = SymTab = NewSymTable (SYMTAB_SIZE_GLOBAL);
/* Create and assign the struct table */ /* Create and assign the tag table */
StructTab0 = StructTab = NewSymTable (SYMTAB_SIZE_GLOBAL); TagTab0 = TagTab = NewSymTable (SYMTAB_SIZE_GLOBAL);
/* Create and assign the enum table */
EnumTab0 = EnumTab = NewSymTable (SYMTAB_SIZE_GLOBAL);
} }
@@ -228,14 +223,12 @@ void LeaveGlobalLevel (void)
/* Dump the tables if requested */ /* Dump the tables if requested */
if (Debug) { if (Debug) {
PrintSymTable (SymTab0, stdout, "Global symbol table"); PrintSymTable (SymTab0, stdout, "Global symbol table");
PrintSymTable (StructTab0, stdout, "Global struct table"); PrintSymTable (TagTab0, stdout, "Global tag table");
PrintSymTable (EnumTab0, stdout, "Global enum table");
} }
/* Don't delete the symbol and struct tables! */ /* Don't delete the symbol and struct tables! */
SymTab0 = SymTab = 0; SymTab0 = SymTab = 0;
StructTab0 = StructTab = 0; TagTab0 = TagTab = 0;
EnumTab0 = EnumTab = 0;
} }
@@ -253,15 +246,10 @@ void EnterFunctionLevel (void)
S->PrevTab = SymTab; S->PrevTab = SymTab;
SymTab = S; SymTab = S;
/* Get a new struct table and make it current */ /* Get a new tag table and make it current */
S = NewSymTable (SYMTAB_SIZE_FUNCTION); S = NewSymTable (SYMTAB_SIZE_FUNCTION);
S->PrevTab = StructTab; S->PrevTab = TagTab;
StructTab = S; TagTab = S;
/* Get a new enum table and make it current */
S = NewSymTable (SYMTAB_SIZE_FUNCTION);
S->PrevTab = EnumTab;
EnumTab = S;
/* Create and assign a new label table */ /* Create and assign a new label table */
LabelTab = NewSymTable (SYMTAB_SIZE_LABEL); LabelTab = NewSymTable (SYMTAB_SIZE_LABEL);
@@ -276,14 +264,12 @@ void RememberFunctionLevel (struct FuncDesc* F)
--LexicalLevel; --LexicalLevel;
/* Remember the tables */ /* Remember the tables */
F->SymTab = SymTab; F->SymTab = SymTab;
F->StructTab = StructTab; F->TagTab = TagTab;
F->EnumTab = EnumTab;
/* Don't delete the tables */ /* Don't delete the tables */
SymTab = SymTab->PrevTab; SymTab = SymTab->PrevTab;
StructTab = StructTab->PrevTab; TagTab = TagTab->PrevTab;
EnumTab = EnumTab->PrevTab;
} }
@@ -298,11 +284,8 @@ void ReenterFunctionLevel (struct FuncDesc* F)
F->SymTab->PrevTab = SymTab; F->SymTab->PrevTab = SymTab;
SymTab = F->SymTab; SymTab = F->SymTab;
F->StructTab->PrevTab = StructTab; F->TagTab->PrevTab = TagTab;
StructTab = F->StructTab; TagTab = F->TagTab;
F->EnumTab->PrevTab = EnumTab;
EnumTab = F->EnumTab;
/* Create and assign a new label table */ /* Create and assign a new label table */
LabelTab = NewSymTable (SYMTAB_SIZE_LABEL); LabelTab = NewSymTable (SYMTAB_SIZE_LABEL);
@@ -326,9 +309,8 @@ void LeaveFunctionLevel (void)
} }
/* Don't delete the tables */ /* Don't delete the tables */
SymTab = SymTab->PrevTab; SymTab = SymTab->PrevTab;
StructTab = StructTab->PrevTab; TagTab = TagTab->PrevTab;
EnumTab = EnumTab->PrevTab;
LabelTab = 0; LabelTab = 0;
} }
@@ -347,15 +329,10 @@ void EnterBlockLevel (void)
S->PrevTab = SymTab; S->PrevTab = SymTab;
SymTab = S; SymTab = S;
/* Get a new struct table and make it current */ /* Get a new tag table and make it current */
S = NewSymTable (SYMTAB_SIZE_BLOCK); S = NewSymTable (SYMTAB_SIZE_BLOCK);
S->PrevTab = StructTab; S->PrevTab = TagTab;
StructTab = S; TagTab = S;
/* Get a new enum table and make it current */
S = NewSymTable (SYMTAB_SIZE_BLOCK);
S->PrevTab = EnumTab;
EnumTab = S;
} }
@@ -370,9 +347,8 @@ void LeaveBlockLevel (void)
CheckSymTable (SymTab); CheckSymTable (SymTab);
/* Don't delete the tables */ /* Don't delete the tables */
SymTab = SymTab->PrevTab; SymTab = SymTab->PrevTab;
StructTab = StructTab->PrevTab; TagTab = TagTab->PrevTab;
EnumTab = EnumTab->PrevTab;
} }
@@ -463,18 +439,18 @@ SymEntry* FindSym (const char* Name)
SymEntry* FindStructSym (const char* Name) SymEntry* FindLocalSym (const char* Name)
/* Find the symbol with the given name in the struct table */ /* Find the symbol with the given name in the current symbol table only */
{ {
return FindSymInTree (StructTab, Name); return FindSymInTable (SymTab, Name, HashStr (Name));
} }
SymEntry* FindEnumSym (const char* Name) SymEntry* FindTagSym (const char* Name)
/* Find the symbol with the given name in the enum table */ /* Find the symbol with the given name in the tag table */
{ {
return FindSymInTree (EnumTab, Name); return FindSymInTree (TagTab, Name);
} }
@@ -552,11 +528,11 @@ SymEntry* AddStructSym (const char* Name, unsigned Size, SymTable* Tab)
/* Add a struct/union entry and return it */ /* Add a struct/union entry and return it */
{ {
/* Do we have an entry with this name already? */ /* Do we have an entry with this name already? */
SymEntry* Entry = FindSymInTable (StructTab, Name, HashStr (Name)); SymEntry* Entry = FindSymInTable (TagTab, Name, HashStr (Name));
if (Entry) { if (Entry) {
/* We do have an entry. This may be a forward, so check it. */ /* We do have an entry. This may be a forward, so check it. */
if (Entry->Flags != SC_STRUCT) { if ((Entry->Flags & SC_STRUCT) == 0) {
/* Existing symbol is not a struct */ /* Existing symbol is not a struct */
Error (ERR_SYMBOL_KIND); Error (ERR_SYMBOL_KIND);
} else if (Size > 0 && Entry->V.S.Size > 0) { } else if (Size > 0 && Entry->V.S.Size > 0) {
@@ -580,7 +556,7 @@ SymEntry* AddStructSym (const char* Name, unsigned Size, SymTable* Tab)
Entry->V.S.Size = Size; Entry->V.S.Size = Size;
/* Add it to the current table */ /* Add it to the current table */
AddSymEntry (StructTab, Entry); AddSymEntry (TagTab, Entry);
} }
/* Return the entry */ /* Return the entry */
@@ -786,6 +762,14 @@ SymTable* GetSymTab (void)
int SymIsLocal (SymEntry* Sym)
/* Return true if the symbol is defined in the highest lexical level */
{
return (Sym->Owner == SymTab || Sym->Owner == TagTab);
}
static int EqualSymTables (SymTable* Tab1, SymTable* Tab2) static int EqualSymTables (SymTable* Tab1, SymTable* Tab2)
/* Compare two symbol tables. Return 1 if they are equal and 0 otherwise */ /* Compare two symbol tables. Return 1 if they are equal and 0 otherwise */
{ {
@@ -825,6 +809,7 @@ int EqualTypes (const type* Type1, const type* Type2)
SymTable* Tab2; SymTable* Tab2;
FuncDesc* F1; FuncDesc* F1;
FuncDesc* F2; FuncDesc* F2;
int Ok;
/* Shortcut here: If the pointers are identical, the types are identical */ /* Shortcut here: If the pointers are identical, the types are identical */
@@ -841,17 +826,36 @@ int EqualTypes (const type* Type1, const type* Type2)
/* Compare the function descriptors */ /* Compare the function descriptors */
F1 = DecodePtr (Type1+1); F1 = DecodePtr (Type1+1);
F2 = DecodePtr (Type2+1); F2 = DecodePtr (Type2+1);
if ((F1->Flags & ~FD_IMPLICIT) != (F2->Flags & ~FD_IMPLICIT)) {
/* Flags differ */ /* If one of the functions is implicitly declared, both
return 0; * functions are considered equal. If one of the functions is
* old style, and the other is empty, the functions are
* considered equal.
*/
if ((F1->Flags & FD_IMPLICIT) != 0 || (F2->Flags & FD_IMPLICIT) != 0) {
Ok = 1;
} else if ((F1->Flags & FD_OLDSTYLE) != 0 && (F2->Flags & FD_EMPTY) != 0) {
Ok = 1;
} else if ((F1->Flags & FD_EMPTY) != 0 && (F2->Flags & FD_OLDSTYLE) != 0) {
Ok = 1;
} else {
Ok = 0;
} }
/* Compare the parameter lists */ if (!Ok) {
if (EqualSymTables (F1->SymTab, F2->SymTab) == 0 ||
EqualSymTables (F1->StructTab, F2->StructTab) == 0 || /* Check the remaining flags */
EqualSymTables (F1->EnumTab, F2->EnumTab) == 0) { if ((F1->Flags & ~FD_IGNORE) != (F2->Flags & ~FD_IGNORE)) {
/* One of the tables is not identical */ /* Flags differ */
return 0; return 0;
}
/* Compare the parameter lists */
if (EqualSymTables (F1->SymTab, F2->SymTab) == 0 ||
EqualSymTables (F1->TagTab, F2->TagTab) == 0) {
/* One of the tables is not identical */
return 0;
}
} }
/* Skip the FuncDesc pointers to compare the return type */ /* Skip the FuncDesc pointers to compare the return type */

View File

@@ -117,11 +117,11 @@ void LeaveStructLevel (void);
SymEntry* FindSym (const char* Name); SymEntry* FindSym (const char* Name);
/* Find the symbol with the given name */ /* Find the symbol with the given name */
SymEntry* FindStructSym (const char* Name); SymEntry* FindLocalSym (const char* Name);
/* Find the symbol with the given name in the struct table */ /* Find the symbol with the given name in the current symbol table only */
SymEntry* FindEnumSym (const char* Name); SymEntry* FindTagSym (const char* Name);
/* Find the symbol with the given name in the enum table */ /* Find the symbol with the given name in the tag table */
SymEntry* FindStructField (const type* TypeArray, const char* Name); SymEntry* FindStructField (const type* TypeArray, const char* Name);
/* Find a struct field in the fields list */ /* Find a struct field in the fields list */
@@ -160,6 +160,9 @@ SymEntry* AddGlobalSym (const char* Name, type* Type, unsigned Flags);
SymTable* GetSymTab (void); SymTable* GetSymTab (void);
/* Return the current symbol table */ /* Return the current symbol table */
int SymIsLocal (SymEntry* Sym);
/* Return true if the symbol is defined in the highest lexical level */
int EqualTypes (const type* t1, const type* t2); int EqualTypes (const type* t1, const type* t2);
/* Recursively compare two types. Return 1 if the types match, return 0 /* Recursively compare two types. Return 1 if the types match, return 0
* otherwise. * otherwise.