// Copyright 2015 syzkaller project authors. All rights reserved.
// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.

package prog

import (
	"bufio"
	"bytes"
	"encoding/hex"
	"fmt"
	"strconv"
	"strings"
)

// String generates a very compact program description (mostly for debug output).
func (p *Prog) String() string {
	buf := new(bytes.Buffer)
	for i, c := range p.Calls {
		if i != 0 {
			fmt.Fprintf(buf, "-")
		}
		fmt.Fprintf(buf, "%v", c.Meta.Name)
	}
	return buf.String()
}

func (p *Prog) Serialize() []byte {
	p.debugValidate()
	ctx := &serializer{
		target: p.Target,
		buf:    new(bytes.Buffer),
		vars:   make(map[*ResultArg]int),
	}
	for _, c := range p.Calls {
		ctx.call(c)
	}
	return ctx.buf.Bytes()
}

type serializer struct {
	target *Target
	buf    *bytes.Buffer
	vars   map[*ResultArg]int
	varSeq int
}

func (ctx *serializer) printf(text string, args ...interface{}) {
	fmt.Fprintf(ctx.buf, text, args...)
}

func (ctx *serializer) allocVarID(arg *ResultArg) int {
	id := ctx.varSeq
	ctx.varSeq++
	ctx.vars[arg] = id
	return id
}

func (ctx *serializer) call(c *Call) {
	if c.Ret != nil && len(c.Ret.uses) != 0 {
		ctx.printf("r%v = ", ctx.allocVarID(c.Ret))
	}
	ctx.printf("%v(", c.Meta.Name)
	for i, a := range c.Args {
		if IsPad(a.Type()) {
			continue
		}
		if i != 0 {
			ctx.printf(", ")
		}
		ctx.arg(a)
	}
	ctx.printf(")\n")
}

func (ctx *serializer) arg(arg Arg) {
	if arg == nil {
		ctx.printf("nil")
		return
	}
	arg.serialize(ctx)
}

func (a *ConstArg) serialize(ctx *serializer) {
	ctx.printf("0x%x", a.Val)
}

func (a *PointerArg) serialize(ctx *serializer) {
	if a.IsSpecial() {
		ctx.printf("0x%x", a.Address)
		return
	}
	target := ctx.target
	ctx.printf("&%v", target.serializeAddr(a))
	if a.Res != nil && isDefault(a.Res) && !target.isAnyPtr(a.Type()) {
		return
	}
	ctx.printf("=")
	if target.isAnyPtr(a.Type()) {
		ctx.printf("ANY=")
	}
	ctx.arg(a.Res)
}

func (a *DataArg) serialize(ctx *serializer) {
	typ := a.Type().(*BufferType)
	if typ.Dir() == DirOut {
		ctx.printf("\"\"/%v", a.Size())
		return
	}
	data := a.Data()
	// Statically typed data will be padded with 0s during deserialization,
	// so we can strip them here for readability always. For variable-size
	// data we strip trailing 0s only if we strip enough of them.
	sz := len(data)
	for len(data) >= 2 && data[len(data)-1] == 0 && data[len(data)-2] == 0 {
		data = data[:len(data)-1]
	}
	if typ.Varlen() && len(data)+8 >= sz {
		data = data[:sz]
	}
	serializeData(ctx.buf, data, isReadableDataType(typ))
	if typ.Varlen() && sz != len(data) {
		ctx.printf("/%v", sz)
	}
}

func (a *GroupArg) serialize(ctx *serializer) {
	var delims []byte
	switch a.Type().(type) {
	case *StructType:
		delims = []byte{'{', '}'}
	case *ArrayType:
		delims = []byte{'[', ']'}
	default:
		panic("unknown group type")
	}
	ctx.buf.WriteByte(delims[0])
	lastNonDefault := len(a.Inner) - 1
	if a.fixedInnerSize() {
		for ; lastNonDefault >= 0; lastNonDefault-- {
			if !isDefault(a.Inner[lastNonDefault]) {
				break
			}
		}
	}
	for i := 0; i <= lastNonDefault; i++ {
		arg1 := a.Inner[i]
		if arg1 != nil && IsPad(arg1.Type()) {
			continue
		}
		if i != 0 {
			ctx.printf(", ")
		}
		ctx.arg(arg1)
	}
	ctx.buf.WriteByte(delims[1])
}

func (a *UnionArg) serialize(ctx *serializer) {
	ctx.printf("@%v", a.Option.Type().FieldName())
	if isDefault(a.Option) {
		return
	}
	ctx.printf("=")
	ctx.arg(a.Option)
}

func (a *ResultArg) serialize(ctx *serializer) {
	if len(a.uses) != 0 {
		ctx.printf("<r%v=>", ctx.allocVarID(a))
	}
	if a.Res == nil {
		ctx.printf("0x%x", a.Val)
		return
	}
	id, ok := ctx.vars[a.Res]
	if !ok {
		panic("no result")
	}
	ctx.printf("r%v", id)
	if a.OpDiv != 0 {
		ctx.printf("/%v", a.OpDiv)
	}
	if a.OpAdd != 0 {
		ctx.printf("+%v", a.OpAdd)
	}
}

type DeserializeMode int

const (
	Strict    DeserializeMode = iota
	NonStrict DeserializeMode = iota
)

func (target *Target) Deserialize(data []byte, mode DeserializeMode) (*Prog, error) {
	p := newParser(target, data, mode == Strict)
	prog, err := p.parseProg()
	if err := p.Err(); err != nil {
		return nil, err
	}
	if err != nil {
		return nil, err
	}
	// This validation is done even in non-debug mode because deserialization
	// procedure does not catch all bugs (e.g. mismatched types).
	// And we can receive bad programs from corpus and hub.
	if err := prog.validate(); err != nil {
		return nil, err
	}
	if p.autos != nil {
		p.fixupAutos(prog)
	}
	for _, c := range prog.Calls {
		target.SanitizeCall(c)
	}
	return prog, nil
}

func (p *parser) parseProg() (*Prog, error) {
	prog := &Prog{
		Target: p.target,
	}
	for p.Scan() {
		if p.EOF() {
			if p.comment != "" {
				prog.Comments = append(prog.Comments, p.comment)
				p.comment = ""
			}
			continue
		}
		if p.Char() == '#' {
			if p.comment != "" {
				prog.Comments = append(prog.Comments, p.comment)
			}
			p.comment = strings.TrimSpace(p.s[p.i+1:])
			continue
		}
		name := p.Ident()
		r := ""
		if p.Char() == '=' {
			r = name
			p.Parse('=')
			name = p.Ident()

		}
		meta := p.target.SyscallMap[name]
		if meta == nil {
			return nil, fmt.Errorf("unknown syscall %v", name)
		}
		c := &Call{
			Meta:    meta,
			Ret:     MakeReturnArg(meta.Ret),
			Comment: p.comment,
		}
		prog.Calls = append(prog.Calls, c)
		p.Parse('(')
		for i := 0; p.Char() != ')'; i++ {
			if i >= len(meta.Args) {
				p.eatExcessive(false, "excessive syscall arguments")
				break
			}
			typ := meta.Args[i]
			if IsPad(typ) {
				return nil, fmt.Errorf("padding in syscall %v arguments", name)
			}
			arg, err := p.parseArg(typ)
			if err != nil {
				return nil, err
			}
			c.Args = append(c.Args, arg)
			if p.Char() != ')' {
				p.Parse(',')
			}
		}
		p.Parse(')')
		p.SkipWs()
		if !p.EOF() {
			if p.Char() != '#' {
				return nil, fmt.Errorf("tailing data (line #%v)", p.l)
			}
			if c.Comment != "" {
				prog.Comments = append(prog.Comments, c.Comment)
			}
			c.Comment = strings.TrimSpace(p.s[p.i+1:])
		}
		for i := len(c.Args); i < len(meta.Args); i++ {
			p.strictFailf("missing syscall args")
			c.Args = append(c.Args, meta.Args[i].DefaultArg())
		}
		if len(c.Args) != len(meta.Args) {
			return nil, fmt.Errorf("wrong call arg count: %v, want %v", len(c.Args), len(meta.Args))
		}
		if r != "" && c.Ret != nil {
			p.vars[r] = c.Ret
		}
		p.comment = ""
	}
	if p.comment != "" {
		prog.Comments = append(prog.Comments, p.comment)
	}
	return prog, nil
}

func (p *parser) parseArg(typ Type) (Arg, error) {
	r := ""
	if p.Char() == '<' {
		p.Parse('<')
		r = p.Ident()
		p.Parse('=')
		p.Parse('>')
	}
	arg, err := p.parseArgImpl(typ)
	if err != nil {
		return nil, err
	}
	if arg == nil {
		if typ != nil {
			arg = typ.DefaultArg()
		} else if r != "" {
			return nil, fmt.Errorf("named nil argument")
		}
	}
	if r != "" {
		if res, ok := arg.(*ResultArg); ok {
			p.vars[r] = res
		}
	}
	return arg, nil
}

func (p *parser) parseArgImpl(typ Type) (Arg, error) {
	if typ == nil && p.Char() != 'n' {
		return nil, fmt.Errorf("non-nil argument for nil type")
	}
	switch p.Char() {
	case '0':
		return p.parseArgInt(typ)
	case 'r':
		return p.parseArgRes(typ)
	case '&':
		return p.parseArgAddr(typ)
	case '"', '\'':
		return p.parseArgString(typ)
	case '{':
		return p.parseArgStruct(typ)
	case '[':
		return p.parseArgArray(typ)
	case '@':
		return p.parseArgUnion(typ)
	case 'n':
		p.Parse('n')
		p.Parse('i')
		p.Parse('l')
		return nil, nil
	case 'A':
		p.Parse('A')
		p.Parse('U')
		p.Parse('T')
		p.Parse('O')
		return p.parseAuto(typ)
	default:
		return nil, fmt.Errorf("failed to parse argument at '%c' (line #%v/%v: %v)",
			p.Char(), p.l, p.i, p.s)
	}
}

func (p *parser) parseArgInt(typ Type) (Arg, error) {
	val := p.Ident()
	v, err := strconv.ParseUint(val, 0, 64)
	if err != nil {
		return nil, fmt.Errorf("wrong arg value '%v': %v", val, err)
	}
	switch typ.(type) {
	case *ConstType, *IntType, *FlagsType, *ProcType, *LenType, *CsumType:
		return MakeConstArg(typ, v), nil
	case *ResourceType:
		return MakeResultArg(typ, nil, v), nil
	case *PtrType, *VmaType:
		index := -v % uint64(len(p.target.SpecialPointers))
		return MakeSpecialPointerArg(typ, index), nil
	default:
		p.eatExcessive(true, "wrong int arg")
		return typ.DefaultArg(), nil
	}
}

func (p *parser) parseAuto(typ Type) (Arg, error) {
	switch typ.(type) {
	case *ConstType, *LenType, *CsumType:
		return p.auto(MakeConstArg(typ, 0)), nil
	default:
		return nil, fmt.Errorf("wrong type %T for AUTO", typ)
	}
}

func (p *parser) parseArgRes(typ Type) (Arg, error) {
	id := p.Ident()
	var div, add uint64
	if p.Char() == '/' {
		p.Parse('/')
		op := p.Ident()
		v, err := strconv.ParseUint(op, 0, 64)
		if err != nil {
			return nil, fmt.Errorf("wrong result div op: '%v'", op)
		}
		div = v
	}
	if p.Char() == '+' {
		p.Parse('+')
		op := p.Ident()
		v, err := strconv.ParseUint(op, 0, 64)
		if err != nil {
			return nil, fmt.Errorf("wrong result add op: '%v'", op)
		}
		add = v
	}
	v := p.vars[id]
	if v == nil {
		p.strictFailf("undeclared variable %v", id)
		return typ.DefaultArg(), nil
	}
	arg := MakeResultArg(typ, v, 0)
	arg.OpDiv = div
	arg.OpAdd = add
	return arg, nil
}

func (p *parser) parseArgAddr(typ Type) (Arg, error) {
	var typ1 Type
	switch t1 := typ.(type) {
	case *PtrType:
		typ1 = t1.Type
	case *VmaType:
	default:
		p.eatExcessive(true, "wrong addr arg")
		return typ.DefaultArg(), nil
	}
	p.Parse('&')
	auto := false
	var addr, vmaSize uint64
	if p.Char() == 'A' {
		p.Parse('A')
		p.Parse('U')
		p.Parse('T')
		p.Parse('O')
		if typ1 == nil {
			return nil, fmt.Errorf("vma type can't be AUTO")
		}
		auto = true
	} else {
		var err error
		addr, vmaSize, err = p.parseAddr()
		if err != nil {
			return nil, err
		}
	}
	var inner Arg
	if p.Char() == '=' {
		p.Parse('=')
		if p.Char() == 'A' {
			p.Parse('A')
			p.Parse('N')
			p.Parse('Y')
			p.Parse('=')
			typ = p.target.makeAnyPtrType(typ.Size(), typ.FieldName())
			typ1 = p.target.any.array
		}
		var err error
		inner, err = p.parseArg(typ1)
		if err != nil {
			return nil, err
		}
	}
	if typ1 == nil {
		if addr%p.target.PageSize != 0 {
			p.strictFailf("unaligned vma address 0x%x", addr)
			addr &= ^(p.target.PageSize - 1)
		}
		return MakeVmaPointerArg(typ, addr, vmaSize), nil
	}
	if inner == nil {
		inner = typ1.DefaultArg()
	}
	arg := MakePointerArg(typ, addr, inner)
	if auto {
		p.auto(arg)
	}
	return arg, nil
}

func (p *parser) parseArgString(typ Type) (Arg, error) {
	if _, ok := typ.(*BufferType); !ok {
		p.eatExcessive(true, "wrong string arg")
		return typ.DefaultArg(), nil
	}
	data, err := p.deserializeData()
	if err != nil {
		return nil, err
	}
	size := ^uint64(0)
	if p.Char() == '/' {
		p.Parse('/')
		sizeStr := p.Ident()
		size, err = strconv.ParseUint(sizeStr, 0, 64)
		if err != nil {
			return nil, fmt.Errorf("failed to parse buffer size: %q", sizeStr)
		}
		maxMem := p.target.NumPages * p.target.PageSize
		if size > maxMem {
			p.strictFailf("too large string argument %v", size)
			size = maxMem
		}
	}
	if !typ.Varlen() {
		size = typ.Size()
	} else if size == ^uint64(0) {
		size = uint64(len(data))
	}
	if typ.Dir() == DirOut {
		return MakeOutDataArg(typ, size), nil
	}
	if diff := int(size) - len(data); diff > 0 {
		data = append(data, make([]byte, diff)...)
	}
	data = data[:size]
	return MakeDataArg(typ, data), nil
}

func (p *parser) parseArgStruct(typ Type) (Arg, error) {
	p.Parse('{')
	t1, ok := typ.(*StructType)
	if !ok {
		p.eatExcessive(false, "wrong struct arg")
		p.Parse('}')
		return typ.DefaultArg(), nil
	}
	var inner []Arg
	for i := 0; p.Char() != '}'; i++ {
		if i >= len(t1.Fields) {
			p.eatExcessive(false, "excessive struct %v fields", typ.Name())
			break
		}
		fld := t1.Fields[i]
		if IsPad(fld) {
			inner = append(inner, MakeConstArg(fld, 0))
		} else {
			arg, err := p.parseArg(fld)
			if err != nil {
				return nil, err
			}
			inner = append(inner, arg)
			if p.Char() != '}' {
				p.Parse(',')
			}
		}
	}
	p.Parse('}')
	for len(inner) < len(t1.Fields) {
		fld := t1.Fields[len(inner)]
		if !IsPad(fld) {
			p.strictFailf("missing struct %v fields %v/%v", typ.Name(), len(inner), len(t1.Fields))
		}
		inner = append(inner, fld.DefaultArg())
	}
	return MakeGroupArg(typ, inner), nil
}

func (p *parser) parseArgArray(typ Type) (Arg, error) {
	p.Parse('[')
	t1, ok := typ.(*ArrayType)
	if !ok {
		p.eatExcessive(false, "wrong array arg")
		p.Parse(']')
		return typ.DefaultArg(), nil
	}
	var inner []Arg
	for i := 0; p.Char() != ']'; i++ {
		arg, err := p.parseArg(t1.Type)
		if err != nil {
			return nil, err
		}
		inner = append(inner, arg)
		if p.Char() != ']' {
			p.Parse(',')
		}
	}
	p.Parse(']')
	if t1.Kind == ArrayRangeLen && t1.RangeBegin == t1.RangeEnd {
		for uint64(len(inner)) < t1.RangeBegin {
			p.strictFailf("missing array elements")
			inner = append(inner, t1.Type.DefaultArg())
		}
		inner = inner[:t1.RangeBegin]
	}
	return MakeGroupArg(typ, inner), nil
}

func (p *parser) parseArgUnion(typ Type) (Arg, error) {
	t1, ok := typ.(*UnionType)
	if !ok {
		p.eatExcessive(true, "wrong union arg")
		return typ.DefaultArg(), nil
	}
	p.Parse('@')
	name := p.Ident()
	var optType Type
	for _, t2 := range t1.Fields {
		if name == t2.FieldName() {
			optType = t2
			break
		}
	}
	if optType == nil {
		p.eatExcessive(true, "wrong union option")
		return typ.DefaultArg(), nil
	}
	var opt Arg
	if p.Char() == '=' {
		p.Parse('=')
		var err error
		opt, err = p.parseArg(optType)
		if err != nil {
			return nil, err
		}
	} else {
		opt = optType.DefaultArg()
	}
	return MakeUnionArg(typ, opt), nil
}

// Eats excessive call arguments and struct fields to recover after description changes.
func (p *parser) eatExcessive(stopAtComma bool, what string, args ...interface{}) {
	p.strictFailf(what, args...)
	paren, brack, brace := 0, 0, 0
	for !p.EOF() && p.e == nil {
		ch := p.Char()
		switch ch {
		case '(':
			paren++
		case ')':
			if paren == 0 {
				return
			}
			paren--
		case '[':
			brack++
		case ']':
			if brack == 0 {
				return
			}
			brack--
		case '{':
			brace++
		case '}':
			if brace == 0 {
				return
			}
			brace--
		case ',':
			if stopAtComma && paren == 0 && brack == 0 && brace == 0 {
				return
			}
		case '\'', '"':
			p.Parse(ch)
			for !p.EOF() && p.Char() != ch {
				p.Parse(p.Char())
			}
			if p.EOF() {
				return
			}
		}
		p.Parse(ch)
	}
}

const (
	encodingAddrBase = 0x7f0000000000
	maxLineLen       = 1 << 20
)

func (target *Target) serializeAddr(arg *PointerArg) string {
	ssize := ""
	if arg.VmaSize != 0 {
		ssize = fmt.Sprintf("/0x%x", arg.VmaSize)
	}
	return fmt.Sprintf("(0x%x%v)", encodingAddrBase+arg.Address, ssize)
}

func (p *parser) parseAddr() (uint64, uint64, error) {
	p.Parse('(')
	pstr := p.Ident()
	addr, err := strconv.ParseUint(pstr, 0, 64)
	if err != nil {
		return 0, 0, fmt.Errorf("failed to parse addr: %q", pstr)
	}
	if addr < encodingAddrBase {
		return 0, 0, fmt.Errorf("address without base offset: %q", pstr)
	}
	addr -= encodingAddrBase
	// This is not used anymore, but left here to parse old programs.
	if p.Char() == '+' || p.Char() == '-' {
		minus := false
		if p.Char() == '-' {
			minus = true
			p.Parse('-')
		} else {
			p.Parse('+')
		}
		ostr := p.Ident()
		off, err := strconv.ParseUint(ostr, 0, 64)
		if err != nil {
			return 0, 0, fmt.Errorf("failed to parse addr offset: %q", ostr)
		}
		if minus {
			off = -off
		}
		addr += off
	}
	target := p.target
	maxMem := target.NumPages * target.PageSize
	var vmaSize uint64
	if p.Char() == '/' {
		p.Parse('/')
		pstr := p.Ident()
		size, err := strconv.ParseUint(pstr, 0, 64)
		if err != nil {
			return 0, 0, fmt.Errorf("failed to parse addr size: %q", pstr)
		}
		addr = addr & ^(target.PageSize - 1)
		vmaSize = (size + target.PageSize - 1) & ^(target.PageSize - 1)
		if vmaSize == 0 {
			vmaSize = target.PageSize
		}
		if vmaSize > maxMem {
			vmaSize = maxMem
		}
		if addr > maxMem-vmaSize {
			addr = maxMem - vmaSize
		}
	}
	p.Parse(')')
	return addr, vmaSize, nil
}

func serializeData(buf *bytes.Buffer, data []byte, readable bool) {
	if !readable && !isReadableData(data) {
		fmt.Fprintf(buf, "\"%v\"", hex.EncodeToString(data))
		return
	}
	buf.WriteByte('\'')
	encodeData(buf, data, true, false)
	buf.WriteByte('\'')
}

func EncodeData(buf *bytes.Buffer, data []byte, readable bool) {
	if !readable && isReadableData(data) {
		readable = true
	}
	encodeData(buf, data, readable, true)
}

func encodeData(buf *bytes.Buffer, data []byte, readable, cstr bool) {
	for _, v := range data {
		if !readable {
			lo, hi := byteToHex(v)
			buf.Write([]byte{'\\', 'x', hi, lo})
			continue
		}
		switch v {
		case '\a':
			buf.Write([]byte{'\\', 'a'})
		case '\b':
			buf.Write([]byte{'\\', 'b'})
		case '\f':
			buf.Write([]byte{'\\', 'f'})
		case '\n':
			buf.Write([]byte{'\\', 'n'})
		case '\r':
			buf.Write([]byte{'\\', 'r'})
		case '\t':
			buf.Write([]byte{'\\', 't'})
		case '\v':
			buf.Write([]byte{'\\', 'v'})
		case '\'':
			buf.Write([]byte{'\\', '\''})
		case '"':
			buf.Write([]byte{'\\', '"'})
		case '\\':
			buf.Write([]byte{'\\', '\\'})
		default:
			if isPrintable(v) {
				buf.WriteByte(v)
			} else {
				if cstr {
					// We would like to use hex encoding with \x,
					// but C's \x is hard to use: it can contain _any_ number of hex digits
					// (not just 2 or 4), so later non-hex encoded chars will glue to \x.
					c0 := (v>>6)&0x7 + '0'
					c1 := (v>>3)&0x7 + '0'
					c2 := (v>>0)&0x7 + '0'
					buf.Write([]byte{'\\', c0, c1, c2})
				} else {
					lo, hi := byteToHex(v)
					buf.Write([]byte{'\\', 'x', hi, lo})
				}
			}
		}
	}
}

func isReadableDataType(typ *BufferType) bool {
	return typ.Kind == BufferString || typ.Kind == BufferFilename
}

func isReadableData(data []byte) bool {
	if len(data) == 0 {
		return false
	}
	for _, v := range data {
		if isPrintable(v) {
			continue
		}
		switch v {
		case 0, '\a', '\b', '\f', '\n', '\r', '\t', '\v':
			continue
		}
		return false
	}
	return true
}

func (p *parser) deserializeData() ([]byte, error) {
	var data []byte
	if p.Char() == '"' {
		p.Parse('"')
		val := ""
		if p.Char() != '"' {
			val = p.Ident()
		}
		p.Parse('"')
		var err error
		data, err = hex.DecodeString(val)
		if err != nil {
			return nil, fmt.Errorf("data arg has bad value %q", val)
		}
	} else {
		if p.consume() != '\'' {
			return nil, fmt.Errorf("data arg does not start with \" nor with '")
		}
		for p.Char() != '\'' && p.Char() != 0 {
			v := p.consume()
			if v != '\\' {
				data = append(data, v)
				continue
			}
			v = p.consume()
			switch v {
			case 'x':
				hi := p.consume()
				lo := p.consume()
				b, ok := hexToByte(lo, hi)
				if !ok {
					return nil, fmt.Errorf("invalid hex \\x%v%v in data arg", hi, lo)
				}
				data = append(data, b)
			case 'a':
				data = append(data, '\a')
			case 'b':
				data = append(data, '\b')
			case 'f':
				data = append(data, '\f')
			case 'n':
				data = append(data, '\n')
			case 'r':
				data = append(data, '\r')
			case 't':
				data = append(data, '\t')
			case 'v':
				data = append(data, '\v')
			case '\'':
				data = append(data, '\'')
			case '"':
				data = append(data, '"')
			case '\\':
				data = append(data, '\\')
			default:
				return nil, fmt.Errorf("invalid \\%c escape sequence in data arg", v)
			}
		}
		p.Parse('\'')
	}
	return data, nil
}

func isPrintable(v byte) bool {
	return v >= 0x20 && v < 0x7f
}

func byteToHex(v byte) (lo, hi byte) {
	return toHexChar(v & 0xf), toHexChar(v >> 4)
}

func hexToByte(lo, hi byte) (byte, bool) {
	h, ok1 := fromHexChar(hi)
	l, ok2 := fromHexChar(lo)
	return h<<4 + l, ok1 && ok2
}

func toHexChar(v byte) byte {
	if v >= 16 {
		panic("bad hex char")
	}
	if v < 10 {
		return '0' + v
	}
	return 'a' + v - 10
}

func fromHexChar(v byte) (byte, bool) {
	if v >= '0' && v <= '9' {
		return v - '0', true
	}
	if v >= 'a' && v <= 'f' {
		return v - 'a' + 10, true
	}
	return 0, false
}

type parser struct {
	target  *Target
	strict  bool
	vars    map[string]*ResultArg
	autos   map[Arg]bool
	comment string

	r *bufio.Scanner
	s string
	i int
	l int
	e error
}

func newParser(target *Target, data []byte, strict bool) *parser {
	p := &parser{
		target: target,
		strict: strict,
		vars:   make(map[string]*ResultArg),
		r:      bufio.NewScanner(bytes.NewReader(data)),
	}
	p.r.Buffer(nil, maxLineLen)
	return p
}

func (p *parser) auto(arg Arg) Arg {
	if p.autos == nil {
		p.autos = make(map[Arg]bool)
	}
	p.autos[arg] = true
	return arg
}

func (p *parser) fixupAutos(prog *Prog) {
	s := analyze(nil, prog, nil)
	for _, c := range prog.Calls {
		p.target.assignSizesArray(c.Args, p.autos)
		ForeachArg(c, func(arg Arg, _ *ArgCtx) {
			if !p.autos[arg] {
				return
			}
			delete(p.autos, arg)
			switch typ := arg.Type().(type) {
			case *ConstType:
				arg.(*ConstArg).Val = typ.Val
				_ = s
			case *PtrType:
				a := arg.(*PointerArg)
				a.Address = s.ma.alloc(nil, a.Res.Size())
			default:
				panic(fmt.Sprintf("unsupported auto type %T", typ))

			}
		})
	}
	if len(p.autos) != 0 {
		panic(fmt.Sprintf("leftoever autos: %+v", p.autos))
	}
}

func (p *parser) Scan() bool {
	if p.e != nil {
		return false
	}
	if !p.r.Scan() {
		p.e = p.r.Err()
		return false
	}
	p.s = p.r.Text()
	p.i = 0
	p.l++
	return true
}

func (p *parser) Err() error {
	return p.e
}

func (p *parser) Str() string {
	return p.s
}

func (p *parser) EOF() bool {
	return p.i == len(p.s)
}

func (p *parser) Char() byte {
	if p.e != nil {
		return 0
	}
	if p.EOF() {
		p.failf("unexpected eof")
		return 0
	}
	return p.s[p.i]
}

func (p *parser) Parse(ch byte) {
	if p.e != nil {
		return
	}
	if p.EOF() {
		p.failf("want %s, got EOF", string(ch))
		return
	}
	if p.s[p.i] != ch {
		p.failf("want '%v', got '%v'", string(ch), string(p.s[p.i]))
		return
	}
	p.i++
	p.SkipWs()
}

func (p *parser) consume() byte {
	if p.e != nil {
		return 0
	}
	if p.EOF() {
		p.failf("unexpected eof")
		return 0
	}
	v := p.s[p.i]
	p.i++
	return v
}

func (p *parser) SkipWs() {
	for p.i < len(p.s) && (p.s[p.i] == ' ' || p.s[p.i] == '\t') {
		p.i++
	}
}

func (p *parser) Ident() string {
	i := p.i
	for p.i < len(p.s) &&
		(p.s[p.i] >= 'a' && p.s[p.i] <= 'z' ||
			p.s[p.i] >= 'A' && p.s[p.i] <= 'Z' ||
			p.s[p.i] >= '0' && p.s[p.i] <= '9' ||
			p.s[p.i] == '_' || p.s[p.i] == '$') {
		p.i++
	}
	if i == p.i {
		p.failf("failed to parse identifier at pos %v", i)
		return ""
	}
	s := p.s[i:p.i]
	p.SkipWs()
	return s
}

func (p *parser) failf(msg string, args ...interface{}) {
	if p.e == nil {
		p.e = fmt.Errorf("%v\nline #%v:%v: %v", fmt.Sprintf(msg, args...), p.l, p.i, p.s)
	}
}

func (p *parser) strictFailf(msg string, args ...interface{}) {
	if p.strict {
		p.failf(msg, args...)
	}
}

// CallSet returns a set of all calls in the program.
// It does very conservative parsing and is intended to parse paste/future serialization formats.
func CallSet(data []byte) (map[string]struct{}, error) {
	calls := make(map[string]struct{})
	s := bufio.NewScanner(bytes.NewReader(data))
	s.Buffer(nil, maxLineLen)
	for s.Scan() {
		ln := s.Bytes()
		if len(ln) == 0 || ln[0] == '#' {
			continue
		}
		bracket := bytes.IndexByte(ln, '(')
		if bracket == -1 {
			return nil, fmt.Errorf("line does not contain opening bracket")
		}
		call := ln[:bracket]
		if eq := bytes.IndexByte(call, '='); eq != -1 {
			eq++
			for eq < len(call) && call[eq] == ' ' {
				eq++
			}
			call = call[eq:]
		}
		if len(call) == 0 {
			return nil, fmt.Errorf("call name is empty")
		}
		calls[string(call)] = struct{}{}
	}
	if err := s.Err(); err != nil {
		return nil, err
	}
	if len(calls) == 0 {
		return nil, fmt.Errorf("program does not contain any calls")
	}
	return calls, nil
}
