Skip to main content
Version: 1.0.1

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 kindDeclared byTypical references
VariablesDeclareVariableCommand (DCL)&VAR in CHGVAR, conditions, parameters
SubroutinesSubroutine (SUBR…ENDSUBR)CALLSUBR
LabelsCLLabelGOTO 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.

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")
}

Resolve a compilation unit​

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")
}
}

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

  • &RC in CHGVAR refers to the DeclareVariableCommand
  • DOWORK on CALLSUBR refers to the Subroutine
  • DONE on GOTO refers to the CLLabel

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.