Files
hakorune/lang/src/compiler/entry/bundle_resolver.hako

118 lines
4.7 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// bundle_resolver.hako — StageB bundling resolver (Boxfirst)
static box BundleResolver {
// Resolve and merge bundles. Returns merged prefix string or null on error.
// Policy:
// - Duplicate named modules are FailFast ([bundle/duplicate] Name)
// - --require-mod Name must appear in named bundles ([bundle/missing] Name)
// - Merge order: bundle-src* → bundle-mod* (in given order)
resolve(bundle_srcs, bundle_names, bundle_mod_srcs, require_mods) {
// Shallow recursion guard to prevent accidental self-recursion in StageB bundler.
{
local depth = env.get("HAKO_STAGEB_BUNDLE_DEPTH")
if depth != null && ("" + depth) != "0" {
print("[stageb/recursion] BundleResolver.resolve recursion detected")
return null
}
env.set("HAKO_STAGEB_BUNDLE_DEPTH", "1")
}
// Alias table via env: HAKO_BUNDLE_ALIAS_TABLE / NYASH_BUNDLE_ALIAS_TABLE
// Format: entries separated by '|||', each entry as 'Name:code'
local table = env.get("HAKO_BUNDLE_ALIAS_TABLE")
if table == null || table == "" { table = env.get("NYASH_BUNDLE_ALIAS_TABLE") }
if table != null && table != "" {
local i = 0
loop(i < table.length()) {
// find next delimiter or end
local j = table.indexOf("|||", i)
local seg = ""
if j >= 0 { seg = table.substring(i, j) } else { seg = table.substring(i, table.length()) }
if seg != "" {
local pos = -1
local k = 0
loop(k < seg.length()) { if seg.substring(k,k+1) == ":" { pos = k break } k = k + 1 }
if pos < 0 { print("[bundle/alias-table/bad] " + seg) return null }
local name = seg.substring(0, pos)
local code = seg.substring(pos+1, seg.length())
if name == "" || code == "" { print("[bundle/alias-table/bad] " + seg) return null }
if bundle_names == null { bundle_names = new ArrayBox() }
if bundle_mod_srcs == null { bundle_mod_srcs = new ArrayBox() }
bundle_names.push(name)
bundle_mod_srcs.push(code)
}
if j < 0 { break }
i = j + 3
}
}
// Env alias injection (TTL, dev-only): HAKO_BUNDLE_ALIAS_<Name> / NYASH_BUNDLE_ALIAS_<Name>
// If a required module is not provided via --bundle-mod, but an env alias
// supplies its code, synthesize a named bundle entry before checks/merge.
if require_mods != null {
local i0 = 0; local rn0 = require_mods.length()
loop(i0 < rn0) {
local need = "" + require_mods.get(i0)
local present = 0
if bundle_names != null {
local j0 = 0; local bn0 = bundle_names.length()
loop(j0 < bn0) { if ("" + bundle_names.get(j0)) == need { present = 1 break } j0 = j0 + 1 }
}
if present == 0 {
local alias_key = "HAKO_BUNDLE_ALIAS_" + need
local code = env.get(alias_key)
if code == null || code == "" { code = env.get("NYASH_BUNDLE_ALIAS_" + need) }
if code != null && code != "" {
if bundle_names == null { bundle_names = new ArrayBox() }
if bundle_mod_srcs == null { bundle_mod_srcs = new ArrayBox() }
bundle_names.push(need)
bundle_mod_srcs.push("" + code)
}
}
i0 = i0 + 1
}
}
// Fail on duplicate names
if bundle_names != null && bundle_names.length() > 1 {
local i = 0; local n = bundle_names.length()
loop(i < n) {
local name_i = "" + bundle_names.get(i)
local j = i + 1
loop(j < n) {
if ("" + bundle_names.get(j)) == name_i {
print("[bundle/duplicate] " + name_i)
return null
}
j = j + 1
}
i = i + 1
}
}
// Check required modules
if require_mods != null && require_mods.length() > 0 {
local idx = 0; local rn = require_mods.length()
loop(idx < rn) {
local need = "" + require_mods.get(idx)
local found = 0
if bundle_names != null {
local j = 0; local bn = bundle_names.length()
loop(j < bn) { if ("" + bundle_names.get(j)) == need { found = 1 break } j = j + 1 }
}
if found == 0 { print("[bundle/missing] " + need) return null }
idx = idx + 1
}
}
// Merge in order: bundle-src* → bundle-mod*
local merged = ""
if bundle_srcs != null {
local i = 0; local m = bundle_srcs.length()
loop(i < m) { merged = merged + bundle_srcs.get(i) + "\n" i = i + 1 }
}
if bundle_mod_srcs != null {
local i2 = 0; local m2 = bundle_mod_srcs.length()
loop(i2 < m2) { merged = merged + bundle_mod_srcs.get(i2) + "\n" i2 = i2 + 1 }
}
// Clear depth guard before returning
env.set("HAKO_STAGEB_BUNDLE_DEPTH", "0")
return merged
}
}