NewLang Project
Yet another programm language
Loading...
Searching...
No Matches
context.cpp
Go to the documentation of this file.
1//#include "pch.h"
2
3#include <filesystem>
4#include <stdbool.h>
5
6#include "warning_push.h"
7#include <torch/torch.h>
8#include <ATen/ATen.h>
9#include "warning_pop.h"
10
11
12#include "context.h"
13#include "term.h"
14#include "macro.h"
15#include "runtime.h"
16#include "module.h"
17#include "types.h"
18#include "analysis.h"
19
20using namespace newlang;
21
22ObjType getSummaryTensorType(Obj *obj, ObjType start = ObjType::None);
23
24Context::Context(RunTime *rt) : m_runtime(rt), m_latter(nullptr) { //, m_static(module) { //ScopeStack(module),
25 push_back({});
26}
27
28std::string Context::Dump(size_t num) {
29 std::string result;
30 if (!num) {
31 // result = "Static: ";
32 // if (m_module) {
33 // result += m_static.Dump();
34 // }
35 }
36
37 size_t count = 0;
38 auto iter = rbegin();
39 while (iter != rend()) {
40 result += "Stack ";
41 result += std::to_string(std::distance(iter, rend()));
42 result += " [";
43 result += iter->ns;
44 result += "]: ";
45
46 std::string list;
47 auto iter_list = iter->vars.begin();
48 while (iter_list != iter->vars.end()) {
49
50 if (!list.empty()) {
51
52 list += ", ";
53 }
54
55 list += iter_list->first;
56 list += "=(";
57 // if (iter_list->second.obj) {
58 // list += iter_list->second.obj->toString();
59 // } else {
60 // list += "nullptr";
61 // }
62 list += ")";
63 iter_list++;
64 }
65
66 // result += "(";
67 result += list;
68 result += "\n";
69 iter++;
70
71 count++;
72 if (num && count >= num) {
73 break;
74 }
75 }
76 return result;
77}
78
79//std::multimap<std::string, DocPtr> Docs::m_docs;
80//bool Context::MatchCompare(Obj &match, ObjPtr &value, MatchMode mode, Context *ctx) {
81// switch (mode) {
82// case MatchMode::MatchEqual:
83// return match.op_equal(value);
84// case MatchMode::MatchStrict:
85// return match.op_accurate(value);
86// case MatchMode::TYPE_NAME:
87// return match.op_class_test(value, ctx);
88// case MatchMode::TYPE_EQUAL:
89// return match.op_duck_test(value, false);
90//
91// case MatchMode::TYPE_STRICT:
92// return match.op_duck_test(value, true);
93// }
94// LOG_RUNTIME("Unknown pattern matching type %d!", static_cast<int> (mode));
95//}
96//
97//bool Context::MatchEstimate(Obj &match, const TermPtr &match_item, MatchMode mode, Context *ctx, Obj * args) {
98//
99// ObjPtr cond = CreateRVal(ctx, match_item, args);
100//
101// if (cond->is_none_type() || MatchCompare(match, cond, mode, ctx)) {
102// return true;
103// } else {
104// for (int i = 0; i < match_item->m_block.size(); i++) {
105//
106// ASSERT(match_item->m_block[i]);
107// cond = CreateRVal(ctx, match_item->m_block[i], args);
108//
109// if (cond->is_none_type() || MatchCompare(match, cond, mode, ctx)) {
110//
111// return true;
112// }
113// }
114// }
115// return false;
116//}
117//
118//ObjPtr Context::eval_MATCHING(Context *ctx, const TermPtr &term, Obj * args, bool eval_block) {
119// /*
120// * [match] ==> { # ~> ~~> ~~~> ===>
121// * [cond1] --> {expr};
122// * [cond2, cond3] --> {expr};
123// * [...] --> {expr};
124// * };
125// */
126//
127// ASSERT(term->m_left);
128// ASSERT(term->m_right);
129//
130// MatchMode mode;
131// if (term->m_text.compare("==>") == 0) {
132// mode = MatchMode::MatchEqual;
133// } else if (term->m_text.compare("===>") == 0) {
134// mode = MatchMode::MatchStrict;
135// } else if (term->m_text.compare("~>") == 0) {
136// mode = MatchMode::TYPE_NAME;
137// } else if (term->m_text.compare("~~>") == 0) {
138// mode = MatchMode::TYPE_EQUAL;
139// } else if (term->m_text.compare("~~~>") == 0) {
140// mode = MatchMode::TYPE_STRICT;
141// } else {
142// NL_PARSER(term, "Unknown pattern matching type!");
143// }
144//
145// ObjPtr value = CreateRVal(ctx, term->m_left, args);
146// TermPtr list = term->m_right;
147//
148//
149// ASSERT(list->m_left);
150// ASSERT(list->m_right);
151//
152// ObjPtr cond = CreateRVal(ctx, list->m_left, args);
153//
154// if (MatchEstimate(*cond.get(), list->m_left, mode, ctx, args)) {
155// return CreateRVal(ctx, list->m_right, args);
156// } else {
157// for (int i = 0; i < list->m_block.size(); i++) {
158//
159// ASSERT(list->m_block[i]->m_left);
160// ASSERT(list->m_block[i]->m_right);
161//
162// if (MatchEstimate(*cond.get(), list->m_block[i]->m_left, mode, ctx, args)) {
163//
164// return CreateRVal(ctx, list->m_block[i]->m_right, args);
165// }
166// }
167// }
168// return Obj::CreateNone();
169//}
170
171//void Context::ItemTensorEval_(torch::Tensor &tensor, c10::IntArrayRef shape, std::vector<Index> &ind, const int64_t pos,
172// ObjPtr &obj, ObjPtr & args) {
173// ASSERT(pos < static_cast<int64_t> (ind.size()));
174// if (pos + 1 < static_cast<int64_t> (ind.size())) {
175// for (ind[pos] = 0; ind[pos].integer() < shape[pos]; ind[pos] = ind[pos].integer() + 1) {
176// ItemTensorEval_(tensor, shape, ind, pos + 1, obj, args);
177// }
178// } else {
179//
180// at::Scalar value;
181// ObjType type = fromTorchType(tensor.scalar_type());
182//
183// for (ind[pos] = 0; ind[pos].integer() < shape[pos]; ind[pos] = ind[pos].integer() + 1) {
184//
185// switch (type) {
186// case ObjType::Int8:
187// case ObjType::Char:
188// case ObjType::Byte:
189// case ObjType::Int16:
190// case ObjType::Word:
191// case ObjType::Int32:
192// case ObjType::DWord:
193// case ObjType::Int64:
194// case ObjType::DWord64:
195// value = at::Scalar(obj->Call(this)->GetValueAsInteger()); // args
196// tensor.index_put_(ind, value);
197// break;
198// case ObjType::Float32:
199// case ObjType::Float64:
200// case ObjType::Single:
201// case ObjType::Double:
202// value = at::Scalar(obj->Call(this)->GetValueAsNumber()); // args
203// tensor.index_put_(ind, value);
204//
205// break;
206// default:
207// ASSERT(!"Not implemented!");
208// }
209// }
210// }
211//}
212//
213//void Context::ItemTensorEval(torch::Tensor &self, ObjPtr obj, ObjPtr args) {
214// if (self.dim() == 0) {
215//
216// signed char *ptr_char = nullptr;
217// int16_t *ptr_short = nullptr;
218// int32_t *ptr_int = nullptr;
219// int64_t *ptr_long = nullptr;
220// float *ptr_float = nullptr;
221// double *ptr_double = nullptr;
222//
223// switch (fromTorchType(self.scalar_type())) {
224// case ObjType::Int8:
225// ptr_char = self.data_ptr<signed char>();
226// ASSERT(ptr_char);
227// *ptr_char = static_cast<signed char> (obj->Call(this)->GetValueAsInteger());
228// return;
229// case ObjType::Int16:
230// ptr_short = self.data_ptr<int16_t>();
231// ASSERT(ptr_short);
232// *ptr_short = static_cast<int16_t> (obj->Call(this)->GetValueAsInteger());
233// return;
234// case ObjType::Int32:
235// ptr_int = self.data_ptr<int32_t>();
236// ASSERT(ptr_int);
237// *ptr_int = static_cast<int32_t> (obj->Call(this)->GetValueAsInteger());
238// return;
239// case ObjType::Int64:
240// ptr_long = self.data_ptr<int64_t>();
241// ASSERT(ptr_long);
242// *ptr_long = static_cast<int64_t> (obj->Call(this)->GetValueAsInteger());
243// return;
244// case ObjType::Float32:
245// ptr_float = self.data_ptr<float>();
246// ASSERT(ptr_float);
247// *ptr_float = static_cast<float> (obj->Call(this)->GetValueAsNumber());
248// return;
249// case ObjType::Float64:
250// ptr_double = self.data_ptr<double>();
251// ASSERT(ptr_double);
252// *ptr_double = static_cast<double> (obj->Call(this)->GetValueAsNumber());
253// return;
254// }
255//
256// ASSERT(!"Not implemented!");
257// } else {
258//
259// c10::IntArrayRef shape = self.sizes(); // Кол-во эментов в каждом измерении
260// std::vector<Index> ind(shape.size(),
261// 0); // Счетчик обхода всех эелемнтов тензора
262// ItemTensorEval_(self, shape, ind, 0, obj, args);
263// }
264//}
265//
266//std::vector<int64_t> GetTensorShape(Context *ctx, TermPtr type, Obj * local_vars, bool eval_block) {
267// std::vector<int64_t> result(type->size());
268// for (int i = 0; i < type->size(); i++) {
269// ObjPtr temp = ctx->CreateRVal(ctx, type->at(i).second, local_vars);
270// if (temp->is_integer() || temp->is_bool_type()) {
271// result[i] = temp->GetValueAsInteger();
272// } else {
273// NL_PARSER(type->at(i).second, "Measurement dimension can be an integer only!");
274// }
275// if (result[i] <= 0) {
276//
277// NL_PARSER(type->at(i).second, "Dimension size can be greater than zero!");
278// }
279// }
280// return result;
281//}
282//
283//std::vector<Index> Context::MakeIndex(Context *ctx, TermPtr term, Obj * local_vars) {
284//
285// // `at::indexing::TensorIndex` is used for converting C++ tensor indices such
286// // as
287// // `{None, "...", Ellipsis, 0, true, Slice(1, None, 2), torch::tensor({1,
288// // 2})}` into its equivalent `std::vector<TensorIndex>`, so that further
289// // tensor indexing operations can be performed using the supplied indices.
290// //
291// // There is one-to-one correspondence between Python and C++ tensor index
292// // types: Python | C++
293// // -----------------------------------------------------
294// // `None` | `at::indexing::None`
295// // `Ellipsis` | `at::indexing::Ellipsis`
296// // `...` | `"..."`
297// // `123` | `123`
298// // `True` / `False` | `true` / `false`
299// // `:` | `Slice()` / `Slice(None, None)`
300// // `::` | `Slice()` / `Slice(None, None, None)`
301// // `1:` | `Slice(1, None)`
302// // `1::` | `Slice(1, None, None)`
303// // `:3` | `Slice(None, 3)`
304// // `:3:` | `Slice(None, 3, None)`
305// // `::2` | `Slice(None, None, 2)`
306// // `1:3` | `Slice(1, 3)`
307// // `1::2` | `Slice(1, None, 2)`
308// // `:3:2` | `Slice(None, 3, 2)`
309// // `1:3:2` | `Slice(1, 3, 2)`
310// // `torch.tensor([1, 2])`) | `torch::tensor({1, 2})`
311//
312// std::vector<Index> result;
313//
314// if (!term->size()) {
315// NL_PARSER(term, "Index not found!");
316// }
317// for (int i = 0; i < term->size(); i++) {
318// if (!term->name(i).empty() || (term->at(i).second && term->at(i).second->isString())) {
319// NL_PARSER(term, "Named index not support '%d'!", i);
320// }
321// if (!term->at(i).second) {
322// NL_PARSER(term, "Empty index '%d'!", i);
323// }
324//
325// if (term->at(i).second->getTermID() == TermID::ELLIPSIS) {
326// result.push_back(Index("..."));
327// } else {
328//
329// ObjPtr temp = ctx->CreateRVal(ctx, term->at(i).second, local_vars);
330//
331// if (temp->is_none_type()) {
332//
333// result.push_back(Index(at::indexing::None));
334// } else if (temp->is_integer() || temp->is_bool_type()) {
335//
336// if (temp->is_scalar()) {
337// result.push_back(Index(temp->GetValueAsInteger()));
338// } else if (temp->m_tensor->dim() == 1) {
339// result.push_back(Index(temp->m_tensor));
340// } else {
341// NL_PARSER(term->at(i).second, "Extra dimensions index not support '%d'!", i);
342// }
343// } else if (temp->is_range()) {
344//
345// int64_t start = temp->at("start").second->GetValueAsInteger();
346// int64_t stop = temp->at("stop").second->GetValueAsInteger();
347// int64_t step = temp->at("step").second->GetValueAsInteger();
348//
349// result.push_back(Index(at::indexing::Slice(start, stop, step)));
350// } else {
351//
352// NL_PARSER(term->at(i).second, "Fail tensor index '%d'!", i);
353// }
354// }
355// }
356// return result;
357//}
358//
359//ObjPtr Context::CreateRVal(Context *ctx, TermPtr term, Obj * local_vars, bool eval_block, CatchType int_catch) {
360//
361// if (!term) {
362// ASSERT(term);
363// }
364// ASSERT(local_vars);
365//
366// ObjPtr result = nullptr;
367// ObjPtr temp = nullptr;
368// ObjPtr args = nullptr;
369// ObjPtr value = nullptr;
370// TermPtr field = nullptr;
371// std::string full_name;
372//
373// result = Obj::CreateNone();
374// result->m_is_reference = !!term->m_ref;
375//
376// int64_t val_int;
377// double val_dbl;
378// ObjType type;
379// bool has_error;
380// std::vector<int64_t> sizes;
381// at::Scalar torch_scalar;
382// switch (term->getTermID()) {
383//
384// /* case TermID::FIELD:
385// if(module && module->HasFunc(term->GetFullName().c_str())) {
386// // Если поле является функцией и она загружена
387// result = Obj::CreateType(Obj::Type::FUNCTION,
388// term->GetFullName().c_str()); result->m_module = module;
389// result->m_is_const = term->m_is_const;
390// result->m_is_ref = term->m_is_ref;
391// return result;
392// }
393// if(!result) {
394// LOG_RUNTIME("Term '%s' not found!",
395// term->toString().c_str());
396// }
397// return result;
398// */
399//
400// case TermID::TYPE:
401//
402// result = ctx->GetTerm(term->GetFullName().c_str(), term->isRef());
403//
404//
405// has_error = false;
406// type = typeFromString(term->GetFullName(), ctx ? ctx->m_runtime.get() : nullptr, &has_error);
407// if (has_error) {
408// LOG_RUNTIME("Type name '%s' undefined!", term->GetFullName().c_str());
409// }
410// ASSERT(result);
411// ASSERT(result->m_var_type_fixed == type);
412//
413// if (result->m_var_type_fixed == ObjType::Class) {
414// //@todo Virtual
415//
416// }
417//
418// // Размерность, если указана
419// result->m_dimensions = Obj::CreateType(ObjType::Dictionary, ObjType::Dictionary, true);
420// for (size_t i = 0; i < term->m_dims.size(); i++) {
421// result->m_dimensions->push_back(CreateRVal(ctx, term->m_dims[i], local_vars, eval_block, int_catch));
422// }
423//
424// args = Obj::CreateDict();
425// for (int64_t i = 0; i < static_cast<int64_t> (term->size()); i++) {
426//
427//
428// if ((*term)[i].second->getTermID() == TermID::FILLING) {
429//
430// // Заполнение значений вызовом функции
431// // :Type(1, 2, 3, ... rand() ... );
432//
433//
434// ASSERT(!(*term)[i].second->m_left);
435// ASSERT((*term)[i].second->m_right);
436//
437//
438// ObjPtr expr = ctx->FindTerm((*term)[i].second->m_right->GetFullName());
439// ASSERT(expr);
440//
441// if (!(*term)[i].second->m_right->isCall()) {
442// LOG_RUNTIME("Operator filling supported function call only!");
443// }
444//
445// if (i + 1 != term->size()) {
446// LOG_RUNTIME("Function filling is supported for the last argument only!");
447// }
448//
449// if (!result->m_dimensions || !result->m_dimensions->size()) {
450// LOG_RUNTIME("Object has no dimensions!");
451// }
452//
453// int64_t full_size = 1;
454// for (int dim_index = 0; dim_index < result->m_dimensions->size(); dim_index++) {
455//
456// if (!(*result->m_dimensions)[dim_index].second->is_integer()) {
457// LOG_RUNTIME("Dimension index for function filling support integer value only!");
458// }
459//
460// full_size *= (*result->m_dimensions)[dim_index].second->GetValueAsInteger();
461// }
462//
463// if (full_size <= 0) {
464// LOG_RUNTIME("Items count error for all dimensions!");
465// }
466//
467//
468// if (expr->size()) {
469// LOG_RUNTIME("Argument in function for filling not implemented!");
470// }
471//
472// for (int64_t dim_index = args->size(); dim_index < full_size; dim_index++) {
473// args->push_back(expr->Call(ctx));
474// }
475//
476// break;
477//
478// } else if ((*term)[i].second->getTermID() == TermID::ELLIPSIS) {
479//
480// if (!term->name(i).empty()) {
481// LOG_RUNTIME("Named ellipsys not implemented!");
482// }
483//
484// if ((*term)[i].second->m_right) {
485//
486// bool named = ((*term)[i].second->m_left && (*term)[i].second->m_left->getTermID() == TermID::ELLIPSIS);
487// ObjPtr exp = CreateRVal(ctx, (*term)[i].second->m_right, eval_block);
488//
489// if (!exp->is_dictionary_type()) {
490// LOG_RUNTIME("Expansion operator applies to dictionary only!");
491// }
492//
493//
494// for (int index = 0; index < exp->size(); index++) {
495// if (named) {
496// args->push_back((*exp)[index].second, exp->name(index).empty() ? "" : exp->name(index));
497// } else {
498// args->push_back((*exp)[index].second);
499// }
500// }
501//
502// continue;
503// }
504// }
505//
506// if (term->name(i).empty()) {
507// args->push_back(CreateRVal(ctx, (*term)[i].second, local_vars));
508// } else {
509// args->push_back(CreateRVal(ctx, (*term)[i].second, local_vars), term->name(i).c_str());
510// }
511//
512// }
513//
514// result = result->Call(ctx, args.get());
515// ASSERT(result);
516//
517// return result;
518//
519//
520// return nullptr;
521//}
522//
523//ObjPtr Context::CreateClass(std::string class_name, TermPtr body, Obj * local_vars) {
524//
525// ASSERT(false);
526// return nullptr;
527//
528// // ASSERT(body->getTermID() == TermID::CLASS);
529// // ASSERT(body->m_base.size());
530// //
531// // ObjPtr new_class = Obj::CreateBaseType(ObjType::Class);
532// // new_class->m_var_name = class_name;
533// // std::string constructor = MakeConstructorName(class_name);
534// //
535// // // LOG_DEBUG("\nCreate class: '%s', constructor %s", class_name.c_str(), constructor.c_str());
536// //
537// //
538// // if (class_name.find(":") == 0) {
539// // class_name.erase(0, 1);
540// // }
541// //
542// // // Пройтись по всем базовым классам
543// // for (int i = 0; i < body->m_base.size(); i++) {
544// //
545// // ObjPtr base = GetTerm(body->m_base[i]->GetFullName().c_str(), false);
546// //
547// // // LOG_DEBUG("Base %s: '%s' %d", body->m_base[i]->GetFullName().c_str(), base->toString().c_str(), (int) base->size());
548// //
549// // bool has_error = false;
550// // ObjType type = typeFromString(body->m_base[i]->GetFullName(), this, &has_error);
551// // if (has_error) {
552// // LOG_RUNTIME("Type name '%s' undefined!", body->m_base[i]->GetFullName().c_str());
553// // }
554// // ASSERT(base);
555// // ASSERT(base->m_var_type_fixed == type);
556// // ASSERT(base->m_class_name.compare(body->m_base[i]->GetFullName()) == 0);
557// // ASSERT(!base->m_dimensions);
558// //
559// // // Клонировать все методы (функции) базового класса с новыми именами
560// // std::set<std::string> methods;
561// // std::string base_constructor = MakeConstructorName(base->m_class_name);
562// // // LOG_DEBUG("base_constructor %s", base_constructor.c_str());
563// //
564// //
565// // std::string find_substr = base->m_class_name.substr(1);
566// // find_substr += "::";
567// //
568// // auto iter = m_terms->begin();
569// // while (iter != m_terms->end()) {
570// // if (iter->first.find(find_substr) == 0) {
571// // if (base_constructor.compare(iter->first) != 0) {
572// // methods.insert(iter->first);
573// // }
574// // }
575// // iter++;
576// // }
577// //
578// //
579// // std::string replace(base->m_class_name.substr(1));
580// // replace += "::";
581// //
582// // std::set<Dict<Obj>::PairType *> rollback;
583// //
584// //
585// // try {
586// //
587// // ObjPtr obj;
588// //
589// // if (i == 0) {
590// // // Только один конструктор у класса
591// // obj = Obj::CreateFunc(constructor, &Obj::ConstructorStub_, ObjType::PureFunc);
592// // push_back(obj, constructor); // weak_ptr
593// // rollback.insert(&m_terms->push_back(obj, constructor));
594// // }
595// //
596// // for (auto &elem : methods) {
597// //
598// // // LOG_DEBUG("Func: %s Replace: %s", elem.c_str(), replace.c_str());
599// //
600// // auto iter = m_terms->find(elem);
601// // ASSERT(iter != m_terms->end());
602// //
603// // obj = iter->second; //.lock();
604// // ASSERT(obj);
605// //
606// // std::string name(elem);
607// // size_t pos = name.find(replace);
608// //
609// // ASSERT(pos != name.npos);
610// // ASSERT(pos == 0 || name[pos - 1] == ':');
611// //
612// // name.erase(pos, replace.size() - 2);
613// // name.insert(pos, class_name);
614// //
615// // if (m_terms->find(name) == m_terms->end()) {
616// // // LOG_DEBUG("new name %s", name.c_str());
617// // push_back(obj, name); // weak_ptr
618// // rollback.insert(&m_terms->push_back(obj, name));
619// // }
620// // }
621// //
622// // base->ClonePropTo(*new_class);
623// //
624// //
625// // // Выполнить тело конструктора типа для создания новых полей и методов у создаваемого типа класса
626// // bool is_pop_ns = m_runtime->m_macro->NamespacePush(class_name);
627// // try {
628// // for (int i = 0; i < body->m_block.size(); i++) {
629// // if (body->m_block[i]->IsCreate()) {
630// // ASSERT(body->m_block[i]->m_left);
631// // if (body->m_block[i]->m_left->IsFunction() || body->m_block[i]->m_left->isCall()) {
632// // ObjPtr func = Eval(this, body->m_block[i], local_vars, true);
633// //
634// // if (body->m_block[i]->m_right->getTermID() == TermID::NONE) {
635// // func->m_var_type_current = ObjType::Virtual;
636// // }
637// //
638// // } else {
639// //
640// // std::string name = body->m_block[i]->m_left->getText();
641// // bool is_exists = (new_class->find(name) != new_class->end());
642// //
643// // if (body->m_block[i]->getText().compare("::=") == 0) {
644// // if (is_exists) {
645// // LOG_RUNTIME("Dublicate property name '%s' in class '%s'!", name.c_str(), class_name.c_str());
646// // }
647// // new_class->push_back(nullptr, name);
648// // } else if (body->m_block[i]->getText().compare("=") == 0) {
649// // if (!is_exists) {
650// // LOG_RUNTIME("Property name '%s' not found on base classes '%s'!", name.c_str(), class_name.c_str());
651// // }
652// // } else if (!is_exists) {
653// // new_class->push_back(nullptr, name);
654// // }
655// //
656// // new_class->at(name).second = CreateRVal(this, body->m_block[i]->m_right, local_vars, true);
657// // }
658// // } else {
659// // LOG_RUNTIME("Only create or assignment operators allowed! %s", body->m_block[i]->toString().c_str());
660// // }
661// // }
662// //
663// // if (is_pop_ns) {
664// // m_runtime->m_macro->NamespacePop();
665// // }
666// // } catch (...) {
667// // if (is_pop_ns) {
668// // m_runtime->m_macro->NamespacePop();
669// // }
670// // throw;
671// // }
672// //
673// //
674// // } catch (...) {
675// //
676// //
677// // for (auto &elem : rollback) {
678// // // LOG_DEBUG("Rollback: '%s'", elem->first.c_str());
679// // // remove(find(elem.first)); // weak_ptr
680// // m_terms->remove(*elem);
681// // }
682// //
683// // throw;
684// // }
685// //
686// // }
687// // new_class->m_var_is_init = true;
688// //
689// // return new_class;
690//}
691//
692
693/*
694 *
695 *
696 */
698// Module::RegisterStaticObject(module, term, ctx);
699 return Eval(term, ctx);
700}
701
703
704 LOG_TEST("run: %s", RunTime::Escape(term->toString()).c_str());
705
707 if ((term->m_id == TermID::SEQUENCE || term->m_id == TermID::BLOCK) && !ctx) {
708 for (auto &elem : term->m_block) {
709 result = Eval(elem, ctx);
710 }
711 } else if (term->isBlock()) {
712 if (!ctx) {
713 LOG_RUNTIME("Can't calculate '%s' in static mode!", term->toString().c_str());
714 }
715 result = ctx->EvalTryBlock_(term);
716 } else {
717 result = EvalTerm(term, ctx);
718 }
719
720 LOG_TEST("result: %s", result.GetVariablePair(true).var.GetValueAsObject()->toString().c_str());
721
722 if (ctx) {
723 ctx->m_latter = result;
724 } else {
725 return result;
726 }
727 return ctx->m_latter;
728}
729
730bool Context::HasReThrow(TermPtr &block, Context &stack, Obj & obj) {
731 ASSERT(isInterrupt(obj.getType()));
732 ASSERT(block->m_id == TermID::SEQUENCE || block->m_id == TermID::BLOCK || block->m_id == TermID::BLOCK_PLUS
733 || block->m_id == TermID::BLOCK_MINUS || block->m_id == TermID::BLOCK_TRY);
734
735 if (obj.m_value.empty()) {
736 // Non named interrupt
737 if (obj.getType() == ObjType::RetPlus && (block->m_id == TermID::BLOCK_PLUS || block->m_id == TermID::BLOCK_TRY)) {
738 return false;
739 } else if (obj.getType() == ObjType::RetMinus && (block->m_id == TermID::BLOCK_MINUS || block->m_id == TermID::BLOCK_TRY)) {
740 return false;
741 }
742
743 } else {
744 // Named interrupt
745
746 if (obj.m_value.compare("::") == 0) {
747 // Global scope - always rethrow
748 return true;
749 }
750 std::string ns = stack.MakeNamespace(0, true);
751 if (ns.rfind(obj.m_value) != std::string::npos) {
752 return false;
753 }
754
755 }
756 return true;
757}
758
760 ASSERT(block->isBlock());
762 CtxPush scope_block(*this, block->m_id, block->m_namespace);
763
764 // std::string str;
765 // for (auto &elem : *this) {
766 // if (!str.empty()) {
767 // str += ", ";
768 // }
769 // str += elem.first;
770 // str += "->'";
772 // str += "'";
773 // }
774
775 // LOG_TEST("Enter block: '%s' VARS: %s", block->m_namespace ? block->m_namespace->m_text.c_str() : "", str.c_str());
776
777 try {
778 size_t i = 0;
779 while (i < block->m_block.size()) {
780
781 m_latter = Eval(block->m_block[i], this);
782
783 // LOG_TEST("step: %d, value: %s", (int) i, m_latter->toString().c_str());
784
786
788
789 if (interrupt->m_value.empty()) {
790
791 // Не именованное прерывание -> выход из блока
792 break;
793
794 } else if (CheckTargetScope(interrupt->m_value)) {
795 if (interrupt->getType() == ObjType::RetPlus) {
796 m_latter = VariablePair::Create(block, interrupt->m_return_obj);
797
798 // Выход из блока
799 break;
800
801 } else if (interrupt->getType() == ObjType::RetMinus) {
802 m_latter = VariablePair::Create(block, interrupt->m_return_obj);
803
804 // На начало блока
805 i = 0;
806 continue;
807
808 } else {
809 LOG_RUNTIME("Interrupt type '%s' not implemented!", toString(interrupt->getType()));
810 }
811 } else {
812 // Именованное прерывание, но блок более низкого уровня
813 return m_latter;
814 }
815 }
816 i++;
817 }
818
819 } catch (IntPlus &plus) {
820
821 if (HasReThrow(block, *this, plus)) {
822 throw;
823 }
825
826 } catch (IntMinus &minus) {
827
828 if (HasReThrow(block, *this, minus)) {
829 throw;
830 }
832
833 } catch (...) {
834
835 throw;
836 }
837
839
840 bool return_value = false;
842
843 if (interrupt->getType() == ObjType::RetPlus && (block->m_id == TermID::BLOCK_PLUS || block->m_id == TermID::BLOCK_TRY)) {
844 return_value = true;
845 } else if (interrupt->getType() == ObjType::RetMinus && (block->m_id == TermID::BLOCK_MINUS || block->m_id == TermID::BLOCK_TRY)) {
846 return_value = true;
847 }
848
849 if (return_value && block->m_left) {
850 // ASSERT(block->m_left->m_id == TermID::WITH);
851 m_latter = VariablePair::Create(block->m_left, interrupt->m_return_obj);
852 }
853 }
854
855 return m_latter;
856}
857
858// Метод вызывается только из NewLnag кода
859
860ObjPtr Context::Call(Context *runner, Obj &obj, TermPtr & term) {
861 ObjPtr args = Obj::CreateDict();
862
863 if (!term->m_dims) {
864 obj.m_dimensions = nullptr;
865 } else {
866 // Размерность, если указана
868 for (size_t i = 0; i < term->m_dims->size(); i++) {
869 obj.m_dimensions->push_back(EvalTerm(term->m_dims->at(i).second, runner).GetVariablePair(true).var.GetValueAsObject(), term->m_dims->at(i).first);
870 }
871 }
872
873 for (int64_t i = 0; i < static_cast<int64_t> (term->size()); i++) {
874
875 if ((*term)[i].second->getTermID() == TermID::FILLING) {
876
877 // Заполнение значений вызовом функции
878 // :Type(1, 2, 3, ... rand() ... );
879
880 ASSERT(!(*term)[i].second->m_left);
881 ASSERT((*term)[i].second->m_right);
882
883 // if (!(*term)[i].second->m_right->isCall()) {
884 // LOG_RUNTIME("Operator filling supported function call only!");
885 // }
886
887 if (i + 1 != term->size()) {
888 LOG_RUNTIME("Filling is supported for the last argument only!");
889 }
890
891 if (!obj.m_dimensions || !obj.m_dimensions->size()) {
892 LOG_RUNTIME("Object has no dimensions!");
893 }
894
895 int64_t full_size = 1;
896 for (int dim_index = 0; dim_index < obj.m_dimensions->size(); dim_index++) {
897
898 if (!(*obj.m_dimensions)[dim_index].second->is_integer()) {
899 LOG_RUNTIME("Dimension index support integer value only!");
900 }
901
902 full_size *= (*obj.m_dimensions)[dim_index].second->GetValueAsInteger();
903 }
904
905 if (full_size <= 0) {
906 LOG_RUNTIME("Items count '%ld' error for all dimensions!", full_size);
907 }
908
909
910 TermPtr fill_obj = (*term)[i].second->m_right;
911 ASSERT(fill_obj);
912
913 if (fill_obj->size()) {
914 LOG_RUNTIME("Argument in function for filling not implemented!");
915 }
916
917 for (int64_t dim_index = args->size(); dim_index < full_size; dim_index++) {
918 args->push_back(EvalTerm(fill_obj, runner).GetVariablePair(true).var.GetValueAsObject());
919 }
920
921 // Filling - last operator in the args
922 break;
923
924 } else if ((*term)[i].second->getTermID() == TermID::ELLIPSIS || (*term)[i].second->isNone()) {
925
926 if (!term->name(i).empty()) {
927 LOG_RUNTIME("Named ellipsys not implemented!");
928 }
929
930 if ((*term)[i].second->m_right) {
931
932 bool named = ((*term)[i].second->m_left && (*term)[i].second->m_left->getTermID() == TermID::ELLIPSIS);
933 ObjPtr exp = EvalTerm((*term)[i].second->m_right, runner).GetVariablePair(true).var.GetValueAsObject();
934
935 // if (exp->is_funtion()) {
936 // exp = exp->Call();
937 // }
938
939 if (exp->is_dictionary_type()) {
940
941 for (int index = 0; index < exp->size(); index++) {
942 if (named) {
943 args->push_back((*exp)[index].second, exp->name(index).empty() ? "" : exp->name(index));
944 } else {
945 args->push_back((*exp)[index].second);
946 }
947 }
948
949 } else if (exp->is_range()) {
950
951 if (named) {
952 LOG_RUNTIME("Named range expansion not applicable!");
953 }
954
955 ObjType type = getSummaryTensorType(exp.get());
956
957 if (isIntegralType(type, true) || isFloatingType(type) || type == ObjType::Rational) {
958
959 ObjPtr start = exp->at("start").second->Clone();
960 ObjPtr stop = exp->at("stop").second;
961 ObjPtr step = exp->at("step").second;
962
963 if (*step > Obj::CreateValue(0)) {
964 while (*start < stop) {
965 args->push_back(start->Clone());
966 *start += step;
967 }
968 } else if (*step < Obj::CreateValue(0)) {
969 while (*start > stop) {
970 args->push_back(start->Clone());
971 *start += step;
972 }
973 } else {
974 LOG_RUNTIME("Zero step in range expansion!");
975 }
976
977 } else {
978 LOG_RUNTIME("Range extension is only supported for integer, rational, or floating point types! (%s)", toString(type));
979 }
980
981 } else {
982 LOG_RUNTIME("Expansion operator applies to dictionary or range only!");
983 }
984
985 continue;
986
987 } else {
988 // Заполнить до конца имеющимися значениями
989
990 if (!obj.m_dimensions || !obj.m_dimensions->size()) {
991 LOG_RUNTIME("Object has no dimensions!");
992 }
993
994 // if (!(*term)[i].second->m_right->isCall()) {
995 // LOG_RUNTIME("Operator filling supported function call only!");
996 // }
997
998 if (i + 1 != term->size()) {
999 LOG_RUNTIME("Filling is supported for the last argument only!");
1000 }
1001
1002 int64_t full_size = 1;
1003 for (int dim_index = 0; dim_index < obj.m_dimensions->size(); dim_index++) {
1004
1005 if (!(*obj.m_dimensions)[dim_index].second->is_integer()) {
1006 LOG_RUNTIME("Dimension index support integer value only!");
1007 }
1008
1009 full_size *= (*obj.m_dimensions)[dim_index].second->GetValueAsInteger();
1010 }
1011
1012 if (full_size <= 0) {
1013 LOG_RUNTIME("Items count '%ld' error for all dimensions!", full_size);
1014 }
1015
1016
1017 std::vector<ObjPtr> dup;
1018
1019 for (size_t c = 0; c < args->size(); c++) {
1020 dup.push_back(args->at(c).second);
1021 }
1022
1023 if (!dup.size()) {
1024 LOG_RUNTIME("Fill items not exist!");
1025 }
1026
1027
1028 if ((full_size - args->size()) % dup.size() && runner) {
1029 if (runner->m_runtime->m_diag->m_fill_remainder) {
1030 LOG_RUNTIME("The data is filled in with the remainder!");
1031 } else {
1032 LOG_WARNING("The data is filled in with the remainder!");
1033 // runner->m_runtime->m_diag->Emit(Diag::DIAG_FILL_REMAINDER);
1034 }
1035 }
1036
1037
1038 int64_t fill_index = 0;
1039 for (int64_t dim_index = args->size(); dim_index < full_size; dim_index++) {
1040 args->push_back(dup[fill_index]->Clone());
1041 fill_index++;
1042 if (fill_index >= dup.size()) {
1043 fill_index = 0;
1044 }
1045 }
1046 // Filling - last operator in the args
1047 break;
1048 }
1049 }
1050
1051 if (term->name(i).empty()) {
1052 args->push_back(EvalTerm((*term)[i].second, runner).GetVariablePair(true).var.GetValueAsObject());
1053 } else {
1054
1055 args->push_back(EvalTerm((*term)[i].second, runner).GetVariablePair(true).var.GetValueAsObject(), term->name(i).c_str());
1056 }
1057 }
1058
1059 // LOG_TEST("Call %s %s", obj.m_prototype ? obj.m_prototype->m_text.c_str() : "", args->toString().c_str());
1060 // LOG_TEST("Local vars: %s", runner->Dump(2).c_str());
1061
1062 return Call(runner, obj, *args.get());
1063}
1064
1065// Метод может быть вызван как из NewLnag кода, так и из кода на C/C++ (в реализации Obj::operator())
1066
1067ObjPtr Context::Call(Context *runner, Obj &obj, Obj & args) {
1068
1069 if (obj.is_native()) {
1070 return Context::CallNative_(runner, obj, &args);
1071 }
1072
1073 args.insert(args.begin(), std::pair<std::string, ObjPtr>("", obj.shared()));
1074 // args->push_back(Obj::CreateValue(args->size()), "$#");
1075 // args->push_back(args->Clone(), "$*");
1076
1077 if (obj.is_string_type() || obj.is_dictionary_type()) {
1078 if (obj.is_string_type()) {
1079 if (obj.getType() == ObjType::FmtChar || obj.getType() == ObjType::FmtWide) {
1080 return Obj::CreateString(StringPrintf(obj.GetValueAsString(), args));
1081 } else {
1082 return Obj::CreateString(StringFormat(obj.GetValueAsString(), args));
1083 }
1084 } else {
1085 LOG_RUNTIME("Clone dict not implemented!");
1086 }
1087 }
1088
1089 if (!runner) {
1090 LOG_RUNTIME("Call static not allowed!");
1091 }
1092
1093 if (obj.is_function_type() || obj.is_type_name()) {
1094
1095 if (obj.m_sequence) {
1096 /* Кол-во аргуметов у функции, их тип проверяются во время синтаксического анализа исходного текста.
1097 * Число позиционных агрументов должно быть не меньше, чем в прототипе функции и они идут по порядку,
1098 * а именованные (во время вызова) могу быть в перемешку и идентифицируются по имени.
1099 *
1100 * Значение по умолчанию подставляется во время анализа и вычислятся во время первого обращения?
1101 *
1102 * Цикл перебора агрументов идет по прототипу функции.
1103 * Во вермя цикла связывается внутренни имена, но новые имена создаваться не могут!!!!
1104 * К дополнительным аргументам можно обратиться по индексу в переменной $$[0] $$[2] и т.д.
1105 */
1106
1107 ASSERT(obj.m_prototype);
1108 // StorageTerm storage(obj.m_prototype->m_int_vars);
1109 //(Context &ctx, const TermID id, const std::string_view &name) : m_ctx(ctx) {
1110 CtxPush stack(*runner, obj.m_sequence->m_id, obj.m_sequence->m_namespace);
1111
1112 ObjPtr args_dict = Obj::CreateDict();
1113
1114 int ags_count = obj.m_prototype->size();
1115 bool is_ellipsis = obj.m_prototype->is_variable_args();
1116 if (is_ellipsis) {
1117 ags_count--;
1118 }
1119
1120 ASSERT(args.size());
1121 runner->back().vars.insert({"$0", VariablePair::Create(Term::CreateIntName("$0", "$0"), args[0].second)});
1122
1123 for (int i = 0; i < std::max(ags_count, (int) args.size() - 1); i++) {
1124 ObjPtr arg_value;
1125 std::string arg_name = ""; //runner->GetNamespace(true);
1126 if (i < ags_count) {
1127 arg_name = "$";
1128 if (obj.m_prototype->at(i).second->m_name_or_class.empty()) {
1129 arg_name += obj.m_prototype->at(i).second->m_text;
1130 } else {
1131 arg_name += obj.m_prototype->at(i).second->m_name_or_class;
1132 }
1133 arg_name = NormalizeName(arg_name);
1134 } else {
1135 if (!is_ellipsis && ags_count + 1 != args.size()) {
1136 LOG_RUNTIME("Неожиданный аргумент! %s", args.toString().c_str());
1137 }
1138 }
1139
1140 if (i + 1 < args.size()) {
1141 arg_value = args[i + 1].second;
1142 } else {
1143 if (i < obj.m_prototype->size()) {
1144 arg_value = Eval(obj.m_prototype->at(i).second, runner).GetVariablePair(true).var.GetValueAsObject();
1145 } else {
1146 LOG_RUNTIME("Неожиданный аргумент по умолчанию!");
1147 }
1148 }
1149
1150 ASSERT(!runner->empty());
1151 if (!arg_name.empty()) {
1152 if (runner->back().vars.find(arg_name) != runner->back().vars.end()) {
1153 LOG_RUNTIME("Argname '%s' already exist!", arg_name.c_str());
1154 }
1155
1156 std::string int_name = obj.m_prototype->at(i).second->m_normalized;
1157 if (int_name.empty()) {
1158 int_name = obj.m_prototype->at(i).second->m_name_or_class.empty() ? obj.m_prototype->at(i).second->m_text : obj.m_prototype->at(i).second->m_name_or_class;
1159 int_name = NormalizeName(int_name);
1160 }
1161
1162 runner->back().vars.insert({arg_name, VariablePair::Create(Term::CreateIntName(arg_name, int_name), arg_value)});
1163 }
1164 std::string arg_num = "$";
1165 arg_num += std::to_string(i + 1);
1166 runner->back().vars.insert({arg_name, VariablePair::Create(Term::CreateIntName(arg_num, arg_num), arg_value)});
1167
1168 args_dict->push_back(arg_value, arg_name);
1169 }
1170
1171 runner->back().vars.insert({"$*", VariablePair::Create(Term::CreateIntName("$*", "$*", TermID::DICT), args_dict)});
1172 runner->back().vars.insert({"$#", VariablePair::Create(Term::CreateIntName("$#", "$#"), Obj::CreateValue(args_dict->size()))});
1173 // if (i >= proto->size()) {
1174 // NL_PARSER(proto, "Argument pos %ld not exist!", i);
1175 // }
1176 // TermPtr argument = proto->at(i).second;
1177 // if (argument->m_name.empty()) {
1178 // // No default value
1179 // args->push_back(EvalTerm((*term)[i].second, runner), argument->m_text);
1180 // } else {
1181 // args->push_back(EvalTerm((*term)[i].second, runner), argument->m_name);
1182 // }
1183
1184 return runner->Eval(obj.m_sequence, runner).GetVariablePair(true).var.GetValueAsObject();
1185
1186 } else {
1187
1188 // LOG_TEST("Args: %s", args.toString().c_str());
1189
1190 ASSERT(std::holds_alternative<void *>(obj.m_var));
1191 FunctionType * func_ptr = (FunctionType *) std::get<void *>(obj.m_var);
1192 ASSERT(func_ptr);
1193 return (*func_ptr)(runner, args);
1194 }
1195 }
1196
1197 ASSERT(!(obj.is_string_type() || obj.is_dictionary_type()));
1198
1199 return obj.Clone();
1200}
1201
1203
1206
1207 ffi_cif m_cif;
1208 std::vector<ffi_type *> m_args_type;
1209 std::vector<void *> m_args_ptr;
1210
1211 union VALUE {
1212 const void *ptr;
1213 size_t size;
1214 int64_t integer;
1215 float number_f;
1216 double number_d;
1217 bool boolean;
1218 };
1219
1220 std::vector<VALUE> m_args_val;
1221 VALUE temp;
1222
1224 ASSERT(obj.m_prototype);
1225
1226 ASSERT(std::holds_alternative<void *>(obj.m_var));
1227 void * func_ptr = std::get<void *>(obj.m_var);
1228
1229 if (!func_ptr) {
1230 LOG_RUNTIME("Dymanic load native address '%s'!", "NOT IMPLEMENTED");
1231 }
1232 // NL_CHECK(func_ptr, "Fail load func name '%s' (%s) or fail load module '%s'!", m_prototype->m_text.c_str(),
1233 // m_func_mangle_name.empty() ? m_prototype->m_text.c_str() : m_func_mangle_name.c_str(),
1234 // m_module_name.empty() ? "none" : m_module_name.c_str());
1235
1236 // bool is_ellipsis = (obj.m_prototype->size() && (*obj.m_prototype)[obj.m_prototype->size() - 1].second->getTermID() == TermID::ELLIPSIS);
1237 // size_t check_count = is_ellipsis ? obj.m_prototype->size() - 1 : obj.m_prototype->size();
1238
1239 // Пропустить нулевой аргумент для нативных функций
1240 for (int i = 0; args && i < args->size(); i++) {
1241
1242 ASSERT((*args)[i].second);
1243 if ((*args)[i].second->m_is_reference) {
1244 LOG_RUNTIME("Argument REFERENCE! %s", (*args)[i].second->toString().c_str());
1245 }
1246
1247 size_t pind = i; // - 1; // Индекс прототипа на единицу меньше из-за пустого нулевого аргумента
1248
1249 ObjType type = (*args)[i].second->getTypeAsLimit();
1250 switch (type) {
1251 case ObjType::Bool:
1252 // if (pind < check_count) {
1253 // NL_CHECK(!isDefaultType((*obj.m_prototype)[pind].second->m_type), "Undefined type arg '%s'", (*obj.m_prototype)[pind].second->toString().c_str());
1254 // NL_CHECK(canCast(type, typeFromString((*obj.m_prototype)[pind].second->m_type, GetRT_(runner))), "Fail cast from '%s' to '%s'",
1255 // (*obj.m_prototype)[pind].second->m_type->asTypeString().c_str(), newlang::toString(type));
1256 // }
1257 m_args_type.push_back(RunTime::m_ffi_type_uint8);
1258 temp.boolean = (*args)[i].second->GetValueAsBoolean();
1259 m_args_val.push_back(temp);
1260 break;
1261
1262 case ObjType::Int8:
1263 case ObjType::Char:
1264 case ObjType::Byte:
1265 // if (pind < check_count) {
1266 // NL_CHECK(!isDefaultType((*obj.m_prototype)[pind].second->m_type), "Undefined type arg '%s'", (*obj.m_prototype)[pind].second->toString().c_str());
1267 // NL_CHECK(canCast(type, typeFromString((*obj.m_prototype)[pind].second->m_type, GetRT_(runner))), "Fail cast from '%s' to '%s'",
1268 // (*obj.m_prototype)[pind].second->m_type->asTypeString().c_str(), newlang::toString(type));
1269 // }
1270 m_args_type.push_back(RunTime::m_ffi_type_sint8);
1271 temp.integer = (*args)[i].second->GetValueAsInteger();
1272 m_args_val.push_back(temp);
1273 break;
1274
1275 case ObjType::Int16:
1276 case ObjType::Word:
1277 // if (pind < check_count) {
1278 // NL_CHECK(!isDefaultType((*obj.m_prototype)[pind].second->m_type), "Undefined type arg '%s'", (*obj.m_prototype)[pind].second->toString().c_str());
1279 // NL_CHECK(canCast(type, typeFromString((*obj.m_prototype)[pind].second->m_type, GetRT_(runner))), "Fail cast from '%s' to '%s'",
1280 // (*obj.m_prototype)[pind].second->m_type->m_text.c_str(), newlang::toString(type));
1281 // }
1282 m_args_type.push_back(RunTime::m_ffi_type_sint16);
1283 temp.integer = (*args)[i].second->GetValueAsInteger();
1284 m_args_val.push_back(temp);
1285 break;
1286
1287 case ObjType::Int32:
1288 case ObjType::DWord:
1289 // if (pind < check_count) {
1290 // NL_CHECK(!isDefaultType((*obj.m_prototype)[pind].second->m_type), "Undefined type arg '%s'", (*obj.m_prototype)[pind].second->toString().c_str());
1291 // NL_CHECK(canCast(type, typeFromString((*obj.m_prototype)[pind].second->m_type, GetRT_(runner))), "Fail cast from '%s' to '%s'",
1292 // (*obj.m_prototype)[pind].second->m_type->m_text.c_str(), newlang::toString(type));
1293 // }
1294 m_args_type.push_back(RunTime::m_ffi_type_sint32);
1295 temp.integer = (*args)[i].second->GetValueAsInteger();
1296 m_args_val.push_back(temp);
1297 break;
1298
1299 case ObjType::Int64:
1300 case ObjType::DWord64:
1301 // if (pind < check_count) {
1302 // NL_CHECK(!isDefaultType((*obj.m_prototype)[pind].second->m_type), "Undefined type arg '%s'", (*obj.m_prototype)[pind].second->toString().c_str());
1303 // NL_CHECK(canCast(type, typeFromString((*obj.m_prototype)[pind].second->m_type, GetRT_(runner))), "Fail cast from '%s' to '%s'",
1304 // (*obj.m_prototype)[pind].second->m_type->m_text.c_str(), newlang::toString(type));
1305 // }
1306 m_args_type.push_back(RunTime::m_ffi_type_sint64);
1307 temp.integer = (*args)[i].second->GetValueAsInteger();
1308 m_args_val.push_back(temp);
1309 break;
1310
1311 case ObjType::Float32:
1312 case ObjType::Single:
1313 // if (pind < check_count) {
1314 // NL_CHECK(!isDefaultType((*obj.m_prototype)[pind].second->m_type), "Undefined type arg '%s'", (*obj.m_prototype)[pind].second->toString().c_str());
1315 // NL_CHECK(canCast(type, typeFromString((*obj.m_prototype)[pind].second->m_type, GetRT_(runner))), "Fail cast from '%s' to '%s'",
1316 // (*obj.m_prototype)[pind].second->m_type->m_text.c_str(), newlang::toString(type));
1317 // }
1318 m_args_type.push_back(RunTime::m_ffi_type_float);
1319 temp.number_f = (*args)[i].second->GetValueAsNumber();
1320 m_args_val.push_back(temp);
1321 break;
1322
1323 case ObjType::Float64:
1324 case ObjType::Double:
1325 // if (pind < check_count) {
1326 // NL_CHECK(!isDefaultType((*obj.m_prototype)[pind].second->m_type), "Undefined type arg '%s'", (*obj.m_prototype)[pind].second->toString().c_str());
1327 // NL_CHECK(canCast(type, typeFromString((*obj.m_prototype)[pind].second->m_type, GetRT_(runner))), "Fail cast from '%s' to '%s'",
1328 // (*obj.m_prototype)[pind].second->m_type->m_text.c_str(), newlang::toString(type));
1329 // }
1330 m_args_type.push_back(RunTime::m_ffi_type_double);
1331 temp.number_d = (*args)[i].second->GetValueAsNumber();
1332 m_args_val.push_back(temp);
1333 break;
1334
1335 case ObjType::StrChar:
1336 case ObjType::FmtChar:
1337 {
1338 // if (pind < check_count) {
1339 // NL_CHECK(!isDefaultType((*obj.m_prototype)[pind].second->m_type), "Undefined type arg '%s'", (*obj.m_prototype)[pind].second->toString().c_str());
1340 // ObjType target = typeFromString((*obj.m_prototype)[pind].second->m_type, GetRT_(runner));
1341 // if (!canCast(type, target)) {
1342 // if ((target == ObjType::Int8 || target == ObjType::Char || target == ObjType::Byte)
1343 // && isStringChar(type) && (*args)[i].second->size() == 1) {
1344 //
1345 // m_args_type.push_back(RunTime::m_ffi_type_sint8);
1346 // temp.integer = (*args)[i].second->m_value[0];
1347 // m_args_val.push_back(temp);
1348 // break;
1349 //
1350 // }
1351 // LOG_RUNTIME("Fail cast from '%s' to '%s'", toString(type), toString(target));
1352 // }
1353 // }
1354 m_args_type.push_back(RunTime::m_ffi_type_pointer);
1355 temp.ptr = (*args)[i].second->m_value.c_str();
1356 m_args_val.push_back(temp);
1357 break;
1358 }
1359 case ObjType::FmtWide:
1360 case ObjType::StrWide:
1361 // if (pind < check_count) {
1362 // NL_CHECK(!isDefaultType((*obj.m_prototype)[pind].second->m_type), "Undefined type arg '%s'", (*obj.m_prototype)[pind].second->toString().c_str());
1363 // ObjType target = typeFromString((*obj.m_prototype)[pind].second->m_type, GetRT_(runner));
1364 // if (!canCast(type, target)) {
1365 // if (target == m_runtime->m_wide_char_type && isStringWide(type) && (*args)[i].second->size() == 1) {
1366 //
1367 // m_args_type.push_back(m_runtime->m_wide_char_type_ffi);
1368 // temp.integer = (*args)[i].second->m_string[0];
1369 // m_args_val.push_back(temp);
1370 // break;
1371 //
1372 // }
1373 // LOG_RUNTIME("Fail cast from '%s' to '%s'", toString(type), toString(target));
1374 // }
1375 // }
1376 m_args_type.push_back(RunTime::m_ffi_type_pointer);
1377 temp.ptr = (*args)[i].second->m_string.c_str();
1378 m_args_val.push_back(temp);
1379 break;
1380
1381 case ObjType::Pointer:
1382 // if (pind < check_count) {
1383 // NL_CHECK(!isDefaultType((*obj.m_prototype)[pind].second->m_type), "Undefined type arg '%s'", (*obj.m_prototype)[pind].second->toString().c_str());
1384 // NL_CHECK(canCast(type, typeFromString((*obj.m_prototype)[pind].second->m_type, GetRT_(runner))), "Fail cast from '%s' to '%s'",
1385 // (*obj.m_prototype)[pind].second->m_type->m_text.c_str(), newlang::toString(type));
1386 // }
1387 m_args_type.push_back(RunTime::m_ffi_type_pointer);
1388
1389 if (std::holds_alternative<void *>((*args)[i].second->m_var)) {
1390 temp.ptr = std::get<void *>((*args)[i].second->m_var);
1391 // } else if (args[i].second->m_var_type_fixed == ObjType::None || args[i].second->m_var_type_current == ObjType::None ) {
1392 // temp.ptr = nullptr;
1393 } else {
1394 LOG_RUNTIME("Fail convert arg '%s' to pointer!", (*args)[i].second->toString().c_str());
1395 }
1396
1397 m_args_val.push_back(temp);
1398 break;
1399
1400 default:
1401 LOG_RUNTIME("Native arg type '%s' not implemented!", newlang::toString((*args)[i].second->getType()));
1402 }
1403 // if (pind < check_count && (*obj.m_prototype)[pind].second->GetType()) {
1404 // if ((*obj.m_prototype)[pind].second->GetType()->m_text.compare(newlang::toString(ObjType::FmtChar)) == 0) {
1405 // NL_CHECK(newlang::ParsePrintfFormat(args, i), "Fail format string or type args!");
1406 // }
1407 // }
1408 }
1409
1410 for (size_t i = 0; i < m_args_val.size(); i++) {
1411 m_args_ptr.push_back((void *) &m_args_val[i]);
1412 }
1413
1414 NL_CHECK(!isDefaultType(obj.m_prototype->m_type), "Undefined return type '%s'", obj.m_prototype->toString().c_str());
1415
1416 VALUE res_value;
1417 ffi_type *result_ffi_type = nullptr;
1418
1419 ObjType return_type = RunTime::BaseTypeFromString(GetRT_(runner), obj.m_prototype->m_type->m_text);
1420
1421 switch (return_type) {
1422 case ObjType::Bool:
1423 result_ffi_type = RunTime::m_ffi_type_uint8;
1424 break;
1425
1426 case ObjType::Int8:
1427 case ObjType::Char:
1428 case ObjType::Byte:
1429 result_ffi_type = RunTime::m_ffi_type_sint8;
1430 break;
1431
1432 case ObjType::Int16:
1433 case ObjType::Word:
1434 result_ffi_type = RunTime::m_ffi_type_sint16;
1435 break;
1436
1437 case ObjType::Int32:
1438 case ObjType::DWord:
1439 result_ffi_type = RunTime::m_ffi_type_sint32;
1440 break;
1441
1442 case ObjType::Int64:
1443 case ObjType::DWord64:
1444 result_ffi_type = RunTime::m_ffi_type_sint64;
1445 break;
1446
1447 case ObjType::Float32:
1448 case ObjType::Single:
1449 result_ffi_type = RunTime::m_ffi_type_float;
1450 break;
1451
1452 case ObjType::Float64:
1453 case ObjType::Double:
1454 result_ffi_type = RunTime::m_ffi_type_double;
1455 break;
1456
1457 case ObjType::Pointer:
1458 case ObjType::StrChar:
1459 case ObjType::StrWide:
1460 result_ffi_type = RunTime::m_ffi_type_pointer;
1461 break;
1462
1463 case ObjType::None:
1464 result_ffi_type = RunTime::m_ffi_type_void;
1465 break;
1466
1467 default:
1468 LOG_RUNTIME("Native return type '%s' not implemented!", obj.m_prototype->m_type->asTypeString().c_str());
1469 }
1470
1471 // ASSERT(ctx->m_func_abi == FFI_DEFAULT_ABI); // Нужны другие типы вызовов ???
1472 if (RunTime::m_ffi_prep_cif(&m_cif, FFI_DEFAULT_ABI, static_cast<unsigned int> (m_args_type.size()), result_ffi_type, m_args_type.data()) == FFI_OK) {
1473
1474 ASSERT(obj.m_prototype->m_type);
1475
1476 RunTime::m_ffi_call(&m_cif, FFI_FN(func_ptr), &res_value, m_args_ptr.data());
1477
1478 if (result_ffi_type == RunTime::m_ffi_type_void) {
1479 return Obj::CreateNone();
1480 } else if (result_ffi_type == RunTime::m_ffi_type_uint8) {
1481 // Возвращаемый тип может быть как Byte, так и Bool
1482 return Obj::CreateValue(static_cast<uint8_t> (res_value.integer), return_type);
1483 } else if (result_ffi_type == RunTime::m_ffi_type_sint8) {
1484 return Obj::CreateValue(static_cast<int8_t> (res_value.integer), return_type);
1485 } else if (result_ffi_type == RunTime::m_ffi_type_sint16) {
1486 return Obj::CreateValue(static_cast<int16_t> (res_value.integer), return_type);
1487 } else if (result_ffi_type == RunTime::m_ffi_type_sint32) {
1488 return Obj::CreateValue(static_cast<int32_t> (res_value.integer), return_type);
1489 } else if (result_ffi_type == RunTime::m_ffi_type_sint64) {
1490 return Obj::CreateValue(res_value.integer, return_type);
1491 } else if (result_ffi_type == RunTime::m_ffi_type_float) {
1492 return Obj::CreateValue(res_value.number_f, return_type);
1493 } else if (result_ffi_type == RunTime::m_ffi_type_double) {
1494 return Obj::CreateValue(res_value.number_d, return_type);
1495 } else if (result_ffi_type == RunTime::m_ffi_type_pointer) {
1496 if (return_type == ObjType::StrChar) {
1497 return Obj::CreateString(reinterpret_cast<const char *> (res_value.ptr));
1498 } else if (return_type == ObjType::StrWide) {
1499 return Obj::CreateString(reinterpret_cast<const wchar_t *> (res_value.ptr));
1500 } else if (return_type == ObjType::Pointer) {
1501 ObjPtr result = Obj::CreateBaseType(return_type); //m_runtime->GetTypeFromString(GetRT_(runner), obj.m_prototype->m_type->m_text.c_str());
1502 result->m_var = (void *) res_value.ptr;
1503 result->m_var_is_init = true;
1504 return result;
1505 } else {
1506 LOG_RUNTIME("Error result type '%s' or not implemented!", obj.m_prototype->m_type->m_text.c_str());
1507 }
1508 } else {
1509 LOG_RUNTIME("Native return type '%s' not implemented!", obj.m_prototype->m_type->m_text.c_str());
1510 }
1511 }
1512
1513 LOG_RUNTIME("Fail native call '%s'!", obj.toString().c_str());
1514
1515 return Obj::CreateNone();
1516}
1517
1519 ObjPtr args = Obj::CreateDict();
1520 for (int i = 0; i < term->size(); i++) {
1521 ASSERT((*term)[i].second);
1522 if (term->name(i).empty()) {
1523 args->push_back(EvalTerm((*term)[i].second, runner).GetVariablePair(true).var.GetValueAsObject());
1524 } else {
1525
1526 args->push_back(EvalTerm((*term)[i].second, runner).GetVariablePair(true).var.GetValueAsObject(), term->name(i).c_str());
1527 }
1528 }
1529 return args;
1530}
1531
1533
1534 ObjPtr result = CreateArgs_(term, runner);
1535 if (term->getTermID() == TermID::DICT) {
1536
1537 result->m_var_type_fixed = ObjType::Class;
1538 result->m_class_name = term->m_name_or_class;
1539 }
1540 return result;
1541}
1542
1545
1546 ASSERT(term->m_type);
1547 ObjType type = GetBaseTypeFromString(term->m_type->m_text);
1548 for (int i = 0; i < term->size(); i++) {
1549 ASSERT(!term->name(i).empty());
1550 result->push_back(EvalTerm((*term)[i].second, runner).GetVariablePair(true).var.GetValueAsObject(), term->name(i).c_str());
1551 result->back().second->toType_(type);
1552 }
1553 if (result->size() == 2) {
1554 result->push_back(Obj::CreateValue(1, type), "step");
1555 }
1556 result->m_var_type_current = ObjType::Range;
1557 result->m_var_type_fixed = ObjType::Range;
1558 result->m_var_is_init = true;
1559
1560 return result;
1561}
1562
1564
1565 ASSERT(term->getTermID() == TermID::TENSOR);
1566 ASSERT(term->m_name_or_class.empty());
1567
1568 ObjPtr result = CreateDict(term, runner);
1569 if (!term->m_type) {
1570 result->m_var_type_fixed = ObjType::None;
1571 } else {
1572 result->m_var_type_fixed = GetBaseTypeFromString(term->m_type->m_text); //, GetRT_(runner)
1573 }
1574 ObjType type = getSummaryTensorType(result.get(), result->m_var_type_fixed);
1575
1576 if (type != ObjType::None) {
1577
1578 std::vector<int64_t> sizes = TensorShapeFromDict(result.get());
1579 result->toType_(type);
1580
1581 if (!sizes.empty()) {
1582 ASSERT(result->m_tensor);
1583 ASSERT(result->m_tensor->defined());
1584 *result->m_tensor = result->m_tensor->reshape(sizes);
1585 }
1586
1587 } else {
1588 result->m_var_is_init = false;
1589 }
1590 result->m_var_type_current = type;
1591
1592 return result;
1593}
1594
1595std::string Context::StringFormat(std::string_view format, Obj & args) {
1596
1597 std::string conv_format = AstAnalysis::ConvertToVFormat_(format, args);
1598
1599 fmt::dynamic_format_arg_store<fmt::format_context> store;
1600 for (int i = 0; i < args.size(); i++) {
1601
1602 switch (args[i].second->getType()) {
1603 case ObjType::Bool:
1604 case ObjType::Int8:
1605 case ObjType::Byte:
1606 case ObjType::Char:
1607 case ObjType::Int16:
1608 case ObjType::Word:
1609 case ObjType::Int32:
1610 case ObjType::DWord:
1611 case ObjType::Int64:
1612 case ObjType::DWord64:
1613 store.push_back(args[i].second->GetValueAsInteger());
1614 break;
1615
1616 case ObjType::Float16:
1617 case ObjType::Float32:
1618 case ObjType::Single:
1619 case ObjType::Float64:
1620 case ObjType::Double:
1621 store.push_back(args[i].second->GetValueAsNumber());
1622 break;
1623
1624 default:
1625 store.push_back(args[i].second->GetValueAsString());
1626 break;
1627 // LOG_RUNTIME("Support type '%s' not implemented!", toString(type));
1628 }
1629 }
1630
1631 return fmt::vformat(conv_format, store);
1632}
1633
1634std::string Context::StringPrintf(std::string_view format, Obj & args) {
1635 static ObjPtr int_snprintf = RunTime::CreateNative("__snprintf__(buffer:Pointer, size:Int32, format:FmtChar, ... ):Int32", nullptr, false, "snprintf");
1636 ASSERT(int_snprintf);
1637
1638 printf("%d %f\n", 100, 1.123);
1639
1640 ObjPtr int_args = Obj::CreateDict();
1641 int_args->push_back(Obj::CreateNil());
1642 int_args->push_back(Obj::CreateValue(0));
1643 int_args->push_back(Obj::CreateString(format.begin()));
1644 for (int i = 1; i < args.size(); i++) {
1645 if ((int) args[i].second->m_var_type_current >= (int) ObjType::Bool && (int) args[i].second->m_var_type_current < (int) ObjType::Int32) {
1646 int_args->push_back(args[i].second->toType(ObjType::Int32));
1647 } else if (args[i].second->m_var_type_current == ObjType::Float16 || args[i].second->m_var_type_current == ObjType::Float32) {
1648 int_args->push_back(args[i].second->toType(ObjType::Double));
1649 } else {
1650 int_args->push_back(args[i]);
1651 }
1652 }
1653
1654
1655 ObjPtr str_size = int_snprintf->op_call(int_args);
1656 ASSERT(str_size);
1657
1658 std::string buffer(str_size->GetValueAsInteger() + 1, '\0');
1659
1660 int_args->at(0).second = Obj::CreateType(ObjType::Pointer, ObjType::Pointer, true);
1661 int_args->at(0).second->m_var = buffer.data();
1662 int_args->at(1).second = Obj::CreateValue(buffer.size());
1663
1664 str_size = int_snprintf->op_call(int_args);
1665 ASSERT(str_size->GetValueAsInteger() + 1 == buffer.size());
1666
1667 return buffer;
1668}
1669
1670LatterType Context::EvalTerm(TermPtr term, Context * runner, bool rvalue) {
1671 ASSERT(term);
1672 ASSERT(!term->isBlock());
1673 try {
1674 // Static calculate
1675 switch (term->m_id) {
1676 case TermID::INTEGER:
1677 {
1678 int64_t val_int = parseInteger(term->getText().c_str());
1679 NL_TYPECHECK(term, typeFromLimit(val_int), typeFromString(term->m_type, GetRT_(runner))); // Соответстствует ли тип значению?
1680 ObjPtr result = Obj::CreateValue(val_int);
1681 result->m_var_type_current = typeFromLimit(val_int);
1682 if (term->GetType() && !isDefaultType(term->GetType())) {
1683 result->m_var_type_fixed = typeFromString(term->m_type, GetRT_(runner));
1684 result->m_var_type_current = result->m_var_type_fixed;
1685 }
1686 return LatterType::Create(term, result);
1687 }
1688 case TermID::NUMBER:
1689 {
1690 double val_dbl = parseDouble(term->getText().c_str());
1691 NL_TYPECHECK(term, typeFromLimit(val_dbl), typeFromString(term->m_type, GetRT_(runner))); // Соответстствует ли тип значению?
1692 ObjPtr result = Obj::CreateValue(val_dbl);
1693 result->m_var_type_current = typeFromLimit(val_dbl);
1694 if (term->GetType() && !isDefaultType(term->GetType())) {
1695 result->m_var_type_fixed = typeFromString(term->m_type, GetRT_(runner));
1696 result->m_var_type_current = result->m_var_type_fixed;
1697 }
1698 return LatterType::Create(term, result);
1699 }
1700 case TermID::RATIONAL:
1701 {
1702 ObjPtr result = Obj::CreateRational(term->m_text);
1703 result->m_var_type_fixed = result->m_var_type_current;
1704 return LatterType::Create(term, result);
1705 }
1706 case TermID::STRWIDE:
1707 {
1708 ObjPtr result = Obj::CreateString(utf8_decode(term->getText()));
1709 ASSERT(result);
1710 if (term->isCall()) {
1711 // Format string
1712 result = Call(runner, *result, term);
1713 }
1714 return LatterType::Create(term, result);
1715 }
1716 case TermID::STRCHAR:
1717 {
1718 ObjPtr result = Obj::CreateString(term->getText());
1719 ASSERT(result);
1720
1721 if (term->GetType()) {
1722 result->m_var_type_current = typeFromString(term->m_type, GetRT_(runner));
1723 result->m_var_type_fixed = result->m_var_type_current;
1724 }
1725
1726 if (term->isCall()) {
1727 // Format string
1728 result = Call(runner, *result, term);
1729 }
1730 return LatterType::Create(term, result);
1731 }
1732
1733 case TermID::TENSOR:
1734 return LatterType::Create(term, CreateTensor(term, runner));
1735 case TermID::DICT:
1736 return LatterType::Create(term, CreateDict(term, runner));
1737 case TermID::RANGE:
1738 return LatterType::Create(term, CreateRange(term, runner));
1739 case TermID::OP_MATH:
1740 return LatterType::Create(term, EvalOpMath_(term, runner));
1741 case TermID::OP_COMPARE:
1742 return LatterType::Create(term, EvalOpCompare_(term, runner));
1743 case TermID::OP_LOGICAL:
1744 return LatterType::Create(term, EvalOpLogical_(term, runner));
1745 case TermID::OP_BITWISE:
1746 return LatterType::Create(term, EvalOpBitwise_(term, runner));
1747 case TermID::FOLLOW:
1748 return LatterType::Create(term, EvalFollow_(term, runner));
1749 case TermID::NATIVE:
1750 return LatterType::Create(term, RunTime::CreateNative(term, RunTime::GetNativeAddress(nullptr, &term->m_text[1])));
1751 case TermID::ELLIPSIS:
1752 return LatterType::Create(term, getEllipsysObj());
1753 case TermID::END:
1754 return LatterType::Create(term, Obj::CreateNone());
1755 case TermID::NAME:
1756 if (term->isNone()) {
1757 return LatterType::Create(term, Obj::CreateNone());
1758 }
1759 }
1760
1761 if (!runner) {
1762 NL_PARSER(term, "The term type '%s' is not calculated statistically!", newlang::toString(term->getTermID()));
1763 }
1764
1765 if (term->isCreate()) {
1766 return runner->EvalCreate_(term);
1767 } else if (term->isNamed()) {
1768
1769 //#ifdef BUILD_DEBUG
1770 // Variable * item = nullptr;
1771 // if (term->isNamed() && !isReservedName(term->m_text)) {
1772 // item = runner->FindVarItem(term);
1773 // }
1774 // if (item) {
1775 // if (item->term_check != item->term.get()) {
1776 // LOG_RUNTIME("item term: %s (%p != %p)", term->m_text.c_str(), item->term_check, item->term.get());
1777 // }
1778 // if (item->obj_check != item->obj.get()) {
1779 // if (item->obj_check) {
1780 // LOG_RUNTIME("item obj: %s (%p != %p)", term->m_text.c_str(), item->obj_check, item->obj.get());
1781 // } else {
1782 // item->obj_check = item->obj.get();
1783 // }
1784 // }
1785 // } else {
1786 // // LOG_TEST("VarItem '%s' - not found!", term->m_text.c_str());
1787 // }
1788 //#endif
1789
1790 // if (isReservedName(term->m_text)) {
1791 // return Obj::CreateNil();
1792 // }
1793
1794 VariablePair * found = runner->FindObject(term->m_normalized);
1795 if (!found || found->var.is_undefined()) {
1796 NL_PARSER(term, "Object '%s' (%s) not calculated!", term->m_text.c_str(), term->m_normalized.c_str());
1797 }
1798 //#ifdef BUILD_DEBUG
1799 // if (item) {
1800 // if (item->term_check != found.get()) {
1801 // LOG_RUNTIME("found term: %s (%p != %p)", term->m_text.c_str(), item->term_check, found.get());
1802 // }
1803 // if (item->obj_check != found->m_obj.get()) {
1804 // if (item->obj_check) {
1805 // LOG_ERROR("found obj: %s (%p != %p)", term->m_text.c_str(), item->obj_check, found->m_obj.get());
1806 // } else {
1807 // if (item->term->m_obj) {
1808 // if (item->obj || item->obj_check) {
1809 // LOG_RUNTIME("found obj: %s %p (%p != %p)", term->m_text.c_str(), item->term->m_obj.get(), item->obj.get(), item->obj_check);
1810 // }
1811 // item->obj = item->term->m_obj;
1812 // item->obj_check = item->term->m_obj.get();
1813 // } else {
1814 // item->obj = found->m_obj;
1815 // item->obj->m_sync = item->sync.get();
1816 // item->term->m_obj = item->obj;
1817 // item->obj_check = item->obj.get();
1818 // }
1819 // }
1820 // }
1821 // } else {
1822 // // LOG_TEST("VarItem '%s' - not found!", term->m_text.c_str());
1823 // }
1824 //#endif
1825
1826 // ASSERT(found);
1827 // if (found->term && !term->m_type) {
1828 // found->term->m_type = found->m_type;
1829 // } else {
1830 // ASSERT(!"Check type?????");
1831 // }
1832
1833 if (term->isCall()) {
1834 // Вызов функции или клонирование объекта
1835 if (term->m_is_take) {
1836 // return Obj::Take(*Call(runner, *found->m_obj, term));
1837 } else {
1838 return LatterType::Create(term, Call(runner, *found->var.GetValueAsObject(), term));
1839 }
1840 } else if (rvalue && term->m_right) {
1841
1842 // if (term->m_right->m_id == TermID::INDEX) {
1843 // return GetIndexValue(term, found->m_obj, runner);
1844 // } else if (term->m_right->m_id == TermID::FIELD) {
1845 // return GetFieldValue(term, found->m_obj, runner);
1846 // } else {
1847 // NL_PARSER(term, "Eval type '%s' not implemented!", toString(term->m_right->m_id));
1848 // }
1849
1850 } else if (term->m_is_take) {
1851 ASSERT(found);
1852 ASSERT(!found);
1853 return LatterType::Create(term, found->var.Take());
1854 } else {
1855 return found;
1856 }
1857
1858 } else {
1859
1860 switch (term->m_id) {
1861
1862 case TermID::ITERATOR:
1863 return LatterType::Create(term, runner->EvalIterator_(term));
1864 case TermID::EVAL:
1865 return LatterType::Create(term, runner->EvalEval_(term));
1866 case TermID::WHILE:
1867 return LatterType::Create(term, runner->EvalWhile_(term));
1868 case TermID::DOWHILE:
1869 return LatterType::Create(term, runner->EvalDoWhile_(term));
1870 case TermID::TAKE:
1871 return LatterType::Create(term, runner->EvalTake_(term));
1872
1873 case TermID::INT_PLUS:
1874 case TermID::INT_MINUS:
1875 case TermID::INT_REPEAT:
1876 return LatterType::Create(term, runner->EvalInterrupt_(term));
1877
1878 }
1879
1880 // if (term->GetType() && !isDefaultType(term->GetType())) {
1881 // term->m_obj->m_var_type_fixed = typeFromString(term->m_type, m_runtime.get());
1882 // term->m_obj->m_var_type_current = term->m_obj->m_var_type_fixed;
1883 // }
1884 }
1885
1886 LOG_RUNTIME("EvalTerm_ for type '%s'(%s) not implemented!", newlang::toString(term->m_id), term->m_text.c_str());
1887
1888 } catch (std::exception & ex) {
1889
1890 NL_PARSER(term, "%s", ex.what());
1891 }
1892
1893 NL_PARSER(term, "The term type '%s' is not calculated statistically!", newlang::toString(term->getTermID()));
1894}
1895
1897 // ASSERT(op->size());
1898 // CheckObjTerm_(op->at(0).second, this);
1899 // ObjPtr args;
1900 // if (op->isCall()) {
1901 // args = CreateArgs_(op, this);
1902 // } else {
1903 // args = Obj::CreateDict();
1904 // args->push_back(op->at(0).second->m_obj);
1905 // }
1906 //
1907 // m_latter = Obj::Take(*args);
1908 //
1909 // return m_latter;
1910 return nullptr;
1911}
1912
1913ObjPtr Context::CreateNative_(TermPtr &proto, const char *module, bool lazzy, const char *mangle_name) {
1914 ObjPtr result = m_runtime->CreateNative(proto, module, lazzy, mangle_name);
1915 result->m_ctx = this;
1916
1917 return result;
1918}
1919
1920VariablePair * Context::FindObject(const std::string_view int_name) {
1921 // std::string int_name;
1922 // if (isInternalName(int_name)) {
1923 // }
1924 // int_name = NormalizeName(int_name);
1925 // ASSERT();
1926 //
1927 // std::string int_name;
1928 //
1929 // if (term->isNone()) {
1930 // term->m_normalized = "_";
1931 // }
1932 if (int_name.empty()) {
1933 LOG_RUNTIME("Has no internal name! AST analysis required!");
1934 }
1935
1936 VariablePair * result = nullptr;
1937 if (int_name.compare("_") == 0) {
1938 result = const_cast<VariablePair *> (&getNonePair()); //VariablePair::Create(Term::CreateNone(), Obj::CreateNone());
1939 } else if (int_name.compare("$^") == 0) {
1940 result = const_cast<VariablePair *> (&m_latter.GetVariablePair());
1941 } else {
1942 result = FindLocalVar(int_name);
1943 if (!result && (isGlobalScope(int_name) || isTypeName(int_name))) {
1944 return m_runtime->FindObject(int_name);
1945 // if (glob) {
1946 // result = glob->var.lock();
1947 // }
1948 }
1949 }
1950 if (!result) {
1951 //#ifdef BUILD_UNITTEST
1952 // if (term->m_text.compare("__STAT_RUNTIME_UNITTEST__") == 0) {
1953 // ASSERT(term->isCall());
1954 // ASSERT(term->size() == 2);
1955 // return Obj::CreateValue(m_rt->__STAT_RUNTIME_UNITTEST__(
1956 // parseInteger(term->at(0).second->m_text.c_str()),
1957 // parseInteger(term->at(1).second->m_text.c_str())));
1958 // }
1959 //#endif
1960 // LOG_RUNTIME("Object with internal name '%s' not found!", int_name.begin());
1961 }
1962
1963 return result;
1964}
1965
1966VariablePair * Context::FindLocalVar(const std::string_view name) {
1967 auto iter = rbegin();
1968 while (iter != rend()) {
1969 auto found = iter->vars.find(name.begin());
1970 if (found != iter->vars.end()) {
1971 return &found->second;
1972 }
1973 iter++;
1974 }
1975 return nullptr;
1976}
1977
1978//TermPtr Context::FindInternalName(const std::string_view int_name) {
1979//
1980// // Variable * item = FindVarItem(int_name);
1981// // int_name = NormalizeName(int_name);
1982//
1983// // StorageTerm & stor = getStorage_();
1984// // if (&stor != &m_static && stor.find(int_name.begin()) != stor.end()) {
1985// // return stor.find(int_name.begin())->second;
1986// // }
1987//
1988// // auto iter = rbegin();
1989// // while (iter != rend()) {
1990// // auto found = iter->vars.find(int_name.begin());
1991// // if (found != iter->vars.end()) {
1992// // return found->second.item;
1993// // }
1994// // iter++;
1995// // }
1996// //
1997// // auto found = m_static.find(int_name.begin());
1998// // if (found != m_static.end()) {
1999// // return found->second.item;
2000// // }
2001//
2002// // if (item) {
2003// // return item->term;
2004// // }
2005//
2006// if (m_runtime) {
2007// // GlobName * found = m_runtime->NameFind(int_name);
2008// // if (found) {
2009// // // if (std::holds_alternative<ObjWeak>(found->obj)) {
2010// // // return std::get<ObjWeak>(found->obj).lock();
2011// // // } else if (std::holds_alternative<std::vector < ObjWeak >> (found->obj)) {
2012// // // return std::get<std::vector < ObjWeak >> (found->obj)[0].lock();
2013// // // }
2014// // if (std::holds_alternative<TermWeak>(found->term)) {
2015// // return std::get<TermWeak>(found->term).lock();
2016// // } else if (std::holds_alternative<std::vector < TermWeak >> (found->term)) {
2017// //
2018// // return std::get<std::vector < TermWeak >> (found->term)[0].lock();
2019// // }
2020// // }
2021// }
2022// return nullptr;
2023//}
2024
2026 ASSERT(op);
2027 ASSERT(op->isCreate());
2028 ASSERT(op->m_left);
2029
2030 if (op->m_left->isCall()) {
2031 // Functions
2032 // a() := %func
2033 // a() := { } func
2034 // && a() := { } async func val := *a(); **( val := *a()){ },[...] { }; -> val := await a() ??????????????????????
2035 // a() := %() { } coro co_yeld, co_return, co_wait ????????????????
2037 } else {
2038 // Variables
2039 if (op->m_right->m_id == TermID::ELLIPSIS) {
2040 // a, b, c := ... dict
2042 } else if (op->m_right->m_id == TermID::FILLING) {
2043 // a, b, c := ... dict ... FILLING
2045 } else {
2046 // a, b, c := value
2047 // a, b := b, a swap
2048
2050 }
2051 }
2052 return m_latter;
2053
2054
2055 // ArrayTermType l_vars = op->m_left->CreateArrayFromList();
2056 //
2057 // bool is_ellipsis = false;
2058 // TermPtr var_found;
2059 // for (auto &elem : l_vars) {
2060 //
2061 // if (elem->getTermID() == TermID::ELLIPSIS) {
2062 //
2063 // //@todo добавить поддержку многоточия с левой стороный оператора присвоения
2064 // // NL_PARSER(elem, "Ellipsis on the left side in assignment not implemented!");
2065 //
2066 // // Игнорировать несколько объектов
2067 // elem->m_obj = getEllipsysObj();
2068 // if (is_ellipsis) {
2069 // NL_PARSER(elem, "Multiple ellipsis on the left side of the assignment!");
2070 // }
2071 // is_ellipsis = true;
2072 //
2073 // } else if (elem->isNone()) {
2074 //
2075 // // Игнорировать один объект
2076 // elem->m_obj = getNoneObj();
2077 //
2078 // } else {
2079 //
2080 // var_found = GetObject(elem->m_normalized);
2081 //
2082 // if (op->isCreateOnce() && var_found && var_found->m_obj) {
2083 // NL_PARSER(elem, "Object '%s' already exist", elem->m_text.c_str());
2084 // } else if (op->getTermID() == TermID::ASSIGN && !(var_found && var_found->m_obj)) {
2085 // NL_PARSER(elem, "Object '%s' not exist!", elem->m_text.c_str());
2086 // }
2087 //
2088 // if (var_found) {
2089 // if (var_found->isCall() && var_found->m_obj) {
2090 // NL_PARSER(elem, "The function cannot be overridden! '%s'", var_found->toString().c_str());
2091 // }
2092 // elem = var_found;
2093 // // elem->m_normalized = var_found->m_normalized;
2094 // // elem->m_obj = var_found->m_obj;
2095 // // LOG_TEST("0: %s = %s (%p)", elem->m_text.c_str(), elem->m_obj ? elem->m_obj->toString().c_str() : "nullptr", elem->m_obj.get());
2096 // }
2097 // }
2098 // }
2099 //
2100 // m_latter = AssignVars_(l_vars, op->m_right, op->isPure());
2101 // for (auto &elem : l_vars) {
2102 //
2103 // // LOG_TEST("4: %s = %s (%p)", elem->m_text.c_str(), elem->m_obj ? elem->m_obj->toString().c_str() : "nullptr", elem->m_obj.get());
2104 //
2105 // if (isGlobalScope(elem->m_normalized)) {
2106 // m_runtime->NameRegister(op->isCreateOnce(), elem->m_normalized.c_str(), elem); //, elem->m_obj);
2107 // }
2108 // }
2109 // return m_latter;
2110}
2111
2113
2114 ASSERT(op->isCreate());
2115
2116 VariablePairList l_vars;
2117 EvalLeftVars_(l_vars, op);
2118
2119 ASSERT(l_vars.size() == 1);
2120 // ASSERT(l_vars[0]->isCall());
2121
2122 // ASSERT(op->m_right);
2123 // if (l_vars[0]->m_ref) {
2124 // // && a() := { } async func val := *a(); **( val := *a()){ },[...] { }; -> val := await a() ??????????????????????
2125 // NL_PARSER(op, "Create Async function not implemented!");
2126 // } else if (op->m_right->getTermID() == TermID::COROUTINE) {
2127 // // a() := %() { } coro co_yeld, co_return, co_wait ????????????????
2128 // NL_PARSER(op, "Create coroutine not implemented!");
2129 //
2130 // } else if (op->m_right->isBlock()) {
2131 // // a() := { } func
2132 // l_vars[0]->m_obj = m_runtime->CreateFunction(l_vars[0], op->m_right);
2133 //
2134 // } else if (op->m_right->getTermID() == TermID::NATIVE) {
2135 // // a() := %func ...
2136 // l_vars[0]->m_obj = m_runtime->CreateNative(l_vars[0], nullptr, false, op->m_right->m_text.substr(1).c_str());
2137 //
2138 // } else {
2139 //
2140 // NL_PARSER(op, "The type of the function being created is not recognized!");
2141 // }
2142 //
2143 // return l_vars[0]->m_obj;
2144 return nullptr;
2145}
2146
2148 // a, b, c := ... dict
2149
2150 // NL_PARSER(op, "Create ellipsis not implemented!");
2151
2152 // При раскрытии словаря присвоить значение можно как одному, так и сразу нескольким терминам:
2153 // var1, var2, _ = ... func(); Первый и второй элементы записывается в var1 и var2,
2154 // а все остальные игнорируются (если они есть)
2155 // var1, var2 = ... func(); Если функция вернула словарь с двумя элементами,
2156 // то их значения записываются в var1 и var2. Если в словаре было больше двух элементов,
2157 // то первый записывается в var1, а все оставшиеся элементы в var2. !!!!!!!!!!!!!
2158 // item, dict = ... dict; Первый элементы записывается в item и удаялется из dict
2159
2160 // _, var1, ..., var2 = ... func();
2161 // Первый элемент словаря игнорируется, второй записывается в var1, а последний в var2.
2162
2163 //@todo добавить поддержку многоточия с левой стороный оператора присвоения
2164
2165 VariablePairList l_vars;
2166 EvalLeftVars_(l_vars, op);
2167
2168 bool is_named = !!op->m_right->m_left;
2169 if (is_named) {
2170 NL_PARSER(op->m_right, "Named ELLIPSIS NOT implemented!");
2171 ASSERT(op->m_right->m_left->getTermID() == TermID::ELLIPSIS);
2172 }
2173
2174 bool is_last = false;
2175 LatterType right_obj = EvalTerm(op->m_right->m_right, this);
2176 for (size_t i = 0; i < l_vars.size(); i++) {
2177 if (l_vars[i].GetVariablePair().term->isNone()) {
2178 // Ignore position
2179 continue;
2180 }
2181 if (i + 1 == l_vars.size()) {
2182 is_last = true;
2183 }
2184
2185 // LOG_TEST("1: %s = %s (%p)", l_vars[i]->m_text.c_str(), l_vars[i]->m_obj ? l_vars[i]->m_obj->toString().c_str() : "nullptr", l_vars[i]->m_obj.get());
2186 if (i < right_obj.GetVariablePair(true).var.GetValueAsObject()->size()) {
2187 if (is_last) {
2188 if (l_vars[i].GetVariablePair().term->m_normalized.compare(op->m_right->m_right->m_normalized) == 0) {
2189 // Остаток элементов присваивается тому же словарю
2190 l_vars[i] = right_obj.GetVariablePair();
2191 l_vars[i].GetVariablePair(true).var.GetValueAsObject()->erase(0, l_vars.size() - 1);
2192 } else {
2193 l_vars[i].GetVariablePair(true).var = right_obj.GetVariablePair(true).var.GetValueAsObject()->Copy();
2194 }
2195 } else {
2196 l_vars[i].GetVariablePair(true).var = (*right_obj.GetVariablePair(true).var.GetValueAsObject())[i].second;
2197 }
2198 } else {
2199 if (is_last) {
2200 if (l_vars[i].GetVariablePair().term->m_normalized.compare(op->m_right->m_right->m_normalized) == 0) {
2201 // Остаток элементов присваивается тому же словарю
2202 l_vars[i].GetVariablePair(true).var = right_obj;
2203 l_vars[i].GetVariablePair(true).var.GetValueAsObject()->erase(0, 0);
2204 } else {
2205 l_vars[i].GetVariablePair(true).var = right_obj.GetVariablePair(true).var.GetValueAsObject()->Copy();
2206 }
2207 } else {
2208 l_vars[i].GetVariablePair(true).var = Obj::CreateNone();
2209 }
2210 }
2211 // LOG_TEST("2: %s = %s (%p)", l_vars[i]->m_text.c_str(), l_vars[i]->m_obj ? l_vars[i]->m_obj->toString().c_str() : "nullptr", l_vars[i]->m_obj.get());
2212 }
2213 m_latter = l_vars[l_vars.size() - 1];
2214 return m_latter;
2215}
2216
2218 // a, b, c := ... func() ...
2219
2220 NL_PARSER(op, "Create filling not implemented!");
2221}
2222
2224 // a, b, c := value
2225 // a, b := b, a
2226 VariablePairList l_vars;
2227 EvalLeftVars_(l_vars, op);
2228 ASSERT(l_vars.size());
2229
2230 BlockType r_vars;
2231 op->m_right->RightToBlock(r_vars, false); //= op->m_right->CreateArrayFromList();
2232 if (r_vars.empty()) {
2233 // Delete vars
2234 NL_PARSER(op, "Delete var NOT implemented!");
2235 // m_latter = getNoneObj();
2236
2237 } else if (r_vars.size() == 1) {
2238
2239 LatterType temp = Eval(r_vars[0], this);
2240
2241 // LOG_TEST("temp: %s = %s (%p)", r_vars[0]->m_text.c_str(), r_vars[0]->m_obj ? r_vars[0]->m_obj->toString().c_str() : "nullptr", r_vars[0]->m_obj.get());
2242
2243 for (auto &elem : l_vars) {
2244 if (elem.GetVariablePair().term->getTermID() == TermID::ELLIPSIS) {
2245 NL_PARSER(elem.GetVariablePair().term, "Ellipses unexpected!");
2246 } else if (elem.GetVariablePair().term->isNone()) {
2247 NL_PARSER(elem.GetVariablePair().term, "None var unexpected!");
2248 } else if (elem.GetVariablePair().term->m_right) {
2249
2250 if (elem.GetVariablePair().term->m_right->m_id == TermID::INDEX) {
2251 SetIndexValue(elem.GetVariablePair().term, temp.GetVariablePair(true).var.GetValueAsObject(), this);
2252 } else if (elem.GetVariablePair().term->m_right->m_id == TermID::FIELD) {
2253 SetFieldValue(elem.GetVariablePair().term, temp.GetVariablePair(true).var.GetValueAsObject(), this);
2254 } else {
2255 // if (elem->var) {
2256 // elem->var = *temp;
2257 // } else {
2258
2259 elem.GetVariablePair(true).var = temp.GetVariablePair().var;
2260
2261 // }
2262 // NL_PARSER(elem, "Eval type '%s' not implemented!", toString(elem->m_right->m_id));
2263 }
2264
2265 } else {
2266
2267 // if (elem->m_obj) {
2268
2269 elem.GetVariablePair(true).var = temp.GetVariablePair().var;
2270
2271 // *elem->m_obj = *temp;
2272 // } else {
2273 // elem->var = std::make_shared<Variable>(temp);
2274 // elem->m_obj = temp;
2275 if (elem.GetVariablePair().term && elem.GetVariablePair().term->m_type) {
2276
2277 ObjType proto_type = typeFromString(elem.GetVariablePair().term->m_type, m_runtime);
2278 // if (!canCast(proto_type, temp->getType())) {
2279 // NL_MESSAGE(LOG_LEVEL_INFO, fill_obj, "Fail cast type '%s' to '%s' type!", fill_obj->m_type->m_text.c_str(), call->m_type->m_text.c_str());
2280 // return false;
2281 // }
2282
2283
2284 // elem->m_obj->m_var_type_current = proto_type;
2285 // elem->m_obj->m_var_type_fixed = proto_type;
2286 }
2287 // }
2288
2289 //#ifdef BUILD_DEBUG
2290 // VarItem * item = nullptr;
2291 // if (elem->isNamed() && !isReservedName(elem->m_text)) {
2292 // item = FindVarItem(elem);
2293 // }
2294 // if (item) {
2295 // if (item->term_check != item->term.get()) {
2296 // LOG_RUNTIME("elem term: %s (%p != %p)", elem->m_text.c_str(), item->term_check, item->term.get());
2297 // }
2298 // if (item->obj_check != item->obj.get()) {
2299 // if (item->obj_check) {
2300 // LOG_RUNTIME("elem obj: %s (%p != %p)", elem->m_text.c_str(), item->obj_check, item->obj.get());
2301 // } else {
2302 // item->obj = elem->m_obj;
2303 // item->obj->m_sync = item->sync.get();
2304 // item->term->m_obj = item->obj;
2305 // item->obj_check = item->obj.get();
2306 // }
2307 // } else if (!item->obj_check) {
2308 // item->obj = elem->m_obj;
2309 // item->obj->m_sync = item->sync.get();
2310 // item->term->m_obj = item->obj;
2311 // item->obj_check = item->obj.get();
2312 // }
2313 // } else {
2314 // LOG_TEST("VarItem '%s' - not found!", elem->m_text.c_str());
2315 // }
2316 //#endif
2317 }
2318 }
2319
2320 } else {
2321
2322 NL_PARSER(op, "Not implemented!");
2323 // // Что присваиваем (правая часть выражения)
2324 // // @todo В будущем можно будет сделать сахар для обмена значениями при одинаковом кол-ве объектов у оператора присваивания
2325 // // a, b = b, a; a, b, c = c, b, a; и т.д.
2326 //
2327 // if (l_vars.size() != r_vars.size()) {
2328 // NL_PARSER(op, "Fail count right values! Expected one or %d.", (int) l_vars.size());
2329 // }
2330 // for (size_t i = 0; i < l_vars.size(); i++) {
2331 // if (l_vars[i]->term->getTermID() == TermID::ELLIPSIS) {
2332 // NL_PARSER(l_vars[i]->term, "Ellipses unexpected!");
2333 // } else if (l_vars[i]->term->isNone()) {
2334 // NL_PARSER(l_vars[i]->term, "None var unexpected!");
2335 // } else {
2336 //
2337 // m_var_latter = std::make_shared<Variable>(Run(r_vars[i], this));
2338 // l_vars[i]->var = m_var_latter;
2339 // }
2340 // }
2341 //
2342 }
2343 return l_vars[l_vars.size() - 1];
2344}
2345
2347
2348 TermPtr elem = op->m_left;
2349 VariablePair * var_found = nullptr;
2350 while (elem) {
2351
2352 if (elem->isNone()) {
2353
2354 // Игнорировать объект
2355 vars.push_back(LatterType::Create(elem, getNoneObj()));
2356
2357 } else {
2358
2359 var_found = FindObject(elem->m_normalized);
2360
2361 // GlobalName *found = m_runtime->FindObject(elem->m_normalized);
2362 // if (found) {
2363 // var_found = found->proto.lock();
2364 // //@todo добавить проверку на многократное предварительное объявление объектов ????
2365 // // NL_PARSER(elem, "Multiple object declaration '%s'!",elem->m_normalized.c_str());
2366 // vars.back().var = &found->data;
2367 // }
2368
2369
2370 if (op->isCreateNew() && var_found && !var_found->var.is_undefined()) {
2371 NL_PARSER(elem, "Object '%s' already exist", elem->m_text.c_str());
2372 } else if (op->getTermID() == TermID::ASSIGN && !(var_found && !var_found->var.is_undefined())) {
2373 NL_PARSER(elem, "Object '%s' not exist!", elem->m_text.c_str());
2374 }
2375
2376 if (var_found && !op->isCreateNew()) {
2377 if (elem->isCall() && var_found) {
2378 NL_PARSER(elem, "Recreate function not implemented!");
2379 }
2380 } else {
2381 ASSERT(!empty());
2382 if (back().vars.find(elem->m_normalized) != back().vars.end()) {
2383 NL_PARSER(elem, "Local object '%s' already exist", elem->m_text.c_str());
2384 }
2385 // std::pair<iterator, bool>
2386 auto ins = back().vars.emplace(std::make_pair(elem->m_normalized, VariablePair::Create(op->m_left, std::monostate())));
2387// back().vars.insert({elem->m_normalized, var_found});
2388// var_found = VariablePair::Create(op->m_left, std::monostate());
2389 ASSERT(ins.second);
2390 var_found = &(*ins.first).second;
2391 }
2392
2393 vars.push_back(var_found);
2394
2395 if (isGlobalScope(elem->m_normalized)) {
2396 m_runtime->RegisterObject(op->isCreateNew(), elem->m_normalized.c_str(), var_found->term, var_found->var);
2397 }
2398 }
2399
2400 elem = elem->m_left;
2401 }
2402}
2403
2404//void Context::EvalLeftVars_(BlockType &vars, const TermPtr & op) {
2405//
2406// vars = op->m_left->CreateArrayFromList();
2407//
2408// bool is_ellipsis = false;
2409// TermPtr var_found = nullptr;
2410// for (auto &elem : vars) {
2411//
2412// if (elem->getTermID() == TermID::ELLIPSIS) {
2413//
2414// //@todo добавить поддержку многоточия с левой стороный оператора присвоения
2415// // NL_PARSER(elem, "Ellipsis on the left side in assignment not implemented!");
2416//
2417// // Игнорировать несколько объектов
2418// elem->m_obj = getEllipsysObj();
2419// if (is_ellipsis) {
2420// NL_PARSER(elem, "Multiple ellipsis on the left side of the assignment!");
2421// }
2422// is_ellipsis = true;
2423//
2424// } else if (elem->isNone()) {
2425//
2426// // Игнорировать один объект
2427// elem->m_obj = getNoneObj();
2428//
2429// } else {
2430//
2431// var_found = GetObject(elem->m_normalized);
2432//
2433// if (op->isCreateOnce() && var_found && var_found->m_obj) {
2434// NL_PARSER(elem, "Object '%s' already exist", elem->m_text.c_str());
2435// } else if (op->getTermID() == TermID::ASSIGN && !(var_found && var_found->m_obj)) {
2436// NL_PARSER(elem, "Object '%s' not exist!", elem->m_text.c_str());
2437// }
2438//
2439// if (var_found && !op->isCreateForce()) {
2440// // if (elem->isCall() && elem->m_obj) {
2441// // NL_PARSER(elem, "Recreate function not implemented!");
2442// // }
2443// // if (elem->m_obj) {
2444// // *elem->m_obj = *var_found->m_obj;
2445// // } else {
2446// elem->m_obj = var_found->m_obj;
2447// // }
2448//
2449// } else {
2450// ASSERT(!empty());
2451// if (back().vars.find(elem->m_normalized) != back().vars.end()) {
2452// NL_PARSER(elem, "Local object '%s' already exist", elem->m_text.c_str());
2453// }
2454//
2455// // VarItem item;
2456// // item.item = op->m_left;
2457// // item.sync = Context::CreateSync(op->m_left);
2458// // item.obj = nullptr;
2459// back().vars.insert({elem->m_normalized, Context::CreateItem(op->m_left, nullptr)});
2460//
2461// }
2462//
2463// if (isGlobalScope(elem->m_normalized)) {
2464//
2465// m_runtime->NameRegister(op->isCreateOnce(), elem->m_normalized.c_str(), elem);
2466// }
2467// }
2468// }
2469//}
2470
2471//ObjPtr Context::AssignVars_(ArrayTermType &l_vars, const TermPtr &r_term, bool is_pure) {
2472//
2473// ASSERT(l_vars.size());
2474// if (r_term->getTermID() == TermID::NATIVE) {
2475//
2476// ASSERT(l_vars.size() == 1);
2477// // ASSERT(vars[0]->m_obj);
2478// // ASSERT(r_term->m_obj);
2479//
2480// l_vars[0]->m_obj = m_runtime->CreateNative(l_vars[0], nullptr, false, r_term->m_text.substr(1).c_str());
2481// // vars[0]->m_obj = r_term->m_obj;
2482// m_latter = l_vars[0]->m_obj;
2483//
2484// } else if (r_term->getTermID() == TermID::ELLIPSIS) {
2485// // При раскрытии словаря присвоить значение можно как одному, так и сразу нескольким терминам:
2486// // var1, var2, _ = ... func(); Первый и второй элементы записывается в var1 и var2,
2487// // а все остальные игнорируются (если они есть)
2488// // var1, var2 = ... func(); Если функция вернула словарь с двумя элементами,
2489// // то их значения записываются в var1 и var2. Если в словаре было больше двух элементов,
2490// // то первый записывается в var1, а все оставшиеся элементы в var2. !!!!!!!!!!!!!
2491// // item, dict = ... dict; Первый элементы записывается в item и удаялется из dict
2492//
2493// // _, var1, ..., var2 = ... func();
2494// // Первый элемент словаря игнорируется, второй записывается в var1, а последний в var2.
2495//
2496// //@todo добавить поддержку многоточия с левой стороный оператора присвоения
2497//
2498// bool is_named = !!r_term->m_left;
2499// if (is_named) {
2500// NL_PARSER(r_term, "Named ELLIPSIS NOT implemented!");
2501// ASSERT(r_term->m_left->getTermID() == TermID::ELLIPSIS);
2502// }
2503//
2504// bool is_last = false;
2505// ObjPtr right_obj = CheckObjTerm_(r_term->m_right, this);
2506// for (size_t i = 0; i < l_vars.size(); i++) {
2507// if (l_vars[i]->isNone()) {
2508// // Ignore position
2509// continue;
2510// }
2511// if (i + 1 == l_vars.size()) {
2512// is_last = true;
2513// }
2514//
2515// // LOG_TEST("1: %s = %s (%p)", l_vars[i]->m_text.c_str(), l_vars[i]->m_obj ? l_vars[i]->m_obj->toString().c_str() : "nullptr", l_vars[i]->m_obj.get());
2516//
2517// if (i < right_obj->size()) {
2518// if (is_last) {
2519// if (l_vars[i]->m_normalized.compare(r_term->m_right->m_normalized) == 0) {
2520// // Остаток элементов присваивается тому же словарю
2521// l_vars[i]->m_obj = right_obj;
2522// } else {
2523// l_vars[i]->m_obj = right_obj->Clone();
2524// }
2525// l_vars[i]->m_obj->erase(0, l_vars.size() - 1);
2526// } else {
2527// l_vars[i]->m_obj = (*right_obj)[i].second;
2528// }
2529// } else {
2530// if (is_last) {
2531// if (l_vars[i]->m_normalized.compare(r_term->m_right->m_normalized) == 0) {
2532// // Остаток элементов присваивается тому же словарю
2533// l_vars[i]->m_obj = right_obj;
2534// } else {
2535// l_vars[i]->m_obj = right_obj->Clone();
2536// }
2537// l_vars[i]->m_obj->erase(0, 0);
2538// } else {
2539// l_vars[i]->m_obj = Obj::CreateNone();
2540// }
2541// }
2542// // LOG_TEST("2: %s = %s (%p)", l_vars[i]->m_text.c_str(), l_vars[i]->m_obj ? l_vars[i]->m_obj->toString().c_str() : "nullptr", l_vars[i]->m_obj.get());
2543// }
2544// m_latter = l_vars[l_vars.size() - 1]->m_obj;
2545//
2546// } else if (r_term->getTermID() == TermID::FILLING) {
2547// // Заполнение переменных значениями последовательным вызовом фукнции?
2548//
2549// //@todo добавить поддержку многоточия с левой стороный оператора присвоения
2550// NL_PARSER(r_term, "FILLING NOT implemented!");
2551//
2552// } else if (r_term->isBlock()) {
2553//
2554// if (l_vars.size() > 1) {
2555// //@todo добавить поддержку присвоения сразу нескольким функциям
2556// NL_PARSER(r_term, "Multiple function assignment not implemented!");
2557// }
2558// ASSERT(l_vars.size() == 1);
2559//
2560// if (!l_vars[0]->isCall()) {
2561// NL_PARSER(l_vars[0], "Function name expected!");
2562// }
2563//
2564// ASSERT(!l_vars[0]->m_right);
2565//
2566// l_vars[0]->m_obj = m_runtime->CreateFunction(l_vars[0], r_term);
2567// m_latter = l_vars[0]->m_obj;
2568//
2569// } else {
2570//
2571// ArrayTermType r_vars = r_term->CreateArrayFromList();
2572// if (r_vars.empty()) {
2573// // Delete vars
2574// NL_PARSER(r_term, "NOT implemented!");
2575// // m_latter = getNoneObj();
2576//
2577// } else if (r_vars.size() == 1) {
2578//
2579// m_latter = Run(r_vars[0], this);
2580// for (auto &elem : l_vars) {
2581// if (elem->getTermID() == TermID::ELLIPSIS) {
2582// NL_PARSER(elem, "Ellipses unexpected!");
2583// } else if (elem->isNone()) {
2584// NL_PARSER(elem, "None var unexpected!");
2585// } else if (elem->m_right) {
2586//
2587// if (elem->m_right->m_id == TermID::INDEX) {
2588// SetIndexValue(elem, m_latter, this);
2589// } else if (elem->m_right->m_id == TermID::FIELD) {
2590// SetFieldValue(elem, m_latter, this);
2591// } else {
2592// elem->m_obj = m_latter;
2593// // NL_PARSER(elem, "Eval type '%s' not implemented!", toString(elem->m_right->m_id));
2594// }
2595//
2596// } else {
2597// elem->m_obj = m_latter;
2598// }
2599// }
2600//
2601// } else {
2602// // Что присваиваем (правая часть выражения)
2603// // @todo В будущем можно будет сделать сахар для обмена значениями при одинаковом кол-ве объектов у оператора присваивания
2604// // a, b = b, a; a, b, c = c, b, a; и т.д.
2605//
2606// if (l_vars.size() != r_vars.size()) {
2607// NL_PARSER(r_term, "Fail count right values! Expected one or %d.", (int) l_vars.size());
2608// }
2609// for (size_t i = 0; i < l_vars.size(); i++) {
2610// if (l_vars[i]->getTermID() == TermID::ELLIPSIS) {
2611// NL_PARSER(l_vars[i], "Ellipses unexpected!");
2612// } else if (l_vars[i]->isNone()) {
2613// NL_PARSER(l_vars[i], "None var unexpected!");
2614// } else {
2615//
2616// m_latter = Run(r_vars[i], this);
2617// l_vars[i]->m_obj = m_latter;
2618// }
2619// }
2620// }
2621// }
2622//
2623// return m_latter;
2624//}
2625
2627
2628 ASSERT(term->m_right);
2629
2630 TermPtr index = term->m_right;
2631 ASSERT(index->size());
2632
2633 switch (term->m_id) {
2634 case TermID::DICT:
2635 case TermID::STRCHAR:
2636 case TermID::STRWIDE:
2637 if (index->size() > 1) {
2638 NL_PARSER(index, "Strings and dictionaries do not support multiple dimensions!");
2639 }
2640 case TermID::TENSOR:
2641 break;
2642
2643 case TermID::NAME:
2644 case TermID::LOCAL:
2645 case TermID::TYPE:
2646 case TermID::ARGS:
2647 case TermID::ARGUMENT:
2648 case TermID::STATIC:
2649 break;
2650
2651 default:
2652 NL_PARSER(term, "Term type '%s' not indexable!", toString(term->m_id));
2653 }
2654
2655 ObjPtr obj = EvalTerm(term, runner, false).GetVariablePair(true).var.GetValueAsObject();
2656 ASSERT(obj);
2657 ObjPtr ind = EvalTerm(index->at(0).second, runner).GetVariablePair(true).var.GetValueAsObject();
2658 ASSERT(ind);
2659
2660 if (isStringChar(obj->getType())) {
2661
2662 if (canCast(value->getType(), ObjType::Int8)) {
2663 obj->index_set_({ind->GetValueAsInteger()}, value);
2664 } else {
2665 NL_PARSER(term, "Fail cast from '%s' to ':Int8'", toString(value->getType()));
2666 }
2667 return value;
2668
2669 } else if (isStringWide(obj->getType())) {
2670
2671 if (canCast(value->getType(), runner->m_runtime->m_wide_char_type)) {
2672 obj->index_set_({ind->GetValueAsInteger()}, value);
2673 } else {
2674
2675 NL_PARSER(term, "Fail cast from '%s' to '%s'", toString(value->getType()), newlang::toString(runner->m_runtime->m_wide_char_type));
2676 }
2677 return value;
2678 }
2679 NL_PARSER(term, "Index type '%s' not implemented!", toString(obj->getType()));
2680}
2681
2683 ASSERT(term->m_right);
2684
2685 TermPtr index = term->m_right;
2686 ASSERT(index->size());
2687
2688 switch (term->m_id) {
2689 case TermID::DICT:
2690 case TermID::STRCHAR:
2691 case TermID::STRWIDE:
2692 if (index->size() > 1) {
2693 NL_PARSER(index, "Strings and dictionaries do not support multiple dimensions!");
2694 }
2695 case TermID::TENSOR:
2696 break;
2697
2698 case TermID::NAME:
2699 case TermID::LOCAL:
2700 case TermID::TYPE:
2701 case TermID::ARGS:
2702 case TermID::ARGUMENT:
2703 case TermID::STATIC:
2704 break;
2705
2706 default:
2707 NL_PARSER(term, "Term type '%s' not indexable!", toString(term->m_id));
2708 }
2709
2710 ObjPtr ind = EvalTerm(index->at(0).second, runner).GetVariablePair(true).var.GetValueAsObject();
2711 ASSERT(ind);
2712
2713 if (isIndexingType(obj->m_var_type_current, obj->m_var_type_fixed)) {
2714 return obj->index_get({ind->GetValueAsInteger()});
2715 }
2716
2717 NL_PARSER(term, "Index type '%s' not implemented!", toString(obj->getType()));
2718}
2719
2721
2722 NL_PARSER(term, "GetFieldValue not implemented!");
2723}
2724
2726
2727 NL_PARSER(term, "SetFieldValue not implemented!");
2728}
2729
2730/*
2731 *
2732 *
2733 *
2734 */
2735
2737 ASSERT(op);
2738 if (op->m_id == TermID::OP_MATH || op->m_id == TermID::OP_LOGICAL) {
2739 // if(op->m_text.compare(==))
2740 }
2741
2742 NL_PARSER(op, "EvalOpOther '%s' not implemented!", op->m_text.c_str());
2743}
2744
2746 ASSERT(op);
2747 ASSERT(op->m_id == TermID::OP_MATH);
2748 ASSERT(op->m_left);
2749 ASSERT(op->m_right);
2750
2751 ObjPtr result = EvalTerm(op->m_left, runner).GetVariablePair(true).var.GetValueAsObject();
2752 ObjPtr value = EvalTerm(op->m_right, runner).GetVariablePair(true).var.GetValueAsObject();
2753
2754 if (op->m_text.rfind("=") == op->m_text.size() - 2) {
2755 result = result->Clone();
2756 }
2757
2758 if (op->m_text.find("+") == 0) {
2759 // LOG_TEST_DUMP("before: %s + %s", result->GetValueAsString().c_str(), op->m_right->m_obj->GetValueAsString().c_str());
2760 (*result) += value;
2761 // LOG_TEST_DUMP("after: %s + %s", result->GetValueAsString().c_str(), op->m_right->m_obj->GetValueAsString().c_str());
2762 } else if (op->m_text.find("-") == 0) {
2763 (*result) -= value;
2764 } else if (op->m_text.find("*") == 0) {
2765 (*result) *= value;
2766 } else if (op->m_text.find("//") == 0) { // x // y __floordiv__(self, other) x //= y __ifloordiv__(self, other)
2767 result->op_div_ceil_(value);
2768 } else if (op->m_text.find("/") == 0) { // x / y __truediv__(self, other) x /= y __itruediv__(self, other)
2769 (*result) /= value;
2770 } else if (op->m_text.find("%") == 0) {
2771 (*result) %= value;
2772 } else {
2773 NL_PARSER(op, "Math operator '%s' not implemented!", op->m_text.c_str());
2774 }
2775 return result;
2776}
2777
2779 ASSERT(op);
2780 ASSERT(op->m_id == TermID::OP_COMPARE);
2781 ASSERT(op->m_left);
2782 ASSERT(op->m_right);
2783
2784 ObjPtr left = EvalTerm(op->m_left, runner).GetVariablePair(true).var.GetValueAsObject();
2785 ObjPtr right = EvalTerm(op->m_right, runner).GetVariablePair(true).var.GetValueAsObject();
2786
2787 // LOG_TEST("Compare: %s %s %s", op->m_left->m_obj->toString().c_str(), op->m_text.c_str(), op->m_right->m_obj->toString().c_str());
2788
2789 if (op->m_text.compare("==") == 0) {
2790 return Obj::CreateBool(left->op_equal(right));
2791 } else if (op->m_text.compare("!=") == 0) {
2792 return Obj::CreateBool(left->op_equal(right));
2793 } else if (op->m_text.compare("<") == 0) {
2794 return Obj::CreateBool((*left) < right);
2795 } else if (op->m_text.compare("<=") == 0) {
2796 return Obj::CreateBool((*left) <= right);
2797 } else if (op->m_text.compare(">") == 0) {
2798 return Obj::CreateBool((*left) > right);
2799 } else if (op->m_text.compare(">=") == 0) {
2800 return Obj::CreateBool((*left) >= right);
2801 } else if (op->m_text.compare("===") == 0) {
2802 return Obj::CreateBool(left->op_accurate(right));
2803 } else if (op->m_text.compare("!==") == 0) {
2804 return Obj::CreateBool(!left->op_accurate(right));
2805 }
2806 NL_PARSER(op, "Compare operator '%s' not implemented!", op->m_text.c_str());
2807}
2808
2810 ASSERT(term->m_left);
2811 ASSERT(term->m_right);
2812
2813 ObjPtr result;
2814 ObjPtr cond = Eval(term->m_left, this).GetVariablePair(true).var.GetValueAsObject();
2815 if (!cond->GetValueAsBoolean() && !term->m_block.empty()) {
2816 // else
2817 ASSERT(term->m_block.size() == 1);
2818 ASSERT(term->m_block[0]->m_left->m_id == TermID::ELLIPSIS);
2819
2820 m_latter = Eval(term->m_block[0]->m_right, this);
2821
2822 } else {
2823 size_t i = 0;
2824 while (cond->GetValueAsBoolean()) {
2825
2826 result = Eval(term->m_right, this).GetVariablePair(true).var.GetValueAsObject();
2827
2828 // LOG_TEST("while: %d, value: %s", (int) i, result->toString().c_str());
2829
2830 if (isInterrupt(result->getType())) {
2831
2832 if (result->m_value.empty()) {
2833
2834 // Не именованное прерывание -> выход из блока
2835 break;
2836
2837 } else if (CheckTargetScope(result->m_value)) {
2838 if (result->getType() == ObjType::RetPlus) {
2839 result = result->m_return_obj;
2840
2841 // Выход из блока
2842 break;
2843
2844 } else if (result->getType() == ObjType::RetMinus) {
2845 result = result->m_return_obj;
2846
2847 // На начало блока
2848 i = 0;
2849 goto while_continue;
2850
2851 } else {
2852
2853 LOG_RUNTIME("Interrupt type '%s' not implemented!", toString(result->getType()));
2854 }
2855 }
2856 }
2857 i++;
2858
2859while_continue:
2860 cond = Eval(term->m_left, this).GetVariablePair(true).var.GetValueAsObject();
2861 }
2862
2864 }
2865
2866
2867 return m_latter;
2868}
2869
2871 ASSERT(term);
2872 ASSERT(term->m_left);
2873 ASSERT(term->m_right);
2874
2875 ObjPtr result;
2876 ObjPtr cond;
2877 size_t i = 0;
2878 do {
2879
2880 // m_latter
2881 result = Eval(term->m_left, this).GetVariablePair(true).var.GetValueAsObject();
2882
2883 LOG_TEST("dowhile: %d, value: %s", (int) i, result->toString().c_str());
2884
2885 if (isInterrupt(result->getType())) {
2886
2887 if (result->m_value.empty()) {
2888
2889 // Не именованное прерывание -> выход из блока
2890 break;
2891
2892 } else if (CheckTargetScope(result->m_value)) {
2893 if (result->getType() == ObjType::RetPlus) {
2894 result = result->m_return_obj;
2895
2896 // Выход из блока
2897 break;
2898
2899 } else if (result->getType() == ObjType::RetMinus) {
2900 result = result->m_return_obj;
2901
2902 // На начало блока
2903 i = 0;
2904 goto dowhile_continue;
2905
2906 } else {
2907 LOG_RUNTIME("Interrupt type '%s' not implemented!", toString(result->getType()));
2908 }
2909 }
2910 }
2911 i++;
2912
2913dowhile_continue:
2914
2915 cond = Eval(term->m_right, this).GetVariablePair(true).var.GetValueAsObject();
2916
2917 } while (cond->GetValueAsBoolean());
2918
2920
2921 return m_latter;
2922}
2923
2925 /*
2926 * [cond] --> {expr};
2927 * [cond] --> {expr}, [...] --> {else};
2928 *
2929 */
2930
2931 for (int64_t i = 0; i < static_cast<int64_t> (term->m_block.size()); i++) {
2932
2933 ASSERT(term->m_block[i]);
2934 ASSERT(term->m_block[i]->m_left);
2935
2936 bool condition = false;
2937 if (term->m_block[i]->m_left->getTermID() == TermID::ELLIPSIS) {
2938 ASSERT(i + 1 == term->m_block.size());
2939 condition = true;
2940 } else {
2941 ObjPtr cond = Eval(term->m_block[i]->m_left, runner).GetVariablePair(true).var.GetValueAsObject();
2942 condition = cond->GetValueAsBoolean();
2943 }
2944
2945 if (condition) {
2946
2947 return Eval(term->m_block[i]->m_right, runner).GetVariablePair(true).var.GetValueAsObject();
2948 }
2949 }
2950 return Obj::CreateNone();
2951}
2952
2954
2955 if (!m_runtime->m_eval_enable) {
2956 NL_PARSER(term, "The eval operator cannot be used! Use flag: --nlc-eval-enable");
2957 }
2958
2959 /*
2960 * subprocess.run(args, *, stdin=None, input=None, stdout=None, stderr=None,
2961 * capture_output=False, shell=False, cwd=None, timeout=None, check=False,
2962 * encoding=None, errors=None, text=None, env=None, universal_newlines=None, **other_popen_kwargs)
2963 */
2964 /* class subprocess.Popen(args, bufsize = -1, executable = None,
2965 * stdin = None, stdout = None, stderr = None,
2966 * preexec_fn = None, close_fds = True, shell = False, cwd = None,
2967 * env = None, universal_newlines = None, startupinfo = None,
2968 * creationflags = 0, restore_signals = True, start_new_session = False,
2969 * pass_fds = (), *, group = None, extra_groups = None, user = None, umask = -1
2970 * , encoding = None, errors = None, text = None,
2971 * pipesize = -1, process_group = None)¶
2972 */
2973
2974
2975 // we use std::array rather than a C-style array to get all the
2976 // C++ array convenience functions
2977 std::array<char, 128> buffer;
2978 std::string result;
2979
2980 // popen() receives the command and parameter "r" for read,
2981 // since we want to read from a stream.
2982 // by using unique_ptr, the pipe object is automatically cleaned
2983 // from memory once we've read all the data from the pipe.
2984 std::unique_ptr<FILE, decltype(&pclose) > pipe(popen(term->getText().c_str(), "r"), pclose);
2985
2986 while (fgets(buffer.data(), buffer.size(), pipe.get()) != nullptr) {
2987
2988 result += buffer.data();
2989 }
2990
2991 return Obj::CreateString(result);
2992}
2993
2995// * Создание итератора
2996// * ?, ?(), ?("Фильтр"), ?(func), ?(func, args...)
2997// *
2998// * Перебор элементов итератора
2999// * !, !(), !(0), !(3), !(-3)
3000// *
3001// * dict! и dict!(0) эквивалентны
3002// * dict! -> 1, dict! -> 2, dict! -> 3, dict! -> 4, dict! -> 5, dict! -> :IteratorEnd
3003// *
3004// * Различия отрицательного размера возвращаемого словаря для итератора
3005// * dict!(-1) -> (1,), ... dict!(-1) -> (5,), dict!(-1) -> (:IteratorEnd,),
3006// * dict!(1) -> (1,), ... dict!(1) -> (5,), dict!(1) -> (,),
3007// * dict!(-3) -> (1, 2, 3,), dict!(-3) -> (4, 5, :IteratorEnd,)
3008// * dict!(3) -> (1, 2, 3,), dict!(3) -> (4, 5,)
3009// *
3010// * Операторы ?! и !? эквивалентны и возвращают текущие данные без перемещения указателя итератора.
3011// *
3012// * Оператор ?? создает итератор и сразу его выполняет, возвращая все значения
3013// * в виде элементов словаря, т.е. аналог последовательности ?(LINQ); !(:Int64.__max__);
3014// *
3015// * Оператор !! - сбрасывает итератор в начальное состояние и возвращает первый элемент
3016// */
3017//
3018
3020 ASSERT(op);
3021 ASSERT(op->m_left);
3022
3023 ObjPtr object;
3024 if (isReservedName(op->m_left->m_text)) {
3025 if (op->m_left->m_text.compare("$") == 0) {
3026
3027 object = Obj::CreateDict();
3028 // for (auto &scope : * this) {
3029 // for (auto &elem : scope.vars) {
3030 // ASSERT(elem.second.term);
3031 // object->push_back(Obj::CreateString(elem.second.term->m_text));
3032 // }
3033 // }
3034 return object;
3035
3036 // } else if (op->m_left->m_text.compare("@") == 0) {
3037 //
3038 // object = Obj::CreateDict();
3039 // if (m_runtime && m_runtime->m_macro) {
3040 // for (auto &elem : *(m_runtime->m_macro)) {
3041 // object->push_back(Obj::CreateString(elem.first));
3042 // }
3043 // }
3044 // return object;
3045
3046 } else if (op->m_left->m_text.compare("$^") == 0) {
3048 } else if (op->m_left->m_text.compare("@::") == 0) {
3049
3050 // object = Obj::CreateDict();
3051 // for (auto &elem : m_static) {
3052 // object->push_back(Obj::CreateString(elem.first));
3053 // }
3054 // return object;
3055 // // } else if (op->m_left->m_text.compare("%") == 0) {
3056 // // } else if (op->m_left->m_text.compare("$$") == 0) {
3057 // // } else if (op->m_left->m_text.compare("@$") == 0) {
3058 // // }
3059 } else {
3060 NL_PARSER(op, "Eval iterator for reserved word '%s' not implemented!", op->m_left->m_text.c_str());
3061 }
3062 } else {
3063 object = EvalTerm(op->m_left, this).GetVariablePair(true).var.GetValueAsObject();
3064 }
3065
3066 ObjPtr args = CreateArgs_(op, this);
3067
3068 // args->insert(args->begin(), {
3069 // "", object
3070 // });
3071
3072 if (op->m_text.compare("?") == 0) {
3073
3074 return object->IteratorMake(args.get());
3075
3076 } else if (op->m_text.compare("!") == 0) {
3077
3078 ASSERT(!args->size() && "Argument processing not implemented");
3079 return object->IteratorNext(0);
3080
3081 } else if (op->m_text.compare("!!") == 0) {
3082
3083 ASSERT(!args->size() && "Argument processing not implemented");
3084 object->IteratorReset();
3085 return object->IteratorData();
3086
3087 } else if (op->m_text.compare("?!") == 0 || op->m_text.compare("!?") == 0) {
3088
3089 return object->IteratorData();
3090
3091 } else if (op->m_text.compare("??") == 0) {
3092
3093 ObjPtr result;
3094 int64_t val_int = std::numeric_limits<int64_t>::max();
3095 if (args->empty() || (args->size() == 1 && args->at(0).second->is_integer())) {
3096 result = object->IteratorMake(nullptr, false);
3097 if (args->size()) {
3098 val_int = args->at(0).second->GetValueAsInteger();
3099 }
3100 } else if (args->size() == 1 && args->at(0).second->is_string_type()) {
3101 result = object->IteratorMake(args->at(0).second->GetValueAsString().c_str(), false);
3102 } else if (args->size() == 2 && args->at(0).second->is_string_type() && args->at(1).second->is_integer()) {
3103 result = object->IteratorMake(args->at(0).second->GetValueAsString().c_str(), false);
3104 val_int = args->at(1).second->GetValueAsInteger();
3105 } else {
3106
3107 LOG_RUNTIME("Iterator`s args '%s' not allowed!", args->toString().c_str());
3108 }
3109 return result->IteratorNext(val_int);
3110
3111 }
3112 NL_PARSER(op, "Eval iterator '%s' not implemented!", op->m_text.c_str());
3113}
3114
3116
3117 ASSERT(op);
3118 NL_PARSER(op, "Bitwise operator '%s' not implemented!", op->m_text.c_str());
3119}
3120
3142//
3143//
3146
3148 ASSERT(term);
3149 ObjType type;
3150 switch (term->m_id) {
3151 case TermID::INT_PLUS:
3152 type = ObjType::RetPlus;
3153 break;
3154 case TermID::INT_MINUS:
3155 type = ObjType::RetMinus;
3156 break;
3157 case TermID::INT_REPEAT:
3158 type = ObjType::RetRepeat;
3159 break;
3160 default:
3161 NL_PARSER(term, "Term '%s' is not interrupt!", toString(term->m_id));
3162 }
3163 ObjPtr result = Obj::CreateType(type, type, true);
3164 if (term->m_right) {
3165 result->m_return_obj = EvalTerm(term->m_right, this).GetVariablePair(true).var.GetValueAsObject();
3166 } else {
3167 result->m_return_obj = Obj::CreateNone();
3168 }
3169 if (!term->m_namespace || term->m_namespace->m_text.compare("::") == 0) {
3170 switch (type) {
3171 case ObjType::RetPlus:
3172 throw IntPlus(result);
3173 case ObjType::RetMinus:
3174 throw IntMinus(result);
3175 case ObjType::RetRepeat:
3176 NL_PARSER(term, "Type RetRepeat not implemented!");
3177 default:
3178 NL_PARSER(term, "Type '%s' is not interrupt!", toString(type));
3179 }
3180 }
3181 result->m_value = term->m_namespace->m_text;
3182
3183 if (!result->m_value.empty() && result->m_value.rfind("::") != result->m_value.size() - 2) {
3184 result->m_value += "::";
3185 }
3186
3187 return result;
3188}
3189
static std::string ConvertToVFormat_(const std::string_view format, T &args)
Definition analysis.h:115
void EvalLeftVars_(VariablePairList &vars, const TermPtrConst &op)
Definition context.cpp:2346
static ObjPtr EvalOpMath_(TermPtr &op, Context *runner)
Definition context.cpp:2745
static ObjPtr SetFieldValue(TermPtr &term, ObjPtr value, Context *runner)
Definition context.cpp:2725
static ObjPtr EvalOpCompare_(TermPtr &op, Context *runner)
Definition context.cpp:2778
static LatterType Eval(TermPtr ast, Context *runner)
Definition context.cpp:702
LatterType m_latter
Definition context.h:116
static LatterType Execute(Module &module, TermPtr ast, Context *runner)
Definition context.cpp:697
ObjPtr EvalEval_(TermPtr &op)
Definition context.cpp:2953
bool CheckTargetScope(const std::string_view &name)
Definition context.h:189
static LatterType EvalTerm(TermPtr term, Context *runner, bool rvalue=true)
Definition context.cpp:1670
std::string MakeNamespace(int skip, bool is_global)
Definition context.h:202
LatterType EvalDoWhile_(TermPtr &op)
Definition context.cpp:2870
ObjPtr EvalInterrupt_(TermPtr &term)
Definition context.cpp:3147
static ObjPtr CallNative_(Context *runner, Obj &obj, Obj *args=nullptr)
Definition context.cpp:1202
static ObjPtr EvalFollow_(TermPtr &op, Context *runner)
Definition context.cpp:2924
static std::string StringPrintf(std::string_view format, Obj &args)
Definition context.cpp:1634
LatterType EvalTryBlock_(TermPtr &block)
Definition context.cpp:759
static ObjPtr CreateArgs_(TermPtr &term, Context *runner)
Definition context.cpp:1518
LatterType EvalWhile_(TermPtr &op)
Definition context.cpp:2809
VariablePair * FindObject(const std::string_view int_name)
Definition context.cpp:1920
static ObjPtr CreateRange(TermPtr &term, Context *runner)
Definition context.cpp:1543
static bool HasReThrow(TermPtr &block, Context &stack, Obj &obj)
Definition context.cpp:730
static ObjPtr CreateTensor(TermPtr &term, Context *runner)
Definition context.cpp:1563
static std::string StringFormat(std::string_view format, Obj &args)
Definition context.cpp:1595
Context(RunTime *rt)
Definition context.cpp:24
static RunTime * GetRT_(Context *runner)
Definition context.h:226
RunTime * m_runtime
Definition context.h:115
std::string Dump(size_t num=0)
Definition context.cpp:28
LatterType EvalCreateAsValue_(TermPtr &op)
Definition context.cpp:2223
ObjPtr EvalTake_(TermPtr &op)
Definition context.cpp:1896
static ObjPtr EvalOpLogical_(TermPtr &op, Context *runner)
Definition context.cpp:2736
VariablePair * FindLocalVar(const TermPtr &term)
Definition context.h:136
LatterType EvalCreateAsEllipsis_(TermPtr &op)
Definition context.cpp:2147
static ObjPtr Call(Context *runner, Obj &obj, TermPtr &term)
Definition context.cpp:860
LatterType EvalCreateAsFunc_(TermPtr &op)
Definition context.cpp:2112
static ObjPtr CreateDict(TermPtr &term, Context *runner)
Definition context.cpp:1532
static ObjPtr SetIndexValue(TermPtr &term, ObjPtr value, Context *runner)
Definition context.cpp:2626
ObjPtr EvalIterator_(TermPtr &term)
Definition context.cpp:3019
static ObjPtr GetFieldValue(TermPtr &term, ObjPtr &value, Context *runner)
Definition context.cpp:2720
static ObjPtr EvalOpBitwise_(TermPtr &op, Context *runner)
Definition context.cpp:3115
ObjPtr CreateNative_(TermPtr &proto, const char *module, bool lazzy, const char *mangle_name)
Definition context.cpp:1913
LatterType EvalCreate_(TermPtr &op)
Definition context.cpp:2025
LatterType EvalCreateAsFilling_(TermPtr &op)
Definition context.cpp:2217
static ObjPtr GetIndexValue(TermPtr &term, ObjPtr &value, Context *runner)
Definition context.cpp:2682
bool RegisterObject(bool only_new, const std::string_view name, TermPtr term, Variable var)
Definition types.cpp:239
VariablePair * FindObject(const std::string_view name)
Definition types.cpp:287
VariablePair & GetVariablePair(bool editable=false)
Definition context.h:69
static LatterType Create(TermPtr term, D d)
Definition context.h:65
bool is_function_type() const
Definition object.h:525
virtual int64_t size() const
Definition object.h:624
static ObjPtr CreateString(const std::string_view str, Sync *sync=nullptr)
Definition object.h:1596
std::variant< std::monostate, int64_t, double, void *, bool *, int8_t *, int16_t *, int32_t *, int64_t *, float *, double *, NativeData, std::string, TermPtr, Iterator< Obj > > m_var
Definition object.h:1897
Obj::iterator begin()
Definition object.h:756
ObjPtr shared()
Definition object.h:389
ObjPtr toType(ObjType type) const
Definition object.h:1725
ObjType m_var_type_current
Текущий тип значения объекта
Definition object.h:1864
bool is_string_type() const
Definition object.h:481
double GetValueAsNumber() const
Definition object.cpp:1558
std::string GetValueAsString() const
Definition object.cpp:1607
ObjPtr m_dimensions
Размерности для ObjType::Type.
Definition object.h:1878
static ObjPtr CreateBaseType(ObjType type)
Definition object.cpp:2554
ObjType getType()
Definition object.h:423
bool is_type_name() const
Definition object.h:580
ObjPtr Clone(const char *new_name=nullptr) const
Definition object.h:1689
std::string toString(bool deep=true) const
Definition object.cpp:1049
static ObjPtr CreateDict(Sync *sync=nullptr)
Definition object.h:1625
static ObjPtr CreateBool(bool value, Sync *sync=nullptr)
Definition object.h:1528
const TermPtr m_prototype
Описание прототипа функции (или данных)
Definition object.h:1874
static std::enable_if< std::is_same< T, std::string >::value||std::is_same< T, constchar * >::value, ObjPtr >::type CreateValue(T value, Sync *sync=nullptr)
Definition object.h:1562
ObjPtr m_return_obj
Definition object.h:1912
static ObjPtr CreateRational(const Rational &val)
Definition object.h:1437
bool is_dictionary_type() const
Definition object.h:496
bool is_native() const
Definition object.h:530
Obj::const_iterator insert(Obj::const_iterator pos, const PairType &data)
Definition object.h:812
std::string m_value
Содержит байтовую строку или байтовый массив с данными для представления в нативном виде (Struct,...
Definition object.h:1905
int64_t GetValueAsInteger() const
Definition object.cpp:1454
TermPtr m_sequence
Последовательно распарсенных команд для выполнения
Definition object.h:1911
static ObjPtr CreateNone(Sync *sync=nullptr)
Definition object.h:1510
static ObjPtr CreateType(ObjType type, ObjType fixed=ObjType::None, bool is_init=false, Sync *sync=nullptr)
Definition object.h:1376
static ObjPtr CreateNil(Sync *sync=nullptr)
Definition object.h:1524
static ffi_type * m_ffi_type_float
Definition runtime.h:281
static ffi_prep_cif_type * m_ffi_prep_cif
Definition runtime.h:285
static ffi_prep_cif_var_type * m_ffi_prep_cif_var
Definition runtime.h:286
DiagPtr m_diag
Definition runtime.h:402
static std::string Escape(const std::string_view str)
Definition runtime.cpp:2186
static ObjType BaseTypeFromString(RunTime *rt, const std::string_view text, bool *has_error=nullptr)
Definition runtime.cpp:1525
static ffi_call_type * m_ffi_call
Definition runtime.h:287
static ffi_type * m_ffi_type_sint64
Definition runtime.h:280
static ffi_type * m_ffi_type_pointer
Definition runtime.h:283
static ffi_type * m_ffi_type_sint8
Definition runtime.h:274
static ffi_type * m_ffi_type_void
Definition runtime.h:272
static void * GetNativeAddress(void *handle, const std::string_view name)
Definition jit.cpp:2796
static ObjType m_wide_char_type
Definition runtime.h:289
static ffi_type * m_ffi_type_uint8
Definition runtime.h:273
static ffi_type * m_ffi_type_double
Definition runtime.h:282
static ObjPtr CreateNative(const char *proto, const char *module=nullptr, bool lazzy=false, const char *mangle_name=nullptr)
Definition runtime.cpp:1755
static ffi_type * m_ffi_type_sint32
Definition runtime.h:278
static ffi_type * m_ffi_type_sint16
Definition runtime.h:276
static TermPtr CreateIntName(const std::string_view name, const std::string_view int_name, TermID id=TermID::NAME)
Definition term.cpp:38
bool is_object_type() const
Definition variable.cpp:695
Variable Take(bool edit_mode=false, const std::chrono::milliseconds &timeout_duration=Sync::SyncTimeoutDeedlock, const std::string_view message="", const std::source_location location=std::source_location::current()) const
Definition variable.h:610
ObjPtr GetValueAsObject() const
Definition variable.cpp:458
bool is_undefined() const
Definition variable.h:591
ObjType getSummaryTensorType(Obj *obj, ObjType start=ObjType::None)
Definition object.cpp:546
yylloc step()
int result
Definition lexer.l:367
#define LOG_RUNTIME(format,...)
Definition logger.h:26
#define LOG_TEST(...)
Definition logger.h:36
#define ASSERT(condition)
Definition logger.h:60
#define LOG_WARNING(...)
Definition logger.h:121
Definition nlc.h:59
bool isFloatingType(ObjType t)
Definition types.h:732
bool isStringChar(ObjType t)
Definition types.h:759
bool isTypeName(ObjType t)
Definition types.h:804
std::wstring utf8_decode(const std::string str)
Definition variable.cpp:22
bool isStringWide(ObjType t)
Definition types.h:764
bool isInterrupt(ObjType t)
Definition types.h:774
const VariablePair & getNonePair()
Definition parser.cpp:1056
bool isIntegralType(ObjType t, bool includeBool)
Definition types.h:725
std::vector< LatterType > VariablePairList
Definition context.h:109
std::shared_ptr< Term > TermPtr
Definition variable.h:33
int64_t parseInteger(const char *str)
Definition types.h:998
std::shared_ptr< Obj > ObjPtr
Definition variable.h:28
bool isGlobalScope(const std::string_view name)
Definition types.h:1078
double parseDouble(const char *str)
Definition types.h:1012
const ObjPtr getNoneObj()
Definition parser.cpp:1040
bool isReservedName(const std::string_view name)
Definition types.h:1036
const Variable & getNoneVar()
Definition parser.cpp:1044
std::shared_ptr< const Term > TermPtrConst
Definition variable.h:34
std::vector< TermPtr > BlockType
Definition types.h:239
ObjType GetBaseTypeFromString(const std::string_view type_arg, bool *has_error=nullptr)
Definition parser.cpp:1102
ObjType typeFromString(TermPtr &term, RunTime *rt, bool *has_error)
Definition runtime.cpp:2243
bool isIndexingType(ObjType curr, ObjType fix)
Definition types.h:814
ObjType
Definition types.h:524
ObjType typeFromLimit(int64_t value, ObjType type_default=ObjType::Int64)
Definition object.cpp:3788
std::string NormalizeName(const std::string_view name)
Definition types.h:1152
const char * toString(TermID type)
Definition term.h:126
ObjPtr FunctionType(Context *ctx, Obj &in)
Definition types.h:248
bool isDefaultType(const TermPtr &term)
Definition parser.cpp:1060
std::vector< int64_t > TensorShapeFromDict(const Obj *obj)
Definition object.cpp:2132
const ObjPtr getEllipsysObj()
Definition parser.cpp:1048
bool canCast(const ObjType from, const ObjType to)
Definition types.h:967
static VariablePair Create(TermPtr term, Variable d)
Definition types.h:190
#define NL_TYPECHECK(term, from, to)
Definition types.h:333
#define NL_PARSER(term, format,...)
Definition types.h:310
#define NL_CHECK(cond, format,...)
Definition types.h:326