// Copyright 2017 The Wuffs Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package parse

// TODO: write a formal grammar for the language.

import (
	"fmt"

	a "github.com/google/wuffs/lang/ast"
	t "github.com/google/wuffs/lang/token"
)

type Options struct {
	AllowBuiltInNames          bool
	AllowDoubleUnderscoreNames bool
}

func validConstName(s string) bool {
	if (len(s) >= 2) && (s[0] == '_') && (s[1] == '_') {
		return false
	}
	for i := 0; i < len(s); i++ {
		switch c := s[i]; {
		default:
			return false
		case c == '_':
		case ('0' <= c) && (c <= '9'):
		case ('A' <= c) && (c <= 'Z'): // Upper A-Z but not lower a-z.
		}
	}
	return true
}

func containsDoubleUnderscore(s string) bool {
	for i := 1; i < len(s); i++ {
		if (s[i-1] == '_') && (s[i] == '_') {
			return true
		}
	}
	return false
}

func isStatusMessage(s string) bool {
	if s == "" {
		return false
	}
	c := s[0]
	return (c == '@') || (c == '#') || (c == '$')
}

func Parse(tm *t.Map, filename string, src []t.Token, opts *Options) (*a.File, error) {
	p := &parser{
		tm:       tm,
		filename: filename,
		src:      src,
	}
	if len(src) > 0 {
		p.lastLine = src[len(src)-1].Line
	}
	if opts != nil {
		p.opts = *opts
	}
	return p.parseFile()
}

func ParseExpr(tm *t.Map, filename string, src []t.Token, opts *Options) (*a.Expr, error) {
	p := &parser{
		tm:       tm,
		filename: filename,
		src:      src,
	}
	if len(src) > 0 {
		p.lastLine = src[len(src)-1].Line
	}
	if opts != nil {
		p.opts = *opts
	}
	return p.parseExpr()
}

type parser struct {
	tm         *t.Map
	filename   string
	src        []t.Token
	opts       Options
	lastLine   uint32
	funcEffect a.Effect
	loops      a.LoopStack
	allowVar   bool
}

func (p *parser) line() uint32 {
	if len(p.src) != 0 {
		return p.src[0].Line
	}
	return p.lastLine
}

func (p *parser) peek1() t.ID {
	if len(p.src) > 0 {
		return p.src[0].ID
	}
	return 0
}

func (p *parser) parseFile() (*a.File, error) {
	topLevelDecls := []*a.Node(nil)
	for len(p.src) > 0 {
		d, err := p.parseTopLevelDecl()
		if err != nil {
			return nil, err
		}
		topLevelDecls = append(topLevelDecls, d)
	}
	return a.NewFile(p.filename, topLevelDecls), nil
}

func (p *parser) parseTopLevelDecl() (*a.Node, error) {
	flags := a.Flags(0)
	line := p.src[0].Line
	switch k := p.peek1(); k {
	case t.IDUse:
		p.src = p.src[1:]
		path := p.peek1()
		if !path.IsDQStrLiteral(p.tm) {
			got := p.tm.ByID(path)
			return nil, fmt.Errorf(`parse: expected "-string literal, got %q at %s:%d`, got, p.filename, p.line())
		}
		p.src = p.src[1:]
		if x := p.peek1(); x != t.IDSemicolon {
			got := p.tm.ByID(x)
			return nil, fmt.Errorf(`parse: expected (implicit) ";", got %q at %s:%d`, got, p.filename, p.line())
		}
		p.src = p.src[1:]
		return a.NewUse(p.filename, line, path).AsNode(), nil

	case t.IDPub:
		flags |= a.FlagsPublic
		fallthrough
	case t.IDPri:
		p.src = p.src[1:]
		switch p.peek1() {
		case t.IDConst:
			p.src = p.src[1:]
			id, err := p.parseIdent()
			if err != nil {
				return nil, err
			}
			if !validConstName(p.tm.ByID(id)) {
				return nil, fmt.Errorf(`parse: invalid const name %q at %s:%d`,
					p.tm.ByID(id), p.filename, p.line())
			}

			if x := p.peek1(); x != t.IDColon {
				got := p.tm.ByID(x)
				return nil, fmt.Errorf(`parse: expected ":", got %q at %s:%d`, got, p.filename, p.line())
			}
			p.src = p.src[1:]

			typ, err := p.parseTypeExpr()
			if err != nil {
				return nil, err
			}
			if p.peek1() != t.IDEq {
				return nil, fmt.Errorf(`parse: const %q has no value at %s:%d`,
					p.tm.ByID(id), p.filename, p.line())
			}
			p.src = p.src[1:]
			value, err := p.parsePossibleListExpr()
			if err != nil {
				return nil, err
			}
			if x := p.peek1(); x != t.IDSemicolon {
				got := p.tm.ByID(x)
				return nil, fmt.Errorf(`parse: expected (implicit) ";", got %q at %s:%d`, got, p.filename, p.line())
			}
			p.src = p.src[1:]
			return a.NewConst(flags, p.filename, line, id, typ, value).AsNode(), nil

		case t.IDFunc:
			p.src = p.src[1:]
			id0, id1, err := p.parseQualifiedIdent()
			if err != nil {
				return nil, err
			}
			if !p.opts.AllowBuiltInNames {
				switch id1 {
				case t.IDInitialize, t.IDReset:
					return nil, fmt.Errorf(`parse: cannot have a method named %q at %s:%d`,
						id1.Str(p.tm), p.filename, p.line())
				}
			}
			// TODO: should we require id0 != 0? In other words, always methods
			// (attached to receivers) and never free standing functions?
			if !p.opts.AllowDoubleUnderscoreNames && containsDoubleUnderscore(p.tm.ByID(id1)) {
				return nil, fmt.Errorf(`parse: double-underscore %q used for func name at %s:%d`,
					p.tm.ByID(id1), p.filename, p.line())
			}

			p.funcEffect = p.parseEffect()
			flags |= p.funcEffect.AsFlags()
			argFields, err := p.parseList(t.IDCloseParen, (*parser).parseFieldNode)
			if err != nil {
				return nil, err
			}
			out := (*a.TypeExpr)(nil)
			if x := p.peek1(); (x != t.IDOpenCurly) && (x != t.IDComma) {
				out, err = p.parseTypeExpr()
				if err != nil {
					return nil, err
				}
			}
			asserts := []*a.Node(nil)
			if p.peek1() == t.IDComma {
				p.src = p.src[1:]
				if p.peek1() == t.IDChoosy {
					p.src = p.src[1:]
					if (flags & a.FlagsPublic) != 0 {
						return nil, fmt.Errorf(`parse: choosy function cannot be pub at %s:%d`,
							p.filename, p.line())
					} else if p.funcEffect.Coroutine() {
						return nil, fmt.Errorf(`parse: choosy function cannot be a coroutine at %s:%d`,
							p.filename, p.line())
					}
					flags |= a.FlagsChoosy
					if p.peek1() != t.IDOpenCurly {
						if x := p.peek1(); x != t.IDComma {
							return nil, fmt.Errorf(`parse: expected ",", got %q at %s:%d`,
								p.tm.ByID(x), p.filename, p.line())
						}
						p.src = p.src[1:]
					}
				}

				asserts, err = p.parseList(t.IDOpenCurly, (*parser).parseAssertNode)
				if err != nil {
					return nil, err
				}
				if err := p.assertsSorted(asserts, true); err != nil {
					return nil, err
				}
				for _, o := range asserts {
					o := o.AsAssert()
					if o.Keyword() != t.IDChoose {
						continue
					} else if o.IsChooseCPUArch() {
						flags |= a.FlagsHasChooseCPUArch
					} else {
						return nil, fmt.Errorf(`parse: invalid "choose" condition at %s:%d`,
							p.filename, p.line())
					}
				}
			}

			p.allowVar = true
			body, err := p.parseBlock(false)
			if err != nil {
				return nil, err
			}
			p.allowVar = false

			if x := p.peek1(); x != t.IDSemicolon {
				got := p.tm.ByID(x)
				return nil, fmt.Errorf(`parse: expected (implicit) ";", got %q at %s:%d`, got, p.filename, p.line())
			}
			p.src = p.src[1:]

			if (flags & a.FlagsHasChooseCPUArch) != 0 {
				if (flags & a.FlagsPublic) != 0 {
					return nil, fmt.Errorf(`parse: cpu_arch function cannot be public at %s:%d`,
						p.filename, p.line())
				}
				if (flags & a.FlagsChoosy) != 0 {
					return nil, fmt.Errorf(`parse: cpu_arch function cannot be choosy at %s:%d`,
						p.filename, p.line())
				}
			}
			p.funcEffect = 0
			in := a.NewStruct(0, p.filename, line, t.IDArgs, nil, argFields)
			return a.NewFunc(flags, p.filename, line, id0, id1, in, out, asserts, body).AsNode(), nil

		case t.IDStatus:
			p.src = p.src[1:]

			message := p.peek1()
			if !message.IsDQStrLiteral(p.tm) {
				got := p.tm.ByID(message)
				return nil, fmt.Errorf(`parse: expected "-string literal, got %q at %s:%d`, got, p.filename, p.line())
			}
			if s, _ := t.Unescape(p.tm.ByID(message)); !isStatusMessage(s) {
				return nil, fmt.Errorf(`parse: status message %q does not start with `+
					`@, # or $ at %s:%d`, s, p.filename, p.line())
			}
			p.src = p.src[1:]
			if x := p.peek1(); x != t.IDSemicolon {
				got := p.tm.ByID(x)
				return nil, fmt.Errorf(`parse: expected (implicit) ";", got %q at %s:%d`, got, p.filename, p.line())
			}
			p.src = p.src[1:]
			return a.NewStatus(flags, p.filename, line, message).AsNode(), nil

		case t.IDStruct:
			p.src = p.src[1:]
			name, err := p.parseIdent()
			if err != nil {
				return nil, err
			}
			if !p.opts.AllowDoubleUnderscoreNames && containsDoubleUnderscore(p.tm.ByID(name)) {
				return nil, fmt.Errorf(`parse: double-underscore %q used for struct name at %s:%d`,
					p.tm.ByID(name), p.filename, p.line())
			}

			if p.peek1() == t.IDQuestion {
				flags |= a.FlagsClassy
				p.src = p.src[1:]
			}

			implements := []*a.Node(nil)
			if p.peek1() == t.IDImplements {
				p.src = p.src[1:]
				implements, err = p.parseList(t.IDOpenParen, (*parser).parseQualifiedIdentAsTypeExprNode)
				if err != nil {
					return nil, err
				}
				if len(implements) > a.MaxImplements {
					return nil, fmt.Errorf(`parse: too many implements listed at %s:%d`, p.filename, p.line())
				}
			}

			fields, err := p.parseList(t.IDCloseParen, (*parser).parseFieldNode)
			if err != nil {
				return nil, err
			}
			if x := p.peek1(); x == t.IDOpenParen {
				extraFields, err := p.parseList(t.IDCloseParen, (*parser).parseExtraFieldNode)
				if err != nil {
					return nil, err
				}
				fields = append(fields, extraFields...)
			}
			if x := p.peek1(); x != t.IDSemicolon {
				got := p.tm.ByID(x)
				return nil, fmt.Errorf(`parse: expected (implicit) ";", got %q at %s:%d`, got, p.filename, p.line())
			}
			p.src = p.src[1:]
			return a.NewStruct(flags, p.filename, line, name, implements, fields).AsNode(), nil
		}
	}
	return nil, fmt.Errorf(`parse: unrecognized top level declaration at %s:%d`, p.filename, line)
}

func (p *parser) parseQualifiedIdentAsTypeExprNode() (*a.Node, error) {
	pkg, name, err := p.parseQualifiedIdent()
	if err != nil {
		return nil, err
	}
	return a.NewTypeExpr(0, pkg, name, nil, nil, nil).AsNode(), nil
}

// parseQualifiedIdent parses "foo.bar" or "bar".
func (p *parser) parseQualifiedIdent() (t.ID, t.ID, error) {
	x, err := p.parseIdent()
	if err != nil {
		return 0, 0, err
	}

	if p.peek1() != t.IDDot {
		return 0, x, nil
	}
	p.src = p.src[1:]

	y, err := p.parseIdent()
	if err != nil {
		return 0, 0, err
	}
	return x, y, nil
}

func (p *parser) parseIdentAsExprNode() (*a.Node, error) {
	id, err := p.parseIdent()
	if err != nil {
		return nil, err
	}
	return a.NewExpr(0, 0, id, nil, nil, nil, nil).AsNode(), nil
}

func (p *parser) parseIdent() (t.ID, error) {
	if len(p.src) == 0 {
		return 0, fmt.Errorf(`parse: expected identifier at %s:%d`, p.filename, p.line())
	}
	x := p.src[0]
	if !x.ID.IsIdent(p.tm) {
		got := p.tm.ByID(x.ID)
		return 0, fmt.Errorf(`parse: expected identifier, got %q at %s:%d`, got, p.filename, p.line())
	}
	p.src = p.src[1:]
	return x.ID, nil
}

func (p *parser) parseList(stop t.ID, parseElem func(*parser) (*a.Node, error)) ([]*a.Node, error) {
	if stop == t.IDCloseParen {
		if x := p.peek1(); x != t.IDOpenParen {
			return nil, fmt.Errorf(`parse: expected "(", got %q at %s:%d`,
				p.tm.ByID(x), p.filename, p.line())
		}
		p.src = p.src[1:]
	}

	ret := []*a.Node(nil)
	for len(p.src) > 0 {
		if id := p.src[0].ID; id == stop {
			if stop == t.IDCloseParen || stop == t.IDCloseBracket {
				p.src = p.src[1:]
			}
			return ret, nil
		} else if (stop == t.IDOpenDoubleCurly) && (id == t.IDOpenCurly) {
			return ret, nil
		}

		elem, err := parseElem(p)
		if err != nil {
			return nil, err
		}
		ret = append(ret, elem)

		switch x := p.peek1(); x {
		case stop:
			if stop == t.IDCloseParen || stop == t.IDCloseBracket {
				p.src = p.src[1:]
			}
			return ret, nil
		case t.IDComma:
			p.src = p.src[1:]
		default:
			return nil, fmt.Errorf(`parse: expected %q, got %q at %s:%d`,
				p.tm.ByID(stop), p.tm.ByID(x), p.filename, p.line())
		}
	}
	return nil, fmt.Errorf(`parse: expected %q at %s:%d`, p.tm.ByID(stop), p.filename, p.line())
}

func (p *parser) parseFieldNode() (*a.Node, error) {
	return p.parseFieldNode1(0)
}

func (p *parser) parseExtraFieldNode() (*a.Node, error) {
	n, err := p.parseFieldNode1(a.FlagsPrivateData)
	if err != nil {
		return nil, err
	}
	typ := n.AsField().XType()
	for typ.Decorator() == t.IDArray {
		typ = typ.Inner()
	}
	if (typ.Decorator() != 0) ||
		(typ.QID()[0] == t.IDBase) && (!typ.IsNumType() || typ.IsRefined()) {

		return nil, fmt.Errorf(`parse: invalid extra-field type %q at %s:%d`,
			n.AsField().XType().Str(p.tm), p.filename, p.line())
	}
	return n, nil
}

func (p *parser) parseFieldNode1(flags a.Flags) (*a.Node, error) {
	name, err := p.parseIdent()
	if err != nil {
		return nil, err
	}
	if x := p.peek1(); x != t.IDColon {
		got := p.tm.ByID(x)
		return nil, fmt.Errorf(`parse: expected ":", got %q at %s:%d`, got, p.filename, p.line())
	}
	p.src = p.src[1:]
	typ, err := p.parseTypeExpr()
	if err != nil {
		return nil, err
	}
	if pkg := typ.Innermost().QID()[0]; (pkg != 0) && (pkg != t.IDBase) {
		flags |= a.FlagsPrivateData
	}
	return a.NewField(flags, name, typ).AsNode(), nil
}

func (p *parser) parseTypeExpr() (*a.TypeExpr, error) {
	if x := p.peek1(); x == t.IDNptr || x == t.IDPtr {
		p.src = p.src[1:]
		rhs, err := p.parseTypeExpr()
		if err != nil {
			return nil, err
		}
		return a.NewTypeExpr(x, 0, 0, nil, nil, rhs), nil
	}

	decorator, arrayLength := t.ID(0), (*a.Expr)(nil)
	switch p.peek1() {
	case t.IDArray:
		decorator = t.IDArray
		p.src = p.src[1:]

		if x := p.peek1(); x != t.IDOpenBracket {
			got := p.tm.ByID(x)
			return nil, fmt.Errorf(`parse: expected "[", got %q at %s:%d`, got, p.filename, p.line())
		}
		p.src = p.src[1:]

		var err error
		arrayLength, err = p.parseExpr()
		if err != nil {
			return nil, err
		}

		if x := p.peek1(); x != t.IDCloseBracket {
			got := p.tm.ByID(x)
			return nil, fmt.Errorf(`parse: expected "]", got %q at %s:%d`, got, p.filename, p.line())
		}
		p.src = p.src[1:]

	case t.IDSlice:
		decorator = t.IDSlice
		p.src = p.src[1:]

	case t.IDTable:
		decorator = t.IDTable
		p.src = p.src[1:]
	}

	if decorator != 0 {
		rhs, err := p.parseTypeExpr()
		if err != nil {
			return nil, err
		}
		return a.NewTypeExpr(decorator, 0, 0, arrayLength.AsNode(), nil, rhs), nil
	}

	pkg, name, err := p.parseQualifiedIdent()
	if err != nil {
		return nil, err
	}

	lhs, mhs := (*a.Expr)(nil), (*a.Expr)(nil)
	if p.peek1() == t.IDOpenBracket {
		_, lhs, mhs, err = p.parseBracket(t.IDDotDotEq)
		if err != nil {
			return nil, err
		}
		if name.IsNumType() &&
			((pkg == t.IDBase) || ((pkg == 0) && p.opts.AllowBuiltInNames)) {
			// No-op.
		} else {
			return nil, fmt.Errorf(`parse: cannot refine non-numeric type at %s:%d`, p.filename, p.line())
		}
	}

	return a.NewTypeExpr(0, pkg, name, lhs.AsNode(), mhs, nil), nil
}

// parseBracket parses "[i .. j]", "[i ..]", "[.. j]" and "[..]". A "..="
// replaces the ".." if sep is t.IDDotDotEq instead of t.IDDotDot. If sep is
// t.IDDotDot, it also parses "[x]". The returned op is sep for a range or
// refinement and t.IDOpenBracket for an index.
func (p *parser) parseBracket(sep t.ID) (op t.ID, ei *a.Expr, ej *a.Expr, err error) {
	if x := p.peek1(); x != t.IDOpenBracket {
		got := p.tm.ByID(x)
		return 0, nil, nil, fmt.Errorf(`parse: expected "[", got %q at %s:%d`, got, p.filename, p.line())
	}
	p.src = p.src[1:]

	if p.peek1() != sep {
		ei, err = p.parseExpr()
		if err != nil {
			return 0, nil, nil, err
		}
	}

	switch x := p.peek1(); {
	case x == sep:
		p.src = p.src[1:]

	case x == t.IDCloseBracket && sep == t.IDDotDot:
		p.src = p.src[1:]
		return a.ExprOperatorIndex, nil, ei, nil

	default:
		extra := ``
		if sep == t.IDDotDot {
			extra = ` or "]"`
		}
		got := p.tm.ByID(x)
		return 0, nil, nil, fmt.Errorf(`parse: expected %q%s, got %q at %s:%d`,
			p.tm.ByID(sep), extra, got, p.filename, p.line())
	}

	if p.peek1() != t.IDCloseBracket {
		ej, err = p.parseExpr()
		if err != nil {
			return 0, nil, nil, err
		}
	}

	if x := p.peek1(); x != t.IDCloseBracket {
		got := p.tm.ByID(x)
		return 0, nil, nil, fmt.Errorf(`parse: expected "]", got %q at %s:%d`, got, p.filename, p.line())
	}
	p.src = p.src[1:]

	return sep, ei, ej, nil
}

func (p *parser) parseBlock(doubleCurly bool) ([]*a.Node, error) {
	if doubleCurly {
		if x := p.peek1(); x != t.IDOpenDoubleCurly {
			got := p.tm.ByID(x)
			return nil, fmt.Errorf(`parse: expected "{{", got %q at %s:%d`, got, p.filename, p.line())
		}
	} else {
		if x := p.peek1(); x != t.IDOpenCurly {
			got := p.tm.ByID(x)
			return nil, fmt.Errorf(`parse: expected "{", got %q at %s:%d`, got, p.filename, p.line())
		}
	}
	p.src = p.src[1:]

	block := []*a.Node(nil)
	for {
		if len(p.src) == 0 {
			return nil, fmt.Errorf(`parse: expected "}" or "}}" at %s:%d`, p.filename, p.line())
		}

		if doubleCurly {
			if p.src[0].ID == t.IDCloseDoubleCurly {
				break
			}
		} else {
			if p.src[0].ID == t.IDCloseCurly {
				break
			}
		}

		s, err := p.parseStatement()
		if err != nil {
			return nil, err
		}
		block = append(block, s)

		if x := p.peek1(); x != t.IDSemicolon {
			got := p.tm.ByID(x)
			return nil, fmt.Errorf(`parse: expected (implicit) ";", got %q at %s:%d`, got, p.filename, p.line())
		}
		p.src = p.src[1:]
	}

	p.src = p.src[1:]
	return block, nil
}

func (p *parser) assertsSorted(asserts []*a.Node, allowChoose bool) error {
	seenPre, seenInv, seenPost := false, false, false
	for _, o := range asserts {
		switch o.AsAssert().Keyword() {
		case t.IDAssert:
			return fmt.Errorf(`parse: assertion chain cannot contain "assert", `+
				`only "pre", "inv" and "post" at %s:%d`, p.filename, p.line())
		case t.IDChoose:
			if !allowChoose {
				return fmt.Errorf(`parse: invalid "choose" at %s:%d`, p.filename, p.line())
			}
			if seenPre || seenPost || seenInv {
				break
			}
			continue
		case t.IDPre:
			if seenPost || seenInv {
				break
			}
			seenPre = true
			continue
		case t.IDInv:
			if seenPost {
				break
			}
			seenInv = true
			continue
		default:
			seenPost = true
			continue
		}
		return fmt.Errorf(`parse: assertion chain not in "choose", "pre", "inv", "post" order at %s:%d`,
			p.filename, p.line())
	}
	return nil
}

func (p *parser) parseAssertNode() (*a.Node, error) {
	switch x := p.peek1(); x {
	case t.IDAssert, t.IDChoose, t.IDPre, t.IDInv, t.IDPost:
		p.src = p.src[1:]
		condition, err := p.parseExpr()
		if err != nil {
			return nil, err
		}
		if condition.Effect() != 0 {
			return nil, fmt.Errorf(`parse: assert-condition %q is not effect-free at %s:%d`,
				condition.Str(p.tm), p.filename, p.line())
		}
		reason, args := t.ID(0), []*a.Node(nil)
		if p.peek1() == t.IDVia {
			p.src = p.src[1:]
			reason = p.peek1()
			if !reason.IsDQStrLiteral(p.tm) {
				got := p.tm.ByID(reason)
				return nil, fmt.Errorf(`parse: expected "-string literal, got %q at %s:%d`, got, p.filename, p.line())
			}
			p.src = p.src[1:]
			args, err = p.parseList(t.IDCloseParen, (*parser).parseArgNode)
			if err != nil {
				return nil, err
			}
		}
		return a.NewAssert(x, condition, reason, args).AsNode(), nil
	}
	return nil, fmt.Errorf(`parse: expected "assert", "pre" or "post" at %s:%d`, p.filename, p.line())
}

func (p *parser) parseStatement() (*a.Node, error) {
	line := uint32(0)
	if len(p.src) > 0 {
		line = p.src[0].Line
	}
	n, err := p.parseStatement1()
	if n != nil {
		n.AsRaw().SetFilenameLine(p.filename, line)
		if n.Kind() == a.KIterate {
			for _, o := range n.AsIterate().Assigns() {
				o.AsRaw().SetFilenameLine(p.filename, line)
			}
		}
	}
	return n, err
}

func (p *parser) parseLabel() (t.ID, error) {
	if p.peek1() == t.IDDot {
		p.src = p.src[1:]
		return p.parseIdent()
	}
	return 0, nil
}

func (p *parser) parseEndwhile(label t.ID) bool {
	if p.peek1() != t.IDEndwhile {
		return false
	}
	p.src = p.src[1:]
	if label != 0 {
		if p.peek1() != t.IDDot {
			return false
		}
		p.src = p.src[1:]
		if p.peek1() != label {
			return false
		}
		p.src = p.src[1:]
	}
	return true
}

func (p *parser) parseStatement1() (*a.Node, error) {
	x := p.peek1()
	if x == t.IDVar {
		if !p.allowVar {
			return nil, fmt.Errorf(`parse: var statement not at the top of a function at %s:%d`,
				p.filename, p.line())
		}
		p.src = p.src[1:]
		return p.parseVarNode()
	}
	p.allowVar = false

	switch x {
	case t.IDAssert:
		return p.parseAssertNode()

	case t.IDBreak, t.IDContinue:
		p.src = p.src[1:]
		label, err := p.parseLabel()
		if err != nil {
			return nil, err
		}

		loop := a.Loop(nil)
		if len(p.loops) == 0 {
			// No-op.
		} else if label == 0 {
			loop = p.loops[len(p.loops)-1]
			if loop.Label() != 0 {
				return nil, fmt.Errorf(`parse: unlabeled %s for labeled %s.%s at %s:%d`,
					x.Str(p.tm), loop.Keyword().Str(p.tm), loop.Label().Str(p.tm), p.filename, p.line())
			}
		} else {
			for i := len(p.loops) - 1; i >= 0; i-- {
				if l := p.loops[i]; label == l.Label() {
					loop = l
					break
				}
			}
		}
		if loop == nil {
			sepStr, labelStr := "", ""
			if label != 0 {
				sepStr, labelStr = ".", label.Str(p.tm)
			}
			return nil, fmt.Errorf(`parse: no matching while/iterate statement for %s%s%s at %s:%d`,
				x.Str(p.tm), sepStr, labelStr, p.filename, p.line())
		}

		if x == t.IDBreak {
			loop.SetHasBreak()
		} else {
			loop.SetHasContinue()
		}
		n := a.NewJump(x, label)
		n.SetJumpTarget(loop)
		return n.AsNode(), nil

	case t.IDChoose:
		p.src = p.src[1:]
		if p.funcEffect.Pure() {
			return nil, fmt.Errorf(`parse: choose within pure function at %s:%d`, p.filename, p.line())
		}
		name, err := p.parseIdent()
		if err != nil {
			return nil, err
		}
		if x := p.peek1(); x != t.IDEq {
			got := p.tm.ByID(x)
			return nil, fmt.Errorf(`parse: expected "=", got %q at %s:%d`, got, p.filename, p.line())
		}
		p.src = p.src[1:]
		if x := p.peek1(); x != t.IDOpenBracket {
			got := p.tm.ByID(x)
			return nil, fmt.Errorf(`parse: expected "[", got %q at %s:%d`, got, p.filename, p.line())
		}
		p.src = p.src[1:]
		args, err := p.parseList(t.IDCloseBracket, (*parser).parseIdentAsExprNode)
		if err != nil {
			return nil, err
		}
		return a.NewChoose(name, args).AsNode(), nil

	case t.IDIOBind, t.IDIOLimit:
		return p.parseIOManipNode()

	case t.IDIf:
		o, err := p.parseIf()
		return o.AsNode(), err

	case t.IDIterate:
		return p.parseIterateNode()

	case t.IDReturn, t.IDYield:
		p.src = p.src[1:]
		if x == t.IDYield {
			if !p.funcEffect.Coroutine() {
				return nil, fmt.Errorf(`parse: yield within non-coroutine at %s:%d`, p.filename, p.line())
			}
			if p.peek1() != t.IDQuestion {
				return nil, fmt.Errorf(`parse: yield not followed by '?' at %s:%d`, p.filename, p.line())
			}
			p.src = p.src[1:]
		}
		value, err := p.parseExpr()
		if err != nil {
			return nil, err
		}
		if value.Effect().Impure() {
			return nil, fmt.Errorf(`parse: %s an impure expression at %s:%d`,
				x.Str(p.tm), p.filename, p.line())
		}
		if (x == t.IDReturn) && (value.Operator() == 0) {
			if s := p.tm.ByID(value.Ident()); (len(s) > 1) && (s[0] == '"') && (s[1] == '$') {
				return nil, fmt.Errorf(`parse: cannot return a suspension at %s:%d`, p.filename, p.line())
			}
		}
		return a.NewRet(x, value).AsNode(), nil

	case t.IDWhile:
		p.src = p.src[1:]
		label, err := p.parseLabel()
		if err != nil {
			return nil, err
		}
		condition, err := p.parseExpr()
		if err != nil {
			return nil, err
		}
		if condition.Effect() != 0 {
			return nil, fmt.Errorf(`parse: while-condition %q is not effect-free at %s:%d`,
				condition.Str(p.tm), p.filename, p.line())
		}
		asserts, err := p.parseAsserts()
		if err != nil {
			return nil, err
		}

		n := a.NewWhile(label, condition, asserts)
		if !p.loops.Push(n) {
			return nil, fmt.Errorf(`parse: duplicate loop label %s at %s:%d`,
				label.Str(p.tm), p.filename, p.line())
		}
		doubleCurly := p.peek1() == t.IDOpenDoubleCurly
		if doubleCurly && !n.IsWhileTrue() {
			return nil, fmt.Errorf(`parse: double {{ }} while loop condition isn't "true" at %s:%d`,
				p.filename, p.line())
		}
		body, err := p.parseBlock(doubleCurly)
		if err != nil {
			return nil, err
		}
		n.SetBody(body)
		p.loops.Pop()

		if !p.parseEndwhile(label) {
			dotLabel := ""
			if label != 0 {
				dotLabel = "." + label.Str(p.tm)
			}
			return nil, fmt.Errorf(`parse: expected endwhile%s at %s:%d`,
				dotLabel, p.filename, p.line())
		}
		if !doubleCurly {
			// No-op.
		} else if n.HasContinue() {
			return nil, fmt.Errorf(`parse: double {{ }} while loop has explicit continue at %s:%d`,
				p.filename, p.line())
		} else if !a.Terminates(body) {
			return nil, fmt.Errorf(`parse: double {{ }} while loop doesn't terminate at %s:%d`,
				p.filename, p.line())
		}
		return n.AsNode(), nil
	}
	return p.parseAssignNode()
}

func (p *parser) parseAssignNode() (*a.Node, error) {
	lhs := (*a.Expr)(nil)
	rhs, err := p.parseExpr()
	if err != nil {
		return nil, err
	}

	op := p.peek1()
	if op.IsAssign() {
		p.src = p.src[1:]
		lhs = rhs
		if lhs.Effect() != 0 {
			return nil, fmt.Errorf(`parse: assignment LHS %q is not effect-free at %s:%d`,
				lhs.Str(p.tm), p.filename, p.line())
		}

		for l := lhs; l != nil; l = l.LHS().AsExpr() {
			switch l.Operator() {
			case 0:
				if id := l.Ident(); id.IsLiteral(p.tm) {
					return nil, fmt.Errorf(`parse: assignment LHS %q is a literal at %s:%d`,
						l.Str(p.tm), p.filename, p.line())
				} else if id.IsCannotAssignTo() {
					if l == lhs {
						return nil, fmt.Errorf(`parse: cannot assign to %q at %s:%d`,
							id.Str(p.tm), p.filename, p.line())
					}
					if !p.funcEffect.Impure() {
						return nil, fmt.Errorf(`parse: cannot assign to %q in a pure function at %s:%d`,
							lhs.Str(p.tm), p.filename, p.line())
					}
				}
			case t.IDDot, t.IDOpenBracket:
				// No-op.
			default:
				return nil, fmt.Errorf(`parse: invalid assignment LHS %q at %s:%d`,
					lhs.Str(p.tm), p.filename, p.line())
			}
		}

		rhs, err = p.parseExpr()
		if err != nil {
			return nil, err
		}

		if op == t.IDEqQuestion {
			if (rhs.Operator() != a.ExprOperatorCall) || (!rhs.Effect().Coroutine()) {
				return nil, fmt.Errorf(`parse: expected ?-function call after "=?", got %q at %s:%d`,
					rhs.Str(p.tm), p.filename, p.line())
			}
		}
	} else {
		op = t.IDEq
	}

	if p.funcEffect.WeakerThan(rhs.Effect()) {
		return nil, fmt.Errorf(`parse: value %q's effect %q is stronger than the func's effect %q at %s:%d`,
			rhs.Str(p.tm), rhs.Effect(), p.funcEffect, p.filename, p.line())
	}

	return a.NewAssign(op, lhs, rhs).AsNode(), nil
}

func (p *parser) parseIterateAssignNode() (*a.Node, error) {
	n, err := p.parseAssignNode()
	if err != nil {
		return nil, err
	}
	o := n.AsAssign()
	if op := o.Operator(); op != t.IDEq {
		return nil, fmt.Errorf(`parse: expected "=", got %q at %s:%d`, op.Str(p.tm), p.filename, p.line())
	}
	if lhs := o.LHS(); lhs.Operator() != 0 {
		return nil, fmt.Errorf(`parse: expected variable, got %q at %s:%d`, lhs.Str(p.tm), p.filename, p.line())
	}
	if rhs := o.RHS(); rhs.Effect() != 0 {
		return nil, fmt.Errorf(`parse: value %q is not effect-free at %s:%d`, rhs.Str(p.tm), p.filename, p.line())
	}
	return o.AsNode(), nil
}

func (p *parser) parseAsserts() ([]*a.Node, error) {
	asserts := []*a.Node(nil)
	if p.peek1() == t.IDComma {
		p.src = p.src[1:]
		var err error
		if asserts, err = p.parseList(t.IDOpenDoubleCurly, (*parser).parseAssertNode); err != nil {
			return nil, err
		}
		if err := p.assertsSorted(asserts, false); err != nil {
			return nil, err
		}
	}
	return asserts, nil
}

func (p *parser) parseIOManipNode() (*a.Node, error) {
	keyword := p.peek1()
	p.src = p.src[1:]

	if x := p.peek1(); x != t.IDOpenParen {
		got := p.tm.ByID(x)
		return nil, fmt.Errorf(`parse: expected "(", got %q at %s:%d`, got, p.filename, p.line())
	}
	p.src = p.src[1:]

	if x := p.peek1(); x != t.IDIO {
		got := p.tm.ByID(x)
		return nil, fmt.Errorf(`parse: expected "io", got %q at %s:%d`, got, p.filename, p.line())
	}
	p.src = p.src[1:]

	if x := p.peek1(); x != t.IDColon {
		got := p.tm.ByID(x)
		return nil, fmt.Errorf(`parse: expected ":", got %q at %s:%d`, got, p.filename, p.line())
	}
	p.src = p.src[1:]

	io, err := p.parseExpr()
	if err != nil {
		return nil, err
	}
	if io.Effect() != 0 {
		return nil, fmt.Errorf(`parse: argument %q is not effect-free at %s:%d`,
			io.Str(p.tm), p.filename, p.line())
	}

	arg1Name := t.ID(0)
	if keyword == t.IDIOBind {
		arg1Name = t.IDData
		if io.Operator() != 0 {
			return nil, fmt.Errorf(`parse: invalid %s argument %q at %s:%d`,
				keyword.Str(p.tm), io.Str(p.tm), p.filename, p.line())
		}
	} else {
		arg1Name = t.IDLimit
		if (io.Operator() != 0) && (io.IsArgsDotFoo() == 0) {
			return nil, fmt.Errorf(`parse: invalid %s argument %q at %s:%d`,
				keyword.Str(p.tm), io.Str(p.tm), p.filename, p.line())
		}
	}

	if x := p.peek1(); x != t.IDComma {
		got := p.tm.ByID(x)
		return nil, fmt.Errorf(`parse: expected ",", got %q at %s:%d`, got, p.filename, p.line())
	}
	p.src = p.src[1:]

	if x := p.peek1(); x != arg1Name {
		got := p.tm.ByID(x)
		return nil, fmt.Errorf(`parse: expected %q, got %q at %s:%d`, arg1Name.Str(p.tm), got, p.filename, p.line())
	}
	p.src = p.src[1:]

	if x := p.peek1(); x != t.IDColon {
		got := p.tm.ByID(x)
		return nil, fmt.Errorf(`parse: expected ":", got %q at %s:%d`, got, p.filename, p.line())
	}
	p.src = p.src[1:]

	arg1, err := p.parseExpr()
	if err != nil {
		return nil, err
	}
	if arg1.Effect() != 0 {
		return nil, fmt.Errorf(`parse: argument %q is not effect-free at %s:%d`,
			io.Str(p.tm), p.filename, p.line())
	}

	histPos := (*a.Expr)(nil)
	if keyword == t.IDIOBind {
		if x := p.peek1(); x != t.IDComma {
			got := p.tm.ByID(x)
			return nil, fmt.Errorf(`parse: expected ",", got %q at %s:%d`, got, p.filename, p.line())
		}
		p.src = p.src[1:]

		if x := p.peek1(); x != t.IDHistoryPosition {
			got := p.tm.ByID(x)
			return nil, fmt.Errorf(`parse: expected "history_position", got %q at %s:%d`, got, p.filename, p.line())
		}
		p.src = p.src[1:]

		if x := p.peek1(); x != t.IDColon {
			got := p.tm.ByID(x)
			return nil, fmt.Errorf(`parse: expected ":", got %q at %s:%d`, got, p.filename, p.line())
		}
		p.src = p.src[1:]

		histPos, err = p.parseExpr()
		if err != nil {
			return nil, err
		}
		if histPos.Effect() != 0 {
			return nil, fmt.Errorf(`parse: argument %q is not effect-free at %s:%d`,
				io.Str(p.tm), p.filename, p.line())
		}
	}

	if x := p.peek1(); x != t.IDCloseParen {
		got := p.tm.ByID(x)
		return nil, fmt.Errorf(`parse: expected ")", got %q at %s:%d`, got, p.filename, p.line())
	}
	p.src = p.src[1:]

	body, err := p.parseBlock(false)
	if err != nil {
		return nil, err
	}

	return a.NewIOManip(keyword, io, arg1, histPos, body).AsNode(), nil
}

func (p *parser) parseIf() (*a.If, error) {
	if x := p.peek1(); x != t.IDIf {
		got := p.tm.ByID(x)
		return nil, fmt.Errorf(`parse: expected "if", got %q at %s:%d`, got, p.filename, p.line())
	}
	p.src = p.src[1:]
	condition, err := p.parseExpr()
	if err != nil {
		return nil, err
	}
	if condition.Effect() != 0 {
		return nil, fmt.Errorf(`parse: if-condition %q is not effect-free at %s:%d`,
			condition.Str(p.tm), p.filename, p.line())
	}
	bodyIfTrue, err := p.parseBlock(false)
	if err != nil {
		return nil, err
	}
	elseIf, bodyIfFalse := (*a.If)(nil), ([]*a.Node)(nil)
	if p.peek1() == t.IDElse {
		p.src = p.src[1:]
		if p.peek1() == t.IDIf {
			elseIf, err = p.parseIf()
			if err != nil {
				return nil, err
			}
		} else {
			bodyIfFalse, err = p.parseBlock(false)
			if err != nil {
				return nil, err
			}
		}
	}
	return a.NewIf(condition, bodyIfTrue, bodyIfFalse, elseIf), nil
}

func (p *parser) parseIterateNode() (*a.Node, error) {
	if p.funcEffect.Coroutine() {
		return nil, fmt.Errorf(`parse: "iterate" inside coroutine at %s:%d`, p.filename, p.line())
	} else if x := p.peek1(); x != t.IDIterate {
		got := p.tm.ByID(x)
		return nil, fmt.Errorf(`parse: expected "iterate", got %q at %s:%d`, got, p.filename, p.line())
	}
	p.src = p.src[1:]
	label, err := p.parseLabel()
	if err != nil {
		return nil, err
	}
	assigns, err := p.parseList(t.IDCloseParen, (*parser).parseIterateAssignNode)
	if err != nil {
		return nil, err
	}
	n, err := p.parseIterateBlock(label, assigns)
	if err != nil {
		return nil, err
	}
	return n.AsNode(), nil
}

func (p *parser) parseIterateBlock(label t.ID, assigns []*a.Node) (*a.Iterate, error) {
	if x := p.peek1(); x != t.IDOpenParen {
		got := p.tm.ByID(x)
		return nil, fmt.Errorf(`parse: expected "(", got %q at %s:%d`, got, p.filename, p.line())
	}
	p.src = p.src[1:]

	if x := p.peek1(); x != t.IDLength {
		got := p.tm.ByID(x)
		return nil, fmt.Errorf(`parse: expected "length", got %q at %s:%d`, got, p.filename, p.line())
	}
	p.src = p.src[1:]

	if x := p.peek1(); x != t.IDColon {
		got := p.tm.ByID(x)
		return nil, fmt.Errorf(`parse: expected ":", got %q at %s:%d`, got, p.filename, p.line())
	}
	p.src = p.src[1:]

	length := p.peek1()
	lengthInt := asSmallPositiveInt256(p.tm, length)
	if lengthInt == 0 {
		return nil, fmt.Errorf(`parse: expected length count in [1 ..= 256], got %q at %s:%d`,
			p.tm.ByID(length), p.filename, p.line())
	}
	p.src = p.src[1:]

	if x := p.peek1(); x != t.IDComma {
		got := p.tm.ByID(x)
		return nil, fmt.Errorf(`parse: expected ",", got %q at %s:%d`, got, p.filename, p.line())
	}
	p.src = p.src[1:]

	if x := p.peek1(); x != t.IDAdvance {
		got := p.tm.ByID(x)
		return nil, fmt.Errorf(`parse: expected "advance", got %q at %s:%d`, got, p.filename, p.line())
	}
	p.src = p.src[1:]

	if x := p.peek1(); x != t.IDColon {
		got := p.tm.ByID(x)
		return nil, fmt.Errorf(`parse: expected ":", got %q at %s:%d`, got, p.filename, p.line())
	}
	p.src = p.src[1:]

	advance := p.peek1()
	advanceInt := asSmallPositiveInt256(p.tm, advance)
	if advanceInt == 0 {
		return nil, fmt.Errorf(`parse: expected advance count in [1 ..= 256], got %q at %s:%d`,
			p.tm.ByID(advance), p.filename, p.line())
	} else if advanceInt > lengthInt {
		return nil, fmt.Errorf(`parse: advance %d is larger than length %d at %s:%d`,
			advanceInt, lengthInt, p.filename, p.line())
	}
	p.src = p.src[1:]

	if x := p.peek1(); x != t.IDComma {
		got := p.tm.ByID(x)
		return nil, fmt.Errorf(`parse: expected ",", got %q at %s:%d`, got, p.filename, p.line())
	}
	p.src = p.src[1:]

	if x := p.peek1(); x != t.IDUnroll {
		got := p.tm.ByID(x)
		return nil, fmt.Errorf(`parse: expected "unroll", got %q at %s:%d`, got, p.filename, p.line())
	}
	p.src = p.src[1:]

	if x := p.peek1(); x != t.IDColon {
		got := p.tm.ByID(x)
		return nil, fmt.Errorf(`parse: expected ":", got %q at %s:%d`, got, p.filename, p.line())
	}
	p.src = p.src[1:]

	unroll := p.peek1()
	if asSmallPositiveInt256(p.tm, unroll) == 0 {
		return nil, fmt.Errorf(`parse: expected unroll count in [1 ..= 256], got %q at %s:%d`,
			p.tm.ByID(unroll), p.filename, p.line())
	}
	p.src = p.src[1:]

	if x := p.peek1(); x != t.IDCloseParen {
		got := p.tm.ByID(x)
		return nil, fmt.Errorf(`parse: expected ")", got %q at %s:%d`, got, p.filename, p.line())
	}
	p.src = p.src[1:]

	asserts, err := p.parseAsserts()
	if err != nil {
		return nil, err
	}
	n := a.NewIterate(label, assigns, length, advance, unroll, asserts)
	// TODO: decide how break/continue work with iterate loops.
	if !p.loops.Push(n) {
		return nil, fmt.Errorf(`parse: duplicate loop label %s at %s:%d`,
			label.Str(p.tm), p.filename, p.line())
	}
	body, err := p.parseBlock(false)
	if err != nil {
		return nil, err
	}
	n.SetBody(body)
	p.loops.Pop()

	if x := p.peek1(); x == t.IDElse {
		p.src = p.src[1:]
		elseIterate, err := p.parseIterateBlock(0, nil)
		if err != nil {
			return nil, err
		}
		n.SetElseIterate(elseIterate)
	}

	return n, nil
}

// asSmallPositiveInt256 returns id's value when id is a numeric literal in the
// range [1 ..= 256]. Otherwise, it returns 0.
func asSmallPositiveInt256(tm *t.Map, id t.ID) int {
	if !id.IsNumLiteral(tm) {
		return 0
	}
	s := id.Str(tm)
	if (len(s) > 3) || (len(s) == 0) || (s[0] < '1') || ('9' < s[0]) {
		return 0
	}
	n, s := int(s[0]-'0'), s[1:]
	for ; len(s) > 0; s = s[1:] {
		if (s[0] < '0') || ('9' < s[0]) {
			return 0
		}
		n = (10 * n) + int(s[0]-'0')
	}
	if n > 256 {
		return 0
	}
	return n
}

func (p *parser) parseArgNode() (*a.Node, error) {
	name, err := p.parseIdent()
	if err != nil {
		return nil, err
	}
	if x := p.peek1(); x != t.IDColon {
		got := p.tm.ByID(x)
		return nil, fmt.Errorf(`parse: expected ":", got %q at %s:%d`, got, p.filename, p.line())
	}
	p.src = p.src[1:]
	value, err := p.parseExpr()
	if err != nil {
		return nil, err
	}
	if value.Effect() != 0 {
		return nil, fmt.Errorf(`parse: arg-value %q is not effect-free at %s:%d`,
			value.Str(p.tm), p.filename, p.line())
	}
	return a.NewArg(name, value).AsNode(), nil
}

func (p *parser) parseVarNode() (*a.Node, error) {
	id, err := p.parseIdent()
	if err != nil {
		return nil, err
	}
	if x := p.peek1(); x != t.IDColon {
		got := p.tm.ByID(x)
		return nil, fmt.Errorf(`parse: expected ":", got %q at %s:%d`, got, p.filename, p.line())
	}
	p.src = p.src[1:]
	typ, err := p.parseTypeExpr()
	if err != nil {
		return nil, err
	}
	return a.NewVar(id, typ).AsNode(), nil
}

func (p *parser) parsePossibleListExprNode() (*a.Node, error) {
	n, err := p.parsePossibleListExpr()
	if err != nil {
		return nil, err
	}
	return n.AsNode(), err
}

func (p *parser) parsePossibleListExpr() (*a.Expr, error) {
	// TODO: put the [ and ] parsing into parseExpr.
	if x := p.peek1(); x != t.IDOpenBracket {
		return p.parseExpr()
	}
	p.src = p.src[1:]
	args, err := p.parseList(t.IDCloseBracket, (*parser).parsePossibleListExprNode)
	if err != nil {
		return nil, err
	}
	return a.NewExpr(0, a.ExprOperatorList, 0, nil, nil, nil, args), nil
}

func (p *parser) parseExpr() (*a.Expr, error) {
	e, err := p.parseExpr1()
	if err != nil {
		return nil, err
	}
	if e.SubExprHasEffect() {
		return nil, fmt.Errorf(`parse: expression %q has an effect-ful sub-expression at %s:%d`,
			e.Str(p.tm), p.filename, p.line())
	}
	return e, nil
}

func (p *parser) parseExpr1() (*a.Expr, error) {
	lhs, err := p.parseOperand()
	if err != nil {
		return nil, err
	}
	if x := p.peek1(); x.IsBinaryOp() {
		p.src = p.src[1:]
		rhs := (*a.Node)(nil)
		if x == t.IDAs {
			o, err := p.parseTypeExpr()
			if err != nil {
				return nil, err
			}
			rhs = o.AsNode()
		} else {
			o, err := p.parseOperand()
			if err != nil {
				return nil, err
			}
			rhs = o.AsNode()
		}

		if !x.IsAssociativeOp() || x != p.peek1() {
			op := x.BinaryForm()
			if op == 0 {
				return nil, fmt.Errorf(`parse: internal error: no binary form for token 0x%02X`, x)
			}
			return a.NewExpr(0, op, 0, lhs.AsNode(), nil, rhs, nil), nil
		}

		args := []*a.Node{lhs.AsNode(), rhs}
		for p.peek1() == x {
			p.src = p.src[1:]
			arg, err := p.parseOperand()
			if err != nil {
				return nil, err
			}
			args = append(args, arg.AsNode())
		}
		op := x.AssociativeForm()
		if op == 0 {
			return nil, fmt.Errorf(`parse: internal error: no associative form for token 0x%02X`, x)
		}
		return a.NewExpr(0, op, 0, nil, nil, nil, args), nil
	}
	return lhs, nil
}

func (p *parser) parseOperand() (*a.Expr, error) {
	switch x := p.peek1(); {
	case x.IsUnaryOp():
		p.src = p.src[1:]
		rhs, err := p.parseOperand()
		if err != nil {
			return nil, err
		}
		op := x.UnaryForm()
		if op == 0 {
			return nil, fmt.Errorf(`parse: internal error: no unary form for token 0x%02X`, x)
		}
		return a.NewExpr(0, op, 0, nil, nil, rhs.AsNode(), nil), nil

	case x.IsLiteral(p.tm):
		p.src = p.src[1:]
		return a.NewExpr(0, 0, x, nil, nil, nil, nil), nil

	case x == t.IDOpenParen:
		p.src = p.src[1:]
		expr, err := p.parseExpr()
		if err != nil {
			return nil, err
		}
		if x := p.peek1(); x != t.IDCloseParen {
			got := p.tm.ByID(x)
			return nil, fmt.Errorf(`parse: expected ")", got %q at %s:%d`, got, p.filename, p.line())
		}
		p.src = p.src[1:]
		return expr, nil
	}

	id, err := p.parseIdent()
	if err != nil {
		return nil, err
	}
	lhs := a.NewExpr(0, 0, id, nil, nil, nil, nil)

	for first := true; ; first = false {
		flags := a.Flags(0)
		switch p.peek1() {
		default:
			return lhs, nil

		case t.IDExclam, t.IDQuestion:
			flags |= p.parseEffect().AsFlags()
			fallthrough

		case t.IDOpenParen:
			args, err := p.parseList(t.IDCloseParen, (*parser).parseArgNode)
			if err != nil {
				return nil, err
			}
			lhs = a.NewExpr(flags, a.ExprOperatorCall, 0, lhs.AsNode(), nil, nil, args)

		case t.IDOpenBracket:
			id0, mhs, rhs, err := p.parseBracket(t.IDDotDot)
			if err != nil {
				return nil, err
			}
			lhs = a.NewExpr(0, id0, 0, lhs.AsNode(), mhs.AsNode(), rhs.AsNode(), nil)

		case t.IDDot:
			p.src = p.src[1:]
			selector := p.peek1()
			if first && selector.IsDQStrLiteral(p.tm) {
				p.src = p.src[1:]
			} else {
				selector, err = p.parseIdent()
				if err != nil {
					return nil, err
				}
			}
			lhs = a.NewExpr(0, a.ExprOperatorSelector, selector, lhs.AsNode(), nil, nil, nil)
		}
	}
}

func (p *parser) parseEffect() a.Effect {
	switch p.peek1() {
	case t.IDExclam:
		p.src = p.src[1:]
		return a.EffectImpure
	case t.IDQuestion:
		p.src = p.src[1:]
		return a.EffectImpureCoroutine
	}
	return 0
}
