diff --git a/kiss/src/kiss/Macros.hx b/kiss/src/kiss/Macros.hx index 7465cee9..f5f1bf66 100644 --- a/kiss/src/kiss/Macros.hx +++ b/kiss/src/kiss/Macros.hx @@ -689,22 +689,25 @@ class Macros { b.symbol("null"); }; - return b.callSymbol("case", [ - firstValue, - b.call( - firstPattern, [ - if (bindingList.length == 0) { - thenExp; - } else { - ifLet(assertLet, wholeExp, [ - b.list(bindingList) - ].concat(exps.slice(1)), k); - } - ]), - b.callSymbol("otherwise", [ + var gensym = b.symbol(); + return b.let( + [gensym, firstValue], + [b.callSymbol("case", [ + gensym, + b.call( + b.callSymbol("when", [gensym, firstPattern]), [ + if (bindingList.length == 0) { + thenExp; + } else { + ifLet(assertLet, wholeExp, [ + b.list(bindingList) + ].concat(exps.slice(1)), k); + } + ]), + b.callSymbol("otherwise", [ elseExp - ]) - ]); + ]) + ])]); } macros["ifLet"] = ifLet.bind(false); @@ -1177,10 +1180,8 @@ class Macros { b.callField(funcName, exps.shift(), exps), b.callSymbol("-1", [b.symbol("haxe.ds.Option.None")]), b.callSymbol("other", [b.callSymbol("haxe.ds.Option.Some", [b.symbol("other")])]), + b.callSymbol("null", [b.callSymbol("throw", [b.str("Haxe indexOf is broken")])]) ]; - if (!(Context.defined('cs') || Context.defined('cpp'))) { - cases.push(b.callSymbol("null", [b.callSymbol("throw", [b.str("Haxe indexOf is broken")])])); - } return b.callSymbol("case", cases); } macros["indexOf"] = indexOfMacro.bind(false); diff --git a/kiss/src/kiss/Prelude.hx b/kiss/src/kiss/Prelude.hx index 85e0acb6..8ab47407 100644 --- a/kiss/src/kiss/Prelude.hx +++ b/kiss/src/kiss/Prelude.hx @@ -349,6 +349,13 @@ class Prelude { public static var joinPath:Function = Reflect.makeVarArgs(_joinPath); + public static function isNull(v:Any) { + return switch (Type.typeof(v)) { + case TNull: true; + default: false; + } + } + public static dynamic function truthy(v:T) { return switch (Type.typeof(v)) { case TNull: false; diff --git a/kiss/src/kiss/SpecialForms.hx b/kiss/src/kiss/SpecialForms.hx index de85f203..e2783c84 100644 --- a/kiss/src/kiss/SpecialForms.hx +++ b/kiss/src/kiss/SpecialForms.hx @@ -338,22 +338,7 @@ class SpecialForms { var exp = k.withoutListWrapping().convert(args[0]); - // On C#, C++, and HashLink, value types (specifically Float and Int) cannot be null, so they cannot be compared with null. - // Therefore a null case doesn't need to be added--and will cause a compile failure if it is. - var canCompareNull = !isTupleCase && - if (Context.defined('cs') || Context.defined('cpp') || Context.defined('hl')) { - var type = exp.typeof(k.typeHints); - switch (type) { - case null: - false; - case Success(TAbstract(ref, [])) if (["Int", "Float", "Bool"].indexOf(ref.get().name) != -1): - false; - case Failure(_): - KissError.warnFromExp(args[0], "Can't detect whether expression can be null-checked"); - false; - default: true; - } - } else true; + var canCompareNull = !isTupleCase; var cases = args.slice(1); // case also override's haxe's switch() behavior by refusing to match null values against patterns. @@ -375,8 +360,11 @@ class SpecialForms { throw KissError.fromExp(wholeExp, "Unmatched pattern: null"); } - var nullCase = b.callSymbol("null", [b.raw(nullExpr.toString())]); - + var nullCase = if (k.hscript) { + b.callSymbol("null", [b.raw(nullExpr.toString())]); + } else { + b.call(b.callSymbol("when", [b.callSymbol("Prelude.isNull", [b.symbol("v")]), b.symbol("v")]), [b.raw(nullExpr.toString())]); + }; cases.insert(0, nullCase); }