mirror of
https://github.com/pfusik/xasm.git
synced 2024-12-13 00:29:33 +00:00
Enable simple local labels.
This commit is contained in:
parent
d50d484e1f
commit
8f06fec50c
20
source/app.d
20
source/app.d
@ -18,6 +18,7 @@
|
||||
|
||||
import std.algorithm;
|
||||
import std.array;
|
||||
import std.ascii;
|
||||
import std.conv;
|
||||
import std.file;
|
||||
import std.math;
|
||||
@ -85,6 +86,7 @@ class Label {
|
||||
|
||||
Label[string] labelTable;
|
||||
Label currentLabel;
|
||||
string lastGlobalLabel;
|
||||
|
||||
alias int function(int a, int b) OperatorFunction;
|
||||
|
||||
@ -261,21 +263,23 @@ void readSpaces() {
|
||||
}
|
||||
|
||||
string readLabel() {
|
||||
string label;
|
||||
int firstColumn = column;
|
||||
while (!eol()) {
|
||||
char c = line[column++];
|
||||
if (c >= '0' && c <= '9' || c == '_') {
|
||||
label ~= c;
|
||||
if (c >= '0' && c <= '9' || c == '_' || c == '?')
|
||||
continue;
|
||||
}
|
||||
c &= 0xdf;
|
||||
if (c >= 'A' && c <= 'Z') {
|
||||
label ~= c;
|
||||
if (c >= 'A' && c <= 'Z')
|
||||
continue;
|
||||
}
|
||||
column--;
|
||||
break;
|
||||
}
|
||||
string label = line[firstColumn .. column].toUpper;
|
||||
if (label.startsWith('?')) {
|
||||
if (lastGlobalLabel is null)
|
||||
throw new AssemblyError("Global label must be declared first");
|
||||
label = lastGlobalLabel ~ label;
|
||||
}
|
||||
return label >= "A" ? label : null;
|
||||
}
|
||||
|
||||
@ -2688,6 +2692,8 @@ void assemblyLine() {
|
||||
currentLabel = null;
|
||||
if (label !is null) {
|
||||
if (!inFalseCondition()) {
|
||||
if (!label.canFind('?'))
|
||||
lastGlobalLabel = label;
|
||||
if (!pass2) {
|
||||
if (label in labelTable)
|
||||
throw new AssemblyError("Label declared twice");
|
||||
|
@ -95,6 +95,28 @@ The label will be assigned the current value of the 'origin counter'
|
||||
unless you use it with the `EQU` directive where it is assigned
|
||||
the value of the `EQU` argument.
|
||||
|
||||
Any label name starting with `?` (question mark) refers to a 'local label'.
|
||||
It is implicitly prefixed with the name of the most recently defined
|
||||
'global label' (i.e. a label without any `?` in name),
|
||||
and stays visible until another global label is defined.
|
||||
It is still possible to access a local label from anywhere in the source
|
||||
by specifying its full name.
|
||||
Local labels provide a way to reuse common, short label names while keeping
|
||||
them unique.
|
||||
Example:
|
||||
----
|
||||
foo ldy #0
|
||||
?loop lda data,y ; full label name is FOO?LOOP
|
||||
beq ?ret
|
||||
jsr sendByte
|
||||
iny:bne ?loop
|
||||
?ret rts
|
||||
|
||||
bar lda baz
|
||||
beq foo?ret ; ok
|
||||
bne ?loop ; ERROR: Undeclared label: BAR?LOOP
|
||||
----
|
||||
|
||||
Instructions and directives must be preceded with some whitespace.
|
||||
Without leading whitespace they are treated as label names.
|
||||
For example:
|
||||
|
Loading…
Reference in New Issue
Block a user