Implement __SCOPE__ (#1845)

This commit is contained in:
Rangi
2025-10-04 16:41:21 -04:00
committed by GitHub
parent 13e85b5151
commit 7733ccdeb6
3 changed files with 51 additions and 0 deletions

View File

@@ -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)

View File

@@ -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
View 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__ === ".."