Fix list destructuring multiple-evaluation bug
This commit is contained in:
@@ -1,7 +1,6 @@
|
|||||||
(defun main []
|
(defun main []
|
||||||
// Day 1
|
// Day 1
|
||||||
// TODO implement unless
|
// TODO implement unless
|
||||||
// TODO list destructuring a funcall results in double evaluation
|
|
||||||
(let [p (pairWithSum 2020 [1721 979 366 299 675 1456])]
|
(let [p (pairWithSum 2020 [1721 979 366 299 675 1456])]
|
||||||
(when !(and (has p 1721) (has p 299))
|
(when !(and (has p 1721) (has p 299))
|
||||||
(throw "pairWithSum is broken")))
|
(throw "pairWithSum is broken")))
|
||||||
|
|||||||
@@ -112,13 +112,17 @@ class SpecialForms {
|
|||||||
case Symbol(_) | TypedExp(_, {pos: _, def: Symbol(_)}):
|
case Symbol(_) | TypedExp(_, {pos: _, def: Symbol(_)}):
|
||||||
[toVar(namesExp, valueExp, k, isFinal)];
|
[toVar(namesExp, valueExp, k, isFinal)];
|
||||||
case ListExp(nameExps):
|
case ListExp(nameExps):
|
||||||
|
var uniqueVarName = "_" + Uuid.v4().toShort();
|
||||||
|
var uniqueVarSymbol = Symbol(uniqueVarName).withPosOf(valueExp);
|
||||||
var idx = 0;
|
var idx = 0;
|
||||||
[
|
// Only evaluate the list expression being destructured once:
|
||||||
|
[toVar(uniqueVarSymbol, valueExp, k, true)].concat([
|
||||||
for (nameExp in nameExps)
|
for (nameExp in nameExps)
|
||||||
toVar(nameExp,
|
toVar(nameExp,
|
||||||
CallExp(Symbol("nth").withPosOf(valueExp), [valueExp, Symbol(Std.string(idx++)).withPosOf(valueExp)]).withPosOf(valueExp),
|
CallExp(Symbol("nth").withPosOf(valueExp),
|
||||||
|
[uniqueVarSymbol, Symbol(Std.string(idx++)).withPosOf(valueExp)]).withPosOf(valueExp),
|
||||||
k, if (isFinal == false) false else null)
|
k, if (isFinal == false) false else null)
|
||||||
];
|
]);
|
||||||
default:
|
default:
|
||||||
throw CompileError.fromExp(namesExp, "Can only bind variables to a symbol or list of symbols for destructuring");
|
throw CompileError.fromExp(namesExp, "Can only bind variables to a symbol or list of symbols for destructuring");
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user