4 Commits

Author SHA1 Message Date
f2105fbd96 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
2025-11-14 16:45:32 -06:00
cb4f6b0d4a tail-recursive interpreteded for loop 2025-11-14 16:45:31 -06:00
3c9600dd5f some aliases are needed in KissInterp2 2025-11-14 16:45:31 -06:00
21299abf80 add Math to KissInterp2 2025-11-14 16:03:55 -06:00
4 changed files with 82 additions and 70 deletions

View File

@@ -38,6 +38,12 @@ class KissInterp2 {
specialForms = _specialForms();
identAliases = kiss.Kiss.defaultIdentAliases;
callAliases = kiss.Kiss.defaultCallAliases;
callAliases["zip"] = kiss.ReaderExp.ReaderExpDef.Symbol("Prelude.zipThrow");
callAliases["zipKeep"] = kiss.ReaderExp.ReaderExpDef.Symbol("Prelude.zipKeep");
callAliases["zipDrop"] = kiss.ReaderExp.ReaderExpDef.Symbol("Prelude.zipDrop");
callAliases["zipThrow"] = kiss.ReaderExp.ReaderExpDef.Symbol("Prelude.zipThrow");
globals["Prelude"] = kiss.Prelude;
$preexistingNewBody;
}

View File

@@ -8,6 +8,7 @@
(import kiss.ReaderExp.ReaderExpDef.FieldExp)
(import kiss.Stream)
// TODO don't add to these directly here! The constructor does it
(prop &mut :ReadTable readTable (Reader.builtins))
(prop &mut :ReadTable startOfLineReadTable (new Map))
(prop &mut :ReadTable startOfFileReadTable (new Map))
@@ -22,6 +23,8 @@
=>"null" null
=>"Std" Std
=>"the" ->[_ v] v
=>"Math" Math
=>"Reflect" Reflect
])
(prop &mut :kiss.List<Map<String,Dynamic>> localScopes [])
@@ -52,16 +55,15 @@
iter (collection.iterator)]
(dictSet (last localScopes) "__iter__" iter)
(localFunction run []
(if (iter.hasNext)
(evalCC (callSymbol "let" (.concat [(listExp [varName (callSymbol "__iter__.next" [])])] body))
->v {(when collect
(results.push v))
(run)
})
{
(localScopes.pop)
(cc results)
}))
// Oof -- everything needs to be synchronous
(unless (iter.hasNext)
(localScopes.pop)
(cc results)
(return))
(evalCC (callSymbol "let" (.concat [(listExp [varName (callSymbol "__iter__.next" [])])] body))
->v (when collect
(results.push v)))
(run))
(run)))))
(method makeFunction [:Array<ReaderExp> argExps :Array<ReaderExp> bodyExps]

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();