- pre-implementation-handtrace-round11(.md/-brief.md) → m2-implementation-round11*
(사용자: 구현 중 문서라 pre-implementation이 안 맞음), 인용처 22곳 일괄 치환
- 명명 규약(사용자 확정, README qa-request/ 행): mN-implementation-roundNN —
라운드 번호는 마일스톤을 가로질러 단순 증가("m3 진행 중 m2 하자로 돌아가는
경우도 있을 것"), 마일스톤 접두가 소속을 담음. round1~10 옛 이름은 실제로
구현 전 라운드라 유지
- CLAUDE.md/project-context.md 머리말: M0~M2 완료, 다음은 M3(디스패치 엔진);
todos 00 종결 표기 — 다음 액션은 M3 착수 규약 문항(사용자와 정할 것)
Co-authored-by: qwreey <me@qwreey.moe>
Claude-Session: https://claude.ai/code/session_01LF78pXeFGD1ZSVD3ifteYG
136 lines
4.1 KiB
Text
136 lines
4.1 KiB
Text
--[[
|
|
Brand — instance brands, one weak-key set per brand.
|
|
`.claude/base/brand-plan.md` "구현 — 인스턴스 브랜드" / "`isX` wrapper" sections,
|
|
as-is.
|
|
|
|
`Brand()` makes one brand object holding a weak-key member set; a value
|
|
registers itself into the brand(s) it belongs to (multi-tagging is the
|
|
point — `Source` is both `SourceBrand` and `EpochBrand`). There is no
|
|
reverse lookup (`Brand.get(x) -> tag` was reversed, see
|
|
`archive/brand-shared-registry-reversed.md`).
|
|
|
|
Every brand instance lives in this leaf file (M2 first-unit plan,
|
|
`qa-request/m2-implementation-round11-brief.md` §6): `EpochBrand`
|
|
is shared by `Source`/`Ref`/`GateNode`, so keeping the instances per type
|
|
module would force a circular require. Each *type* still registers only
|
|
into its own brand at its own construction sites; subtype relations are
|
|
expressed once, in the predicate (`isState`/`isRef` below), never by
|
|
double registration.
|
|
|
|
Method names are lowercase (`:register`/`:is`) on purpose — this is a
|
|
base-internal utility, not a public quad surface (`brand-plan.md`).
|
|
|
|
`Brand` depends on nothing. In particular there is no `None` special
|
|
case here — `isNone` is `v == None` and lives with `None.luau` (M3).
|
|
]]
|
|
|
|
export type Brand = {
|
|
register: (self: Brand, x: any) -> (),
|
|
is: (self: Brand, x: any) -> boolean,
|
|
}
|
|
|
|
local function Brand(): Brand
|
|
local members = setmetatable({}, { __mode = "k" }) :: { [any]: true }
|
|
return {
|
|
register = function(_self: Brand, x: any)
|
|
members[x] = true
|
|
end,
|
|
is = function(_self: Brand, x: any): boolean
|
|
return members[x] == true
|
|
end,
|
|
}
|
|
end
|
|
|
|
-- Each type owns exactly one brand. The full list is declared here even for
|
|
-- types that arrive in later milestones (`Tag`/`Attribute`/`Tween`/`Slot`)
|
|
-- so that the set of brands has one source; their `is*` predicates are added
|
|
-- with the type.
|
|
local ObserverBrand = Brand()
|
|
local EffectBrand = Brand()
|
|
local TagBrand = Brand()
|
|
local AttributeBrand = Brand()
|
|
local TweenBrand = Brand()
|
|
local BlockerBrand = Brand()
|
|
local StateBrand = Brand()
|
|
local SourceBrand = Brand()
|
|
local StoreBrand = Brand()
|
|
local SlotBrand = Brand()
|
|
local RefBrand = Brand()
|
|
local PreRefBrand = Brand()
|
|
local PostRefBrand = Brand()
|
|
local ModifierBrand = Brand()
|
|
local EpochBrand = Brand()
|
|
|
|
-- Plain identity predicates.
|
|
local function isEpoch(x: any): boolean
|
|
return EpochBrand:is(x)
|
|
end
|
|
local function isSource(x: any): boolean
|
|
return SourceBrand:is(x)
|
|
end
|
|
local function isStore(x: any): boolean
|
|
return StoreBrand:is(x)
|
|
end
|
|
local function isObserver(x: any): boolean
|
|
return ObserverBrand:is(x)
|
|
end
|
|
local function isEffect(x: any): boolean
|
|
return EffectBrand:is(x)
|
|
end
|
|
local function isBlocker(x: any): boolean
|
|
return BlockerBrand:is(x)
|
|
end
|
|
local function isModifier(x: any): boolean
|
|
return ModifierBrand:is(x)
|
|
end
|
|
|
|
-- Subtype relations: the more specific predicate is defined first and the
|
|
-- wider one is composed on top of it, so the direction of inclusion is
|
|
-- visible in the code (`brand-plan.md`).
|
|
local function isState(x: any): boolean
|
|
return isSource(x) or StateBrand:is(x) -- Source structurally satisfies State
|
|
end
|
|
|
|
local function isPreRef(x: any): boolean
|
|
return PreRefBrand:is(x)
|
|
end
|
|
local function isPostRef(x: any): boolean
|
|
return PostRefBrand:is(x)
|
|
end
|
|
local function isRef(x: any): boolean
|
|
-- PreRef/PostRef reuse the Ref runtime = both are a kind of Ref.
|
|
-- They are exclusive siblings of each other.
|
|
return isPreRef(x) or isPostRef(x) or RefBrand:is(x)
|
|
end
|
|
|
|
return {
|
|
Brand = Brand,
|
|
|
|
ObserverBrand = ObserverBrand,
|
|
EffectBrand = EffectBrand,
|
|
TagBrand = TagBrand,
|
|
AttributeBrand = AttributeBrand,
|
|
TweenBrand = TweenBrand,
|
|
BlockerBrand = BlockerBrand,
|
|
StateBrand = StateBrand,
|
|
SourceBrand = SourceBrand,
|
|
StoreBrand = StoreBrand,
|
|
SlotBrand = SlotBrand,
|
|
RefBrand = RefBrand,
|
|
PreRefBrand = PreRefBrand,
|
|
PostRefBrand = PostRefBrand,
|
|
ModifierBrand = ModifierBrand,
|
|
EpochBrand = EpochBrand,
|
|
|
|
isEpoch = isEpoch,
|
|
isSource = isSource,
|
|
isState = isState,
|
|
isStore = isStore,
|
|
isObserver = isObserver,
|
|
isEffect = isEffect,
|
|
isBlocker = isBlocker,
|
|
isModifier = isModifier,
|
|
isRef = isRef,
|
|
isPreRef = isPreRef,
|
|
isPostRef = isPostRef,
|
|
}
|