(apply [func] [args]) with math op support

This commit is contained in:
2020-12-04 11:21:21 -07:00
parent 1b07c2ddf9
commit 8329c867a5
4 changed files with 57 additions and 15 deletions

View File

@@ -41,12 +41,7 @@
(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 (= 5522401584 (let [hillTile (Util.readLines "src/year2020/inputs/day3-1.txt")]
(*
(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))))))
(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)))))))
(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

View File

@@ -20,14 +20,6 @@ class Macros {
public static function builtins() {
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) -> {
wholeExp.checkNumArgs(2, 2, '(% [divisor] [dividend])');
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);
};
macros["+"] = variadicMacro("Prelude.add");
macros["-"] = variadicMacro("Prelude.subtract");
macros["*"] = variadicMacro("Prelude.multiply");
macros["/"] = variadicMacro("Prelude.divide");
macros["min"] = variadicMacro("Prelude.min");
macros["max"] = variadicMacro("Prelude.max");
@@ -48,6 +48,46 @@ class Macros {
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) {
wholeExp.checkNumArgs(2, null, '($formName [condition] [body...])');
var condition = if (negated) {

View File

@@ -221,4 +221,8 @@ class BasicTestCase extends Test {
function testAssert() {
_testAssert();
}
function testApply() {
_testApply();
}
}

View File

@@ -300,3 +300,6 @@
(assert true)
(assert ![]))
(defun _testApply []
(Assert.equals 6 (apply + [1 2 3])))