optional arguments

This commit is contained in:
2020-11-30 13:53:08 -07:00
parent 3f5e81f03e
commit 550af52a65
3 changed files with 38 additions and 20 deletions

View File

@@ -55,8 +55,34 @@ class Helpers {
} }
// TODO generic type parameter declarations // TODO generic type parameter declarations
public static function makeFunction(?name:ReaderExp, argList:ReaderExp, body:Array<ReaderExp>, k:KissState):Function { public static function makeFunction(?name:ReaderExp, argList:ReaderExp, body:Array<ReaderExp>, 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 { return {
ret: if (name != null) switch (name.def) { ret: if (name != null) switch (name.def) {
case TypedExp(type, _): Helpers.parseComplexType(type, name); case TypedExp(type, _): Helpers.parseComplexType(type, name);
@@ -64,24 +90,7 @@ class Helpers {
} else null, } else null,
args: switch (argList.def) { args: switch (argList.def) {
case ListExp(funcArgs): case ListExp(funcArgs):
[ funcArgs.map(makeFuncArg);
// 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;
}
}
];
case CallExp(_, _): case CallExp(_, _):
throw CompileError.fromExp(argList, 'expected an argument list. Change the parens () to brackets []'); throw CompileError.fromExp(argList, 'expected an argument list. Change the parens () to brackets []');
default: default:

View File

@@ -206,4 +206,8 @@ class BasicTestCase extends Test {
function testDoFor() { function testDoFor() {
_testDoFor(); _testDoFor();
} }
function testOptionalArguments() {
myOptionalFunc(5);
}
} }

View File

@@ -231,4 +231,9 @@
(doFor [a e i] smallerMetaList (doFor [a e i] smallerMetaList
(Assert.equals 1 a) (Assert.equals 1 a)
(Assert.equals 5 e) (Assert.equals 5 e)
(Assert.equals 10 i))) (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