From fea27985135cd9e994e2ffa4c066d58a24602069 Mon Sep 17 00:00:00 2001 From: Nat Quayle Nelson Date: Wed, 18 Nov 2020 16:11:58 -0700 Subject: [PATCH] try/catch --- src/kiss/SpecialForms.hx | 38 +++++++++++++++++++++++++++++-- src/test/cases/BasicTestCase.hx | 6 +++++ src/test/cases/BasicTestCase.kiss | 9 +++++++- 3 files changed, 50 insertions(+), 3 deletions(-) diff --git a/src/kiss/SpecialForms.hx b/src/kiss/SpecialForms.hx index 85ba7672..5190ba56 100644 --- a/src/kiss/SpecialForms.hx +++ b/src/kiss/SpecialForms.hx @@ -50,7 +50,41 @@ class SpecialForms { // TODO special form for try - // TODO special form for throw + map["try"] = (args:Array, convert:ExprConversion) -> { + if (args.length == 0) { + throw '(try...) expression has nothing to try'; + } + var tryKissExp = args[0]; + var catchKissExps = args.slice(1); + ETry(convert(tryKissExp), [ + for (catchKissExp in catchKissExps) { + switch (catchKissExp) { + case CallExp(Symbol("catch"), catchArgs): + { + name: switch (catchArgs[0]) { + case ListExp([Symbol(name) | TypedExp(_, Symbol(name))]): name; + default: throw 'first argument to (catch... ) should be a one-element argument list, not ${catchArgs[0]}'; + }, + type: switch (catchArgs[0]) { + case ListExp([TypedExp(type, _)]): + Helpers.parseTypePath(type); + default: null; + }, + expr: convert(CallExp(Symbol("begin"), catchArgs.slice(1))) + }; + default: + throw 'expressions following the first expression in a (try... ) should all be (catch... ) expressions, but you used $catchKissExp'; + } + } + ]).withPos(); + }; + + map["throw"] = (args:Array, convert:ExprConversion) -> { + if (args.length != 1) { + throw 'throw expression should only throw one value, not: $args'; + } + EThrow(convert(args[0])).withPos(); + }; map["<"] = foldComparison("_min"); map["<="] = foldComparison("min"); @@ -60,7 +94,7 @@ class SpecialForms { map["if"] = (args:Array, convert:ExprConversion) -> { if (args.length < 2 || args.length > 3) { - throw 'if statement has wrong number of arguments: ${args.length}'; + throw '(if...) expression has wrong number of arguments: ${args.length}'; } var condition = macro Prelude.truthy(${convert(args[0])}); diff --git a/src/test/cases/BasicTestCase.hx b/src/test/cases/BasicTestCase.hx index 0fc5004c..8bdc5798 100644 --- a/src/test/cases/BasicTestCase.hx +++ b/src/test/cases/BasicTestCase.hx @@ -131,4 +131,10 @@ class BasicTestCase extends Test { function testTypedDefvar() { Assert.equals(8, BasicTestCase.myInt); } + + function testTryCatch() { + Assert.equals(5, BasicTestCase.myTryCatch("string error")); + Assert.equals(6, BasicTestCase.myTryCatch(404)); + Assert.equals(7, BasicTestCase.myTryCatch(["list error"])); + } } diff --git a/src/test/cases/BasicTestCase.kiss b/src/test/cases/BasicTestCase.kiss index 4f7a894d..cca625af 100644 --- a/src/test/cases/BasicTestCase.kiss +++ b/src/test/cases/BasicTestCase.kiss @@ -75,4 +75,11 @@ (defmacrofun doTwiceString [stringOp] ,stringOp - ,stringOp) \ No newline at end of file + ,stringOp) + +(defun myTryCatch [:Any e] + (try + (throw e) + (catch [:String error] 5) + (catch [:Int error] 6) + (catch [error] 7))) \ No newline at end of file