mirror of
https://github.com/cc65/cc65.git
synced 2024-09-28 10:55:43 +00:00
Fixed a problem with {} enclosed token lists and implemented them for
.blank and .tcount. git-svn-id: svn://svn.cc65.org/cc65/trunk@3014 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
parent
fdb685b874
commit
b10b7cd3e8
@ -323,31 +323,35 @@ static ExprNode* FuncBankByte (void)
|
|||||||
static ExprNode* FuncBlank (void)
|
static ExprNode* FuncBlank (void)
|
||||||
/* Handle the .BLANK builtin function */
|
/* Handle the .BLANK builtin function */
|
||||||
{
|
{
|
||||||
int Result = 1;
|
/* We have a list of tokens that ends with the closing paren. Skip
|
||||||
|
* the tokens, and count them. Allow optionally curly braces.
|
||||||
/* Assume no tokens if the closing brace follows (this is not correct in
|
|
||||||
* all cases, since the token may be the closing brace, but this will
|
|
||||||
* give a syntax error anyway and may not be handled by .BLANK.
|
|
||||||
*/
|
*/
|
||||||
if (Tok != TOK_RPAREN) {
|
enum Token Term = GetTokListTerm (TOK_RPAREN);
|
||||||
/* Skip any tokens */
|
unsigned Count = 0;
|
||||||
int Braces = 0;
|
while (Tok != Term) {
|
||||||
while (!TokIsSep (Tok)) {
|
|
||||||
if (Tok == TOK_LPAREN) {
|
/* Check for end of line or end of input. Since the calling function
|
||||||
++Braces;
|
* will check for the closing paren, we don't need to print an error
|
||||||
} else if (Tok == TOK_RPAREN) {
|
* here, just bail out.
|
||||||
if (Braces == 0) {
|
*/
|
||||||
/* Done */
|
if (TokIsSep (Tok)) {
|
||||||
break;
|
break;
|
||||||
} else {
|
|
||||||
--Braces;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
NextTok ();
|
|
||||||
}
|
}
|
||||||
Result = 0;
|
|
||||||
|
/* One more token */
|
||||||
|
++Count;
|
||||||
|
|
||||||
|
/* Skip the token */
|
||||||
|
NextTok ();
|
||||||
}
|
}
|
||||||
return GenLiteralExpr (Result);
|
|
||||||
|
/* If the list was enclosed in curly braces, skip the closing brace */
|
||||||
|
if (Term == TOK_RCURLY && Tok == TOK_RCURLY) {
|
||||||
|
NextTok ();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return true if the list was empty */
|
||||||
|
return GenLiteralExpr (Count == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -418,7 +422,6 @@ static ExprNode* DoMatch (enum TC EqualityLevel)
|
|||||||
/* Handle the .MATCH and .XMATCH builtin functions */
|
/* Handle the .MATCH and .XMATCH builtin functions */
|
||||||
{
|
{
|
||||||
int Result;
|
int Result;
|
||||||
enum Token Term;
|
|
||||||
TokNode* Root = 0;
|
TokNode* Root = 0;
|
||||||
TokNode* Last = 0;
|
TokNode* Last = 0;
|
||||||
TokNode* Node;
|
TokNode* Node;
|
||||||
@ -427,12 +430,7 @@ static ExprNode* DoMatch (enum TC EqualityLevel)
|
|||||||
* single linked list of tokens including attributes. The list is
|
* single linked list of tokens including attributes. The list is
|
||||||
* either enclosed in curly braces, or terminated by a comma.
|
* either enclosed in curly braces, or terminated by a comma.
|
||||||
*/
|
*/
|
||||||
if (Tok == TOK_LCURLY) {
|
enum Token Term = GetTokListTerm (TOK_COMMA);
|
||||||
NextTok ();
|
|
||||||
Term = TOK_RCURLY;
|
|
||||||
} else {
|
|
||||||
Term = TOK_COMMA;
|
|
||||||
}
|
|
||||||
while (Tok != Term) {
|
while (Tok != Term) {
|
||||||
|
|
||||||
/* We may not end-of-line of end-of-file here */
|
/* We may not end-of-line of end-of-file here */
|
||||||
@ -465,15 +463,10 @@ static ExprNode* DoMatch (enum TC EqualityLevel)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Read the second list which is optionally enclosed in curly braces and
|
/* Read the second list which is optionally enclosed in curly braces and
|
||||||
* terminated by the right parenthesis. Compare each token against the
|
* terminated by the right parenthesis. Compare each token against the
|
||||||
* one in the first list.
|
* one in the first list.
|
||||||
*/
|
*/
|
||||||
if (Tok == TOK_LCURLY) {
|
Term = GetTokListTerm (TOK_RPAREN);
|
||||||
NextTok ();
|
|
||||||
Term = TOK_RCURLY;
|
|
||||||
} else {
|
|
||||||
Term = TOK_RPAREN;
|
|
||||||
}
|
|
||||||
Result = 1;
|
Result = 1;
|
||||||
Node = Root;
|
Node = Root;
|
||||||
while (Tok != Term) {
|
while (Tok != Term) {
|
||||||
@ -716,11 +709,11 @@ static ExprNode* FuncTCount (void)
|
|||||||
/* Handle the .TCOUNT function */
|
/* Handle the .TCOUNT function */
|
||||||
{
|
{
|
||||||
/* We have a list of tokens that ends with the closing paren. Skip
|
/* We have a list of tokens that ends with the closing paren. Skip
|
||||||
* the tokens, handling nested braces and count them.
|
* the tokens, and count them. Allow optionally curly braces.
|
||||||
*/
|
*/
|
||||||
int Count = 0;
|
enum Token Term = GetTokListTerm (TOK_RPAREN);
|
||||||
unsigned Parens = 0;
|
int Count = 0;
|
||||||
while (Parens != 0 || Tok != TOK_RPAREN) {
|
while (Tok != Term) {
|
||||||
|
|
||||||
/* Check for end of line or end of input. Since the calling function
|
/* Check for end of line or end of input. Since the calling function
|
||||||
* will check for the closing paren, we don't need to print an error
|
* will check for the closing paren, we don't need to print an error
|
||||||
@ -733,17 +726,15 @@ static ExprNode* FuncTCount (void)
|
|||||||
/* One more token */
|
/* One more token */
|
||||||
++Count;
|
++Count;
|
||||||
|
|
||||||
/* Keep track of the nesting level */
|
|
||||||
switch (Tok) {
|
|
||||||
case TOK_LPAREN: ++Parens; break;
|
|
||||||
case TOK_RPAREN: --Parens; break;
|
|
||||||
default: break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Skip the token */
|
/* Skip the token */
|
||||||
NextTok ();
|
NextTok ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If the list was enclosed in curly braces, skip the closing brace */
|
||||||
|
if (Term == TOK_RCURLY && Tok == TOK_RCURLY) {
|
||||||
|
NextTok ();
|
||||||
|
}
|
||||||
|
|
||||||
/* Return the number of tokens */
|
/* Return the number of tokens */
|
||||||
return GenLiteralExpr (Count);
|
return GenLiteralExpr (Count);
|
||||||
}
|
}
|
||||||
@ -760,7 +751,7 @@ static ExprNode* FuncXMatch (void)
|
|||||||
|
|
||||||
static ExprNode* Function (ExprNode* (*F) (void))
|
static ExprNode* Function (ExprNode* (*F) (void))
|
||||||
/* Handle builtin functions */
|
/* Handle builtin functions */
|
||||||
{
|
{
|
||||||
ExprNode* E;
|
ExprNode* E;
|
||||||
|
|
||||||
/* Skip the keyword */
|
/* Skip the keyword */
|
||||||
|
@ -677,12 +677,7 @@ static void StartExpClassic (Macro* M)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* The macro may optionally be enclosed in curly braces */
|
/* The macro may optionally be enclosed in curly braces */
|
||||||
if (Tok == TOK_LCURLY) {
|
Term = GetTokListTerm (TOK_COMMA);
|
||||||
NextTok ();
|
|
||||||
Term = TOK_RCURLY;
|
|
||||||
} else {
|
|
||||||
Term = TOK_COMMA;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Read tokens for one parameter, accept empty params */
|
/* Read tokens for one parameter, accept empty params */
|
||||||
Last = 0;
|
Last = 0;
|
||||||
@ -760,16 +755,10 @@ static void StartExpDefine (Macro* M)
|
|||||||
/* Read the actual parameters */
|
/* Read the actual parameters */
|
||||||
while (Count--) {
|
while (Count--) {
|
||||||
|
|
||||||
enum Token Term;
|
|
||||||
TokNode* Last;
|
TokNode* Last;
|
||||||
|
|
||||||
/* The macro may optionally be enclosed in curly braces */
|
/* The macro may optionally be enclosed in curly braces */
|
||||||
if (Tok == TOK_LCURLY) {
|
enum Token Term = GetTokListTerm (TOK_COMMA);
|
||||||
NextTok ();
|
|
||||||
Term = TOK_RCURLY;
|
|
||||||
} else {
|
|
||||||
Term = TOK_COMMA;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check if there is really a parameter */
|
/* Check if there is really a parameter */
|
||||||
if (TokIsSep (Tok) || Tok == Term) {
|
if (TokIsSep (Tok) || Tok == Term) {
|
||||||
|
@ -71,22 +71,15 @@ static TokList* CollectTokens (unsigned Start, unsigned Count)
|
|||||||
* return this token list.
|
* return this token list.
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
enum Token Term;
|
|
||||||
unsigned Current;
|
|
||||||
|
|
||||||
/* Create the token list */
|
/* Create the token list */
|
||||||
TokList* List = NewTokList ();
|
TokList* List = NewTokList ();
|
||||||
|
|
||||||
/* Determine if the list is enclosed in curly braces. */
|
/* Determine if the list is enclosed in curly braces. */
|
||||||
if (Tok == TOK_LCURLY) {
|
enum Token Term = GetTokListTerm (TOK_RPAREN);
|
||||||
NextTok ();
|
|
||||||
Term = TOK_RCURLY;
|
|
||||||
} else {
|
|
||||||
Term = TOK_LCURLY;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Read the token list */
|
/* Read the token list */
|
||||||
Current = 0;
|
unsigned Current = 0;
|
||||||
while (Tok != Term) {
|
while (Tok != Term) {
|
||||||
|
|
||||||
/* Check for end of line or end of input */
|
/* Check for end of line or end of input */
|
||||||
|
@ -42,6 +42,7 @@
|
|||||||
/* ca65 */
|
/* ca65 */
|
||||||
#include "error.h"
|
#include "error.h"
|
||||||
#include "istack.h"
|
#include "istack.h"
|
||||||
|
#include "nexttok.h"
|
||||||
#include "scanner.h"
|
#include "scanner.h"
|
||||||
#include "toklist.h"
|
#include "toklist.h"
|
||||||
|
|
||||||
@ -174,6 +175,22 @@ void FreeTokList (TokList* List)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
enum Token GetTokListTerm (enum Token Term)
|
||||||
|
/* Determine if the following token list is enclosed in curly braces. This is
|
||||||
|
* the case if the next token is the opening brace. If so, skip it and return
|
||||||
|
* a closing brace, otherwise return Term.
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
if (Tok == TOK_LCURLY) {
|
||||||
|
NextTok ();
|
||||||
|
return TOK_RCURLY;
|
||||||
|
} else {
|
||||||
|
return Term;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AddCurTok (TokList* List)
|
void AddCurTok (TokList* List)
|
||||||
/* Add the current token to the token list */
|
/* Add the current token to the token list */
|
||||||
{
|
{
|
||||||
|
@ -6,10 +6,10 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 2000 Ullrich von Bassewitz */
|
/* (C) 2000-2004 Ullrich von Bassewitz */
|
||||||
/* Wacholderweg 14 */
|
/* Römerstraße 52 */
|
||||||
/* D-70597 Stuttgart */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@musoftware.de */
|
/* EMail: uz@cc65.org */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* This software is provided 'as-is', without any expressed or implied */
|
/* This software is provided 'as-is', without any expressed or implied */
|
||||||
@ -109,6 +109,12 @@ TokList* NewTokList (void);
|
|||||||
void FreeTokList (TokList* T);
|
void FreeTokList (TokList* T);
|
||||||
/* Delete the token list including all token nodes */
|
/* Delete the token list including all token nodes */
|
||||||
|
|
||||||
|
enum Token GetTokListTerm (enum Token Term);
|
||||||
|
/* Determine if the following token list is enclosed in curly braces. This is
|
||||||
|
* the case if the next token is the opening brace. If so, skip it and return
|
||||||
|
* a closing brace, otherwise return Term.
|
||||||
|
*/
|
||||||
|
|
||||||
void AddCurTok (TokList* T);
|
void AddCurTok (TokList* T);
|
||||||
/* Add the current token to the token list */
|
/* Add the current token to the token list */
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user