package eval

import (
	
	
	
)

// Utilities for working with nodes.

func ( *compiler,  *parse.Compound,  string) string {
	,  := cmpd.StringLiteralOrError(, )
	if  != nil {
		.errorpf(, "%v", )
	}
	return 
}

type errorpfer interface {
	errorpf(r diag.Ranger, fmt string, args ...interface{})
}

// argsWalker is used by builtin special forms to implement argument parsing.
type argsWalker struct {
	cp   errorpfer
	form *parse.Form
	idx  int
}

func ( *compiler) ( *parse.Form) *argsWalker {
	return &argsWalker{, , 0}
}

func ( *argsWalker) () bool {
	return .idx < len(.form.Args)
}

func ( *argsWalker) () *parse.Compound {
	if !.more() {
		.cp.errorpf(.form, "need more arguments")
	}
	return .form.Args[.idx]
}

func ( *argsWalker) () *parse.Compound {
	 := .peek()
	.idx++
	return 
}

// nextIs returns whether the next argument's source matches the given text. It
// also consumes the argument if it is.
func ( *argsWalker) ( string) bool {
	if .more() && parse.SourceText(.form.Args[.idx]) ==  {
		.idx++
		return true
	}
	return false
}

// nextMustLambda fetches the next argument, raising an error if it is not a
// lambda.
func ( *argsWalker) ( string) *parse.Primary {
	 := .next()
	,  := cmpd.Lambda()
	if ! {
		.cp.errorpf(, "%s must be lambda, found %s", , cmpd.Shape())
	}
	return 
}

func ( *argsWalker) ( string) *parse.Primary {
	if .nextIs() {
		return .nextMustLambda( + " body")
	}
	return nil
}

func ( *argsWalker) () {
	if .more() {
		.cp.errorpf(diag.Ranging{From: .form.Args[.idx].Range().From, To: .form.Range().To}, "too many arguments")
	}
}