KSeExpr 6.0.0.0
ExprFunc.cpp
Go to the documentation of this file.
1// SPDX-FileCopyrightText: 2011-2019 Disney Enterprises, Inc.
2// SPDX-License-Identifier: LicenseRef-Apache-2.0
3// SPDX-FileCopyrightText: 2020 L. E. Segovia <amy@amyspark.me>
4// SPDX-License-Identifier: GPL-3.0-or-later
5
6#include <cstdlib>
7#include <iostream>
8#include <map>
9#include <mutex>
10#include <string>
11
12#include "ExprBuiltins.h"
13#include "ExprFunc.h"
14#include "ExprNode.h"
15#include "Expression.h"
16
17namespace
18{
19// FuncTable - table of pre-defined functions
20class FuncTable
21{
22public:
23 void define(const char *name, const KSeExpr::ExprFunc &f, const char *docString = nullptr)
24 {
25 if (docString)
26 funcmap[name] = FuncMapItem(std::string(docString), f);
27 else
28 funcmap[name] = FuncMapItem(name, f);
29 }
30
31 const KSeExpr::ExprFunc *lookup(const std::string &name)
32 {
33 const auto &i = funcmap.find(name);
34 if (i == funcmap.end())
35 return nullptr;
36 else
37 return &i->second.second;
38 }
39
40 void getFunctionNames(std::vector<std::string> &names)
41 {
42 for (const auto &i : funcmap)
43 names.push_back(i.first);
44 }
45
46 std::string getDocString(const char *functionName)
47 {
48 const auto &i = funcmap.find(functionName);
49 if (i == funcmap.end())
50 return "";
51 else
52 return i->second.first;
53 }
54
55 size_t sizeInBytes() const
56 {
57 size_t totalSize = 0;
58 for (const auto &it : funcmap) {
59 totalSize += it.first.size() + sizeof(FuncMapItem);
60 const KSeExpr::ExprFunc &function = it.second.second;
61 if (const KSeExpr::ExprFuncX *funcx = function.funcx()) {
62 totalSize += funcx->sizeInBytes();
63 }
64 }
65 return totalSize;
66 }
67
68 KSeExpr::Statistics statistics() const
69 {
70 KSeExpr::Statistics statisticsDump;
71 size_t totalSize = 0;
72 for (const auto &it : funcmap) {
73 totalSize += it.first.size() + sizeof(FuncMapItem);
74 const KSeExpr::ExprFunc &function = it.second.second;
75 if (const KSeExpr::ExprFuncX *funcx = function.funcx()) {
76 funcx->statistics(statisticsDump);
77 }
78 }
79 return statisticsDump;
80 }
81
82private:
83 using FuncMapItem = std::pair<std::string, KSeExpr::ExprFunc>;
84 using FuncMap = std::map<std::string, FuncMapItem>;
85 FuncMap funcmap;
86};
87
88std::unique_ptr<FuncTable> Functions;
89} // namespace
90
91// ExprType ExprFuncX::prep(ExprFuncNode* node, bool scalarWanted, ExprVarEnv & env) const
92//{
93// /* call base node prep by default:
94// this passes wantVec to all the children and sets isVec true if any
95// child is a vec */
96// /* TODO: check that this is correct behavior */
97// return node->ExprNode::prep(scalarWanted, env);
98//}
99
100namespace KSeExpr
101{
102static std::mutex mutex;
103
105{
106 std::lock_guard<std::mutex> locker(mutex);
107 initInternal();
108}
109
111{
112 std::lock_guard<std::mutex> locker(mutex);
113 Functions = nullptr;
114}
115
116const ExprFunc *ExprFunc::lookup(const std::string &name)
117{
118 std::lock_guard<std::mutex> locker(mutex);
119 if (!Functions)
120 initInternal();
121 const ExprFunc *ret = Functions->lookup(name);
122 return ret;
123}
124
125inline static void defineInternal(const char *name, const ExprFunc &f)
126{
127 // THIS FUNCTION IS NOT THREAD SAFE, it assumes you have a mutex from callee
128 // ALSO YOU MUST BE VERY CAREFUL NOT TO CALL ANYTHING THAT TRIES TO REACQUIRE MUTEX!
129 Functions->define(name, f);
130}
131
132inline static void defineInternal3(const char *name, const ExprFunc &f, const char *docString)
133{
134 // THIS FUNCTION IS NOT THREAD SAFE, it assumes you have a mutex from callee
135 // ALSO YOU MUST BE VERY CAREFUL NOT TO CALL ANYTHING THAT TRIES TO REACQUIRE MUTEX!
136 Functions->define(name, f, docString);
137}
138
140{
141 // THIS FUNCTION IS NOT THREAD SAFE, it assumes you have a mutex from callee
142 // ALSO YOU MUST BE VERY CAREFUL NOT TO CALL ANYTHING THAT TRIES TO REACQUIRE MUTEX!
143
144 if (Functions)
145 return;
146 Functions = std::make_unique<FuncTable>();
148}
149
150void ExprFunc::define(const char *name, const ExprFunc &f)
151{
152 std::lock_guard<std::mutex> locker(mutex);
153 if (!Functions)
154 initInternal();
155 defineInternal(name, f);
156}
157
158void ExprFunc::define(const char *name, const ExprFunc &f, const char *docString)
159{
160 std::lock_guard<std::mutex> locker(mutex);
161 if (!Functions)
162 initInternal();
163 defineInternal3(name, f, docString);
164}
165
166void ExprFunc::getFunctionNames(std::vector<std::string> &names)
167{
168 std::lock_guard<std::mutex> locker(mutex);
169 if (!Functions)
170 initInternal();
171 Functions->getFunctionNames(names);
172}
173
174std::string ExprFunc::getDocString(const char *functionName)
175{
176 std::lock_guard<std::mutex> locker(mutex);
177 if (!Functions)
178 initInternal();
179 std::string ret = Functions->getDocString(functionName);
180 return ret;
181}
182
184{
185 std::lock_guard<std::mutex> locker(mutex);
186 if (!Functions)
187 initInternal();
188 return Functions->sizeInBytes();
189}
190
192{
193 std::lock_guard<std::mutex> locker(mutex);
194 if (!Functions)
195 initInternal();
196 return Functions->statistics();
197}
198} // namespace KSeExpr
Extension function spec, used for complicated argument custom functions.
Definition ExprFuncX.h:23
Function Definition, used in parse tree and func table.
Definition ExprFunc.h:35
static void getFunctionNames(std::vector< std::string > &names)
Get a list of registered builtin and DSO generated functions.
Definition ExprFunc.cpp:166
const ExprFuncX * funcx() const
return pointer to the funcx
Definition ExprFunc.h:177
static void define(const char *name, const ExprFunc &f, const char *docString)
Definition ExprFunc.cpp:158
static size_t sizeInBytes()
Get the total size estimate of all plugins.
Definition ExprFunc.cpp:183
static void init()
call to define built-in funcs
Definition ExprFunc.cpp:104
static const ExprFunc * lookup(const std::string &name)
Lookup a builtin function by name.
Definition ExprFunc.cpp:116
static void initInternal()
Definition ExprFunc.cpp:139
static void cleanup()
cleanup all functions
Definition ExprFunc.cpp:110
static std::string getDocString(const char *functionName)
Get doc string for a specific function.
Definition ExprFunc.cpp:174
static Statistics statistics()
Dump statistics.
Definition ExprFunc.cpp:191
static std::mutex mutex
Definition ExprFunc.cpp:102
static void defineInternal(const char *name, const ExprFunc &f)
Definition ExprFunc.cpp:125
std::map< std::string, double > Statistics
Definition ExprFuncX.h:16
void defineBuiltins(ExprFunc::Define, ExprFunc::Define3 define3)
static void defineInternal3(const char *name, const ExprFunc &f, const char *docString)
Definition ExprFunc.cpp:132