]> git.sur5r.net Git - cc65/commitdiff
Working on the new parser.
authorcuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Sun, 15 Oct 2000 19:51:39 +0000 (19:51 +0000)
committercuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Sun, 15 Oct 2000 19:51:39 +0000 (19:51 +0000)
git-svn-id: svn://svn.cc65.org/cc65/trunk@368 b7a2c559-68d2-44c3-8de9-860c34a00d81

src/cc65/exprheap.c
src/cc65/exprheap.h
src/cc65/exprnode.c
src/cc65/exprnode.h
src/cc65/parser.c

index cd5e49f7923fa90cdd728d0b0b038883bf790baa..bbf683716365e56ad8d5b8530ee1c2a11284e0b8 100644 (file)
@@ -163,7 +163,7 @@ ExprHeap* PopExprHeap (void)
 
 ExprNode* AllocExprNode (nodetype_t NT, type* Type, int LValue)
 /* Get a new node from the current expression heap */
-{                                                             
+{
     ExprNode* N;
 
     /* Must have a heap */
@@ -205,4 +205,23 @@ void FreeExprNode (ExprNode* N)
 
 
 
+void FreeExprTree (ExprNode* N)
+/* Free a complete expression tree starting with the current node */
+{
+    if (IsBranchNode (N)) {
+       /* Free the leaf nodes if necessary */
+       if ((N->NT & NT_MASK_LIST) == NT_LIST_EXPR) {
+           unsigned I;
+           unsigned Count = CollCount (&N->List);
+           for (I = 0; I < Count; ++I) {
+               FreeExprNode (CollAt (&N->List, I));
+           }
+       }
+    }
+
+    /* Free the node itself */
+    FreeExprNode (N);
+}
+
+
 
index a87d04b54019d6aff0fd49abbaf39fae30eed27a..09c57677824cd982477c08ae3cc894dbcf0ceb24 100644 (file)
@@ -73,6 +73,9 @@ ExprNode* AllocExprNode (nodetype_t NT, type* Type, int LValue);
 void FreeExprNode (ExprNode* N);
 /* Free an expression node from the current expression heap */
 
+void FreeExprTree (ExprNode* N);
+/* Free a complete expression tree starting with the current node */
+
 
 
 /* End of exprheap.h */
index 8c3e2c61c0a6e24a1b308f4cccf204a33b45e3b0..7cf7aa1001d6714f87b025fe780f1dc7048c06ef 100644 (file)
 
 
 
+/* common */
+#include "check.h"
+
+/* cc65 */
+#include "error.h"
 #include "exprnode.h"
 
 
@@ -156,4 +161,321 @@ void SetNodeSym (ExprNode* N, struct SymEntry* Sym)
 
 
 
+int IsLeafNode (const ExprNode* E)
+/* Return true if this is a leaf node */
+{
+    return (E->NT & NT_MASK_LEAF) == NT_LEAF;
+}
+
+
+
+int IsBranchNode (const ExprNode* E)
+/* Return true if this is a branch node */
+{
+    return (E->NT & NT_MASK_LEAF) == NT_BRANCH;
+}
+
+
+
+void DumpExpr (FILE* F, const ExprNode* E)
+/* Dump an expression in UPN notation to the given file */
+{
+    if (IsLeafNode (E)) {
+
+       /* Operand */
+       switch (E->NT) {
+
+           case NT_SYM:
+               /* Symbol */
+               fprintf (F, "SYM ");
+               break;
+
+           case NT_CONST:
+               /* A constant of some sort */
+               if (IsClassInt (E->Type)) {
+                   fprintf (F, "%0*lX ", SizeOf (E->Type), E->IVal);
+               } else if (IsClassFloat (E->Type)) {
+                   fprintf (F, "%f ", E->FVal);
+               } else {
+                   Internal ("Unknown type for NT_CONST");
+               }
+               break;
+
+           case NT_ASM:
+               /* Inline assembler */
+               fprintf (F, "ASM ");
+               break;
+
+           case NT_REG_A:
+               /* A register */
+               fprintf (F, "REG_A ");
+               break;
+
+           case NT_REG_X:
+               /* X register */
+               fprintf (F, "REG_X ");
+               break;
+
+           case NT_REG_Y:
+               /* Y register */
+               fprintf (F, "REG_Y ");
+               break;
+
+           case NT_REG_AX:
+               /* AX register */
+               fprintf (F, "REG_AX ");
+               break;
+
+           case NT_REG_EAX:
+               /* EAX register */
+               fprintf (F, "REG_EAX ");
+               break;
+
+           default:
+               Internal ("Unknown node type: %04X", E->NT);
+               break;
+
+       }
+
+    } else {
+
+       unsigned I, Count;
+
+       /* Dump the operands */
+       switch (E->NT & NT_MASK_LIST) {
+
+           case NT_LIST_EXPR:
+               Count = CollCount (&E->List);
+               for (I = 0; I < Count; ++I) {
+                   DumpExpr (F, CollConstAt (&E->List, I));
+               }
+               break;
+
+           default:
+               Internal ("Operator with LIST != NT_LIST_EXPR");
+
+       }
+
+       /* Dump the operator */
+       switch (E->NT) {
+
+           case NT_ARRAY_SUBSCRIPT:
+               /* Array subscript */
+               fprintf (F, "[] ");
+               break;
+
+           case NT_STRUCT_ACCESS:
+               /* Access of a struct field */
+               fprintf (F, ". ");
+               break;
+
+           case NT_STRUCTPTR_ACCESS:
+               /* Access via struct ptr */
+               fprintf (F, "-> ");
+               break;
+
+           case NT_FUNCTION_CALL:
+               /* Call a function */
+               fprintf (F, "CALL ");
+               break;
+
+           case NT_TYPECAST:
+               /* A cast */
+               fprintf (F, "CAST ");
+               break;
+
+           case NT_ADDRESS:
+               /* Address operator (&) */
+               fprintf (F, "ADDR ");
+               break;
+
+           case NT_INDIRECT:
+               /* Indirection operator (*) */
+               fprintf (F, "FETCH ");
+               break;
+
+           case NT_UNARY_MINUS:
+               /* - */
+               fprintf (F, "NEG ");
+               break;
+
+           case NT_COMPLEMENT:
+               /* ~ */
+               fprintf (F, "~ ");
+               break;
+
+           case NT_BOOL_NOT:
+               /* ! */
+               fprintf (F, "! ");
+               break;
+
+           case NT_PLUS:
+               /* + */
+               fprintf (F, "+ ");
+               break;
+
+           case NT_MINUS:
+               /* - */
+               fprintf (F, "- ");
+               break;
+
+           case NT_MUL:
+               /* * */
+               fprintf (F, "* ");
+               break;
+
+           case NT_DIV:
+               /* / */
+               fprintf (F, "/ ");
+               break;
+
+           case NT_SHL:
+               /* << */
+               fprintf (F, "<< ");
+               break;
+
+           case NT_SHR:
+               /* >> */
+               fprintf (F, ">> ");
+               break;
+
+           case NT_AND:
+               /* & */
+               fprintf (F, "& ");
+               break;
+
+           case NT_OR:
+               /* | */
+               fprintf (F, "| ");
+               break;
+
+           case NT_XOR:
+               /* ^ */
+               fprintf (F, "^ ");
+               break;
+
+           case NT_TERNARY:
+               /* ?: */
+               fprintf (F, "?: ");
+               break;
+
+           case NT_ASSIGN:
+               /* = */
+               fprintf (F, "= ");
+               break;
+
+           case NT_PLUS_ASSIGN:
+               /* += */
+               fprintf (F, "+= ");
+               break;
+
+           case NT_MINUS_ASSIGN:
+               /* -= */
+               fprintf (F, "-= ");
+               break;
+
+           case NT_MUL_ASSIGN:
+               /* *= */
+               fprintf (F, "*= ");
+               break;
+
+           case NT_DIV_ASSIGN:
+               /* /= */
+               fprintf (F, "/= ");
+               break;
+
+           case NT_SHL_ASSIGN:
+               /* <<= */
+               fprintf (F, "<<= ");
+               break;
+
+           case NT_SHR_ASSIGN:
+               /* >>= */
+               fprintf (F, ">>= ");
+               break;
+
+           case NT_AND_ASSIGN:
+               /* &= */
+               fprintf (F, "&= ");
+               break;
+
+           case NT_OR_ASSIGN:
+               /* |= */
+               fprintf (F, "|= ");
+               break;
+
+           case NT_XOR_ASSIGN:
+               /* ^= */
+               fprintf (F, "^= ");
+               break;
+
+           case NT_PRE_DEC:
+               /* -- */
+               fprintf (F, "<-- ");
+               break;
+
+           case NT_POST_DEC:
+               /* -- */
+               fprintf (F, "--> ");
+               break;
+
+           case NT_PRE_INC:
+               /* ++ */
+               fprintf (F, "<++ ");
+               break;
+
+           case NT_POST_INC:
+               /* ++ */
+               fprintf (F, "++> ");
+               break;
+
+           case NT_BOOL_OR:
+               /* || */
+               fprintf (F, "|| ");
+               break;
+
+           case NT_BOOL_AND:
+               /* && */
+               fprintf (F, "&& ");
+               break;
+
+           case NT_EQ:
+               /* == */
+               fprintf (F, "== ");
+               break;
+
+           case NT_NE:
+               /* != */
+               fprintf (F, "!= ");
+               break;
+
+           case NT_LT:
+               /* < */
+               fprintf (F, "< ");
+               break;
+
+           case NT_LE:
+               /* <= */
+               fprintf (F, "<= ");
+               break;
+
+           case NT_GT:
+               /* > */
+               fprintf (F, "> ");
+               break;
+
+           case NT_GE:
+               /* >= */
+               fprintf (F, ">= ");
+               break;
+
+           default:
+               Internal ("Unknown node type: %04X", E->NT);
+               break;
+
+       }
+    }
+}
+
+
 
index bf518c213e356a6171cc27f809b2ba825a9cf9aa..30284f350bc42b92ba95bc47c5cb25923f4ff1b6 100644 (file)
@@ -76,8 +76,9 @@ typedef enum {
     NT_MASK_LIST       = 0x0300,
 
     /* Two bits telling if this is a leaf or a branch */
-    NT_BRANCH          = 0x4000,       /* Branch */
-    NT_LEAF            = 0x8000,       /* Leaf */
+    NT_LEAF                    = 0x0000,       /* Leaf */
+    NT_BRANCH          = 0x8000,       /* Branch */
+    NT_MASK_LEAF       = 0x8000,
 
     /* Special node type */
     NT_NONE            = 0x0000,       /* None (invalid) op */
@@ -142,7 +143,9 @@ typedef enum {
     NT_LT              = 0x0037 | NT_BRANCH | NT_LIST_EXPR,    /* < */
     NT_LE              = 0x0038 | NT_BRANCH | NT_LIST_EXPR,    /* <= */
     NT_GT              = 0x0039 | NT_BRANCH | NT_LIST_EXPR,    /* > */
-    NT_GE                      = 0x003A | NT_BRANCH | NT_LIST_EXPR     /* >= */
+    NT_GE                      = 0x003A | NT_BRANCH | NT_LIST_EXPR,    /* >= */
+
+    NT_MASK_TYPE       = 0x00FF
 
 } nodetype_t;
 
@@ -224,13 +227,17 @@ struct SymEntry* GetNodeSym (ExprNode* N);
 void SetNodeSym (ExprNode* N, struct SymEntry* Sym);
 /* Set the symbol entry in a NT_SYM node */
 
+int IsLeafNode (const ExprNode* E);
+/* Return true if this is a leaf node */
 
+int IsBranchNode (const ExprNode* E);
+/* Return true if this is a branch node */
 
-/* End of exprnode.h */
 
-#endif
 
+/* End of exprnode.h */
 
+#endif
 
 
 
index 1d22b397c33146f55b46607cafc02ba3f751b0bb..8349aa4fa82b51a33f1007c8c2d9e78d2210c10d 100644 (file)
@@ -543,8 +543,8 @@ static ExprNode* DoFunctionCall (ExprNode* Left)
        /* Call to non function */
        Error (ERR_ILLEGAL_FUNC_CALL);
 
-       /* Free the old node */
-       FreeExprNode (Left);
+       /* Free the old tree */
+       FreeExprTree (Left);
 
        /* Return something safe */
        return GetIntNode (0);
@@ -759,11 +759,11 @@ static ExprNode* DoUnaryPlusMinus (void)
     /* Type check */
     if (!IsClassInt (Op->Type) && !IsClassFloat (Op->Type)) {
 
-       /* Display diagnostic */
+       /* Output diagnostic */
        Error (ERR_SYNTAX);
 
        /* Free the errorneous node */
-       FreeExprNode (Op);
+       FreeExprTree (Op);
 
        /* Return something that makes sense later */
        return GetIntNode (0);
@@ -822,7 +822,7 @@ static ExprNode* DoComplement (void)
        Error (ERR_OP_NOT_ALLOWED);
 
        /* Free the errorneous node */
-       FreeExprNode (Op);
+       FreeExprTree (Op);
 
        /* Return something that makes sense later */
        return GetIntNode (0);
@@ -894,8 +894,8 @@ static ExprNode* DoAddress (void)
        /* Print diagnostics */
        Error (ERR_ILLEGAL_ADDRESS);
 
-       /* Free the problematic node */
-       FreeExprNode (Op);
+       /* Free the problematic tree */
+       FreeExprTree (Op);
 
        /* Return something that is safe later */
        Root = AllocExprNode (NT_CONST, PointerTo (type_void), 0);
@@ -928,8 +928,8 @@ static ExprNode* DoIndirect (void)
        /* Print diagnostics */
        Error (ERR_ILLEGAL_INDIRECT);
 
-       /* Free the problematic node */
-       FreeExprNode (Op);
+       /* Free the problematic tree */
+       FreeExprTree (Op);           
 
        /* Return something that is safe later ### */
        return GetIntNode (0);
@@ -980,7 +980,7 @@ static ExprNode* DoSizeOf (void)
                Size = SizeOf (N->Type);
 
                /* Free the node */
-               FreeExprNode (N);
+               FreeExprTree (N);
 
     }
 
@@ -1021,8 +1021,8 @@ static ExprNode* DoTypeCast (void)
 
     } else {
 
-       /* Must be casted. Setup the expression tree and return the new node */
-       Root = AllocExprNode (NT_BOOL_NOT, TargetType, RVALUE);
+       /* Must be casted. Setup the expression tree and return the new node */
+       Root = AllocExprNode (NT_BOOL_NOT, TargetType, RVALUE);
        SetLeftNode (Root, Op);
        return Root;
 
@@ -1049,7 +1049,7 @@ static ExprNode* UnaryExpr (void)
 
            case TOK_PLUS:
            case TOK_MINUS:
-               return DoUnaryPlusMinus ();
+                       return DoUnaryPlusMinus ();
 
            case TOK_COMP:
                return DoComplement ();
@@ -1066,18 +1066,57 @@ static ExprNode* UnaryExpr (void)
            case TOK_SIZEOF:
                return DoSizeOf ();
 
-           default:
-               /* Type cast */
-               return DoTypeCast ();
+           default:
+               /* Type cast */
+               return DoTypeCast ();
 
-       }
+       }
 
     } else {
 
-       /* Call the lower level */
-       return PostfixExpr ();
+       /* Call the lower level */
+       return PostfixExpr ();
+
+    }
+}
+
+
+
+static ExprNode* DoMul (ExprNode* Left)
+/* Handle multiplication */
+{
+    type      TargetType[MAXTYPELEN];
+    ExprNode* Right;
+    ExprNode* Root;
+
+    /* Check the type of the left operand */
+    if (!IsClassInt (Left->Type) && !IsClassFloat (Left->Type)) {
+       MError ("Invalid left operand to binary operator `*'");
+       FreeExprTree (Left);
+       Left = GetIntNode (0);
+    }
+
+    /* Skip the operator token */
+    NextToken ();
+
+    /* Read the right expression */
+    Right = UnaryExpr ();
 
+    /* Check the type of the right operand */
+    if (!IsClassInt (Right->Type) && !IsClassFloat (Right->Type)) {
+       MError ("Invalid right operand to binary operator `*'");
+       FreeExprTree (Right);
+       Right = GetIntNode (0);
     }
+
+    /* Do minor optimizations ### */
+
+    /* Make the root node */
+    Root = AllocExprNode (NT_BOOL_NOT, TargetType, RVALUE);
+    SetLeftNode (Root, Left);
+    SetRightNode (Root, Right);
+
+    return Root;
 }
 
 
@@ -1094,6 +1133,7 @@ static ExprNode* MultExpr (void)
        switch (CurTok.Tok) {
 
            case TOK_MUL:
+               Root = DoMul (Root);
                break;
 
            case TOK_DIV:
@@ -1262,8 +1302,8 @@ static ExprNode* AndExpr (void)
            Error (ERR_OP_NOT_ALLOWED);
 
            /* Remove the unneeded nodes */
-           FreeExprNode (Right);
-           FreeExprNode (Left);
+           FreeExprTree (Right);
+           FreeExprTree (Left);
 
            /* Create something safe */
            Root = GetIntNode (0);
@@ -1277,8 +1317,8 @@ static ExprNode* AndExpr (void)
                int Result = GetBoolRep (Left) & GetBoolRep (Right);
 
                /* Remove the unneeded nodes */
-               FreeExprNode (Right);
-               FreeExprNode (Left);
+               FreeExprTree (Right);
+               FreeExprTree (Left);
 
                /* Create a constant result */
                Root = GetIntNode (Result);
@@ -1325,8 +1365,8 @@ static ExprNode* XorExpr (void)
            Error (ERR_OP_NOT_ALLOWED);
 
            /* Remove the unneeded nodes */
-           FreeExprNode (Right);
-           FreeExprNode (Left);
+           FreeExprTree (Right);
+           FreeExprTree (Left);
 
            /* Create something safe */
            Root = GetIntNode (0);
@@ -1340,8 +1380,8 @@ static ExprNode* XorExpr (void)
                int Result = GetBoolRep (Left) ^ GetBoolRep (Right);
 
                /* Remove the unneeded nodes */
-               FreeExprNode (Right);
-               FreeExprNode (Left);
+               FreeExprTree (Right);
+               FreeExprTree (Left);
 
                /* Create a constant result */
                Root = GetIntNode (Result);
@@ -1388,8 +1428,8 @@ static ExprNode* OrExpr (void)
            Error (ERR_OP_NOT_ALLOWED);
 
            /* Remove the unneeded nodes */
-           FreeExprNode (Right);
-           FreeExprNode (Left);
+           FreeExprTree (Right);
+           FreeExprTree (Left);
 
            /* Create something safe */
            Root = GetIntNode (0);
@@ -1403,8 +1443,8 @@ static ExprNode* OrExpr (void)
                int Result = GetBoolRep (Left) | GetBoolRep (Right);
 
                /* Remove the unneeded nodes */
-               FreeExprNode (Right);
-               FreeExprNode (Left);
+               FreeExprTree (Right);
+               FreeExprTree (Left);
 
                /* Create a constant result */
                Root = GetIntNode (Result);
@@ -1451,8 +1491,8 @@ static ExprNode* BoolAndExpr (void)
            int Result = GetBoolRep (Left) && GetBoolRep (Right);
 
            /* Remove the unneeded nodes */
-           FreeExprNode (Right);
-           FreeExprNode (Left);
+           FreeExprTree (Right);
+           FreeExprTree (Left);
 
            /* Create a constant result */
            Root = GetIntNode (Result);
@@ -1499,8 +1539,8 @@ static ExprNode* BoolOrExpr (void)
            int Result = GetBoolRep (Left) && GetBoolRep (Right);
 
            /* Remove the unneeded nodes */
-           FreeExprNode (Right);
-           FreeExprNode (Left);
+           FreeExprTree (Right);
+           FreeExprTree (Left);
 
            /* Create a constant result */
            Root = GetIntNode (Result);