/* */
/* */
/* */
-/* (C) 2000 Ullrich von Bassewitz */
+/* (C) 2000-2001 Ullrich von Bassewitz */
/* Wacholderweg 14 */
/* D-70597 Stuttgart */
/* EMail: uz@musoftware.de */
static int IsTypeExpr (void)
-/* Return true if some sort of variable or type is waiting (helper for cast
- * and sizeof() in hie10).
- */
+/* Return true if some sort of variable or type is waiting */
{
SymEntry* Entry;
/*****************************************************************************/
-/* Code */
+/* Code */
/*****************************************************************************/
if (CurTok.Tok != TOK_SCONST) {
/* Print an error */
- Error (ERR_STRLIT_EXPECTED);
+ Error ("String literal expected");
/* To be on the safe side later, insert an empty asm string */
AppendItem (N, xstrdup (""));
* 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 (CurTok.IVal);
+ ResetLiteralPoolOffs (CurTok.IVal);
}
/* Skip the string token */
*/
if (Preprocessing) {
/* Illegal expression in PP mode */
- Error (ERR_CPP_EXPR_EXPECTED);
+ Error ("Preprocessor expression expected");
/* Skip the token for error recovery */
NextToken ();
/* Check for illegal symbol types */
if ((Sym->Flags & SC_LABEL) == SC_LABEL) {
/* Cannot use labels in expressions */
- Error (ERR_SYMBOL_KIND);
+ Error ("Cannot use a label in an expression");
return GetIntNode (0);
} else if (Sym->Flags & SC_TYPE) {
/* Cannot use type symbols */
- Error (ERR_VAR_IDENT_EXPECTED);
+ Error ("Cannot use a type in an expression");
/* Assume an int type to make lval valid */
return GetIntNode (0);
}
- /* Handle enum values as constant integers */
- if ((Sym->Flags & SC_ENUM) == SC_ENUM) {
+ /* Handle constants including enum values */
+ if ((Sym->Flags & SC_CONST) == SC_CONST) {
- N = GetIntNode (Sym->V.EnumVal);
+ N = AllocExprNode (NT_CONST, Sym->Type, RVALUE);
+ N->IVal = Sym->V.ConstVal;
} else {
if (CurTok.Tok == TOK_LPAREN) {
/* Warn about the use of a function without prototype */
- Warning (WARN_FUNC_WITHOUT_PROTO);
+ Warning ("Function call without a prototype");
/* Declare a function returning int. For that purpose, prepare
* a function signature for a function having an empty param
} else {
/* Print an error about an undeclared variable */
- Error (ERR_UNDEFINED_SYMBOL, Ident);
+ Error ("Undefined symbiol: `%s'", Ident);
/* Undeclared Variable */
Sym = AddLocalSym (Ident, type_int, SC_AUTO | SC_REF, 0);
} else {
/* Illegal primary. */
- Error (ERR_EXPR_EXPECTED);
+ Error ("Expression expected");
N = GetIntNode (0);
}
Right = Expression ();
/* Check the types. As special "C" feature, accept a reversal of base and
- * index types:
- * char C = 3["abcdefg"];
- * is legal C!
+ * 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);
+ Error ("Invalid subscript");
/* To avoid problems later, create a new, legal subscript
* expression
*/
ExprNode* Tmp;
/* Left side must be some sort of integer */
- if (!IsClassInt (Right->Type)) {
+ if (!IsClassInt (Left->Type)) {
/* Print an error */
- Error (ERR_CANNOT_SUBSCRIPT);
+ Error ("Invalid subscript");
/* To avoid problems later, create a new, legal subscript
* expression
*/
/* Invalid array expression. Skip the closing bracket, then return
* an integer instead of the array expression to be safe later.
*/
- Error (ERR_CANNOT_SUBSCRIPT);
+ Error ("Invalid subscript");
ConsumeRBrack ();
return GetIntNode (0);
}
if (CurTok.Tok == TOK_PTR_REF) {
NT = NT_STRUCTPTR_ACCESS;
if (!IsTypePtr (StructType)) {
- Error (ERR_STRUCT_PTR_EXPECTED);
+ Error ("Struct pointer expected");
return GetIntNode (0);
}
StructType = Indirect (StructType);
NT = NT_STRUCT_ACCESS;
}
if (!IsClassStruct (StructType)) {
- Error (ERR_STRUCT_EXPECTED);
+ Error ("Struct expected");
return GetIntNode (0);
}
NextToken ();
if (CurTok.Tok != TOK_IDENT) {
/* Print an error */
- Error (ERR_IDENT_EXPECTED);
+ Error ("Identifier expected");
/* Return an integer expression instead */
return GetIntNode (0);
}
Field = FindStructField (StructType, Ident);
if (Field == 0) {
/* Struct field not found */
- Error (ERR_STRUCT_FIELD_MISMATCH, Ident);
+ Error ("Struct/union has no field named `%s'", Ident);
/* Return an integer expression instead */
return GetIntNode (0);
}
if (!IsTypeFunc (Left->Type) && !IsTypeFuncPtr (Left->Type)) {
/* Call to non function */
- Error (ERR_ILLEGAL_FUNC_CALL);
+ Error ("Illegal function call");
- /* Free the old node */
- FreeExprNode (Left);
+ /* Free the old tree */
+ FreeExprTree (Left);
/* Return something safe */
return GetIntNode (0);
}
} else if (!Ellipsis) {
/* Too many arguments. Do we have an open param list? */
- if ((Func->Flags & FD_ELLIPSIS) == 0) {
+ if ((Func->Flags & FD_VARIADIC) == 0) {
/* End of param list reached, no ellipsis */
- Error (ERR_TOO_MANY_FUNC_ARGS);
+ Error ("Too many function arguments");
}
/* Assume an ellipsis even in case of errors to avoid an error
* message for each other argument.
/* Check if we had enough parameters */
if (ParamCount < Func->ParamCount) {
- Error (ERR_TOO_FEW_FUNC_ARGS);
+ Error ("Too few function arguments");
}
/* Return the function call node */
if (Left->LValue == 0) {
/* Print a diagnostics */
- Error (ERR_LVALUE_EXPECTED);
+ Error ("lvalue expected");
/* It is safe to return the operand expression and probably better
* than returning an int, since the operand expression already has
static ExprNode* PostfixExpr (void)
+/* Handle a postfix expression */
{
/* Get the lower level expression */
ExprNode* Root = Primary ();
if (Op->LValue == 0) {
/* Print a diagnostics */
- Error (ERR_LVALUE_EXPECTED);
+ Error ("lvalue expected");
/* It is safe to return the operand expression and probably better
* than returning an int, since the operand expression already has
/* Type check */
if (!IsClassInt (Op->Type) && !IsClassFloat (Op->Type)) {
- /* Display diagnostic */
- Error (ERR_SYNTAX);
+ /* Output diagnostic */
+ Error ("Syntax error");
/* Free the errorneous node */
- FreeExprNode (Op);
+ FreeExprTree (Op);
/* Return something that makes sense later */
return GetIntNode (0);
if (!IsClassInt (Op->Type)) {
/* Display diagnostic */
- Error (ERR_OP_NOT_ALLOWED);
+ Error ("Operation not allowed on this type");
/* Free the errorneous node */
- FreeExprNode (Op);
+ FreeExprTree (Op);
/* Return something that makes sense later */
return GetIntNode (0);
ExprNode* Root;
/* Print diagnostics */
- Error (ERR_ILLEGAL_ADDRESS);
+ Error ("Cannot take address of rvalue");
- /* 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);
static ExprNode* DoIndirect (void)
-/* Handle the indirection operaror * */
+/* Handle the indirection operator * */
{
ExprNode* Op;
type* ResultType;
if (!IsClassPtr (Op->Type)) {
/* Print diagnostics */
- Error (ERR_ILLEGAL_INDIRECT);
+ Error ("Illegal indirection");
- /* Free the problematic node */
- FreeExprNode (Op);
+ /* Free the problematic tree */
+ FreeExprTree (Op);
/* Return something that is safe later ### */
return GetIntNode (0);
Size = SizeOf (N->Type);
/* Free the node */
- FreeExprNode (N);
+ FreeExprTree (N);
}
} 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_TYPECAST, TargetType, RVALUE);
SetLeftNode (Root, Op);
return Root;
case TOK_PLUS:
case TOK_MINUS:
- return DoUnaryPlusMinus ();
+ return DoUnaryPlusMinus ();
case TOK_COMP:
return DoComplement ();
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)) {
+ Error ("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)) {
+ Error ("Invalid right operand to binary operator `*'");
+ FreeExprTree (Right);
+ Right = GetIntNode (0);
}
+
+ /* Make the root node */
+ Root = AllocExprNode (NT_BOOL_NOT, TargetType, RVALUE);
+ SetLeftNode (Root, Left);
+ SetRightNode (Root, Right);
+
+ return Root;
}
switch (CurTok.Tok) {
case TOK_MUL:
+ Root = DoMul (Root);
break;
case TOK_DIV:
if (!IsClassInt (Left->Type) || !IsClassInt (Right->Type)) {
/* Print a diagnostic */
- Error (ERR_OP_NOT_ALLOWED);
+ Error ("Operation not allowed for these types");
/* Remove the unneeded nodes */
- FreeExprNode (Right);
- FreeExprNode (Left);
+ FreeExprTree (Right);
+ FreeExprTree (Left);
/* Create something safe */
Root = GetIntNode (0);
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);
if (!IsClassInt (Left->Type) || !IsClassInt (Right->Type)) {
/* Print a diagnostic */
- Error (ERR_OP_NOT_ALLOWED);
+ Error ("Operation not allowed for these types");
/* Remove the unneeded nodes */
- FreeExprNode (Right);
- FreeExprNode (Left);
+ FreeExprTree (Right);
+ FreeExprTree (Left);
/* Create something safe */
Root = GetIntNode (0);
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);
if (!IsClassInt (Left->Type) || !IsClassInt (Right->Type)) {
/* Print a diagnostic */
- Error (ERR_OP_NOT_ALLOWED);
+ Error ("Operation not allowed for these types");
/* Remove the unneeded nodes */
- FreeExprNode (Right);
- FreeExprNode (Left);
+ FreeExprTree (Right);
+ FreeExprTree (Left);
/* Create something safe */
Root = GetIntNode (0);
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);
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);
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);
-