Skip to content

Commit dc8279d

Browse files
committed
Beginning of macro implementation
Some small bugfixes and improvements to line parser Added some more error messages Renamed the demo source file extensions from .asm (too generic) to .6502 (better)
1 parent d7646ae commit dc8279d

16 files changed

+478
-91
lines changed

demo.asm demo.6502

File renamed without changes.

relocdemo.asm relocdemo.6502

File renamed without changes.

src/Makefile

+2-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,8 @@ LDLIBS := -lstdc++ -lm
5151

5252
# Parameters to the executable
5353

54-
PARAMS := -i ../demo.asm -do ../demo.ssd -boot Code
54+
#PARAMS := -i ../demo.6502 -do ../demo.ssd -boot Code
55+
PARAMS := -i ../test.6502 -v
5556

5657

5758

src/Makefile.inc

+1-1
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ deps: folders
192192
code: deps objs $(TARGET)
193193

194194
run:
195-
$(ECHO) Running ... $(TARGET)\n
195+
$(ECHO) Running ... $(TARGET)
196196
$(VB)$(TARGET) $(PARAMS)
197197

198198

src/VS2010/BeebAsm.vcxproj

+2-1
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@
8282
<ClCompile Include="..\expression.cpp" />
8383
<ClCompile Include="..\globaldata.cpp" />
8484
<ClCompile Include="..\lineparser.cpp" />
85+
<ClCompile Include="..\macro.cpp" />
8586
<ClCompile Include="..\main.cpp" />
8687
<ClCompile Include="..\objectcode.cpp" />
8788
<ClCompile Include="..\sourcefile.cpp" />
@@ -94,12 +95,12 @@
9495
<ClInclude Include="..\discimage.h" />
9596
<ClInclude Include="..\globaldata.h" />
9697
<ClInclude Include="..\lineparser.h" />
98+
<ClInclude Include="..\macro.h" />
9799
<ClInclude Include="..\main.h" />
98100
<ClInclude Include="..\objectcode.h" />
99101
<ClInclude Include="..\sourcefile.h" />
100102
<ClInclude Include="..\stringutils.h" />
101103
<ClInclude Include="..\symboltable.h" />
102-
<ClInclude Include="..\tokens.h" />
103104
</ItemGroup>
104105
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
105106
<ImportGroup Label="ExtensionTargets">

src/VS2010/BeebAsm.vcxproj.filters

+5-2
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,9 @@
5454
<ClCompile Include="..\BASIC.cpp">
5555
<Filter>Source Files</Filter>
5656
</ClCompile>
57+
<ClCompile Include="..\macro.cpp">
58+
<Filter>Source Files</Filter>
59+
</ClCompile>
5760
</ItemGroup>
5861
<ItemGroup>
5962
<ClInclude Include="..\asmexception.h">
@@ -83,10 +86,10 @@
8386
<ClInclude Include="..\symboltable.h">
8487
<Filter>Header Files</Filter>
8588
</ClInclude>
86-
<ClInclude Include="..\tokens.h">
89+
<ClInclude Include="..\BASIC.h">
8790
<Filter>Header Files</Filter>
8891
</ClInclude>
89-
<ClInclude Include="..\BASIC.h">
92+
<ClInclude Include="..\macro.h">
9093
<Filter>Header Files</Filter>
9194
</ClInclude>
9295
</ItemGroup>

src/asmexception.h

+5-1
Original file line numberDiff line numberDiff line change
@@ -199,8 +199,12 @@ DEFINE_SYNTAX_EXCEPTION( BadIndexed, "Syntax error in indexed instruction." );
199199
DEFINE_SYNTAX_EXCEPTION( NoIndexedX, "X indexed mode does not exist for this instruction." );
200200
DEFINE_SYNTAX_EXCEPTION( NoIndexedY, "Y indexed mode does not exist for this instruction." );
201201
DEFINE_SYNTAX_EXCEPTION( LabelAlreadyDefined, "Symbol already defined." );
202-
DEFINE_SYNTAX_EXCEPTION( InvalidSymbolName, "Invalid symbol name; must start with a letter and contain only numbers and underscore." );
202+
DEFINE_SYNTAX_EXCEPTION( InvalidSymbolName, "Invalid symbol name; must start with a letter and contain only letters, numbers and underscore." );
203203
DEFINE_SYNTAX_EXCEPTION( SecondPassProblem, "Fatal error: the second assembler pass has generated different code to the first." );
204+
DEFINE_SYNTAX_EXCEPTION( InvalidMacroName, "Invalid macro name; must start with a letter and contain only letters, numbers and underscore." );
205+
DEFINE_SYNTAX_EXCEPTION( NoNestedMacros, "Cannot define one macro inside another." );
206+
DEFINE_SYNTAX_EXCEPTION( EndMacroUnexpected, "ENDMACRO encountered without a matching MACRO directive." );
207+
DEFINE_SYNTAX_EXCEPTION( DuplicateMacroName, "Macro name already defined." );
204208

205209
// meta-language parsing exceptions
206210
DEFINE_SYNTAX_EXCEPTION( NextWithoutFor, "NEXT without FOR." );

src/commands.cpp

+100-7
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,9 @@ const LineParser::Token LineParser::m_gaTokenTable[] =
7070
{ "}", &LineParser::HandleCloseBrace, 0 },
7171
{ "MAPCHAR", &LineParser::HandleMapChar, 0 },
7272
{ "PUTFILE", &LineParser::HandlePutFile, 0 },
73-
{ "PUTBASIC", &LineParser::HandlePutBasic, 0 }
73+
{ "PUTBASIC", &LineParser::HandlePutBasic, 0 },
74+
{ "MACRO", &LineParser::HandleMacro, &SourceFile::StartMacro },
75+
{ "ENDMACRO", &LineParser::HandleEndMacro, &SourceFile::EndMacro }
7476
};
7577

7678

@@ -568,7 +570,7 @@ void LineParser::HandleInclude()
568570
{
569571
string filename( m_line.substr( m_column + 1, endQuotePos - m_column - 1 ) );
570572

571-
if ( GlobalData::Instance().IsFirstPass() )
573+
if ( GlobalData::Instance().ShouldOutputAsm() )
572574
{
573575
cerr << "Including file " << filename << endl;
574576
}
@@ -1049,10 +1051,10 @@ void LineParser::HandleSave()
10491051

10501052
// expect no more
10511053

1052-
if ( AdvanceAndCheckEndOfStatement() )
1054+
if ( m_line[ m_column ] == ',' )
10531055
{
1054-
// found something else - wrong!
1055-
throw AsmException_SyntaxError_InvalidCharacter( m_line, m_column );
1056+
// Unexpected comma (remembering that an expression can validly end with a comma)
1057+
throw AsmException_SyntaxError_UnexpectedComma( m_line, m_column );
10561058
}
10571059

10581060
// OK - do it
@@ -1535,8 +1537,6 @@ void LineParser::HandlePutFile()
15351537
inputFile.read( buffer, fileSize );
15361538
inputFile.close();
15371539

1538-
cout << "Read file " << hostFilename << ": size " << fileSize << " bytes" << ": " << hex << start << " " << exec << endl;
1539-
15401540
if ( GlobalData::Instance().UsesDiscImage() )
15411541
{
15421542
// disc image version of the save
@@ -1656,3 +1656,96 @@ void LineParser::HandlePutBasic()
16561656

16571657
}
16581658

1659+
1660+
/*************************************************************************************************/
1661+
/**
1662+
LineParser::HandleMacro()
1663+
*/
1664+
/*************************************************************************************************/
1665+
void LineParser::HandleMacro()
1666+
{
1667+
if ( !AdvanceAndCheckEndOfStatement() )
1668+
{
1669+
throw AsmException_SyntaxError_EmptyExpression( m_line, m_column );
1670+
}
1671+
1672+
string macroName;
1673+
1674+
if ( isalpha( m_line[ m_column ] ) || m_line[ m_column ] == '_' )
1675+
{
1676+
macroName = GetSymbolName();
1677+
1678+
if ( GlobalData::Instance().IsFirstPass() )
1679+
{
1680+
if ( MacroTable::Instance().Exists( macroName ) )
1681+
{
1682+
throw AsmException_SyntaxError_DuplicateMacroName( m_line, m_column );
1683+
}
1684+
1685+
m_sourceFile->GetCurrentMacro()->SetName( macroName );
1686+
cout << "MACRO '" << macroName << "'" << endl;
1687+
}
1688+
}
1689+
else
1690+
{
1691+
throw AsmException_SyntaxError_InvalidMacroName( m_line, m_column );
1692+
}
1693+
1694+
bool bExpectComma = false;
1695+
bool bHasParameters = false;
1696+
1697+
while ( AdvanceAndCheckEndOfStatement() )
1698+
{
1699+
if ( bExpectComma )
1700+
{
1701+
if ( m_line[ m_column ] == ',' )
1702+
{
1703+
m_column++;
1704+
bExpectComma = false;
1705+
}
1706+
else
1707+
{
1708+
throw AsmException_SyntaxError_MissingComma( m_line, m_column );
1709+
}
1710+
}
1711+
else if ( isalpha( m_line[ m_column ] ) || m_line[ m_column ] == '_' )
1712+
{
1713+
string param = GetSymbolName();
1714+
1715+
if ( GlobalData::Instance().IsFirstPass() )
1716+
{
1717+
m_sourceFile->GetCurrentMacro()->AddParameter( param );
1718+
cout << " param: '" << param << "'" << endl;
1719+
}
1720+
bExpectComma = true;
1721+
bHasParameters = true;
1722+
}
1723+
else
1724+
{
1725+
throw AsmException_SyntaxError_InvalidSymbolName( m_line, m_column );
1726+
}
1727+
}
1728+
1729+
if ( bHasParameters && !bExpectComma )
1730+
{
1731+
throw AsmException_SyntaxError_UnexpectedComma( m_line, m_column - 1 );
1732+
}
1733+
1734+
m_sourceFile->SetCurrentIfCondition(false);
1735+
}
1736+
1737+
1738+
/*************************************************************************************************/
1739+
/**
1740+
LineParser::HandleEndMacro()
1741+
*/
1742+
/*************************************************************************************************/
1743+
void LineParser::HandleEndMacro()
1744+
{
1745+
if ( AdvanceAndCheckEndOfStatement() )
1746+
{
1747+
// found something
1748+
throw AsmException_SyntaxError_InvalidCharacter( m_line, m_column );
1749+
}
1750+
}
1751+

src/lineparser.cpp

+37-21
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
*/
2323
/*************************************************************************************************/
2424

25+
#include <iostream>
2526
#include "lineparser.h"
2627
#include "asmexception.h"
2728
#include "stringutils.h"
@@ -130,6 +131,7 @@ void LineParser::Process()
130131
{
131132
m_column = oldColumn;
132133
SkipStatement();
134+
133135
continue;
134136
}
135137

@@ -210,35 +212,49 @@ void LineParser::SkipStatement()
210212
bool bInQuotes = false;
211213
bool bInSingleQuotes = false;
212214

213-
while ( m_column < m_line.length() && ( bInQuotes || bInSingleQuotes || MoveToNextAtom( ":;\\" ) ) )
215+
int oldColumn = m_column;
216+
217+
if ( m_line[ m_column ] == '{' || m_line[ m_column ] == '}' || m_line[ m_column ] == ':' )
214218
{
215-
if ( m_line[ m_column ] == '\"' && !bInSingleQuotes )
216-
{
217-
bInQuotes = !bInQuotes;
218-
}
219-
else if ( m_line[ m_column ] == '\'' )
219+
m_column++;
220+
}
221+
else if ( m_line[ m_column ] == '\\' || m_line[ m_column ] == ';' )
222+
{
223+
m_column = m_line.length();
224+
}
225+
else
226+
{
227+
while ( m_column < m_line.length() && ( bInQuotes || bInSingleQuotes || MoveToNextAtom( ":;\\{}" ) ) )
220228
{
221-
if ( bInSingleQuotes )
229+
if ( m_line[ m_column ] == '\"' && !bInSingleQuotes )
222230
{
223-
bInSingleQuotes = false;
231+
bInQuotes = !bInQuotes;
224232
}
225-
else if ( m_line[ m_column + 2 ] == '\'' && !bInQuotes )
233+
else if ( m_line[ m_column ] == '\'' )
226234
{
227-
bInSingleQuotes = true;
228-
m_column++;
235+
if ( bInSingleQuotes )
236+
{
237+
bInSingleQuotes = false;
238+
}
239+
else if ( m_line[ m_column + 2 ] == '\'' && !bInQuotes )
240+
{
241+
bInSingleQuotes = true;
242+
m_column++;
243+
}
229244
}
230-
}
231245

232-
m_column++;
246+
m_column++;
247+
}
233248
}
234249

235-
if ( m_line[ m_column ] == '\\' || m_line[ m_column ] == ';' )
250+
if ( m_sourceFile->GetCurrentMacro() != NULL &&
251+
m_line[ oldColumn ] != ':' &&
252+
m_line[ oldColumn ] != '\\' &&
253+
m_line[ oldColumn ] != ';' )
236254
{
237-
m_column = m_line.length();
238-
}
239-
else if ( m_line[ m_column ] == ':' )
240-
{
241-
m_column++;
255+
string command = m_line.substr( oldColumn, m_column - oldColumn );
256+
m_sourceFile->GetCurrentMacro()->AddLine( command );
257+
cout << " '" << command << "'" << endl;
242258
}
243259
}
244260

@@ -378,7 +394,7 @@ bool LineParser::AdvanceAndCheckEndOfLine()
378394
/*************************************************************************************************/
379395
bool LineParser::AdvanceAndCheckEndOfStatement()
380396
{
381-
return MoveToNextAtom( ";:\\" );
397+
return MoveToNextAtom( ";:\\{}" );
382398
}
383399

384400

@@ -398,7 +414,7 @@ bool LineParser::AdvanceAndCheckEndOfStatement()
398414
/*************************************************************************************************/
399415
bool LineParser::AdvanceAndCheckEndOfSubStatement()
400416
{
401-
return MoveToNextAtom( ";:\\," );
417+
return MoveToNextAtom( ";:\\,{}" );
402418
}
403419

404420

src/lineparser.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ class LineParser
4646
private:
4747

4848
typedef void ( LineParser::*TokenHandler )();
49-
typedef void ( SourceFile::*DirectiveHandler )( std::string line, int column );
49+
typedef void ( SourceFile::*DirectiveHandler )( const std::string& line, int column );
5050

5151
struct Token
5252
{
@@ -150,6 +150,8 @@ class LineParser
150150
void HandleMapChar();
151151
void HandlePutFile();
152152
void HandlePutBasic();
153+
void HandleMacro();
154+
void HandleEndMacro();
153155

154156
// expression evaluating methods
155157

0 commit comments

Comments
 (0)