Make (apply...) work in interp2
Some checks failed
CI / test (push) Failing after 52s
CI / test-core (14, ubuntu-latest, 3.x, nodejs) (push) Failing after 1m37s
CI / test-core (14, ubuntu-latest, 3.x, interp) (push) Failing after 1m39s
CI / test-core (14, ubuntu-latest, 3.x, js) (push) Failing after 2m8s
CI / test-core (14, ubuntu-latest, 3.x, cpp) (push) Failing after 2m30s
CI / test-core (14, ubuntu-latest, 3.x, py) (push) Failing after 2m24s

This commit is contained in:
2025-11-14 16:45:06 -06:00
parent cb4f6b0d4a
commit f2105fbd96
3 changed files with 65 additions and 60 deletions

View File

@@ -24,6 +24,7 @@
=>"Std" Std
=>"the" ->[_ v] v
=>"Math" Math
=>"Reflect" Reflect
])
(prop &mut :kiss.List<Map<String,Dynamic>> localScopes [])

View File

@@ -81,67 +81,8 @@ class Macros {
destructiveVersion("*", "*=");
destructiveVersion("/", "/=");
var opAliases = [
// These shouldn't be ident aliases because they are common variable names
"min" => "Prelude.min",
"max" => "Prelude.max",
// These might not be common, but playing it safe:
"iHalf" => "Prelude.iHalf",
"iThird" => "Prelude.iThird",
"iFourth" => "Prelude.iFourth",
"iFifth" => "Prelude.iFifth",
"iSixth" => "Prelude.iSixth",
"iSeventh" => "Prelude.iSeventh",
"iEighth" => "Prelude.iEighth",
"iNinth" => "Prelude.iNinth",
"iTenth" => "Prelude.iTenth",
"fHalf" => "Prelude.fHalf",
"fThird" => "Prelude.fThird",
"fFourth" => "Prelude.fFourth",
"fFifth" => "Prelude.fFifth",
"fSixth" => "Prelude.fSixth",
"fSeventh" => "Prelude.fSeventh",
"fEighth" => "Prelude.fEighth",
"fNinth" => "Prelude.fNinth",
"fTenth" => "Prelude.fTenth",
// These can't be ident aliases because they would supercede the typed call macros that wrap them:
"zip" => "Prelude.zipThrow",
"zipThrow" => "Prelude.zipThrow",
"zipKeep" => "Prelude.zipKeep",
"zipDrop" => "Prelude.zipDrop",
"concat" => "Prelude.concat",
"intersect" => "Prelude.intersect",
"and" => "Prelude.and",
"or" => "Prelude.or"
];
k.doc("apply", 2, 2, '(apply <func> <argList>)' );
macros["apply"] = (wholeExp:ReaderExp, exps:Array<ReaderExp>, k) -> {
var b = wholeExp.expBuilder();
var isSafe = false;
var callOn = switch (exps[0].def) {
case FieldExp(field, exp, safe):
isSafe = safe;
exp;
default:
b.symbol("null");
};
var func = switch (exps[0].def) {
case Symbol(func) if (opAliases.exists(func)):
b.symbol(opAliases[func]);
default:
exps[0];
};
var args = exps[1];
var exp = b.call(
b.symbol("Reflect.callMethod"), [
callOn, func, args
]);
if (isSafe)
exp = b.callSymbol("when", [callOn, exp]);
exp;
};
macros["apply"] = wrapPortable(PortableMacros.apply);
function prepareForConditional(i:KissInterp, k:KissState) {
i.variables.set("kissFile", k.file);

View File

@@ -15,9 +15,72 @@ class PortableMacros {
m["/="] = destructiveVersion("/");
m["when"] = bodyIf("if", false);
m["unless"] = bodyIf("if", true);
m["apply"] = apply;
return m;
}
static var opAliases = [
// These shouldn't be ident aliases because they are common variable names
"min" => "Prelude.min",
"max" => "Prelude.max",
// These might not be common, but playing it safe:
"iHalf" => "Prelude.iHalf",
"iThird" => "Prelude.iThird",
"iFourth" => "Prelude.iFourth",
"iFifth" => "Prelude.iFifth",
"iSixth" => "Prelude.iSixth",
"iSeventh" => "Prelude.iSeventh",
"iEighth" => "Prelude.iEighth",
"iNinth" => "Prelude.iNinth",
"iTenth" => "Prelude.iTenth",
"fHalf" => "Prelude.fHalf",
"fThird" => "Prelude.fThird",
"fFourth" => "Prelude.fFourth",
"fFifth" => "Prelude.fFifth",
"fSixth" => "Prelude.fSixth",
"fSeventh" => "Prelude.fSeventh",
"fEighth" => "Prelude.fEighth",
"fNinth" => "Prelude.fNinth",
"fTenth" => "Prelude.fTenth",
// These can't be ident aliases because they would supercede the typed call macros that wrap them:
"zip" => "Prelude.zipThrow",
"zipThrow" => "Prelude.zipThrow",
"zipKeep" => "Prelude.zipKeep",
"zipDrop" => "Prelude.zipDrop",
"concat" => "Prelude.concat",
"intersect" => "Prelude.intersect",
"and" => "Prelude.and",
"or" => "Prelude.or"
];
public static function apply(wholeExp:ReaderExp, exps:Array<ReaderExp>) {
var b = wholeExp.expBuilder();
var isSafe = false;
var callOn = switch (exps[0].def) {
case FieldExp(field, exp, safe):
isSafe = safe;
exp;
default:
b.symbol("null");
};
var func = switch (exps[0].def) {
case Symbol(func) if (opAliases.exists(func)):
b.symbol(opAliases[func]);
default:
exps[0];
};
var args = exps[1];
var exp = b.call(
b.symbol("Reflect.callMethod"), [
callOn, func, args
]);
if (isSafe)
exp = b.callSymbol("when", [callOn, exp]);
return exp;
}
public static function destructiveVersion(op:String) {
return (wholeExp:ReaderExp, exps:Array<ReaderExp>) -> {
var b = wholeExp.expBuilder();