mirror of
https://github.com/gbdev/rgbds.git
synced 2025-11-20 10:12:06 +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 EQUS Ta The current global 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 _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)
|
||||
|
||||
@@ -39,6 +39,7 @@ static Symbol const *localScope = nullptr; // Current section's local label sco
|
||||
|
||||
static Symbol *PCSymbol;
|
||||
static Symbol *NARGSymbol;
|
||||
static Symbol *SCOPESymbol;
|
||||
static Symbol *globalScopeSymbol;
|
||||
static Symbol *localScopeSymbol;
|
||||
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() {
|
||||
if (!globalScope) {
|
||||
error("`.` has no value outside of a label scope");
|
||||
@@ -296,6 +310,10 @@ Symbol *sym_FindScopedValidSymbol(std::string const &symName) {
|
||||
if (sym == localScopeSymbol && !localScope) {
|
||||
return nullptr;
|
||||
}
|
||||
// `__SCOPE__` has no value outside of a section
|
||||
if (sym == SCOPESymbol && !sect_GetSymbolSection()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return sym;
|
||||
}
|
||||
@@ -683,6 +701,11 @@ void sym_Init(time_t now) {
|
||||
localScopeSymbol->data = localScopeCallback;
|
||||
localScopeSymbol->isBuiltin = true;
|
||||
|
||||
SCOPESymbol = &createSymbol("__SCOPE__"s);
|
||||
SCOPESymbol->type = SYM_EQUS;
|
||||
SCOPESymbol->data = SCOPECallback;
|
||||
SCOPESymbol->isBuiltin = true;
|
||||
|
||||
RSSymbol = sym_AddVar("_RS"s, 0);
|
||||
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