From 76d94bc8d926578e9dd86eda060d595c2d726e8a Mon Sep 17 00:00:00 2001 From: cuz Date: Mon, 9 May 2005 18:57:03 +0000 Subject: [PATCH] Added a .IDENT function git-svn-id: svn://svn.cc65.org/cc65/trunk@3506 b7a2c559-68d2-44c3-8de9-860c34a00d81 --- src/ca65/nexttok.c | 85 ++++++++++++++++++++++++++++++++++++++++++++++ src/ca65/pseudo.c | 1 + src/ca65/scanner.c | 5 +-- src/ca65/scanner.h | 9 ++++- 4 files changed, 97 insertions(+), 3 deletions(-) diff --git a/src/ca65/nexttok.c b/src/ca65/nexttok.c index b455d32fd..12bed7e48 100644 --- a/src/ca65/nexttok.c +++ b/src/ca65/nexttok.c @@ -42,6 +42,7 @@ /* ca65 */ #include "error.h" #include "expr.h" +#include "global.h" #include "scanner.h" #include "toklist.h" #include "nexttok.h" @@ -223,6 +224,86 @@ static void FuncLeft (void) +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 */ { @@ -384,6 +465,10 @@ void NextTok (void) FuncLeft (); break; + case TOK_MAKEIDENT: + FuncIdent (); + break; + case TOK_MID: FuncMid (); break; diff --git a/src/ca65/pseudo.c b/src/ca65/pseudo.c index 84f6f5eb4..1ed627212 100644 --- a/src/ca65/pseudo.c +++ b/src/ca65/pseudo.c @@ -1720,6 +1720,7 @@ static CtrlDesc CtrlCmdTab [] = { { ccNone, DoUnexpected }, /* .HIWORD */ { ccNone, DoI16 }, { ccNone, DoI8 }, + { ccNone, DoUnexpected }, /* .IDENT */ { ccKeepToken, DoConditionals }, /* .IF */ { ccKeepToken, DoConditionals }, /* .IFBLANK */ { ccKeepToken, DoConditionals }, /* .IFCONST */ diff --git a/src/ca65/scanner.c b/src/ca65/scanner.c index 30b0828a6..f07be47b7 100644 --- a/src/ca65/scanner.c +++ b/src/ca65/scanner.c @@ -179,6 +179,7 @@ struct DotKeyword { { ".HIWORD", TOK_HIWORD }, { ".I16", TOK_I16 }, { ".I8", TOK_I8 }, + { ".IDENT", TOK_MAKEIDENT }, { ".IF", TOK_IF }, { ".IFBLANK", TOK_IFBLANK }, { ".IFCONST", TOK_IFCONST }, @@ -276,7 +277,7 @@ static void NextChar (void); -static int IsIdChar (int C) +int IsIdChar (int C) /* Return true if the character is a valid character for an identifier */ { return IsAlNum (C) || @@ -287,7 +288,7 @@ static int IsIdChar (int C) -static int IsIdStart (int C) +int IsIdStart (int C) /* Return true if the character may start an identifier */ { return IsAlpha (C) || C == '_'; diff --git a/src/ca65/scanner.h b/src/ca65/scanner.h index cf98dff02..637ae3816 100644 --- a/src/ca65/scanner.h +++ b/src/ca65/scanner.h @@ -6,7 +6,7 @@ /* */ /* */ /* */ -/* (C) 1998-2004 Ullrich von Bassewitz */ +/* (C) 1998-2005 Ullrich von Bassewitz */ /* Römerstraße 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ @@ -174,6 +174,7 @@ enum Token { TOK_HIWORD, TOK_I16, TOK_I8, + TOK_MAKEIDENT, TOK_IF, TOK_IFBLANK, TOK_IFCONST, @@ -267,6 +268,12 @@ extern int ForcedEnd; /* Force end of assembly */ +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 */