mirror of
https://github.com/gbdev/rgbds.git
synced 2025-11-20 18:22:07 +00:00
Implement __SCOPE__ (#1845)
This commit is contained in:
@@ -1729,6 +1729,7 @@ The following symbols are defined by the assembler:
|
|||||||
.It Dv @ Ta Ic EQU Ta PC value (essentially, the current memory address)
|
.It Dv @ Ta Ic EQU Ta PC value (essentially, the current memory address)
|
||||||
.It Dv . Ta Ic EQUS Ta The current global label scope
|
.It Dv . Ta Ic EQUS Ta The current global label scope
|
||||||
.It Dv .. Ta Ic EQUS Ta The current local label scope
|
.It Dv .. Ta Ic EQUS Ta The current local label scope
|
||||||
|
.It Dv __SCOPE__ Ta Ic EQUS Ta The innermost current label scope level (empty, ".", or "..")
|
||||||
.It Dv _RS Ta Ic = Ta _RS Counter
|
.It Dv _RS Ta Ic = Ta _RS Counter
|
||||||
.It Dv _NARG Ta Ic EQU Ta Number of arguments passed to macro, updated by Ic SHIFT
|
.It Dv _NARG Ta Ic EQU Ta Number of arguments passed to macro, updated by Ic SHIFT
|
||||||
.It Dv __ISO_8601_LOCAL__ Ta Ic EQUS Ta ISO 8601 timestamp (local)
|
.It Dv __ISO_8601_LOCAL__ Ta Ic EQUS Ta ISO 8601 timestamp (local)
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ static Symbol const *localScope = nullptr; // Current section's local label sco
|
|||||||
|
|
||||||
static Symbol *PCSymbol;
|
static Symbol *PCSymbol;
|
||||||
static Symbol *NARGSymbol;
|
static Symbol *NARGSymbol;
|
||||||
|
static Symbol *SCOPESymbol;
|
||||||
static Symbol *globalScopeSymbol;
|
static Symbol *globalScopeSymbol;
|
||||||
static Symbol *localScopeSymbol;
|
static Symbol *localScopeSymbol;
|
||||||
static Symbol *RSSymbol;
|
static Symbol *RSSymbol;
|
||||||
@@ -67,6 +68,19 @@ static int32_t NARGCallback() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static std::shared_ptr<std::string> SCOPECallback() {
|
||||||
|
if (localScope) {
|
||||||
|
return std::make_shared<std::string>("..");
|
||||||
|
} else if (globalScope) {
|
||||||
|
return std::make_shared<std::string>(".");
|
||||||
|
} else {
|
||||||
|
if (!sect_GetSymbolSection()) {
|
||||||
|
error("`__SCOPE__` has no value outside of a section");
|
||||||
|
}
|
||||||
|
return std::make_shared<std::string>("");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static std::shared_ptr<std::string> globalScopeCallback() {
|
static std::shared_ptr<std::string> globalScopeCallback() {
|
||||||
if (!globalScope) {
|
if (!globalScope) {
|
||||||
error("`.` has no value outside of a label scope");
|
error("`.` has no value outside of a label scope");
|
||||||
@@ -296,6 +310,10 @@ Symbol *sym_FindScopedValidSymbol(std::string const &symName) {
|
|||||||
if (sym == localScopeSymbol && !localScope) {
|
if (sym == localScopeSymbol && !localScope) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
// `__SCOPE__` has no value outside of a section
|
||||||
|
if (sym == SCOPESymbol && !sect_GetSymbolSection()) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
return sym;
|
return sym;
|
||||||
}
|
}
|
||||||
@@ -683,6 +701,11 @@ void sym_Init(time_t now) {
|
|||||||
localScopeSymbol->data = localScopeCallback;
|
localScopeSymbol->data = localScopeCallback;
|
||||||
localScopeSymbol->isBuiltin = true;
|
localScopeSymbol->isBuiltin = true;
|
||||||
|
|
||||||
|
SCOPESymbol = &createSymbol("__SCOPE__"s);
|
||||||
|
SCOPESymbol->type = SYM_EQUS;
|
||||||
|
SCOPESymbol->data = SCOPECallback;
|
||||||
|
SCOPESymbol->isBuiltin = true;
|
||||||
|
|
||||||
RSSymbol = sym_AddVar("_RS"s, 0);
|
RSSymbol = sym_AddVar("_RS"s, 0);
|
||||||
RSSymbol->isBuiltin = true;
|
RSSymbol->isBuiltin = true;
|
||||||
|
|
||||||
|
|||||||
27
test/asm/scope-level.asm
Normal file
27
test/asm/scope-level.asm
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
assert !def(__SCOPE__)
|
||||||
|
|
||||||
|
section "test", rom0
|
||||||
|
|
||||||
|
assert !def(.)
|
||||||
|
assert !def(..)
|
||||||
|
assert #__SCOPE__ === ""
|
||||||
|
|
||||||
|
Alpha.local1:
|
||||||
|
assert !def(.)
|
||||||
|
assert #.. === "Alpha.local1"
|
||||||
|
assert #__SCOPE__ === ".."
|
||||||
|
|
||||||
|
Beta:
|
||||||
|
assert #. === "Beta"
|
||||||
|
assert !def(..)
|
||||||
|
assert #__SCOPE__ === "."
|
||||||
|
|
||||||
|
Alpha.local2:
|
||||||
|
assert #. === "Beta"
|
||||||
|
assert #.. === "Alpha.local2"
|
||||||
|
assert #__SCOPE__ === ".."
|
||||||
|
|
||||||
|
.newLocal:
|
||||||
|
assert #. === "Beta"
|
||||||
|
assert #.. === "Beta.newLocal"
|
||||||
|
assert #__SCOPE__ === ".."
|
||||||
Reference in New Issue
Block a user