From fd102deb77e555ed0615f3482823c27ae75f883a Mon Sep 17 00:00:00 2001 From: cuz Date: Fri, 12 Dec 2003 15:59:44 +0000 Subject: [PATCH] New pseudo functions: .LOBYTE, .HIBYTE, .BANKBYTE, .LOWORD, .HIWORD git-svn-id: svn://svn.cc65.org/cc65/trunk@2731 b7a2c559-68d2-44c3-8de9-860c34a00d81 --- src/ca65/expr.c | 187 +++++++++++++++++++++++++++++++++++++++------ src/ca65/pseudo.c | 5 ++ src/ca65/scanner.c | 7 +- src/ca65/scanner.h | 5 ++ 4 files changed, 179 insertions(+), 25 deletions(-) diff --git a/src/ca65/expr.c b/src/ca65/expr.c index d8f46f6bd..af3562b4f 100644 --- a/src/ca65/expr.c +++ b/src/ca65/expr.c @@ -196,6 +196,106 @@ static int IsEasyConst (const ExprNode* E, long* Val) +static ExprNode* LoByte (ExprNode* Operand) +/* Return the low byte of the given expression */ +{ + ExprNode* Expr; + long Val; + + /* Special handling for const expressions */ + if (IsEasyConst (Operand, &Val)) { + FreeExpr (Operand); + Expr = GenLiteralExpr (Val & 0xFF); + } else { + /* Extract byte #0 */ + Expr = NewExprNode (EXPR_BYTE0); + Expr->Left = Operand; + } + return Expr; +} + + + +static ExprNode* HiByte (ExprNode* Operand) +/* Return the high byte of the given expression */ +{ + ExprNode* Expr; + long Val; + + /* Special handling for const expressions */ + if (IsEasyConst (Operand, &Val)) { + FreeExpr (Operand); + Expr = GenLiteralExpr ((Val >> 8) & 0xFF); + } else { + /* Extract byte #1 */ + Expr = NewExprNode (EXPR_BYTE1); + Expr->Left = Operand; + } + return Expr; +} + + + +static ExprNode* BankByte (ExprNode* Operand) +/* Return the bank byte of the given expression */ +{ + ExprNode* Expr; + long Val; + + /* Special handling for const expressions */ + if (IsEasyConst (Operand, &Val)) { + FreeExpr (Operand); + Expr = GenLiteralExpr ((Val >> 16) & 0xFF); + } else { + /* Extract byte #2 */ + Expr = NewExprNode (EXPR_BYTE2); + Expr->Left = Operand; + } + return Expr; +} + + + +static ExprNode* LoWord (ExprNode* Operand) +/* Return the low word of the given expression */ +{ + ExprNode* Expr; + long Val; + + /* Special handling for const expressions */ + if (IsEasyConst (Operand, &Val)) { + FreeExpr (Operand); + Expr = GenLiteralExpr (Val & 0xFFFF); + } else { + /* Extract word #0 */ + Expr = NewExprNode (EXPR_WORD0); + Expr->Left = Operand; + } + return Expr; +} + + + +static ExprNode* HiWord (ExprNode* Operand) +/* Return the high word of the given expression */ +{ + ExprNode* Expr; + long Val; + + /* Special handling for const expressions */ + if (IsEasyConst (Operand, &Val)) { + FreeExpr (Operand); + Expr = GenLiteralExpr ((Val >> 16) & 0xFFFF); + } else { + /* Extract word #1 */ + Expr = NewExprNode (EXPR_WORD1); + Expr->Left = Operand; + } + return Expr; +} + + + static ExprNode* Symbol (SymEntry* S) /* Reference a symbol and return an expression for it */ { @@ -212,6 +312,14 @@ static ExprNode* Symbol (SymEntry* S) +static ExprNode* FuncBankByte (void) +/* Handle the .BANKBYTE builtin function */ +{ + return BankByte (Expression ()); +} + + + static ExprNode* FuncBlank (void) /* Handle the .BLANK builtin function */ { @@ -274,6 +382,38 @@ static ExprNode* FuncDefined (void) +static ExprNode* FuncHiByte (void) +/* Handle the .HIBYTE builtin function */ +{ + return HiByte (Expression ()); +} + + + +static ExprNode* FuncHiWord (void) +/* Handle the .HIWORD builtin function */ +{ + return HiWord (Expression ()); +} + + + +static ExprNode* FuncLoByte (void) +/* Handle the .LOBYTE builtin function */ +{ + return LoByte (Expression ()); +} + + + +static ExprNode* FuncLoWord (void) +/* Handle the .LOWORD builtin function */ +{ + return LoWord (Expression ()); +} + + + static ExprNode* DoMatch (enum TC EqualityLevel) /* Handle the .MATCH and .XMATCH builtin functions */ { @@ -687,38 +827,17 @@ static ExprNode* Factor (void) case TOK_LT: NextTok (); - L = Factor (); - if (IsEasyConst (L, &Val)) { - FreeExpr (L); - N = GenLiteralExpr (Val & 0xFF); - } else { - N = NewExprNode (EXPR_BYTE0); - N->Left = L; - } + N = LoByte (Factor ()); break; case TOK_GT: NextTok (); - L = Factor (); - if (IsEasyConst (L, &Val)) { - FreeExpr (L); - N = GenLiteralExpr ((Val >> 8) & 0xFF); - } else { - N = NewExprNode (EXPR_BYTE1); - N->Left = L; - } + N = HiByte (Factor ()); break; case TOK_BANK: NextTok (); - L = Factor (); - if (IsEasyConst (L, &Val)) { - FreeExpr (L); - N = GenLiteralExpr ((Val >> 16) & 0xFF); - } else { - N = NewExprNode (EXPR_BYTE2); - N->Left = L; - } + N = BankByte (Factor ()); break; case TOK_LPAREN: @@ -727,6 +846,10 @@ static ExprNode* Factor (void) ConsumeRParen (); break; + case TOK_BANKBYTE: + N = Function (FuncBankByte); + break; + case TOK_BLANK: N = Function (FuncBlank); break; @@ -744,6 +867,22 @@ static ExprNode* Factor (void) N = Function (FuncDefined); break; + case TOK_HIBYTE: + N = Function (FuncHiByte); + break; + + case TOK_HIWORD: + N = Function (FuncHiWord); + break; + + case TOK_LOBYTE: + N = Function (FuncLoByte); + break; + + case TOK_LOWORD: + N = Function (FuncLoWord); + break; + case TOK_MATCH: N = Function (FuncMatch); break; diff --git a/src/ca65/pseudo.c b/src/ca65/pseudo.c index 018232717..c0fcfcab8 100644 --- a/src/ca65/pseudo.c +++ b/src/ca65/pseudo.c @@ -1626,6 +1626,7 @@ static CtrlDesc CtrlCmdTab [] = { { ccNone, DoASCIIZ }, { ccNone, DoAssert }, { ccNone, DoAutoImport }, + { ccNone, DoUnexpected }, /* .BANKBYTE */ { ccNone, DoUnexpected }, /* .BLANK */ { ccNone, DoBss }, { ccNone, DoByte }, @@ -1668,6 +1669,8 @@ static CtrlDesc CtrlCmdTab [] = { { ccNone, DoUnexpected }, /* .FORCEWORD */ { ccNone, DoGlobal }, { ccNone, DoGlobalZP }, + { ccNone, DoUnexpected }, /* .HIBYTE */ + { ccNone, DoUnexpected }, /* .HIWORD */ { ccNone, DoI16 }, { ccNone, DoI8 }, { ccKeepToken, DoConditionals }, /* .IF */ @@ -1691,8 +1694,10 @@ static CtrlDesc CtrlCmdTab [] = { { ccNone, DoLineCont }, { ccNone, DoList }, { ccNone, DoListBytes }, + { ccNone, DoUnexpected }, /* .LOBYTE */ { ccNone, DoUnexpected }, /* .LOCAL */ { ccNone, DoLocalChar }, + { ccNone, DoUnexpected }, /* .LOWORD */ { ccNone, DoMacPack }, { ccNone, DoMacro }, { ccNone, DoUnexpected }, /* .MATCH */ diff --git a/src/ca65/scanner.c b/src/ca65/scanner.c index d06e3d0e7..8f9f940bf 100644 --- a/src/ca65/scanner.c +++ b/src/ca65/scanner.c @@ -126,6 +126,7 @@ struct DotKeyword { { ".ASCIIZ", TOK_ASCIIZ }, { ".ASSERT", TOK_ASSERT }, { ".AUTOIMPORT", TOK_AUTOIMPORT }, + { ".BANKBYTE", TOK_BANKBYTE }, { ".BITAND", TOK_AND }, { ".BITNOT", TOK_NOT }, { ".BITOR", TOK_OR }, @@ -178,6 +179,8 @@ struct DotKeyword { { ".FORCEWORD", TOK_FORCEWORD }, { ".GLOBAL", TOK_GLOBAL }, { ".GLOBALZP", TOK_GLOBALZP }, + { ".HIBYTE", TOK_HIBYTE }, + { ".HIWORD", TOK_HIWORD }, { ".I16", TOK_I16 }, { ".I8", TOK_I8 }, { ".IF", TOK_IF }, @@ -201,8 +204,10 @@ struct DotKeyword { { ".LINECONT", TOK_LINECONT }, { ".LIST", TOK_LIST }, { ".LISTBYTES", TOK_LISTBYTES }, + { ".LOBYTE", TOK_LOBYTE }, { ".LOCAL", TOK_LOCAL }, { ".LOCALCHAR", TOK_LOCALCHAR }, + { ".LOWORD", TOK_LOWORD }, { ".MAC", TOK_MACRO }, { ".MACPACK", TOK_MACPACK }, { ".MACRO", TOK_MACRO }, @@ -1127,7 +1132,7 @@ int GetSubKey (const char** Keys, unsigned Count) if (!IgnoreCase) { UpcaseSVal (); } - + /* Do a linear search (a binary search is not worth the effort) */ for (I = 0; I < Count; ++I) { if (strcmp (SVal, Keys [I]) == 0) { diff --git a/src/ca65/scanner.h b/src/ca65/scanner.h index c958e2464..bcc76c37e 100644 --- a/src/ca65/scanner.h +++ b/src/ca65/scanner.h @@ -124,6 +124,7 @@ enum Token { TOK_ASCIIZ, TOK_ASSERT, TOK_AUTOIMPORT, + TOK_BANKBYTE, TOK_BLANK, TOK_BSS, TOK_BYTE, @@ -166,6 +167,8 @@ enum Token { TOK_FORCEWORD, TOK_GLOBAL, TOK_GLOBALZP, + TOK_HIBYTE, + TOK_HIWORD, TOK_I16, TOK_I8, TOK_IF, @@ -189,8 +192,10 @@ enum Token { TOK_LINECONT, TOK_LIST, TOK_LISTBYTES, + TOK_LOBYTE, TOK_LOCAL, TOK_LOCALCHAR, + TOK_LOWORD, TOK_MACPACK, TOK_MACRO, TOK_MATCH, -- 2.39.5