generic function parameters

This commit is contained in:
2022-06-28 04:40:13 +00:00
parent df68450ad8
commit e8a5bafa4d
6 changed files with 46 additions and 6 deletions

View File

@@ -124,6 +124,13 @@ class FieldForms {
var returnsValue = !isVoid(args[0]); var returnsValue = !isVoid(args[0]);
var wasInStatic = k.inStaticFunction; var wasInStatic = k.inStaticFunction;
var typeParams = switch (args[1].def) {
case TypeParams(p):
args.splice(1, 1);
p;
default:
[];
}
var f:Field = { var f:Field = {
name: name, name: name,
@@ -135,7 +142,8 @@ class FieldForms {
args[1], args[1],
args.slice(2), args.slice(2),
k.forStaticFunction(inStaticFunction), k.forStaticFunction(inStaticFunction),
formName)), formName,
typeParams)),
pos: wholeExp.macroPos() pos: wholeExp.macroPos()
}; };

View File

@@ -109,14 +109,31 @@ class Helpers {
}; };
} }
// TODO generic type parameter declarations public static function makeTypeParam(param:ReaderExp, ?constraints:Array<ComplexType> = null):TypeParamDecl {
public static function makeFunction(?name:ReaderExp, returnsValue:Bool, argList:ReaderExp, body:List<ReaderExp>, k:KissState, formName:String):Function { 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) { var funcName = if (name != null) {
varName(formName, name, "function"); varName(formName, name, "function");
} else { } else {
""; "";
}; };
var params = [for (p in typeParams) makeTypeParam(p)];
var numArgs = 0; var numArgs = 0;
// Once the &opt meta appears, all following arguments are optional until &rest // Once the &opt meta appears, all following arguments are optional until &rest
var opt = false; var opt = false;
@@ -218,7 +235,8 @@ class Helpers {
return { return {
ret: if (name != null) Helpers.explicitType(name) else null, ret: if (name != null) Helpers.explicitType(name) else null,
args: args, args: args,
expr: expr expr: expr,
params: params
}; };
} }

View File

@@ -307,7 +307,8 @@ class Kiss {
b.list([]), b.list([]),
[topLevelBegin], [topLevelBegin],
k, k,
"function")), "function",
[])),
pos: topLevelBegin.macroPos() pos: topLevelBegin.macroPos()
}); });
} }

View File

@@ -39,6 +39,8 @@ class Reader {
// and also handles string interpolation cases like "${exp}moreString" // and also handles string interpolation cases like "${exp}moreString"
readTable["{"] = (stream:Stream, k) -> CallExp(Symbol("begin").withPos(stream.position()), readExpArray(stream, "}", k)); 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['"'] = readString.bind(_, _, false);
readTable["#"] = readRawString; readTable["#"] = readRawString;
@@ -506,6 +508,16 @@ class Reader {
].join(" "); ].join(" ");
str += ']'; str += ']';
str; str;
case TypeParams(exps):
// <>[T1 T2 T3]
var str = '<>[';
str += [
for (exp in exps) {
exp.def.toString();
}
].join(" ");
str += ']';
str;
case StrExp(s): case StrExp(s):
// "literal" // "literal"
'"$s"'; '"$s"';

View File

@@ -23,5 +23,6 @@ enum ReaderExpDef {
UnquoteList(exp:ReaderExp); // ,@[exp] UnquoteList(exp:ReaderExp); // ,@[exp]
ListEatingExp(exps:Array<ReaderExp>); // [::exp exp ...exps exp] ListEatingExp(exps:Array<ReaderExp>); // [::exp exp ...exps exp]
ListRestExp(name:String); // ...exps or ... ListRestExp(name:String); // ...exps or ...
TypeParams(types:Array<ReaderExp>); // <>[T :Constraint U :Constraint1 :Constraint2 V]
None; // not an expression, i.e. (#unless falseCondition exp) None; // not an expression, i.e. (#unless falseCondition exp)
} }

View File

@@ -230,7 +230,7 @@ class SpecialForms {
default: default:
true; 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) { function forExpr(formName:String, wholeExp:ReaderExp, args:Array<ReaderExp>, k:KissState) {