@@ -159,6 +159,10 @@ bool Skrypt::Add(std::string_view line) {
159159 return Add (v);
160160}
161161
162+ bool Skrypt::Add (const ::omnn::math::Variable& var, ::omnn::math::Valuable&& val) {
163+ return base::Add (var, std::move (val));
164+ }
165+
162166namespace {
163167 std::string Questionless (std::string s) {
164168 s.erase (std::remove (s.begin (), s.end (), ' ?' ), s.end ());
@@ -170,6 +174,132 @@ namespace {
170174 auto FindBracePos (std::string_view line) {
171175 return line.find_first_of (" {}[]" sv);
172176 }
177+
178+ bool IsFunctionDefinition (std::string_view line) {
179+ auto openParenPos = line.find (' (' );
180+ if (openParenPos == std::string_view::npos) return false ;
181+
182+ auto closeParenPos = line.find (' )' , openParenPos);
183+ if (closeParenPos == std::string_view::npos) return false ;
184+
185+ auto equalPos = line.find (' =' , closeParenPos);
186+ if (equalPos == std::string_view::npos) return false ;
187+
188+ if (openParenPos == 0 ) return false ;
189+
190+ return true ;
191+ }
192+
193+ bool IsFunctionApplication (std::string_view line) {
194+ auto equalPos = line.find (' =' );
195+ auto openParenPos = line.find (' (' );
196+
197+ if (openParenPos == std::string_view::npos) return false ;
198+
199+ if (equalPos != std::string_view::npos && openParenPos < equalPos) return false ;
200+
201+ auto closeParenPos = line.find (' )' , openParenPos);
202+ if (closeParenPos == std::string_view::npos) return false ;
203+
204+ if (openParenPos == 0 ) return false ;
205+
206+ return true ;
207+ }
208+
209+ std::vector<std::string> ParseFunctionArgs (std::string_view argsStr) {
210+ std::vector<std::string> args;
211+ std::string currentArg;
212+
213+ for (size_t i = 0 ; i < argsStr.size (); ++i) {
214+ char c = argsStr[i];
215+ if (c == ' ,' ) {
216+ boost::algorithm::trim (currentArg);
217+ if (!currentArg.empty ()) {
218+ args.push_back (currentArg);
219+ currentArg.clear ();
220+ }
221+ } else {
222+ currentArg += c;
223+ }
224+ }
225+
226+ boost::algorithm::trim (currentArg);
227+ if (!currentArg.empty ()) {
228+ args.push_back (currentArg);
229+ }
230+
231+ return args;
232+ }
233+ }
234+
235+ bool Skrypt::ProcessFunctionDefinition (std::string_view& line)
236+ {
237+ if (!IsFunctionDefinition (line)) {
238+ return false ;
239+ }
240+
241+ auto openParenPos = line.find (' (' );
242+ auto closeParenPos = line.find (' )' , openParenPos);
243+ auto equalPos = line.find (' =' , closeParenPos);
244+
245+ std::string_view funcName = line.substr (0 , openParenPos);
246+ boost::algorithm::trim (funcName);
247+
248+ std::string_view argsStr = line.substr (openParenPos + 1 , closeParenPos - openParenPos - 1 );
249+ auto args = ParseFunctionArgs (argsStr);
250+
251+ std::string_view exprStr = line.substr (equalPos + 1 );
252+ boost::algorithm::trim (exprStr);
253+
254+ std::string lambdaExpr = std::string (exprStr);
255+
256+ auto & funcVar = varHost->Host (std::string (funcName));
257+
258+ std::string functionDef = " Function(" ;
259+ functionDef += std::string (funcName);
260+ functionDef += " , [" ;
261+ for (size_t i = 0 ; i < args.size (); ++i) {
262+ if (i > 0 ) functionDef += " , " ;
263+ functionDef += args[i];
264+ }
265+ functionDef += " ], " ;
266+ functionDef += std::string (exprStr);
267+ functionDef += " )" ;
268+
269+ Add (funcVar, ::omnn::math::Valuable (functionDef, varHost));
270+
271+ return true ;
272+ }
273+
274+ bool Skrypt::ProcessFunctionApplication (std::string_view& line)
275+ {
276+ if (!IsFunctionApplication (line)) {
277+ return false ;
278+ }
279+
280+ auto equalPos = line.find (' =' );
281+ std::string_view leftSide;
282+ std::string_view rightSide;
283+
284+ if (equalPos != std::string_view::npos) {
285+ leftSide = line.substr (0 , equalPos);
286+ boost::algorithm::trim (leftSide);
287+ rightSide = line.substr (equalPos + 1 );
288+ } else {
289+ rightSide = line;
290+ }
291+
292+ boost::algorithm::trim (rightSide);
293+
294+ if (equalPos != std::string_view::npos) {
295+ auto & resultVar = varHost->Host (std::string (leftSide));
296+
297+ Add (resultVar, ::omnn::math::Valuable (rightSide, varHost));
298+ } else {
299+ Add (::omnn::math::Valuable (rightSide, varHost));
300+ }
301+
302+ return true ;
173303}
174304
175305void Skrypt::ProcessQuestionLine (std::string_view& line)
@@ -332,6 +462,8 @@ bool Skrypt::ParseNextLine(std::istream& in, std::string_view& line)
332462
333463 if (boost::algorithm::contains (line, " ?" )) {
334464 ProcessQuestionLine (line);
465+ } else if (ProcessFunctionDefinition (line)) {
466+ } else if (ProcessFunctionApplication (line)) {
335467 } else {
336468 Valuable expression;
337469 try {
@@ -676,4 +808,4 @@ Skrypt::Skrypt(const skrypt::Skrypt& that)
676808 , sourceFilePath(that.sourceFilePath)
677809 , moduleFileSearchAdditionalPaths(that.moduleFileSearchAdditionalPaths)
678810{
679- }
811+ }
0 commit comments