Don't compile the arguments of special commands twice.

This fixes #1204.
This commit is contained in:
Qi Xiao 2021-01-09 23:33:24 +00:00
parent 28f86fefc6
commit d84e9801b5
2 changed files with 9 additions and 1 deletions

View File

@ -184,11 +184,13 @@ func (cp *compiler) formOp(n *parse.Form) effectOp {
if n.Head != nil {
headStr, ok := oneString(n.Head)
argOpsNeeded := true
if ok {
special, fnRef := resolveCmdHeadInternally(cp, headStr, n.Head)
switch {
case special != nil:
specialOp = special(cp, n)
argOpsNeeded = false
case fnRef != nil:
headOp = variableOp{n.Head.Range(), false, headStr + FnSuffix, fnRef}
default:
@ -199,7 +201,9 @@ func (cp *compiler) formOp(n *parse.Form) effectOp {
// expression.
headOp = cp.compoundOp(n.Head)
}
argOps = cp.compoundOps(n.Args)
if argOpsNeeded {
argOps = cp.compoundOps(n.Args)
}
} else {
// Assignment form.
lhs := cp.parseCompoundLValues(n.Vars)

View File

@ -70,6 +70,10 @@ func TestCompileEffect(t *testing.T) {
// Command errors when any optional evaluation errors.
That("put &x=[][1]").Throws(ErrorWithType(errs.OutOfRange{}), "[][1]"),
// Regression test for #1204; ensures that the arguments of special
// forms are not accidentally compiled twice.
That("nop (and (use builtin)); nop $builtin:echo~").DoesNothing(),
// Assignments
// -----------