1
0
mirror of https://github.com/cc65/cc65.git synced 2024-12-27 15:29:46 +00:00

Working on the new parser.

git-svn-id: svn://svn.cc65.org/cc65/trunk@368 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
cuz 2000-10-15 19:51:39 +00:00
parent 669d063e75
commit 5cf9e0af18
5 changed files with 432 additions and 41 deletions

View 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);
}

View 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 */

View File

@ -33,6 +33,11 @@
/* 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;
}
}
}

View 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,6 +227,12 @@ 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 */
@ -232,5 +241,3 @@ void SetNodeSym (ExprNode* N, struct SymEntry* Sym);

View 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,22 +1066,61 @@ 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;
}
static ExprNode* MultExpr (void)
/* Handle multiplicative expressions: '*' '/' and '%' */
{
@ -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);