/* ca65 */
#include "error.h"
#include "expr.h"
+#include "global.h"
#include "scanner.h"
#include "toklist.h"
#include "nexttok.h"
+static void NoIdent (void)
+/* Print an error message and skip the remainder of the line */
+{
+ Error ("Argument of .IDENT is not a valid identifier");
+ SkipUntilSep ();
+}
+
+
+
+static void FuncIdent (void)
+/* Handle the .IDENT function */
+{
+ char Buf[sizeof(SVal)];
+ enum Token Id;
+ unsigned Len;
+ unsigned I;
+
+ /* Skip it */
+ NextTok ();
+
+ /* Left paren expected */
+ ConsumeLParen ();
+
+ /* The function expects a string argument */
+ if (Tok != TOK_STRCON) {
+ Error ("String constant expected");
+ SkipUntilSep ();
+ return;
+ }
+
+ /* Check that the string contains a valid identifier. While doing so,
+ * determine if it is a cheap local, or global one.
+ */
+ Len = strlen (SVal);
+ if (Len == 0) {
+ NoIdent ();
+ return;
+ }
+ I = 0;
+ if (SVal[0] == LocalStart) {
+ if (Len < 2) {
+ NoIdent ();
+ return;
+ }
+ I = 1;
+ Id = TOK_LOCAL_IDENT;
+ } else {
+ Id = TOK_IDENT;
+ }
+ if (!IsIdStart (SVal[I])) {
+ NoIdent ();
+ return;
+ }
+ while (I < Len) {
+ if (!IsIdChar (SVal[I])) {
+ NoIdent ();
+ return;
+ }
+ ++I;
+ }
+ if (IgnoreCase) {
+ UpcaseSVal ();
+ }
+
+ /* If anything is ok, save and skip the string. Check that the next token
+ * is a right paren, in which case SVal is untouched. Replace the token by
+ * a identifier token.
+ */
+ memcpy (Buf, SVal, Len+1);
+ NextTok ();
+ if (Tok != TOK_RPAREN) {
+ Error ("`)' expected");
+ } else {
+ Tok = Id;
+ memcpy (SVal, Buf, Len+1);
+ }
+}
+
+
+
static void FuncMid (void)
/* Handle the .MID function */
{
FuncLeft ();
break;
+ case TOK_MAKEIDENT:
+ FuncIdent ();
+ break;
+
case TOK_MID:
FuncMid ();
break;
{ ccNone, DoUnexpected }, /* .HIWORD */
{ ccNone, DoI16 },
{ ccNone, DoI8 },
+ { ccNone, DoUnexpected }, /* .IDENT */
{ ccKeepToken, DoConditionals }, /* .IF */
{ ccKeepToken, DoConditionals }, /* .IFBLANK */
{ ccKeepToken, DoConditionals }, /* .IFCONST */
{ ".HIWORD", TOK_HIWORD },
{ ".I16", TOK_I16 },
{ ".I8", TOK_I8 },
+ { ".IDENT", TOK_MAKEIDENT },
{ ".IF", TOK_IF },
{ ".IFBLANK", TOK_IFBLANK },
{ ".IFCONST", TOK_IFCONST },
-static int IsIdChar (int C)
+int IsIdChar (int C)
/* Return true if the character is a valid character for an identifier */
{
return IsAlNum (C) ||
-static int IsIdStart (int C)
+int IsIdStart (int C)
/* Return true if the character may start an identifier */
{
return IsAlpha (C) || C == '_';
/* */
/* */
/* */
-/* (C) 1998-2004 Ullrich von Bassewitz */
+/* (C) 1998-2005 Ullrich von Bassewitz */
/* Römerstraße 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
TOK_HIWORD,
TOK_I16,
TOK_I8,
+ TOK_MAKEIDENT,
TOK_IF,
TOK_IFBLANK,
TOK_IFCONST,
+int IsIdChar (int C);
+/* Return true if the character is a valid character for an identifier */
+
+int IsIdStart (int C);
+/* Return true if the character may start an identifier */
+
void NewInputFile (const char* Name);
/* Open a new input file */