gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

variant_parser.go (15692B)


      1 package dbus
      2 
      3 import (
      4 	"bytes"
      5 	"errors"
      6 	"fmt"
      7 	"io"
      8 	"reflect"
      9 	"strconv"
     10 	"strings"
     11 	"unicode/utf8"
     12 )
     13 
     14 type varParser struct {
     15 	tokens []varToken
     16 	i      int
     17 }
     18 
     19 func (p *varParser) backup() {
     20 	p.i--
     21 }
     22 
     23 func (p *varParser) next() varToken {
     24 	if p.i < len(p.tokens) {
     25 		t := p.tokens[p.i]
     26 		p.i++
     27 		return t
     28 	}
     29 	return varToken{typ: tokEOF}
     30 }
     31 
     32 type varNode interface {
     33 	Infer() (Signature, error)
     34 	String() string
     35 	Sigs() sigSet
     36 	Value(Signature) (interface{}, error)
     37 }
     38 
     39 func varMakeNode(p *varParser) (varNode, error) {
     40 	var sig Signature
     41 
     42 	for {
     43 		t := p.next()
     44 		switch t.typ {
     45 		case tokEOF:
     46 			return nil, io.ErrUnexpectedEOF
     47 		case tokError:
     48 			return nil, errors.New(t.val)
     49 		case tokNumber:
     50 			return varMakeNumNode(t, sig)
     51 		case tokString:
     52 			return varMakeStringNode(t, sig)
     53 		case tokBool:
     54 			if sig.str != "" && sig.str != "b" {
     55 				return nil, varTypeError{t.val, sig}
     56 			}
     57 			b, err := strconv.ParseBool(t.val)
     58 			if err != nil {
     59 				return nil, err
     60 			}
     61 			return boolNode(b), nil
     62 		case tokArrayStart:
     63 			return varMakeArrayNode(p, sig)
     64 		case tokVariantStart:
     65 			return varMakeVariantNode(p, sig)
     66 		case tokDictStart:
     67 			return varMakeDictNode(p, sig)
     68 		case tokType:
     69 			if sig.str != "" {
     70 				return nil, errors.New("unexpected type annotation")
     71 			}
     72 			if t.val[0] == '@' {
     73 				sig.str = t.val[1:]
     74 			} else {
     75 				sig.str = varTypeMap[t.val]
     76 			}
     77 		case tokByteString:
     78 			if sig.str != "" && sig.str != "ay" {
     79 				return nil, varTypeError{t.val, sig}
     80 			}
     81 			b, err := varParseByteString(t.val)
     82 			if err != nil {
     83 				return nil, err
     84 			}
     85 			return byteStringNode(b), nil
     86 		default:
     87 			return nil, fmt.Errorf("unexpected %q", t.val)
     88 		}
     89 	}
     90 }
     91 
     92 type varTypeError struct {
     93 	val string
     94 	sig Signature
     95 }
     96 
     97 func (e varTypeError) Error() string {
     98 	return fmt.Sprintf("dbus: can't parse %q as type %q", e.val, e.sig.str)
     99 }
    100 
    101 type sigSet map[Signature]bool
    102 
    103 func (s sigSet) Empty() bool {
    104 	return len(s) == 0
    105 }
    106 
    107 func (s sigSet) Intersect(s2 sigSet) sigSet {
    108 	r := make(sigSet)
    109 	for k := range s {
    110 		if s2[k] {
    111 			r[k] = true
    112 		}
    113 	}
    114 	return r
    115 }
    116 
    117 func (s sigSet) Single() (Signature, bool) {
    118 	if len(s) == 1 {
    119 		for k := range s {
    120 			return k, true
    121 		}
    122 	}
    123 	return Signature{}, false
    124 }
    125 
    126 func (s sigSet) ToArray() sigSet {
    127 	r := make(sigSet, len(s))
    128 	for k := range s {
    129 		r[Signature{"a" + k.str}] = true
    130 	}
    131 	return r
    132 }
    133 
    134 type numNode struct {
    135 	sig Signature
    136 	str string
    137 	val interface{}
    138 }
    139 
    140 var numSigSet = sigSet{
    141 	Signature{"y"}: true,
    142 	Signature{"n"}: true,
    143 	Signature{"q"}: true,
    144 	Signature{"i"}: true,
    145 	Signature{"u"}: true,
    146 	Signature{"x"}: true,
    147 	Signature{"t"}: true,
    148 	Signature{"d"}: true,
    149 }
    150 
    151 func (n numNode) Infer() (Signature, error) {
    152 	if strings.ContainsAny(n.str, ".e") {
    153 		return Signature{"d"}, nil
    154 	}
    155 	return Signature{"i"}, nil
    156 }
    157 
    158 func (n numNode) String() string {
    159 	return n.str
    160 }
    161 
    162 func (n numNode) Sigs() sigSet {
    163 	if n.sig.str != "" {
    164 		return sigSet{n.sig: true}
    165 	}
    166 	if strings.ContainsAny(n.str, ".e") {
    167 		return sigSet{Signature{"d"}: true}
    168 	}
    169 	return numSigSet
    170 }
    171 
    172 func (n numNode) Value(sig Signature) (interface{}, error) {
    173 	if n.sig.str != "" && n.sig != sig {
    174 		return nil, varTypeError{n.str, sig}
    175 	}
    176 	if n.val != nil {
    177 		return n.val, nil
    178 	}
    179 	return varNumAs(n.str, sig)
    180 }
    181 
    182 func varMakeNumNode(tok varToken, sig Signature) (varNode, error) {
    183 	if sig.str == "" {
    184 		return numNode{str: tok.val}, nil
    185 	}
    186 	num, err := varNumAs(tok.val, sig)
    187 	if err != nil {
    188 		return nil, err
    189 	}
    190 	return numNode{sig: sig, val: num}, nil
    191 }
    192 
    193 func varNumAs(s string, sig Signature) (interface{}, error) {
    194 	isUnsigned := false
    195 	size := 32
    196 	switch sig.str {
    197 	case "n":
    198 		size = 16
    199 	case "i":
    200 	case "x":
    201 		size = 64
    202 	case "y":
    203 		size = 8
    204 		isUnsigned = true
    205 	case "q":
    206 		size = 16
    207 		isUnsigned = true
    208 	case "u":
    209 		isUnsigned = true
    210 	case "t":
    211 		size = 64
    212 		isUnsigned = true
    213 	case "d":
    214 		d, err := strconv.ParseFloat(s, 64)
    215 		if err != nil {
    216 			return nil, err
    217 		}
    218 		return d, nil
    219 	default:
    220 		return nil, varTypeError{s, sig}
    221 	}
    222 	base := 10
    223 	if strings.HasPrefix(s, "0x") {
    224 		base = 16
    225 		s = s[2:]
    226 	}
    227 	if strings.HasPrefix(s, "0") && len(s) != 1 {
    228 		base = 8
    229 		s = s[1:]
    230 	}
    231 	if isUnsigned {
    232 		i, err := strconv.ParseUint(s, base, size)
    233 		if err != nil {
    234 			return nil, err
    235 		}
    236 		var v interface{} = i
    237 		switch sig.str {
    238 		case "y":
    239 			v = byte(i)
    240 		case "q":
    241 			v = uint16(i)
    242 		case "u":
    243 			v = uint32(i)
    244 		}
    245 		return v, nil
    246 	}
    247 	i, err := strconv.ParseInt(s, base, size)
    248 	if err != nil {
    249 		return nil, err
    250 	}
    251 	var v interface{} = i
    252 	switch sig.str {
    253 	case "n":
    254 		v = int16(i)
    255 	case "i":
    256 		v = int32(i)
    257 	}
    258 	return v, nil
    259 }
    260 
    261 type stringNode struct {
    262 	sig Signature
    263 	str string      // parsed
    264 	val interface{} // has correct type
    265 }
    266 
    267 var stringSigSet = sigSet{
    268 	Signature{"s"}: true,
    269 	Signature{"g"}: true,
    270 	Signature{"o"}: true,
    271 }
    272 
    273 func (n stringNode) Infer() (Signature, error) {
    274 	return Signature{"s"}, nil
    275 }
    276 
    277 func (n stringNode) String() string {
    278 	return n.str
    279 }
    280 
    281 func (n stringNode) Sigs() sigSet {
    282 	if n.sig.str != "" {
    283 		return sigSet{n.sig: true}
    284 	}
    285 	return stringSigSet
    286 }
    287 
    288 func (n stringNode) Value(sig Signature) (interface{}, error) {
    289 	if n.sig.str != "" && n.sig != sig {
    290 		return nil, varTypeError{n.str, sig}
    291 	}
    292 	if n.val != nil {
    293 		return n.val, nil
    294 	}
    295 	switch {
    296 	case sig.str == "g":
    297 		return Signature{n.str}, nil
    298 	case sig.str == "o":
    299 		return ObjectPath(n.str), nil
    300 	case sig.str == "s":
    301 		return n.str, nil
    302 	default:
    303 		return nil, varTypeError{n.str, sig}
    304 	}
    305 }
    306 
    307 func varMakeStringNode(tok varToken, sig Signature) (varNode, error) {
    308 	if sig.str != "" && sig.str != "s" && sig.str != "g" && sig.str != "o" {
    309 		return nil, fmt.Errorf("invalid type %q for string", sig.str)
    310 	}
    311 	s, err := varParseString(tok.val)
    312 	if err != nil {
    313 		return nil, err
    314 	}
    315 	n := stringNode{str: s}
    316 	if sig.str == "" {
    317 		return stringNode{str: s}, nil
    318 	}
    319 	n.sig = sig
    320 	switch sig.str {
    321 	case "o":
    322 		n.val = ObjectPath(s)
    323 	case "g":
    324 		n.val = Signature{s}
    325 	case "s":
    326 		n.val = s
    327 	}
    328 	return n, nil
    329 }
    330 
    331 func varParseString(s string) (string, error) {
    332 	// quotes are guaranteed to be there
    333 	s = s[1 : len(s)-1]
    334 	buf := new(bytes.Buffer)
    335 	for len(s) != 0 {
    336 		r, size := utf8.DecodeRuneInString(s)
    337 		if r == utf8.RuneError && size == 1 {
    338 			return "", errors.New("invalid UTF-8")
    339 		}
    340 		s = s[size:]
    341 		if r != '\\' {
    342 			buf.WriteRune(r)
    343 			continue
    344 		}
    345 		r, size = utf8.DecodeRuneInString(s)
    346 		if r == utf8.RuneError && size == 1 {
    347 			return "", errors.New("invalid UTF-8")
    348 		}
    349 		s = s[size:]
    350 		switch r {
    351 		case 'a':
    352 			buf.WriteRune(0x7)
    353 		case 'b':
    354 			buf.WriteRune(0x8)
    355 		case 'f':
    356 			buf.WriteRune(0xc)
    357 		case 'n':
    358 			buf.WriteRune('\n')
    359 		case 'r':
    360 			buf.WriteRune('\r')
    361 		case 't':
    362 			buf.WriteRune('\t')
    363 		case '\n':
    364 		case 'u':
    365 			if len(s) < 4 {
    366 				return "", errors.New("short unicode escape")
    367 			}
    368 			r, err := strconv.ParseUint(s[:4], 16, 32)
    369 			if err != nil {
    370 				return "", err
    371 			}
    372 			buf.WriteRune(rune(r))
    373 			s = s[4:]
    374 		case 'U':
    375 			if len(s) < 8 {
    376 				return "", errors.New("short unicode escape")
    377 			}
    378 			r, err := strconv.ParseUint(s[:8], 16, 32)
    379 			if err != nil {
    380 				return "", err
    381 			}
    382 			buf.WriteRune(rune(r))
    383 			s = s[8:]
    384 		default:
    385 			buf.WriteRune(r)
    386 		}
    387 	}
    388 	return buf.String(), nil
    389 }
    390 
    391 var boolSigSet = sigSet{Signature{"b"}: true}
    392 
    393 type boolNode bool
    394 
    395 func (boolNode) Infer() (Signature, error) {
    396 	return Signature{"b"}, nil
    397 }
    398 
    399 func (b boolNode) String() string {
    400 	if b {
    401 		return "true"
    402 	}
    403 	return "false"
    404 }
    405 
    406 func (boolNode) Sigs() sigSet {
    407 	return boolSigSet
    408 }
    409 
    410 func (b boolNode) Value(sig Signature) (interface{}, error) {
    411 	if sig.str != "b" {
    412 		return nil, varTypeError{b.String(), sig}
    413 	}
    414 	return bool(b), nil
    415 }
    416 
    417 type arrayNode struct {
    418 	set      sigSet
    419 	children []varNode
    420 	val      interface{}
    421 }
    422 
    423 func (n arrayNode) Infer() (Signature, error) {
    424 	for _, v := range n.children {
    425 		csig, err := varInfer(v)
    426 		if err != nil {
    427 			continue
    428 		}
    429 		return Signature{"a" + csig.str}, nil
    430 	}
    431 	return Signature{}, fmt.Errorf("can't infer type for %q", n.String())
    432 }
    433 
    434 func (n arrayNode) String() string {
    435 	s := "["
    436 	for i, v := range n.children {
    437 		s += v.String()
    438 		if i != len(n.children)-1 {
    439 			s += ", "
    440 		}
    441 	}
    442 	return s + "]"
    443 }
    444 
    445 func (n arrayNode) Sigs() sigSet {
    446 	return n.set
    447 }
    448 
    449 func (n arrayNode) Value(sig Signature) (interface{}, error) {
    450 	if n.set.Empty() {
    451 		// no type information whatsoever, so this must be an empty slice
    452 		return reflect.MakeSlice(typeFor(sig.str), 0, 0).Interface(), nil
    453 	}
    454 	if !n.set[sig] {
    455 		return nil, varTypeError{n.String(), sig}
    456 	}
    457 	s := reflect.MakeSlice(typeFor(sig.str), len(n.children), len(n.children))
    458 	for i, v := range n.children {
    459 		rv, err := v.Value(Signature{sig.str[1:]})
    460 		if err != nil {
    461 			return nil, err
    462 		}
    463 		s.Index(i).Set(reflect.ValueOf(rv))
    464 	}
    465 	return s.Interface(), nil
    466 }
    467 
    468 func varMakeArrayNode(p *varParser, sig Signature) (varNode, error) {
    469 	var n arrayNode
    470 	if sig.str != "" {
    471 		n.set = sigSet{sig: true}
    472 	}
    473 	if t := p.next(); t.typ == tokArrayEnd {
    474 		return n, nil
    475 	} else {
    476 		p.backup()
    477 	}
    478 Loop:
    479 	for {
    480 		t := p.next()
    481 		switch t.typ {
    482 		case tokEOF:
    483 			return nil, io.ErrUnexpectedEOF
    484 		case tokError:
    485 			return nil, errors.New(t.val)
    486 		}
    487 		p.backup()
    488 		cn, err := varMakeNode(p)
    489 		if err != nil {
    490 			return nil, err
    491 		}
    492 		if cset := cn.Sigs(); !cset.Empty() {
    493 			if n.set.Empty() {
    494 				n.set = cset.ToArray()
    495 			} else {
    496 				nset := cset.ToArray().Intersect(n.set)
    497 				if nset.Empty() {
    498 					return nil, fmt.Errorf("can't parse %q with given type information", cn.String())
    499 				}
    500 				n.set = nset
    501 			}
    502 		}
    503 		n.children = append(n.children, cn)
    504 		switch t := p.next(); t.typ {
    505 		case tokEOF:
    506 			return nil, io.ErrUnexpectedEOF
    507 		case tokError:
    508 			return nil, errors.New(t.val)
    509 		case tokArrayEnd:
    510 			break Loop
    511 		case tokComma:
    512 			continue
    513 		default:
    514 			return nil, fmt.Errorf("unexpected %q", t.val)
    515 		}
    516 	}
    517 	return n, nil
    518 }
    519 
    520 type variantNode struct {
    521 	n varNode
    522 }
    523 
    524 var variantSet = sigSet{
    525 	Signature{"v"}: true,
    526 }
    527 
    528 func (variantNode) Infer() (Signature, error) {
    529 	return Signature{"v"}, nil
    530 }
    531 
    532 func (n variantNode) String() string {
    533 	return "<" + n.n.String() + ">"
    534 }
    535 
    536 func (variantNode) Sigs() sigSet {
    537 	return variantSet
    538 }
    539 
    540 func (n variantNode) Value(sig Signature) (interface{}, error) {
    541 	if sig.str != "v" {
    542 		return nil, varTypeError{n.String(), sig}
    543 	}
    544 	sig, err := varInfer(n.n)
    545 	if err != nil {
    546 		return nil, err
    547 	}
    548 	v, err := n.n.Value(sig)
    549 	if err != nil {
    550 		return nil, err
    551 	}
    552 	return MakeVariant(v), nil
    553 }
    554 
    555 func varMakeVariantNode(p *varParser, sig Signature) (varNode, error) {
    556 	n, err := varMakeNode(p)
    557 	if err != nil {
    558 		return nil, err
    559 	}
    560 	if t := p.next(); t.typ != tokVariantEnd {
    561 		return nil, fmt.Errorf("unexpected %q", t.val)
    562 	}
    563 	vn := variantNode{n}
    564 	if sig.str != "" && sig.str != "v" {
    565 		return nil, varTypeError{vn.String(), sig}
    566 	}
    567 	return variantNode{n}, nil
    568 }
    569 
    570 type dictEntry struct {
    571 	key, val varNode
    572 }
    573 
    574 type dictNode struct {
    575 	kset, vset sigSet
    576 	children   []dictEntry
    577 	val        interface{}
    578 }
    579 
    580 func (n dictNode) Infer() (Signature, error) {
    581 	for _, v := range n.children {
    582 		ksig, err := varInfer(v.key)
    583 		if err != nil {
    584 			continue
    585 		}
    586 		vsig, err := varInfer(v.val)
    587 		if err != nil {
    588 			continue
    589 		}
    590 		return Signature{"a{" + ksig.str + vsig.str + "}"}, nil
    591 	}
    592 	return Signature{}, fmt.Errorf("can't infer type for %q", n.String())
    593 }
    594 
    595 func (n dictNode) String() string {
    596 	s := "{"
    597 	for i, v := range n.children {
    598 		s += v.key.String() + ": " + v.val.String()
    599 		if i != len(n.children)-1 {
    600 			s += ", "
    601 		}
    602 	}
    603 	return s + "}"
    604 }
    605 
    606 func (n dictNode) Sigs() sigSet {
    607 	r := sigSet{}
    608 	for k := range n.kset {
    609 		for v := range n.vset {
    610 			sig := "a{" + k.str + v.str + "}"
    611 			r[Signature{sig}] = true
    612 		}
    613 	}
    614 	return r
    615 }
    616 
    617 func (n dictNode) Value(sig Signature) (interface{}, error) {
    618 	set := n.Sigs()
    619 	if set.Empty() {
    620 		// no type information -> empty dict
    621 		return reflect.MakeMap(typeFor(sig.str)).Interface(), nil
    622 	}
    623 	if !set[sig] {
    624 		return nil, varTypeError{n.String(), sig}
    625 	}
    626 	m := reflect.MakeMap(typeFor(sig.str))
    627 	ksig := Signature{sig.str[2:3]}
    628 	vsig := Signature{sig.str[3 : len(sig.str)-1]}
    629 	for _, v := range n.children {
    630 		kv, err := v.key.Value(ksig)
    631 		if err != nil {
    632 			return nil, err
    633 		}
    634 		vv, err := v.val.Value(vsig)
    635 		if err != nil {
    636 			return nil, err
    637 		}
    638 		m.SetMapIndex(reflect.ValueOf(kv), reflect.ValueOf(vv))
    639 	}
    640 	return m.Interface(), nil
    641 }
    642 
    643 func varMakeDictNode(p *varParser, sig Signature) (varNode, error) {
    644 	var n dictNode
    645 
    646 	if sig.str != "" {
    647 		if len(sig.str) < 5 {
    648 			return nil, fmt.Errorf("invalid signature %q for dict type", sig)
    649 		}
    650 		ksig := Signature{string(sig.str[2])}
    651 		vsig := Signature{sig.str[3 : len(sig.str)-1]}
    652 		n.kset = sigSet{ksig: true}
    653 		n.vset = sigSet{vsig: true}
    654 	}
    655 	if t := p.next(); t.typ == tokDictEnd {
    656 		return n, nil
    657 	} else {
    658 		p.backup()
    659 	}
    660 Loop:
    661 	for {
    662 		t := p.next()
    663 		switch t.typ {
    664 		case tokEOF:
    665 			return nil, io.ErrUnexpectedEOF
    666 		case tokError:
    667 			return nil, errors.New(t.val)
    668 		}
    669 		p.backup()
    670 		kn, err := varMakeNode(p)
    671 		if err != nil {
    672 			return nil, err
    673 		}
    674 		if kset := kn.Sigs(); !kset.Empty() {
    675 			if n.kset.Empty() {
    676 				n.kset = kset
    677 			} else {
    678 				n.kset = kset.Intersect(n.kset)
    679 				if n.kset.Empty() {
    680 					return nil, fmt.Errorf("can't parse %q with given type information", kn.String())
    681 				}
    682 			}
    683 		}
    684 		t = p.next()
    685 		switch t.typ {
    686 		case tokEOF:
    687 			return nil, io.ErrUnexpectedEOF
    688 		case tokError:
    689 			return nil, errors.New(t.val)
    690 		case tokColon:
    691 		default:
    692 			return nil, fmt.Errorf("unexpected %q", t.val)
    693 		}
    694 		t = p.next()
    695 		switch t.typ {
    696 		case tokEOF:
    697 			return nil, io.ErrUnexpectedEOF
    698 		case tokError:
    699 			return nil, errors.New(t.val)
    700 		}
    701 		p.backup()
    702 		vn, err := varMakeNode(p)
    703 		if err != nil {
    704 			return nil, err
    705 		}
    706 		if vset := vn.Sigs(); !vset.Empty() {
    707 			if n.vset.Empty() {
    708 				n.vset = vset
    709 			} else {
    710 				n.vset = n.vset.Intersect(vset)
    711 				if n.vset.Empty() {
    712 					return nil, fmt.Errorf("can't parse %q with given type information", vn.String())
    713 				}
    714 			}
    715 		}
    716 		n.children = append(n.children, dictEntry{kn, vn})
    717 		t = p.next()
    718 		switch t.typ {
    719 		case tokEOF:
    720 			return nil, io.ErrUnexpectedEOF
    721 		case tokError:
    722 			return nil, errors.New(t.val)
    723 		case tokDictEnd:
    724 			break Loop
    725 		case tokComma:
    726 			continue
    727 		default:
    728 			return nil, fmt.Errorf("unexpected %q", t.val)
    729 		}
    730 	}
    731 	return n, nil
    732 }
    733 
    734 type byteStringNode []byte
    735 
    736 var byteStringSet = sigSet{
    737 	Signature{"ay"}: true,
    738 }
    739 
    740 func (byteStringNode) Infer() (Signature, error) {
    741 	return Signature{"ay"}, nil
    742 }
    743 
    744 func (b byteStringNode) String() string {
    745 	return string(b)
    746 }
    747 
    748 func (b byteStringNode) Sigs() sigSet {
    749 	return byteStringSet
    750 }
    751 
    752 func (b byteStringNode) Value(sig Signature) (interface{}, error) {
    753 	if sig.str != "ay" {
    754 		return nil, varTypeError{b.String(), sig}
    755 	}
    756 	return []byte(b), nil
    757 }
    758 
    759 func varParseByteString(s string) ([]byte, error) {
    760 	// quotes and b at start are guaranteed to be there
    761 	b := make([]byte, 0, 1)
    762 	s = s[2 : len(s)-1]
    763 	for len(s) != 0 {
    764 		c := s[0]
    765 		s = s[1:]
    766 		if c != '\\' {
    767 			b = append(b, c)
    768 			continue
    769 		}
    770 		c = s[0]
    771 		s = s[1:]
    772 		switch c {
    773 		case 'a':
    774 			b = append(b, 0x7)
    775 		case 'b':
    776 			b = append(b, 0x8)
    777 		case 'f':
    778 			b = append(b, 0xc)
    779 		case 'n':
    780 			b = append(b, '\n')
    781 		case 'r':
    782 			b = append(b, '\r')
    783 		case 't':
    784 			b = append(b, '\t')
    785 		case 'x':
    786 			if len(s) < 2 {
    787 				return nil, errors.New("short escape")
    788 			}
    789 			n, err := strconv.ParseUint(s[:2], 16, 8)
    790 			if err != nil {
    791 				return nil, err
    792 			}
    793 			b = append(b, byte(n))
    794 			s = s[2:]
    795 		case '0':
    796 			if len(s) < 3 {
    797 				return nil, errors.New("short escape")
    798 			}
    799 			n, err := strconv.ParseUint(s[:3], 8, 8)
    800 			if err != nil {
    801 				return nil, err
    802 			}
    803 			b = append(b, byte(n))
    804 			s = s[3:]
    805 		default:
    806 			b = append(b, c)
    807 		}
    808 	}
    809 	return append(b, 0), nil
    810 }
    811 
    812 func varInfer(n varNode) (Signature, error) {
    813 	if sig, ok := n.Sigs().Single(); ok {
    814 		return sig, nil
    815 	}
    816 	return n.Infer()
    817 }