/* expr.c
**
** 1998-06-21, Ullrich von Bassewitz
-** 2015-06-26, Greg King
+** 2017-12-05, Greg King
*/
/* Special handling for function pointers */
if (IsFuncPtr) {
+ if (Func->WrappedCall) {
+ Warning ("Calling a wrapped function via a pointer, wrapped-call will not be used");
+ }
+
/* If the function is not a fastcall function, load the pointer to
** the function into the primary.
*/
} else {
/* Normal function */
- g_call (TypeOf (Expr->Type), (const char*) Expr->Name, ParamSize);
+ if (Func->WrappedCall) {
+ char tmp[64];
+ StrBuf S = AUTO_STRBUF_INITIALIZER;
+
+ /* Store the WrappedCall data in tmp4 */
+ sprintf(tmp, "ldy #%u", Func->WrappedCallData);
+ SB_AppendStr (&S, tmp);
+ g_asmcode (&S);
+ SB_Clear(&S);
+
+ SB_AppendStr (&S, "sty tmp4");
+ g_asmcode (&S);
+ SB_Clear(&S);
+
+ /* Store the original function address in ptr4 */
+ SB_AppendStr (&S, "ldy #<(_");
+ SB_AppendStr (&S, (const char*) Expr->Name);
+ SB_AppendChar (&S, ')');
+ g_asmcode (&S);
+ SB_Clear(&S);
+
+ SB_AppendStr (&S, "sty ptr4");
+ g_asmcode (&S);
+ SB_Clear(&S);
+
+ SB_AppendStr (&S, "ldy #>(_");
+ SB_AppendStr (&S, (const char*) Expr->Name);
+ SB_AppendChar (&S, ')');
+ g_asmcode (&S);
+ SB_Clear(&S);
+
+ SB_AppendStr (&S, "sty ptr4+1");
+ g_asmcode (&S);
+ SB_Clear(&S);
+
+ SB_Done (&S);
+
+ g_call (TypeOf (Expr->Type), Func->WrappedCall->Name, ParamSize);
+ } else {
+ g_call (TypeOf (Expr->Type), (const char*) Expr->Name, ParamSize);
+ }
}
switch (CurTok.Tok) {
+ case TOK_BOOL_AND:
+ /* A computed goto label address */
+ if (IS_Get (&Standard) >= STD_CC65) {
+ NextToken ();
+ SymEntry* Entry = AddLabelSym (CurTok.Ident, SC_REF | SC_GOTO_IND);
+ /* output its label */
+ E->Flags = E_RTYPE_RVAL | E_LOC_STATIC;
+ E->Name = Entry->V.L.Label;
+ E->Type = PointerTo(type_void);
+ NextToken ();
+ } else {
+ Error ("Computed gotos are a C extension, not supported with this --standard");
+ ED_MakeConstAbsInt (E, 1);
+ }
+ break;
+
case TOK_IDENT:
/* Identifier. Get a pointer to the symbol table entry */
Sym = E->Sym = FindSym (CurTok.Ident);
} else if ((Sym->Flags & SC_FUNC) == SC_FUNC) {
/* Function */
E->Flags = E_LOC_GLOBAL | E_RTYPE_LVAL;
- E->Name = (unsigned long) Sym->Name;
+ E->Name = (uintptr_t) Sym->Name;
} else if ((Sym->Flags & SC_AUTO) == SC_AUTO) {
/* Local variable. If this is a parameter for a variadic
** function, we have to add some address calculations, and the
/* Static variable */
if (Sym->Flags & (SC_EXTERN | SC_STORAGE)) {
E->Flags = E_LOC_GLOBAL | E_RTYPE_LVAL;
- E->Name = (unsigned long) Sym->Name;
+ E->Name = (uintptr_t) Sym->Name;
} else {
E->Flags = E_LOC_STATIC | E_RTYPE_LVAL;
- E->Name = Sym->V.Label;
+ E->Name = Sym->V.L.Label;
}
} else {
/* Local static variable */
** list and returning int.
*/
if (IS_Get (&Standard) >= STD_C99) {
- Error ("Call to undefined function `%s'", Ident);
+ Error ("Call to undefined function '%s'", Ident);
} else {
- Warning ("Call to undefined function `%s'", Ident);
+ Warning ("Call to undefined function '%s'", Ident);
}
Sym = AddGlobalSym (Ident, GetImplicitFuncType(), SC_EXTERN | SC_REF | SC_FUNC);
E->Type = Sym->Type;
E->Flags = E_LOC_GLOBAL | E_RTYPE_RVAL;
- E->Name = (unsigned long) Sym->Name;
+ E->Name = (uintptr_t) Sym->Name;
} else {
/* Undeclared Variable */
Sym = AddLocalSym (Ident, type_int, SC_AUTO | SC_REF, 0);
E->Flags = E_LOC_STACK | E_RTYPE_LVAL;
E->Type = type_int;
- Error ("Undefined symbol: `%s'", Ident);
+ Error ("Undefined symbol: '%s'", Ident);
}
}
NextToken ();
Field = FindStructField (Expr->Type, Ident);
if (Field == 0) {
- Error ("Struct/union has no field named `%s'", Ident);
+ Error ("Struct/union has no field named '%s'", Ident);
/* Make the expression an integer at address zero */
ED_MakeConstAbs (Expr, 0, type_int);
return;
** Since we don't have a name, invent one.
*/
ED_MakeConstAbs (Expr, 0, GetImplicitFuncType ());
- Expr->Name = (long) IllegalFunc;
+ Expr->Name = (uintptr_t) IllegalFunc;
}
/* Call the function */
FunctionCall (Expr);
/* Get the data type */
Flags = TypeOf (Expr->Type);
- /* Push the address if needed */
- PushAddr (Expr);
+ /* Emit smaller code if a char variable is at a constant location */
+ if ((Flags & CF_CHAR) == CF_CHAR && ED_IsLocConst(Expr)) {
- /* Fetch the value and save it (since it's the result of the expression) */
- LoadExpr (CF_NONE, Expr);
- g_save (Flags | CF_FORCECHAR);
+ LoadExpr (CF_NONE, Expr);
+ AddCodeLine ("inc %s", ED_GetLabelName(Expr, 0));
- /* If we have a pointer expression, increment by the size of the type */
- if (IsTypePtr (Expr->Type)) {
- g_inc (Flags | CF_CONST | CF_FORCECHAR, CheckedSizeOf (Expr->Type + 1));
} else {
- g_inc (Flags | CF_CONST | CF_FORCECHAR, 1);
- }
- /* Store the result back */
- Store (Expr, 0);
+ /* Push the address if needed */
+ PushAddr (Expr);
+
+ /* Fetch the value and save it (since it's the result of the expression) */
+ LoadExpr (CF_NONE, Expr);
+ g_save (Flags | CF_FORCECHAR);
- /* Restore the original value in the primary register */
- g_restore (Flags | CF_FORCECHAR);
+ /* If we have a pointer expression, increment by the size of the type */
+ if (IsTypePtr (Expr->Type)) {
+ g_inc (Flags | CF_CONST | CF_FORCECHAR, CheckedSizeOf (Expr->Type + 1));
+ } else {
+ g_inc (Flags | CF_CONST | CF_FORCECHAR, 1);
+ }
+
+ /* Store the result back */
+ Store (Expr, 0);
+
+ /* Restore the original value in the primary register */
+ g_restore (Flags | CF_FORCECHAR);
+ }
/* The result is always an expression, no reference */
ED_MakeRValExpr (Expr);
/* Get the data type */
Flags = TypeOf (Expr->Type);
- /* Push the address if needed */
- PushAddr (Expr);
+ /* Emit smaller code if a char variable is at a constant location */
+ if ((Flags & CF_CHAR) == CF_CHAR && ED_IsLocConst(Expr)) {
- /* Fetch the value and save it (since it's the result of the expression) */
- LoadExpr (CF_NONE, Expr);
- g_save (Flags | CF_FORCECHAR);
+ LoadExpr (CF_NONE, Expr);
+ AddCodeLine ("dec %s", ED_GetLabelName(Expr, 0));
- /* If we have a pointer expression, increment by the size of the type */
- if (IsTypePtr (Expr->Type)) {
- g_dec (Flags | CF_CONST | CF_FORCECHAR, CheckedSizeOf (Expr->Type + 1));
} else {
- g_dec (Flags | CF_CONST | CF_FORCECHAR, 1);
- }
- /* Store the result back */
- Store (Expr, 0);
+ /* Push the address if needed */
+ PushAddr (Expr);
+
+ /* Fetch the value and save it (since it's the result of the expression) */
+ LoadExpr (CF_NONE, Expr);
+ g_save (Flags | CF_FORCECHAR);
+
+ /* If we have a pointer expression, increment by the size of the type */
+ if (IsTypePtr (Expr->Type)) {
+ g_dec (Flags | CF_CONST | CF_FORCECHAR, CheckedSizeOf (Expr->Type + 1));
+ } else {
+ g_dec (Flags | CF_CONST | CF_FORCECHAR, 1);
+ }
- /* Restore the original value in the primary register */
- g_restore (Flags | CF_FORCECHAR);
+ /* Store the result back */
+ Store (Expr, 0);
+
+ /* Restore the original value in the primary register */
+ g_restore (Flags | CF_FORCECHAR);
+ }
/* The result is always an expression, no reference */
ED_MakeRValExpr (Expr);
typeadjust (Expr, &Expr2, 1);
} else {
/* OOPS */
- Error ("Invalid operands for binary operator `+'");
+ Error ("Invalid operands for binary operator '+'");
}
} else {
}
} else {
/* OOPS */
- Error ("Invalid operands for binary operator `+'");
+ Error ("Invalid operands for binary operator '+'");
flags = CF_INT;
}
flags = typeadjust (Expr, &Expr2, 1);
} else {
/* OOPS */
- Error ("Invalid operands for binary operator `+'");
+ Error ("Invalid operands for binary operator '+'");
flags = CF_INT;
}
flags = typeadjust (Expr, &Expr2, 0) & ~CF_CONST;
} else {
/* OOPS */
- Error ("Invalid operands for binary operator `+'");
+ Error ("Invalid operands for binary operator '+'");
flags = CF_INT;
}
/* lhs cannot be function or pointer to function */
if (IsTypeFunc (Expr->Type) || IsTypeFuncPtr (Expr->Type)) {
- Error ("Invalid left operand for binary operator `-'");
+ Error ("Invalid left operand for binary operator '-'");
/* Make it pointer to char to avoid further errors */
Expr->Type = type_uchar;
}
/* rhs cannot be function or pointer to function */
if (IsTypeFunc (Expr2.Type) || IsTypeFuncPtr (Expr2.Type)) {
- Error ("Invalid right operand for binary operator `-'");
+ Error ("Invalid right operand for binary operator '-'");
/* Make it pointer to char to avoid further errors */
Expr2.Type = type_uchar;
}
Expr->IVal -= Expr2.IVal;
} else {
/* OOPS */
- Error ("Invalid operands for binary operator `-'");
+ Error ("Invalid operands for binary operator '-'");
}
/* Result is constant, condition codes not set */
flags = typeadjust (Expr, &Expr2, 1);
} else {
/* OOPS */
- Error ("Invalid operands for binary operator `-'");
+ Error ("Invalid operands for binary operator '-'");
flags = CF_INT;
}
flags = typeadjust (Expr, &Expr2, 0);
} else {
/* OOPS */
- Error ("Invalid operands for binary operator `-'");
+ Error ("Invalid operands for binary operator '-'");
flags = CF_INT;
}
/* The rhs must be an integer (or a float, but we don't support that yet */
if (!IsClassInt (Expr2.Type)) {
- Error ("Invalid right operand for binary operator `%s'", Op);
+ Error ("Invalid right operand for binary operator '%s'", Op);
/* Continue. Wrong code will be generated, but the compiler won't
** break, so this is the best error recovery.
*/
*/
hie1 (&Expr2);
if (!IsClassInt (Expr2.Type)) {
- Error ("Invalid right operand for binary operator `%s'", Op);
+ Error ("Invalid right operand for binary operator '%s'", Op);
/* Continue. Wrong code will be generated, but the compiler won't
** break, so this is the best error recovery.
*/