From 550af52a65ec0760127ab7381d3bd9011600ad4f Mon Sep 17 00:00:00 2001 From: Nat Quayle Nelson Date: Mon, 30 Nov 2020 13:53:08 -0700 Subject: [PATCH] optional arguments --- src/kiss/Helpers.hx | 47 ++++++++++++++++++------------- src/test/cases/BasicTestCase.hx | 4 +++ src/test/cases/BasicTestCase.kiss | 7 ++++- 3 files changed, 38 insertions(+), 20 deletions(-) diff --git a/src/kiss/Helpers.hx b/src/kiss/Helpers.hx index 5a44234a..d767479e 100644 --- a/src/kiss/Helpers.hx +++ b/src/kiss/Helpers.hx @@ -55,8 +55,34 @@ class Helpers { } // TODO generic type parameter declarations - public static function makeFunction(?name:ReaderExp, argList:ReaderExp, body:Array, k:KissState):Function { + // Once the &opt meta appears, all following arguments are optional until &rest + var opt = false; + // TODO rest arguments + // ^ rest arguments will have to define a macro with the function's name that wraps the rest args in a list when calling it from Kiss + function makeFuncArg(funcArg:ReaderExp):FunctionArg { + return switch (funcArg.def) { + case MetaExp("opt", innerFuncArg): + opt = true; + makeFuncArg(innerFuncArg); + default: + { + name: switch (funcArg.def) { + case Symbol(name) | TypedExp(_, {pos: _, def: Symbol(name)}): + name; + default: + throw CompileError.fromExp(funcArg, 'function argument should be a symbol or typed symbol'); + }, + type: switch (funcArg.def) { + case TypedExp(type, _): + Helpers.parseComplexType(type, funcArg); + default: null; + }, + opt: opt + }; + }; + } + return { ret: if (name != null) switch (name.def) { case TypedExp(type, _): Helpers.parseComplexType(type, name); @@ -64,24 +90,7 @@ class Helpers { } else null, args: switch (argList.def) { case ListExp(funcArgs): - [ - // TODO optional arguments, rest arguments - // ^ rest arguments will have to define a macro with the function's name that wraps the rest args in a list when calling it from Kiss - for (funcArg in funcArgs) - { - name: switch (funcArg.def) { - case Symbol(name) | TypedExp(_, {pos: _, def: Symbol(name)}): - name; - default: - throw CompileError.fromExp(funcArg, 'function argument should be a symbol or typed symbol'); - }, - type: switch (funcArg.def) { - case TypedExp(type, _): - Helpers.parseComplexType(type, funcArg); - default: null; - } - } - ]; + funcArgs.map(makeFuncArg); case CallExp(_, _): throw CompileError.fromExp(argList, 'expected an argument list. Change the parens () to brackets []'); default: diff --git a/src/test/cases/BasicTestCase.hx b/src/test/cases/BasicTestCase.hx index 0129f916..59b69420 100644 --- a/src/test/cases/BasicTestCase.hx +++ b/src/test/cases/BasicTestCase.hx @@ -206,4 +206,8 @@ class BasicTestCase extends Test { function testDoFor() { _testDoFor(); } + + function testOptionalArguments() { + myOptionalFunc(5); + } } diff --git a/src/test/cases/BasicTestCase.kiss b/src/test/cases/BasicTestCase.kiss index eb0f8d08..93be921e 100644 --- a/src/test/cases/BasicTestCase.kiss +++ b/src/test/cases/BasicTestCase.kiss @@ -231,4 +231,9 @@ (doFor [a e i] smallerMetaList (Assert.equals 1 a) (Assert.equals 5 e) - (Assert.equals 10 i))) \ No newline at end of file + (Assert.equals 10 i))) + + (defun myOptionalFunc [a &opt b c] + (Assert.equals 5 a) + (Assert.equals null b) + (Assert.equals 6 (or c 6))) // (or [optionalVar] [defaultValue]) is the convention for default values \ No newline at end of file