Refactor to prepare for DRY typeCase
This commit is contained in:
@@ -642,7 +642,13 @@ class Helpers {
|
||||
function let(bindings:Array<ReaderExp>, body:Array<ReaderExp>) {
|
||||
return callSymbol("let", [list(bindings)].concat(body));
|
||||
}
|
||||
|
||||
function throwAssertOrNeverError(messageExp:ReaderExp) {
|
||||
var failureError = KissError.fromExp(posRef, "").toString(AssertionFail);
|
||||
var colonsInPrefix = if (Sys.systemName() == "Windows") 5 else 4;
|
||||
return callSymbol("throw", [
|
||||
callSymbol("kiss.Prelude.runtimeInsertAssertionMessage", [messageExp, str(failureError), int(colonsInPrefix)])
|
||||
]);
|
||||
}
|
||||
return {
|
||||
call: call,
|
||||
callSymbol: callSymbol,
|
||||
@@ -666,22 +672,30 @@ class Helpers {
|
||||
objectWith: objectWith,
|
||||
// Only use within assertion macros
|
||||
throwAssertionError: () -> {
|
||||
var failureError = KissError.fromExp(posRef, "").toString(AssertionFail);
|
||||
var colonsInPrefix = if (Sys.systemName() == "Windows") 5 else 4;
|
||||
var usage = "throwAssertionError can only be used in a builder of an assertion macro";
|
||||
var exps = switch (posRef.def) {
|
||||
case CallExp(_, exps):
|
||||
exps;
|
||||
default:
|
||||
throw KissError.fromExp(_symbol("throwAssertionError"), "throwAssertionError can only be used in a builder of an assertion macro");
|
||||
throw KissError.fromExp(_symbol("throwAssertionError"), usage);
|
||||
}
|
||||
var messageExp = if (exps.length > 1) {
|
||||
exps[1];
|
||||
} else {
|
||||
str("");
|
||||
};
|
||||
callSymbol("throw", [
|
||||
callSymbol("kiss.Prelude.runtimeInsertAssertionMessage", [messageExp, str(failureError), int(colonsInPrefix)])
|
||||
]);
|
||||
throwAssertOrNeverError(messageExp);
|
||||
},
|
||||
neverCase: () -> {
|
||||
switch (posRef.def) {
|
||||
case CallExp({pos: _, def: Symbol("never")}, neverExps):
|
||||
posRef.checkNumArgs(1, 1, '(never <pattern>)');
|
||||
call(neverExps[0], [
|
||||
throwAssertOrNeverError(str('case should never match pattern ${Reader.toString(neverExps[0].def)}'))
|
||||
]);
|
||||
default:
|
||||
posRef;
|
||||
}
|
||||
},
|
||||
// Compile-time only!
|
||||
throwKissError: (reason:String) -> {
|
||||
@@ -705,6 +719,16 @@ class Helpers {
|
||||
};
|
||||
}
|
||||
|
||||
public static function checkNoEarlyOtherwise(cases:kiss.List<ReaderExp>) {
|
||||
for (i in 0...cases.length) {
|
||||
switch (cases[i].def) {
|
||||
case CallExp({pos: _, def: Symbol("otherwise")}, _) if (i != cases.length - 1):
|
||||
throw KissError.fromExp(cases[i], "(otherwise <body...>) branch must come last in a (case <...>) expression");
|
||||
default:
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static function argList(exp:ReaderExp, forThis:String, allowEmpty = true):Array<ReaderExp> {
|
||||
return switch (exp.def) {
|
||||
case ListExp([]) if (allowEmpty):
|
||||
|
@@ -333,27 +333,11 @@ class SpecialForms {
|
||||
// to cover all patterns.
|
||||
var args:kiss.List<ReaderExp> = args.copy();
|
||||
|
||||
var cases:kiss.List<ReaderExp> = args.slice(1);
|
||||
for (i in 0...cases.length) {
|
||||
switch (cases[i].def) {
|
||||
case CallExp({pos: _, def: Symbol("never")}, neverExps):
|
||||
cases[i].checkNumArgs(1, 1, '(never <pattern>)');
|
||||
var b = cases[i].expBuilder();
|
||||
var failureError = KissError.fromExp(cases[i], '').toString(AssertionFail);
|
||||
var colonsInPrefix = if (Sys.systemName() == "Windows") 5 else 4;
|
||||
cases[i] = b.call(neverExps[0], [
|
||||
b.callSymbol('throw', [
|
||||
b.callSymbol('kiss.Prelude.runtimeInsertAssertionMessage', [b.str('${Reader.toString(neverExps[0].def)} should never match pattern ${Reader.toString(neverExps[0].def)}'), b.str(failureError), b.int(colonsInPrefix)])])]);
|
||||
default:
|
||||
}
|
||||
}
|
||||
for (i in 0...cases.length) {
|
||||
switch (cases[i].def) {
|
||||
case CallExp({pos: _, def: Symbol("otherwise")}, _) if (i != cases.length - 1):
|
||||
throw KissError.fromExp(cases[i], "(otherwise <body...>) branch must come last in a (case <...>) expression");
|
||||
default:
|
||||
}
|
||||
}
|
||||
var cases:kiss.List<ReaderExp> = [for (c in args.slice(1)) {
|
||||
c.expBuilder().neverCase();
|
||||
}];
|
||||
|
||||
Helpers.checkNoEarlyOtherwise(cases);
|
||||
|
||||
var isTupleCase = switch (args[0].def) {
|
||||
case ListExp(_):
|
||||
|
Reference in New Issue
Block a user