(apply [func] [args]) with math op support
This commit is contained in:
@@ -41,12 +41,7 @@
|
|||||||
(assert (= 2 (Toboggan.pathTrees exampleHillTile 0 0 1 2)))
|
(assert (= 2 (Toboggan.pathTrees exampleHillTile 0 0 1 2)))
|
||||||
(assert (= 289 (Util.countChar "#" (Toboggan.pathString (Util.readLines "src/year2020/inputs/day3-1.txt") 0 0 3 1))))
|
(assert (= 289 (Util.countChar "#" (Toboggan.pathString (Util.readLines "src/year2020/inputs/day3-1.txt") 0 0 3 1))))
|
||||||
(assert (= 5522401584 (let [hillTile (Util.readLines "src/year2020/inputs/day3-1.txt")]
|
(assert (= 5522401584 (let [hillTile (Util.readLines "src/year2020/inputs/day3-1.txt")]
|
||||||
(*
|
(apply * (for args [[0 0 1 1] [0 0 3 1] [0 0 5 1] [0 0 7 1] [0 0 1 2]] (apply (Toboggan.pathTrees.bind hillTile) args)))))))
|
||||||
(Toboggan.pathTrees hillTile 0 0 1 1)
|
|
||||||
(Toboggan.pathTrees hillTile 0 0 3 1)
|
|
||||||
(Toboggan.pathTrees hillTile 0 0 5 1)
|
|
||||||
(Toboggan.pathTrees hillTile 0 0 7 1)
|
|
||||||
(Toboggan.pathTrees hillTile 0 0 1 2))))))
|
|
||||||
|
|
||||||
(defun :kiss.List<Int> pairWithSum [sum :kiss.List<Int> numbers]
|
(defun :kiss.List<Int> pairWithSum [sum :kiss.List<Int> numbers]
|
||||||
// Put the numbers in a map for random access. This gives an O(n) solution
|
// Put the numbers in a map for random access. This gives an O(n) solution
|
||||||
|
|||||||
@@ -20,14 +20,6 @@ class Macros {
|
|||||||
public static function builtins() {
|
public static function builtins() {
|
||||||
var macros:Map<String, MacroFunction> = [];
|
var macros:Map<String, MacroFunction> = [];
|
||||||
|
|
||||||
macros["+"] = variadicMacro("Prelude.add");
|
|
||||||
|
|
||||||
macros["-"] = variadicMacro("Prelude.subtract");
|
|
||||||
|
|
||||||
macros["*"] = variadicMacro("Prelude.multiply");
|
|
||||||
|
|
||||||
macros["/"] = variadicMacro("Prelude.divide");
|
|
||||||
|
|
||||||
macros["%"] = (wholeExp:ReaderExp, exps:Array<ReaderExp>, k) -> {
|
macros["%"] = (wholeExp:ReaderExp, exps:Array<ReaderExp>, k) -> {
|
||||||
wholeExp.checkNumArgs(2, 2, '(% [divisor] [dividend])');
|
wholeExp.checkNumArgs(2, 2, '(% [divisor] [dividend])');
|
||||||
CallExp(Symbol("Prelude.mod").withPosOf(wholeExp), [exps[1], exps[0]]).withPosOf(wholeExp);
|
CallExp(Symbol("Prelude.mod").withPosOf(wholeExp), [exps[1], exps[0]]).withPosOf(wholeExp);
|
||||||
@@ -38,6 +30,14 @@ class Macros {
|
|||||||
CallExp(Symbol("Prelude.pow").withPosOf(wholeExp), [exps[1], exps[0]]).withPosOf(wholeExp);
|
CallExp(Symbol("Prelude.pow").withPosOf(wholeExp), [exps[1], exps[0]]).withPosOf(wholeExp);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
macros["+"] = variadicMacro("Prelude.add");
|
||||||
|
|
||||||
|
macros["-"] = variadicMacro("Prelude.subtract");
|
||||||
|
|
||||||
|
macros["*"] = variadicMacro("Prelude.multiply");
|
||||||
|
|
||||||
|
macros["/"] = variadicMacro("Prelude.divide");
|
||||||
|
|
||||||
macros["min"] = variadicMacro("Prelude.min");
|
macros["min"] = variadicMacro("Prelude.min");
|
||||||
macros["max"] = variadicMacro("Prelude.max");
|
macros["max"] = variadicMacro("Prelude.max");
|
||||||
|
|
||||||
@@ -48,6 +48,46 @@ class Macros {
|
|||||||
|
|
||||||
macros["="] = variadicMacro("Prelude.areEqual");
|
macros["="] = variadicMacro("Prelude.areEqual");
|
||||||
|
|
||||||
|
// the (apply [func] [args]) macro keeps its own list of aliases for the math operators
|
||||||
|
// that can't just be function aliases because they emulate &rest behavior
|
||||||
|
var opAliases = [
|
||||||
|
"+" => "Prelude.add",
|
||||||
|
"-" => "Prelude.subtract",
|
||||||
|
"*" => "Prelude.multiply",
|
||||||
|
"/" => "Prelude.divide",
|
||||||
|
">" => "Prelude.greaterThan",
|
||||||
|
">=" => "Prelude.greaterEqual",
|
||||||
|
"<" => "Prelude.lessThan",
|
||||||
|
"<=" => "Prelude.lesserEqual",
|
||||||
|
"=" => "Prelude.areEqual"
|
||||||
|
];
|
||||||
|
|
||||||
|
macros["apply"] = (wholeExp:ReaderExp, exps:Array<ReaderExp>, k) -> {
|
||||||
|
wholeExp.checkNumArgs(2, 2, '(apply [func] [argList])');
|
||||||
|
|
||||||
|
var callOn = switch (exps[0].def) {
|
||||||
|
case FieldExp(field, exp):
|
||||||
|
exp;
|
||||||
|
default:
|
||||||
|
Symbol("null").withPosOf(wholeExp);
|
||||||
|
};
|
||||||
|
var func = switch (exps[0].def) {
|
||||||
|
case Symbol(sym) if (opAliases.exists(sym)):
|
||||||
|
Symbol(opAliases[sym]).withPosOf(wholeExp);
|
||||||
|
default:
|
||||||
|
exps[0];
|
||||||
|
};
|
||||||
|
var args = switch (exps[0].def) {
|
||||||
|
case Symbol(sym) if (opAliases.exists(sym)):
|
||||||
|
ListExp([
|
||||||
|
CallExp(FieldExp("map", exps[1]).withPosOf(wholeExp), [Symbol("kiss.Operand.fromDynamic").withPosOf(wholeExp)]).withPosOf(wholeExp)
|
||||||
|
]).withPosOf(wholeExp);
|
||||||
|
default:
|
||||||
|
exps[1];
|
||||||
|
};
|
||||||
|
CallExp(Symbol("Reflect.callMethod").withPosOf(wholeExp), [callOn, func, args]).withPosOf(wholeExp);
|
||||||
|
};
|
||||||
|
|
||||||
function bodyIf(formName:String, negated:Bool, wholeExp:ReaderExp, args:Array<ReaderExp>, k) {
|
function bodyIf(formName:String, negated:Bool, wholeExp:ReaderExp, args:Array<ReaderExp>, k) {
|
||||||
wholeExp.checkNumArgs(2, null, '($formName [condition] [body...])');
|
wholeExp.checkNumArgs(2, null, '($formName [condition] [body...])');
|
||||||
var condition = if (negated) {
|
var condition = if (negated) {
|
||||||
|
|||||||
@@ -221,4 +221,8 @@ class BasicTestCase extends Test {
|
|||||||
function testAssert() {
|
function testAssert() {
|
||||||
_testAssert();
|
_testAssert();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function testApply() {
|
||||||
|
_testApply();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -299,4 +299,7 @@
|
|||||||
(Assert.equals "Assertion false failed: false should have been true" message)))
|
(Assert.equals "Assertion false failed: false should have been true" message)))
|
||||||
|
|
||||||
(assert true)
|
(assert true)
|
||||||
(assert ![]))
|
(assert ![]))
|
||||||
|
|
||||||
|
(defun _testApply []
|
||||||
|
(Assert.equals 6 (apply + [1 2 3])))
|
||||||
Reference in New Issue
Block a user