Added .SIZEOF
git-svn-id: svn://svn.cc65.org/cc65/trunk@2671 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
@@ -54,6 +54,7 @@
|
|||||||
#include "nexttok.h"
|
#include "nexttok.h"
|
||||||
#include "objfile.h"
|
#include "objfile.h"
|
||||||
#include "segment.h"
|
#include "segment.h"
|
||||||
|
#include "struct.h"
|
||||||
#include "symbol.h"
|
#include "symbol.h"
|
||||||
#include "symtab.h"
|
#include "symtab.h"
|
||||||
#include "toklist.h"
|
#include "toklist.h"
|
||||||
@@ -229,17 +230,16 @@ static int IsEasyConst (const ExprNode* E, long* Val)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
static int FuncBlank (void)
|
static ExprNode* FuncBlank (void)
|
||||||
/* Handle the .BLANK builtin function */
|
/* Handle the .BLANK builtin function */
|
||||||
{
|
{
|
||||||
|
int Result = 1;
|
||||||
|
|
||||||
/* Assume no tokens if the closing brace follows (this is not correct in
|
/* 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
|
* 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.
|
* give a syntax error anyway and may not be handled by .BLANK.
|
||||||
*/
|
*/
|
||||||
if (Tok == TOK_RPAREN) {
|
if (Tok != TOK_RPAREN) {
|
||||||
/* No tokens */
|
|
||||||
return 1;
|
|
||||||
} else {
|
|
||||||
/* Skip any tokens */
|
/* Skip any tokens */
|
||||||
int Braces = 0;
|
int Braces = 0;
|
||||||
while (!TokIsSep (Tok)) {
|
while (!TokIsSep (Tok)) {
|
||||||
@@ -257,18 +257,19 @@ static int FuncBlank (void)
|
|||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
return GenLiteralExpr (Result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static int FuncConst (void)
|
static ExprNode* FuncConst (void)
|
||||||
/* Handle the .CONST builtin function */
|
/* Handle the .CONST builtin function */
|
||||||
{
|
{
|
||||||
/* Read an expression */
|
/* Read an expression */
|
||||||
ExprNode* Expr = Expression ();
|
ExprNode* Expr = Expression ();
|
||||||
|
|
||||||
/* Check the constness of the expression */
|
/* Check the constness of the expression */
|
||||||
int Result = IsConstExpr (Expr, 0);
|
ExprNode* Result = GenLiteralExpr (IsConstExpr (Expr, 0));
|
||||||
|
|
||||||
/* Free the expression */
|
/* Free the expression */
|
||||||
FreeExpr (Expr);
|
FreeExpr (Expr);
|
||||||
@@ -279,19 +280,19 @@ static int FuncConst (void)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
static int FuncDefined (void)
|
static ExprNode* FuncDefined (void)
|
||||||
/* Handle the .DEFINED builtin function */
|
/* Handle the .DEFINED builtin function */
|
||||||
{
|
{
|
||||||
/* Parse the symbol name and search for the symbol */
|
/* Parse the symbol name and search for the symbol */
|
||||||
SymEntry* Sym = ParseScopedSymName (SYM_FIND_EXISTING);
|
SymEntry* Sym = ParseScopedSymName (SYM_FIND_EXISTING);
|
||||||
|
|
||||||
/* Check if the symbol is defined */
|
/* Check if the symbol is defined */
|
||||||
return (Sym != 0 && SymIsDef (Sym));
|
return GenLiteralExpr (Sym != 0 && SymIsDef (Sym));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static int DoMatch (enum TC EqualityLevel)
|
static ExprNode* DoMatch (enum TC EqualityLevel)
|
||||||
/* Handle the .MATCH and .XMATCH builtin functions */
|
/* Handle the .MATCH and .XMATCH builtin functions */
|
||||||
{
|
{
|
||||||
int Result;
|
int Result;
|
||||||
@@ -342,7 +343,7 @@ static int DoMatch (enum TC EqualityLevel)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Compare the tokens if the result is not already known */
|
/* Compare the tokens if the result is not already known */
|
||||||
if (Result != 0) {
|
if (Result != 0) {
|
||||||
if (Node == 0) {
|
if (Node == 0) {
|
||||||
/* The second list is larger than the first one */
|
/* The second list is larger than the first one */
|
||||||
@@ -375,12 +376,12 @@ static int DoMatch (enum TC EqualityLevel)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Done, return the result */
|
/* Done, return the result */
|
||||||
return Result;
|
return GenLiteralExpr (Result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static int FuncMatch (void)
|
static ExprNode* FuncMatch (void)
|
||||||
/* Handle the .MATCH function */
|
/* Handle the .MATCH function */
|
||||||
{
|
{
|
||||||
return DoMatch (tcSameToken);
|
return DoMatch (tcSameToken);
|
||||||
@@ -388,23 +389,46 @@ static int FuncMatch (void)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
static int FuncReferenced (void)
|
static ExprNode* FuncReferenced (void)
|
||||||
/* Handle the .REFERENCED builtin function */
|
/* Handle the .REFERENCED builtin function */
|
||||||
{
|
{
|
||||||
/* Parse the symbol name and search for the symbol */
|
/* Parse the symbol name and search for the symbol */
|
||||||
SymEntry* Sym = ParseScopedSymName (SYM_FIND_EXISTING);
|
SymEntry* Sym = ParseScopedSymName (SYM_FIND_EXISTING);
|
||||||
|
|
||||||
/* Check if the symbol is referenced */
|
/* Check if the symbol is referenced */
|
||||||
return (Sym != 0 && SymIsRef (Sym));
|
return GenLiteralExpr (Sym != 0 && SymIsRef (Sym));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static int FuncStrAt (void)
|
static ExprNode* FuncSizeOf (void)
|
||||||
|
/* Handle the .SIZEOF function */
|
||||||
|
{
|
||||||
|
long Size;
|
||||||
|
|
||||||
|
/* Get the struct for the scoped struct name */
|
||||||
|
SymTable* Struct = ParseScopedSymTable (SYM_FIND_EXISTING);
|
||||||
|
|
||||||
|
/* Check if the given symbol is really a struct */
|
||||||
|
if (GetSymTabType (Struct) != ST_STRUCT) {
|
||||||
|
Error ("Argument to .SIZEOF is not a struct");
|
||||||
|
Size = 1;
|
||||||
|
} else {
|
||||||
|
Size = GetStructSize (Struct);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return the size */
|
||||||
|
return GenLiteralExpr (Size);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static ExprNode* FuncStrAt (void)
|
||||||
/* Handle the .STRAT function */
|
/* Handle the .STRAT function */
|
||||||
{
|
{
|
||||||
char Str [sizeof(SVal)];
|
char Str [sizeof(SVal)];
|
||||||
long Index;
|
long Index;
|
||||||
|
unsigned char C;
|
||||||
|
|
||||||
/* String constant expected */
|
/* String constant expected */
|
||||||
if (Tok != TOK_STRCON) {
|
if (Tok != TOK_STRCON) {
|
||||||
@@ -430,17 +454,22 @@ static int FuncStrAt (void)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return the char, handle as unsigned. Be sure to translate it into
|
/* Get the char, handle as unsigned. Be sure to translate it into
|
||||||
* the target character set.
|
* the target character set.
|
||||||
*/
|
*/
|
||||||
return (unsigned char) TgtTranslateChar (Str [(size_t)Index]);
|
C = TgtTranslateChar (Str [(size_t)Index]);
|
||||||
|
|
||||||
|
/* Return the char expression */
|
||||||
|
return GenLiteralExpr (C);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static int FuncStrLen (void)
|
static ExprNode* FuncStrLen (void)
|
||||||
/* Handle the .STRLEN function */
|
/* Handle the .STRLEN function */
|
||||||
{
|
{
|
||||||
|
int Len;
|
||||||
|
|
||||||
/* String constant expected */
|
/* String constant expected */
|
||||||
if (Tok != TOK_STRCON) {
|
if (Tok != TOK_STRCON) {
|
||||||
|
|
||||||
@@ -449,25 +478,24 @@ static int FuncStrLen (void)
|
|||||||
if (Tok != TOK_RPAREN) {
|
if (Tok != TOK_RPAREN) {
|
||||||
NextTok ();
|
NextTok ();
|
||||||
}
|
}
|
||||||
return 0;
|
Len = 0;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
/* Get the length of the string */
|
/* Get the length of the string */
|
||||||
int Len = strlen (SVal);
|
Len = strlen (SVal);
|
||||||
|
|
||||||
/* Skip the string */
|
/* Skip the string */
|
||||||
NextTok ();
|
NextTok ();
|
||||||
|
|
||||||
/* Return the length */
|
|
||||||
return Len;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Return the length */
|
||||||
|
return GenLiteralExpr (Len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static int FuncTCount (void)
|
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
|
||||||
@@ -500,12 +528,12 @@ static int FuncTCount (void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Return the number of tokens */
|
/* Return the number of tokens */
|
||||||
return Count;
|
return GenLiteralExpr (Count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static int FuncXMatch (void)
|
static ExprNode* FuncXMatch (void)
|
||||||
/* Handle the .XMATCH function */
|
/* Handle the .XMATCH function */
|
||||||
{
|
{
|
||||||
return DoMatch (tcIdentical);
|
return DoMatch (tcIdentical);
|
||||||
@@ -513,10 +541,10 @@ static int FuncXMatch (void)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
static ExprNode* Function (int (*F) (void))
|
static ExprNode* Function (ExprNode* (*F) (void))
|
||||||
/* Handle builtin functions */
|
/* Handle builtin functions */
|
||||||
{
|
{
|
||||||
long Result;
|
ExprNode* E;
|
||||||
|
|
||||||
/* Skip the keyword */
|
/* Skip the keyword */
|
||||||
NextTok ();
|
NextTok ();
|
||||||
@@ -530,13 +558,13 @@ static ExprNode* Function (int (*F) (void))
|
|||||||
NextTok ();
|
NextTok ();
|
||||||
|
|
||||||
/* Call the function itself */
|
/* Call the function itself */
|
||||||
Result = F ();
|
E = F ();
|
||||||
|
|
||||||
/* Closing brace must follow */
|
/* Closing brace must follow */
|
||||||
ConsumeRParen ();
|
ConsumeRParen ();
|
||||||
|
|
||||||
/* Return an expression node with the boolean code */
|
/* Return the result of the actual function */
|
||||||
return GenLiteralExpr (Result);
|
return E;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -682,6 +710,10 @@ static ExprNode* Factor (void)
|
|||||||
N = Function (FuncReferenced);
|
N = Function (FuncReferenced);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case TOK_SIZEOF:
|
||||||
|
N = Function (FuncSizeOf);
|
||||||
|
break;
|
||||||
|
|
||||||
case TOK_STRAT:
|
case TOK_STRAT:
|
||||||
N = Function (FuncStrAt);
|
N = Function (FuncStrAt);
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -1710,6 +1710,7 @@ static CtrlDesc CtrlCmdTab [] = {
|
|||||||
{ ccNone, DoScope },
|
{ ccNone, DoScope },
|
||||||
{ ccNone, DoSegment },
|
{ ccNone, DoSegment },
|
||||||
{ ccNone, DoSetCPU },
|
{ ccNone, DoSetCPU },
|
||||||
|
{ ccNone, DoUnexpected }, /* .SIZEOF */
|
||||||
{ ccNone, DoSmart },
|
{ ccNone, DoSmart },
|
||||||
{ ccNone, DoUnexpected }, /* .STRAT */
|
{ ccNone, DoUnexpected }, /* .STRAT */
|
||||||
{ ccNone, DoUnexpected }, /* .STRING */
|
{ ccNone, DoUnexpected }, /* .STRING */
|
||||||
|
|||||||
@@ -236,6 +236,7 @@ struct DotKeyword {
|
|||||||
{ ".SETCPU", TOK_SETCPU },
|
{ ".SETCPU", TOK_SETCPU },
|
||||||
{ ".SHL", TOK_SHL },
|
{ ".SHL", TOK_SHL },
|
||||||
{ ".SHR", TOK_SHR },
|
{ ".SHR", TOK_SHR },
|
||||||
|
{ ".SIZEOF", TOK_SIZEOF },
|
||||||
{ ".SMART", TOK_SMART },
|
{ ".SMART", TOK_SMART },
|
||||||
{ ".STRAT", TOK_STRAT },
|
{ ".STRAT", TOK_STRAT },
|
||||||
{ ".STRING", TOK_STRING },
|
{ ".STRING", TOK_STRING },
|
||||||
|
|||||||
@@ -215,6 +215,7 @@ enum Token {
|
|||||||
TOK_SCOPE,
|
TOK_SCOPE,
|
||||||
TOK_SEGMENT,
|
TOK_SEGMENT,
|
||||||
TOK_SETCPU,
|
TOK_SETCPU,
|
||||||
|
TOK_SIZEOF,
|
||||||
TOK_SMART,
|
TOK_SMART,
|
||||||
TOK_STRAT,
|
TOK_STRAT,
|
||||||
TOK_STRING,
|
TOK_STRING,
|
||||||
|
|||||||
Reference in New Issue
Block a user