Permalink
Cannot retrieve contributors at this time
Name already in use
A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
xll/test/lambda.cpp
Go to fileThis commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
87 lines (78 sloc)
1.94 KB
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "../xll/xll.h" | |
using namespace xll; | |
struct lambda { | |
OPER body; | |
lambda(const OPER& body) | |
: body(body) | |
{ } | |
OPER evaluate(LPXLOPERX* ppa) | |
{ | |
int n = SetNames(ppa); | |
OPER result = Excel(xlfEvaluate, body); | |
UnsetNames(n); | |
return result; | |
} | |
private: | |
static OPER arg(int i) | |
{ | |
return Excel(xlfConcatenate, OPER("_"), OPER(i)); | |
} | |
int SetNames(LPXLOPERX* ppa) | |
{ | |
int i = 0; | |
while((*ppa)->xltype != xltypeMissing) { | |
Excel(xlfSetName, arg(i), **ppa); | |
++ppa; | |
++i; | |
} | |
return i; | |
} | |
void UnsetNames(int n) | |
{ | |
for (int i = 0; i < n; ++i) { | |
Excel(xlfSetName, arg(i)); | |
} | |
} | |
}; | |
AddIn xai_lambda( | |
Function(XLL_LPOPER, "xll_lambda", "\\") | |
.Arguments({ | |
Arg(XLL_LPOPER, "body", "is a handle or a string expression using arguments _0, _1, ..."), | |
Arg(XLL_LPOPER, "_arg0", "is the optional first argument"), | |
Arg(XLL_LPOPER, "_arg1", "is the optional second argument"), | |
Arg(XLL_LPOPER, "_arg2", "is the optional third argument"), | |
Arg(XLL_LPOPER, "_arg3", "is the optional fourth argument"), | |
}) | |
.Uncalced() | |
.FunctionHelp("Return handle to a lambda or evaluate when supplied with arguments.") | |
.Category("XLL") | |
.Documentation(R"xyzyx( | |
Call <code>\(body)<code> where <code>body</code> is a string expression with arguments | |
<code>_0</code>, <code>_1</code>, ... | |
Call <code>\(lambda, args, ...)</code> to evaluate. | |
)xyzyx") | |
); | |
LPXLOPERX WINAPI xll_lambda(LPXLOPERX body, LPXLOPERX pa0, LPXLOPERX, LPXLOPERX, LPXLOPERX) | |
{ | |
#pragma XLLEXPORT | |
static OPER result; | |
try { | |
if (body->xltype == xltypeStr) { | |
ensure(pa0->xltype == xltypeMissing); | |
handle<lambda> h_(new lambda(*body)); | |
result = h_.get(); | |
} | |
else if (body->xltype == xltypeNum) { | |
handle<lambda> h_(body->val.num); | |
ensure(h_); | |
result = h_->evaluate(&pa0); | |
} | |
else { | |
result = ErrNA; | |
} | |
} | |
catch (const std::exception& ex) { | |
XLL_ERROR(ex.what()); | |
} | |
return &result; | |
} | |