mirror of
https://github.com/cc65/cc65.git
synced 2025-02-09 02:30:42 +00:00
Removed the strexpr module and placed the implementation of the .STRING
builtin function into the NextTok function. Added the .CONCAT function. git-svn-id: svn://svn.cc65.org/cc65/trunk@113 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
parent
66df712d40
commit
6b002da603
@ -25,7 +25,6 @@ OBJS = condasm.o \
|
|||||||
options.o \
|
options.o \
|
||||||
pseudo.o \
|
pseudo.o \
|
||||||
scanner.o \
|
scanner.o \
|
||||||
strexpr.o \
|
|
||||||
symtab.o \
|
symtab.o \
|
||||||
toklist.o \
|
toklist.o \
|
||||||
ulabel.o
|
ulabel.o
|
||||||
|
@ -82,7 +82,6 @@ OBJS = condasm.obj \
|
|||||||
options.obj \
|
options.obj \
|
||||||
pseudo.obj \
|
pseudo.obj \
|
||||||
scanner.obj \
|
scanner.obj \
|
||||||
strexpr.obj \
|
|
||||||
symtab.obj \
|
symtab.obj \
|
||||||
toklist.obj \
|
toklist.obj \
|
||||||
ulabel.obj
|
ulabel.obj
|
||||||
@ -126,7 +125,6 @@ FILE objfile.obj
|
|||||||
FILE options.obj
|
FILE options.obj
|
||||||
FILE pseudo.obj
|
FILE pseudo.obj
|
||||||
FILE scanner.obj
|
FILE scanner.obj
|
||||||
FILE strexpr.obj
|
|
||||||
FILE symtab.obj
|
FILE symtab.obj
|
||||||
FILE toklist.obj
|
FILE toklist.obj
|
||||||
FILE ulabel.obj
|
FILE ulabel.obj
|
||||||
|
@ -33,6 +33,8 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "error.h"
|
#include "error.h"
|
||||||
#include "expr.h"
|
#include "expr.h"
|
||||||
#include "scanner.h"
|
#include "scanner.h"
|
||||||
@ -93,10 +95,79 @@ static TokList* CollectTokens (unsigned Start, unsigned Count)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static void FuncConcat (void)
|
||||||
|
/* Handle the .CONCAT function */
|
||||||
|
{
|
||||||
|
char Buf[MAX_STR_LEN+1];
|
||||||
|
char* B;
|
||||||
|
unsigned Length;
|
||||||
|
unsigned L;
|
||||||
|
|
||||||
|
/* Skip it */
|
||||||
|
NextTok ();
|
||||||
|
|
||||||
|
/* Left paren expected */
|
||||||
|
ConsumeLParen ();
|
||||||
|
|
||||||
|
/* Concatenate any number of strings */
|
||||||
|
B = Buf;
|
||||||
|
B[0] = '\0';
|
||||||
|
Length = 0;
|
||||||
|
while (1) {
|
||||||
|
|
||||||
|
/* Next token must be a string */
|
||||||
|
if (Tok != TOK_STRCON) {
|
||||||
|
Error (ERR_STRCON_EXPECTED);
|
||||||
|
SkipUntilSep ();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get the length of the string const and check total length */
|
||||||
|
L = strlen (SVal);
|
||||||
|
if (Length + L > MAX_STR_LEN) {
|
||||||
|
Error (ERR_STRING_TOO_LONG);
|
||||||
|
/* Try to recover */
|
||||||
|
SkipUntilSep ();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add the new string */
|
||||||
|
memcpy (B, SVal, L);
|
||||||
|
Length += L;
|
||||||
|
B += L;
|
||||||
|
|
||||||
|
/* Skip the string token */
|
||||||
|
NextTok ();
|
||||||
|
|
||||||
|
/* Comma means another argument */
|
||||||
|
if (Tok == TOK_COMMA) {
|
||||||
|
NextTok ();
|
||||||
|
} else {
|
||||||
|
/* Done */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Terminate the string */
|
||||||
|
*B = '\0';
|
||||||
|
|
||||||
|
/* We expect a closing parenthesis, but will not skip it but replace it
|
||||||
|
* by the string token just created.
|
||||||
|
*/
|
||||||
|
if (Tok != TOK_RPAREN) {
|
||||||
|
Error (ERR_RPAREN_EXPECTED);
|
||||||
|
} else {
|
||||||
|
Tok = TOK_STRCON;
|
||||||
|
strcpy (SVal, Buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void FuncMid (void)
|
static void FuncMid (void)
|
||||||
/* Handle the .MID function */
|
/* Handle the .MID function */
|
||||||
{
|
{
|
||||||
long Start;
|
long Start;
|
||||||
long Count;
|
long Count;
|
||||||
TokList* List;
|
TokList* List;
|
||||||
|
|
||||||
@ -104,13 +175,13 @@ static void FuncMid (void)
|
|||||||
NextTok ();
|
NextTok ();
|
||||||
|
|
||||||
/* Left paren expected */
|
/* Left paren expected */
|
||||||
ConsumeRParen ();
|
ConsumeLParen ();
|
||||||
|
|
||||||
/* Start argument */
|
/* Start argument */
|
||||||
Start = ConstExpression ();
|
Start = ConstExpression ();
|
||||||
if (Start < 0 || Start > 100) {
|
if (Start < 0 || Start > 100) {
|
||||||
Error (ERR_RANGE);
|
Error (ERR_RANGE);
|
||||||
Start = 0;
|
Start = 0;
|
||||||
}
|
}
|
||||||
ConsumeComma ();
|
ConsumeComma ();
|
||||||
|
|
||||||
@ -133,6 +204,41 @@ static void FuncMid (void)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static void FuncString (void)
|
||||||
|
/* Handle the .STRING function */
|
||||||
|
{
|
||||||
|
char Buf[MAX_STR_LEN+1];
|
||||||
|
|
||||||
|
/* Skip it */
|
||||||
|
NextTok ();
|
||||||
|
|
||||||
|
/* Left paren expected */
|
||||||
|
ConsumeLParen ();
|
||||||
|
|
||||||
|
/* Accept identifiers or numeric expressions */
|
||||||
|
if (Tok == TOK_IDENT) {
|
||||||
|
/* Save the identifier, then skip it */
|
||||||
|
strcpy (Buf, SVal);
|
||||||
|
NextTok ();
|
||||||
|
} else {
|
||||||
|
/* Numeric expression */
|
||||||
|
long Val = ConstExpression ();
|
||||||
|
sprintf (Buf, "%ld", Val);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We expect a closing parenthesis, but will not skip it but replace it
|
||||||
|
* by the string token just created.
|
||||||
|
*/
|
||||||
|
if (Tok != TOK_RPAREN) {
|
||||||
|
Error (ERR_RPAREN_EXPECTED);
|
||||||
|
} else {
|
||||||
|
Tok = TOK_STRCON;
|
||||||
|
strcpy (SVal, Buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void NextTok (void)
|
void NextTok (void)
|
||||||
/* Get next token and handle token level functions */
|
/* Get next token and handle token level functions */
|
||||||
{
|
{
|
||||||
@ -142,10 +248,18 @@ void NextTok (void)
|
|||||||
/* Check for token handling functions */
|
/* Check for token handling functions */
|
||||||
switch (Tok) {
|
switch (Tok) {
|
||||||
|
|
||||||
|
case TOK_CONCAT:
|
||||||
|
FuncConcat ();
|
||||||
|
break;
|
||||||
|
|
||||||
case TOK_MID:
|
case TOK_MID:
|
||||||
FuncMid ();
|
FuncMid ();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case TOK_STRING:
|
||||||
|
FuncString ();
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
/* Quiet down gcc */
|
/* Quiet down gcc */
|
||||||
break;
|
break;
|
||||||
|
@ -52,7 +52,6 @@
|
|||||||
#include "nexttok.h"
|
#include "nexttok.h"
|
||||||
#include "objcode.h"
|
#include "objcode.h"
|
||||||
#include "options.h"
|
#include "options.h"
|
||||||
#include "strexpr.h"
|
|
||||||
#include "symtab.h"
|
#include "symtab.h"
|
||||||
#include "pseudo.h"
|
#include "pseudo.h"
|
||||||
|
|
||||||
@ -250,7 +249,7 @@ static void DoASCIIZ (void)
|
|||||||
/* Define text with a zero terminator */
|
/* Define text with a zero terminator */
|
||||||
{
|
{
|
||||||
while (1) {
|
while (1) {
|
||||||
if (StringExpression () == 0) {
|
if (Tok != TOK_STRCON) {
|
||||||
ErrorSkip (ERR_STRCON_EXPECTED);
|
ErrorSkip (ERR_STRCON_EXPECTED);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -287,7 +286,7 @@ static void DoByte (void)
|
|||||||
/* Define bytes */
|
/* Define bytes */
|
||||||
{
|
{
|
||||||
while (1) {
|
while (1) {
|
||||||
if (StringExpression () != 0) {
|
if (Tok == TOK_STRCON) {
|
||||||
/* A string */
|
/* A string */
|
||||||
EmitData (SVal, strlen (SVal));
|
EmitData (SVal, strlen (SVal));
|
||||||
NextTok ();
|
NextTok ();
|
||||||
@ -399,7 +398,7 @@ static void DoEndProc (void)
|
|||||||
static void DoError (void)
|
static void DoError (void)
|
||||||
/* Use error */
|
/* Use error */
|
||||||
{
|
{
|
||||||
if (StringExpression () == 0) {
|
if (Tok == TOK_STRCON) {
|
||||||
ErrorSkip (ERR_STRCON_EXPECTED);
|
ErrorSkip (ERR_STRCON_EXPECTED);
|
||||||
} else {
|
} else {
|
||||||
Error (ERR_USER, SVal);
|
Error (ERR_USER, SVal);
|
||||||
@ -535,7 +534,7 @@ static void DoFileOpt (void)
|
|||||||
ConsumeComma ();
|
ConsumeComma ();
|
||||||
|
|
||||||
/* We accept only string options for now */
|
/* We accept only string options for now */
|
||||||
if (StringExpression () == 0) {
|
if (Tok != TOK_STRCON) {
|
||||||
ErrorSkip (ERR_STRCON_EXPECTED);
|
ErrorSkip (ERR_STRCON_EXPECTED);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -579,7 +578,7 @@ static void DoFileOpt (void)
|
|||||||
ConsumeComma ();
|
ConsumeComma ();
|
||||||
|
|
||||||
/* We accept only string options for now */
|
/* We accept only string options for now */
|
||||||
if (StringExpression () == 0) {
|
if (Tok != TOK_STRCON) {
|
||||||
ErrorSkip (ERR_STRCON_EXPECTED);
|
ErrorSkip (ERR_STRCON_EXPECTED);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -656,7 +655,7 @@ static void DoIncBin (void)
|
|||||||
/* Include a binary file */
|
/* Include a binary file */
|
||||||
{
|
{
|
||||||
/* Name must follow */
|
/* Name must follow */
|
||||||
if (StringExpression () == 0) {
|
if (Tok != TOK_STRCON) {
|
||||||
ErrorSkip (ERR_STRCON_EXPECTED);
|
ErrorSkip (ERR_STRCON_EXPECTED);
|
||||||
} else {
|
} else {
|
||||||
/* Try to open the file */
|
/* Try to open the file */
|
||||||
@ -686,7 +685,7 @@ static void DoInclude (void)
|
|||||||
char Name [MAX_STR_LEN+1];
|
char Name [MAX_STR_LEN+1];
|
||||||
|
|
||||||
/* Name must follow */
|
/* Name must follow */
|
||||||
if (StringExpression () == 0) {
|
if (Tok != TOK_STRCON) {
|
||||||
ErrorSkip (ERR_STRCON_EXPECTED);
|
ErrorSkip (ERR_STRCON_EXPECTED);
|
||||||
} else {
|
} else {
|
||||||
strcpy (Name, SVal);
|
strcpy (Name, SVal);
|
||||||
@ -823,7 +822,7 @@ static void DoOrg (void)
|
|||||||
static void DoOut (void)
|
static void DoOut (void)
|
||||||
/* Output a string */
|
/* Output a string */
|
||||||
{
|
{
|
||||||
if (StringExpression () == 0) {
|
if (Tok != TOK_STRCON) {
|
||||||
ErrorSkip (ERR_STRCON_EXPECTED);
|
ErrorSkip (ERR_STRCON_EXPECTED);
|
||||||
} else {
|
} else {
|
||||||
/* Output the string and be sure to flush the output to keep it in
|
/* Output the string and be sure to flush the output to keep it in
|
||||||
@ -950,7 +949,7 @@ static void DoSegment (void)
|
|||||||
char Name [sizeof (SVal)];
|
char Name [sizeof (SVal)];
|
||||||
int SegType;
|
int SegType;
|
||||||
|
|
||||||
if (StringExpression () == 0) {
|
if (Tok != TOK_STRCON) {
|
||||||
ErrorSkip (ERR_STRCON_EXPECTED);
|
ErrorSkip (ERR_STRCON_EXPECTED);
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
@ -1079,6 +1078,7 @@ static CtrlDesc CtrlCmdTab [] = {
|
|||||||
{ ccNone, DoByte },
|
{ ccNone, DoByte },
|
||||||
{ ccNone, DoCase },
|
{ ccNone, DoCase },
|
||||||
{ ccNone, DoCode },
|
{ ccNone, DoCode },
|
||||||
|
{ ccNone, DoUnexpected, }, /* .CONCAT */
|
||||||
{ ccNone, DoUnexpected }, /* .CONST */
|
{ ccNone, DoUnexpected }, /* .CONST */
|
||||||
{ ccNone, DoUnexpected }, /* .CPU */
|
{ ccNone, DoUnexpected }, /* .CPU */
|
||||||
{ ccNone, DoData },
|
{ ccNone, DoData },
|
||||||
|
@ -136,6 +136,7 @@ struct DotKeyword {
|
|||||||
{ "BYTE", TOK_BYTE },
|
{ "BYTE", TOK_BYTE },
|
||||||
{ "CASE", TOK_CASE },
|
{ "CASE", TOK_CASE },
|
||||||
{ "CODE", TOK_CODE },
|
{ "CODE", TOK_CODE },
|
||||||
|
{ "CONCAT", TOK_CONCAT },
|
||||||
{ "CONST", TOK_CONST },
|
{ "CONST", TOK_CONST },
|
||||||
{ "CPU", TOK_CPU },
|
{ "CPU", TOK_CPU },
|
||||||
{ "DATA", TOK_DATA },
|
{ "DATA", TOK_DATA },
|
||||||
|
@ -118,6 +118,7 @@ enum Token {
|
|||||||
TOK_BYTE,
|
TOK_BYTE,
|
||||||
TOK_CASE,
|
TOK_CASE,
|
||||||
TOK_CODE,
|
TOK_CODE,
|
||||||
|
TOK_CONCAT,
|
||||||
TOK_CONST,
|
TOK_CONST,
|
||||||
TOK_CPU,
|
TOK_CPU,
|
||||||
TOK_DATA,
|
TOK_DATA,
|
||||||
|
@ -1,97 +0,0 @@
|
|||||||
/*****************************************************************************/
|
|
||||||
/* */
|
|
||||||
/* strexpr.c */
|
|
||||||
/* */
|
|
||||||
/* String expressions for the ca65 macroassembler */
|
|
||||||
/* */
|
|
||||||
/* */
|
|
||||||
/* */
|
|
||||||
/* (C) 2000 Ullrich von Bassewitz */
|
|
||||||
/* Wacholderweg 14 */
|
|
||||||
/* D-70597 Stuttgart */
|
|
||||||
/* EMail: uz@musoftware.de */
|
|
||||||
/* */
|
|
||||||
/* */
|
|
||||||
/* This software is provided 'as-is', without any expressed or implied */
|
|
||||||
/* warranty. In no event will the authors be held liable for any damages */
|
|
||||||
/* arising from the use of this software. */
|
|
||||||
/* */
|
|
||||||
/* Permission is granted to anyone to use this software for any purpose, */
|
|
||||||
/* including commercial applications, and to alter it and redistribute it */
|
|
||||||
/* freely, subject to the following restrictions: */
|
|
||||||
/* */
|
|
||||||
/* 1. The origin of this software must not be misrepresented; you must not */
|
|
||||||
/* claim that you wrote the original software. If you use this software */
|
|
||||||
/* in a product, an acknowledgment in the product documentation would be */
|
|
||||||
/* appreciated but is not required. */
|
|
||||||
/* 2. Altered source versions must be plainly marked as such, and must not */
|
|
||||||
/* be misrepresented as being the original software. */
|
|
||||||
/* 3. This notice may not be removed or altered from any source */
|
|
||||||
/* distribution. */
|
|
||||||
/* */
|
|
||||||
/*****************************************************************************/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#include "error.h"
|
|
||||||
#include "expr.h"
|
|
||||||
#include "scanner.h"
|
|
||||||
#include "strexpr.h"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
|
||||||
/* Code */
|
|
||||||
/*****************************************************************************/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const char* StringExpression (void)
|
|
||||||
/* Evaluate a string expression. If there are no errors, the function will
|
|
||||||
* place the string into the token attribute buffer SVal and the token will
|
|
||||||
* be TOK_STRCON. A pointer to the buffer is returned.
|
|
||||||
* If there was an error, a NULL pointer is returned.
|
|
||||||
*/
|
|
||||||
{
|
|
||||||
char Buf [sizeof (SVal)];
|
|
||||||
|
|
||||||
/* Check for a string constant or a function that returns a string */
|
|
||||||
switch (Tok) {
|
|
||||||
|
|
||||||
case TOK_STRING:
|
|
||||||
NextTok ();
|
|
||||||
ConsumeLParen ();
|
|
||||||
if (Tok == TOK_IDENT) {
|
|
||||||
/* Save the identifier, then skip it */
|
|
||||||
strcpy (Buf, SVal);
|
|
||||||
NextTok ();
|
|
||||||
} else {
|
|
||||||
/* Numeric expression */
|
|
||||||
long Val = ConstExpression ();
|
|
||||||
sprintf (Buf, "%ld", Val);
|
|
||||||
}
|
|
||||||
if (Tok != TOK_RPAREN) {
|
|
||||||
Error (ERR_RPAREN_EXPECTED);
|
|
||||||
}
|
|
||||||
/* Overwrite the token, do not skip it! */
|
|
||||||
strcpy (SVal, Buf);
|
|
||||||
Tok = TOK_STRCON;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case TOK_STRCON:
|
|
||||||
/* We already have a string */
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
/* Error - no string constant */
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Return a pointer to the buffer */
|
|
||||||
return SVal;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,61 +0,0 @@
|
|||||||
/*****************************************************************************/
|
|
||||||
/* */
|
|
||||||
/* strexpr.h */
|
|
||||||
/* */
|
|
||||||
/* String expressions for the ca65 macroassembler */
|
|
||||||
/* */
|
|
||||||
/* */
|
|
||||||
/* */
|
|
||||||
/* (C) 2000 Ullrich von Bassewitz */
|
|
||||||
/* Wacholderweg 14 */
|
|
||||||
/* D-70597 Stuttgart */
|
|
||||||
/* EMail: uz@musoftware.de */
|
|
||||||
/* */
|
|
||||||
/* */
|
|
||||||
/* This software is provided 'as-is', without any expressed or implied */
|
|
||||||
/* warranty. In no event will the authors be held liable for any damages */
|
|
||||||
/* arising from the use of this software. */
|
|
||||||
/* */
|
|
||||||
/* Permission is granted to anyone to use this software for any purpose, */
|
|
||||||
/* including commercial applications, and to alter it and redistribute it */
|
|
||||||
/* freely, subject to the following restrictions: */
|
|
||||||
/* */
|
|
||||||
/* 1. The origin of this software must not be misrepresented; you must not */
|
|
||||||
/* claim that you wrote the original software. If you use this software */
|
|
||||||
/* in a product, an acknowledgment in the product documentation would be */
|
|
||||||
/* appreciated but is not required. */
|
|
||||||
/* 2. Altered source versions must be plainly marked as such, and must not */
|
|
||||||
/* be misrepresented as being the original software. */
|
|
||||||
/* 3. This notice may not be removed or altered from any source */
|
|
||||||
/* distribution. */
|
|
||||||
/* */
|
|
||||||
/*****************************************************************************/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef STREXPR_H
|
|
||||||
#define STREXPR_H
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
|
||||||
/* Code */
|
|
||||||
/*****************************************************************************/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const char* StringExpression (void);
|
|
||||||
/* Evaluate a string expression. If there are no errors, the function will
|
|
||||||
* place the string into the token attribute buffer SVal and the token will
|
|
||||||
* be TOK_STRCON. A pointer to the buffer is returned.
|
|
||||||
* If there was an error, a NULL pointer is returned.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* End of strexpr.h */
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user