#include "asserts.h"
#include "condasm.h"
#include "dbginfo.h"
+#include "enum.h"
#include "error.h"
#include "expr.h"
#include "feature.h"
#include "pseudo.h"
#include "repeat.h"
#include "segment.h"
+#include "sizeof.h"
#include "spool.h"
+#include "struct.h"
+#include "symbol.h"
#include "symtab.h"
/* Keyword we're about to handle */
-static char Keyword [sizeof (SVal)+1] = ".";
+static char Keyword [sizeof (SVal)+1];
/* Segment stack */
#define MAX_PUSHED_SEGMENTS 16
static void DoEndProc (void)
/* Leave a lexical level */
{
- if (CurrentScope == RootScope || GetCurrentSymTabType () != ST_PROC) {
+ if (GetCurrentSymTabType () != ST_PROC) {
/* No local scope */
ErrorSkip ("No open .PROC");
} else {
static void DoEndScope (void)
/* Leave a lexical level */
{
- if (CurrentScope == RootScope || GetCurrentSymTabType () != ST_SCOPE) {
+ if ( GetCurrentSymTabType () != ST_SCOPE) {
/* No local scope */
ErrorSkip ("No open .SCOPE");
} else {
if (Tok == TOK_IDENT) {
+ SymEntry* Sym;
+
/* The new scope has a name. Remember it. */
strcpy (Name, SVal);
/* Search for the symbol, generate a new one if needed */
- SymEntry* Sym = SymFind (CurrentScope, Name, SYM_ALLOC_NEW);
+ Sym = SymFind (CurrentScope, Name, SYM_ALLOC_NEW);
/* Skip the scope name */
NextTok ();
-static void DoStruct (void)
-/* Struct definition */
-{
- Error ("Not implemented");
-}
-
-
-
static void DoSunPlus (void)
/* Switch to the SUNPLUS CPU */
{
-static void DoUnion (void)
-/* Union definition */
+static void DoTag (void)
+/* Allocate space for a struct */
{
- Error ("Not implemented");
+ SymEntry* SizeSym;
+ long Size;
+
+ /* Read the struct name */
+ SymTable* Struct = ParseScopedSymTable ();
+
+ /* Check the supposed struct */
+ if (Struct == 0) {
+ ErrorSkip ("Unknown struct");
+ return;
+ }
+ if (GetSymTabType (Struct) != ST_STRUCT) {
+ ErrorSkip ("Not a struct");
+ return;
+ }
+
+ /* Get the symbol that defines the size of the struct */
+ SizeSym = GetSizeOfScope (Struct);
+
+ /* Check if it does exist and if its value is known */
+ if (SizeSym == 0 || !SymIsConst (SizeSym, &Size)) {
+ ErrorSkip ("Size of struct/union is unknown");
+ return;
+ }
+
+ /* Optional multiplicator may follow */
+ if (Tok == TOK_COMMA) {
+ long Multiplicator;
+ NextTok ();
+ Multiplicator = ConstExpression ();
+ /* Multiplicator must make sense */
+ if (Multiplicator <= 0) {
+ ErrorSkip ("Range error");
+ return;
+ }
+ Size *= Multiplicator;
+ }
+
+ /* Emit fill fragments */
+ EmitFill (Size);
}
{ ccNone, DoASCIIZ },
{ ccNone, DoAssert },
{ ccNone, DoAutoImport },
+ { ccNone, DoUnexpected }, /* .BANKBYTE */
{ ccNone, DoUnexpected }, /* .BLANK */
{ ccNone, DoBss },
{ ccNone, DoByte },
{ ccKeepToken, DoConditionals }, /* .ELSE */
{ ccKeepToken, DoConditionals }, /* .ELSEIF */
{ ccKeepToken, DoEnd },
+ { ccNone, DoUnexpected }, /* .ENDENUM */
{ ccKeepToken, DoConditionals }, /* .ENDIF */
{ ccNone, DoUnexpected }, /* .ENDMACRO */
{ ccNone, DoEndProc },
{ ccNone, DoUnexpected }, /* .ENDREPEAT */
{ ccNone, DoEndScope },
{ ccNone, DoUnexpected }, /* .ENDSTRUCT */
+ { ccNone, DoUnexpected }, /* .ENDUNION */
+ { ccNone, DoEnum },
{ ccNone, DoError },
{ ccNone, DoExitMacro },
{ ccNone, DoExport },
{ ccNone, DoUnexpected }, /* .FORCEWORD */
{ ccNone, DoGlobal },
{ ccNone, DoGlobalZP },
+ { ccNone, DoUnexpected }, /* .HIBYTE */
+ { ccNone, DoUnexpected }, /* .HIWORD */
{ ccNone, DoI16 },
{ ccNone, DoI8 },
{ ccKeepToken, DoConditionals }, /* .IF */
{ ccNone, DoLineCont },
{ ccNone, DoList },
{ ccNone, DoListBytes },
+ { ccNone, DoUnexpected }, /* .LOBYTE */
{ ccNone, DoUnexpected }, /* .LOCAL */
{ ccNone, DoLocalChar },
+ { ccNone, DoUnexpected }, /* .LOWORD */
{ ccNone, DoMacPack },
{ ccNone, DoMacro },
{ ccNone, DoUnexpected }, /* .MATCH */
{ ccNone, DoScope },
{ ccNone, DoSegment },
{ ccNone, DoSetCPU },
+ { ccNone, DoUnexpected }, /* .SIZEOF */
{ ccNone, DoSmart },
{ ccNone, DoUnexpected }, /* .STRAT */
{ ccNone, DoUnexpected }, /* .STRING */
{ ccNone, DoUnexpected }, /* .STRLEN */
{ ccNone, DoStruct },
{ ccNone, DoSunPlus },
- { ccNone, DoUnexpected }, /* .TAG */
+ { ccNone, DoTag },
{ ccNone, DoUnexpected }, /* .TCOUNT */
{ ccNone, DoUnexpected }, /* .TIME */
{ ccNone, DoUnion },
-int TokIsPseudo (unsigned Tok)
-/* Return true if the given token is a pseudo instruction token */
-{
- return (Tok >= TOK_FIRSTPSEUDO && Tok <= TOK_LASTPSEUDO);
-}
-
-
-
void HandlePseudo (void)
/* Handle a pseudo instruction */
{
/* Remember the instruction, then skip it if needed */
if ((D->Flags & ccKeepToken) == 0) {
- strcpy (Keyword+1, SVal);
+ strcpy (Keyword, SVal);
NextTok ();
}