mirror of
https://github.com/pfusik/xasm.git
synced 2024-12-22 00:29:15 +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.algorithm;
|
||||||
import std.array;
|
import std.array;
|
||||||
|
import std.ascii;
|
||||||
import std.conv;
|
import std.conv;
|
||||||
import std.file;
|
import std.file;
|
||||||
import std.math;
|
import std.math;
|
||||||
@ -85,6 +86,7 @@ class Label {
|
|||||||
|
|
||||||
Label[string] labelTable;
|
Label[string] labelTable;
|
||||||
Label currentLabel;
|
Label currentLabel;
|
||||||
|
string lastGlobalLabel;
|
||||||
|
|
||||||
alias int function(int a, int b) OperatorFunction;
|
alias int function(int a, int b) OperatorFunction;
|
||||||
|
|
||||||
@ -261,21 +263,23 @@ void readSpaces() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
string readLabel() {
|
string readLabel() {
|
||||||
string label;
|
int firstColumn = column;
|
||||||
while (!eol()) {
|
while (!eol()) {
|
||||||
char c = line[column++];
|
char c = line[column++];
|
||||||
if (c >= '0' && c <= '9' || c == '_') {
|
if (c >= '0' && c <= '9' || c == '_' || c == '?')
|
||||||
label ~= c;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
c &= 0xdf;
|
c &= 0xdf;
|
||||||
if (c >= 'A' && c <= 'Z') {
|
if (c >= 'A' && c <= 'Z')
|
||||||
label ~= c;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
column--;
|
column--;
|
||||||
break;
|
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;
|
return label >= "A" ? label : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2688,6 +2692,8 @@ void assemblyLine() {
|
|||||||
currentLabel = null;
|
currentLabel = null;
|
||||||
if (label !is null) {
|
if (label !is null) {
|
||||||
if (!inFalseCondition()) {
|
if (!inFalseCondition()) {
|
||||||
|
if (!label.canFind('?'))
|
||||||
|
lastGlobalLabel = label;
|
||||||
if (!pass2) {
|
if (!pass2) {
|
||||||
if (label in labelTable)
|
if (label in labelTable)
|
||||||
throw new AssemblyError("Label declared twice");
|
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
|
unless you use it with the `EQU` directive where it is assigned
|
||||||
the value of the `EQU` argument.
|
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.
|
Instructions and directives must be preceded with some whitespace.
|
||||||
Without leading whitespace they are treated as label names.
|
Without leading whitespace they are treated as label names.
|
||||||
For example:
|
For example:
|
||||||
|
Loading…
Reference in New Issue
Block a user