AGC assembly graphs¶
codingest parses yaYUL Apollo Guidance Computer source (.agc) without running
the assembler. Identifiers are qualified by the top-level program directory,
so Comanche055.START and Luminary099.START are independent graph symbols.
Nodes¶
Executable labels remain Function nodes so ordinary cross-language queries
continue to work. They carry symbol_kind = "agc_label"; labels reached by a
resolved returning call also carry the conservative role_hint = "routine".
Branch-only, computed-dispatch, externally entered, and fall-through labels are
not guessed to be routines.
Data definitions are Constant nodes. Their kind preserves the yaYUL
pseudo-op, including agc_equals, agc_equals_alias, agc_erase, numeric
literals, address words, and verb/noun codes. ERASE symbols additionally carry
is_mutable = true and storage = "erasable".
Relationships¶
Relationship |
Meaning |
|---|---|
|
Returning |
|
Non-returning |
|
Conditional BZF/BZMF transfer |
|
Exact program-local access from an executable label to data |
|
Resolved symbolic EQUALS or |
|
Resolved ADRES/CADR/ECADR/GENADR/BBCON definition |
Control edges preserve their source lines and count. raw_targets, offsets,
via, and address_lines retain source spelling, signed offsets, inter-bank
mechanisms, and consumed CADR/FCADR lines when present. REFERENCES retains its
legacy first line and adds reference_lines, reference_count, opcodes,
accesses, has_read, has_write, and has_address.
Register-indirect and relative-only transfers are retained internally as
unresolved sites but do not fabricate graph edges. In particular, TC Q is a
return idiom; BANKJUMP and SWCALL receive their destination through register A;
and CCS operand accesses data rather than branching to that operand.
Queries¶
Find returning callers of a routine:
MATCH (caller:Function)-[r:CALLS]->(target:Function)
WHERE target.qualified_name = 'Comanche055.IMUSTALL'
RETURN caller.qualified_name, r.call_lines, r.via
ORDER BY caller.qualified_name
Keep jumps and conditional branches distinct:
MATCH (source:Function)-[r:JUMPS_TO|BRANCHES_TO]->(target:Function)
WHERE target.qualified_name = 'Luminary099.ENDOFJOB'
RETURN type(r), source.qualified_name, r.transfer_lines
Find writes to erasable storage:
MATCH (source:Function)-[r:REFERENCES]->(data:Constant)
WHERE r.has_write = true AND data.storage = 'erasable'
RETURN data.qualified_name, source.qualified_name, r.opcodes, r.reference_lines
ORDER BY data.qualified_name
Traverse aliases and address constants without discarding their source names:
MATCH (symbol:Constant)-[r:ALIAS_OF|POINTS_TO]->(target)
RETURN symbol.qualified_name, type(r), target.qualified_name, r.raw_target
Deliberate limits¶
The graph does not claim a static bank for every symbol. BANK changes are implicit and EBANK can be dynamic, so a bank model requires assembler-grade state tracking. Instruction-level relative skip control flow (including CCS) is likewise outside this label-level graph. Missing edges for those cases mean “not statically established,” not “no runtime transfer.”