/* */
/* */
/* */
-/* (C) 1998-2011, Ullrich von Bassewitz */
+/* (C) 1998-2012, Ullrich von Bassewitz */
/* Roemerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
#include <string.h>
#include <ctype.h>
#include <errno.h>
-#include <sys/types.h> /* EMX needs this */
-#include <sys/stat.h>
/* common */
+#include "alignment.h"
#include "assertion.h"
#include "bitops.h"
#include "cddefs.h"
#include "coll.h"
+#include "filestat.h"
#include "gentype.h"
#include "intstack.h"
#include "scopedefs.h"
#include "incpath.h"
#include "instr.h"
#include "listing.h"
-#include "macpack.h"
#include "macro.h"
#include "nexttok.h"
#include "objcode.h"
+static StrBuf* GenArrayType (StrBuf* Type, unsigned SpanSize,
+ const char* ElementType,
+ unsigned ElementTypeLen)
+/* Create an array (or single data) of the given type. SpanSize is the size
+ * of the span, ElementType is a string that encodes the element data type.
+ * The function returns Type.
+ */
+{
+ /* Get the size of the element type */
+ unsigned ElementSize = GT_GET_SIZE (ElementType[0]);
+
+ /* Get the number of array elements */
+ unsigned ElementCount = SpanSize / ElementSize;
+
+ /* The span size must be divideable by the element size */
+ CHECK ((SpanSize % ElementSize) == 0);
+
+ /* Encode the array */
+ GT_AddArray (Type, ElementCount);
+ SB_AppendBuf (Type, ElementType, ElementTypeLen);
+
+ /* Return the pointer to the created array type */
+ return Type;
+}
+
+
+
/*****************************************************************************/
-/* Handler functions */
+/* Handler functions */
/*****************************************************************************/
static void DoAddr (void)
/* Define addresses */
{
+ /* Element type for the generated array */
+ static const char EType[2] = { GT_PTR, GT_VOID };
+
/* Record type information */
Span* S = OpenSpan ();
StrBuf Type = STATIC_STRBUF_INITIALIZER;
/* Parse arguments */
while (1) {
- if (GetCPU() == CPU_65816) {
- EmitWord (GenWordExpr (Expression ()));
- } else {
+ ExprNode* Expr = Expression ();
+ if (GetCPU () == CPU_65816 || ForceRange) {
/* Do a range check */
- EmitWord (Expression ());
- }
+ Expr = GenWordExpr (Expr);
+ }
+ EmitWord (Expr);
if (CurTok.Tok != TOK_COMMA) {
break;
} else {
/* Close the span, then add type information to it */
S = CloseSpan (S);
- GT_AddArray (&Type, GetSpanSize (S));
- SB_AppendChar (&Type, GT_PTR);
- SetSpanType (S, &Type);
+ SetSpanType (S, GenArrayType (&Type, GetSpanSize (S), EType, sizeof (EType)));
- /* Free the type string */
+ /* Free the strings */
SB_Done (&Type);
}
static void DoAlign (void)
/* Align the PC to some boundary */
{
- long Val;
- long Align;
- unsigned Bit;
+ long FillVal;
+ long Alignment;
/* Read the alignment value */
- Align = ConstExpression ();
- if (Align <= 0 || Align > 0x10000) {
- ErrorSkip ("Range error");
- return;
+ Alignment = ConstExpression ();
+ if (Alignment <= 0 || (unsigned long) Alignment > MAX_ALIGNMENT) {
+ ErrorSkip ("Range error");
+ return;
}
/* Optional value follows */
if (CurTok.Tok == TOK_COMMA) {
- NextTok ();
- Val = ConstExpression ();
- /* We need a byte value here */
- if (!IsByteRange (Val)) {
- ErrorSkip ("Range error");
- return;
- }
+ NextTok ();
+ FillVal = ConstExpression ();
+ /* We need a byte value here */
+ if (!IsByteRange (FillVal)) {
+ ErrorSkip ("Range error");
+ return;
+ }
} else {
- Val = -1;
+ FillVal = -1;
}
- /* Check if the alignment is a power of two */
- Bit = BitFind (Align);
- if (Align != (0x01L << Bit)) {
- Error ("Alignment value must be a power of 2");
- } else {
- SegAlign (Bit, (int) Val);
- }
+ /* Generate the alignment */
+ SegAlign (Alignment, (int) FillVal);
}
static void DoByte (void)
/* Define bytes */
{
+ /* Element type for the generated array */
+ static const char EType[1] = { GT_BYTE };
+
/* Record type information */
Span* S = OpenSpan ();
StrBuf Type = STATIC_STRBUF_INITIALIZER;
EmitStrBuf (&CurTok.SVal);
NextTok ();
} else {
- EmitByte (Expression ());
+ EmitByte (BoundedExpr (Expression, 1));
}
if (CurTok.Tok != TOK_COMMA) {
break;
/* Do smart handling of dangling comma */
if (CurTok.Tok == TOK_SEP) {
Error ("Unexpected end of line");
- break;
+ break;
}
}
}
/* Close the span, then add type information to it */
S = CloseSpan (S);
- GT_AddArray (&Type, GetSpanSize (S));
- SB_AppendChar (&Type, GT_BYTE);
- SetSpanType (S, &Type);
+ SetSpanType (S, GenArrayType (&Type, GetSpanSize (S), EType, sizeof (EType)));
/* Free the type string */
SB_Done (&Type);
/* Read the index as numerical value */
Index = ConstExpression ();
- if (Index < 0 || Index > 255) {
+ if (Index <= 0 || Index > 255) {
/* Value out of range */
ErrorSkip ("Range error");
return;
{
static const char* Keys[] = {
"FILE",
+ "FUNC",
"LINE",
"SYM",
};
/* Check the key and dispatch to a handler */
switch (Key) {
case 0: DbgInfoFile (); break;
- case 1: DbgInfoLine (); break;
- case 2: DbgInfoSym (); break;
+ case 1: DbgInfoFunc (); break;
+ case 2: DbgInfoLine (); break;
+ case 3: DbgInfoSym (); break;
default: ErrorSkip ("Syntax error"); break;
}
}
static void DoDByt (void)
/* Output double bytes */
{
+ /* Element type for the generated array */
+ static const char EType[1] = { GT_DBYTE };
+
/* Record type information */
Span* S = OpenSpan ();
StrBuf Type = STATIC_STRBUF_INITIALIZER;
/* Parse arguments */
while (1) {
- EmitWord (GenSwapExpr (Expression ()));
+ EmitWord (GenSwapExpr (BoundedExpr (Expression, 2)));
if (CurTok.Tok != TOK_COMMA) {
break;
} else {
/* Close the span, then add type information to it */
S = CloseSpan (S);
- GT_AddArray (&Type, GetSpanSize (S));
- SB_AppendChar (&Type, GT_DBYTE);
- SetSpanType (S, &Type);
+ SetSpanType (S, GenArrayType (&Type, GetSpanSize (S), EType, sizeof (EType)));
/* Free the type string */
SB_Done (&Type);
/* Define dwords */
{
while (1) {
- EmitDWord (Expression ());
+ EmitDWord (BoundedExpr (Expression, 4));
if (CurTok.Tok != TOK_COMMA) {
break;
} else {
static void DoFarAddr (void)
/* Define far addresses (24 bit) */
{
+ /* Element type for the generated array */
+ static const char EType[2] = { GT_FAR_PTR, GT_VOID };
+
/* Record type information */
Span* S = OpenSpan ();
StrBuf Type = STATIC_STRBUF_INITIALIZER;
/* Parse arguments */
while (1) {
- EmitFarAddr (Expression ());
+ EmitFarAddr (BoundedExpr (Expression, 3));
if (CurTok.Tok != TOK_COMMA) {
break;
} else {
/* Close the span, then add type information to it */
S = CloseSpan (S);
- GT_AddArray (&Type, GetSpanSize (S));
- SB_AppendChar (&Type, GT_FAR_PTR);
- SetSpanType (S, &Type);
+ SetSpanType (S, GenArrayType (&Type, GetSpanSize (S), EType, sizeof (EType)));
/* Free the type string */
SB_Done (&Type);
* here.
*/
SB_Terminate (&Name);
- if (stat (SB_GetConstBuf (&Name), &StatBuf) != 0) {
+ if (FileStat (SB_GetConstBuf (&Name), &StatBuf) != 0) {
Fatal ("Cannot stat input file `%m%p': %s", &Name, strerror (errno));
}
static void DoMacPack (void)
/* Insert a macro package */
{
- int Package;
-
/* We expect an identifier */
if (CurTok.Tok != TOK_IDENT) {
ErrorSkip ("Identifier expected");
- return;
- }
-
- /* Search for the macro package name */
- LocaseSVal ();
- Package = MacPackFind (&CurTok.SVal);
- if (Package < 0) {
- /* Not found */
- ErrorSkip ("Invalid macro package");
- return;
- }
-
- /* Insert the package. If this fails, skip the remainder of the line to
- * avoid additional error messages.
- */
- if (MacPackInsert (Package) == 0) {
- SkipUntilSep ();
+ } else {
+ SB_AppendStr (&CurTok.SVal, ".mac");
+ SB_Terminate (&CurTok.SVal);
+ if (NewInputFile (SB_GetConstBuf (&CurTok.SVal)) == 0) {
+ /* Error opening the file, skip remainder of line */
+ SkipUntilSep ();
+ }
}
}
static void DoWord (void)
/* Define words */
{
+ /* Element type for the generated array */
+ static const char EType[1] = { GT_WORD };
+
/* Record type information */
Span* S = OpenSpan ();
StrBuf Type = STATIC_STRBUF_INITIALIZER;
/* Parse arguments */
while (1) {
- EmitWord (Expression ());
+ EmitWord (BoundedExpr (Expression, 2));
if (CurTok.Tok != TOK_COMMA) {
break;
} else {
/* Close the span, then add type information to it */
S = CloseSpan (S);
- GT_AddArray (&Type, GetSpanSize (S));
- SB_AppendChar (&Type, GT_WORD);
- SetSpanType (S, &Type);
+ SetSpanType (S, GenArrayType (&Type, GetSpanSize (S), EType, sizeof (EType)));
/* Free the type string */
SB_Done (&Type);
/* Control commands flags */
enum {
- ccNone = 0x0000, /* No special flags */
- ccKeepToken = 0x0001 /* Do not skip the current token */
+ ccNone = 0x0000, /* No special flags */
+ ccKeepToken = 0x0001 /* Do not skip the current token */
};
/* Control command table */
typedef struct CtrlDesc CtrlDesc;
struct CtrlDesc {
- unsigned Flags; /* Flags for this directive */
+ unsigned Flags; /* Flags for this directive */
void (*Handler) (void); /* Command handler */
};
{ ccNone, DoASCIIZ },
{ ccNone, DoAssert },
{ ccNone, DoAutoImport },
+ { ccNone, DoUnexpected }, /* .BANK */
{ ccNone, DoUnexpected }, /* .BANKBYTE */
{ ccNone, DoBankBytes },
{ ccNone, DoUnexpected }, /* .BLANK */