/* */
/* */
/* */
-/* (C) 1998-2000 Ullrich von Bassewitz */
+/* (C) 1998-2003 Ullrich von Bassewitz */
/* Wacholderweg 14 */
/* D-70597 Stuttgart */
/* EMail: uz@musoftware.de */
+#include <string.h>
+#include <time.h>
+
/* common */
#include "check.h"
#include "exprdefs.h"
+#include "print.h"
#include "tgttrans.h"
#include "xmalloc.h"
} else {
/* Skip any tokens */
int Braces = 0;
- while (Tok != TOK_SEP && Tok != TOK_EOF) {
+ while (!TokIsSep (Tok)) {
if (Tok == TOK_LPAREN) {
++Braces;
} else if (Tok == TOK_RPAREN) {
static int FuncDefined (void)
/* Handle the .DEFINED builtin function */
{
+ static const char* Keys[] = {
+ "ANY",
+ "GLOBAL",
+ "LOCAL",
+ };
+
+ char Name [sizeof (SVal)];
int Result = 0;
+ int Scope;
+ /* First argument is a symbol name */
if (Tok != TOK_IDENT) {
Error (ERR_IDENT_EXPECTED);
if (Tok != TOK_RPAREN) {
NextTok ();
}
+ return 0;
+ }
+
+ /* Remember the name, then skip it */
+ strcpy (Name, SVal);
+ NextTok ();
+
+ /* Comma and scope spec may follow */
+ if (Tok == TOK_COMMA) {
+
+ /* Skip the comma */
+ NextTok ();
+
+ /* An identifier must follow */
+ if (Tok != TOK_IDENT) {
+ Error (ERR_IDENT_EXPECTED);
+ return 0;
+ }
+
+ /* Get the scope, then skip it */
+ Scope = GetSubKey (Keys, sizeof (Keys) / sizeof (Keys [0]));
+ NextTok ();
+
+ /* Check if we got a valid keyword */
+ if (Scope < 0) {
+ Error (ERR_ILLEGAL_SCOPE);
+ return 0;
+ }
+
+ /* Map the scope */
+ switch (Scope) {
+ case 0: Scope = SCOPE_ANY; break;
+ case 1: Scope = SCOPE_GLOBAL; break;
+ case 2: Scope = SCOPE_LOCAL; break;
+ default: Internal ("Invalid scope: %d", Scope);
+ }
+
} else {
- Result = SymIsDef (SVal);
- NextTok ();
+
+ /* Any scope */
+ Scope = SCOPE_ANY;
+
}
+ /* Search for the symbol */
+ Result = SymIsDef (SVal, Scope);
+
/* Done */
return Result;
}
while (Tok != TOK_COMMA) {
/* We may not end-of-line of end-of-file here */
- if (Tok == TOK_SEP || Tok == TOK_EOF) {
+ if (TokIsSep (Tok)) {
Error (ERR_UNEXPECTED_EOL);
return 0;
}
while (Tok != TOK_RPAREN) {
/* We may not end-of-line of end-of-file here */
- if (Tok == TOK_SEP || Tok == TOK_EOF) {
+ if (TokIsSep (Tok)) {
Error (ERR_UNEXPECTED_EOL);
return 0;
}
NextTok ();
}
} else {
- Result = SymIsRef (SVal);
+ Result = SymIsRef (SVal, SCOPE_ANY);
NextTok ();
}
Index = ConstExpression ();
/* Must be a valid index */
- if (Index >= strlen (Str)) {
+ if (Index >= (long) strlen (Str)) {
Error (ERR_RANGE);
return 0;
}
- /* Return the char, handle as unsigned */
- return (unsigned char) Str[(size_t)Index];
+ /* Return the char, handle as unsigned. Be sure to translate it into
+ * the target character set.
+ */
+ return (unsigned char) TgtTranslateChar (Str [(size_t)Index]);
}
* will check for the closing paren, we don't need to print an error
* here, just bail out.
*/
- if (Tok == TOK_SEP || Tok == TOK_EOF) {
+ if (TokIsSep (Tok)) {
break;
}
Error (ERR_IDENT_EXPECTED);
N = LiteralExpr (0); /* Dummy */
} else {
- S = SymRefGlobal (SVal);
+ S = SymRef (SVal, SCOPE_GLOBAL);
if (SymIsConst (S)) {
/* Use the literal value instead */
N = LiteralExpr (GetSymVal (S));
break;
case TOK_IDENT:
- S = SymRef (SVal);
+ S = SymRef (SVal, SCOPE_LOCAL);
if (SymIsConst (S)) {
/* Use the literal value instead */
N = LiteralExpr (GetSymVal (S));
N = Function (FuncTCount);
break;
+ case TOK_TIME:
+ N = LiteralExpr (time (0));
+ NextTok ();
+ break;
+
case TOK_XMATCH:
N = Function (FuncXMatch);
break;
default:
- N = LiteralExpr (0); /* Dummy */
- Error (ERR_SYNTAX);
+ if (LooseCharTerm && Tok == TOK_STRCON && strlen(SVal) == 1) {
+ /* A character constant */
+ N = LiteralExpr (TgtTranslateChar (SVal[0]));
+ } else {
+ N = LiteralExpr (0); /* Dummy */
+ Error (ERR_SYNTAX);
+ }
NextTok ();
break;
}
if (RelocMode) {
/* Create SegmentBase + Offset */
Left = NewExprNode ();
- Left->Op = EXPR_SEGMENT;
+ Left->Op = EXPR_SECTION;
Left->V.SegNum = GetSegNum ();
Root = NewExprNode ();
/* Create *+Offs */
if (RelocMode) {
Left = NewExprNode ();
- Left->Op = EXPR_SEGMENT;
+ Left->Op = EXPR_SECTION;
Left->V.SegNum = GetSegNum ();
N = NewExprNode ();
case EXPR_SYMBOL:
Sym = Root->V.Sym;
if (SymHasUserMark (Sym)) {
- if (Verbose) {
+ if (Verbosity > 0) {
DumpExpr (Root);
}
PError (GetSymPos (Sym), ERR_CIRCULAR_REFERENCE);
case EXPR_LEAFNODE:
switch (N->Op) {
- case EXPR_SYMBOL:
- if (SymIsZP (N->V.Sym)) {
- *IsByte = 1;
- }
+ case EXPR_SYMBOL:
+ if (SymIsZP (N->V.Sym)) {
+ *IsByte = 1;
+ } else if (SymHasExpr (N->V.Sym)) {
+ /* Check if this expression is a byte expression */
+ *IsByte = IsByteExpr (GetSymExpr (N->V.Sym));
+ }
break;
- case EXPR_SEGMENT:
+ case EXPR_SECTION:
if (GetSegType (N->V.SegNum) == SEGTYPE_ZP) {
*IsByte = 1;
}
SymEntry* Sym = Expr->V.Sym;
if (SymHasUserMark (Sym)) {
/* Circular definition */
- if (Verbose) {
+ if (Verbosity) {
DumpExpr (Expr);
}
PError (GetSymPos (Sym), ERR_CIRCULAR_REFERENCE);
Clone->V.Sym = Expr->V.Sym;
break;
- case EXPR_SEGMENT:
+ case EXPR_SECTION:
Clone->V.SegNum = Expr->V.SegNum;
break;
return Left;
} else {
/* Check for SEG - SEG which is now possible */
- if (Left->Op == EXPR_SEGMENT && Right->Op == EXPR_SEGMENT &&
+ if (Left->Op == EXPR_SECTION && Right->Op == EXPR_SECTION &&
Left->V.SegNum == Right->V.SegNum) {
/* SEG - SEG, remove it completely */
FreeExprNode (Left);
Clone->V.Sym = Expr->V.Sym;
break;
- case EXPR_SEGMENT:
+ case EXPR_SECTION:
Clone->V.SegNum = Expr->V.SegNum;
break;
ObjWrite16 (GetSymIndex (Expr->V.Sym));
break;
- case EXPR_SEGMENT:
+ case EXPR_SECTION:
ObjWrite8 (Expr->V.SegNum);
break;