Much improved error messages for ca65. For most errors it will now say what
was expected and what was found instead. Also improved error recovery in a few places.
This commit is contained in:
@@ -194,7 +194,7 @@ static void FreeIf (void)
|
|||||||
{
|
{
|
||||||
int Done;
|
int Done;
|
||||||
do {
|
do {
|
||||||
IfDesc* ID = GetCurrentIf();
|
IfDesc* ID = GetCurrentIf ();
|
||||||
if (ID == 0) {
|
if (ID == 0) {
|
||||||
Error (" Unexpected .ENDIF");
|
Error (" Unexpected .ENDIF");
|
||||||
Done = 1;
|
Done = 1;
|
||||||
@@ -318,7 +318,7 @@ void DoConditionals (void)
|
|||||||
D = AllocIf (".IFCONST", 1);
|
D = AllocIf (".IFCONST", 1);
|
||||||
NextTok ();
|
NextTok ();
|
||||||
if (IfCond) {
|
if (IfCond) {
|
||||||
ExprNode* Expr = Expression();
|
ExprNode* Expr = Expression ();
|
||||||
SetIfCond (D, IsConstExpr (Expr, 0));
|
SetIfCond (D, IsConstExpr (Expr, 0));
|
||||||
FreeExpr (Expr);
|
FreeExpr (Expr);
|
||||||
ExpectSep ();
|
ExpectSep ();
|
||||||
@@ -354,7 +354,7 @@ void DoConditionals (void)
|
|||||||
D = AllocIf (".IFNCONST", 1);
|
D = AllocIf (".IFNCONST", 1);
|
||||||
NextTok ();
|
NextTok ();
|
||||||
if (IfCond) {
|
if (IfCond) {
|
||||||
ExprNode* Expr = Expression();
|
ExprNode* Expr = Expression ();
|
||||||
SetIfCond (D, !IsConstExpr (Expr, 0));
|
SetIfCond (D, !IsConstExpr (Expr, 0));
|
||||||
FreeExpr (Expr);
|
FreeExpr (Expr);
|
||||||
ExpectSep ();
|
ExpectSep ();
|
||||||
@@ -388,7 +388,7 @@ void DoConditionals (void)
|
|||||||
D = AllocIf (".IFP02", 1);
|
D = AllocIf (".IFP02", 1);
|
||||||
NextTok ();
|
NextTok ();
|
||||||
if (IfCond) {
|
if (IfCond) {
|
||||||
SetIfCond (D, GetCPU() == CPU_6502);
|
SetIfCond (D, GetCPU () == CPU_6502);
|
||||||
}
|
}
|
||||||
ExpectSep ();
|
ExpectSep ();
|
||||||
CalcOverallIfCond ();
|
CalcOverallIfCond ();
|
||||||
@@ -398,7 +398,7 @@ void DoConditionals (void)
|
|||||||
D = AllocIf (".IFP02X", 1);
|
D = AllocIf (".IFP02X", 1);
|
||||||
NextTok ();
|
NextTok ();
|
||||||
if (IfCond) {
|
if (IfCond) {
|
||||||
SetIfCond (D, GetCPU() == CPU_6502X);
|
SetIfCond (D, GetCPU () == CPU_6502X);
|
||||||
}
|
}
|
||||||
ExpectSep ();
|
ExpectSep ();
|
||||||
CalcOverallIfCond ();
|
CalcOverallIfCond ();
|
||||||
@@ -408,7 +408,7 @@ void DoConditionals (void)
|
|||||||
D = AllocIf (".IFP4510", 1);
|
D = AllocIf (".IFP4510", 1);
|
||||||
NextTok ();
|
NextTok ();
|
||||||
if (IfCond) {
|
if (IfCond) {
|
||||||
SetIfCond (D, GetCPU() == CPU_4510);
|
SetIfCond (D, GetCPU () == CPU_4510);
|
||||||
}
|
}
|
||||||
ExpectSep ();
|
ExpectSep ();
|
||||||
CalcOverallIfCond ();
|
CalcOverallIfCond ();
|
||||||
@@ -418,7 +418,7 @@ void DoConditionals (void)
|
|||||||
D = AllocIf (".IFP45GS02", 1);
|
D = AllocIf (".IFP45GS02", 1);
|
||||||
NextTok ();
|
NextTok ();
|
||||||
if (IfCond) {
|
if (IfCond) {
|
||||||
SetIfCond (D, GetCPU() == CPU_45GS02);
|
SetIfCond (D, GetCPU () == CPU_45GS02);
|
||||||
}
|
}
|
||||||
ExpectSep ();
|
ExpectSep ();
|
||||||
CalcOverallIfCond ();
|
CalcOverallIfCond ();
|
||||||
@@ -428,7 +428,7 @@ void DoConditionals (void)
|
|||||||
D = AllocIf (".IFP6280", 1);
|
D = AllocIf (".IFP6280", 1);
|
||||||
NextTok ();
|
NextTok ();
|
||||||
if (IfCond) {
|
if (IfCond) {
|
||||||
SetIfCond (D, GetCPU() == CPU_HUC6280);
|
SetIfCond (D, GetCPU () == CPU_HUC6280);
|
||||||
}
|
}
|
||||||
ExpectSep ();
|
ExpectSep ();
|
||||||
CalcOverallIfCond ();
|
CalcOverallIfCond ();
|
||||||
@@ -438,7 +438,7 @@ void DoConditionals (void)
|
|||||||
D = AllocIf (".IFP816", 1);
|
D = AllocIf (".IFP816", 1);
|
||||||
NextTok ();
|
NextTok ();
|
||||||
if (IfCond) {
|
if (IfCond) {
|
||||||
SetIfCond (D, GetCPU() == CPU_65816);
|
SetIfCond (D, GetCPU () == CPU_65816);
|
||||||
}
|
}
|
||||||
ExpectSep ();
|
ExpectSep ();
|
||||||
CalcOverallIfCond ();
|
CalcOverallIfCond ();
|
||||||
@@ -448,7 +448,7 @@ void DoConditionals (void)
|
|||||||
D = AllocIf (".IFPC02", 1);
|
D = AllocIf (".IFPC02", 1);
|
||||||
NextTok ();
|
NextTok ();
|
||||||
if (IfCond) {
|
if (IfCond) {
|
||||||
SetIfCond (D, GetCPU() == CPU_65C02);
|
SetIfCond (D, GetCPU () == CPU_65C02);
|
||||||
}
|
}
|
||||||
ExpectSep ();
|
ExpectSep ();
|
||||||
CalcOverallIfCond ();
|
CalcOverallIfCond ();
|
||||||
@@ -458,7 +458,7 @@ void DoConditionals (void)
|
|||||||
D = AllocIf (".IFPCE02", 1);
|
D = AllocIf (".IFPCE02", 1);
|
||||||
NextTok ();
|
NextTok ();
|
||||||
if (IfCond) {
|
if (IfCond) {
|
||||||
SetIfCond (D, GetCPU() == CPU_65CE02);
|
SetIfCond (D, GetCPU () == CPU_65CE02);
|
||||||
}
|
}
|
||||||
ExpectSep ();
|
ExpectSep ();
|
||||||
CalcOverallIfCond ();
|
CalcOverallIfCond ();
|
||||||
@@ -468,7 +468,7 @@ void DoConditionals (void)
|
|||||||
D = AllocIf (".IFPDTV", 1);
|
D = AllocIf (".IFPDTV", 1);
|
||||||
NextTok ();
|
NextTok ();
|
||||||
if (IfCond) {
|
if (IfCond) {
|
||||||
SetIfCond (D, GetCPU() == CPU_6502DTV);
|
SetIfCond (D, GetCPU () == CPU_6502DTV);
|
||||||
}
|
}
|
||||||
ExpectSep ();
|
ExpectSep ();
|
||||||
CalcOverallIfCond ();
|
CalcOverallIfCond ();
|
||||||
@@ -478,7 +478,7 @@ void DoConditionals (void)
|
|||||||
D = AllocIf (".IFPM740", 1);
|
D = AllocIf (".IFPM740", 1);
|
||||||
NextTok ();
|
NextTok ();
|
||||||
if (IfCond) {
|
if (IfCond) {
|
||||||
SetIfCond (D, GetCPU() == CPU_M740);
|
SetIfCond (D, GetCPU () == CPU_M740);
|
||||||
}
|
}
|
||||||
ExpectSep ();
|
ExpectSep ();
|
||||||
CalcOverallIfCond ();
|
CalcOverallIfCond ();
|
||||||
@@ -488,7 +488,7 @@ void DoConditionals (void)
|
|||||||
D = AllocIf (".IFPSC02", 1);
|
D = AllocIf (".IFPSC02", 1);
|
||||||
NextTok ();
|
NextTok ();
|
||||||
if (IfCond) {
|
if (IfCond) {
|
||||||
SetIfCond (D, GetCPU() == CPU_65SC02);
|
SetIfCond (D, GetCPU () == CPU_65SC02);
|
||||||
}
|
}
|
||||||
ExpectSep ();
|
ExpectSep ();
|
||||||
CalcOverallIfCond ();
|
CalcOverallIfCond ();
|
||||||
@@ -498,7 +498,7 @@ void DoConditionals (void)
|
|||||||
D = AllocIf (".IFPSWEET16", 1);
|
D = AllocIf (".IFPSWEET16", 1);
|
||||||
NextTok ();
|
NextTok ();
|
||||||
if (IfCond) {
|
if (IfCond) {
|
||||||
SetIfCond (D, GetCPU() == CPU_SWEET16);
|
SetIfCond (D, GetCPU () == CPU_SWEET16);
|
||||||
}
|
}
|
||||||
ExpectSep ();
|
ExpectSep ();
|
||||||
CalcOverallIfCond ();
|
CalcOverallIfCond ();
|
||||||
@@ -508,7 +508,7 @@ void DoConditionals (void)
|
|||||||
D = AllocIf (".IFPWC02", 1);
|
D = AllocIf (".IFPWC02", 1);
|
||||||
NextTok ();
|
NextTok ();
|
||||||
if (IfCond) {
|
if (IfCond) {
|
||||||
SetIfCond (D, GetCPU() == CPU_W65C02);
|
SetIfCond (D, GetCPU () == CPU_W65C02);
|
||||||
}
|
}
|
||||||
ExpectSep ();
|
ExpectSep ();
|
||||||
CalcOverallIfCond ();
|
CalcOverallIfCond ();
|
||||||
|
|||||||
@@ -238,8 +238,7 @@ void DbgInfoFunc (void)
|
|||||||
ConsumeComma ();
|
ConsumeComma ();
|
||||||
|
|
||||||
/* Type */
|
/* Type */
|
||||||
if (CurTok.Tok != TOK_STRCON) {
|
if (!ExpectSkip (TOK_STRCON, "Expected a string constant")) {
|
||||||
ErrorSkip ("String constant expected");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Type = ValidateType (&CurTok.SVal);
|
Type = ValidateType (&CurTok.SVal);
|
||||||
@@ -267,8 +266,7 @@ void DbgInfoFunc (void)
|
|||||||
ConsumeComma ();
|
ConsumeComma ();
|
||||||
|
|
||||||
/* Assembler name follows */
|
/* Assembler name follows */
|
||||||
if (CurTok.Tok != TOK_STRCON) {
|
if (!ExpectSkip (TOK_STRCON, "Expected a string constant")) {
|
||||||
ErrorSkip ("String constant expected");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
AsmName = GetStrBufId (&CurTok.SVal);
|
AsmName = GetStrBufId (&CurTok.SVal);
|
||||||
@@ -321,8 +319,7 @@ void DbgInfoLine (void)
|
|||||||
ConsumeComma ();
|
ConsumeComma ();
|
||||||
|
|
||||||
/* The name of the file follows */
|
/* The name of the file follows */
|
||||||
if (CurTok.Tok != TOK_STRCON) {
|
if (!ExpectSkip (TOK_STRCON, "Expected a string constant")) {
|
||||||
ErrorSkip ("String constant expected");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -371,8 +368,7 @@ void DbgInfoSym (void)
|
|||||||
ConsumeComma ();
|
ConsumeComma ();
|
||||||
|
|
||||||
/* Name */
|
/* Name */
|
||||||
if (CurTok.Tok != TOK_STRCON) {
|
if (!ExpectSkip (TOK_STRCON, "Expected a string constant")) {
|
||||||
ErrorSkip ("String constant expected");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Name = GetStrBufId (&CurTok.SVal);
|
Name = GetStrBufId (&CurTok.SVal);
|
||||||
@@ -382,8 +378,7 @@ void DbgInfoSym (void)
|
|||||||
ConsumeComma ();
|
ConsumeComma ();
|
||||||
|
|
||||||
/* Type */
|
/* Type */
|
||||||
if (CurTok.Tok != TOK_STRCON) {
|
if (!ExpectSkip (TOK_STRCON, "Expected a string constant")) {
|
||||||
ErrorSkip ("String constant expected");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Type = ValidateType (&CurTok.SVal);
|
Type = ValidateType (&CurTok.SVal);
|
||||||
@@ -418,8 +413,7 @@ void DbgInfoSym (void)
|
|||||||
Offs = ConstExpression ();
|
Offs = ConstExpression ();
|
||||||
} else {
|
} else {
|
||||||
/* Register, extern or static: Assembler name follows */
|
/* Register, extern or static: Assembler name follows */
|
||||||
if (CurTok.Tok != TOK_STRCON) {
|
if (!ExpectSkip (TOK_STRCON, "Expected a string constant")) {
|
||||||
ErrorSkip ("String constant expected");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
AsmName = GetStrBufId (&CurTok.SVal);
|
AsmName = GetStrBufId (&CurTok.SVal);
|
||||||
|
|||||||
@@ -62,11 +62,11 @@ void GetEA (EffAddr* A)
|
|||||||
if (BracketAsIndirect) {
|
if (BracketAsIndirect) {
|
||||||
IndirectEnter = TOK_LBRACK;
|
IndirectEnter = TOK_LBRACK;
|
||||||
IndirectLeave = TOK_RBRACK;
|
IndirectLeave = TOK_RBRACK;
|
||||||
IndirectExpect = "']' expected";
|
IndirectExpect = "Expected ']'";
|
||||||
} else {
|
} else {
|
||||||
IndirectEnter = TOK_LPAREN;
|
IndirectEnter = TOK_LPAREN;
|
||||||
IndirectLeave = TOK_RPAREN;
|
IndirectLeave = TOK_RPAREN;
|
||||||
IndirectExpect = "')' expected";
|
IndirectExpect = "Expected ')'";
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Clear the output struct */
|
/* Clear the output struct */
|
||||||
@@ -136,16 +136,22 @@ void GetEA (EffAddr* A)
|
|||||||
/* (adr,x) */
|
/* (adr,x) */
|
||||||
NextTok ();
|
NextTok ();
|
||||||
A->AddrModeSet = AM65_ABS_X_IND | AM65_DIR_X_IND;
|
A->AddrModeSet = AM65_ABS_X_IND | AM65_DIR_X_IND;
|
||||||
Consume (IndirectLeave, IndirectExpect);
|
if (!Consume (IndirectLeave, IndirectExpect)) {
|
||||||
|
SkipUntilSep ();
|
||||||
|
}
|
||||||
} else if (CurTok.Tok == TOK_S) {
|
} else if (CurTok.Tok == TOK_S) {
|
||||||
/* (rel,s),y */
|
/* (rel,s),y */
|
||||||
NextTok ();
|
NextTok ();
|
||||||
A->AddrModeSet = AM65_STACK_REL_IND_Y;
|
A->AddrModeSet = AM65_STACK_REL_IND_Y;
|
||||||
Consume (IndirectLeave, IndirectExpect);
|
if (!Consume (IndirectLeave, IndirectExpect) ||
|
||||||
ConsumeComma ();
|
!ConsumeComma () ||
|
||||||
Consume (TOK_Y, "'Y' expected");
|
!Consume (TOK_Y, "Expected 'Y'")) {
|
||||||
|
/* In case of errors skip anything else on the line */
|
||||||
|
SkipUntilSep ();
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
Error ("Syntax error");
|
ErrorExpect ("Expected 'X' or 'S'");
|
||||||
|
SkipUntilSep ();
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
@@ -162,7 +168,9 @@ void GetEA (EffAddr* A)
|
|||||||
A->AddrModeSet = AM65_DIR_IND;
|
A->AddrModeSet = AM65_DIR_IND;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
Consume (TOK_Y, "'Y' expected");
|
if (!Consume (TOK_Y, "Expected 'Y'")) {
|
||||||
|
SkipUntilSep ();
|
||||||
|
}
|
||||||
A->AddrModeSet = AM65_DIR_IND_Y;
|
A->AddrModeSet = AM65_DIR_IND_Y;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -190,16 +198,22 @@ void GetEA (EffAddr* A)
|
|||||||
/* [dir] or [dir],y */
|
/* [dir] or [dir],y */
|
||||||
NextTok ();
|
NextTok ();
|
||||||
A->Expr = Expression ();
|
A->Expr = Expression ();
|
||||||
Consume (TOK_RBRACK, "']' expected");
|
if (!Consume (TOK_RBRACK, "Expected ']'")) {
|
||||||
|
SkipUntilSep ();
|
||||||
|
}
|
||||||
if (CurTok.Tok == TOK_COMMA) {
|
if (CurTok.Tok == TOK_COMMA) {
|
||||||
/* [dir],y */
|
/* [dir],y */
|
||||||
NextTok ();
|
NextTok ();
|
||||||
if (GetCPU () == CPU_45GS02) {
|
if (GetCPU () == CPU_45GS02) {
|
||||||
Consume (TOK_Z, "'Z' expected");
|
if (!Consume (TOK_Z, "Expected 'Z'")) {
|
||||||
|
SkipUntilSep ();
|
||||||
|
}
|
||||||
A->AddrModeSet = AM65_32BIT_BASE_IND_Z;
|
A->AddrModeSet = AM65_32BIT_BASE_IND_Z;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Consume (TOK_Y, "'Y' expected");
|
if (!Consume (TOK_Y, "Expected 'Y'")) {
|
||||||
|
SkipUntilSep ();
|
||||||
|
}
|
||||||
A->AddrModeSet = AM65_DIR_IND_LONG_Y;
|
A->AddrModeSet = AM65_DIR_IND_LONG_Y;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ void GetSweet16EA (EffAddr* A)
|
|||||||
/* Register number */
|
/* Register number */
|
||||||
A->Reg = (unsigned) Reg;
|
A->Reg = (unsigned) Reg;
|
||||||
} else {
|
} else {
|
||||||
ErrorSkip ("Register or register number expected");
|
ErrorExpect ("Expected register or register number");
|
||||||
A->Reg = 0;
|
A->Reg = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -87,12 +87,13 @@ void DoEnum (void)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Allow conditionals within an enum */
|
||||||
|
if (CheckConditionals ()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
/* The format is "identifier [ = value ]" */
|
/* The format is "identifier [ = value ]" */
|
||||||
if (CurTok.Tok != TOK_IDENT) {
|
if (!ExpectSkip (TOK_IDENT, "Expected an identifier")) {
|
||||||
/* Maybe it's a conditional? */
|
|
||||||
if (!CheckConditionals ()) {
|
|
||||||
ErrorSkip ("Identifier expected");
|
|
||||||
}
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -421,8 +421,7 @@ static ExprNode* FuncCapability (void)
|
|||||||
capability_t Cap;
|
capability_t Cap;
|
||||||
|
|
||||||
/* We must have an identifier */
|
/* We must have an identifier */
|
||||||
if (CurTok.Tok != TOK_IDENT) {
|
if (!Expect (TOK_IDENT, "Expected a capability name")) {
|
||||||
Error ("Arguments to .CAPABILITY must be identifiers");
|
|
||||||
/* Skip tokens until closing paren or end of line */
|
/* Skip tokens until closing paren or end of line */
|
||||||
while (CurTok.Tok != TOK_RPAREN && !TokIsSep (CurTok.Tok)) {
|
while (CurTok.Tok != TOK_RPAREN && !TokIsSep (CurTok.Tok)) {
|
||||||
NextTok ();
|
NextTok ();
|
||||||
@@ -942,8 +941,7 @@ static ExprNode* FuncStrAt (void)
|
|||||||
unsigned char C = 0;
|
unsigned char C = 0;
|
||||||
|
|
||||||
/* String constant expected */
|
/* String constant expected */
|
||||||
if (CurTok.Tok != TOK_STRCON) {
|
if (!Expect (TOK_STRCON, "Expected a string constant")) {
|
||||||
Error ("String constant expected");
|
|
||||||
NextTok ();
|
NextTok ();
|
||||||
goto ExitPoint;
|
goto ExitPoint;
|
||||||
}
|
}
|
||||||
@@ -985,9 +983,8 @@ static ExprNode* FuncStrLen (void)
|
|||||||
int Len;
|
int Len;
|
||||||
|
|
||||||
/* String constant expected */
|
/* String constant expected */
|
||||||
if (CurTok.Tok != TOK_STRCON) {
|
if (!Expect (TOK_STRCON, "Expected a string constant")) {
|
||||||
|
|
||||||
Error ("String constant expected");
|
|
||||||
/* Smart error recovery */
|
/* Smart error recovery */
|
||||||
if (CurTok.Tok != TOK_RPAREN) {
|
if (CurTok.Tok != TOK_RPAREN) {
|
||||||
NextTok ();
|
NextTok ();
|
||||||
@@ -1062,9 +1059,7 @@ static ExprNode* Function (ExprNode* (*F) (void))
|
|||||||
NextTok ();
|
NextTok ();
|
||||||
|
|
||||||
/* Expression must be enclosed in braces */
|
/* Expression must be enclosed in braces */
|
||||||
if (CurTok.Tok != TOK_LPAREN) {
|
if (!ExpectSkip (TOK_LPAREN, "Expected '('")) {
|
||||||
Error ("'(' expected");
|
|
||||||
SkipUntilSep ();
|
|
||||||
return GenLiteral0 ();
|
return GenLiteral0 ();
|
||||||
}
|
}
|
||||||
NextTok ();
|
NextTok ();
|
||||||
@@ -1296,7 +1291,7 @@ static ExprNode* Factor (void)
|
|||||||
NextTok ();
|
NextTok ();
|
||||||
} else {
|
} else {
|
||||||
N = GenLiteral0 (); /* Dummy */
|
N = GenLiteral0 (); /* Dummy */
|
||||||
Error ("Syntax error");
|
ErrorExpect ("Expected an expression");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1957,9 +1952,8 @@ ExprNode* GenNearAddrExpr (ExprNode* Expr)
|
|||||||
if (IsEasyConst (Expr, &Val)) {
|
if (IsEasyConst (Expr, &Val)) {
|
||||||
FreeExpr (Expr);
|
FreeExpr (Expr);
|
||||||
Expr = GenLiteralExpr (Val & 0xFFFF);
|
Expr = GenLiteralExpr (Val & 0xFFFF);
|
||||||
if (Val > 0xFFFF)
|
if (Val > 0xFFFF) {
|
||||||
{
|
Error ("Range error: constant too large for assumed near address.");
|
||||||
Error("Range error: constant too large for assumed near address.");
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ExprNode* Operand = Expr;
|
ExprNode* Operand = Expr;
|
||||||
|
|||||||
@@ -2091,7 +2091,7 @@ static void PutBitBranch_m740 (const InsDesc* Ins)
|
|||||||
EffAddr A;
|
EffAddr A;
|
||||||
|
|
||||||
/* Evaluate the addressing mode used */
|
/* Evaluate the addressing mode used */
|
||||||
GetEA(&A);
|
GetEA (&A);
|
||||||
|
|
||||||
/* From the possible addressing modes, remove the ones that are invalid
|
/* From the possible addressing modes, remove the ones that are invalid
|
||||||
** for this instruction or CPU.
|
** for this instruction or CPU.
|
||||||
@@ -2375,7 +2375,7 @@ static void PutJSR_m740 (const InsDesc* Ins)
|
|||||||
/* direct page */
|
/* direct page */
|
||||||
A.Opcode = 0x22;
|
A.Opcode = 0x22;
|
||||||
Emit0 (A.Opcode);
|
Emit0 (A.Opcode);
|
||||||
EmitByte(GenByteExpr(A.Expr));
|
EmitByte (GenByteExpr (A.Expr));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -406,11 +406,11 @@ void MacDef (unsigned Style)
|
|||||||
Pos = CurTok.Pos;
|
Pos = CurTok.Pos;
|
||||||
|
|
||||||
/* We expect a macro name here */
|
/* We expect a macro name here */
|
||||||
if (CurTok.Tok != TOK_IDENT) {
|
if (!Expect (TOK_IDENT, "Expected an identifier")) {
|
||||||
Error ("Identifier expected");
|
|
||||||
MacSkipDef (Style);
|
MacSkipDef (Style);
|
||||||
return;
|
return;
|
||||||
} else if (!UbiquitousIdents && FindInstruction (&CurTok.SVal) >= 0) {
|
}
|
||||||
|
if (!UbiquitousIdents && FindInstruction (&CurTok.SVal) >= 0) {
|
||||||
/* The identifier is a name of a 6502 instruction, which is not
|
/* The identifier is a name of a 6502 instruction, which is not
|
||||||
** allowed if not explicitly enabled.
|
** allowed if not explicitly enabled.
|
||||||
*/
|
*/
|
||||||
@@ -439,7 +439,7 @@ void MacDef (unsigned Style)
|
|||||||
** otherwise, we may have parameters without parentheses.
|
** otherwise, we may have parameters without parentheses.
|
||||||
*/
|
*/
|
||||||
if (Style == MAC_STYLE_CLASSIC) {
|
if (Style == MAC_STYLE_CLASSIC) {
|
||||||
HaveParams = 1;
|
HaveParams = (CurTok.Tok != TOK_SEP);
|
||||||
} else {
|
} else {
|
||||||
if (CurTok.Tok == TOK_LPAREN) {
|
if (CurTok.Tok == TOK_LPAREN) {
|
||||||
HaveParams = 1;
|
HaveParams = 1;
|
||||||
@@ -451,7 +451,7 @@ void MacDef (unsigned Style)
|
|||||||
|
|
||||||
/* Parse the parameter list */
|
/* Parse the parameter list */
|
||||||
if (HaveParams) {
|
if (HaveParams) {
|
||||||
while (CurTok.Tok == TOK_IDENT) {
|
while (Expect (TOK_IDENT, "Expected a parameter name")) {
|
||||||
/* Create a struct holding the identifier */
|
/* Create a struct holding the identifier */
|
||||||
IdDesc* I = NewIdDesc (&CurTok.SVal);
|
IdDesc* I = NewIdDesc (&CurTok.SVal);
|
||||||
|
|
||||||
@@ -533,7 +533,7 @@ void MacDef (unsigned Style)
|
|||||||
|
|
||||||
/* Need an identifer */
|
/* Need an identifer */
|
||||||
if (CurTok.Tok != TOK_IDENT && CurTok.Tok != TOK_LOCAL_IDENT) {
|
if (CurTok.Tok != TOK_IDENT && CurTok.Tok != TOK_LOCAL_IDENT) {
|
||||||
Error ("Identifier expected");
|
ErrorExpect ("Expected an identifier");
|
||||||
SkipUntilSep ();
|
SkipUntilSep ();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -591,7 +591,7 @@ void MacDef (unsigned Style)
|
|||||||
/* Save if last token was a separator to know if .endmacro is at
|
/* Save if last token was a separator to know if .endmacro is at
|
||||||
** the start of a line
|
** the start of a line
|
||||||
*/
|
*/
|
||||||
LastTokWasSep = TokIsSep(CurTok.Tok);
|
LastTokWasSep = TokIsSep (CurTok.Tok);
|
||||||
|
|
||||||
/* Read the next token */
|
/* Read the next token */
|
||||||
NextTok ();
|
NextTok ();
|
||||||
@@ -938,10 +938,8 @@ static void StartExpDefine (MacExp* E)
|
|||||||
|
|
||||||
/* Check for a comma */
|
/* Check for a comma */
|
||||||
if (Count > 0) {
|
if (Count > 0) {
|
||||||
if (CurTok.Tok == TOK_COMMA) {
|
if (Expect (TOK_COMMA, "Expected ','")) {
|
||||||
NextTok ();
|
NextTok ();
|
||||||
} else {
|
|
||||||
Error ("',' expected");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -145,7 +145,7 @@ static void SetOptions (void)
|
|||||||
OptTranslator (&Buf);
|
OptTranslator (&Buf);
|
||||||
|
|
||||||
/* Set date and time */
|
/* Set date and time */
|
||||||
OptDateTime ((unsigned long) time(0));
|
OptDateTime ((unsigned long) time (0));
|
||||||
|
|
||||||
/* Release memory for the string */
|
/* Release memory for the string */
|
||||||
SB_Done (&Buf);
|
SB_Done (&Buf);
|
||||||
@@ -708,7 +708,7 @@ static void OptVersion (const char* Opt attribute ((unused)),
|
|||||||
/* Print the assembler version */
|
/* Print the assembler version */
|
||||||
{
|
{
|
||||||
fprintf (stderr, "%s V%s\n", ProgName, GetVersionAsString ());
|
fprintf (stderr, "%s V%s\n", ProgName, GetVersionAsString ());
|
||||||
exit(EXIT_SUCCESS);
|
exit (EXIT_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -727,7 +727,7 @@ static void DoPCAssign (void)
|
|||||||
{
|
{
|
||||||
long PC = ConstExpression ();
|
long PC = ConstExpression ();
|
||||||
if (PC < 0 || PC > 0xFFFFFF) {
|
if (PC < 0 || PC > 0xFFFFFF) {
|
||||||
Error ("Range error");
|
Error ("Program counter value is out of valid range");
|
||||||
} else {
|
} else {
|
||||||
EnterAbsoluteMode (PC);
|
EnterAbsoluteMode (PC);
|
||||||
}
|
}
|
||||||
@@ -820,11 +820,10 @@ static void OneLine (void)
|
|||||||
NextTok ();
|
NextTok ();
|
||||||
|
|
||||||
/* Define the symbol with the expression following the '=' */
|
/* Define the symbol with the expression following the '=' */
|
||||||
SymDef (Sym, Expression(), ADDR_SIZE_DEFAULT, Flags);
|
SymDef (Sym, Expression (), ADDR_SIZE_DEFAULT, Flags);
|
||||||
|
|
||||||
/* Don't allow anything after a symbol definition */
|
/* Don't allow anything after a symbol definition */
|
||||||
ConsumeSep ();
|
goto Done;
|
||||||
return;
|
|
||||||
|
|
||||||
} else if (CurTok.Tok == TOK_SET) {
|
} else if (CurTok.Tok == TOK_SET) {
|
||||||
|
|
||||||
@@ -842,8 +841,7 @@ static void OneLine (void)
|
|||||||
SymDef (Sym, Expr, ADDR_SIZE_DEFAULT, SF_VAR);
|
SymDef (Sym, Expr, ADDR_SIZE_DEFAULT, SF_VAR);
|
||||||
|
|
||||||
/* Don't allow anything after a symbol definition */
|
/* Don't allow anything after a symbol definition */
|
||||||
ConsumeSep ();
|
goto Done;
|
||||||
return;
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
@@ -859,7 +857,8 @@ static void OneLine (void)
|
|||||||
*/
|
*/
|
||||||
if (CurTok.Tok != TOK_COLON) {
|
if (CurTok.Tok != TOK_COLON) {
|
||||||
if (HadWS || !NoColonLabels) {
|
if (HadWS || !NoColonLabels) {
|
||||||
ErrorSkip ("Expected ':' after identifier to form a label");
|
ErrorExpect ("Expected ':' after identifier to form a label");
|
||||||
|
SkipUntilSep ();
|
||||||
goto Done;
|
goto Done;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -903,17 +902,23 @@ static void OneLine (void)
|
|||||||
HandleInstruction (Instr);
|
HandleInstruction (Instr);
|
||||||
} else if (PCAssignment && (CurTok.Tok == TOK_STAR || CurTok.Tok == TOK_PC)) {
|
} else if (PCAssignment && (CurTok.Tok == TOK_STAR || CurTok.Tok == TOK_PC)) {
|
||||||
NextTok ();
|
NextTok ();
|
||||||
if (CurTok.Tok != TOK_EQ) {
|
if (!ExpectSkip (TOK_EQ, "Expected '='")) {
|
||||||
ErrorSkip ("'=' expected");
|
|
||||||
goto Done;
|
goto Done;
|
||||||
} else {
|
|
||||||
/* Skip the equal sign */
|
|
||||||
NextTok ();
|
|
||||||
/* Enter absolute mode */
|
|
||||||
DoPCAssign ();
|
|
||||||
}
|
}
|
||||||
|
/* Skip the equal sign */
|
||||||
|
NextTok ();
|
||||||
|
/* Enter absolute mode */
|
||||||
|
DoPCAssign ();
|
||||||
|
} else if ((CurTok.Tok >= TOK_FIRSTOP && CurTok.Tok <= TOK_LASTOP) ||
|
||||||
|
(CurTok.Tok >= TOK_FIRSTREG && CurTok.Tok <= TOK_LASTREG) ||
|
||||||
|
CurTok.Tok == TOK_INTCON || CurTok.Tok == TOK_CHARCON ||
|
||||||
|
CurTok.Tok == TOK_STRCON) {
|
||||||
|
ErrorExpect ("Expected a mnemonic");
|
||||||
|
SkipUntilSep ();
|
||||||
|
goto Done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* If we have defined a label, remember its size. Sym is also set by
|
/* If we have defined a label, remember its size. Sym is also set by
|
||||||
** a symbol assignment, but in this case Done is false, so we don't
|
** a symbol assignment, but in this case Done is false, so we don't
|
||||||
** come here.
|
** come here.
|
||||||
@@ -1233,7 +1238,7 @@ int main (int argc, char* argv [])
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (WarningCount > 0 && WarningsAsErrors) {
|
if (WarningCount > 0 && WarningsAsErrors) {
|
||||||
Error("Warnings as errors");
|
Error ("Warnings as errors");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If we didn't have an errors, finish off the line infos */
|
/* If we didn't have an errors, finish off the line infos */
|
||||||
|
|||||||
@@ -725,52 +725,118 @@ void NextTok (void)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void Consume (token_t Expected, const char* ErrMsg)
|
void ErrorExpect (const char* Msg)
|
||||||
/* Consume Expected, print an error if we don't find it */
|
/* Output an error message about some expected token using Msg and the
|
||||||
|
* description of the following token. This means that Msg should contain
|
||||||
|
* something like "xyz expected". The actual error message would the be
|
||||||
|
* "xyz expected but found zyx".
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
StrBuf S = AUTO_STRBUF_INITIALIZER;
|
||||||
|
TokenDesc (&CurTok, &S);
|
||||||
|
Error ("%s but found '%s'", Msg, SB_GetConstBuf (&S));
|
||||||
|
SB_Done (&S);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int Expect (token_t Expected, const char* Msg)
|
||||||
|
/* Check if the next token is the expected one. If not, print Msg plus some
|
||||||
|
* information about the token that was actually found. This means that Msg
|
||||||
|
* should contain something like "xyz expected". The actual error message would
|
||||||
|
* the be "xyz expected but found zyx".
|
||||||
|
* Returns true if the token was found, otherwise false.
|
||||||
|
*/
|
||||||
{
|
{
|
||||||
if (CurTok.Tok == Expected) {
|
if (CurTok.Tok == Expected) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ErrorExpect (Msg);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int ExpectSkip (token_t Expected, const char* Msg)
|
||||||
|
/* Check if the next token is the expected one. If not, print Msg plus some
|
||||||
|
* information about the token that was actually found and skip the remainder
|
||||||
|
* of the line. This means that Msg should contain something like "xyz
|
||||||
|
* expected". The actual error message would the be "xyz expected but found
|
||||||
|
* zyx".
|
||||||
|
* Returns true if the token was found, otherwise false.
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
if (CurTok.Tok == Expected) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ErrorExpect (Msg);
|
||||||
|
SkipUntilSep ();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int Consume (token_t Expected, const char* ErrMsg)
|
||||||
|
/* Consume Token, print an error if we don't find it. Return true if the token
|
||||||
|
** was found and false otherwise.
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
if (Expect (Expected, ErrMsg)) {
|
||||||
NextTok ();
|
NextTok ();
|
||||||
|
return 1;
|
||||||
} else {
|
} else {
|
||||||
Error ("%s", ErrMsg);
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void ConsumeSep (void)
|
int ConsumeSep (void)
|
||||||
/* Consume a separator token */
|
/* Consume a separator token. Return true if the token was found and false
|
||||||
|
* otherwise.
|
||||||
|
*/
|
||||||
{
|
{
|
||||||
/* We expect a separator token */
|
/* We expect a separator token */
|
||||||
ExpectSep ();
|
int Found = ExpectSep ();
|
||||||
|
|
||||||
/* If we are at end of line, skip it */
|
/* If we are at end of line, skip it */
|
||||||
if (CurTok.Tok == TOK_SEP) {
|
if (CurTok.Tok == TOK_SEP) {
|
||||||
NextTok ();
|
NextTok ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return Found;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void ConsumeLParen (void)
|
int ConsumeLParen (void)
|
||||||
/* Consume a left paren */
|
/* Consume a left paren. Return true if the token was found and false
|
||||||
|
** otherwise.
|
||||||
|
*/
|
||||||
{
|
{
|
||||||
Consume (TOK_LPAREN, "'(' expected");
|
return Consume (TOK_LPAREN, "Expected '('");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void ConsumeRParen (void)
|
int ConsumeRParen (void)
|
||||||
/* Consume a right paren */
|
/* Consume a right paren. Return true if the token was found and false
|
||||||
|
** otherwise.
|
||||||
|
*/
|
||||||
{
|
{
|
||||||
Consume (TOK_RPAREN, "')' expected");
|
return Consume (TOK_RPAREN, "Expected ')'");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void ConsumeComma (void)
|
int ConsumeComma (void)
|
||||||
/* Consume a comma */
|
/* Consume a comma. Return true if the token was found and false
|
||||||
|
** otherwise.
|
||||||
|
*/
|
||||||
{
|
{
|
||||||
Consume (TOK_COMMA, "',' expected");
|
return Consume (TOK_COMMA, "Expected ','");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -785,13 +851,21 @@ void SkipUntilSep (void)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void ExpectSep (void)
|
int ExpectSep (void)
|
||||||
/* Check if we've reached a line separator, and output an error if not. Do
|
/* Check if we've reached a line separator. If so, return true. If not, output
|
||||||
** not skip the line separator.
|
** an error and skip all tokens until the line separator is reached. Then
|
||||||
|
** return false.
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
if (!TokIsSep (CurTok.Tok)) {
|
if (!TokIsSep (CurTok.Tok)) {
|
||||||
ErrorSkip ("Unexpected trailing garbage characters");
|
/* Try to be helpful by giving information about the token that was
|
||||||
|
* unexpected.
|
||||||
|
*/
|
||||||
|
ErrorExpect ("Expected 'end-of-line'");
|
||||||
|
SkipUntilSep ();
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -51,27 +51,62 @@
|
|||||||
void NextTok (void);
|
void NextTok (void);
|
||||||
/* Get next token and handle token level functions */
|
/* Get next token and handle token level functions */
|
||||||
|
|
||||||
void Consume (token_t Expected, const char* ErrMsg);
|
void ErrorExpect (const char* Msg);
|
||||||
/* Consume Token, print an error if we don't find it */
|
/* Output an error message about some expected token using Msg and the
|
||||||
|
* description of the following token. This means that Msg should contain
|
||||||
|
* something like "xyz expected". The actual error message would the be
|
||||||
|
* "xyz expected but found zyx".
|
||||||
|
*/
|
||||||
|
|
||||||
void ConsumeSep (void);
|
int Expect (token_t Expected, const char* Msg);
|
||||||
/* Consume a separator token */
|
/* Check if the next token is the expected one. If not, print Msg plus some
|
||||||
|
* information about the token that was actually found. This means that Msg
|
||||||
|
* should contain something like "xyz expected". The actual error message would
|
||||||
|
* the be "xyz expected but found zyx".
|
||||||
|
* Returns true if the token was found, otherwise false.
|
||||||
|
*/
|
||||||
|
|
||||||
void ConsumeLParen (void);
|
int ExpectSkip (token_t Expected, const char* Msg);
|
||||||
/* Consume a left paren */
|
/* Check if the next token is the expected one. If not, print Msg plus some
|
||||||
|
* information about the token that was actually found and skip the remainder
|
||||||
|
* of the line. This means that Msg should contain something like "xyz
|
||||||
|
* expected". The actual error message would the be "xyz expected but found
|
||||||
|
* zyx".
|
||||||
|
* Returns true if the token was found, otherwise false.
|
||||||
|
*/
|
||||||
|
|
||||||
void ConsumeRParen (void);
|
int Consume (token_t Expected, const char* ErrMsg);
|
||||||
/* Consume a right paren */
|
/* Consume Token, print an error if we don't find it. Return true if the token
|
||||||
|
** was found and false otherwise.
|
||||||
|
*/
|
||||||
|
|
||||||
void ConsumeComma (void);
|
int ConsumeSep (void);
|
||||||
/* Consume a comma */
|
/* Consume a separator token. Return true if the token was found and false
|
||||||
|
* otherwise.
|
||||||
|
*/
|
||||||
|
|
||||||
|
int ConsumeLParen (void);
|
||||||
|
/* Consume a left paren. Return true if the token was found and false
|
||||||
|
** otherwise.
|
||||||
|
*/
|
||||||
|
|
||||||
|
int ConsumeRParen (void);
|
||||||
|
/* Consume a right paren. Return true if the token was found and false
|
||||||
|
** otherwise.
|
||||||
|
*/
|
||||||
|
|
||||||
|
int ConsumeComma (void);
|
||||||
|
/* Consume a comma. Return true if the token was found and false
|
||||||
|
** otherwise.
|
||||||
|
*/
|
||||||
|
|
||||||
void SkipUntilSep (void);
|
void SkipUntilSep (void);
|
||||||
/* Skip tokens until we reach a line separator or end of file */
|
/* Skip tokens until we reach a line separator or end of file */
|
||||||
|
|
||||||
void ExpectSep (void);
|
int ExpectSep (void);
|
||||||
/* Check if we've reached a line separator, and output an error if not. Do
|
/* Check if we've reached a line separator. If so, return true. If not, output
|
||||||
** not skip the line separator.
|
** an error and skip all tokens until the line separator is reached. Then
|
||||||
|
** return false.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void EnterRawTokenMode (void);
|
void EnterRawTokenMode (void);
|
||||||
|
|||||||
@@ -167,13 +167,17 @@ static void SetBoolOption (unsigned char* Flag)
|
|||||||
switch (GetSubKey (Keys, sizeof (Keys) / sizeof (Keys [0]))) {
|
switch (GetSubKey (Keys, sizeof (Keys) / sizeof (Keys [0]))) {
|
||||||
case 0: *Flag = 0; NextTok (); break;
|
case 0: *Flag = 0; NextTok (); break;
|
||||||
case 1: *Flag = 1; NextTok (); break;
|
case 1: *Flag = 1; NextTok (); break;
|
||||||
default: ErrorSkip ("'on' or 'off' expected"); break;
|
default:
|
||||||
|
ErrorExpect ("Expected ON or OFF");
|
||||||
|
SkipUntilSep ();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
} else if (TokIsSep (CurTok.Tok)) {
|
} else if (TokIsSep (CurTok.Tok)) {
|
||||||
/* Without anything assume switch on */
|
/* Without anything assume switch on */
|
||||||
*Flag = 1;
|
*Flag = 1;
|
||||||
} else {
|
} else {
|
||||||
ErrorSkip ("'on' or 'off' expected");
|
ErrorExpect ("Expected ON or OFF");
|
||||||
|
SkipUntilSep ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -216,8 +220,7 @@ static void ExportImport (void (*Func) (SymEntry*, unsigned char, unsigned),
|
|||||||
while (1) {
|
while (1) {
|
||||||
|
|
||||||
/* We need an identifier here */
|
/* We need an identifier here */
|
||||||
if (CurTok.Tok != TOK_IDENT) {
|
if (!ExpectSkip (TOK_IDENT, "Expected an identifier")) {
|
||||||
ErrorSkip ("Identifier expected");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -283,7 +286,7 @@ static void ConDes (const StrBuf* Name, unsigned Type)
|
|||||||
Prio = ConstExpression ();
|
Prio = ConstExpression ();
|
||||||
if (Prio < CD_PRIO_MIN || Prio > CD_PRIO_MAX) {
|
if (Prio < CD_PRIO_MIN || Prio > CD_PRIO_MAX) {
|
||||||
/* Value out of range */
|
/* Value out of range */
|
||||||
Error ("Range error");
|
Error ("Given priority is out of range");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -333,7 +336,7 @@ static StrBuf* GenArrayType (StrBuf* Type, unsigned SpanSize,
|
|||||||
static void DoA16 (void)
|
static void DoA16 (void)
|
||||||
/* Switch the accu to 16 bit mode (assembler only) */
|
/* Switch the accu to 16 bit mode (assembler only) */
|
||||||
{
|
{
|
||||||
if (GetCPU() != CPU_65816) {
|
if (GetCPU () != CPU_65816) {
|
||||||
Error ("Command is only valid in 65816 mode");
|
Error ("Command is only valid in 65816 mode");
|
||||||
} else {
|
} else {
|
||||||
/* Immidiate mode has two extension bytes */
|
/* Immidiate mode has two extension bytes */
|
||||||
@@ -346,7 +349,7 @@ static void DoA16 (void)
|
|||||||
static void DoA8 (void)
|
static void DoA8 (void)
|
||||||
/* Switch the accu to 8 bit mode (assembler only) */
|
/* Switch the accu to 8 bit mode (assembler only) */
|
||||||
{
|
{
|
||||||
if (GetCPU() != CPU_65816) {
|
if (GetCPU () != CPU_65816) {
|
||||||
Error ("Command is only valid in 65816 mode");
|
Error ("Command is only valid in 65816 mode");
|
||||||
} else {
|
} else {
|
||||||
/* Immidiate mode has one extension byte */
|
/* Immidiate mode has one extension byte */
|
||||||
@@ -400,7 +403,7 @@ static void DoAlign (void)
|
|||||||
/* Read the alignment value */
|
/* Read the alignment value */
|
||||||
Alignment = ConstExpression ();
|
Alignment = ConstExpression ();
|
||||||
if (Alignment <= 0 || (unsigned long) Alignment > MAX_ALIGNMENT) {
|
if (Alignment <= 0 || (unsigned long) Alignment > MAX_ALIGNMENT) {
|
||||||
ErrorSkip ("Range error");
|
ErrorSkip ("Alignment is out of range");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -410,7 +413,7 @@ static void DoAlign (void)
|
|||||||
FillVal = ConstExpression ();
|
FillVal = ConstExpression ();
|
||||||
/* We need a byte value here */
|
/* We need a byte value here */
|
||||||
if (!IsByteRange (FillVal)) {
|
if (!IsByteRange (FillVal)) {
|
||||||
ErrorSkip ("Range error");
|
ErrorSkip ("Fill value is not in byte range");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -428,8 +431,7 @@ static void DoASCIIZ (void)
|
|||||||
{
|
{
|
||||||
while (1) {
|
while (1) {
|
||||||
/* Must have a string constant */
|
/* Must have a string constant */
|
||||||
if (CurTok.Tok != TOK_STRCON) {
|
if (!ExpectSkip (TOK_STRCON, "Expected a string constant")) {
|
||||||
ErrorSkip ("String constant expected");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -463,11 +465,10 @@ static void DoAssert (void)
|
|||||||
|
|
||||||
/* First we have the expression that has to evaluated */
|
/* First we have the expression that has to evaluated */
|
||||||
ExprNode* Expr = Expression ();
|
ExprNode* Expr = Expression ();
|
||||||
ConsumeComma ();
|
|
||||||
|
|
||||||
/* Action follows */
|
/* Followed by comma and action */
|
||||||
if (CurTok.Tok != TOK_IDENT) {
|
if (!ConsumeComma () || !Expect (TOK_IDENT, "Expected an identifier")) {
|
||||||
ErrorSkip ("Identifier expected");
|
SkipUntilSep ();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
switch (GetSubKey (ActionTab, sizeof (ActionTab) / sizeof (ActionTab[0]))) {
|
switch (GetSubKey (ActionTab, sizeof (ActionTab) / sizeof (ActionTab[0]))) {
|
||||||
@@ -496,9 +497,8 @@ static void DoAssert (void)
|
|||||||
|
|
||||||
default:
|
default:
|
||||||
Error ("Illegal assert action specifier");
|
Error ("Illegal assert action specifier");
|
||||||
/* Use lderror - there won't be an .o file anyway */
|
SkipUntilSep ();
|
||||||
Action = ASSERT_ACT_LDERROR;
|
return;
|
||||||
break;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
NextTok ();
|
NextTok ();
|
||||||
@@ -512,8 +512,7 @@ static void DoAssert (void)
|
|||||||
NextTok ();
|
NextTok ();
|
||||||
|
|
||||||
/* Read the message */
|
/* Read the message */
|
||||||
if (CurTok.Tok != TOK_STRCON) {
|
if (!ExpectSkip (TOK_STRCON, "Expected a string constant")) {
|
||||||
ErrorSkip ("String constant expected");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -642,20 +641,23 @@ static void DoCharMap (void)
|
|||||||
|
|
||||||
/* Read the index as numerical value */
|
/* Read the index as numerical value */
|
||||||
Index = ConstExpression ();
|
Index = ConstExpression ();
|
||||||
if (Index < 0 || Index > 255) {
|
if (IsByteRange (Index)) {
|
||||||
/* Value out of range */
|
/* Value out of range */
|
||||||
ErrorSkip ("Index range error");
|
ErrorSkip ("Index must be in byte range");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Comma follows */
|
/* Comma follows */
|
||||||
ConsumeComma ();
|
if (!ConsumeComma ()) {
|
||||||
|
SkipUntilSep ();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* Read the character code */
|
/* Read the character code */
|
||||||
Code = ConstExpression ();
|
Code = ConstExpression ();
|
||||||
if (Code < 0 || Code > 255) {
|
if (!IsByteRange (Code)) {
|
||||||
/* Value out of range */
|
/* Value out of range */
|
||||||
ErrorSkip ("Code range error");
|
ErrorSkip ("Replacement character code must be in byte range");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -685,15 +687,17 @@ static void DoConDes (void)
|
|||||||
long Type;
|
long Type;
|
||||||
|
|
||||||
/* Symbol name follows */
|
/* Symbol name follows */
|
||||||
if (CurTok.Tok != TOK_IDENT) {
|
if (!ExpectSkip (TOK_IDENT, "Expected an identifier")) {
|
||||||
ErrorSkip ("Identifier expected");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
SB_Copy (&Name, &CurTok.SVal);
|
SB_Copy (&Name, &CurTok.SVal);
|
||||||
NextTok ();
|
NextTok ();
|
||||||
|
|
||||||
/* Type follows. May be encoded as identifier or numerical */
|
/* Type follows. May be encoded as identifier or numerical */
|
||||||
ConsumeComma ();
|
if (!ConsumeComma ()) {
|
||||||
|
SkipUntilSep ();
|
||||||
|
goto ExitPoint;
|
||||||
|
}
|
||||||
if (CurTok.Tok == TOK_IDENT) {
|
if (CurTok.Tok == TOK_IDENT) {
|
||||||
|
|
||||||
/* Map the following keyword to a number, then skip it */
|
/* Map the following keyword to a number, then skip it */
|
||||||
@@ -702,7 +706,8 @@ static void DoConDes (void)
|
|||||||
|
|
||||||
/* Check if we got a valid keyword */
|
/* Check if we got a valid keyword */
|
||||||
if (Type < 0) {
|
if (Type < 0) {
|
||||||
ErrorSkip ("Syntax error");
|
ErrorExpect ("Expected CONSTRUCTOR, DESTRUCTOR or INTERRUPTOR");
|
||||||
|
SkipUntilSep ();
|
||||||
goto ExitPoint;
|
goto ExitPoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -712,7 +717,7 @@ static void DoConDes (void)
|
|||||||
Type = ConstExpression ();
|
Type = ConstExpression ();
|
||||||
if (Type < CD_TYPE_MIN || Type > CD_TYPE_MAX) {
|
if (Type < CD_TYPE_MIN || Type > CD_TYPE_MAX) {
|
||||||
/* Value out of range */
|
/* Value out of range */
|
||||||
ErrorSkip ("Range error");
|
ErrorSkip ("Numeric condes type is out of range");
|
||||||
goto ExitPoint;
|
goto ExitPoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -734,8 +739,7 @@ static void DoConstructor (void)
|
|||||||
StrBuf Name = STATIC_STRBUF_INITIALIZER;
|
StrBuf Name = STATIC_STRBUF_INITIALIZER;
|
||||||
|
|
||||||
/* Symbol name follows */
|
/* Symbol name follows */
|
||||||
if (CurTok.Tok != TOK_IDENT) {
|
if (!ExpectSkip (TOK_IDENT, "Expected an identifier")) {
|
||||||
ErrorSkip ("Identifier expected");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
SB_Copy (&Name, &CurTok.SVal);
|
SB_Copy (&Name, &CurTok.SVal);
|
||||||
@@ -771,8 +775,7 @@ static void DoDbg (void)
|
|||||||
|
|
||||||
|
|
||||||
/* We expect a subkey */
|
/* We expect a subkey */
|
||||||
if (CurTok.Tok != TOK_IDENT) {
|
if (!ExpectSkip (TOK_IDENT, "Expected an identifier")) {
|
||||||
ErrorSkip ("Identifier expected");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -788,7 +791,10 @@ static void DoDbg (void)
|
|||||||
case 1: DbgInfoFunc (); break;
|
case 1: DbgInfoFunc (); break;
|
||||||
case 2: DbgInfoLine (); break;
|
case 2: DbgInfoLine (); break;
|
||||||
case 3: DbgInfoSym (); break;
|
case 3: DbgInfoSym (); break;
|
||||||
default: ErrorSkip ("Syntax error"); break;
|
default:
|
||||||
|
ErrorExpect ("Expected FILE, FUNC, LINE or SYM");
|
||||||
|
SkipUntilSep ();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -853,9 +859,7 @@ static void DoDelMac (void)
|
|||||||
/* Delete a classic macro */
|
/* Delete a classic macro */
|
||||||
{
|
{
|
||||||
/* We expect an identifier */
|
/* We expect an identifier */
|
||||||
if (CurTok.Tok != TOK_IDENT) {
|
if (ExpectSkip (TOK_IDENT, "Expected an identifier")) {
|
||||||
ErrorSkip ("Identifier expected");
|
|
||||||
} else {
|
|
||||||
MacUndef (&CurTok.SVal, MAC_STYLE_CLASSIC);
|
MacUndef (&CurTok.SVal, MAC_STYLE_CLASSIC);
|
||||||
NextTok ();
|
NextTok ();
|
||||||
}
|
}
|
||||||
@@ -869,8 +873,7 @@ static void DoDestructor (void)
|
|||||||
StrBuf Name = STATIC_STRBUF_INITIALIZER;
|
StrBuf Name = STATIC_STRBUF_INITIALIZER;
|
||||||
|
|
||||||
/* Symbol name follows */
|
/* Symbol name follows */
|
||||||
if (CurTok.Tok != TOK_IDENT) {
|
if (!ExpectSkip (TOK_IDENT, "Expected an identifier")) {
|
||||||
ErrorSkip ("Identifier expected");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
SB_Copy (&Name, &CurTok.SVal);
|
SB_Copy (&Name, &CurTok.SVal);
|
||||||
@@ -938,9 +941,7 @@ static void DoEndScope (void)
|
|||||||
static void DoError (void)
|
static void DoError (void)
|
||||||
/* User error */
|
/* User error */
|
||||||
{
|
{
|
||||||
if (CurTok.Tok != TOK_STRCON) {
|
if (ExpectSkip (TOK_STRCON, "Expected a string constant")) {
|
||||||
ErrorSkip ("String constant expected");
|
|
||||||
} else {
|
|
||||||
Error ("User error: %m%p", &CurTok.SVal);
|
Error ("User error: %m%p", &CurTok.SVal);
|
||||||
SkipUntilSep ();
|
SkipUntilSep ();
|
||||||
}
|
}
|
||||||
@@ -1010,9 +1011,7 @@ static void DoFarAddr (void)
|
|||||||
static void DoFatal (void)
|
static void DoFatal (void)
|
||||||
/* Fatal user error */
|
/* Fatal user error */
|
||||||
{
|
{
|
||||||
if (CurTok.Tok != TOK_STRCON) {
|
if (ExpectSkip (TOK_STRCON, "Expected a string constant")) {
|
||||||
ErrorSkip ("String constant expected");
|
|
||||||
} else {
|
|
||||||
Fatal ("User error: %m%p", &CurTok.SVal);
|
Fatal ("User error: %m%p", &CurTok.SVal);
|
||||||
SkipUntilSep ();
|
SkipUntilSep ();
|
||||||
}
|
}
|
||||||
@@ -1030,14 +1029,13 @@ static void DoFeature (void)
|
|||||||
while (1) {
|
while (1) {
|
||||||
|
|
||||||
/* We expect an identifier */
|
/* We expect an identifier */
|
||||||
if (CurTok.Tok != TOK_IDENT) {
|
if (!ExpectSkip (TOK_IDENT, "Expected an identifier")) {
|
||||||
ErrorSkip ("Identifier expected");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Make the string attribute lower case */
|
/* Make the string attribute lower case */
|
||||||
LocaseSVal ();
|
LocaseSVal ();
|
||||||
Feature = FindFeature(&CurTok.SVal);
|
Feature = FindFeature (&CurTok.SVal);
|
||||||
if (Feature == FEAT_UNKNOWN) {
|
if (Feature == FEAT_UNKNOWN) {
|
||||||
/* Not found */
|
/* Not found */
|
||||||
ErrorSkip ("Invalid feature: '%m%p'", &CurTok.SVal);
|
ErrorSkip ("Invalid feature: '%m%p'", &CurTok.SVal);
|
||||||
@@ -1045,7 +1043,8 @@ static void DoFeature (void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (Feature == FEAT_ADDRSIZE) {
|
if (Feature == FEAT_ADDRSIZE) {
|
||||||
Warning (1, "Deprecated feature: '.feature addrsize'. Pseudo function .addrsize is always available.");
|
Warning (1, "Deprecated feature: '.feature addrsize'. "
|
||||||
|
"Pseudo function .addrsize is always available.");
|
||||||
}
|
}
|
||||||
|
|
||||||
NextTok ();
|
NextTok ();
|
||||||
@@ -1053,7 +1052,7 @@ static void DoFeature (void)
|
|||||||
/* Optional +/- or ON/OFF */
|
/* Optional +/- or ON/OFF */
|
||||||
On = 1;
|
On = 1;
|
||||||
if (CurTok.Tok != TOK_COMMA && !TokIsSep (CurTok.Tok)) {
|
if (CurTok.Tok != TOK_COMMA && !TokIsSep (CurTok.Tok)) {
|
||||||
SetBoolOption(&On);
|
SetBoolOption (&On);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Apply feature setting. */
|
/* Apply feature setting. */
|
||||||
@@ -1087,19 +1086,17 @@ static void DoFileOpt (void)
|
|||||||
OptNum = GetSubKey (Keys, sizeof (Keys) / sizeof (Keys [0]));
|
OptNum = GetSubKey (Keys, sizeof (Keys) / sizeof (Keys [0]));
|
||||||
if (OptNum < 0) {
|
if (OptNum < 0) {
|
||||||
/* Not found */
|
/* Not found */
|
||||||
ErrorSkip ("File option keyword expected");
|
ErrorExpect ("Expected a file option keyword");
|
||||||
|
SkipUntilSep ();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Skip the keyword */
|
/* Skip the keyword */
|
||||||
NextTok ();
|
NextTok ();
|
||||||
|
|
||||||
/* Must be followed by a comma */
|
/* Must be followed by a comma and a string option */
|
||||||
ConsumeComma ();
|
if (!ConsumeComma () || !Expect (TOK_STRCON, "Expected a string constant")) {
|
||||||
|
SkipUntilSep ();
|
||||||
/* We accept only string options for now */
|
|
||||||
if (CurTok.Tok != TOK_STRCON) {
|
|
||||||
ErrorSkip ("String constant expected");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1134,16 +1131,13 @@ static void DoFileOpt (void)
|
|||||||
/* Option given as number */
|
/* Option given as number */
|
||||||
OptNum = ConstExpression ();
|
OptNum = ConstExpression ();
|
||||||
if (!IsByteRange (OptNum)) {
|
if (!IsByteRange (OptNum)) {
|
||||||
ErrorSkip ("Range error");
|
ErrorSkip ("Option number must be in byte range");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Must be followed by a comma */
|
/* Must be followed by a comma plus a string constant */
|
||||||
ConsumeComma ();
|
if (!ConsumeComma () || !Expect (TOK_STRCON, "Expected a string constant")) {
|
||||||
|
SkipUntilSep ();
|
||||||
/* We accept only string options for now */
|
|
||||||
if (CurTok.Tok != TOK_STRCON) {
|
|
||||||
ErrorSkip ("String constant expected");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1198,7 +1192,7 @@ static void DoHiBytes (void)
|
|||||||
static void DoI16 (void)
|
static void DoI16 (void)
|
||||||
/* Switch the index registers to 16 bit mode (assembler only) */
|
/* Switch the index registers to 16 bit mode (assembler only) */
|
||||||
{
|
{
|
||||||
if (GetCPU() != CPU_65816) {
|
if (GetCPU () != CPU_65816) {
|
||||||
Error ("Command is only valid in 65816 mode");
|
Error ("Command is only valid in 65816 mode");
|
||||||
} else {
|
} else {
|
||||||
/* Immidiate mode has two extension bytes */
|
/* Immidiate mode has two extension bytes */
|
||||||
@@ -1211,7 +1205,7 @@ static void DoI16 (void)
|
|||||||
static void DoI8 (void)
|
static void DoI8 (void)
|
||||||
/* Switch the index registers to 16 bit mode (assembler only) */
|
/* Switch the index registers to 16 bit mode (assembler only) */
|
||||||
{
|
{
|
||||||
if (GetCPU() != CPU_65816) {
|
if (GetCPU () != CPU_65816) {
|
||||||
Error ("Command is only valid in 65816 mode");
|
Error ("Command is only valid in 65816 mode");
|
||||||
} else {
|
} else {
|
||||||
/* Immidiate mode has one extension byte */
|
/* Immidiate mode has one extension byte */
|
||||||
@@ -1248,8 +1242,7 @@ static void DoIncBin (void)
|
|||||||
FILE* F;
|
FILE* F;
|
||||||
|
|
||||||
/* Name must follow */
|
/* Name must follow */
|
||||||
if (CurTok.Tok != TOK_STRCON) {
|
if (!ExpectSkip (TOK_STRCON, "Expected a string constant")) {
|
||||||
ErrorSkip ("String constant expected");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
SB_Copy (&Name, &CurTok.SVal);
|
SB_Copy (&Name, &CurTok.SVal);
|
||||||
@@ -1314,13 +1307,16 @@ static void DoIncBin (void)
|
|||||||
Count = Size - Start;
|
Count = Size - Start;
|
||||||
if (Count < 0) {
|
if (Count < 0) {
|
||||||
/* Nothing to read - flag this as a range error */
|
/* Nothing to read - flag this as a range error */
|
||||||
ErrorSkip ("Range error");
|
ErrorSkip ("Start offset is larger than file size");
|
||||||
goto Done;
|
goto Done;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* Count was given, check if it is valid */
|
/* Count was given, check if it is valid */
|
||||||
if (Start + Count > Size) {
|
if (Start > Size) {
|
||||||
ErrorSkip ("Range error");
|
ErrorSkip ("Start offset is larger than file size");
|
||||||
|
goto Done;
|
||||||
|
} else if (Start + Count > Size) {
|
||||||
|
ErrorSkip ("Not enough bytes left in file at offset %ld", Start);
|
||||||
goto Done;
|
goto Done;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1367,9 +1363,7 @@ static void DoInclude (void)
|
|||||||
/* Include another file */
|
/* Include another file */
|
||||||
{
|
{
|
||||||
/* Name must follow */
|
/* Name must follow */
|
||||||
if (CurTok.Tok != TOK_STRCON) {
|
if (ExpectSkip (TOK_STRCON, "Expected a string constant")) {
|
||||||
ErrorSkip ("String constant expected");
|
|
||||||
} else {
|
|
||||||
SB_Terminate (&CurTok.SVal);
|
SB_Terminate (&CurTok.SVal);
|
||||||
if (NewInputFile (SB_GetConstBuf (&CurTok.SVal)) == 0) {
|
if (NewInputFile (SB_GetConstBuf (&CurTok.SVal)) == 0) {
|
||||||
/* Error opening the file, skip remainder of line */
|
/* Error opening the file, skip remainder of line */
|
||||||
@@ -1386,8 +1380,7 @@ static void DoInterruptor (void)
|
|||||||
StrBuf Name = STATIC_STRBUF_INITIALIZER;
|
StrBuf Name = STATIC_STRBUF_INITIALIZER;
|
||||||
|
|
||||||
/* Symbol name follows */
|
/* Symbol name follows */
|
||||||
if (CurTok.Tok != TOK_IDENT) {
|
if (!ExpectSkip (TOK_IDENT, "Expected an identifier")) {
|
||||||
ErrorSkip ("Identifier expected");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
SB_Copy (&Name, &CurTok.SVal);
|
SB_Copy (&Name, &CurTok.SVal);
|
||||||
@@ -1474,9 +1467,7 @@ static void DoListBytes (void)
|
|||||||
static void DoLocalChar (void)
|
static void DoLocalChar (void)
|
||||||
/* Define the character that starts local labels */
|
/* Define the character that starts local labels */
|
||||||
{
|
{
|
||||||
if (CurTok.Tok != TOK_CHARCON) {
|
if (ExpectSkip (TOK_CHARCON, "Expected a character constant")) {
|
||||||
ErrorSkip ("Character constant expected");
|
|
||||||
} else {
|
|
||||||
if (CurTok.IVal != '@' && CurTok.IVal != '?') {
|
if (CurTok.IVal != '@' && CurTok.IVal != '?') {
|
||||||
Error ("Invalid start character for locals");
|
Error ("Invalid start character for locals");
|
||||||
} else {
|
} else {
|
||||||
@@ -1492,15 +1483,14 @@ static void DoMacPack (void)
|
|||||||
/* Insert a macro package */
|
/* Insert a macro package */
|
||||||
{
|
{
|
||||||
/* We expect an identifier */
|
/* We expect an identifier */
|
||||||
if (CurTok.Tok != TOK_IDENT) {
|
if (!ExpectSkip (TOK_IDENT, "Expected an identifier")) {
|
||||||
ErrorSkip ("Identifier expected");
|
return;
|
||||||
} else {
|
}
|
||||||
SB_AppendStr (&CurTok.SVal, ".mac");
|
SB_AppendStr (&CurTok.SVal, ".mac");
|
||||||
SB_Terminate (&CurTok.SVal);
|
SB_Terminate (&CurTok.SVal);
|
||||||
if (NewInputFile (SB_GetConstBuf (&CurTok.SVal)) == 0) {
|
if (NewInputFile (SB_GetConstBuf (&CurTok.SVal)) == 0) {
|
||||||
/* Error opening the file, skip remainder of line */
|
/* Error opening the file, skip remainder of line */
|
||||||
SkipUntilSep ();
|
SkipUntilSep ();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1538,12 +1528,10 @@ static void DoOrg (void)
|
|||||||
static void DoOut (void)
|
static void DoOut (void)
|
||||||
/* Output a string */
|
/* Output a string */
|
||||||
{
|
{
|
||||||
if (CurTok.Tok != TOK_STRCON) {
|
if (ExpectSkip (TOK_STRCON, "Expected a string constant")) {
|
||||||
ErrorSkip ("String constant expected");
|
|
||||||
} 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
|
||||||
** sync with any error messages if the output is redirected to a file.
|
* sync with any error messages if the output is redirected to a file.
|
||||||
*/
|
*/
|
||||||
printf ("%.*s\n",
|
printf ("%.*s\n",
|
||||||
(int) SB_GetLen (&CurTok.SVal),
|
(int) SB_GetLen (&CurTok.SVal),
|
||||||
SB_GetConstBuf (&CurTok.SVal));
|
SB_GetConstBuf (&CurTok.SVal));
|
||||||
@@ -1835,7 +1823,7 @@ static void DoRes (void)
|
|||||||
|
|
||||||
Count = ConstExpression ();
|
Count = ConstExpression ();
|
||||||
if (Count > 0xFFFF || Count < 0) {
|
if (Count > 0xFFFF || Count < 0) {
|
||||||
ErrorSkip ("Range error");
|
ErrorSkip ("Invalid number of bytes specified");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (CurTok.Tok == TOK_COMMA) {
|
if (CurTok.Tok == TOK_COMMA) {
|
||||||
@@ -1843,7 +1831,7 @@ static void DoRes (void)
|
|||||||
Val = ConstExpression ();
|
Val = ConstExpression ();
|
||||||
/* We need a byte value here */
|
/* We need a byte value here */
|
||||||
if (!IsByteRange (Val)) {
|
if (!IsByteRange (Val)) {
|
||||||
ErrorSkip ("Range error");
|
ErrorSkip ("Fill value is not in byte range");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1903,12 +1891,10 @@ static void DoScope (void)
|
|||||||
static void DoSegment (void)
|
static void DoSegment (void)
|
||||||
/* Switch to another segment */
|
/* Switch to another segment */
|
||||||
{
|
{
|
||||||
StrBuf Name = STATIC_STRBUF_INITIALIZER;
|
if (ExpectSkip (TOK_STRCON, "Expected a string constant")) {
|
||||||
SegDef Def;
|
|
||||||
|
|
||||||
if (CurTok.Tok != TOK_STRCON) {
|
SegDef Def;
|
||||||
ErrorSkip ("String constant expected");
|
StrBuf Name = AUTO_STRBUF_INITIALIZER;
|
||||||
} else {
|
|
||||||
|
|
||||||
/* Save the name of the segment and skip it */
|
/* Save the name of the segment and skip it */
|
||||||
SB_Copy (&Name, &CurTok.SVal);
|
SB_Copy (&Name, &CurTok.SVal);
|
||||||
@@ -1923,10 +1909,10 @@ static void DoSegment (void)
|
|||||||
|
|
||||||
/* Set the segment */
|
/* Set the segment */
|
||||||
UseSeg (&Def);
|
UseSeg (&Def);
|
||||||
}
|
|
||||||
|
|
||||||
/* Free memory for Name */
|
/* Free memory for Name */
|
||||||
SB_Done (&Name);
|
SB_Done (&Name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1935,9 +1921,7 @@ static void DoSetCPU (void)
|
|||||||
/* Switch the CPU instruction set */
|
/* Switch the CPU instruction set */
|
||||||
{
|
{
|
||||||
/* We expect an identifier */
|
/* We expect an identifier */
|
||||||
if (CurTok.Tok != TOK_STRCON) {
|
if (ExpectSkip (TOK_STRCON, "Expected a string constant")) {
|
||||||
ErrorSkip ("String constant expected");
|
|
||||||
} else {
|
|
||||||
cpu_t CPU;
|
cpu_t CPU;
|
||||||
|
|
||||||
/* Try to find the CPU */
|
/* Try to find the CPU */
|
||||||
@@ -1948,8 +1932,8 @@ static void DoSetCPU (void)
|
|||||||
SetCPU (CPU);
|
SetCPU (CPU);
|
||||||
|
|
||||||
/* Skip the identifier. If the CPU switch was successful, the scanner
|
/* Skip the identifier. If the CPU switch was successful, the scanner
|
||||||
** will treat the input now correctly for the new CPU.
|
* will treat the input now correctly for the new CPU.
|
||||||
*/
|
*/
|
||||||
NextTok ();
|
NextTok ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2024,9 +2008,7 @@ static void DoUnDef (void)
|
|||||||
EnableDefineStyleMacros ();
|
EnableDefineStyleMacros ();
|
||||||
|
|
||||||
/* We expect an identifier */
|
/* We expect an identifier */
|
||||||
if (CurTok.Tok != TOK_IDENT) {
|
if (ExpectSkip (TOK_IDENT, "Expected an identifier")) {
|
||||||
ErrorSkip ("Identifier expected");
|
|
||||||
} else {
|
|
||||||
MacUndef (&CurTok.SVal, MAC_STYLE_DEFINE);
|
MacUndef (&CurTok.SVal, MAC_STYLE_DEFINE);
|
||||||
NextTok ();
|
NextTok ();
|
||||||
}
|
}
|
||||||
@@ -2046,9 +2028,7 @@ static void DoUnexpected (void)
|
|||||||
static void DoWarning (void)
|
static void DoWarning (void)
|
||||||
/* User warning */
|
/* User warning */
|
||||||
{
|
{
|
||||||
if (CurTok.Tok != TOK_STRCON) {
|
if (ExpectSkip (TOK_STRCON, "Expected a string constant")) {
|
||||||
ErrorSkip ("String constant expected");
|
|
||||||
} else {
|
|
||||||
Warning (0, "User warning: %m%p", &CurTok.SVal);
|
Warning (0, "User warning: %m%p", &CurTok.SVal);
|
||||||
SkipUntilSep ();
|
SkipUntilSep ();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -120,7 +120,7 @@ void ParseRepeat (void)
|
|||||||
/* Repeat count follows */
|
/* Repeat count follows */
|
||||||
long RepCount = ConstExpression ();
|
long RepCount = ConstExpression ();
|
||||||
if (RepCount < 0) {
|
if (RepCount < 0) {
|
||||||
Error ("Range error");
|
Error ("Repeat count must be positive or zero");
|
||||||
RepCount = 0;
|
RepCount = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -132,9 +132,7 @@ void ParseRepeat (void)
|
|||||||
NextTok ();
|
NextTok ();
|
||||||
|
|
||||||
/* Check for an identifier */
|
/* Check for an identifier */
|
||||||
if (CurTok.Tok != TOK_IDENT) {
|
if (ExpectSkip (TOK_IDENT, "Expected an identifier")) {
|
||||||
ErrorSkip ("Identifier expected");
|
|
||||||
} else {
|
|
||||||
/* Remember the name and skip it */
|
/* Remember the name and skip it */
|
||||||
SB_Terminate (&CurTok.SVal);
|
SB_Terminate (&CurTok.SVal);
|
||||||
Name = xstrdup (SB_GetConstBuf (&CurTok.SVal));
|
Name = xstrdup (SB_GetConstBuf (&CurTok.SVal));
|
||||||
|
|||||||
@@ -818,7 +818,7 @@ static void ReadStringConst (int StringTerm)
|
|||||||
int Cooked = 1;
|
int Cooked = 1;
|
||||||
NeedNext = 1;
|
NeedNext = 1;
|
||||||
|
|
||||||
if (StringTerm == 0 && SB_GetLen(&CurTok.SVal) == 1) {
|
if (StringTerm == 0 && SB_GetLen (&CurTok.SVal) == 1) {
|
||||||
if (C == '\'') {
|
if (C == '\'') {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -901,12 +901,12 @@ static void ReadStringConst (int StringTerm)
|
|||||||
case '7':
|
case '7':
|
||||||
{ /* brace needed for scoping */
|
{ /* brace needed for scoping */
|
||||||
int Count = 1;
|
int Count = 1;
|
||||||
int Final = DigitVal(C);
|
int Final = DigitVal (C);
|
||||||
Cooked = 0;
|
Cooked = 0;
|
||||||
NextChar ();
|
NextChar ();
|
||||||
while (IsODigit (C) && Count++ < 3) {
|
while (IsODigit (C) && Count++ < 3) {
|
||||||
Final = (Final << 3) | DigitVal(C);
|
Final = (Final << 3) | DigitVal (C);
|
||||||
NextChar();
|
NextChar ();
|
||||||
}
|
}
|
||||||
if (C >= 256)
|
if (C >= 256)
|
||||||
Error ("Octal character constant out of range");
|
Error ("Octal character constant out of range");
|
||||||
@@ -1587,8 +1587,8 @@ CharAgain:
|
|||||||
/* Always a character constant
|
/* Always a character constant
|
||||||
** Hack: Pass 0 to ReadStringConst for special handling.
|
** Hack: Pass 0 to ReadStringConst for special handling.
|
||||||
*/
|
*/
|
||||||
ReadStringConst(0);
|
ReadStringConst (0);
|
||||||
if (SB_GetLen(&CurTok.SVal) != 1) {
|
if (SB_GetLen (&CurTok.SVal) != 1) {
|
||||||
Error ("Illegal character constant");
|
Error ("Illegal character constant");
|
||||||
goto CharAgain;
|
goto CharAgain;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -105,14 +105,21 @@ static long DoStructInternal (long Offs, unsigned Type)
|
|||||||
** union, the struct may be anonymous; in which case, no new lexical level
|
** union, the struct may be anonymous; in which case, no new lexical level
|
||||||
** is started.
|
** is started.
|
||||||
*/
|
*/
|
||||||
int Anon = (CurTok.Tok != TOK_IDENT);
|
int Anon = (CurTok.Tok == TOK_SEP);
|
||||||
|
|
||||||
if (!Anon) {
|
if (!Anon) {
|
||||||
/* Enter a new scope, then skip the name */
|
/* Non anonymous structs must have an identifier as name */
|
||||||
SymEnterLevel (&CurTok.SVal, SCOPE_STRUCT, ADDR_SIZE_ABS, 0);
|
if (Expect (TOK_IDENT, "Expected a struct/union name")) {
|
||||||
NextTok ();
|
/* Enter a new scope, then skip the name */
|
||||||
/* Start at zero offset in the new scope */
|
SymEnterLevel (&CurTok.SVal, SCOPE_STRUCT, ADDR_SIZE_ABS, 0);
|
||||||
Offs = 0;
|
NextTok ();
|
||||||
|
/* Start at zero offset in the new scope */
|
||||||
|
Offs = 0;
|
||||||
|
} else {
|
||||||
|
/* Skip the junk on the line before proceeding */
|
||||||
|
SkipUntilSep ();
|
||||||
|
Anon = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Test for end of line */
|
/* Test for end of line */
|
||||||
@@ -183,7 +190,7 @@ static long DoStructInternal (long Offs, unsigned Type)
|
|||||||
case TOK_RES:
|
case TOK_RES:
|
||||||
NextTok ();
|
NextTok ();
|
||||||
if (CurTok.Tok == TOK_SEP) {
|
if (CurTok.Tok == TOK_SEP) {
|
||||||
ErrorSkip ("Size is missing");
|
ErrorExpect ("Expected a byte count");
|
||||||
} else {
|
} else {
|
||||||
MemberSize = Member (1);
|
MemberSize = Member (1);
|
||||||
}
|
}
|
||||||
@@ -192,7 +199,7 @@ static long DoStructInternal (long Offs, unsigned Type)
|
|||||||
case TOK_ORG:
|
case TOK_ORG:
|
||||||
NextTok ();
|
NextTok ();
|
||||||
if (CurTok.Tok == TOK_SEP) {
|
if (CurTok.Tok == TOK_SEP) {
|
||||||
ErrorSkip ("Address is missing");
|
ErrorExpect ("Expected an address");
|
||||||
} else {
|
} else {
|
||||||
Offs = ConstExpression ();
|
Offs = ConstExpression ();
|
||||||
|
|
||||||
@@ -233,7 +240,12 @@ static long DoStructInternal (long Offs, unsigned Type)
|
|||||||
default:
|
default:
|
||||||
if (!CheckConditionals ()) {
|
if (!CheckConditionals ()) {
|
||||||
/* Not a conditional directive */
|
/* Not a conditional directive */
|
||||||
ErrorSkip ("Invalid storage allocator in struct/union");
|
if (Sym) {
|
||||||
|
ErrorExpect ("Expected a storage allocator after the field name");
|
||||||
|
} else {
|
||||||
|
ErrorExpect ("Expected a storage allocator");
|
||||||
|
}
|
||||||
|
SkipUntilSep ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -275,9 +287,9 @@ static long DoStructInternal (long Offs, unsigned Type)
|
|||||||
|
|
||||||
/* End of struct/union definition */
|
/* End of struct/union definition */
|
||||||
if (Type == STRUCT) {
|
if (Type == STRUCT) {
|
||||||
Consume (TOK_ENDSTRUCT, "'.ENDSTRUCT' expected");
|
Consume (TOK_ENDSTRUCT, "Expected '.ENDSTRUCT'");
|
||||||
} else {
|
} else {
|
||||||
Consume (TOK_ENDUNION, "'.ENDUNION' expected");
|
Consume (TOK_ENDUNION, "Expected '.ENDUNION'");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return the size of the struct */
|
/* Return the size of the struct */
|
||||||
|
|||||||
@@ -1359,8 +1359,7 @@ static void StudyNearAddr (ExprNode* Expr, ExprDesc* D)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Promote to absolute if smaller. */
|
/* Promote to absolute if smaller. */
|
||||||
if (D->AddrSize < ADDR_SIZE_ABS)
|
if (D->AddrSize < ADDR_SIZE_ABS) {
|
||||||
{
|
|
||||||
D->AddrSize = ADDR_SIZE_ABS;
|
D->AddrSize = ADDR_SIZE_ABS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ SymTable* ParseScopedIdent (StrBuf* Name, StrBuf* FullName)
|
|||||||
/* Start from the root scope */
|
/* Start from the root scope */
|
||||||
Scope = RootScope;
|
Scope = RootScope;
|
||||||
|
|
||||||
} else if (CurTok.Tok == TOK_IDENT) {
|
} else if (Expect (TOK_IDENT, "Expected an identifier")) {
|
||||||
|
|
||||||
/* Remember the name and skip it */
|
/* Remember the name and skip it */
|
||||||
SB_Copy (Name, &CurTok.SVal);
|
SB_Copy (Name, &CurTok.SVal);
|
||||||
@@ -115,8 +115,7 @@ SymTable* ParseScopedIdent (StrBuf* Name, StrBuf* FullName)
|
|||||||
while (1) {
|
while (1) {
|
||||||
|
|
||||||
/* Next token must be an identifier. */
|
/* Next token must be an identifier. */
|
||||||
if (CurTok.Tok != TOK_IDENT) {
|
if (!Expect (TOK_IDENT, "Expected an identifier")) {
|
||||||
Error ("Identifier expected");
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
304
src/ca65/token.c
304
src/ca65/token.c
@@ -33,30 +33,261 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
/* ca65 */
|
/* ca65 */
|
||||||
#include "token.h"
|
#include "token.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* Code */
|
/* Data */
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int TokHasSVal (token_t Tok)
|
/* Use a struct so we can extend it if required */
|
||||||
/* Return true if the given token has an attached SVal */
|
typedef struct TokDescEntry TokDescEntry;
|
||||||
{
|
struct TokDescEntry {
|
||||||
return (Tok == TOK_IDENT || Tok == TOK_LOCAL_IDENT || Tok == TOK_STRCON);
|
const char* Desc;
|
||||||
}
|
};
|
||||||
|
|
||||||
|
static const TokDescEntry TokDesc[] = {
|
||||||
|
{ "none", },
|
||||||
|
{ "end-of-file", },
|
||||||
|
{ "end-of-line", },
|
||||||
|
{ "{s}", },
|
||||||
|
{ "{s}", },
|
||||||
|
|
||||||
|
{ "{i}", },
|
||||||
|
{ "'{c}'", },
|
||||||
|
{ "\"{s}\"", },
|
||||||
|
|
||||||
|
{ "A", },
|
||||||
|
{ "Q", },
|
||||||
|
{ "S", },
|
||||||
|
{ "X", },
|
||||||
|
{ "Y", },
|
||||||
|
{ "Z", },
|
||||||
|
{ "R{i}", },
|
||||||
|
|
||||||
|
{ ":=", },
|
||||||
|
{ "unnamed label", },
|
||||||
|
|
||||||
|
{ "=", },
|
||||||
|
{ "<>", },
|
||||||
|
{ "<", },
|
||||||
|
{ ">", },
|
||||||
|
{ "<=", },
|
||||||
|
{ ">=", },
|
||||||
|
|
||||||
|
{ ".AND", },
|
||||||
|
{ ".OR", },
|
||||||
|
{ ".XOR", },
|
||||||
|
{ ".NOT", },
|
||||||
|
|
||||||
|
{ "+", },
|
||||||
|
{ "-", },
|
||||||
|
{ "*", },
|
||||||
|
{ "/", },
|
||||||
|
{ "!", },
|
||||||
|
{ "|", },
|
||||||
|
{ "^", },
|
||||||
|
{ "&", },
|
||||||
|
{ "<<", },
|
||||||
|
{ ">>", },
|
||||||
|
{ "~", },
|
||||||
|
|
||||||
|
{ "$", },
|
||||||
|
{ "::", },
|
||||||
|
{ ".", },
|
||||||
|
{ ",", },
|
||||||
|
{ "#", },
|
||||||
|
{ ":", },
|
||||||
|
{ "(", },
|
||||||
|
{ ")", },
|
||||||
|
{ "[", },
|
||||||
|
{ "]", },
|
||||||
|
{ "{", },
|
||||||
|
{ "}", },
|
||||||
|
{ "@", },
|
||||||
|
|
||||||
|
{ "z:", },
|
||||||
|
{ "a:", },
|
||||||
|
{ "f:", },
|
||||||
|
|
||||||
|
{ "macro parameter", },
|
||||||
|
{ "repeat counter", },
|
||||||
|
|
||||||
|
{ ".A16" },
|
||||||
|
{ ".A8" },
|
||||||
|
{ ".ADDR" },
|
||||||
|
{ ".ADDRSIZE" },
|
||||||
|
{ ".ALIGN" },
|
||||||
|
{ ".ASCIIZ" },
|
||||||
|
{ ".ASIZE" },
|
||||||
|
{ ".ASSERT" },
|
||||||
|
{ ".AUTOIMPORT" },
|
||||||
|
{ ".BANK" },
|
||||||
|
{ ".BANKBYTE" },
|
||||||
|
{ ".BANKBYTES" },
|
||||||
|
{ ".BLANK" },
|
||||||
|
{ ".BSS" },
|
||||||
|
{ ".BYTE" },
|
||||||
|
{ ".CAP" },
|
||||||
|
{ ".CASE" },
|
||||||
|
{ ".CHARMAP" },
|
||||||
|
{ ".CODE" },
|
||||||
|
{ ".CONCAT" },
|
||||||
|
{ ".CONDES" },
|
||||||
|
{ ".CONST" },
|
||||||
|
{ ".CONSTRUCTOR" },
|
||||||
|
{ ".CPU" },
|
||||||
|
{ ".DATA" },
|
||||||
|
{ ".DBG" },
|
||||||
|
{ ".DBYT" },
|
||||||
|
{ ".DEBUGINFO" },
|
||||||
|
{ ".DEFINE" },
|
||||||
|
{ ".DEFINED" },
|
||||||
|
{ ".DEFINEDMACRO" },
|
||||||
|
{ ".DELMAC" },
|
||||||
|
{ ".DESTRUCTOR" },
|
||||||
|
{ ".DWORD" },
|
||||||
|
{ ".ELSE" },
|
||||||
|
{ ".ELSEIF" },
|
||||||
|
{ ".END" },
|
||||||
|
{ ".ENDENUM" },
|
||||||
|
{ ".ENDIF" },
|
||||||
|
{ ".ENDMACRO" },
|
||||||
|
{ ".ENDPROC" },
|
||||||
|
{ ".ENDREP" },
|
||||||
|
{ ".ENDSCOPE" },
|
||||||
|
{ ".ENDSTRUCT" },
|
||||||
|
{ ".ENDUNION" },
|
||||||
|
{ ".ENUM" },
|
||||||
|
{ ".ERROR" },
|
||||||
|
{ ".EXITMACRO" },
|
||||||
|
{ ".EXPORT" },
|
||||||
|
{ ".EXPORTZP" },
|
||||||
|
{ ".FARADDR" },
|
||||||
|
{ ".FATAL" },
|
||||||
|
{ ".FEATURE" },
|
||||||
|
{ ".FILEOPT" },
|
||||||
|
{ ".FORCEIMPORT" },
|
||||||
|
{ ".FORCEWORD" },
|
||||||
|
{ ".GLOBAL" },
|
||||||
|
{ ".GLOBALZP" },
|
||||||
|
{ ".HIBYTE" },
|
||||||
|
{ ".HIBYTES" },
|
||||||
|
{ ".HIWORD" },
|
||||||
|
{ ".I16" },
|
||||||
|
{ ".I8" },
|
||||||
|
{ ".MAKEIDENT" },
|
||||||
|
{ ".IF" },
|
||||||
|
{ ".IFBLANK" },
|
||||||
|
{ ".IFCONST" },
|
||||||
|
{ ".IFDEF" },
|
||||||
|
{ ".IFNBLANK" },
|
||||||
|
{ ".IFNCONST" },
|
||||||
|
{ ".IFNDEF" },
|
||||||
|
{ ".IFNREF" },
|
||||||
|
{ ".IFP02" },
|
||||||
|
{ ".IFP02X" },
|
||||||
|
{ ".IFP4510" },
|
||||||
|
{ ".IFP45GS02" },
|
||||||
|
{ ".IFP6280" },
|
||||||
|
{ ".IFP816" },
|
||||||
|
{ ".IFPC02" },
|
||||||
|
{ ".IFPCE02" },
|
||||||
|
{ ".IFPDTV" },
|
||||||
|
{ ".IFPM740" },
|
||||||
|
{ ".IFPSC02" },
|
||||||
|
{ ".IFPSWEET16" },
|
||||||
|
{ ".IFPWC02" },
|
||||||
|
{ ".IFREF" },
|
||||||
|
{ ".IMPORT" },
|
||||||
|
{ ".IMPORTZP" },
|
||||||
|
{ ".INCBIN" },
|
||||||
|
{ ".INCLUDE" },
|
||||||
|
{ ".INTERRUPTOR" },
|
||||||
|
{ ".ISIZE" },
|
||||||
|
{ ".ISMNEMONIC" },
|
||||||
|
{ ".LEFT" },
|
||||||
|
{ ".LINECONT" },
|
||||||
|
{ ".LIST" },
|
||||||
|
{ ".LISTBYTES" },
|
||||||
|
{ ".LITERAL" },
|
||||||
|
{ ".LOBYTE" },
|
||||||
|
{ ".LOBYTES" },
|
||||||
|
{ ".LOCAL" },
|
||||||
|
{ ".LOCALCHAR" },
|
||||||
|
{ ".LOWORD" },
|
||||||
|
{ ".MACPACK" },
|
||||||
|
{ ".MACRO" },
|
||||||
|
{ ".MATCH" },
|
||||||
|
{ ".MAX" },
|
||||||
|
{ ".MID" },
|
||||||
|
{ ".MIN" },
|
||||||
|
{ ".NULL" },
|
||||||
|
{ ".ORG" },
|
||||||
|
{ ".OUT" },
|
||||||
|
{ ".P02" },
|
||||||
|
{ ".P02X" },
|
||||||
|
{ ".P4510" },
|
||||||
|
{ ".P45GS02" },
|
||||||
|
{ ".P6280" },
|
||||||
|
{ ".P816" },
|
||||||
|
{ ".PAGELENGTH" },
|
||||||
|
{ ".PARAMCOUNT" },
|
||||||
|
{ ".PC02" },
|
||||||
|
{ ".PCE02" },
|
||||||
|
{ ".PDTV" },
|
||||||
|
{ ".PM740" },
|
||||||
|
{ ".POPCHARMAP" },
|
||||||
|
{ ".POPCPU" },
|
||||||
|
{ ".POPSEG" },
|
||||||
|
{ ".PROC" },
|
||||||
|
{ ".PSC02" },
|
||||||
|
{ ".PSWEET16" },
|
||||||
|
{ ".PUSHCHARMAP" },
|
||||||
|
{ ".PUSHCPU" },
|
||||||
|
{ ".PUSHSEG" },
|
||||||
|
{ ".PWC02" },
|
||||||
|
{ ".REFERENCED" },
|
||||||
|
{ ".REFERTO" },
|
||||||
|
{ ".RELOC" },
|
||||||
|
{ ".REPEAT" },
|
||||||
|
{ ".RES" },
|
||||||
|
{ ".RIGHT" },
|
||||||
|
{ ".RODATA" },
|
||||||
|
{ ".SCOPE" },
|
||||||
|
{ ".SEGMENT" },
|
||||||
|
{ ".SET" },
|
||||||
|
{ ".SETCPU" },
|
||||||
|
{ ".SIZEOF" },
|
||||||
|
{ ".SMART" },
|
||||||
|
{ ".SPRINTF" },
|
||||||
|
{ ".STRAT" },
|
||||||
|
{ ".STRING" },
|
||||||
|
{ ".STRLEN" },
|
||||||
|
{ ".STRUCT" },
|
||||||
|
{ ".TAG" },
|
||||||
|
{ ".TCOUNT" },
|
||||||
|
{ ".TIME" },
|
||||||
|
{ ".UNDEF" },
|
||||||
|
{ ".UNION" },
|
||||||
|
{ ".VERSION" },
|
||||||
|
{ ".WARNING" },
|
||||||
|
{ ".WORD" },
|
||||||
|
{ ".XMATCH" },
|
||||||
|
{ ".ZEROPAGE" },
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int TokHasIVal (token_t Tok)
|
/*****************************************************************************/
|
||||||
/* Return true if the given token has an attached IVal */
|
/* Code */
|
||||||
{
|
/*****************************************************************************/
|
||||||
return (Tok == TOK_INTCON || Tok == TOK_CHARCON || Tok == TOK_REG);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -72,3 +303,54 @@ void CopyToken (Token* Dst, const Token* Src)
|
|||||||
SB_Copy (&Dst->SVal, &Src->SVal);
|
SB_Copy (&Dst->SVal, &Src->SVal);
|
||||||
Dst->Pos = Src->Pos;
|
Dst->Pos = Src->Pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
StrBuf* TokenDesc (const Token* T, StrBuf* S)
|
||||||
|
/* Place a textual description of the given token into S. */
|
||||||
|
{
|
||||||
|
PRECONDITION (sizeof (TokDesc) / sizeof (TokDesc[0]) == TOK_COUNT);
|
||||||
|
|
||||||
|
/* Clear the target buffer */
|
||||||
|
SB_Clear (S);
|
||||||
|
|
||||||
|
/* Get the description for the token */
|
||||||
|
const char* Desc = TokDesc[T->Tok].Desc;
|
||||||
|
|
||||||
|
/* Repeatedly replace {c}, {i} and {s} */
|
||||||
|
size_t Start = 0;
|
||||||
|
while (1) {
|
||||||
|
const char* P = strchr (Desc + Start, '{');
|
||||||
|
if (P) {
|
||||||
|
/* Check if this is really {c}, {i} or {s} */
|
||||||
|
if ((P[1] != 'c' &&
|
||||||
|
P[1] != 'i' &&
|
||||||
|
P[1] != 's') ||
|
||||||
|
P[2] != '}') {
|
||||||
|
++Start;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
/* Append the text before the replacement token */
|
||||||
|
SB_AppendBuf (S, Desc + Start, P - (Desc + Start));
|
||||||
|
Start += P - (Desc + Start) + 3;
|
||||||
|
/* Append the replacement text */
|
||||||
|
if (P[1] == 'c') {
|
||||||
|
SB_AppendChar (S, (char)T->IVal);
|
||||||
|
} else if (P[1] == 'i') {
|
||||||
|
char Buf[64];
|
||||||
|
snprintf (Buf, sizeof (Buf), "%ld", T->IVal);
|
||||||
|
SB_AppendStr (S, Buf);
|
||||||
|
} else {
|
||||||
|
SB_Append (S, &T->SVal);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* No more replacements found, append remainder */
|
||||||
|
SB_AppendStr (S, Desc + Start);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Zero-terminate the buffer and return it */
|
||||||
|
SB_Terminate (S);
|
||||||
|
return S;
|
||||||
|
}
|
||||||
|
|||||||
147
src/ca65/token.h
147
src/ca65/token.h
@@ -53,76 +53,80 @@
|
|||||||
|
|
||||||
/* Tokens */
|
/* Tokens */
|
||||||
typedef enum token_t {
|
typedef enum token_t {
|
||||||
TOK_NONE, /* Start value, invalid */
|
TOK_NONE, /* Start value, invalid */
|
||||||
TOK_EOF, /* End of input file */
|
TOK_EOF, /* End of input file */
|
||||||
TOK_SEP, /* Separator (usually newline) */
|
TOK_SEP, /* Separator (usually newline) */
|
||||||
TOK_IDENT, /* An identifier */
|
TOK_IDENT, /* An identifier */
|
||||||
TOK_LOCAL_IDENT, /* A cheap local identifier */
|
TOK_LOCAL_IDENT, /* A cheap local identifier */
|
||||||
|
|
||||||
TOK_INTCON, /* Integer constant */
|
TOK_INTCON, /* Integer constant */
|
||||||
TOK_CHARCON, /* Character constant */
|
TOK_CHARCON, /* Character constant */
|
||||||
TOK_STRCON, /* String constant */
|
TOK_STRCON, /* String constant */
|
||||||
|
|
||||||
TOK_A, /* A)ccumulator */
|
TOK_FIRSTREG, /* First register name token */
|
||||||
TOK_X, /* X register */
|
TOK_A = TOK_FIRSTREG, /* A)ccumulator */
|
||||||
TOK_Y, /* Y register */
|
TOK_Q, /* Q pseudo register */
|
||||||
TOK_Z, /* Z register */
|
TOK_S, /* S register */
|
||||||
TOK_S, /* S register */
|
TOK_X, /* X register */
|
||||||
TOK_Q, /* Q pseudo register */
|
TOK_Y, /* Y register */
|
||||||
TOK_REG, /* Sweet16 R.. register (in sweet16 mode) */
|
TOK_Z, /* Z register */
|
||||||
|
TOK_REG, /* Sweet16 R.. register (in sweet16 mode) */
|
||||||
|
TOK_LASTREG = TOK_REG, /* Last register name token */
|
||||||
|
|
||||||
TOK_ASSIGN, /* := */
|
TOK_ASSIGN, /* := */
|
||||||
TOK_ULABEL, /* An unnamed label */
|
TOK_ULABEL, /* An unnamed label */
|
||||||
|
|
||||||
TOK_EQ, /* = */
|
TOK_FIRSTOP, /* First operator token */
|
||||||
TOK_NE, /* <> */
|
TOK_EQ = TOK_FIRSTOP, /* = */
|
||||||
TOK_LT, /* < */
|
TOK_NE, /* <> */
|
||||||
TOK_GT, /* > */
|
TOK_LT, /* < */
|
||||||
TOK_LE, /* <= */
|
TOK_GT, /* > */
|
||||||
TOK_GE, /* >= */
|
TOK_LE, /* <= */
|
||||||
|
TOK_GE, /* >= */
|
||||||
|
|
||||||
TOK_BOOLAND, /* .and */
|
TOK_BOOLAND, /* .and */
|
||||||
TOK_BOOLOR, /* .or */
|
TOK_BOOLOR, /* .or */
|
||||||
TOK_BOOLXOR, /* .xor */
|
TOK_BOOLXOR, /* .xor */
|
||||||
TOK_BOOLNOT, /* .not */
|
TOK_BOOLNOT, /* .not */
|
||||||
|
|
||||||
TOK_PLUS, /* + */
|
TOK_PLUS, /* + */
|
||||||
TOK_MINUS, /* - */
|
TOK_MINUS, /* - */
|
||||||
TOK_MUL, /* * */
|
TOK_MUL, /* * */
|
||||||
TOK_STAR = TOK_MUL, /* Alias */
|
TOK_STAR = TOK_MUL, /* Alias */
|
||||||
TOK_DIV, /* / */
|
TOK_DIV, /* / */
|
||||||
TOK_MOD, /* ! */
|
TOK_MOD, /* ! */
|
||||||
TOK_OR, /* | */
|
TOK_OR, /* | */
|
||||||
TOK_XOR, /* ^ */
|
TOK_XOR, /* ^ */
|
||||||
TOK_AND, /* & */
|
TOK_AND, /* & */
|
||||||
TOK_SHL, /* << */
|
TOK_SHL, /* << */
|
||||||
TOK_SHR, /* >> */
|
TOK_SHR, /* >> */
|
||||||
TOK_NOT, /* ~ */
|
TOK_NOT, /* ~ */
|
||||||
|
TOK_LASTOP = TOK_NOT, /* Last operator token */
|
||||||
|
|
||||||
TOK_PC, /* $ if enabled */
|
TOK_PC, /* $ if enabled */
|
||||||
TOK_NAMESPACE, /* :: */
|
TOK_NAMESPACE, /* :: */
|
||||||
TOK_DOT, /* . */
|
TOK_DOT, /* . */
|
||||||
TOK_COMMA, /* , */
|
TOK_COMMA, /* , */
|
||||||
TOK_HASH, /* # */
|
TOK_HASH, /* # */
|
||||||
TOK_COLON, /* : */
|
TOK_COLON, /* : */
|
||||||
TOK_LPAREN, /* ( */
|
TOK_LPAREN, /* ( */
|
||||||
TOK_RPAREN, /* ) */
|
TOK_RPAREN, /* ) */
|
||||||
TOK_LBRACK, /* [ */
|
TOK_LBRACK, /* [ */
|
||||||
TOK_RBRACK, /* ] */
|
TOK_RBRACK, /* ] */
|
||||||
TOK_LCURLY, /* { */
|
TOK_LCURLY, /* { */
|
||||||
TOK_RCURLY, /* } */
|
TOK_RCURLY, /* } */
|
||||||
TOK_AT, /* @ - in Sweet16 mode */
|
TOK_AT, /* @ - in Sweet16 mode */
|
||||||
|
|
||||||
TOK_OVERRIDE_ZP, /* z: */
|
TOK_OVERRIDE_ZP, /* z: */
|
||||||
TOK_OVERRIDE_ABS, /* a: */
|
TOK_OVERRIDE_ABS, /* a: */
|
||||||
TOK_OVERRIDE_FAR, /* f: */
|
TOK_OVERRIDE_FAR, /* f: */
|
||||||
|
|
||||||
TOK_MACPARAM, /* Macro parameter, not generated by scanner */
|
TOK_MACPARAM, /* Macro parameter, not generated by scanner */
|
||||||
TOK_REPCOUNTER, /* Repeat counter, not generated by scanner */
|
TOK_REPCOUNTER, /* Repeat counter, not generated by scanner */
|
||||||
|
|
||||||
/* The next ones are tokens for the pseudo instructions. Keep together! */
|
/* The next ones are tokens for the pseudo instructions. Keep together! */
|
||||||
TOK_FIRSTPSEUDO,
|
TOK_FIRSTPSEUDO,
|
||||||
TOK_A16 = TOK_FIRSTPSEUDO,
|
TOK_A16 = TOK_FIRSTPSEUDO,
|
||||||
TOK_A8,
|
TOK_A8,
|
||||||
TOK_ADDR,
|
TOK_ADDR,
|
||||||
TOK_ADDRSIZE,
|
TOK_ADDRSIZE,
|
||||||
@@ -284,9 +288,9 @@ typedef enum token_t {
|
|||||||
TOK_WORD,
|
TOK_WORD,
|
||||||
TOK_XMATCH,
|
TOK_XMATCH,
|
||||||
TOK_ZEROPAGE,
|
TOK_ZEROPAGE,
|
||||||
TOK_LASTPSEUDO = TOK_ZEROPAGE,
|
TOK_LASTPSEUDO = TOK_ZEROPAGE,
|
||||||
|
|
||||||
TOK_COUNT /* Count of tokens */
|
TOK_COUNT /* Count of tokens */
|
||||||
} token_t;
|
} token_t;
|
||||||
|
|
||||||
|
|
||||||
@@ -318,11 +322,27 @@ struct Token {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
int TokHasSVal (token_t Tok);
|
#if defined(HAVE_INLINE)
|
||||||
|
INLINE int TokHasSVal (token_t Tok)
|
||||||
/* Return true if the given token has an attached SVal */
|
/* Return true if the given token has an attached SVal */
|
||||||
|
{
|
||||||
|
return (Tok == TOK_IDENT || Tok == TOK_LOCAL_IDENT || Tok == TOK_STRCON);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
# define TokHasIVal(T) \
|
||||||
|
((T) == TOK_IDENT || (T) == TOK_LOCAL_IDENT || (T) == TOK_STRCON)
|
||||||
|
#endif
|
||||||
|
|
||||||
int TokHasIVal (token_t Tok);
|
#if defined(HAVE_INLINE)
|
||||||
|
INLINE int TokHasIVal (token_t Tok)
|
||||||
/* Return true if the given token has an attached IVal */
|
/* Return true if the given token has an attached IVal */
|
||||||
|
{
|
||||||
|
return (Tok == TOK_INTCON || Tok == TOK_CHARCON || Tok == TOK_REG);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
# define TokHasIVal(T) \
|
||||||
|
((T) == TOK_INTCON || (T) == TOK_CHARCON || (T) == TOK_REG)
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(HAVE_INLINE)
|
#if defined(HAVE_INLINE)
|
||||||
INLINE int TokIsSep (enum token_t T)
|
INLINE int TokIsSep (enum token_t T)
|
||||||
@@ -339,6 +359,9 @@ void CopyToken (Token* Dst, const Token* Src);
|
|||||||
** initialized.
|
** initialized.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
StrBuf* TokenDesc (const Token* T, StrBuf* S);
|
||||||
|
/* Place a textual description of the given token into S. */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* End of token.h */
|
/* End of token.h */
|
||||||
|
|||||||
@@ -111,7 +111,7 @@ ExprNode* ULabRef (int Which)
|
|||||||
if (Which == 0) {
|
if (Which == 0) {
|
||||||
Error ("Invalid unnamed label reference");
|
Error ("Invalid unnamed label reference");
|
||||||
/* We must return something valid */
|
/* We must return something valid */
|
||||||
return GenCurrentPC();
|
return GenCurrentPC ();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get the index of the referenced label */
|
/* Get the index of the referenced label */
|
||||||
@@ -125,7 +125,7 @@ ExprNode* ULabRef (int Which)
|
|||||||
/* Label does not exist */
|
/* Label does not exist */
|
||||||
Error ("Undefined label");
|
Error ("Undefined label");
|
||||||
/* We must return something valid */
|
/* We must return something valid */
|
||||||
return GenCurrentPC();
|
return GenCurrentPC ();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if the label exists. If not, generate enough forward labels. */
|
/* Check if the label exists. If not, generate enough forward labels. */
|
||||||
|
|||||||
@@ -1,6 +1,4 @@
|
|||||||
|
|
||||||
.macpack cpu
|
|
||||||
|
|
||||||
; step 1: try to assemble an instruction that's exclusive to this set
|
; step 1: try to assemble an instruction that's exclusive to this set
|
||||||
; (when possible)
|
; (when possible)
|
||||||
|
|
||||||
|
|||||||
1
test/asm/listing/120-errormsg.s
Normal file
1
test/asm/listing/120-errormsg.s
Normal file
@@ -0,0 +1 @@
|
|||||||
|
0:
|
||||||
1
test/asm/listing/121-errormsg.s
Normal file
1
test/asm/listing/121-errormsg.s
Normal file
@@ -0,0 +1 @@
|
|||||||
|
foo
|
||||||
3
test/asm/listing/122-errormsg.s
Normal file
3
test/asm/listing/122-errormsg.s
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
.struct x
|
||||||
|
.word
|
||||||
|
.endstruct
|
||||||
1
test/asm/listing/123-errormsg.s
Normal file
1
test/asm/listing/123-errormsg.s
Normal file
@@ -0,0 +1 @@
|
|||||||
|
lda #$00 foo
|
||||||
1
test/asm/listing/124-errormsg.s
Normal file
1
test/asm/listing/124-errormsg.s
Normal file
@@ -0,0 +1 @@
|
|||||||
|
lda ($00),a
|
||||||
1
test/asm/listing/125-errormsg.s
Normal file
1
test/asm/listing/125-errormsg.s
Normal file
@@ -0,0 +1 @@
|
|||||||
|
lda ($00,a)
|
||||||
3
test/asm/listing/126-errormsg.s
Normal file
3
test/asm/listing/126-errormsg.s
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
.struct foo
|
||||||
|
bar
|
||||||
|
.endstruct
|
||||||
1
test/asm/listing/127-errormsg.s
Normal file
1
test/asm/listing/127-errormsg.s
Normal file
@@ -0,0 +1 @@
|
|||||||
|
127
|
||||||
1
test/asm/listing/128-errormsg.s
Normal file
1
test/asm/listing/128-errormsg.s
Normal file
@@ -0,0 +1 @@
|
|||||||
|
.fileopt author
|
||||||
1
test/asm/listing/129-errormsg.s
Normal file
1
test/asm/listing/129-errormsg.s
Normal file
@@ -0,0 +1 @@
|
|||||||
|
.assert 1
|
||||||
2
test/asm/listing/130-errormsg.s
Normal file
2
test/asm/listing/130-errormsg.s
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
lda |
|
||||||
|
|
||||||
1
test/asm/listing/131-errormsg.s
Normal file
1
test/asm/listing/131-errormsg.s
Normal file
@@ -0,0 +1 @@
|
|||||||
|
.byte 0 1
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
110-capabilities.s:3: Error: Arguments to .CAPABILITY must be identifiers
|
110-capabilities.s:3: Error: Expected a capability name but found ')'
|
||||||
110-capabilities.s:8: Error: Arguments to .CAPABILITY must be identifiers
|
110-capabilities.s:8: Error: Expected a capability name but found 'end-of-line'
|
||||||
110-capabilities.s:8: Error: ')' expected
|
110-capabilities.s:8: Error: Expected ')' but found 'end-of-line'
|
||||||
110-capabilities.s:12: Error: Not a valid capability name: CPU_HAS_BR
|
110-capabilities.s:12: Error: Not a valid capability name: CPU_HAS_BR
|
||||||
110-capabilities.s:17: Error: ')' expected
|
110-capabilities.s:17: Error: Expected ')' but found 'cpu_has_bra8'
|
||||||
110-capabilities.s:17: Error: Unexpected trailing garbage characters
|
110-capabilities.s:17: Error: Expected 'end-of-line' but found 'cpu_has_bra8'
|
||||||
|
|||||||
1
test/asm/listing/ref/120-errormsg.err2
Normal file
1
test/asm/listing/ref/120-errormsg.err2
Normal file
@@ -0,0 +1 @@
|
|||||||
|
120-errormsg.s:1: Error: Expected 'end-of-line' but found '0'
|
||||||
1
test/asm/listing/ref/121-errormsg.err2
Normal file
1
test/asm/listing/ref/121-errormsg.err2
Normal file
@@ -0,0 +1 @@
|
|||||||
|
121-errormsg.s:1: Error: Expected ':' after identifier to form a label but found 'end-of-line'
|
||||||
1
test/asm/listing/ref/122-errormsg.err2
Normal file
1
test/asm/listing/ref/122-errormsg.err2
Normal file
@@ -0,0 +1 @@
|
|||||||
|
122-errormsg.s:1: Error: Expected a struct/union name but found 'X'
|
||||||
1
test/asm/listing/ref/123-errormsg.err2
Normal file
1
test/asm/listing/ref/123-errormsg.err2
Normal file
@@ -0,0 +1 @@
|
|||||||
|
123-errormsg.s:1: Error: Expected 'end-of-line' but found 'foo'
|
||||||
1
test/asm/listing/ref/124-errormsg.err2
Normal file
1
test/asm/listing/ref/124-errormsg.err2
Normal file
@@ -0,0 +1 @@
|
|||||||
|
124-errormsg.s:1: Error: Expected 'Y' but found 'A'
|
||||||
2
test/asm/listing/ref/125-errormsg.err2
Normal file
2
test/asm/listing/ref/125-errormsg.err2
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
125-errormsg.s:1: Error: Expected 'X' or 'S' but found 'A'
|
||||||
|
125-errormsg.s:1: Error: Illegal addressing mode
|
||||||
1
test/asm/listing/ref/126-errormsg.err2
Normal file
1
test/asm/listing/ref/126-errormsg.err2
Normal file
@@ -0,0 +1 @@
|
|||||||
|
126-errormsg.s:2: Error: Expected a storage allocator after the field name but found 'end-of-line'
|
||||||
1
test/asm/listing/ref/127-errormsg.err2
Normal file
1
test/asm/listing/ref/127-errormsg.err2
Normal file
@@ -0,0 +1 @@
|
|||||||
|
127-errormsg.s:1: Error: Expected a mnemonic but found '127'
|
||||||
1
test/asm/listing/ref/128-errormsg.err2
Normal file
1
test/asm/listing/ref/128-errormsg.err2
Normal file
@@ -0,0 +1 @@
|
|||||||
|
128-errormsg.s:1: Error: Expected ',' but found 'end-of-line'
|
||||||
1
test/asm/listing/ref/129-errormsg.err2
Normal file
1
test/asm/listing/ref/129-errormsg.err2
Normal file
@@ -0,0 +1 @@
|
|||||||
|
129-errormsg.s:1: Error: Expected ',' but found 'end-of-line'
|
||||||
2
test/asm/listing/ref/130-errormsg.err2
Normal file
2
test/asm/listing/ref/130-errormsg.err2
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
130-errormsg.s:1: Error: Expected an expression but found '|'
|
||||||
|
130-errormsg.s:1: Error: Expected an expression but found 'end-of-line'
|
||||||
1
test/asm/listing/ref/131-errormsg.err2
Normal file
1
test/asm/listing/ref/131-errormsg.err2
Normal file
@@ -0,0 +1 @@
|
|||||||
|
131-errormsg.s:1: Error: Expected 'end-of-line' but found '1'
|
||||||
Reference in New Issue
Block a user