record.mx raw

   1  package iskra
   2  
   3  import "git.smesh.lol/iskradb/lattice"
   4  
   5  // NullLatticeRec mirrors lattice.NullRec for use in iskra without importing lattice everywhere.
   6  const NullLatticeRec = lattice.NullRec
   7  
   8  // KindToBranch maps a NodeKind to the iskradb branch it belongs to.
   9  func KindToBranch(kind NodeKind) lattice.Branch {
  10  	if kind.Has(KindFunc | KindMethod) {
  11  		return lattice.Bverb
  12  	}
  13  	if kind.Has(KindType | KindPkg | KindImport | KindConst | KindVar) {
  14  		return lattice.Bnoun
  15  	}
  16  	return lattice.Bmodifier
  17  }
  18  
  19  // otherBranches returns the two branches that are not b, in a stable order.
  20  func otherBranches(b lattice.Branch) [2]lattice.Branch {
  21  	switch b {
  22  	case lattice.Bnoun:
  23  		return [2]lattice.Branch{lattice.Bverb, lattice.Bmodifier}
  24  	case lattice.Bverb:
  25  		return [2]lattice.Branch{lattice.Bnoun, lattice.Bmodifier}
  26  	default: // Bmodifier
  27  		return [2]lattice.Branch{lattice.Bnoun, lattice.Bverb}
  28  	}
  29  }
  30  
  31  // SetFormOnRecord stores form in rec.Inline (up to 23 bytes) or overflows
  32  // into pool with rec.DataFile=1, rec.DataOff/DataLen pointing into pool.
  33  func SetFormOnRecord(rec *lattice.Record, form string, pool *[]byte) {
  34  	b := []byte(form)
  35  	if len(b) <= 23 {
  36  		copy(rec.Inline[:], b)
  37  		rec.Inline[23] = byte(len(b)) // length in last byte
  38  		rec.DataFile = 0
  39  		rec.DataOff = 0
  40  		rec.DataLen = 0
  41  	} else {
  42  		copy(rec.Inline[:23], b[:23])
  43  		rec.Inline[23] = 0 // overflow marker: length=0 means overflow
  44  		rec.DataFile = 1
  45  		rec.DataOff = uint32(len(*pool))
  46  		rec.DataLen = uint32(len(b))
  47  		*pool = append(*pool, b...)
  48  	}
  49  }
  50  
  51  // FormFromRecord retrieves the surface form from rec.
  52  func FormFromRecord(rec *lattice.Record, pool []byte) string {
  53  	if rec.Inline[23] != 0 {
  54  		// inline: length stored in Inline[23]
  55  		n := int(rec.Inline[23])
  56  		return string(rec.Inline[:n])
  57  	}
  58  	if rec.DataFile == 1 && rec.DataLen > 0 {
  59  		end := rec.DataOff + rec.DataLen
  60  		if int(end) <= len(pool) {
  61  			return string(pool[rec.DataOff:end])
  62  		}
  63  	}
  64  	return ""
  65  }
  66