optional arguments
This commit is contained in:
@@ -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:
|
||||||
|
@@ -206,4 +206,8 @@ class BasicTestCase extends Test {
|
|||||||
function testDoFor() {
|
function testDoFor() {
|
||||||
_testDoFor();
|
_testDoFor();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function testOptionalArguments() {
|
||||||
|
myOptionalFunc(5);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -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
|
Reference in New Issue
Block a user