-
Notifications
You must be signed in to change notification settings - Fork 1
/
lambda.t
50 lines (44 loc) · 1.71 KB
/
lambda.t
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
-- SPDX-FileCopyrightText: 2024 René Hiemstra <[email protected]>
-- SPDX-FileCopyrightText: 2024 Torsten Keßler <[email protected]>
--
-- SPDX-License-Identifier: MIT
--lua function that generates a terra type that are function objects. these wrap
--a function in the 'apply' metamethod and store any captured variables in the struct
--as entries
local ckecklambdaexpr = function(expr)
if not (expr.tree and expr.tree.type and expr.tree.type:isstruct()) then
error("Not a valid capture. " ..
"The capture syntax uses named arguments as follows: " ..
"{x = xvalue, ...}.", 2)
end
end
local makelambda = function(fun, lambdaobj)
--check capture object
ckecklambdaexpr(lambdaobj)
local lambdatype = lambdaobj:gettype()
--overloading the call operator - making 'lambdaobj' a function object
lambdatype.metamethods.__apply = macro(terralib.memoize(function(self, ...)
local args = terralib.newlist{...}
return `fun([args], unpackstruct(self))
end))
--add returntype and parameter info if available
local funtype = fun:gettype()
if funtype:ispointertofunction() then
lambdatype.returntype = funtype.type.returntype
local nargs = #funtype.type.parameters - #lambdatype.entries
lambdatype.parameters = funtype.type.parameters:filteri(function(i,v) return i <= nargs end)
end
return lambdaobj
end
local function genempty()
return terralib.types.newstruct()
end
--return a function object with captured variables in ...
local new = macro(function(fun, capture)
local lambda = makelambda(fun, capture or quote var c: genempty() in c end)
return `lambda
end)
return {
new = new,
makelambda = makelambda
}