Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -643,10 +643,39 @@ Abort assembly if any of the expressions is false.

Seed the random number generator used by the RND() function. If this is not used, the random number generator is seeded based on the current time and so each build of a program using `RND()` will be different.


`ASM <str>`

Assemble the supplied assembly language string. For example `ASM "LDA #&41"`.


`DEFINE <var-name> <expr>`

Evaluates `<var-name>` as the name of a variable to define with value `<expr>`. The `<var-name>` expressison must be a string, for example `DEFINE "addr" &70`. It is not possible to re-assign variables.

This must be used instead of `=` when the variable name needs to be generated dynamically such as from macro arguments, for example:

```
MACRO VIA name, base_addr
DEFINE name, addr
DEFINE name + "_IOR_B", base_addr
DEFINE name + "_IOR_A", base_addr + 1
DEFINE name + "_DDR_B", base_addr + 2
DEFINE name + "_DDR_A", base_addr + 3
; ...
; ...
ENDMACRO

VIA SYSVIA, &FE40
VIA USERVIA, &FE60
```


`ASSIGN <var-name> <expr>`

Does the same thing as `DEFINE <var-name> <expr>` except that it can be used to change the value of a variable.


## 7. TIPS AND TRICKS

BeebAsm's approach of treating memory as a canvas which can be written to, saved, and rewritten if desired makes it very easy to create certain types of applications.
Expand Down
75 changes: 74 additions & 1 deletion src/commands.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,9 @@ const LineParser::Token LineParser::m_gaTokenTable[] =
{ "ERROR", &LineParser::HandleError, 0 },
{ "COPYBLOCK", &LineParser::HandleCopyBlock, 0 },
{ "RANDOMIZE", &LineParser::HandleRandomize, 0 },
{ "ASM", &LineParser::HandleAsm, 0 }
{ "ASM", &LineParser::HandleAsm, 0 },
{ "DEFINE", &LineParser::HandleDefine, 0 },
{ "ASSIGN", &LineParser::HandleAssign, 0 }
};


Expand Down Expand Up @@ -1876,3 +1878,74 @@ void LineParser::HandleAsm()

parser.HandleAssembler(instruction);
}

/*************************************************************************************************/
/**
LineParser::HandleDefineAssignCommon()
LineParser::HandleDefine()
LineParser::HandleAssign()
*/
/*************************************************************************************************/
void LineParser::HandleDefineAssignCommon( bool bAllowRedefinition )
{
string name = EvaluateExpressionAsString();

if ( name.empty() || ! ( isalpha( name[0] ) || name[0] == '_' ) )
{
throw AsmException_SyntaxError_InvalidSymbolName( m_line, m_column );
}
for (std::string::size_type i = 1, e = name.size(); i < e; ++i)
{
if ( ! ( ( isalpha( name[ i ] ) ||
isdigit( name[ i ] ) ||
name[ i ] == '_' ||
name[ i ] == '%' ||
name[ i ] == '$' ) &&
name[ i - 1 ] != '%' &&
name[ i - 1 ] != '$' ) )
{
throw AsmException_SyntaxError_InvalidSymbolName( m_line, m_column );
}
}

if ( ! ( AdvanceAndCheckEndOfStatement() && m_line[ m_column ] == ',' ) )
{
throw AsmException_SyntaxError_MissingComma( m_line, m_column );
}

++m_column;
if ( ! AdvanceAndCheckEndOfStatement() )
{
throw AsmException_SyntaxError_MissingValue( m_line, m_column );
}

Value value = EvaluateExpression();

if ( AdvanceAndCheckEndOfStatement() )
{
throw AsmException_SyntaxError_InvalidCharacter( m_line, m_column );
}

if ( GlobalData::Instance().IsFirstPass() )
{
if ( SymbolTable::Instance().IsSymbolDefined( name ) )
{
if ( !bAllowRedefinition )
{
throw AsmException_SyntaxError_LabelAlreadyDefined( m_line, m_column );
}
SymbolTable::Instance().RemoveSymbol( name );
}
SymbolTable::Instance().AddSymbol( name, value );
}
}

void LineParser::HandleDefine()
{
HandleDefineAssignCommon( false );
}

void LineParser::HandleAssign()
{
HandleDefineAssignCommon( true );
}
3 changes: 3 additions & 0 deletions src/lineparser.h
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,9 @@ class LineParser
void HandleCopyBlock();
void HandleRandomize();
void HandleAsm();
void HandleDefineAssignCommon( bool bAllowRedefinition );
void HandleDefine();
void HandleAssign();

// expression evaluating methods

Expand Down
23 changes: 23 additions & 0 deletions test/3-directives/assign/define-variable.6502
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
\ Assign examples

ASSIGN "v1",27183
ASSERT v1 = 27183

ASSIGN "v2",v1+1
ASSERT v2 = 27184

prefix = "v"
ASSIGN prefix + "3", "A string"
ASSERT v3 = "A string"

ASSIGN "_a",1
ASSERT _a = 1

ASSIGN "a_",2
ASSERT a_ = 2

ASSIGN "a$","str"
ASSERT a$ = "str"

ASSIGN "a%",3
ASSERT a% = 3
2 changes: 2 additions & 0 deletions test/3-directives/assign/name-contains-bang.fail.6502
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
\ Variable name cannot contain general punctuation
ASSIGN "a!b",13
1 change: 1 addition & 0 deletions test/3-directives/assign/name-contains-bang.fail.gold.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
error: Invalid symbol name; must start with a letter
2 changes: 2 additions & 0 deletions test/3-directives/assign/name-contains-dollar.fail.6502
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
\ Variable name cannot contain a dollar
ASSIGN "a$b",13
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
error: Invalid symbol name; must start with a letter
2 changes: 2 additions & 0 deletions test/3-directives/assign/name-contains-percent.fail.6502
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
\ Variable name cannot contain a percent
ASSIGN "a%b",13
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
error: Invalid symbol name; must start with a letter
2 changes: 2 additions & 0 deletions test/3-directives/assign/name-empty.fail.6502
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
\ Variable name can't be empty
ASSIGN "",13
1 change: 1 addition & 0 deletions test/3-directives/assign/name-empty.fail.gold.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
error: Invalid symbol name; must start with a letter
2 changes: 2 additions & 0 deletions test/3-directives/assign/name-not-string.fail.6502
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
\ Variable name must be a string.
ASSIGN 1,13
1 change: 1 addition & 0 deletions test/3-directives/assign/name-not-string.fail.gold.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
error: Type mismatch
2 changes: 2 additions & 0 deletions test/3-directives/assign/name-starts-with-dollar.fail.6502
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
\ Variable name can't start with $
ASSIGN "$a",13
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
error: Invalid symbol name; must start with a letter
2 changes: 2 additions & 0 deletions test/3-directives/assign/name-starts-with-number.fail.6502
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
\ Variable name can't start with a number
ASSIGN "1a",13
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
error: Invalid symbol name; must start with a letter
2 changes: 2 additions & 0 deletions test/3-directives/assign/name-starts-with-percent.fail.6502
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
\ Variable name can't start with %
ASSIGN "%a",13
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
error: Invalid symbol name; must start with a letter
4 changes: 4 additions & 0 deletions test/3-directives/assign/redefine.6502
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
\ Can reassign variables
a = 12
ASSIGN "a",13
ASSERT a = 13
23 changes: 23 additions & 0 deletions test/3-directives/define/define-variable.6502
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
\ Define examples

DEFINE "v1",27183
ASSERT v1 = 27183

DEFINE "v2",v1+1
ASSERT v2 = 27184

prefix = "v"
DEFINE prefix + "3", "A string"
ASSERT v3 = "A string"

DEFINE "_a",1
ASSERT _a = 1

DEFINE "a_",2
ASSERT a_ = 2

DEFINE "a$","str"
ASSERT a$ = "str"

DEFINE "a%",3
ASSERT a% = 3
2 changes: 2 additions & 0 deletions test/3-directives/define/name-contains-bang.fail.6502
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
\ Variable name cannot contain general punctuation
DEFINE "a!b",13
1 change: 1 addition & 0 deletions test/3-directives/define/name-contains-bang.fail.gold.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
error: Invalid symbol name; must start with a letter
2 changes: 2 additions & 0 deletions test/3-directives/define/name-contains-dollar.fail.6502
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
\ Variable name cannot contain a dollar
DEFINE "a$b",13
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
error: Invalid symbol name; must start with a letter
2 changes: 2 additions & 0 deletions test/3-directives/define/name-contains-percent.fail.6502
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
\ Variable name cannot contain a percent
DEFINE "a%b",13
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
error: Invalid symbol name; must start with a letter
2 changes: 2 additions & 0 deletions test/3-directives/define/name-empty.fail.6502
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
\ Variable name can't be empty
DEFINE "",13
1 change: 1 addition & 0 deletions test/3-directives/define/name-empty.fail.gold.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
error: Invalid symbol name; must start with a letter
2 changes: 2 additions & 0 deletions test/3-directives/define/name-not-string.fail.6502
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
\ Variable name must be a string.
DEFINE 1,13
1 change: 1 addition & 0 deletions test/3-directives/define/name-not-string.fail.gold.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
error: Type mismatch
2 changes: 2 additions & 0 deletions test/3-directives/define/name-starts-with-dollar.fail.6502
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
\ Variable name can't start with $
DEFINE "$a",13
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
error: Invalid symbol name; must start with a letter
2 changes: 2 additions & 0 deletions test/3-directives/define/name-starts-with-number.fail.6502
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
\ Variable name can't start with a number
DEFINE "1a",13
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
error: Invalid symbol name; must start with a letter
2 changes: 2 additions & 0 deletions test/3-directives/define/name-starts-with-percent.fail.6502
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
\ Variable name can't start with %
DEFINE "%a",13
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
error: Invalid symbol name; must start with a letter
3 changes: 3 additions & 0 deletions test/3-directives/define/redefine.fail.6502
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
\ Can't redefine variables
a = 12
DEFINE "a",13
1 change: 1 addition & 0 deletions test/3-directives/define/redefine.fail.gold.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
error: Symbol already defined
3 changes: 1 addition & 2 deletions test/testrunner.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ def run_test(beebasm, path, file_names, file_name):
# Duplicate captured data on stdout
sys.stdout.write(capture)
with open(gold_txt, 'r') as gold_file:
gold = gold_file.read()
gold = gold_file.read().strip()
print('Comparing beebasm output to', gold_txt, end = '')
if capture.find(gold) != -1:
print(' succeeded')
Expand Down Expand Up @@ -199,4 +199,3 @@ def parse_args():
except TestFailure as e:
print("FAILURE: " + e.args[0], file = original_stdout)
sys.exit(1)