Nested (or) in (case) patterns
This commit is contained in:
@@ -164,9 +164,6 @@ class Helpers {
|
|||||||
throw CompileError.fromExp(caseExp, "case expression can only have one `when` guard");
|
throw CompileError.fromExp(caseExp, "case expression can only have one `when` guard");
|
||||||
guard = macro Prelude.truthy(${k.convert(whenExps[0])});
|
guard = macro Prelude.truthy(${k.convert(whenExps[0])});
|
||||||
makeSwitchPattern(whenExps[1]);
|
makeSwitchPattern(whenExps[1]);
|
||||||
case CallExp({pos: _, def: Symbol("or")}, orExps):
|
|
||||||
patternExp.checkNumArgs(2, null, "(or [pattern1] [pattern2] [patterns...])");
|
|
||||||
orExps.map(k.forCaseParsing().convert);
|
|
||||||
default:
|
default:
|
||||||
[k.forCaseParsing().convert(patternExp)];
|
[k.forCaseParsing().convert(patternExp)];
|
||||||
}
|
}
|
||||||
|
@@ -220,6 +220,8 @@ class Kiss {
|
|||||||
public static function forCaseParsing(k:KissState):KissState {
|
public static function forCaseParsing(k:KissState):KissState {
|
||||||
var copy = Reflect.copy(k);
|
var copy = Reflect.copy(k);
|
||||||
copy.wrapListExps = false;
|
copy.wrapListExps = false;
|
||||||
|
k.macros.remove("or");
|
||||||
|
k.specialForms["or"] = SpecialForms.caseOr;
|
||||||
return copy;
|
return copy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -335,4 +335,13 @@ class SpecialForms {
|
|||||||
|
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function caseOr(wholeExp:ReaderExp, args:Array<ReaderExp>, k:KissState):Expr {
|
||||||
|
wholeExp.checkNumArgs(2, null, "(or [v1] [v2] [values...])");
|
||||||
|
return if (args.length == 2) {
|
||||||
|
macro ${k.convert(args[0])} | ${k.convert(args[1])};
|
||||||
|
} else {
|
||||||
|
macro ${k.convert(args[0])} | ${caseOr(wholeExp, args.slice(1), k)};
|
||||||
|
};
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
@@ -341,16 +341,17 @@
|
|||||||
(case 5
|
(case 5
|
||||||
((when false (or 5 6)) (Assert.fail))
|
((when false (or 5 6)) (Assert.fail))
|
||||||
(otherwise (Assert.pass)))
|
(otherwise (Assert.pass)))
|
||||||
// TODO in Haxe,
|
// In Haxe,
|
||||||
// `switch (Some(true)) { case Some(true | false): "a"; default: "b"; }`
|
// `switch (Some(true)) { case Some(true | false): "a"; default: "b"; }`
|
||||||
// returns "a", so this should also be valid:
|
// returns "a", so nested use of `or` in case patterns should also be valid:
|
||||||
/*(case (Some true)
|
(case (Some true)
|
||||||
((Some (or true false))
|
((Some (or true false))
|
||||||
(Assert.pass))
|
(Assert.pass))
|
||||||
(otherwise (Assert.fail)))*/
|
(otherwise (Assert.fail)))
|
||||||
// ^ Implement by overriding the `or` macro with an `or` special form to return variadically nested OpOr binop exps
|
(case (Some 5)
|
||||||
// in KissState.forCaseParsing() instead of handling CallExp(Symbol(or)) specially
|
((Some (or 6 5 4))
|
||||||
)
|
(Assert.pass))
|
||||||
|
(otherwise (Assert.fail))))
|
||||||
|
|
||||||
(defun _testMaps []
|
(defun _testMaps []
|
||||||
(deflocal :Map<String,String> myMap [=>"hey" "you"
|
(deflocal :Map<String,String> myMap [=>"hey" "you"
|
||||||
|
Reference in New Issue
Block a user