]> git.sur5r.net Git - cc65/commitdiff
Working on the new parser
authorcuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Sat, 19 Aug 2000 21:55:06 +0000 (21:55 +0000)
committercuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Sat, 19 Aug 2000 21:55:06 +0000 (21:55 +0000)
git-svn-id: svn://svn.cc65.org/cc65/trunk@290 b7a2c559-68d2-44c3-8de9-860c34a00d81

12 files changed:
src/cc65/datatype.c
src/cc65/datatype.h
src/cc65/error.h
src/cc65/exprheap.c [new file with mode: 0644]
src/cc65/exprheap.h [new file with mode: 0644]
src/cc65/exprnode.c
src/cc65/exprnode.h
src/cc65/make/gcc.mak
src/cc65/make/watcom.mak
src/cc65/parser.c [new file with mode: 0644]
src/cc65/parser.h [new file with mode: 0644]
src/cc65/scanner.h

index ac86cfa4963b564838862a40287c8c611c799705..59a0adddd3b49da88e1e3d7b196eb99d0746c0c1 100644 (file)
@@ -511,6 +511,22 @@ int IsTypeLong (const type* T)
 
 
 
+int IsTypeFloat (const type* T)
+/* Return true if this is a float type */
+{
+    return (T[0] & T_MASK_TYPE) == T_TYPE_FLOAT;
+}
+
+
+
+int IsTypeDouble (const type* T)
+/* Return true if this is a double type */
+{
+    return (T[0] & T_MASK_TYPE) == T_TYPE_DOUBLE;
+}
+
+
+
 int IsTypePtr (const type* T)
 /* Return true if this is a pointer type */
 {
@@ -551,6 +567,14 @@ int IsClassInt (const type* T)
 
 
 
+int IsClassFloat (const type* T)
+/* Return true if this is a float type */
+{
+    return (T[0] & T_MASK_CLASS) == T_CLASS_FLOAT;
+}
+
+
+
 int IsClassPtr (const type* T)
 /* Return true if this is a pointer type */
 {
index 9224c78d82ccbedce8ef934aef7e482798967b39..680428c128ebb5036e2da4f2e1ed5c57f260f1a7 100644 (file)
@@ -40,6 +40,9 @@
 
 #include <stdio.h>
 
+/* common */
+#include "attrib.h"
+
 
 
 /*****************************************************************************/
@@ -223,67 +226,76 @@ type* Indirect (type* Type);
  * given type points to.
  */
 
-int IsTypeChar (const type* T);
+int IsTypeChar (const type* T) attribute ((const));
 /* Return true if this is a character type */
 
-int IsTypeInt (const type* T);
+int IsTypeInt (const type* T) attribute ((const));
 /* Return true if this is an int type (signed or unsigned) */
 
-int IsTypeLong (const type* T);
+int IsTypeLong (const type* T) attribute ((const));
 /* Return true if this is a long type (signed or unsigned) */
 
-int IsTypePtr (const type* Type);
+int IsTypeFloat (const type* T) attribute ((const));
+/* Return true if this is a float type */
+
+int IsTypeDouble (const type* T) attribute ((const));
+/* Return true if this is a double type */
+
+int IsTypePtr (const type* Type) attribute ((const));
 /* Return true if this is a pointer type */
 
-int IsTypeArray (const type* Type);
+int IsTypeArray (const type* Type) attribute ((const));
 /* Return true if this is an array type */
 
-int IsTypeVoid (const type* Type);
+int IsTypeVoid (const type* Type) attribute ((const));
 /* Return true if this is a void type */
 
-int IsTypeFunc (const type* Type);
+int IsTypeFunc (const type* Type) attribute ((const));
 /* Return true if this is a function class */
 
-int IsClassInt (const type* Type);
+int IsClassInt (const type* Type) attribute ((const));
 /* Return true if this is an integer type */
 
-int IsClassPtr (const type* Type);
+int IsClassFloat (const type* Type) attribute ((const));
+/* Return true if this is a float type */
+
+int IsClassPtr (const type* Type) attribute ((const));
 /* Return true if this is a pointer type */
 
-int IsClassStruct (const type* Type);
+int IsClassStruct (const type* Type) attribute ((const));
 /* Return true if this is a struct type */
 
-int IsSignUnsigned (const type* Type);
+int IsSignUnsigned (const type* Type) attribute ((const));
 /* Return true if this is an unsigned type */
 
-int IsQualConst (const type* T);
+int IsQualConst (const type* T) attribute ((const));
 /* Return true if the given type has a const memory image */
 
-int IsQualVolatile (const type* T);
+int IsQualVolatile (const type* T) attribute ((const));
 /* Return true if the given type has a volatile type qualifier */
 
-int IsFastCallFunc (const type* T);
+int IsFastCallFunc (const type* T) attribute ((const));
 /* Return true if this is a function type with __fastcall__ calling conventions */
 
-int IsTypeFuncPtr (const type* T);
+int IsTypeFuncPtr (const type* T) attribute ((const));
 /* Return true if this is a function pointer */
 
-type GetType (const type* T);
+type GetType (const type* T) attribute ((const));
 /* Get the raw type */
 
-type GetClass (const type* T);
+type GetClass (const type* T) attribute ((const));
 /* Get the class of a type string */
 
-type GetSignedness (const type* T);
+type GetSignedness (const type* T) attribute ((const));
 /* Get the sign of a type */
 
-type GetSizeModifier (const type* T);
+type GetSizeModifier (const type* T) attribute ((const));
 /* Get the size modifier of a type */
 
-type GetQualifier (const type* T);
+type GetQualifier (const type* T) attribute ((const));
 /* Get the qualifier from the given type string */
 
-struct FuncDesc* GetFuncDesc (const type* T);
+struct FuncDesc* GetFuncDesc (const type* T) attribute ((const));
 /* Get the FuncDesc pointer from a function or pointer-to-function type */
 
 
index afedb3dd3cf0d2fd6a38231483b8d408fb762c77..d8b52ae474cbaf8ee87eebbf635b8b3040ebca4f 100644 (file)
 #define ERROR_H
 
 
+                  
+/* common */
+#include "attrib.h"
+
+
 
 /*****************************************************************************/
 /*                                  Data                                    */
@@ -197,7 +202,7 @@ void PPError (unsigned ErrNum, ...);
 void Fatal (unsigned FatNum, ...);
 /* Print a message about a fatal error and die */
 
-void Internal (char* Format, ...);
+void Internal (char* Format, ...) attribute ((noreturn));
 /* Print a message about an internal compiler error and die. */
 
 void ErrorReport (void);
diff --git a/src/cc65/exprheap.c b/src/cc65/exprheap.c
new file mode 100644 (file)
index 0000000..cd5e49f
--- /dev/null
@@ -0,0 +1,208 @@
+/*****************************************************************************/
+/*                                                                           */
+/*                               exprheap.c                                 */
+/*                                                                           */
+/*                      Expression node heap manager                        */
+/*                                                                           */
+/*                                                                           */
+/*                                                                           */
+/* (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.                                                          */
+/*                                                                           */
+/*****************************************************************************/
+
+
+
+/* common */
+#include "check.h"
+#include "xmalloc.h"
+
+/* cc65 */
+#include "exprheap.h"
+
+
+
+/*****************************************************************************/
+/*                                  Data                                    */
+/*****************************************************************************/
+
+
+
+/* A block of expression nodes */
+typedef struct ExprNodeBlock ExprNodeBlock;
+struct ExprNodeBlock {
+    ExprNodeBlock*     Next;           /* Pointer to next block */
+    unsigned           Count;          /* Number of nodes in the block */
+    unsigned           Used;           /* Number of nodes used */
+    ExprNode                   Nodes[1];       /* Nodes, dynamically allocated */
+};
+
+/* An expression heap */
+struct ExprHeap {
+    ExprHeap*          Last;           /* Upper level expression tree */
+    ExprNodeBlock*             BlockRoot;      /* Root of node blocks */
+    ExprNodeBlock*     BlockLast;      /* Last node block */
+    ExprNode*          FreeList;       /* List of free nodes */
+};
+
+/* The current expression heap */
+static ExprHeap*       CurHeap = 0;
+
+
+
+/*****************************************************************************/
+/*                          struct ExprHeapBlock                            */
+/*****************************************************************************/
+
+
+
+static ExprNodeBlock* NewExprNodeBlock (unsigned Count)
+/* Create a new ExprNodeBlock, initialize and return it */
+{
+    /* Calculate the size of the memory block requested */
+    unsigned Size = sizeof (ExprNodeBlock) + (Count-1) * sizeof (ExprNode);
+
+    /* Allocate memory */
+    ExprNodeBlock* B = xmalloc (Size);
+
+    /* Initialize the fields */
+    B->Next  = 0;
+    B->Count = Count;
+    B->Used  = 0;
+
+    /* Return the new block */
+    return B;
+}
+
+
+
+/*****************************************************************************/
+/*                             struct ExprHeap                              */
+/*****************************************************************************/
+
+
+
+static ExprHeap* NewExprHeap (void)
+/* Create and return a new expression tree */
+{
+    /* Allocate memory */
+    ExprHeap* H = xmalloc (sizeof (ExprHeap));
+
+    /* Allocate the first node block */
+    H->BlockRoot = NewExprNodeBlock (64);
+
+    /* Initialize the remaining fields */
+    H->Last      = 0;
+    H->BlockLast = H->BlockRoot;
+    H->FreeList  = 0;
+
+    /* Return the new heap */
+    return H;
+}
+
+
+
+/*****************************************************************************/
+/*                                  Code                                    */
+/*****************************************************************************/
+
+
+
+void PushExprHeap (void)
+/* Create a new expression heap and push it onto the expression heap stack, so
+ * it is the current expression heap.
+ */
+{
+    /* Create a new heap */
+    ExprHeap* H = NewExprHeap ();
+
+    /* Push it onto the stack */
+    H->Last = CurHeap;
+    CurHeap = H;
+}
+
+
+
+ExprHeap* PopExprHeap (void)
+/* Pop the current expression heap from the heap stack and return it */
+{
+    ExprHeap* H;
+
+    /* Cannot pop a non existant heap */
+    PRECONDITION (CurHeap != 0);
+
+    /* Pop the heap */
+    H = CurHeap;
+    CurHeap = H->Last;
+
+    /* Return the old heap */
+    return H;
+}
+
+
+
+ExprNode* AllocExprNode (nodetype_t NT, type* Type, int LValue)
+/* Get a new node from the current expression heap */
+{                                                             
+    ExprNode* N;
+
+    /* Must have a heap */
+    PRECONDITION (CurHeap != 0);
+
+    /* Get a node from the freelist if possible */
+    if (CurHeap->FreeList) {
+       /* There are nodes in the free list */
+       N = CurHeap->FreeList;
+       CurHeap->FreeList = N->MData.Next;
+    } else {
+       /* Free list is empty, allocate a new node */
+       ExprNodeBlock* B = CurHeap->BlockLast;
+       if (B->Used >= B->Count) {
+           /* No nodes left, allocate a new node block */
+           B = NewExprNodeBlock (64);
+           CurHeap->BlockLast->Next = B;
+           CurHeap->BlockLast = B;
+       }
+       N = B->Nodes + B->Count++;
+    }
+
+    /* Initialize and return the allocated node */
+    return InitExprNode (N, NT, Type, LValue, CurHeap);
+}
+
+
+
+void FreeExprNode (ExprNode* N)
+/* Free an expression node from the current expression heap */
+{
+    /* There must be a heap, and the node must be from this heap */
+    PRECONDITION (CurHeap != 0 && N->MData.Owner == CurHeap);
+
+    /* Insert the node in the freelist invalidating the owner pointer */
+    N->MData.Next = CurHeap->FreeList;
+    CurHeap->FreeList = N;
+}
+
+
+
+
diff --git a/src/cc65/exprheap.h b/src/cc65/exprheap.h
new file mode 100644 (file)
index 0000000..a87d04b
--- /dev/null
@@ -0,0 +1,83 @@
+/*****************************************************************************/
+/*                                                                           */
+/*                               exprheap.h                                 */
+/*                                                                           */
+/*                      Expression node heap manager                        */
+/*                                                                           */
+/*                                                                           */
+/*                                                                           */
+/* (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 EXPRHEAP_H
+#define EXPRHEAP_H
+
+
+
+#include "exprnode.h"
+
+
+
+/*****************************************************************************/
+/*                                  Data                                    */
+/*****************************************************************************/
+
+
+
+/* An expression heap */
+typedef struct ExprHeap ExprHeap;
+
+
+
+/*****************************************************************************/
+/*                                  Code                                    */
+/*****************************************************************************/
+
+
+
+void PushExprHeap (void);
+/* Create a new expression heap and push it onto the expression heap stack, so
+ * it is the current expression heap.
+ */
+
+ExprHeap* PopExprHeap (void);
+/* Pop the current expression heap from the heap stack and return it */
+
+ExprNode* AllocExprNode (nodetype_t NT, type* Type, int LValue);
+/* Get a new node from the current expression heap */
+
+void FreeExprNode (ExprNode* N);
+/* Free an expression node from the current expression heap */
+
+
+
+/* End of exprheap.h */
+
+#endif
+
+
+
index d8bc2eda02a50c16f5ecb5482bb1737305256619..c802fcf39c9fabe439d840505421f89e2b6346d3 100644 (file)
 
 
 
-void InitExprNode (ExprNode* E)
+ExprNode* InitExprNode (ExprNode* E, nodetype_t NT, type* Type,
+                       int LValue, struct ExprHeap* Owner)
 /* Initialize a new expression node */
 {
-    E->Left    = 0;
-    E->Right   = 0;
-    E->NT      = NT_NONE;
-    E->Type    = 0;
-    E->LValue  = 0;
+    /* Intialize basic data */
+    E->MData.Owner = Owner;
+    E->NT         = NT;
+    E->Type       = Type;
+    E->LValue     = LValue;
+
+    /* Initialize the expression list in the node */
+    InitCollection (&E->List);
+
+    /* Return the node just initialized */
+    return E;
+}
+
+
+
+void* GetItem (ExprNode* N, unsigned Index)
+/* Return one of the items from the nodes item list */
+{
+    return CollAt (&N->List, Index);
+}
+
+
+
+void AppendItem (ExprNode* N, void* Item)
+/* Append an item to the nodes item list */
+{
+    CollAppend (&N->List, Item);
+}
+
+
+
+void SetItem (ExprNode* N, void* Item, unsigned Index)
+/* Set a specific node item. The item list is filled with null pointers as
+ * needed.
+ */
+{
+    if (Index >= CollCount (&N->List)) {
+       /* Fill up with NULL pointers */
+               while (Index >= CollCount (&N->List) < Index) {
+           CollAppend (&N->List, 0);
+       }
+       /* Append the new item */
+       CollAppend (&N->List, Item);
+    } else {
+       /* There is an item with this index, replace it */
+       CollReplace (&N->List, Item, Index);
+    }
+}
+
+
+
+ExprNode* GetNode (ExprNode* N, unsigned Index)
+/* Get one of the sub-nodes from the list */
+{
+    return GetNode (N, Index);
+}
+
+
+
+ExprNode* GetLeftNode (ExprNode* N)
+/* Get the left sub-node from the list */
+{
+    return GetNode (N, IDX_LEFT);
 }
 
 
 
+void SetLeftNode (ExprNode* Root, ExprNode* Left)
+/* Set the left node in Root */
+{
+    SetItem (Root, Left, IDX_LEFT);
+}
+
+
+
+ExprNode* GetRightNode (ExprNode* N)
+/* Get the right sub-node from the list */
+{
+    return GetNode (N, IDX_RIGHT);
+}
+
+
+
+void SetRightNode (ExprNode* Root, ExprNode* Right)
+/* Set the right node in Root */
+{
+    SetItem (Root, Right, IDX_RIGHT);
+}
+
+
+
+struct SymEntry* GetNodeSym (ExprNode* N)
+/* Get the symbol entry for a NT_SYM node */
+{
+    return GetItem (N, IDX_SYM);
+}
+
+
+
+void SetNodeSym (ExprNode* N, struct SymEntry* Sym)
+/* Set the symbol entry in a NT_SYM node */
+{
+    SetItem (N, Sym, IDX_SYM);
+}
+
+
+
+
index 969ee7506f9a694cf6b4ca3080b2c55da53bc6fe..83065d1127931dd7de626e53ac4eea3090153a0b 100644 (file)
 
 
 
+/* common */
+#include "coll.h"
+
+/* cc65 */
 #include "datatype.h"
 
 
 
 /*****************************************************************************/
-/*                                Forwards                                  */
+/*                                Forwards                                  */
 /*****************************************************************************/
 
 
 
+struct ExprHeap;
 struct SymEntry;
 
 
@@ -64,9 +69,7 @@ typedef enum {
 
     NT_SYM,                    /* Symbol */
     NT_CONST,                          /* A constant of some sort */
-
-    NT_ICAST,                          /* Implicit type cast */
-    NT_ECAST,                          /* Explicit type cast */
+    NT_ASM,                    /* Inline assembler */
 
     NT_REG_A,                          /* A register */
     NT_REG_X,                          /* X register */
@@ -74,9 +77,12 @@ typedef enum {
     NT_REG_AX,                         /* AX register */
     NT_REG_EAX,                        /* EAX register */
 
-    NT_CALLFUNC,                       /* Function call */
-    NT_PUSH,                           /* Push the value onto the stack */
-    NT_POP,                            /* Pop the value from the stack */
+    NT_ARRAY_SUBSCRIPT,                /* Array subscript */
+    NT_STRUCT_ACCESS,          /* Access of a struct field */
+    NT_STRUCTPTR_ACCESS,               /* Access via struct ptr */
+    NT_FUNCTION_CALL,          /* Call a function */
+
+    NT_UNARY_MINUS,
 
     NT_NOT,                            /* ~ */
     NT_PLUS,                           /* + */
@@ -127,36 +133,79 @@ typedef enum {
 typedef struct ExprNode ExprNode;
 struct ExprNode {
 
-    ExprNode*                  Left;   /* Left and right leaves */
-    ExprNode*                  Right;
+    /* Management data */
+    union {
+       struct ExprHeap*        Owner;  /* Heap, this node is in */
+       struct ExprNode*        Next;   /* Next in free list */
+    } MData;
 
+    Collection                 List;   /* List of subexpressions */
     nodetype_t                 NT;     /* Node type */
-    type*                      Type;   /* Resulting type */
-    int                                LValue; /* True if this is an lvalue */
+    type*                      Type;   /* Resulting type */
+    int                                LValue; /* True if this is an lvalue */
 
     union {
-       /* Branch data */
-       ExprNode*               Test;   /* Third expr for ternary op */
-
-       /* Leave data */
                long                    I;      /* Constant int value if any */
                double                  F;      /* Constant float value if any */
-               struct SymEntry*        Sym;    /* Symbol table entry if any */
     } V;
+};
+
+
+
+/* Predefined indices for node items in List */
+enum {
+    IDX_LEFT   = 0,
+    IDX_RIGHT  = 1,
+    IDX_SYM    = 0
+};
 
+/* Some other constants for better readability */
+enum {
+    RVALUE     = 0,
+    LVALUE     = 1
 };
 
 
 
 /*****************************************************************************/
-/*                                  Code                                    */
+/*                                  Code                                    */
 /*****************************************************************************/
 
 
 
-void InitExprNode (ExprNode* E);
+ExprNode* InitExprNode (ExprNode* E, nodetype_t NT, type* Type,
+                       int LValue, struct ExprHeap* Owner);
 /* Initialize a new expression node */
 
+void* GetItem (ExprNode* N, unsigned Index);
+/* Return one of the items from the nodes item list */
+
+void AppendItem (ExprNode* N, void* Item);
+/* Append an item to the nodes item list */
+
+void SetItem (ExprNode* N, void* Item, unsigned Index);
+/* Set a specific node item. The item list is filled with null pointers as
+ * needed.
+ */
+
+ExprNode* GetLeftNode (ExprNode* N);
+/* Get the left sub-node from the list */
+
+void SetLeftNode (ExprNode* Root, ExprNode* Left);
+/* Set the left node in Root */
+
+ExprNode* GetRightNode (ExprNode* N);
+/* Get the right sub-node from the list */
+
+void SetRightNode (ExprNode* Root, ExprNode* Right);
+/* Set the right node in Root */
+
+struct SymEntry* GetNodeSym (ExprNode* N);
+/* Get the symbol entry for a NT_SYM node */
+
+void SetNodeSym (ExprNode* N, struct SymEntry* Sym);
+/* Set the symbol entry in a NT_SYM node */
+
 
 
 /* End of exprnode.h */
index 314d7415b945f9396176e09592c1835b0e670dd2..3639d85442f688a2b198b2d65793431f89aa1b8b 100644 (file)
@@ -24,8 +24,8 @@ OBJS =        anonname.o      \
        declare.o       \
        error.o         \
        expr.o          \
+       exprheap.o      \
        exprnode.o      \
-       exprtree.o      \
        funcdesc.o      \
        function.o      \
        global.o        \
@@ -70,7 +70,7 @@ cc65: $(OBJS)
 
 clean:
        rm -f *~ core *.map
-                        
+
 zap:   clean
        rm -f *.o $(EXECS) .depend
 
index 2e7b041798272d3ba3afbd4c2a8f69a925359fb1..d171b2a87913a62ede555e638e6e46efc95ae8e3 100644 (file)
@@ -73,14 +73,14 @@ OBJS =      anonname.obj    \
        asmline.obj     \
        codegen.obj     \
        compile.obj     \
-       cpu.obj         \
+       cpu.obj         \
        ctrans.obj      \
        datatype.obj    \
        declare.obj     \
        error.obj       \
        expr.obj        \
+       exprheap.obj    \
        exprnode.obj    \
-       exprtree.obj    \
        funcdesc.obj    \
        function.obj    \
        global.obj      \
@@ -138,8 +138,8 @@ FILE datatype.obj
 FILE declare.obj
 FILE error.obj
 FILE expr.obj
+FILE exprheap.obj
 FILE exprnode.obj
-FILE exprtree.obj
 FILE funcdesc.obj
 FILE function.obj
 FILE global.obj
diff --git a/src/cc65/parser.c b/src/cc65/parser.c
new file mode 100644 (file)
index 0000000..1cd0297
--- /dev/null
@@ -0,0 +1,783 @@
+/*****************************************************************************/
+/*                                                                           */
+/*                                parser.c                                  */
+/*                                                                           */
+/*                            Expression parser                             */
+/*                                                                           */
+/*                                                                           */
+/*                                                                           */
+/* (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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+/* common */
+#include "check.h"
+#include "xmalloc.h"
+
+/* cc65 */
+#include "datatype.h"
+#include "declare.h"
+#include "error.h"
+#include "exprheap.h"
+#include "funcdesc.h"
+#include "function.h"
+#include "global.h"
+#include "litpool.h"
+#include "macrotab.h"
+#include "preproc.h"
+#include "scanner.h"
+#include "stdfunc.h"
+#include "symtab.h"
+#include "typecmp.h"
+#include "parser.h"
+
+
+
+/*****************************************************************************/
+/*                                Forwards                                  */
+/*****************************************************************************/
+
+
+
+static ExprNode* UnaryExpr (void);
+ExprNode* Expr1 (void);
+ExprNode* Expr0 (void);
+
+
+
+/*****************************************************************************/
+/*                            Helper functions                              */
+/*****************************************************************************/
+
+
+
+static int IsTypeExpr (void)
+/* Return true if some sort of variable or type is waiting (helper for cast
+ * and sizeof() in hie10).
+ */
+{
+    SymEntry* Entry;
+
+    return curtok == TOK_LPAREN && (
+                   (nxttok >= TOK_FIRSTTYPE && nxttok <= TOK_LASTTYPE) ||
+           (nxttok == TOK_CONST)                               ||
+                   (nxttok  == TOK_IDENT                               &&
+           (Entry = FindSym (NextTok.Ident)) != 0              &&
+           IsTypeDef (Entry))
+           );
+}
+
+
+
+/*****************************************************************************/
+/*                    Expression node helper functions                      */
+/*****************************************************************************/
+
+
+
+static ExprNode* GetIntNode (int Value)
+/* Allocate a new expression node from the tree, make it a valid integer
+ * node and return it. Often used if an error occurs to get a safe expression
+ * tree.
+ */
+{
+    ExprNode* N = AllocExprNode (NT_CONST, type_int, RVALUE);
+    N->V.I = Value;
+    return N;
+}
+
+
+
+/*****************************************************************************/
+/*                                  Code                                    */
+/*****************************************************************************/
+
+
+
+ExprNode* DoAsm (void)
+/* This function parses ASM statements. The syntax of the ASM directive
+ * looks like the one defined for C++ (C has no ASM directive), that is,
+ * a string literal in parenthesis.
+ */
+{
+    ExprNode* N;
+
+
+    /* Skip the ASM */
+    NextToken ();
+
+    /* Need left parenthesis */
+    ConsumeLParen ();
+
+    /* Create a new expression node and assign a void type */
+    N = AllocExprNode (NT_ASM, type_void, RVALUE);
+
+    /* String literal */
+    if (curtok != TOK_SCONST) {
+
+               /* Print an error */
+       Error (ERR_STRLIT_EXPECTED);
+
+       /* To be on the safe side later, insert an empty asm string */
+       AppendItem (N, xstrdup (""));
+
+    } else {
+
+       /* Insert a copy of the string into the expression node */
+       AppendItem (N, xstrdup (GetLiteral (curval)));
+
+       /* Reset the string pointer, effectivly clearing the string from the
+        * string table. Since we're working with one token lookahead, this
+        * will fail if the next token is also a string token, but that's a
+        * syntax error anyway, because we expect a right paren.
+        */
+       ResetLiteralOffs (curval);
+    }
+
+    /* Skip the string token */
+    NextToken ();
+
+    /* Closing paren needed */
+    ConsumeRParen ();
+
+    /* Return the created node */
+    return N;
+}
+
+
+
+static ExprNode* Primary (void)
+/* Evaluate a primary expression */
+{
+    ExprNode* N;
+
+    /* Process a parenthesized subexpression. In this case we don't need to
+     * allocate a new node ourselves.
+     */
+    if (curtok == TOK_LPAREN) {
+               NextToken ();
+               N = Expr0 ();
+               ConsumeRParen ();
+               return N;
+    }
+
+    /* Check for an integer or character constant */
+    if (curtok == TOK_ICONST || curtok == TOK_CCONST) {
+
+       /* Create the new node */
+       N = AllocExprNode (NT_CONST, CurTok.Type, RVALUE);
+               N->V.I = CurTok.IVal;
+
+       /* Skip the token and return the result */
+       NextToken ();
+       return N;
+    }
+
+    /* Check for a float constant */
+    if (curtok == TOK_FCONST) {
+
+       /* Create the new node */
+       N = AllocExprNode (NT_CONST, CurTok.Type, RVALUE);
+               N->V.F = CurTok.FVal;
+
+       /* Skip the token and return the result */
+       NextToken ();
+       return N;
+    }
+
+    /* All others may only be used if the expression evaluation is not called
+     * recursively by the preprocessor.
+     */
+    if (Preprocessing) {
+               /* Illegal expression in PP mode */
+       Error (ERR_CPP_EXPR_EXPECTED);
+
+       /* Skip the token for error recovery */
+       NextToken ();
+
+       /* Return an integer constant */
+       return GetIntNode (0);
+    }
+
+    /* Identifier? */
+    if (curtok == TOK_IDENT) {
+
+       /* Identifier */
+       SymEntry* Sym;
+       ident Ident;
+
+       /* Get a pointer to the symbol table entry */
+               Sym = FindSym (CurTok.Ident);
+
+       /* Is the symbol known? */
+       if (Sym) {
+
+           /* We found the symbol - skip the name token */
+           NextToken ();
+
+           /* Check for illegal symbol types */
+           if ((Sym->Flags & SC_LABEL) == SC_LABEL) {
+               /* Cannot use labels in expressions */
+               Error (ERR_SYMBOL_KIND);
+               return GetIntNode (0);
+                   } else if (Sym->Flags & SC_TYPE) {
+               /* Cannot use type symbols */
+               Error (ERR_VAR_IDENT_EXPECTED);
+               /* Assume an int type to make lval valid */
+               return GetIntNode (0);
+           }
+
+           /* Handle enum values as constant integers */
+                   if ((Sym->Flags & SC_ENUM) == SC_ENUM) {
+
+               N = GetIntNode (Sym->V.EnumVal);
+
+           } else {
+
+               /* All symbols besides functions and arrays are lvalues */
+               int LVal = (!IsTypeFunc (Sym->Type) && !IsTypeArray (Sym->Type));
+
+               /* Create the node */
+               N = AllocExprNode (NT_SYM, Sym->Type, LVal);
+
+               /* Set the symbol pointer */
+               SetNodeSym (N, Sym);
+           }
+
+           /* The symbol is referenced now */
+           Sym->Flags |= SC_REF;
+
+       } else {
+
+           /* We did not find the symbol. Remember the name, then skip it */
+           strcpy (Ident, CurTok.Ident);
+           NextToken ();
+
+           /* IDENT is either an auto-declared function or an undefined
+            * variable.
+            */
+           if (curtok == TOK_LPAREN) {
+
+               /* Warn about the use of a function without prototype */
+               Warning (WARN_FUNC_WITHOUT_PROTO);
+
+               /* Declare a function returning int. For that purpose, prepare
+                * a function signature for a function having an empty param
+                * list and returning int.
+                */
+               Sym = AddGlobalSym (Ident, GetImplicitFuncType(), SC_EXTERN | SC_REF | SC_FUNC);
+               N   = AllocExprNode (NT_SYM, Sym->Type, RVALUE);
+               SetNodeSym (N, Sym);
+
+           } else {
+
+               /* Print an error about an undeclared variable */
+               Error (ERR_UNDEFINED_SYMBOL, Ident);
+
+               /* Undeclared Variable */
+               Sym = AddLocalSym (Ident, type_int, SC_AUTO | SC_REF, 0);
+               N   = AllocExprNode (NT_SYM, Sym->Type, LVALUE);
+               SetNodeSym (N, Sym);
+
+           }
+
+       }
+
+    } else if (curtok == TOK_SCONST) {
+
+       /* String literal */
+       N = AllocExprNode (NT_CONST, GetCharArrayType (strlen (GetLiteral (curval))), RVALUE);
+               N->V.I = curval;
+
+    } else if (curtok == TOK_ASM) {
+
+       /* ASM statement? */
+       N = DoAsm ();
+
+    } else if (curtok == TOK_A) {
+
+       /* A register */
+       N = AllocExprNode (NT_REG_A, type_uchar, LVALUE);
+
+    } else if (curtok == TOK_X) {
+
+       /* X register */
+               N = AllocExprNode (NT_REG_X, type_uchar, LVALUE);
+
+    } else if (curtok == TOK_Y) {
+
+       /* Y register */
+               N = AllocExprNode (NT_REG_Y, type_uchar, LVALUE);
+
+    } else if (curtok == TOK_AX) {
+
+       /* AX pseudo register */
+               N = AllocExprNode (NT_REG_AX, type_uint, LVALUE);
+
+    } else if (curtok == TOK_EAX) {
+
+       /* EAX pseudo register */
+               N = AllocExprNode (NT_REG_EAX, type_ulong, LVALUE);
+
+    } else {
+
+       /* Illegal primary. */
+       Error (ERR_EXPR_EXPECTED);
+               N = GetIntNode (0);
+
+    }
+
+    /* Return the new node */
+    return N;
+}
+
+
+
+static ExprNode* DoArray (ExprNode* Left)
+/* Handle arrays */
+{
+    ExprNode* Right;
+    ExprNode* Root;
+    type*     ElementType;
+
+
+    /* Skip the bracket */
+    NextToken ();
+
+    /* Get the index */
+    Right = Expr0 ();
+
+    /* Check the types.        As special "C" feature, accept a reversal of base and
+     * index types:
+     *          char C = 3["abcdefg"];
+     * is legal C!
+     */
+    if (IsClassPtr (Left->Type)) {
+       /* Right side must be some sort of integer */
+       if (!IsClassInt (Right->Type)) {
+           /* Print an error */
+           Error (ERR_CANNOT_SUBSCRIPT);
+           /* To avoid problems later, create a new, legal subscript
+            * expression
+            */
+           Right = GetIntNode (0);
+       }
+    } else if (IsClassPtr (Right->Type)) {
+
+       ExprNode* Tmp;
+
+       /* Left side must be some sort of integer */
+       if (!IsClassInt (Right->Type)) {
+           /* Print an error */
+           Error (ERR_CANNOT_SUBSCRIPT);
+           /* To avoid problems later, create a new, legal subscript
+            * expression
+            */
+           Left = GetIntNode (0);
+       }
+
+       /* Swap the expression to it's normal form */
+       Tmp   = Right;
+       Right = Left;
+       Left  = Tmp;
+
+    } else {
+       /* Invalid array expression. Skip the closing bracket, then return
+        * an integer instead of the array expression to be safe later.
+        */
+       Error (ERR_CANNOT_SUBSCRIPT);
+       ConsumeRBrack ();
+       return GetIntNode (0);
+    }
+
+    /* Skip the right bracket */
+    ConsumeRBrack ();
+
+    /* Get the type of the array elements */
+    ElementType = Indirect (Left->Type);
+
+    /* Allocate the branch node for the array expression */
+    Root = AllocExprNode (NT_ARRAY_SUBSCRIPT,
+                         ElementType,
+                         IsTypeArray (ElementType)? RVALUE : LVALUE);
+
+    /* Setup the branches */
+    SetLeftNode (Root, Left);
+    SetRightNode (Root, Right);
+
+    /* ...and return it */
+    return Root;
+}
+
+
+
+static ExprNode* DoStruct (ExprNode* Left)
+/* Process struct field access */
+{
+    nodetype_t NT;
+    ident       Ident;
+    type*      StructType;
+    ExprNode*   Right;
+    ExprNode*   Root;
+    SymEntry*  Field;
+
+
+    /* Type check */
+    StructType = Left->Type;
+    if (curtok == TOK_PTR_REF) {
+       NT = NT_STRUCTPTR_ACCESS;
+       if (!IsTypePtr (StructType)) {
+           Error (ERR_STRUCT_PTR_EXPECTED);
+           return GetIntNode (0);
+       }
+       StructType = Indirect (StructType);
+    } else {
+       NT = NT_STRUCT_ACCESS;
+    }
+    if (!IsClassStruct (StructType)) {
+       Error (ERR_STRUCT_EXPECTED);
+       return GetIntNode (0);
+    }
+
+    /* Skip the token and check for an identifier */
+    NextToken ();
+    if (curtok != TOK_IDENT) {
+       /* Print an error */
+       Error (ERR_IDENT_EXPECTED);
+       /* Return an integer expression instead */
+       return GetIntNode (0);
+    }
+
+    /* Get the symbol table entry and check for a struct field */
+    strcpy (Ident, CurTok.Ident);
+    NextToken ();
+    Field = FindStructField (StructType, Ident);
+    if (Field == 0) {
+       /* Struct field not found */
+       Error (ERR_STRUCT_FIELD_MISMATCH, Ident);
+       /* Return an integer expression instead */
+       return GetIntNode (0);
+    }
+
+    /* Allocate and set up the right (== field) node */
+    Right = AllocExprNode (NT_SYM, Field->Type, RVALUE);
+    SetNodeSym (Right, Field);
+
+    /* Allocate the branch node for the resulting expression */
+    Root = AllocExprNode (NT, Right->Type,
+                         IsTypeArray (Right->Type)? RVALUE : LVALUE);
+
+    /* Setup the branches */
+    SetLeftNode (Root, Left);
+    SetRightNode (Root, Right);
+
+    /* ...and return it */
+    return Root;
+}
+
+
+
+static ExprNode* DoFunctionCall (ExprNode* Left)
+/* Process a function call */
+{
+    type*      ResultType;     /* Type of function result */
+    FuncDesc*  Func;           /* Function descriptor */
+    ExprNode*  Root;           /* Function call node */
+    int                Ellipsis;       /* True if we have an open param list */
+    SymEntry*  Param;          /* Current formal parameter */
+    unsigned   ParamCount;     /* Actual parameter count */
+    unsigned   ParamSize;      /* Number of parameter bytes */
+
+
+    /* Type check */
+    if (!IsTypeFunc (Left->Type) && !IsTypeFuncPtr (Left->Type)) {
+
+       /* Call to non function */
+       Error (ERR_ILLEGAL_FUNC_CALL);
+
+       /* Free the old node */
+       FreeExprNode (Left);
+
+       /* Return something safe */
+       return GetIntNode (0);
+    }
+
+    /* Get the type of the function result */
+    ResultType = Left->Type;
+    if (IsTypeFuncPtr (Left->Type)) {
+       ++ResultType;
+    }
+    ResultType += DECODE_SIZE + 1;     /* Set to result type */
+
+    /* Skip the opening parenthesis */
+    NextToken ();
+
+    /* Allocate the function call node */
+    Root = AllocExprNode (NT_FUNCTION_CALL, ResultType, RVALUE);
+
+    /* Get a pointer to the function descriptor from the type string */
+    Func = GetFuncDesc (Left->Type);
+
+    /* Initialize vars to keep gcc silent */
+    Param = 0;
+
+    /* Parse the parameter list */
+    ParamSize  = 0;
+    ParamCount = 0;
+    Ellipsis   = 0;
+    while (curtok != TOK_RPAREN) {
+
+       /* Count arguments */
+       ++ParamCount;
+
+       /* Fetch the pointer to the next argument, check for too many args */
+       if (ParamCount <= Func->ParamCount) {
+           if (ParamCount == 1) {
+               /* First argument */
+               Param = Func->SymTab->SymHead;
+           } else {
+               /* Next argument */
+               Param = Param->NextSym;
+               CHECK ((Param->Flags & SC_PARAM) != 0);
+           }
+       } else if (!Ellipsis) {
+           /* Too many arguments. Do we have an open param list? */
+           if ((Func->Flags & FD_ELLIPSIS) == 0) {
+               /* End of param list reached, no ellipsis */
+               Error (ERR_TOO_MANY_FUNC_ARGS);
+           }
+           /* Assume an ellipsis even in case of errors to avoid an error
+            * message for each other argument.
+            */
+           Ellipsis = 1;
+       }
+
+               /* Get the parameter value expression tree and add it to the parameter
+        * list. (### check expr level)
+        */
+       AppendItem (Root, Expr1 ());
+
+       /* Check for end of argument list */
+       if (curtok != TOK_COMMA) {
+           break;
+       }
+       NextToken ();
+    }
+
+    /* We need the closing bracket here */
+    ConsumeRParen ();
+
+    /* Check if we had enough parameters */
+    if (ParamCount < Func->ParamCount) {
+       Error (ERR_TOO_FEW_FUNC_ARGS);
+    }
+
+    /* Return the function call node */
+    return Root;
+}
+
+
+
+static ExprNode* PostfixExpr (void)
+{
+    /* Get the lower level expression */
+    ExprNode* Root = Primary ();
+
+    /* */
+    while (curtok == TOK_LBRACK || curtok == TOK_LPAREN  ||
+          curtok == TOK_DOT    || curtok == TOK_PTR_REF ||
+          curtok == TOK_INC    || curtok == TOK_DEC) {
+
+       /* This is for us */
+       switch (curtok) {
+
+           case TOK_LBRACK:
+               Root = DoArray (Root);
+               break;
+
+           case TOK_LPAREN:
+               Root = DoFunctionCall (Root);
+               break;
+
+           case TOK_DOT:
+           case TOK_PTR_REF:
+               Root = DoStruct (Root);
+               break;
+
+           case TOK_INC:
+               break;
+
+           case TOK_DEC:
+               break;
+
+           default:
+               Internal ("Unexpected token");
+
+       }
+    }
+
+    /* Return the result */
+    return Root;
+}
+
+
+
+static ExprNode* DoPreIncDec (void)
+/* Handle preincrement and predecrement */
+{
+    ExprNode* Op;
+    ExprNode* Root;
+
+    /* Determine the type of the node */
+    nodetype_t NT = (curtok == TOK_INC)? NT_PRE_INC : NT_PRE_DEC;
+
+    /* Skip the operator token */
+    NextToken ();
+
+    /* Get the expression to increment or decrement */
+    Op = UnaryExpr ();
+
+    /* The operand must be an lvalue */
+    if (Op->LValue == 0) {
+
+       /* Print a diagnostics */
+       Error (ERR_LVALUE_EXPECTED);
+
+       /* It is safe to return the operand expression and probably better
+        * than returning an int, since the operand expression already has
+        * the correct type as expected by the program at this place, and
+        * it is even an rvalue.
+        */
+       return Op;
+    }
+
+    /* Setup the expression tree */
+    Root = AllocExprNode (NT, Op->Type, RVALUE);
+    SetLeftNode (Root, Op);
+
+    /* Return the new node */
+    return Root;
+}
+
+
+
+static ExprNode* DoUnaryPlusMinus (void)
+/* Handle unary +/- */
+{
+    ExprNode* Op;
+    ExprNode* Root;
+
+    /* Remember the current token for later, then skip it */
+    token_t Tok = curtok;
+    NextToken ();
+
+    /* Get the operand */
+    Op = UnaryExpr ();
+
+    /* Type check */
+    if (!IsClassInt (Op->Type) && !IsClassFloat (Op->Type)) {
+
+       /* Display diagnostic */
+       Error (ERR_SYNTAX);
+
+       /* Free the errorneous node */
+       FreeExprNode (Op);
+
+       /* Return something that makes sense later */
+       return GetIntNode (0);
+    }
+
+    /* In case of PLUS, we must do nothing */
+    if (Tok == TOK_PLUS) {
+
+       /* Use the operand unchanged */
+       Root = Op;
+
+    } else {
+
+       /* Setup the expression tree */
+       Root = AllocExprNode (NT_UNARY_MINUS, Op->Type, RVALUE);
+       SetLeftNode (Root, Op);
+
+    }
+
+    /* Return the new node */
+    return Root;
+}
+
+
+
+static ExprNode* UnaryExpr (void)
+{
+    /* */
+    if (curtok == TOK_INC    || curtok == TOK_DEC      ||
+               curtok == TOK_PLUS   || curtok == TOK_MINUS    ||
+               curtok == TOK_AND    || curtok == TOK_STAR     ||
+               curtok == TOK_COMP   || curtok == TOK_BOOL_NOT ||
+               curtok == TOK_SIZEOF || IsTypeExpr ()) {
+
+       /* Check the token */
+               switch (curtok) {
+
+           case TOK_INC:
+           case TOK_DEC:
+               return DoPreIncDec ();
+
+           case TOK_PLUS:
+           case TOK_MINUS:
+               return DoUnaryPlusMinus ();
+
+           case TOK_AND:
+               break;
+
+           case TOK_STAR:
+               break;
+
+           case TOK_COMP:
+               break;
+
+           case TOK_BOOL_NOT:
+               break;
+
+           case TOK_SIZEOF:
+               break;
+
+           default:
+               break;
+
+       }
+
+    } else {
+
+       /* Call the lower level */
+       return PostfixExpr ();
+
+    }
+}
diff --git a/src/cc65/parser.h b/src/cc65/parser.h
new file mode 100644 (file)
index 0000000..c2dda4a
--- /dev/null
@@ -0,0 +1,64 @@
+/*****************************************************************************/
+/*                                                                           */
+/*                                parser.h                                  */
+/*                                                                           */
+/*                            Expression parser                             */
+/*                                                                           */
+/*                                                                           */
+/*                                                                           */
+/* (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 PARSER_H
+#define PARSER_H
+
+
+
+#include "exprnode.h"
+
+
+
+/*****************************************************************************/
+/*                                  Code                                    */
+/*****************************************************************************/
+
+
+
+ExprNode* DoAsm (void);
+/* This function parses ASM statements. The syntax of the ASM directive
+ * looks like the one defined for C++ (C has no ASM directive), that is,
+ * a string literal in parenthesis.
+ */
+
+
+
+/* End of parser.h */
+
+#endif
+
+
+
index db10cb9b909b1f39c7e1ee636d4db6d4354812e6..b7cd10ac58ee1efa32aba00b9af8bd6173be8136 100644 (file)
@@ -129,7 +129,7 @@ typedef enum token_t {
     TOK_FASTCALL,
     TOK_A,
     TOK_X,
-    TOK_Y,       
+    TOK_Y,
     TOK_AX,
     TOK_EAX,
 
@@ -148,10 +148,11 @@ typedef enum token_t {
 typedef struct Token_ Token;
 struct Token_ {
     token_t    Tok;            /* The token itself */
-    long       IVal;           /* The integer attribute */
+    long       IVal;           /* The integer attribute */ 
+    double     FVal;           /* The float attribute */
     ident      Ident;          /* Identifier if IDENT */
     unsigned   Pos;            /* Source line where the token comes from */
-    type*      IType;          /* Type if integer constant */
+    type*              Type;           /* Type if integer or float constant */
 };
 
 extern Token CurTok;           /* The current token */
@@ -161,12 +162,12 @@ extern Token NextTok;             /* The next token */
 #define curtok         CurTok.Tok
 #define curval         CurTok.IVal
 #define curpos         CurTok.Pos
-#define curtype        CurTok.IType
+#define curtype        CurTok.Type
 
 #define nxttok         NextTok.Tok
 #define nxtval         NextTok.IVal
 #define nxtpos         NextTok.Pos
-#define nxttype        NextTok.IType
+#define nxttype        NextTok.Type