generic function parameters
This commit is contained in:
@@ -124,6 +124,13 @@ class FieldForms {
|
||||
var returnsValue = !isVoid(args[0]);
|
||||
|
||||
var wasInStatic = k.inStaticFunction;
|
||||
var typeParams = switch (args[1].def) {
|
||||
case TypeParams(p):
|
||||
args.splice(1, 1);
|
||||
p;
|
||||
default:
|
||||
[];
|
||||
}
|
||||
|
||||
var f:Field = {
|
||||
name: name,
|
||||
@@ -135,7 +142,8 @@ class FieldForms {
|
||||
args[1],
|
||||
args.slice(2),
|
||||
k.forStaticFunction(inStaticFunction),
|
||||
formName)),
|
||||
formName,
|
||||
typeParams)),
|
||||
pos: wholeExp.macroPos()
|
||||
};
|
||||
|
||||
|
@@ -109,14 +109,31 @@ class Helpers {
|
||||
};
|
||||
}
|
||||
|
||||
// TODO generic type parameter declarations
|
||||
public static function makeFunction(?name:ReaderExp, returnsValue:Bool, argList:ReaderExp, body:List<ReaderExp>, k:KissState, formName:String):Function {
|
||||
public static function makeTypeParam(param:ReaderExp, ?constraints:Array<ComplexType> = null):TypeParamDecl {
|
||||
if (constraints == null) constraints = [];
|
||||
switch (param.def) {
|
||||
case Symbol(name):
|
||||
return {
|
||||
name: name,
|
||||
constraints: constraints
|
||||
};
|
||||
case TypedExp(type, param):
|
||||
constraints.push(parseComplexType(type));
|
||||
return makeTypeParam(param, constraints);
|
||||
default:
|
||||
throw KissError.fromExp(param, "expected <GenericTypeName> or :<Constraint> <GenericTypeName>");
|
||||
}
|
||||
}
|
||||
|
||||
public static function makeFunction(?name:ReaderExp, returnsValue:Bool, argList:ReaderExp, body:List<ReaderExp>, k:KissState, formName:String, typeParams:Array<ReaderExp>):Function {
|
||||
var funcName = if (name != null) {
|
||||
varName(formName, name, "function");
|
||||
} else {
|
||||
"";
|
||||
};
|
||||
|
||||
var params = [for (p in typeParams) makeTypeParam(p)];
|
||||
|
||||
var numArgs = 0;
|
||||
// Once the &opt meta appears, all following arguments are optional until &rest
|
||||
var opt = false;
|
||||
@@ -218,7 +235,8 @@ class Helpers {
|
||||
return {
|
||||
ret: if (name != null) Helpers.explicitType(name) else null,
|
||||
args: args,
|
||||
expr: expr
|
||||
expr: expr,
|
||||
params: params
|
||||
};
|
||||
}
|
||||
|
||||
|
@@ -307,7 +307,8 @@ class Kiss {
|
||||
b.list([]),
|
||||
[topLevelBegin],
|
||||
k,
|
||||
"function")),
|
||||
"function",
|
||||
[])),
|
||||
pos: topLevelBegin.macroPos()
|
||||
});
|
||||
}
|
||||
|
@@ -39,6 +39,8 @@ class Reader {
|
||||
// and also handles string interpolation cases like "${exp}moreString"
|
||||
readTable["{"] = (stream:Stream, k) -> CallExp(Symbol("begin").withPos(stream.position()), readExpArray(stream, "}", k));
|
||||
|
||||
readTable["<>["] = (stream, k) -> TypeParams(readExpArray(stream, "]", k));
|
||||
|
||||
readTable['"'] = readString.bind(_, _, false);
|
||||
readTable["#"] = readRawString;
|
||||
|
||||
@@ -506,6 +508,16 @@ class Reader {
|
||||
].join(" ");
|
||||
str += ']';
|
||||
str;
|
||||
case TypeParams(exps):
|
||||
// <>[T1 T2 T3]
|
||||
var str = '<>[';
|
||||
str += [
|
||||
for (exp in exps) {
|
||||
exp.def.toString();
|
||||
}
|
||||
].join(" ");
|
||||
str += ']';
|
||||
str;
|
||||
case StrExp(s):
|
||||
// "literal"
|
||||
'"$s"';
|
||||
|
@@ -23,5 +23,6 @@ enum ReaderExpDef {
|
||||
UnquoteList(exp:ReaderExp); // ,@[exp]
|
||||
ListEatingExp(exps:Array<ReaderExp>); // [::exp exp ...exps exp]
|
||||
ListRestExp(name:String); // ...exps or ...
|
||||
TypeParams(types:Array<ReaderExp>); // <>[T :Constraint U :Constraint1 :Constraint2 V]
|
||||
None; // not an expression, i.e. (#unless falseCondition exp)
|
||||
}
|
||||
|
@@ -230,7 +230,7 @@ class SpecialForms {
|
||||
default:
|
||||
true;
|
||||
}
|
||||
EFunction(FAnonymous, Helpers.makeFunction(null, returnsValue, args[0], args.slice(1), k, "lambda")).withMacroPosOf(wholeExp);
|
||||
EFunction(FAnonymous, Helpers.makeFunction(null, returnsValue, args[0], args.slice(1), k, "lambda", [])).withMacroPosOf(wholeExp);
|
||||
};
|
||||
|
||||
function forExpr(formName:String, wholeExp:ReaderExp, args:Array<ReaderExp>, k:KissState) {
|
||||
|
Reference in New Issue
Block a user