// processSymbols resolves symbol references. func (c *Compiler) processSymbols(ns []Node) []Node { ns = c.collectSymbols(ns) for i, nd := range ns { errorNd := mkErrorNodef(nd) n, ok := nd.(*TextNode) if !ok { continue // skip non-text nodes } for _, r := range n.Symbols { v, ok := c.Symbols[r.Name] if !ok { ns = setNode(ns, i, errorNd("unresolved symbol: %s", r.Name)) c.ErrorCount++ continue } setSpec(n.Text, r.ByteSpec, machine.Word(v)) n.Symbols = n.Symbols[1:] } if len(n.Symbols) != 0 { msg := "unresolved symbols left: " for _, s := range n.Symbols { msg += s.Name + " " } ns = setNode(ns, i, errorNd(msg)) c.ErrorCount++ continue } ns = setNode(ns, i, n) } return ns }
// setSpec replaces range of bits in text defined by spec with those of val. func setSpec(text []machine.Word, spec ByteSpec, val machine.Word) { mask := machine.Word(1<<spec.Size - 1) val &= mask text[spec.Offset] &^= mask text[spec.Offset] &= val << uint(spec.Position) }