Resolve Symbols
The semantics module binds CLReferenceExpr names to declarations in scope. After resolution, each reference's ReferenceByName points at the defining node when a match exists.
CL name lookup is case-insensitive (&CURDATE and &curdate are the same symbol).
What gets resolved
| Symbol kind | Declared by | Typical references |
|---|---|---|
| Variables | DeclareVariableCommand (DCL) | &VAR in CHGVAR, conditions, parameters |
| Subroutines | Subroutine (SUBR…ENDSUBR) | CALLSUBR |
| Labels | CLLabel | GOTO CMDLBL(...) |
Scopes nest as compilation unit → procedure (PGM) → subroutine. Variables declared in a procedure are visible inside its subroutines; labels inside a subroutine are local to that body.
Add Dependencies
You need both the AST/parser artifact and the semantics module.
- Kotlin
- Java
repositories {
mavenLocal()
mavenCentral()
flatDir {
dirs("deps")
}
}
dependencies {
implementation(files("deps/clparser-with-dependencies-1.0.1-all.jar"))
implementation(files("deps/clparser-symbol-resolution-1.0.1.jar"))
implementation("com.strumenta.kolasu:kolasu-semantics:1.5.107")
implementation("com.strumenta.kolasu:kolasu-codebase:1.5.107")
}
repositories {
mavenLocal()
mavenCentral()
flatDir {
dirs("deps")
}
}
dependencies {
implementation(files("deps/clparser-with-dependencies-1.0.1-all.jar"))
implementation(files("deps/clparser-symbol-resolution-1.0.1.jar"))
implementation("com.strumenta.kolasu:kolasu-semantics:1.5.107")
implementation("com.strumenta.kolasu:kolasu-codebase:1.5.107")
implementation("com.strumenta.kolasu:kolasu-javalib:1.5.107")
}
Resolve a compilation unit
- Kotlin
- Java
import com.strumenta.cl.model.CLReferenceExpr
import com.strumenta.cl.parser.CLKolasuParser
import com.strumenta.cl.semantics.CLSemantics
import com.strumenta.kolasu.commercial.LicenseManager
import com.strumenta.kolasu.traversing.walkDescendants
import java.io.File
fun resolveAndReport(clFile: File, license: File) {
LicenseManager.registerLicense(license)
val root = CLKolasuParser().parse(clFile).root ?: return
val refsBefore = root.walkDescendants(CLReferenceExpr::class).toList()
val unresolvedBefore = refsBefore.count { it.name.referred == null }
println("References before resolve: ${refsBefore.size} ($unresolvedBefore unbound)")
CLSemantics().resolve(root)
val refs = root.walkDescendants(CLReferenceExpr::class).toList()
refs.forEach { ref ->
val target = ref.name.referred
val status = if (target != null) {
"→ ${target::class.simpleName} ${target.name}"
} else {
"→ <unresolved>"
}
println("${ref.name.name} $status")
}
}
import com.strumenta.cl.model.CLCompilationUnit;
import com.strumenta.cl.model.CLReferenceExpr;
import com.strumenta.cl.parser.CLKolasuParser;
import com.strumenta.cl.semantics.CLSemantics;
import com.strumenta.kolasu.commercial.LicenseManager;
import com.strumenta.kolasu.javalib.Traversing;
import com.strumenta.kolasu.model.Named;
import java.io.File;
public class ResolveSymbols {
public static void resolveAndReport(File clFile, File license) {
LicenseManager.INSTANCE.registerLicense(license);
CLCompilationUnit root = new CLKolasuParser().parse(clFile).getRoot();
if (root == null) return;
new CLSemantics().resolve(root);
Traversing.walkDescendantsBreadthFirst(root, CLReferenceExpr.class, node -> {
CLReferenceExpr ref = (CLReferenceExpr) node;
Named target = ref.getName().getReferred();
String status = target != null
? "→ " + target.getClass().getSimpleName() + " " + target.getName()
: "→ <unresolved>";
System.out.println(ref.getName().getName() + " " + status);
});
}
}
Example
Given source like:
PGM
DCL VAR(&RC) TYPE(*INT) LEN(4)
CALLSUBR SUBR(DOWORK)
GOTO CMDLBL(DONE)
SUBR SUBR(DOWORK)
CHGVAR VAR(&RC) VALUE(1)
ENDSUBR
DONE: SNDPGMMSG MSG('done')
ENDPGM
After CLSemantics().resolve(cu):
&RCinCHGVARrefers to theDeclareVariableCommandDOWORKonCALLSUBRrefers to theSubroutineDONEonGOTOrefers to theCLLabel
Codebase enrichment
For StarLasu pipelines, Codebase.semanticEnrichment in the semantics module wraps per-file resolve over a codebase file. Prefer the single-unit CLSemantics().resolve(cu) API shown above for scripts and unit tests.