From 64b38b639485a3457515e097e89a4e71ae8c818a Mon Sep 17 00:00:00 2001 From: Aleksandr Ryabikov Date: Fri, 24 Jun 2022 12:57:24 +0300 Subject: [PATCH 01/31] Fix build for CPU torch lib --- contrib/build.sh | 7 +++++++ core/nbproject/Makefile-LLVM.mk | 20 +++++++++++++++++++- core/nbproject/Makefile-UnitTest.mk | 2 +- core/nbproject/Makefile-UnitTest_LLVM.mk | 20 +++++++++++++++++++- core/nbproject/configurations.xml | 2 -- 5 files changed, 46 insertions(+), 5 deletions(-) diff --git a/contrib/build.sh b/contrib/build.sh index acd25b6e..199e6b04 100755 --- a/contrib/build.sh +++ b/contrib/build.sh @@ -4,3 +4,10 @@ cd libffi make make install cd .. + +cd text2cpp +./autogen.sh +./configure --prefix=`pwd`/output +make +make install +cd .. diff --git a/core/nbproject/Makefile-LLVM.mk b/core/nbproject/Makefile-LLVM.mk index 6726aa14..fb756104 100644 --- a/core/nbproject/Makefile-LLVM.mk +++ b/core/nbproject/Makefile-LLVM.mk @@ -46,7 +46,9 @@ OBJECTFILES= \ ${OBJECTDIR}/object.o \ ${OBJECTDIR}/parser.o \ ${OBJECTDIR}/parser.yy.o \ + ${OBJECTDIR}/syntax_help.o \ ${OBJECTDIR}/term.o \ + ${OBJECTDIR}/test/alg_test.o \ ${OBJECTDIR}/test/eval_test.o \ ${OBJECTDIR}/test/fraction_test.o \ ${OBJECTDIR}/test/lexer_test.o \ @@ -54,7 +56,8 @@ OBJECTFILES= \ ${OBJECTDIR}/test/nlc_test.o \ ${OBJECTDIR}/test/object_test.o \ ${OBJECTDIR}/test/parser_test.o \ - ${OBJECTDIR}/variable.o + ${OBJECTDIR}/variable.o \ + ${OBJECTDIR}/version.o # C Compiler Flags @@ -156,6 +159,11 @@ ${OBJECTDIR}/parser.yy.o: parser.yy.cpp parser.y @echo Выполнение шага пользовательского сборки +${OBJECTDIR}/syntax_help.o: syntax_help.cpp + ${MKDIR} -p ${OBJECTDIR} + ${RM} "$@.d" + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I/usr/lib/llvm-12/lib/clang/12.0.1/include -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I.. -std=c++14 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/syntax_help.o syntax_help.cpp + ${OBJECTDIR}/term.o: term.cpp ${MKDIR} -p ${OBJECTDIR} ${RM} "$@.d" @@ -165,6 +173,11 @@ ${OBJECTDIR}/term.o: term.cpp @echo Выполнение шага пользовательского сборки +${OBJECTDIR}/test/alg_test.o: test/alg_test.cpp + ${MKDIR} -p ${OBJECTDIR}/test + ${RM} "$@.d" + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I/usr/lib/llvm-12/lib/clang/12.0.1/include -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I.. -std=c++14 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/alg_test.o test/alg_test.cpp + ${OBJECTDIR}/test/eval_test.o: test/eval_test.cpp ${MKDIR} -p ${OBJECTDIR}/test ${RM} "$@.d" @@ -205,6 +218,11 @@ ${OBJECTDIR}/variable.o: variable.cpp ${RM} "$@.d" $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I/usr/lib/llvm-12/lib/clang/12.0.1/include -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I.. -std=c++14 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/variable.o variable.cpp +${OBJECTDIR}/version.o: version.c + ${MKDIR} -p ${OBJECTDIR} + ${RM} "$@.d" + $(COMPILE.c) -g -s -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DUMP -DUNITTEST -I/usr/local/include -I/usr/include/x86_64-linux-gnu/c++/10 -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I.. -std=c11 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/version.o version.c + : warning_pop.h parser.yy.cpp location.hh @echo Выполнение шага пользовательского сборки diff --git a/core/nbproject/Makefile-UnitTest.mk b/core/nbproject/Makefile-UnitTest.mk index 3496ffda..600fa49c 100644 --- a/core/nbproject/Makefile-UnitTest.mk +++ b/core/nbproject/Makefile-UnitTest.mk @@ -75,7 +75,7 @@ FFLAGS= ASFLAGS= # Link Libraries and Options -LDLIBSOPTIONS=-L../contrib/libtorch/lib -Wl,-rpath,'../contrib/libtorch/lib' -lpthread -ldl ../contrib/libffi/output/lib/libffi.a -lcrypto -lLLVM-13 -ltorch -lc10 -lc10_cuda -ltorch_cpu -ltorch_cuda +LDLIBSOPTIONS=-L../contrib/libtorch/lib -Wl,-rpath,'../contrib/libtorch/lib' -lpthread -ldl ../contrib/libffi/output/lib/libffi.a -lcrypto -lLLVM-13 -ltorch -lc10 -ltorch_cpu # Build Targets .build-conf: ${BUILD_SUBPROJECTS} diff --git a/core/nbproject/Makefile-UnitTest_LLVM.mk b/core/nbproject/Makefile-UnitTest_LLVM.mk index a0e1fe84..e2351714 100644 --- a/core/nbproject/Makefile-UnitTest_LLVM.mk +++ b/core/nbproject/Makefile-UnitTest_LLVM.mk @@ -47,7 +47,9 @@ OBJECTFILES= \ ${OBJECTDIR}/object.o \ ${OBJECTDIR}/parser.o \ ${OBJECTDIR}/parser.yy.o \ + ${OBJECTDIR}/syntax_help.o \ ${OBJECTDIR}/term.o \ + ${OBJECTDIR}/test/alg_test.o \ ${OBJECTDIR}/test/eval_test.o \ ${OBJECTDIR}/test/fraction_test.o \ ${OBJECTDIR}/test/lexer_test.o \ @@ -55,7 +57,8 @@ OBJECTFILES= \ ${OBJECTDIR}/test/nlc_test.o \ ${OBJECTDIR}/test/object_test.o \ ${OBJECTDIR}/test/parser_test.o \ - ${OBJECTDIR}/variable.o + ${OBJECTDIR}/variable.o \ + ${OBJECTDIR}/version.o # C Compiler Flags @@ -162,6 +165,11 @@ ${OBJECTDIR}/parser.yy.o: parser.yy.cpp parser.y @echo Выполнение шага пользовательского сборки +${OBJECTDIR}/syntax_help.o: syntax_help.cpp + ${MKDIR} -p ${OBJECTDIR} + ${RM} "$@.d" + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I/usr/lib/llvm-12/lib/clang/12.0.1/include -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I.. -std=c++14 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/syntax_help.o syntax_help.cpp + ${OBJECTDIR}/term.o: term.cpp ${MKDIR} -p ${OBJECTDIR} ${RM} "$@.d" @@ -171,6 +179,11 @@ ${OBJECTDIR}/term.o: term.cpp @echo Выполнение шага пользовательского сборки +${OBJECTDIR}/test/alg_test.o: test/alg_test.cpp + ${MKDIR} -p ${OBJECTDIR}/test + ${RM} "$@.d" + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I/usr/lib/llvm-12/lib/clang/12.0.1/include -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I.. -std=c++14 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/alg_test.o test/alg_test.cpp + ${OBJECTDIR}/test/eval_test.o: test/eval_test.cpp ${MKDIR} -p ${OBJECTDIR}/test ${RM} "$@.d" @@ -211,6 +224,11 @@ ${OBJECTDIR}/variable.o: variable.cpp ${RM} "$@.d" $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I/usr/lib/llvm-12/lib/clang/12.0.1/include -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I.. -std=c++14 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/variable.o variable.cpp +${OBJECTDIR}/version.o: version.c + ${MKDIR} -p ${OBJECTDIR} + ${RM} "$@.d" + $(COMPILE.c) -g -s -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DUMP -DUNITTEST -I/usr/local/include -I/usr/include/x86_64-linux-gnu/c++/10 -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I.. -std=c11 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/version.o version.c + : warning_pop.h parser.yy.cpp location.hh @echo Выполнение шага пользовательского сборки diff --git a/core/nbproject/configurations.xml b/core/nbproject/configurations.xml index 89280023..f9cefb1f 100644 --- a/core/nbproject/configurations.xml +++ b/core/nbproject/configurations.xml @@ -597,9 +597,7 @@ LLVM-13 torch c10 - c10_cuda torch_cpu - torch_cuda -Wl,--export-dynamic From ac4c4a54c6c29c28a824dc00650ea68e9e32533e Mon Sep 17 00:00:00 2001 From: Aleksandr Ryabikov Date: Fri, 24 Jun 2022 23:18:39 +0300 Subject: [PATCH 02/31] =?UTF-8?q?=D0=97=D0=B0=D0=B3=D0=BE=D1=82=D0=BE?= =?UTF-8?q?=D0=B2=D0=BA=D0=B0=20=D0=B4=D0=BB=D1=8F=20=D0=BC=D0=B0=D0=BA?= =?UTF-8?q?=D1=80=D0=BE=D1=81=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/context.cpp | 371 +++++++++-------- core/context.h | 650 ++++++++++++++--------------- core/object.cpp | 849 +++++++++++++++++++------------------- core/object.h | 4 +- core/parser.h | 100 +++++ core/parser.y | 20 +- core/test/parser_test.cpp | 95 ++++- core/types.h | 6 +- 8 files changed, 1162 insertions(+), 933 deletions(-) diff --git a/core/context.cpp b/core/context.cpp index 9ae06c7c..da397910 100644 --- a/core/context.cpp +++ b/core/context.cpp @@ -6,6 +6,7 @@ #include #include #include +#include using namespace newlang; @@ -41,26 +42,27 @@ std::map Context::m_ops; std::map Context::m_builtin_calls; std::map Context::m_types; std::map Context::m_funcs; +std::map Context::m_macros; Context::Context(RuntimePtr global) { m_runtime = global; - if (Context::m_funcs.empty()) { - Context::m_funcs["min"] = CreateBuiltin("min(arg, ...)", (void *) &min, ObjType::TRANSPARENT); - Context::m_funcs["мин"] = Context::m_funcs["min"]; + if(Context::m_funcs.empty()) { - Context::m_funcs["max"] = CreateBuiltin("max(arg, ...)", (void *) &max, ObjType::TRANSPARENT); - Context::m_funcs["макс"] = Context::m_funcs["max"]; + VERIFY(CreateBuiltin("min(arg, ...)", (void *) &min, ObjType::TRANSPARENT)); + VERIFY(CreateBuiltin("мин(arg, ...)", (void *) &min, ObjType::TRANSPARENT)); + VERIFY(CreateBuiltin("max(arg, ...)", (void *) &max, ObjType::TRANSPARENT)); + VERIFY(CreateBuiltin("макс(arg, ...)", (void *) &max, ObjType::TRANSPARENT)); - Context::m_funcs["import"] = CreateBuiltin("import(arg, module='', lazzy=0)", (void *) &import, ObjType::FUNCTION); + VERIFY(CreateBuiltin("import(arg, module='', lazzy=0)", (void *) &import, ObjType::FUNCTION)); - Context::m_funcs["eval"] = CreateBuiltin("eval(string:String)", (void *) &eval, ObjType::FUNCTION); - Context::m_funcs["exec"] = CreateBuiltin("exec(filename:String)", (void *) &exec, ObjType::FUNCTION); - Context::m_funcs["help"] = CreateBuiltin("help(...)", (void *) &help, ObjType::TRANSPARENT); + VERIFY(CreateBuiltin("eval(string:String)", (void *) &eval, ObjType::FUNCTION)); + VERIFY(CreateBuiltin("exec(filename:String)", (void *) &exec, ObjType::FUNCTION)); + VERIFY(CreateBuiltin("help(...)", (void *) &help, ObjType::TRANSPARENT)); } - if (Context::m_types.empty()) { + if(Context::m_types.empty()) { VERIFY(RegisterTypeHierarchy(ObjType::None,{})); VERIFY(RegisterTypeHierarchy(ObjType::Any,{})); @@ -134,7 +136,7 @@ Context::Context(RuntimePtr global) { } - if (Context::m_builtin_calls.empty()) { + if(Context::m_builtin_calls.empty()) { #define REGISTER_FUNC(name, func) \ ASSERT(Context::m_builtin_calls.find(name) == Context::m_builtin_calls.end()); \ Context::m_builtin_calls[name] = &Context::func_##func; @@ -144,7 +146,7 @@ Context::Context(RuntimePtr global) { #undef REGISTER_FUNC } - if (Context::m_ops.empty()) { + if(Context::m_ops.empty()) { #define REGISTER_OP(op, func) \ ASSERT(Context::m_ops.find(op) == Context::m_ops.end()); \ Context::m_ops[op] = &Context::op_##func; @@ -155,7 +157,7 @@ Context::Context(RuntimePtr global) { } } -ObjPtr Context::CreateBuiltin(const char *prototype, void *func, ObjType type) { +bool Context::CreateBuiltin(const char *prototype, void *func, ObjType type) { ASSERT(prototype); ASSERT(func); @@ -163,18 +165,25 @@ ObjPtr Context::CreateBuiltin(const char *prototype, void *func, ObjType type) { func_dump += " := {};"; TermPtr proto = Parser::ParseString(func_dump); - ObjPtr obj = - Obj::CreateFunc(this, proto->Left(), type, - proto->Left()->getName().empty() ? proto->Left()->getText() : proto->Left()->getName()); + ASSERT(proto->Left() && !proto->Left()->getText().empty()); + ObjPtr obj = Obj::CreateFunc(this, proto->Left(), type, proto->Left()->getText()); + obj->m_func_ptr = func; obj->m_var_is_init = true; - return obj; + auto found = m_funcs.find(proto->Left()->getText()); + if(found != m_funcs.end()) { + LOG_DEBUG("Buildin function %s already exists!", proto->Left()->toString().c_str()); + return false; + } + + Context::m_funcs[proto->Left()->getText()] = obj; + return true; } inline ObjType newlang::typeFromString(const std::string type, Context *ctx, bool *has_error) { - if (ctx) { + if(ctx) { return ctx->BaseTypeFromString(type, has_error); } @@ -183,15 +192,15 @@ inline ObjType newlang::typeFromString(const std::string type, Context *ctx, boo return ObjType:: name; \ } - if (type.empty()) { + if(type.empty()) { return ObjType::None; - } else if (type.compare("_") == 0) { + } else if(type.compare("_") == 0) { return ObjType::None; } NL_TYPES(DEFINE_CASE) #undef DEFINE_CASE - if (has_error) { + if(has_error) { *has_error = true; return ObjType::None; @@ -200,16 +209,16 @@ inline ObjType newlang::typeFromString(const std::string type, Context *ctx, boo } ObjPtr Context::RegisterObject(ObjPtr var) { - if (!var || var->getName().empty()) { + if(!var || var->getName().empty()) { LOG_RUNTIME("Empty object name %s", var ? var->toString().c_str() : ""); } ASSERT(var->m_namespace.empty()); - if (isGlobal(var->getName())) { + if(isGlobal(var->getName())) { var->getName() = var->getName().substr(1); m_global_terms.push_back(var, var->getName()); } - if (isLocal(var->getName())) { + if(isLocal(var->getName())) { var->getName() = var->getName().substr(1); } push_back(var, var->getName()); @@ -232,7 +241,7 @@ ObjPtr Context::ExecStr(Context *ctx, TermPtr term, Obj *args) { // auto previous_handler = signal(SIGABRT, &NewLangSignalHandler); // try { - switch (term->m_id) { + switch(term->m_id) { case TermID::END: return eval_END(ctx, term, args); @@ -456,7 +465,7 @@ ObjPtr Context::CREATE_OR_ASSIGN(Context *ctx, const TermPtr &term, Obj *local_v std::vector list_obj; // Список реальных переменных ассоциированных с терминами TermPtr next = term->Left(); - while (next && next->getTermID() != TermID::END) { + while(next && next->getTermID() != TermID::END) { list_term.push_back(next); next = next->m_comma_seq; } @@ -465,41 +474,41 @@ ObjPtr Context::CREATE_OR_ASSIGN(Context *ctx, const TermPtr &term, Obj *local_v bool is_ellipsis = false; for (auto & elem : list_term) { - if (elem->getTermID() == TermID::ELLIPSIS) { + if(elem->getTermID() == TermID::ELLIPSIS) { //@todo добавить поддержку многоточия с левой стороный оператора присвоения NL_PARSER(elem, "Ellipsis on the left side in assignment not implemented!"); - if (is_ellipsis) { + if(is_ellipsis) { NL_PARSER(elem, "Multiple ellipsis on the left side of the assignment!"); } is_ellipsis = true; result = Obj::CreateType(ObjType::Ellipsis); - } else if (elem->getTermID() == TermID::NONE) { + } else if(elem->getTermID() == TermID::NONE) { result = Obj::CreateNone(); } else { auto found = ctx->select(elem->m_text); - if (found.complete() && mode == CreateMode::ASSIGN_ONLY) { + if(found.complete() && mode == CreateMode::ASSIGN_ONLY) { NL_PARSER(elem, "Variable '%s' not found!", elem->m_text.c_str()); } - if (!found.complete()) { + if(!found.complete()) { result = (*found).lock(); // Но она может быть возвращена как локальная } - if (result && mode == CreateMode::CREATE_ONLY) { + if(result && mode == CreateMode::CREATE_ONLY) { NL_PARSER(elem, "Variable '%s' already exists!", elem->m_text.c_str()); } - if (!term->Right()) { // Удаление глобальной переменной + if(!term->Right()) { // Удаление глобальной переменной ctx->erase(found); } else { - if (!result && (mode == CreateMode::ASSIGN_ONLY)) { + if(!result && (mode == CreateMode::ASSIGN_ONLY)) { NL_PARSER(term->Left(), "Object '%s' not found!", term->Left()->m_text.c_str()); } - if (!result) { + if(!result) { result = CreateLVal(ctx, elem, local_vars); - if (!result) { + if(!result) { NL_PARSER(term->Left(), "Fail create lvalue object!"); } } @@ -508,7 +517,7 @@ ObjPtr Context::CREATE_OR_ASSIGN(Context *ctx, const TermPtr &term, Obj *local_v list_obj.push_back(result); } - if (!term->Right()) { + if(!term->Right()) { // Для удаления переменных все сделано return result; } @@ -516,38 +525,38 @@ ObjPtr Context::CREATE_OR_ASSIGN(Context *ctx, const TermPtr &term, Obj *local_v // Что присваиваем (правая часть выражения) - пока единичный объект // @todo В будущем можно будет сделать сахар для обмена значениями при одинаковом кол-ве объектов у оператора присваивания // a, b = b, a; a, b, c = c, b, a; и т.д. - if (term->Right() && term->Right()->getTermID() != TermID::ELLIPSIS && term->Right()->m_comma_seq) { + if(term->Right() && term->Right()->getTermID() != TermID::ELLIPSIS && term->Right()->m_comma_seq) { NL_PARSER(term->Right()->Right(), "Multiple assignments not implemented!"); } ObjPtr rval; - if (term->Right()->getTermID() == TermID::ELLIPSIS) { + if(term->Right()->getTermID() == TermID::ELLIPSIS) { ASSERT(term->Right()->Right()); rval = ExecStr(ctx, term->Right()->Right(), local_vars); } else { rval = ExecStr(ctx, term->Right(), local_vars); } - if (!rval) { + if(!rval) { NL_PARSER(term->Right(), "Object is missing or expression is not evaluated!"); } ASSERT(list_obj.size() == list_term.size()); - if (term->Right()->getTermID() == TermID::ELLIPSIS) { - if (rval->is_dictionary_type() || rval->is_tensor()) { - if (rval->is_scalar()) { + if(term->Right()->getTermID() == TermID::ELLIPSIS) { + if(rval->is_dictionary_type() || rval->is_tensor()) { + if(rval->is_scalar()) { LOG_RUNTIME("Fail expand scalar!"); } for (int i = 0; i < list_obj.size() - 1; i++) { - if (list_term[i]->getTermID() != TermID::NONE) { - if (i < rval->size()) { + if(list_term[i]->getTermID() != TermID::NONE) { + if(i < rval->size()) { list_obj[i]->SetValue_((*rval)[i]); //->Clone() } else { list_obj[i]->SetValue_(Obj::CreateNone()); } } } - if (list_obj.size() - 1 < rval->size()) { + if(list_obj.size() - 1 < rval->size()) { // Удалить первые элементы rval->resize_(-(rval->size() - (list_obj.size() - 1)), nullptr); } else { @@ -564,10 +573,10 @@ ObjPtr Context::CREATE_OR_ASSIGN(Context *ctx, const TermPtr &term, Obj *local_v // Присвоеить единственное значение всем элементам с левой стороны оператора присовения for (int i = 0; i < list_obj.size(); i++) { - if (isType(list_term[i]->m_text)) { + if(isType(list_term[i]->m_text)) { // Новый тип - if (ctx->m_types.find(list_term[i]->m_text) != ctx->m_types.end()) { + if(ctx->m_types.find(list_term[i]->m_text) != ctx->m_types.end()) { LOG_RUNTIME("Type name '%s' already exists!", list_term[i]->m_text.c_str()); } @@ -578,11 +587,11 @@ ObjPtr Context::CREATE_OR_ASSIGN(Context *ctx, const TermPtr &term, Obj *local_v ctx->m_types[list_term[i]->m_text] = result; - } else if (list_term[i]->getTermID() == TermID::NONE) { + } else if(list_term[i]->getTermID() == TermID::NONE) { // Skip } else { list_obj[i]->SetValue_(rval); - if (list_obj[i]->m_var_type_current == ObjType::FUNCTION && (rval->m_var_type_current == ObjType::BLOCK || rval->m_var_type_current == ObjType::BLOCK_TRY)) { + if(list_obj[i]->m_var_type_current == ObjType::FUNCTION && (rval->m_var_type_current == ObjType::BLOCK || rval->m_var_type_current == ObjType::BLOCK_TRY)) { list_obj[i]->m_var_type_current = ObjType::EVAL_FUNCTION; } result = list_obj[i]; @@ -621,8 +630,8 @@ ObjPtr Context::eval_FUNCTION(Context *ctx, const TermPtr &term, Obj * args) { ASSERT(ctx); auto found = ctx->select(term->Left()->m_text); - if (!term->Right()) { - if (!found.complete()) { + if(!term->Right()) { + if(!found.complete()) { ctx->erase(found); return Obj::Yes(); } @@ -630,22 +639,22 @@ ObjPtr Context::eval_FUNCTION(Context *ctx, const TermPtr &term, Obj * args) { } ObjPtr lval = CreateLVal(ctx, term->Left(), args); - if (!lval) { + if(!lval) { NL_PARSER(term->Left(), "Fail create lvalue object!"); } - if (term->Right()->getTermID() == TermID::CALL) { + if(term->Right()->getTermID() == TermID::CALL) { lval->SetValue_(CreateRVal(ctx, term->Right())); } else { - if (term->getTermID() == TermID::FUNCTION) { + if(term->getTermID() == TermID::FUNCTION) { lval->m_var_type_current = ObjType::EVAL_FUNCTION; - } else if (term->getTermID() == TermID::TRANSPARENT) { + } else if(term->getTermID() == TermID::TRANSPARENT) { lval->m_var_type_current = ObjType::SimplePureFunc; - } else if (term->getTermID() == TermID::SIMPLE_AND) { + } else if(term->getTermID() == TermID::SIMPLE_AND) { lval->m_var_type_current = ObjType::SimplePureAND; - } else if (term->getTermID() == TermID::SIMPLE_OR) { + } else if(term->getTermID() == TermID::SIMPLE_OR) { lval->m_var_type_current = ObjType::SimplePureOR; - } else if (term->getTermID() == TermID::SIMPLE_XOR) { + } else if(term->getTermID() == TermID::SIMPLE_XOR) { lval->m_var_type_current = ObjType::SimplePureXOR; } else { @@ -723,7 +732,7 @@ ObjPtr Context::eval_WHILE(Context *ctx, const TermPtr &term, Obj * args) { ObjPtr result = Obj::CreateNone(); ObjPtr cond = ExecStr(ctx, term->Left(), args); - while (cond->GetValueAsBoolean()) { + while(cond->GetValueAsBoolean()) { result = CreateRVal(ctx, term->Right(), args); cond = ExecStr(ctx, term->Left(), args); @@ -740,7 +749,7 @@ ObjPtr Context::eval_UNTIL(Context *ctx, const TermPtr &term, Obj * args) { do { result = CreateRVal(ctx, term->Left(), args); cond = ExecStr(ctx, term->Right(), args); - } while (cond->GetValueAsBoolean()); + } while(cond->GetValueAsBoolean()); return result; } @@ -758,7 +767,7 @@ ObjPtr Context::eval_FOLLOW(Context *ctx, const TermPtr &term, Obj * args) { ASSERT(term->m_follow[i]->Left()); ObjPtr cond = ExecStr(ctx, term->m_follow[i]->Left(), args); - if (cond->GetValueAsBoolean() || (i + 1 == term->m_follow.size() && cond->is_none_type())) { + if(cond->GetValueAsBoolean() || (i + 1 == term->m_follow.size() && cond->is_none_type())) { return CreateRVal(ctx, term->m_follow[i]->Right(), args); } @@ -767,7 +776,7 @@ ObjPtr Context::eval_FOLLOW(Context *ctx, const TermPtr &term, Obj * args) { } bool Context::MatchCompare(Obj &match, ObjPtr &value, MatchMode mode, Context *ctx) { - switch (mode) { + switch(mode) { case MatchMode::EQUAL: return match.op_equal(value); case MatchMode::STRICT: @@ -787,7 +796,7 @@ bool Context::MatchEstimate(Obj &match, const TermPtr &match_item, MatchMode mod ObjPtr cond = CreateRVal(ctx, match_item, args); - if (cond->is_none_type() || MatchCompare(match, cond, mode, ctx)) { + if(cond->is_none_type() || MatchCompare(match, cond, mode, ctx)) { return true; } else { for (int i = 0; i < match_item->m_follow.size(); i++) { @@ -795,7 +804,7 @@ bool Context::MatchEstimate(Obj &match, const TermPtr &match_item, MatchMode mod ASSERT(match_item->m_follow[i]); cond = CreateRVal(ctx, match_item->m_follow[i], args); - if (cond->is_none_type() || MatchCompare(match, cond, mode, ctx)) { + if(cond->is_none_type() || MatchCompare(match, cond, mode, ctx)) { return true; } @@ -817,15 +826,15 @@ ObjPtr Context::eval_MATCHING(Context *ctx, const TermPtr &term, Obj * args) { ASSERT(term->Right()); MatchMode mode; - if (term->m_text.compare("==>") == 0) { + if(term->m_text.compare("==>") == 0) { mode = MatchMode::EQUAL; - } else if (term->m_text.compare("===>") == 0) { + } else if(term->m_text.compare("===>") == 0) { mode = MatchMode::STRICT; - } else if (term->m_text.compare("~>") == 0) { + } else if(term->m_text.compare("~>") == 0) { mode = MatchMode::TYPE_NAME; - } else if (term->m_text.compare("~~>") == 0) { + } else if(term->m_text.compare("~~>") == 0) { mode = MatchMode::TYPE_EQUAL; - } else if (term->m_text.compare("~~~>") == 0) { + } else if(term->m_text.compare("~~~>") == 0) { mode = MatchMode::TYPE_STRICT; } else { NL_PARSER(term, "Unknown pattern matching type!"); @@ -840,7 +849,7 @@ ObjPtr Context::eval_MATCHING(Context *ctx, const TermPtr &term, Obj * args) { ObjPtr cond = CreateRVal(ctx, list->Left(), args); - if (MatchEstimate(*cond.get(), list->Left(), mode, ctx, args)) { + if(MatchEstimate(*cond.get(), list->Left(), mode, ctx, args)) { return CreateRVal(ctx, list->Right(), args); } else { for (int i = 0; i < list->m_block.size(); i++) { @@ -848,7 +857,7 @@ ObjPtr Context::eval_MATCHING(Context *ctx, const TermPtr &term, Obj * args) { ASSERT(list->m_block[i]->Left()); ASSERT(list->m_block[i]->Right()); - if (MatchEstimate(*cond.get(), list->m_block[i]->Left(), mode, ctx, args)) { + if(MatchEstimate(*cond.get(), list->m_block[i]->Left(), mode, ctx, args)) { return CreateRVal(ctx, list->m_block[i]->Right(), args); } @@ -886,7 +895,7 @@ ObjPtr Context::eval_SOURCE(Context *ctx, const TermPtr &term, Obj * args) { */ ObjPtr Context::eval_OPERATOR(Context *ctx, const TermPtr &term, Obj * args) { - if (Context::m_ops.find(term->m_text) == Context::m_ops.end()) { + if(Context::m_ops.find(term->m_text) == Context::m_ops.end()) { LOG_RUNTIME("Eval op '%s' not exist!", term->m_text.c_str()); } @@ -1022,7 +1031,7 @@ ObjPtr Context::op_BIT_XOR_(Context *ctx, const TermPtr &term, Obj * args) { ObjPtr Context::op_PLUS(Context *ctx, const TermPtr &term, Obj * args) { ASSERT(term); ASSERT(term->Right()); - if (term->Left()) { + if(term->Left()) { return ExecStr(ctx, term->Left(), args)->operator+(ExecStr(ctx, term->Right(), args)); } @@ -1032,7 +1041,7 @@ ObjPtr Context::op_PLUS(Context *ctx, const TermPtr &term, Obj * args) { ObjPtr Context::op_MINUS(Context *ctx, const TermPtr &term, Obj * args) { ASSERT(term); ASSERT(term->Right()); - if (term->Left()) { + if(term->Left()) { return ExecStr(ctx, term->Left(), args)->operator-(ExecStr(ctx, term->Right(), args)); } @@ -1152,7 +1161,7 @@ ObjPtr Context::op_TYPE_EQ(Context *ctx, const TermPtr &term, Obj * args) { ASSERT(term->Left()); ASSERT(term->Right()); - if (isType(term->Right()->GetFullName())) { + if(isType(term->Right()->GetFullName())) { return Obj::CreateBool(ExecStr(ctx, term->Left(), args)->op_class_test(term->Right()->GetFullName().c_str(), ctx)); } return Obj::CreateBool(ExecStr(ctx, term->Left(), args)->op_class_test(ExecStr(ctx, term->Right(), args), ctx)); @@ -1178,7 +1187,7 @@ ObjPtr Context::op_TYPE_NE(Context *ctx, const TermPtr &term, Obj * args) { ASSERT(term); ASSERT(term->Left()); ASSERT(term->Right()); - if (isType(term->Right()->GetFullName())) { + if(isType(term->Right()->GetFullName())) { return Obj::CreateBool(!ExecStr(ctx, term->Left(), args)->op_class_test(term->Right()->GetFullName().c_str(), ctx)); } return Obj::CreateBool(!ExecStr(ctx, term->Left(), args)->op_class_test(ExecStr(ctx, term->Right(), args), ctx)); @@ -1255,8 +1264,8 @@ ObjPtr Context::eval_EXIT(Context *ctx, const TermPtr &term, Obj * args) { ObjPtr ret = nullptr; bool is_return_data = (bool)term->Right(); - if (is_return_data) { - if (isType(term->Right()->GetFullName())) { + if(is_return_data) { + if(isType(term->Right()->GetFullName())) { ret = CreateRVal(ctx, term->Right(), args); } else { ret = ctx->GetTypeFromString(Interrupt::Return); @@ -1273,7 +1282,7 @@ ObjPtr Context::eval_EXIT(Context *ctx, const TermPtr &term, Obj * args) { ObjPtr Context::CallBlock(Context *ctx, const TermPtr &block, Obj * local_vars) { ObjPtr result = Obj::CreateNone(); ASSERT(block); - if (!block->m_block.empty()) { + if(!block->m_block.empty()) { for (size_t i = 0; i < block->m_block.size(); i++) { result = ExecStr(ctx, block->m_block[i], local_vars); } @@ -1292,16 +1301,16 @@ ObjPtr Context::CallBlockTry(Context *ctx, const TermPtr &block, Obj * local_var ASSERT(obj.m_obj); - if (!block->m_class_name.empty()) { + if(!block->m_class_name.empty()) { type_return = block->m_class_name; } - if (obj.m_obj->op_class_test(type_return.c_str(), ctx)) { - if (block->m_class_name.empty()) { + if(obj.m_obj->op_class_test(type_return.c_str(), ctx)) { + if(block->m_class_name.empty()) { // Только при возврате значения :Return ASSERT(obj.m_obj->size() == 1); return (*obj.m_obj)[0]; } - } else if (!block->m_class_name.empty()) { + } else if(!block->m_class_name.empty()) { throw; // Объект возврата не соответствует требуемому типу } result = obj.m_obj; @@ -1311,17 +1320,17 @@ ObjPtr Context::CallBlockTry(Context *ctx, const TermPtr &block, Obj * local_var ObjPtr Context::EvalBlockAND(Context *ctx, const TermPtr &block, Obj * local_vars) { ObjPtr result = nullptr; - if (block->GetTokenID() == TermID::BLOCK) { + if(block->GetTokenID() == TermID::BLOCK) { for (size_t i = 0; i < block->m_block.size(); i++) { result = ExecStr(ctx, block->m_block[i], local_vars); - if (!result || !result->GetValueAsBoolean()) { + if(!result || !result->GetValueAsBoolean()) { return Obj::No(); } } } else { result = ExecStr(ctx, block, local_vars); } - if (!result || !result->GetValueAsBoolean()) { + if(!result || !result->GetValueAsBoolean()) { return Obj::No(); } @@ -1330,17 +1339,17 @@ ObjPtr Context::EvalBlockAND(Context *ctx, const TermPtr &block, Obj * local_var ObjPtr Context::EvalBlockOR(Context *ctx, const TermPtr &block, Obj * local_vars) { ObjPtr result = nullptr; - if (block->GetTokenID() == TermID::BLOCK) { + if(block->GetTokenID() == TermID::BLOCK) { for (size_t i = 0; i < block->m_block.size(); i++) { result = ExecStr(ctx, block->m_block[i], local_vars); - if (result && result->GetValueAsBoolean()) { + if(result && result->GetValueAsBoolean()) { return Obj::Yes(); } } } else { result = ExecStr(ctx, block, local_vars); } - if (result && result->GetValueAsBoolean()) { + if(result && result->GetValueAsBoolean()) { return Obj::Yes(); } @@ -1350,16 +1359,16 @@ ObjPtr Context::EvalBlockOR(Context *ctx, const TermPtr &block, Obj * local_vars ObjPtr Context::EvalBlockXOR(Context *ctx, const TermPtr &block, Obj * local_vars) { ObjPtr result; size_t xor_counter = 0; - if (block->GetTokenID() == TermID::BLOCK) { + if(block->GetTokenID() == TermID::BLOCK) { for (size_t i = 0; i < block->m_block.size(); i++) { result = ExecStr(ctx, block->m_block[i], local_vars); - if (result && result->GetValueAsBoolean()) { + if(result && result->GetValueAsBoolean()) { xor_counter++; } } } else { result = ExecStr(ctx, block, local_vars); - if (result && result->GetValueAsBoolean()) { + if(result && result->GetValueAsBoolean()) { xor_counter++; } @@ -1394,13 +1403,13 @@ ObjPtr Context::CreateNative(TermPtr proto, const char *module, bool lazzy, cons ObjPtr result; ObjType type; - if (proto->GetTokenID() == TermID::TERM) { - if (proto->m_type_name.empty()) { + if(proto->GetTokenID() == TermID::TERM) { + if(proto->m_type_name.empty()) { LOG_RUNTIME("Cannot create native variable without specifying the type!"); } type = typeFromString(proto->m_type_name, this); - switch (type) { + switch(type) { case ObjType::Bool: // case ObjType::Byte: case ObjType::Char: @@ -1414,7 +1423,7 @@ ObjPtr Context::CreateNative(TermPtr proto, const char *module, bool lazzy, cons default: LOG_RUNTIME("Creating a variable with type '%s' is not supported!", proto->m_type_name.c_str()); } - } else if (proto->GetTokenID() == TermID::CALL) { + } else if(proto->GetTokenID() == TermID::CALL) { type = ObjType::NativeFunc; } @@ -1424,20 +1433,20 @@ ObjPtr Context::CreateNative(TermPtr proto, const char *module, bool lazzy, cons *const_cast (&result->m_func_proto) = proto; result->m_func_abi = abi; - if (mangle_name) { + if(mangle_name) { result->m_func_mangle_name = mangle_name; } - if (module) { + if(module) { result->m_module_name = module; } - if (lazzy) { + if(lazzy) { result->m_func_ptr = nullptr; } else { result->m_func_ptr = m_runtime->GetProcAddress( result->m_func_mangle_name.empty() ? proto->m_text.c_str() : result->m_func_mangle_name.c_str(), module); - if (result->is_function() || type == ObjType::Pointer) { + if(result->is_function() || type == ObjType::Pointer) { NL_CHECK(result->m_func_ptr, "Error getting address '%s' from '%s'!", proto->toString().c_str(), module); - } else if (result->m_func_ptr && result->is_tensor()) { + } else if(result->m_func_ptr && result->is_tensor()) { result->m_value = torch::from_blob(result->m_func_ptr, { }, toTorchType(type)); result->m_var_is_init = true; @@ -1450,11 +1459,11 @@ ObjPtr Context::CreateNative(TermPtr proto, const char *module, bool lazzy, cons } void *RunTime::GetProcAddress(const char *name, const char *module) { - if (module && module[0]) { - if (m_modules.find(module) == m_modules.end()) { + if(module && module[0]) { + if(m_modules.find(module) == m_modules.end()) { LoadModule(module, false, nullptr); } - if (m_modules.find(module) == m_modules.end()) { + if(m_modules.find(module) == m_modules.end()) { LOG_WARNING("Fail load module '%s'!", module); return nullptr; @@ -1466,9 +1475,9 @@ void *RunTime::GetProcAddress(const char *name, const char *module) { ObjPtr Context::FindSessionTerm(const char *name, bool current_only) { auto found = select(MakeName(name)); - while (!found.complete()) { + while(!found.complete()) { ObjPtr obj = found.data().second.lock(); - if (obj) { + if(obj) { return obj; } @@ -1491,15 +1500,15 @@ ObjPtr Context::FindSessionTerm(const char *name, bool current_only) { */ ObjPtr Context::FindTerm(const std::string name) { ObjPtr result = FindSessionTerm(name.c_str()); - if (!result && isType(name)) { + if(!result && isType(name)) { return GetTypeFromString(name); } - if (!result) { + if(!result) { return GetObject(name.c_str()); } - if (result || isLocalAny(name.c_str()) || isLocal(name)) { + if(result || isLocalAny(name.c_str()) || isLocal(name)) { return result; } @@ -1507,7 +1516,7 @@ ObjPtr Context::FindTerm(const std::string name) { } ObjPtr Context::GetTerm(const std::string name, bool is_ref) { - if (isType(name)) { + if(isType(name)) { return GetTypeFromString(name); } @@ -1517,7 +1526,7 @@ ObjPtr Context::GetTerm(const std::string name, bool is_ref) { std::string newlang::GetFileExt(const char *str) { std::string filename(str); std::string::size_type idx = filename.rfind('.'); - if (idx != std::string::npos) { + if(idx != std::string::npos) { return filename.substr(idx); } @@ -1527,7 +1536,7 @@ std::string newlang::GetFileExt(const char *str) { std::string newlang::AddDefaultFileExt(const char *str, const char *ext_default) { std::string filename(str); std::string file_ext = GetFileExt(str); - if (file_ext.empty() && !filename.empty() && filename.compare(".") != 0) { + if(file_ext.empty() && !filename.empty() && filename.compare(".") != 0) { filename.append(ext_default); } @@ -1537,11 +1546,11 @@ std::string newlang::AddDefaultFileExt(const char *str, const char *ext_default) std::string newlang::ReplaceFileExt(const char *str, const char *ext_old, const char *ext_new) { std::string filename(str); std::string file_ext = GetFileExt(str); - if (file_ext.compare(ext_old) == 0) { + if(file_ext.compare(ext_old) == 0) { filename = filename.substr(0, filename.length() - file_ext.length()); } file_ext = GetFileExt(filename.c_str()); - if (file_ext.compare(".") != 0 && file_ext.compare(ext_new) != 0 && !filename.empty() && + if(file_ext.compare(".") != 0 && file_ext.compare(ext_new) != 0 && !filename.empty() && filename.compare(".") != 0) { filename.append(ext_new); @@ -1566,9 +1575,9 @@ ObjPtr Context::CreateLVal(Context *ctx, TermPtr term, Obj * args) { auto iter = ctx->select(term->m_text); - if (!iter.complete()) { + if(!iter.complete()) { ObjPtr obj = (*iter).lock(); - if (obj) { + if(obj) { return obj; } } @@ -1585,24 +1594,24 @@ ObjPtr Context::CreateLVal(Context *ctx, TermPtr term, Obj * args) { *const_cast (&result->m_func_proto) = term; TermPtr type = term->GetType(); - if (term->IsFunction() || term->getTermID() == TermID::CALL) { + if(term->IsFunction() || term->getTermID() == TermID::CALL) { result->m_var_type_current = ObjType::FUNCTION; result->m_var_type_fixed = result->m_var_type_current; *const_cast (&result->m_func_proto) = term; - } else if (type) { + } else if(type) { result->m_var_type_current = typeFromString(type->getText().c_str(), ctx); result->m_var_type_fixed = result->m_var_type_current; - if (result->is_tensor()) { + if(result->is_tensor()) { std::vector dims; - if (type->m_dims.size()) { + if(type->m_dims.size()) { for (size_t i = 0; i < type->m_dims.size(); i++) { NL_CHECK(type->m_dims[i]->getName().empty(), "Dimension named not supported!"); ObjPtr temp = CreateRVal(ctx, type->m_dims[i]); - if (!temp) { + if(!temp) { NL_PARSER(type, "Term not found!"); } - if (!temp->is_integer()) { + if(!temp->is_integer()) { NL_PARSER(type, "Term type not integer!"); } @@ -1612,7 +1621,7 @@ ObjPtr Context::CreateLVal(Context *ctx, TermPtr term, Obj * args) { result->m_value = torch::empty(dims, toTorchType(result->m_var_type_current)); } } - if (!isType(term->m_text)) { + if(!isType(term->m_text)) { ctx->RegisterObject(result); } return result; @@ -1629,7 +1638,7 @@ ObjPtr Context::CreateRVal(Context *ctx, const char *source, Obj * local_vars) { void Context::ItemTensorEval_(torch::Tensor &tensor, c10::IntArrayRef shape, std::vector &ind, const int64_t pos, ObjPtr &obj, ObjPtr & args) { ASSERT(pos < ind.size()); - if (pos + 1 < ind.size()) { + if(pos + 1 < ind.size()) { for (ind[pos] = 0; ind[pos].integer() < shape[pos]; ind[pos] = ind[pos].integer() + 1) { ItemTensorEval_(tensor, shape, ind, pos + 1, obj, args); } @@ -1640,7 +1649,7 @@ void Context::ItemTensorEval_(torch::Tensor &tensor, c10::IntArrayRef shape, std for (ind[pos] = 0; ind[pos].integer() < shape[pos]; ind[pos] = ind[pos].integer() + 1) { - switch (type) { + switch(type) { case ObjType::Char: case ObjType::Short: case ObjType::Int: @@ -1662,7 +1671,7 @@ void Context::ItemTensorEval_(torch::Tensor &tensor, c10::IntArrayRef shape, std } void Context::ItemTensorEval(torch::Tensor &self, ObjPtr obj, ObjPtr args) { - if (self.dim() == 0) { + if(self.dim() == 0) { signed char *ptr_char = nullptr; short *ptr_short = nullptr; @@ -1671,7 +1680,7 @@ void Context::ItemTensorEval(torch::Tensor &self, ObjPtr obj, ObjPtr args) { float *ptr_float = nullptr; double *ptr_double = nullptr; - switch (fromTorchType(self.scalar_type())) { + switch(fromTorchType(self.scalar_type())) { case ObjType::Char: ptr_char = self.data_ptr(); ASSERT(ptr_char); @@ -1718,12 +1727,12 @@ std::vector GetTensorShape(Context *ctx, TermPtr type, Obj * local_vars std::vector result(type->size()); for (int i = 0; i < type->size(); i++) { ObjPtr temp = ctx->CreateRVal(ctx, type->at(i).second, local_vars); - if (temp->is_integer() || temp->is_bool_type()) { + if(temp->is_integer() || temp->is_bool_type()) { result[i] = temp->GetValueAsInteger(); } else { NL_PARSER(type->at(i).second, "Measurement dimension can be an integer only!"); } - if (result[i] <= 0) { + if(result[i] <= 0) { NL_PARSER(type->at(i).second, "Dimension size can be greater than zero!"); } @@ -1762,36 +1771,36 @@ std::vector Context::MakeIndex(Context *ctx, TermPtr term, Obj * local_va std::vector result; - if (!term->size()) { + if(!term->size()) { NL_PARSER(term, "Index not found!"); } for (int i = 0; i < term->size(); i++) { - if (!term->name(i).empty() || (term->at(i).second && term->at(i).second->IsString())) { + if(!term->name(i).empty() || (term->at(i).second && term->at(i).second->IsString())) { NL_PARSER(term, "Named index not support '%d'!", i); } - if (!term->at(i).second) { + if(!term->at(i).second) { NL_PARSER(term, "Empty index '%d'!", i); } - if (term->at(i).second->getTermID() == TermID::ELLIPSIS) { + if(term->at(i).second->getTermID() == TermID::ELLIPSIS) { result.push_back(Index("...")); } else { ObjPtr temp = ctx->CreateRVal(ctx, term->at(i).second, local_vars); - if (temp->is_none_type()) { + if(temp->is_none_type()) { result.push_back(Index(at::indexing::None)); - } else if (temp->is_integer() || temp->is_bool_type()) { + } else if(temp->is_integer() || temp->is_bool_type()) { - if (temp->is_scalar()) { + if(temp->is_scalar()) { result.push_back(Index(temp->GetValueAsInteger())); - } else if (temp->m_value.dim() == 1) { + } else if(temp->m_value.dim() == 1) { result.push_back(Index(temp->m_value)); } else { NL_PARSER(term->at(i).second, "Extra dimensions index not support '%d'!", i); } - } else if (temp->is_range()) { + } else if(temp->is_range()) { int64_t start = temp->at("start")->GetValueAsInteger(); int64_t stop = temp->at("stop")->GetValueAsInteger(); @@ -1809,7 +1818,7 @@ std::vector Context::MakeIndex(Context *ctx, TermPtr term, Obj * local_va ObjPtr Context::CreateRVal(Context *ctx, TermPtr term, Obj * local_vars) { - if (!term) { + if(!term) { ASSERT(term); } ASSERT(local_vars); @@ -1832,13 +1841,13 @@ ObjPtr Context::CreateRVal(Context *ctx, TermPtr term, Obj * local_vars) { bool has_error; std::vector sizes; at::Scalar torch_scalar; - switch (term->getTermID()) { + switch(term->getTermID()) { case TermID::INTEGER: val_int = parseInteger(term->getText().c_str()); NL_TYPECHECK(term, newlang::toString(typeFromLimit(val_int)), term->m_type_name); // Соответстствует ли тип значению? result->m_var_type_current = typeFromLimit(val_int); - if (term->GetType()) { + if(term->GetType()) { result->m_var_type_fixed = typeFromString(term->m_type_name, ctx); result->m_var_type_current = result->m_var_type_fixed; } @@ -1850,7 +1859,7 @@ ObjPtr Context::CreateRVal(Context *ctx, TermPtr term, Obj * local_vars) { NL_TYPECHECK(term, newlang::toString(typeFromLimit(val_dbl)), term->m_type_name); // Соответстствует ли тип значению? result->m_var_type_current = typeFromLimit(val_dbl); - if (term->GetType()) { + if(term->GetType()) { result->m_var_type_fixed = typeFromString(term->m_type_name, ctx); result->m_var_type_current = result->m_var_type_fixed; } @@ -1892,7 +1901,7 @@ ObjPtr Context::CreateRVal(Context *ctx, TermPtr term, Obj * local_vars) { return result; case TermID::TERM: - if (term->GetType()) { + if(term->GetType()) { result->m_var_type_current = typeFromString(term->GetType()->m_text, ctx); result->m_var_type_fixed = result->m_var_type_current; @@ -1901,21 +1910,21 @@ ObjPtr Context::CreateRVal(Context *ctx, TermPtr term, Obj * local_vars) { // Check BuildInType has_error = false; typeFromString(term->GetType()->m_text, nullptr, &has_error); - if (has_error) { + if(has_error) { result->m_class_name = term->GetType()->m_text; } return result; } - if (term->m_text.compare("_") == 0) { + if(term->m_text.compare("_") == 0) { result->m_var_type_current = ObjType::None; return result; - } else if (term->m_text.compare("$") == 0) { + } else if(term->m_text.compare("$") == 0) { result->m_var_type_current = ObjType::Dictionary; result->m_var_name = "$"; size_t pos = 0; - while (ctx && pos < ctx->size()) { - if (ctx->at(pos).second.lock()) { + while(ctx && pos < ctx->size()) { + if(ctx->at(pos).second.lock()) { result->push_back(Obj::CreateString(ctx->at(pos).first)); // result->push_back(Obj::Arg(ctx->at(pos).first)); pos++; @@ -1925,11 +1934,11 @@ ObjPtr Context::CreateRVal(Context *ctx, TermPtr term, Obj * local_vars) { } result->m_var_is_init = true; return result; - } else if (term->m_text.compare("@") == 0) { - } else if (term->m_text.compare("%") == 0) { + } else if(term->m_text.compare("@") == 0) { + } else if(term->m_text.compare("%") == 0) { } - if (isLocal(term->m_text.c_str())) { + if(isLocal(term->m_text.c_str())) { full_name = MakeName(term->m_text); return local_vars->at(full_name); } else { @@ -1937,31 +1946,31 @@ ObjPtr Context::CreateRVal(Context *ctx, TermPtr term, Obj * local_vars) { // Типы данных обрабатываются тут, а не в вызовах функций (TermID::CALL) - if (term->size()) { + if(term->size()) { Obj args(ctx, term, true, local_vars); result = result->Call(ctx, &args); } } - if (!result) { + if(!result) { // Делать ислкючение или возвращать объект "ошибка" ????? LOG_RUNTIME("Term '%s' not found!", term->GetFullName().c_str()); } field = term->m_right; - if (field && field->getTermID() == TermID::FIELD) { - while (field) { + if(field && field->getTermID() == TermID::FIELD) { + while(field) { result = result->at(field->getText()); field = field->m_right; ASSERT(!field); // Нужно выполнять, а не просто получать значение поля } - } else if (field && field->getTermID() == TermID::INDEX) { - while (field) { + } else if(field && field->getTermID() == TermID::INDEX) { + while(field) { result = result->index_get(MakeIndex(ctx, field, local_vars)); field = field->m_right; ASSERT(!field); // Нужно выполнять, а не просто получать значение поля } - } else if (field) { + } else if(field) { LOG_RUNTIME("Not implemented! %s", field->toString().c_str()); } @@ -1975,7 +1984,7 @@ ObjPtr Context::CreateRVal(Context *ctx, TermPtr term, Obj * local_vars) { has_error = false; type = typeFromString(term->GetFullName(), ctx, &has_error); - if (has_error) { + if(has_error) { LOG_RUNTIME("Type name '%s' undefined!", term->GetFullName().c_str()); } ASSERT(result); @@ -1991,7 +2000,7 @@ ObjPtr Context::CreateRVal(Context *ctx, TermPtr term, Obj * local_vars) { for (size_t i = 0; i < term->size(); i++) { - if ((*term)[i]->GetTokenID() == TermID::FILLING) { + if((*term)[i]->GetTokenID() == TermID::FILLING) { // Заполнение значений вызовом функции // :Type(1, 2, 3, ... rand() ... ); @@ -2003,34 +2012,34 @@ ObjPtr Context::CreateRVal(Context *ctx, TermPtr term, Obj * local_vars) { ObjPtr expr = ctx->FindTerm((*term)[i]->Right()->GetFullName()); - if ((*term)[i]->Right()->getTermID() != TermID::CALL) { + if((*term)[i]->Right()->getTermID() != TermID::CALL) { LOG_RUNTIME("Operator filling supported function call only!"); } - if (i + 1 != term->size()) { + if(i + 1 != term->size()) { LOG_RUNTIME("Function filling is supported for the last argument only!"); } - if (!result->m_dimensions || !result->m_dimensions->size()) { + if(!result->m_dimensions || !result->m_dimensions->size()) { LOG_RUNTIME("Object has no dimensions!"); } int64_t full_size = 1; for (int dim_index = 0; dim_index < result->m_dimensions->size(); dim_index++) { - if (!(*result->m_dimensions)[dim_index]->is_integer()) { + if(!(*result->m_dimensions)[dim_index]->is_integer()) { LOG_RUNTIME("Dimension index for function filling support integer value only!"); } full_size *= (*result->m_dimensions)[dim_index]->GetValueAsInteger(); } - if (full_size <= 0) { + if(full_size <= 0) { LOG_RUNTIME("Items count error for all dimensions!"); } - if (expr->size()) { + if(expr->size()) { LOG_RUNTIME("Argument in function for filling not implemented!"); } @@ -2040,24 +2049,24 @@ ObjPtr Context::CreateRVal(Context *ctx, TermPtr term, Obj * local_vars) { break; - } else if ((*term)[i]->GetTokenID() == TermID::ELLIPSIS) { + } else if((*term)[i]->GetTokenID() == TermID::ELLIPSIS) { - if (!term->name(i).empty()) { + if(!term->name(i).empty()) { LOG_RUNTIME("Named ellipsys not implemented!"); } - if ((*term)[i]->Right()) { + if((*term)[i]->Right()) { bool named = ((*term)[i]->Left() && (*term)[i]->Left()->getTermID() == TermID::ELLIPSIS); ObjPtr exp = CreateRVal(ctx, (*term)[i]->Right()); - if (!exp->is_dictionary_type()) { + if(!exp->is_dictionary_type()) { LOG_RUNTIME("Expansion operator applies to dictionary only!"); } for (int index = 0; index < exp->size(); index++) { - if (named) { + if(named) { args->push_back((*exp)[index], exp->name(index).empty() ? "" : exp->name(index)); } else { args->push_back((*exp)[index]); @@ -2068,7 +2077,7 @@ ObjPtr Context::CreateRVal(Context *ctx, TermPtr term, Obj * local_vars) { } } - if (term->name(i).empty()) { + if(term->name(i).empty()) { args->push_back(CreateRVal(ctx, (*term)[i], local_vars)); } else { args->push_back(CreateRVal(ctx, (*term)[i], local_vars), term->name(i).c_str()); @@ -2088,20 +2097,20 @@ ObjPtr Context::CreateRVal(Context *ctx, TermPtr term, Obj * local_vars) { temp = ctx->GetTerm(term->GetFullName().c_str(), term->isRef()); - if (!temp) { + if(!temp) { ASSERT(temp); } args = Obj::CreateDict(); for (size_t i = 0; i < term->size(); i++) { - if (term->name(i).empty()) { + if(term->name(i).empty()) { args->push_back(CreateRVal(ctx, (*term)[i], local_vars)); } else { args->push_back(CreateRVal(ctx, (*term)[i], local_vars), term->name(i).c_str()); } } - if (term->getTermID() == TermID::EXIT) { + if(term->getTermID() == TermID::EXIT) { return result; } @@ -2113,19 +2122,19 @@ ObjPtr Context::CreateRVal(Context *ctx, TermPtr term, Obj * local_vars) { case TermID::DICT: result->m_var_type_current = ObjType::Dictionary; for (size_t i = 0; i < term->size(); i++) { - if (term->name(i).empty()) { + if(term->name(i).empty()) { result->push_back(CreateRVal(ctx, (*term)[i], local_vars)); } else { result->push_back(CreateRVal(ctx, (*term)[i], local_vars), term->name(i).c_str()); } } result->m_var_is_init = true; - if (term->getTermID() == TermID::TENSOR) { + if(term->getTermID() == TermID::TENSOR) { result->m_var_type_fixed = typeFromString(term->m_type_name, ctx); type = getSummaryTensorType(result, result->m_var_type_fixed); - if (type != ObjType::None) { + if(type != ObjType::None) { result->m_value = ConvertToTensor(result.get(), toTorchType(type)); } else { result->m_var_is_init = false; @@ -2140,7 +2149,7 @@ ObjPtr Context::CreateRVal(Context *ctx, TermPtr term, Obj * local_vars) { case TermID::ARGUMENT: val_int = IndexArg(term); - if (val_int < local_vars->size()) { + if(val_int < local_vars->size()) { return local_vars->at(val_int).second; } LOG_RUNTIME("Argument '%s' not exist!", term->toString().c_str()); @@ -2164,7 +2173,7 @@ ObjPtr Context::CreateRVal(Context *ctx, TermPtr term, Obj * local_vars) { result->push_back(CreateRVal(ctx, (*term)[i], local_vars), term->name(i).c_str()); } - if (result->size() == 2) { + if(result->size() == 2) { result->push_back(Obj::CreateValue(1, ObjType::None), "step"); } diff --git a/core/context.h b/core/context.h index 7f074a36..4c674e60 100644 --- a/core/context.h +++ b/core/context.h @@ -10,39 +10,39 @@ namespace newlang { - std::string GetFileExt(const char * str); - std::string AddDefaultFileExt(const char * str, const char *ext_default); - std::string ReplaceFileExt(const char * str, const char *ext_old, const char *ext_new); - std::string ReadFile(const char *fileName); +std::string GetFileExt(const char * str); +std::string AddDefaultFileExt(const char * str, const char *ext_default); +std::string ReplaceFileExt(const char * str, const char *ext_old, const char *ext_new); +std::string ReadFile(const char *fileName); - bool Tranliterate(const wchar_t c, std::wstring &str); - std::string MangleName(const char * name); +bool Tranliterate(const wchar_t c, std::wstring &str); +std::string MangleName(const char * name); - std::string MangaledFuncCPP(const char *name, const char *space = nullptr); - std::string MangaledFunc(const std::string name); +std::string MangaledFuncCPP(const char *name, const char *space = nullptr); +std::string MangaledFunc(const std::string name); - inline std::string MakeName(std::string name) { - if (!name.empty() && (name[0] == '$' || name[0] == '@' || name[0] == '%')) { - return name.substr(1); - } - return name; +inline std::string MakeName(std::string name) { + if (!name.empty() && (name[0] == '$' || name[0] == '@' || name[0] == '%')) { + return name.substr(1); } + return name; +} - inline std::string MakeLocalName(std::string name) { - return MangleName(MakeName(name).c_str()); - } +inline std::string MakeLocalName(std::string name) { + return MangleName(MakeName(name).c_str()); +} - /* - * Класс контекст предназначен для хранения контекста среды выполнения при вызове функций. - * С его помощью передаются переменные среды окружения, параметры и аргументы приложения, входные и выходные параметры функций, - * текущие локальные и глобальные переменныеи, создание и доступ к итераторам и т.д. - * - * - * - */ - class ContextCursor; +/* + * Класс контекст предназначен для хранения контекста среды выполнения при вызове функций. + * С его помощью передаются переменные среды окружения, параметры и аргументы приложения, входные и выходные параметры функций, + * текущие локальные и глобальные переменныеи, создание и доступ к итераторам и т.д. + * + * + * + */ +class ContextCursor; - typedef std::map ProtoType; +typedef std::map ProtoType; #define NL_OPS(_) \ @@ -103,412 +103,414 @@ namespace newlang { _("export", NOT_SUPPORT)\ _("local", NOT_SUPPORT) - class Context : public Variable< std::weak_ptr > { - public: +class Context : public Variable< std::weak_ptr > { +public: - static ObjPtr eval_END(Context *ctx, const TermPtr & term, Obj *args); - static ObjPtr func_NOT_SUPPORT(Context *ctx, const TermPtr & term, Obj *args); + static ObjPtr eval_END(Context *ctx, const TermPtr & term, Obj *args); + static ObjPtr func_NOT_SUPPORT(Context *ctx, const TermPtr & term, Obj *args); - enum class CreateMode { - CREATE_ONLY, - CREATE_OR_ASSIGN, - ASSIGN_ONLY, - }; - static ObjPtr CREATE_OR_ASSIGN(Context *ctx, const TermPtr & term, Obj *args, CreateMode mode); + enum class CreateMode { + CREATE_ONLY, + CREATE_OR_ASSIGN, + ASSIGN_ONLY, + }; + static ObjPtr CREATE_OR_ASSIGN(Context *ctx, const TermPtr & term, Obj *args, CreateMode mode); #define DEFINE_CASE(name) \ static ObjPtr eval_ ## name(Context *ctx, const TermPtr &term, Obj *args); - NL_TERMS(DEFINE_CASE); + NL_TERMS(DEFINE_CASE); #undef DEFINE_CASE #define PROTO_OP(_, func) \ static ObjPtr op_ ## func(Context *ctx, const TermPtr &term, Obj *args); - NL_OPS(PROTO_OP); + NL_OPS(PROTO_OP); #undef PROTO_OP - typedef ObjPtr(*EvalFunction)(Context *ctx, const TermPtr & term, Obj *args); + typedef ObjPtr(*EvalFunction)(Context *ctx, const TermPtr & term, Obj *args); - static std::map m_ops; - static std::map m_builtin_calls; + static std::map m_ops; + static std::map m_builtin_calls; + static std::map m_macros; ///< Хотя макросы и могут обработываться в рантайме, но доступны только для парсера - static void Reset() { - m_types.clear(); - m_funcs.clear(); - m_ops.clear(); - m_builtin_calls.clear(); - } + static void Reset() { + m_types.clear(); + m_funcs.clear(); + m_macros.clear(); + m_ops.clear(); + m_builtin_calls.clear(); + } - inline ObjPtr ExecFile(const std::string &filename) { - std::string source = ReadFile(filename.c_str()); - if (source.empty()) { - LOG_RUNTIME("Empty source or file '%s' not found!", filename.c_str()); - } - return ExecStr(source); + inline ObjPtr ExecFile(const std::string &filename) { + std::string source = ReadFile(filename.c_str()); + if (source.empty()) { + LOG_RUNTIME("Empty source or file '%s' not found!", filename.c_str()); } + return ExecStr(source); + } - inline ObjPtr ExecStr(const std::string &source) { - TermPtr exec = Parser::ParseString(source); - if (exec->m_id == TermID::BLOCK) { - exec->m_id = TermID::CALL_BLOCK; - } else if (exec->m_id == TermID::BLOCK_TRY) { - exec->m_id = TermID::CALL_TRY; - } - return ExecStr(this, exec); + inline ObjPtr ExecStr(const std::string &source) { + TermPtr exec = Parser::ParseString(source); + if (exec->m_id == TermID::BLOCK) { + exec->m_id = TermID::CALL_BLOCK; + } else if (exec->m_id == TermID::BLOCK_TRY) { + exec->m_id = TermID::CALL_TRY; } + return ExecStr(this, exec); + } - inline ObjPtr ExecStr(const std::string_view str, Obj *args) { - return ExecStr(this, Parser::ParseString(str), args); - } + inline ObjPtr ExecStr(const std::string_view str, Obj *args) { + return ExecStr(this, Parser::ParseString(str), args); + } - inline static ObjPtr ExecStr(Context *ctx, TermPtr term) { - Obj args; - return ExecStr(ctx, term, &args); - } - static ObjPtr ExecStr(Context *ctx, TermPtr term, Obj *args); + inline static ObjPtr ExecStr(Context *ctx, TermPtr term) { + Obj args; + return ExecStr(ctx, term, &args); + } + static ObjPtr ExecStr(Context *ctx, TermPtr term, Obj *args); - static ObjPtr ExpandAssign(Context *ctx, TermPtr lvar, TermPtr rval, Obj *args, CreateMode mode); - static ObjPtr ExpandCreate(Context *ctx, TermPtr lvar, TermPtr rval, Obj *args); + static ObjPtr ExpandAssign(Context *ctx, TermPtr lvar, TermPtr rval, Obj *args, CreateMode mode); + static ObjPtr ExpandCreate(Context *ctx, TermPtr lvar, TermPtr rval, Obj *args); - Context(RuntimePtr global); + Context(RuntimePtr global); - static std::map m_types; - typedef std::variant> FuncItem; - static std::map m_funcs; // Системный и встроенные функции + static std::map m_types; + typedef std::variant> FuncItem; + static std::map m_funcs; // Системный и встроенные функции - inline static ObjPtr CreateLVal(Context *ctx, TermPtr type) { - Obj args; - return CreateLVal(ctx, type, &args); - } + inline static ObjPtr CreateLVal(Context *ctx, TermPtr type) { + Obj args; + return CreateLVal(ctx, type, &args); + } - inline static ObjPtr CreateRVal(Context *ctx, TermPtr term) { - Obj args; - return CreateRVal(ctx, term, &args); - } + inline static ObjPtr CreateRVal(Context *ctx, TermPtr term) { + Obj args; + return CreateRVal(ctx, term, &args); + } - inline static ObjPtr CreateRVal(Context *ctx, const char *source) { - Obj args; - return CreateRVal(ctx, source, &args); - } + inline static ObjPtr CreateRVal(Context *ctx, const char *source) { + Obj args; + return CreateRVal(ctx, source, &args); + } - static ObjPtr CreateLVal(Context *ctx, TermPtr type, Obj *args); - static ObjPtr CreateRVal(Context *ctx, TermPtr term, Obj *args); - static ObjPtr CreateRVal(Context *ctx, const char *source, Obj *args); + static ObjPtr CreateLVal(Context *ctx, TermPtr type, Obj *args); + static ObjPtr CreateRVal(Context *ctx, TermPtr term, Obj *args); + static ObjPtr CreateRVal(Context *ctx, const char *source, Obj *args); - static std::vector MakeIndex(Context *ctx, TermPtr term, Obj *local_vars); + static std::vector MakeIndex(Context *ctx, TermPtr term, Obj *local_vars); - void ItemTensorEval_(torch::Tensor &tensor, c10::IntArrayRef shape, std::vector &ind, const int64_t pos, ObjPtr & obj, ObjPtr &args); - void ItemTensorEval(torch::Tensor &tensor, ObjPtr obj, ObjPtr args); + void ItemTensorEval_(torch::Tensor &tensor, c10::IntArrayRef shape, std::vector &ind, const int64_t pos, ObjPtr & obj, ObjPtr &args); + void ItemTensorEval(torch::Tensor &tensor, ObjPtr obj, ObjPtr args); - void ReadBuiltInProto(ProtoType & proto); + void ReadBuiltInProto(ProtoType & proto); - ObjPtr CreateBuiltin(const char * prototype, void * func, ObjType type); - ObjPtr RegisterObject(ObjPtr var); + bool CreateBuiltin(const char * prototype, void * func, ObjType type); + ObjPtr RegisterObject(ObjPtr var); - ObjPtr RemoveObject(const char * name) { - std::string str(name); - if (str.size() && (str[0] == '$' || str[0] == '@')) { - str = str.substr(1); - } - auto found = select(name); - if (!found.complete()) { - erase(found); - return Obj::Yes(); - } - return Obj::No(); + ObjPtr RemoveObject(const char * name) { + std::string str(name); + if (str.size() && (str[0] == '$' || str[0] == '@')) { + str = str.substr(1); + } + auto found = select(name); + if (!found.complete()) { + erase(found); + return Obj::Yes(); } + return Obj::No(); + } - ObjPtr GetObject(const std::string name) { - std::string str(name); - if (str.size() && (str[0] == '$' || str[0] == '@')) { - str = str.substr(1); - } - auto found = select(str); - if (!found.complete()) { - return (*found).lock(); - } - auto func = m_funcs.find(str); - if (func != m_funcs.end()) { - if (std::holds_alternative(func->second)) { - return std::get(func->second); - } - ASSERT(std::holds_alternative> (func->second)); - return std::get> (func->second)[0]; + ObjPtr GetObject(const std::string name) { + std::string str(name); + if (str.size() && (str[0] == '$' || str[0] == '@')) { + str = str.substr(1); + } + auto found = select(str); + if (!found.complete()) { + return (*found).lock(); + } + auto func = m_funcs.find(str); + if (func != m_funcs.end()) { + if (std::holds_alternative(func->second)) { + return std::get(func->second); } - return nullptr; + ASSERT(std::holds_alternative> (func->second)); + return std::get> (func->second)[0]; } + return nullptr; + } - RuntimePtr m_runtime; // Глобальный контекс, если к нему есть доступ - Variable m_global_terms; + RuntimePtr m_runtime; // Глобальный контекс, если к нему есть доступ + Variable m_global_terms; - virtual ~Context() { - } + virtual ~Context() { + } - ObjPtr GetTerm(const std::string name, bool is_ref); - ObjPtr FindTerm(const std::string name); - ObjPtr FindSessionTerm(const char *name, bool current_only = false); + ObjPtr GetTerm(const std::string name, bool is_ref); + ObjPtr FindTerm(const std::string name); + ObjPtr FindSessionTerm(const char *name, bool current_only = false); - ObjPtr CreateSessionTerm(ObjPtr obj, const char *name); + ObjPtr CreateSessionTerm(ObjPtr obj, const char *name); - ObjPtr FindGlobalTerm(TermPtr term); + ObjPtr FindGlobalTerm(TermPtr term); - ObjPtr FindGlobalTerm(const std::string name) { - auto found = m_global_terms.select(MakeName(name)); - if (!found.complete()) { + ObjPtr FindGlobalTerm(const std::string name) { + auto found = m_global_terms.select(MakeName(name)); + if (!found.complete()) { - return *found; - } - return GetObject(name); + return *found; } + return GetObject(name); + } - void RegisterInContext(ObjPtr &args) { - RegisterInContext(*args); - } + void RegisterInContext(ObjPtr &args) { + RegisterInContext(*args); + } - void RegisterInContext(Obj &args) { - for (int i = static_cast (args.size()) - 1; args.size() && i >= 0; i--) { - push_front(args.at(i).second, args.at(i).first); - } + void RegisterInContext(Obj &args) { + for (int i = static_cast (args.size()) - 1; args.size() && i >= 0; i--) { + push_front(args.at(i).second, args.at(i).first); } + } - void UnRegisterInContext(Obj &args) { - for (int i = static_cast (args.size()) - 1; args.size() && i >= 0; i--) { - pop_front(); - } + void UnRegisterInContext(Obj &args) { + for (int i = static_cast (args.size()) - 1; args.size() && i >= 0; i--) { + pop_front(); } + } - static ObjPtr CallBlock(Context *ctx, const TermPtr &block, Obj *local_vars); - static ObjPtr CallBlockTry(Context *ctx, const TermPtr &block, Obj *local_vars); + static ObjPtr CallBlock(Context *ctx, const TermPtr &block, Obj *local_vars); + static ObjPtr CallBlockTry(Context *ctx, const TermPtr &block, Obj *local_vars); - static ObjPtr EvalBlockAND(Context *ctx, const TermPtr &block, Obj *local_vars); - static ObjPtr EvalBlockOR(Context *ctx, const TermPtr &block, Obj *local_vars); - static ObjPtr EvalBlockXOR(Context *ctx, const TermPtr &block, Obj *local_vars); + static ObjPtr EvalBlockAND(Context *ctx, const TermPtr &block, Obj *local_vars); + static ObjPtr EvalBlockOR(Context *ctx, const TermPtr &block, Obj *local_vars); + static ObjPtr EvalBlockXOR(Context *ctx, const TermPtr &block, Obj *local_vars); - ObjPtr CreateNative(const char *proto, const char *module = nullptr, bool lazzy = false, const char *mangle_name = nullptr, ffi_abi abi = FFI_DEFAULT_ABI); - ObjPtr CreateNative(TermPtr proto, const char *module = nullptr, bool lazzy = false, const char *mangle_name = nullptr, ffi_abi abi = FFI_DEFAULT_ABI); - ObjPtr CreateNative(Obj args); + ObjPtr CreateNative(const char *proto, const char *module = nullptr, bool lazzy = false, const char *mangle_name = nullptr, ffi_abi abi = FFI_DEFAULT_ABI); + ObjPtr CreateNative(TermPtr proto, const char *module = nullptr, bool lazzy = false, const char *mangle_name = nullptr, ffi_abi abi = FFI_DEFAULT_ABI); + ObjPtr CreateNative(Obj args); - static bool pred_compare(const std::string_view find, const std::string_view str) { - size_t pos = 0; - while (pos < find.size() && pos < str.size()) { - if (find[pos] != str[pos]) { - return false; - } - pos++; + static bool pred_compare(const std::string_view find, const std::string_view str) { + size_t pos = 0; + while (pos < find.size() && pos < str.size()) { + if (find[pos] != str[pos]) { + return false; } - return find.empty() || (pos && find.size() == pos); + pos++; } + return find.empty() || (pos && find.size() == pos); + } - std::vector SelectPredict(std::wstring_view wstart, size_t overage_count = 0) { - return SelectPredict(utf8_encode(wstart), overage_count); - } + std::vector SelectPredict(std::wstring_view wstart, size_t overage_count = 0) { + return SelectPredict(utf8_encode(wstart), overage_count); + } - std::vector SelectPredict(std::string_view start, size_t overage_count = 0) { - - std::vector result; - - bool find_local = false; - bool find_global = false; - bool find_types = false; - - std::string prefix; - - if (isGlobal(start)) { - prefix = start[0]; - start.remove_prefix(1); - find_global = true; - } else if (isLocal(start)) { - prefix = start[0]; - start.remove_prefix(1); - find_local = true; - } else if (isType(start)) { - // prefix = start[0]; - // start.remove_prefix(1); - find_types = true; - } else { - find_local = true; - find_global = true; - find_types = true; - } + std::vector SelectPredict(std::string_view start, size_t overage_count = 0) { + + std::vector result; + + bool find_local = false; + bool find_global = false; + bool find_types = false; + + std::string prefix; + + if (isGlobal(start)) { + prefix = start[0]; + start.remove_prefix(1); + find_global = true; + } else if (isLocal(start)) { + prefix = start[0]; + start.remove_prefix(1); + find_local = true; + } else if (isType(start)) { + // prefix = start[0]; + // start.remove_prefix(1); + find_types = true; + } else { + find_local = true; + find_global = true; + find_types = true; + } - if (find_local) { - for (int i = 0; i < size(); i++) { - if (pred_compare(start, at(i).first)) { - ObjPtr object = at(i).second.lock(); - if (object && object->is_function()) { - result.push_back(utf8_decode(prefix + at(i).first) + L"("); - } else if (object) { - result.push_back(utf8_decode(prefix + at(i).first)); - } - if (result.size() > overage_count + 1) { - break; - } + if (find_local) { + for (int i = 0; i < size(); i++) { + if (pred_compare(start, at(i).first)) { + ObjPtr object = at(i).second.lock(); + if (object && object->is_function()) { + result.push_back(utf8_decode(prefix + at(i).first) + L"("); + } else if (object) { + result.push_back(utf8_decode(prefix + at(i).first)); + } + if (result.size() > overage_count + 1) { + break; } } } + } - if (find_global) { - for (int i = 0; i < m_global_terms.size(); i++) { - if (pred_compare(start, m_global_terms.at(i).first)) { - if (m_global_terms.at(i).second->is_function()) { - result.push_back(utf8_decode(prefix + m_global_terms.at(i).first) + L"("); - } else { - result.push_back(utf8_decode(prefix + m_global_terms.at(i).first)); - } - if (result.size() > overage_count + 1) { - break; - } + if (find_global) { + for (int i = 0; i < m_global_terms.size(); i++) { + if (pred_compare(start, m_global_terms.at(i).first)) { + if (m_global_terms.at(i).second->is_function()) { + result.push_back(utf8_decode(prefix + m_global_terms.at(i).first) + L"("); + } else { + result.push_back(utf8_decode(prefix + m_global_terms.at(i).first)); + } + if (result.size() > overage_count + 1) { + break; } } + } - for (auto &elem : m_funcs) { + for (auto &elem : m_funcs) { - if (pred_compare(start, elem.first)) { - result.push_back(utf8_decode(prefix + elem.first) + L"("); - if (result.size() > overage_count + 1) { - break; - } + if (pred_compare(start, elem.first)) { + result.push_back(utf8_decode(prefix + elem.first) + L"("); + if (result.size() > overage_count + 1) { + break; } } } + } - if (find_types) { - for (auto &elem : m_types) { - if (pred_compare(start, elem.first)) { - result.push_back(utf8_decode(elem.first)); - if (result.size() > overage_count + 1) { - break; - } + if (find_types) { + for (auto &elem : m_types) { + if (pred_compare(start, elem.first)) { + result.push_back(utf8_decode(elem.first)); + if (result.size() > overage_count + 1) { + break; } } } - return result; - } + return result; - inline ObjPtr ConvertType(const ObjType type, const Dimension *dims, ObjPtr obj, const ObjPtr obj2 = nullptr) { - ObjPtr result = obj->Clone(); - ConvertType_(type, dims, result, obj2); - return result; - } - void ConvertType_(const ObjType type, const Dimension *dims, ObjPtr obj, const ObjPtr obj2 = nullptr); + } - ObjPtr CreateConvertTypeFunc(const char *prototype, void *func, ObjType type) { - ASSERT(prototype); - ASSERT(func); + inline ObjPtr ConvertType(const ObjType type, const Dimension *dims, ObjPtr obj, const ObjPtr obj2 = nullptr) { + ObjPtr result = obj->Clone(); + ConvertType_(type, dims, result, obj2); + return result; + } + void ConvertType_(const ObjType type, const Dimension *dims, ObjPtr obj, const ObjPtr obj2 = nullptr); + + ObjPtr CreateConvertTypeFunc(const char *prototype, void *func, ObjType type) { + ASSERT(prototype); + ASSERT(func); + + std::string func_dump(prototype); + func_dump += " := {};"; - std::string func_dump(prototype); - func_dump += " := {};"; + TermPtr proto = Parser::ParseString(func_dump); + ObjPtr obj = + Obj::CreateFunc(this, proto->Left(), type, + proto->Left()->getName().empty() ? proto->Left()->getText() : proto->Left()->getName()); + obj->m_func_ptr = func; + + return obj; + } - TermPtr proto = Parser::ParseString(func_dump); - ObjPtr obj = - Obj::CreateFunc(this, proto->Left(), type, - proto->Left()->getName().empty() ? proto->Left()->getText() : proto->Left()->getName()); - obj->m_func_ptr = func; + /** + * Функция для организации встроенных типов в иерархию наследования. + * Другие функции: CreateBaseType - создает базовые типы данных (для расширения классов требуется контекст) + * и BaseTypeConstructor - функция обратного вызова при создании нового объекта базового типа данных + * @param type - Базовый тип данных \ref ObjType + * @param parents - Список сторок с именами родительских типов + * @return - Успешность регистрации базовго типа в иерархии + */ + bool RegisterTypeHierarchy(ObjType type, std::vector parents) { + // std::array < std::string, sizeof...(parents) > list = {parents...}; - return obj; + std::string type_name(toString(type)); + auto base = m_types.find(type_name); + if (base != m_types.end()) { + return false; } - /** - * Функция для организации встроенных типов в иерархию наследования. - * Другие функции: CreateBaseType - создает базовые типы данных (для расширения классов требуется контекст) - * и BaseTypeConstructor - функция обратного вызова при создании нового объекта базового типа данных - * @param type - Базовый тип данных \ref ObjType - * @param parents - Список сторок с именами родительских типов - * @return - Успешность регистрации базовго типа в иерархии - */ - bool RegisterTypeHierarchy(ObjType type, std::vector parents) { - // std::array < std::string, sizeof...(parents) > list = {parents...}; - - std::string type_name(toString(type)); - auto base = m_types.find(type_name); - if (base != m_types.end()) { + ObjPtr result = Obj::CreateBaseType(type); + ASSERT(result->m_var_type_fixed == type); + ASSERT(result->m_var_type_current == ObjType::Type); + ASSERT(!type_name.empty() && result->m_class_name.compare(type_name) == 0); + ASSERT(result->m_class_parents.empty()); + + for (auto &parent : parents) { + auto iter = m_types.find(parent); + if (iter == m_types.end()) { + LOG_DEBUG("Parent type '%s' not found!", parent.c_str()); return false; } - - ObjPtr result = Obj::CreateBaseType(type); - ASSERT(result->m_var_type_fixed == type); - ASSERT(result->m_var_type_current == ObjType::Type); - ASSERT(!type_name.empty() && result->m_class_name.compare(type_name) == 0); - ASSERT(result->m_class_parents.empty()); - - for (auto &parent : parents) { - auto iter = m_types.find(parent); - if (iter == m_types.end()) { - LOG_DEBUG("Parent type '%s' not found!", parent.c_str()); + for (auto &elem : result->m_class_parents) { + ASSERT(elem); + if (!elem->m_class_name.empty() && elem->m_class_name.compare(parent) == 0) { + LOG_DEBUG("The type '%s' already exists in the parents of '%s'!", parent.c_str(), type_name.c_str()); return false; } - for (auto &elem : result->m_class_parents) { - ASSERT(elem); - if (!elem->m_class_name.empty() && elem->m_class_name.compare(parent) == 0) { - LOG_DEBUG("The type '%s' already exists in the parents of '%s'!", parent.c_str(), type_name.c_str()); - return false; - } - } - ASSERT(iter->first.compare(parent) == 0); - result->m_class_parents.push_back(iter->second); } - m_types[type_name] = result; - return true; + ASSERT(iter->first.compare(parent) == 0); + result->m_class_parents.push_back(iter->second); } + m_types[type_name] = result; + return true; + } - ObjType BaseTypeFromString(const std::string & type, bool *has_error = nullptr) { - ObjPtr obj_type = GetTypeFromString(type, has_error); + ObjType BaseTypeFromString(const std::string & type, bool *has_error = nullptr) { + ObjPtr obj_type = GetTypeFromString(type, has_error); - if (obj_type == nullptr) { - if (has_error) { - *has_error = true; - return ObjType::None; - } - LOG_RUNTIME("Type name '%s' not found!", type.c_str()); + if (obj_type == nullptr) { + if (has_error) { + *has_error = true; + return ObjType::None; } - return obj_type->m_var_type_fixed; + LOG_RUNTIME("Type name '%s' not found!", type.c_str()); } + return obj_type->m_var_type_fixed; + } - ObjPtr GetTypeFromString(const std::string & type, bool *has_error = nullptr) { - if (type.empty()) { - return Obj::CreateNone(); - } - auto result = m_types.find(type); - if (result == m_types.end()) { - if (has_error) { - *has_error = true; - return nullptr; - } - LOG_RUNTIME("Type name '%s' not found!", type.c_str()); + ObjPtr GetTypeFromString(const std::string & type, bool *has_error = nullptr) { + if (type.empty()) { + return Obj::CreateNone(); + } + auto result = m_types.find(type); + if (result == m_types.end()) { + if (has_error) { + *has_error = true; + return nullptr; } - return result->second; + LOG_RUNTIME("Type name '%s' not found!", type.c_str()); } + return result->second; + } - enum class MatchMode { - EQUAL, - STRICT, - TYPE_NAME, - TYPE_EQUAL, - TYPE_STRICT, - }; - static bool MatchCompare(Obj &match, ObjPtr &value, MatchMode mode, Context *ctx); - static bool MatchEstimate(Obj &match, const TermPtr &match_item, MatchMode mode, Context *ctx, Obj * args); + enum class MatchMode { + EQUAL, + STRICT, + TYPE_NAME, + TYPE_EQUAL, + TYPE_STRICT, + }; + static bool MatchCompare(Obj &match, ObjPtr &value, MatchMode mode, Context *ctx); + static bool MatchEstimate(Obj &match, const TermPtr &match_item, MatchMode mode, Context *ctx, Obj * args); - SCOPE(protected) : - size_t GetCount(); - ObjPtr GetIndex(size_t index); + SCOPE(protected) : + size_t GetCount(); + ObjPtr GetIndex(size_t index); - private: +private: - Context(const Context&) = delete; - const Context& operator=(const Context&) = delete; + Context(const Context&) = delete; + const Context& operator=(const Context&) = delete; - }; +}; } #endif //INCLUDED_NEWLANG_CONTEXT_ diff --git a/core/object.cpp b/core/object.cpp index 0ef9de7e..12e66c1b 100644 --- a/core/object.cpp +++ b/core/object.cpp @@ -17,7 +17,7 @@ std::ostream &operator<<(std::ostream &out, newlang::Obj &var) { } std::ostream &operator<<(std::ostream &out, newlang::ObjPtr var) { - if (var) { + if(var) { out << var->toString().c_str(); } else { out << ""; @@ -31,7 +31,7 @@ ObjPtr Interrupt::CreateErrorMessage(const std::string message, const std::strin std::string str(message); ObjPtr result; - if (has_error) { + if(has_error) { str += " Extra error: Type name interrupt '" + error_name + "' is not a base type!"; result = Obj::CreateType(ObjType::Error); } else { @@ -55,9 +55,9 @@ const char* Interrupt::what() const noexcept { } int64_t Obj::size(int64_t dim) const { - if (is_tensor()) { - if (is_scalar()) { - if (dim != 0) { + if(is_tensor()) { + if(is_scalar()) { + if(dim != 0) { LOG_RUNTIME("Scalar has zero dimension!"); } return 0; @@ -65,9 +65,9 @@ int64_t Obj::size(int64_t dim) const { return m_value.size(dim); } ASSERT(dim == 0); - if (m_var_type_current == ObjType::StrChar) { + if(m_var_type_current == ObjType::StrChar) { return m_str.size(); - } else if (m_var_type_current == ObjType::StrWide) { + } else if(m_var_type_current == ObjType::StrWide) { return m_wstr.size(); } return Variable::size(); @@ -75,35 +75,35 @@ int64_t Obj::size(int64_t dim) const { int64_t Obj::resize_(int64_t size, ObjPtr fill, const std::string name) { - if (is_string_type()) { + if(is_string_type()) { - if (size >= 0) { + if(size >= 0) { // Размер положительный, просто изменить число элементов добавив или удалив последние - if (m_var_type_current == ObjType::StrChar) { + if(m_var_type_current == ObjType::StrChar) { m_str.resize(size, ' '); return m_str.size(); - } else if (m_var_type_current == ObjType::StrWide) { + } else if(m_var_type_current == ObjType::StrWide) { m_wstr.resize(size, L' '); return m_wstr.size(); } } else { // Если размер отрицательный - добавить или удалить вначале size = -size; - if (m_data.size() > size) { - if (m_var_type_current == ObjType::StrChar) { + if(m_data.size() > size) { + if(m_var_type_current == ObjType::StrChar) { m_str.erase(0, size); return m_str.size(); - } else if (m_var_type_current == ObjType::StrWide) { + } else if(m_var_type_current == ObjType::StrWide) { m_str.erase(0, size); return m_wstr.size(); } - } else if (m_data.size() < size) { - if (m_var_type_current == ObjType::StrChar) { + } else if(m_data.size() < size) { + if(m_var_type_current == ObjType::StrChar) { m_str.insert(0, size, ' '); return m_str.size(); - } else if (m_var_type_current == ObjType::StrWide) { + } else if(m_var_type_current == ObjType::StrWide) { m_wstr.insert(0, size, L' '); return m_wstr.size(); @@ -111,21 +111,21 @@ int64_t Obj::resize_(int64_t size, ObjPtr fill, const std::string name) { } } - } else if (is_dictionary_type()) { + } else if(is_dictionary_type()) { return Variable::resize(size, fill ? fill : Obj::CreateNone(), name); - } else if (is_tensor()) { + } else if(is_tensor()) { std::vector sizes; for (int i = 0; i < m_value.dim(); i++) { sizes.push_back(m_value.size(i)); } - if (sizes.empty()) { // Scalar + if(sizes.empty()) { // Scalar LOG_RUNTIME("Method resize for SCALAR type '%s' not implemented!", newlang::toString(m_var_type_current)); - } else if (size == 0 || sizes[0] == size) { + } else if(size == 0 || sizes[0] == size) { // Tensor size OK - do nothing - } else if (size > 0) { // Increase tensor size + } else if(size > 0) { // Increase tensor size // The size is positive, just change the number of elements by adding or removing the last ASSERT(sizes.size() == 1); @@ -136,9 +136,9 @@ int64_t Obj::resize_(int64_t size, ObjPtr fill, const std::string name) { } else { // Decrease tensor size // If the size is negative - add or remove elements first size = -size; - if (sizes[0] == size) { + if(sizes[0] == size) { // Tensor size OK - do nothing - } else if (sizes[0] > size) { + } else if(sizes[0] > size) { ASSERT(sizes.size() == 1); @@ -159,12 +159,12 @@ int64_t Obj::resize_(int64_t size, ObjPtr fill, const std::string name) { } else { // sizes[0] < size ASSERT(sizes.size() == 1); - + m_value = at::cat({torch::zeros(size - sizes[0], m_value.scalar_type()), m_value}); - } + } } - if (size == 0) { + if(size == 0) { m_value.reset(); m_var_is_init = false; } @@ -174,20 +174,20 @@ int64_t Obj::resize_(int64_t size, ObjPtr fill, const std::string name) { } const Variable::PairType & Obj::at(int64_t index) const { - if (m_var_type_current == ObjType::StrChar) { - if (index < m_str.size()) { + if(m_var_type_current == ObjType::StrChar) { + if(index < m_str.size()) { m_str_pair = pair(CreateString(std::string(1, m_str[index]))); return m_str_pair; } LOG_RUNTIME("Index '%lu' not exists in byte string '%s'!", static_cast (index), m_str.c_str()); - } else if (m_var_type_current == ObjType::StrWide) { - if (index < m_wstr.size()) { + } else if(m_var_type_current == ObjType::StrWide) { + if(index < m_wstr.size()) { m_str_pair = pair(CreateString(std::wstring(1, m_wstr[index]))); return m_str_pair; } LOG_RUNTIME("Index '%lu' not exists in byte string '%s'!", static_cast (index), "WIDE"); - } else if (is_tensor()) { + } else if(is_tensor()) { torch::Tensor t = m_value.index({(int) index}); m_str_pair = pair(Obj::CreateTensor(t)); return m_str_pair; @@ -196,20 +196,20 @@ const Variable::PairType & Obj::at(int64_t index) const { } Variable::PairType & Obj::at(int64_t index) { - if (m_var_type_current == ObjType::StrChar) { - if (index < m_str.size()) { + if(m_var_type_current == ObjType::StrChar) { + if(index < m_str.size()) { m_str_pair = pair(CreateString(std::string(1, m_str[index]))); return m_str_pair; } LOG_RUNTIME("Index '%lu' not exists in byte string '%s'!", static_cast (index), m_str.c_str()); - } else if (m_var_type_current == ObjType::StrWide) { - if (index < m_wstr.size()) { + } else if(m_var_type_current == ObjType::StrWide) { + if(index < m_wstr.size()) { m_str_pair = pair(CreateString(std::wstring(1, m_wstr[index]))); return m_str_pair; } LOG_RUNTIME("Index '%lu' not exists in byte string '%s'!", static_cast (index), "WIDE"); - } else if (is_tensor()) { + } else if(is_tensor()) { torch::Tensor t = m_value.index({(int) index}); m_str_pair = pair(Obj::CreateTensor(t)); return m_str_pair; @@ -218,51 +218,51 @@ Variable::PairType & Obj::at(int64_t index) { } const ObjPtr Obj::index_get(const std::vector &index) const { - if (m_var_type_current == ObjType::StrChar) { - if (index.size() != 1 || !index[0].is_integer()) { + if(m_var_type_current == ObjType::StrChar) { + if(index.size() != 1 || !index[0].is_integer()) { LOG_RUNTIME("The index must be an integer value '%s'!", IndexToString(index).c_str()); } - if (index[0].integer() < m_str.size()) { + if(index[0].integer() < m_str.size()) { return CreateString(std::string(1, m_str[index[0].integer()])); } LOG_RUNTIME("Index '%s' not exists in byte string '%s'!", IndexToString(index).c_str(), m_str.c_str()); - } else if (m_var_type_current == ObjType::StrWide) { - if (index.size() != 1 || !index[0].is_integer()) { + } else if(m_var_type_current == ObjType::StrWide) { + if(index.size() != 1 || !index[0].is_integer()) { LOG_RUNTIME("The index must be an integer value '%s'!", IndexToString(index).c_str()); } - if (index[0].integer() < m_wstr.size()) { + if(index[0].integer() < m_wstr.size()) { return CreateString(std::wstring(1, m_wstr[index[0].integer()])); } LOG_RUNTIME("Index '%s' not exists in byte string '%s'!", IndexToString(index).c_str(), "WIDE"); - } else if (is_tensor()) { + } else if(is_tensor()) { torch::Tensor t = m_value.index(index); return Obj::CreateTensor(t); } - if (index.size() != 1 || !index[0].is_integer()) { + if(index.size() != 1 || !index[0].is_integer()) { LOG_RUNTIME("The index must be an integer value '%s'!", IndexToString(index).c_str()); } return Variable::at(index[0].integer()).second; } ObjPtr Obj::index_set_(const std::vector &index, const ObjPtr value) { - if (m_var_type_current == ObjType::StrChar) { - if (index.size() != 1 || !index[0].is_integer()) { + if(m_var_type_current == ObjType::StrChar) { + if(index.size() != 1 || !index[0].is_integer()) { LOG_RUNTIME("The index must be an integer value '%s'!", IndexToString(index).c_str()); } - if (index[0].integer() < m_str.size()) { + if(index[0].integer() < m_str.size()) { m_str.erase(index[0].integer(), 1); m_str.insert(index[0].integer(), value->toType(ObjType::StrChar)->m_str); m_var_is_init = true; return shared(); } LOG_RUNTIME("Index '%s' not exists in byte string '%s'!", IndexToString(index).c_str(), m_str.c_str()); - } else if (m_var_type_current == ObjType::StrWide) { - if (index.size() != 1 || !index[0].is_integer()) { + } else if(m_var_type_current == ObjType::StrWide) { + if(index.size() != 1 || !index[0].is_integer()) { LOG_RUNTIME("The index must be an integer value '%s'!", IndexToString(index).c_str()); } - if (index[0].integer() < m_wstr.size()) { + if(index[0].integer() < m_wstr.size()) { m_wstr.erase(index[0].integer(), 1); m_wstr.insert(index[0].integer(), value->toType(ObjType::StrWide)->m_wstr); m_var_is_init = true; @@ -270,14 +270,14 @@ ObjPtr Obj::index_set_(const std::vector &index, const ObjPtr value) { } LOG_RUNTIME("Index '%s' not exists in byte string '%s'!", IndexToString(index).c_str(), "WIDE"); - } else if (is_tensor()) { + } else if(is_tensor()) { m_value.index_put_(index, value->toTensor()); m_var_is_init = true; return shared(); - } else if (is_dictionary_type()) { - if (index.size() != 1 || !index[0].is_integer()) { + } else if(is_dictionary_type()) { + if(index.size() != 1 || !index[0].is_integer()) { LOG_RUNTIME("The index must be an integer value '%s'!", IndexToString(index).c_str()); } (*at(index[0].integer()).second) = value; @@ -288,16 +288,16 @@ ObjPtr Obj::index_set_(const std::vector &index, const ObjPtr value) { } ObjPtr Obj::op_set_index(size_t index, std::string value) { - if (m_var_type_current == ObjType::StrChar) { - if (index < m_str.size()) { + if(m_var_type_current == ObjType::StrChar) { + if(index < m_str.size()) { m_str.erase(index, 1); m_str.insert(index, value); m_var_is_init = true; return shared(); } LOG_RUNTIME("Index '%lu' not exists in byte string '%s'!", static_cast (index), m_str.c_str()); - } else if (m_var_type_current == ObjType::StrWide) { - if (index < m_wstr.size()) { + } else if(m_var_type_current == ObjType::StrWide) { + if(index < m_wstr.size()) { m_wstr.erase(index, 1); m_wstr.insert(index, utf8_decode(value)); m_var_is_init = true; @@ -312,9 +312,9 @@ ObjPtr Obj::op_set_index(size_t index, std::string value) { bool Obj::exist(ObjPtr &find, bool strong) { for (auto &elem : * this) { - if (strong && find->op_accurate(elem.second)) { + if(strong && find->op_accurate(elem.second)) { return true; - } else if (!strong && find->op_equal(elem.second)) { + } else if(!strong && find->op_equal(elem.second)) { return true; } } @@ -330,16 +330,16 @@ bool Obj::exist(ObjPtr &find, bool strong) { ObjType newlang::getSummaryTensorType(ObjPtr &obj, ObjType start) { ObjType result = ObjType::None; - if (!obj->getName().empty()) { + if(!obj->getName().empty()) { LOG_RUNTIME("Tensor does not support named data or dimensions '%s'!", obj->getName().c_str()); } - if (obj->is_dictionary_type()) { + if(obj->is_dictionary_type()) { for (size_t i = 0; i < obj->size(); i++) { result = getSummaryTensorType(obj->at(i).second, result); } return result; - } else if (obj->is_arithmetic_type() || obj->is_bool_type()) { - if (start >= std::max(obj->m_var_type_current, obj->m_var_type_fixed)) { + } else if(obj->is_arithmetic_type() || obj->is_bool_type()) { + if(start >= std::max(obj->m_var_type_current, obj->m_var_type_fixed)) { return start; } else { return std::max(obj->m_var_type_current, obj->m_var_type_fixed); @@ -349,17 +349,17 @@ ObjType newlang::getSummaryTensorType(ObjPtr &obj, ObjType start) { } ObjPtr Obj::operator+=(Obj value) { - if (is_tensor()) { - if (value.is_tensor()) { + if(is_tensor()) { + if(value.is_tensor()) { testResultIntegralType(value.m_var_type_current, true); m_value.add_(value.m_value); return shared(); } } - switch (m_var_type_current) { + switch(m_var_type_current) { case ObjType::StrChar: case ObjType::StrWide: - switch (value.m_var_type_current) { + switch(value.m_var_type_current) { case ObjType::None: return shared(); case ObjType::StrChar: @@ -373,9 +373,9 @@ ObjPtr Obj::operator+=(Obj value) { case ObjType::Class: case ObjType::Dictionary: - if (value.m_var_type_current == ObjType::None) { + if(value.m_var_type_current == ObjType::None) { return shared(); - } else if (value.m_var_type_current == ObjType::Class || value.m_var_type_current == ObjType::Dictionary) { + } else if(value.m_var_type_current == ObjType::Class || value.m_var_type_current == ObjType::Dictionary) { for (size_t i = 0; i < value.size(); i++) { push_back(value.at(i)); } @@ -387,28 +387,28 @@ ObjPtr Obj::operator+=(Obj value) { } ObjPtr Obj::operator-=(Obj value) { - if (m_var_type_current == ObjType::None) { + if(m_var_type_current == ObjType::None) { m_var_type_current = value.m_var_type_current; - } else if (is_tensor() && value.is_tensor()) { + } else if(is_tensor() && value.is_tensor()) { testResultIntegralType(value.m_var_type_current, true); - if (is_bool_type()) { + if(is_bool_type()) { toType_(ObjType::Char); } - if (value.is_bool_type()) { + if(value.is_bool_type()) { value.toType_(ObjType::Char); } m_value.sub_(value.m_value); return shared(); } - switch (m_var_type_current) { + switch(m_var_type_current) { case ObjType::Class: case ObjType::Dictionary: - if (value.m_var_type_current == ObjType::None) { + if(value.m_var_type_current == ObjType::None) { return shared(); - } else if (value.m_var_type_current == ObjType::Class || value.m_var_type_current == ObjType::Dictionary) { + } else if(value.m_var_type_current == ObjType::Class || value.m_var_type_current == ObjType::Dictionary) { for (size_t i = 0; i < value.size(); i++) { auto found = select(value.name(i)); - if (!found.complete()) { + if(!found.complete()) { erase(found); } } @@ -420,40 +420,40 @@ ObjPtr Obj::operator-=(Obj value) { } ObjPtr Obj::operator*=(Obj value) { - if (m_var_type_current == ObjType::None) { + if(m_var_type_current == ObjType::None) { m_var_type_current = value.m_var_type_current; - } else if (is_tensor() && value.is_tensor()) { + } else if(is_tensor() && value.is_tensor()) { testResultIntegralType(value.m_var_type_current, true); m_value.mul_(value.m_value); return shared(); } - switch (m_var_type_current) { + switch(m_var_type_current) { case ObjType::Class: case ObjType::Dictionary: - if (value.m_var_type_current == ObjType::None) { + if(value.m_var_type_current == ObjType::None) { Variable::clear_(); return shared(); - } else if (value.m_var_type_current == ObjType::Class || value.m_var_type_current == ObjType::Dictionary) { + } else if(value.m_var_type_current == ObjType::Class || value.m_var_type_current == ObjType::Dictionary) { op_bit_and_set(value, false); return shared(); } break; case ObjType::StrChar: - if (value.is_integer()) { + if(value.is_integer()) { m_str = repeat(m_str, value.GetValueAsInteger()); return shared(); - } else if (value.is_string_type()) { + } else if(value.is_string_type()) { m_str += value.GetValueAsString(); return shared(); } case ObjType::StrWide: - if (value.is_integer()) { + if(value.is_integer()) { m_wstr = repeat(m_wstr, value.GetValueAsInteger()); return shared(); - } else if (value.is_string_type()) { + } else if(value.is_string_type()) { m_wstr += utf8_decode(value.GetValueAsString()); return shared(); } @@ -463,7 +463,7 @@ ObjPtr Obj::operator*=(Obj value) { } ObjPtr Obj::operator/=(Obj value) { - if (is_tensor() && value.is_tensor()) { + if(is_tensor() && value.is_tensor()) { testResultIntegralType(ObjType::Double, false); m_value.div_(value.m_value); return shared(); @@ -472,7 +472,7 @@ ObjPtr Obj::operator/=(Obj value) { } ObjPtr Obj::op_div_ceil_(Obj & value) { - if (is_tensor() && value.is_tensor()) { + if(is_tensor() && value.is_tensor()) { ObjType type = m_var_type_current; testResultIntegralType(ObjType::Float, false); m_value.div_(value.m_value, "floor"); @@ -483,7 +483,7 @@ ObjPtr Obj::op_div_ceil_(Obj & value) { } ObjPtr Obj::operator%=(Obj value) { - if (is_tensor() && value.is_tensor()) { + if(is_tensor() && value.is_tensor()) { testResultIntegralType(value.m_var_type_current, false); m_value.fmod_(value.m_value); return shared(); @@ -494,9 +494,9 @@ ObjPtr Obj::operator%=(Obj value) { size_t Obj::ItemValueCount(ObjPtr &find, bool strong) { size_t result = 0; for (auto &elem : * this) { - if (strong && find->op_accurate(elem.second)) { + if(strong && find->op_accurate(elem.second)) { result++; - } else if (!strong && find->op_equal(elem.second)) { + } else if(!strong && find->op_equal(elem.second)) { result++; } } @@ -507,13 +507,13 @@ void Obj::CloneDataTo(Obj & clone) const { NL_CHECK(!isLocalType(m_var_type_current), "Local object not clonable!"); - if (&clone != this) { // Не клонировать сам в себя + if(&clone != this) { // Не клонировать сам в себя clone.m_var_type_current = m_var_type_current; clone.m_var_type_fixed = m_var_type_fixed; clone.m_var_is_init = m_var_is_init; // clone.m_var_type_name = m_var_type_name; - if (m_dimensions) { + if(m_dimensions) { clone.m_dimensions = m_dimensions->Clone(); } @@ -529,7 +529,7 @@ void Obj::CloneDataTo(Obj & clone) const { clone.m_ref_count = m_ref_count; clone.m_func_ptr = m_func_ptr; *const_cast (&clone.m_func_proto) = m_func_proto; - if (is_tensor() && m_var_is_init) { + if(is_tensor() && m_var_is_init) { clone.m_value = m_value.clone(); } } @@ -540,14 +540,14 @@ void Obj::ClonePropTo(Obj & clone) const { NL_CHECK(!isLocalType(m_var_type_current), "Local object not clonable!"); for (int i = 0; i < Variable::size(); i++) { - if (Variable::at(i).second) { - if (Variable::at(i).second->m_is_reference || Variable::at(i).second->m_is_reference) { + if(Variable::at(i).second) { + if(Variable::at(i).second->m_is_reference || Variable::at(i).second->m_is_reference) { clone.push_back(Variable::at(i)); } else { clone.push_back(Variable::at(i).second->Clone(nullptr), name(i)); } } else { - if (name(i).empty()) { + if(name(i).empty()) { LOG_RUNTIME("Null arg %d without name! %s", i, toString().c_str()); } // Объекта может не быть у обязательных параметров функций @@ -561,9 +561,9 @@ void Obj::SetTermProp(Term & term) { } void newlang::calcTensorDims(ObjPtr &obj, std::vector &dims) { - if (obj->is_dictionary_type()) { + if(obj->is_dictionary_type()) { dims.push_back(obj->size()); - if (obj->size()) { + if(obj->size()) { calcTensorDims(obj->at(0).second, dims); } } @@ -573,7 +573,7 @@ ObjPtr Obj::GetIndex(ObjPtr obj, TermPtr index_arg) { ASSERT(index_arg->size() == 1); TermPtr index = index_arg->at(0).second; ASSERT(index); - if (index->getTermID() != TermID::INTEGER) { + if(index->getTermID() != TermID::INTEGER) { LOG_RUNTIME("Fail index type %s '%s'", newlang::toString(index->getTermID()), index->toString().c_str()); } return GetIndex(obj, std::stoi(index->m_text.c_str())); @@ -582,26 +582,26 @@ ObjPtr Obj::GetIndex(ObjPtr obj, TermPtr index_arg) { std::string Obj::toString(bool deep) const { std::string result(m_is_reference ? "&" : ""); result += m_var_name; - if (!result.empty() && m_var_type_current == ObjType::Class && !deep && m_is_reference) { + if(!result.empty() && m_var_type_current == ObjType::Class && !deep && m_is_reference) { return result; } - if (!m_var_name.empty()) { + if(!m_var_name.empty()) { result.append("="); } size_t dot, last; std::stringstream ss; - if (m_var_type_current == ObjType::None) { - if (m_func_proto && m_func_proto->GetType()) { + if(m_var_type_current == ObjType::None) { + if(m_func_proto && m_func_proto->GetType()) { result += m_func_proto->GetType()->toString(); - } else if (m_var_type_fixed != ObjType::None) { + } else if(m_var_type_fixed != ObjType::None) { result += newlang::toString(m_var_type_fixed); } result += "_"; return result; - } else if (is_tensor()) { - if (is_scalar()) { + } else if(is_tensor()) { + if(is_scalar()) { result += GetValueAsString(); } else { result += "["; @@ -610,11 +610,11 @@ std::string Obj::toString(bool deep) const { result += "]"; } return result; - } else if (isSimpleType(m_var_type_current)) { + } else if(isSimpleType(m_var_type_current)) { result += GetValueAsString(); return result; } else { - switch (m_var_type_current) { + switch(m_var_type_current) { case ObjType::None: // name:= result = "_"; @@ -646,9 +646,12 @@ std::string Obj::toString(bool deep) const { case ObjType::Return: case ObjType::Error: + case ObjType::ErrorParser: + case ObjType::ErrorRunTime: + case ObjType::ErrorSignal: case ObjType::Continue: case ObjType::Break: - if (m_class_name.empty()) { + if(m_class_name.empty()) { result += newlang::toString(m_var_type_current); } else { result += m_class_name; @@ -674,10 +677,10 @@ std::string Obj::toString(bool deep) const { case ObjType::Type: result += newlang::toString(m_var_type_fixed); - if (m_dimensions && m_dimensions->size()) { + if(m_dimensions && m_dimensions->size()) { result += "["; for (int i = 0; i < m_dimensions->size(); i++) { - if (i) { + if(i) { result += ","; } result += (*m_dimensions)[i]->toString(); @@ -686,7 +689,7 @@ std::string Obj::toString(bool deep) const { } - if (size()) { + if(size()) { result += "("; dump_dict_(result); result += ")"; @@ -701,7 +704,7 @@ std::string Obj::toString(bool deep) const { result += "("; m_func_proto->dump_items_(result); result += ")"; - if (!m_func_proto->m_type_name.empty()) { + if(!m_func_proto->m_type_name.empty()) { result += m_func_proto->m_type_name; } @@ -723,34 +726,34 @@ std::string Obj::toString(bool deep) const { result += "("; m_func_proto->dump_items_(result); result += ")"; - if (!m_func_proto->m_type_name.empty()) { + if(!m_func_proto->m_type_name.empty()) { result += m_func_proto->m_type_name; } - if (m_var_type_current == ObjType::EVAL_FUNCTION) { + if(m_var_type_current == ObjType::EVAL_FUNCTION) { result += ":="; - } else if (m_var_type_current == ObjType::SimplePureFunc) { + } else if(m_var_type_current == ObjType::SimplePureFunc) { result += ":-"; - } else if (m_var_type_current == ObjType::SimplePureAND) { + } else if(m_var_type_current == ObjType::SimplePureAND) { result += "::&&="; - } else if (m_var_type_current == ObjType::SimplePureOR) { + } else if(m_var_type_current == ObjType::SimplePureOR) { result += "::||="; - } else if (m_var_type_current == ObjType::SimplePureXOR) { + } else if(m_var_type_current == ObjType::SimplePureXOR) { result += "::^^="; } else { LOG_RUNTIME("Fail function type"); } - if (m_block_source->getTermID() != TermID::BLOCK) { + if(m_block_source->getTermID() != TermID::BLOCK) { result += "{"; } - if (m_block_source) { + if(m_block_source) { result += m_block_source->toString(); - if (m_block_source->getTermID() != TermID::BLOCK) { + if(m_block_source->getTermID() != TermID::BLOCK) { result += ";"; } } - if (m_block_source->getTermID() != TermID::BLOCK) { + if(m_block_source->getTermID() != TermID::BLOCK) { result.append("}"); } return result; @@ -759,7 +762,7 @@ std::string Obj::toString(bool deep) const { result += m_class_name; result += "("; - if (!empty()) { + if(!empty()) { dump_dict_(result); } result += ")"; @@ -778,15 +781,15 @@ void TensorToString_(const torch::Tensor &tensor, c10::IntArrayRef shape, std::v std::string intend; ASSERT(pos < ind.size()); str << "["; - if (shape.size() > 1 && pos + 1 < ind.size()) { + if(shape.size() > 1 && pos + 1 < ind.size()) { str << "\n"; intend = std::string((pos + 1) * 2, ' '); str << intend; } - if (pos + 1 < ind.size()) { + if(pos + 1 < ind.size()) { bool comma = false; for (ind[pos] = 0; ind[pos].integer() < shape[pos]; ind[pos] = ind[pos].integer() + 1) { - if (comma) { + if(comma) { str << ", "; } else { comma = true; @@ -796,14 +799,14 @@ void TensorToString_(const torch::Tensor &tensor, c10::IntArrayRef shape, std::v } else { bool comma = false; for (ind[pos] = 0; ind[pos].integer() < shape[pos]; ind[pos] = ind[pos].integer() + 1) { - if (comma) { + if(comma) { str << ", "; } else { comma = true; } - if (tensor.is_floating_point()) { + if(tensor.is_floating_point()) { str << tensor.index(ind).item(); - } else if (tensor.is_complex()) { + } else if(tensor.is_complex()) { ASSERT(!"Not implemented!"); } else { str << tensor.index(ind).item(); @@ -811,7 +814,7 @@ void TensorToString_(const torch::Tensor &tensor, c10::IntArrayRef shape, std::v } } str << ","; - if (!intend.empty()) { + if(!intend.empty()) { str << "\n"; } str << "]"; @@ -821,11 +824,11 @@ std::string newlang::TensorToString(const torch::Tensor & tensor) { std::string result; std::stringstream ss; - if (tensor.dim() == 0) { - if (tensor.is_floating_point()) { + if(tensor.dim() == 0) { + if(tensor.is_floating_point()) { ss << tensor.item(); ss >> result; - } else if (tensor.is_complex()) { + } else if(tensor.is_complex()) { ASSERT(!"Not implemented!"); // return std::to_string(tensor.item>()); } else { @@ -851,7 +854,7 @@ std::string Obj::GetValueAsString() const { TEST_INIT_(); - switch (m_var_type_current) { + switch(m_var_type_current) { case ObjType::None: return result; @@ -892,7 +895,7 @@ std::string Obj::GetValueAsString() const { case ObjType::Error: result = m_var_name; - if (!m_var_name.empty()) { + if(!m_var_name.empty()) { result += ": "; } temp = m_str; @@ -903,7 +906,7 @@ std::string Obj::GetValueAsString() const { case ObjType::Pointer: ss << m_func_ptr; result += ss.str(); - if (m_class_name.empty()) { + if(m_class_name.empty()) { result += ":Pointer"; } else { result += m_class_name; @@ -940,7 +943,7 @@ ObjPtr Obj::CreateFunc(Context *ctx, TermPtr proto, ObjType type, const std::str Obj args(ctx, proto, false, &local); args.ClonePropTo(*result); *const_cast (&result->m_func_proto) = proto; - if (!result->CheckArgs()) { + if(!result->CheckArgs()) { LOG_RUNTIME("Fail create function '%s'!", proto->toString().c_str()); } return result; @@ -948,7 +951,7 @@ ObjPtr Obj::CreateFunc(Context *ctx, TermPtr proto, ObjType type, const std::str Obj::Obj(Context *ctx, const TermPtr term, bool as_value, Obj * local_vars) { - if (!term) { + if(!term) { NL_CHECK(term, "Fail term!"); } @@ -962,8 +965,8 @@ Obj::Obj(Context *ctx, const TermPtr term, bool as_value, Obj * local_vars) { *const_cast (&m_func_proto) = term; for (size_t i = 0; i < term->size(); i++) { - if (term->name(i).empty()) { - if (as_value) { + if(term->name(i).empty()) { + if(as_value) { // Не именованный аргумент push_back(Context::CreateRVal(ctx, (*term)[i], local_vars)); } else { @@ -980,13 +983,13 @@ bool Obj::CheckArgs() const { bool has_error = false; bool named = false; for (size_t start = 0; start < size(); start++) { - if (at(start).first.empty()) { + if(at(start).first.empty()) { // Аргумент не имеет имени LOG_ERROR("Argument %d has no name!", (int) start + 1); has_error = true; } - if (at(start).second == nullptr) { - if (named) { + if(at(start).second == nullptr) { + if(named) { // Обязательный аргумент после параметров со значениями по умолчанию LOG_ERROR("Rrequired argument %d after parameters with default values!", (int) start + 1); has_error = true; @@ -994,7 +997,7 @@ bool Obj::CheckArgs() const { } else { named = true; for (size_t i = start + 1; i < size(); i++) { - if (at(start).first.compare(at(i).first) == 0) { + if(at(start).first.compare(at(i).first) == 0) { LOG_ERROR("Duplicate named argument '%s'!", at(start).first.c_str()); has_error = true; } @@ -1005,14 +1008,14 @@ bool Obj::CheckArgs() const { } ObjPtr Obj::Call(Context *ctx, Obj * args) { - if (is_string_type()) { + if(is_string_type()) { ObjPtr result = Clone(); result->m_str = format(result->m_str, args); return result; - } else if (is_function() || m_var_type_current == ObjType::Type) { + } else if(is_function() || m_var_type_current == ObjType::Type) { Obj local; ObjPtr param; - if (m_func_proto) { + if(m_func_proto) { param = std::make_shared(ctx, m_func_proto, false, &local); } else { param = Obj::CreateDict(); @@ -1020,43 +1023,43 @@ ObjPtr Obj::Call(Context *ctx, Obj * args) { param->ConvertToArgs_(*args, true, ctx); param->push_front(pair(shared(), "$0")); // Self - if (ctx) { + if(ctx) { ctx->RegisterInContext(param); } ObjPtr result; - if (m_var_type_current == ObjType::FUNCTION) { + if(m_var_type_current == ObjType::FUNCTION) { result = (*reinterpret_cast (m_func_ptr))(ctx, *param.get()); // Непосредственно вызов функции - } else if (m_var_type_current == ObjType::TRANSPARENT || (m_var_type_current == ObjType::Type && m_func_ptr)) { + } else if(m_var_type_current == ObjType::TRANSPARENT || (m_var_type_current == ObjType::Type && m_func_ptr)) { result = (*reinterpret_cast (m_func_ptr))(ctx, *param.get()); // Непосредственно вызов функции - } else if (m_var_type_current == ObjType::NativeFunc) { + } else if(m_var_type_current == ObjType::NativeFunc) { result = CallNative(ctx, *param.get()); - } else if (m_var_type_current == ObjType::EVAL_FUNCTION || m_var_type_current == ObjType::SimplePureFunc) { + } else if(m_var_type_current == ObjType::EVAL_FUNCTION || m_var_type_current == ObjType::SimplePureFunc) { result = Context::CallBlock(ctx, m_block_source, param.get()); - } else if (m_var_type_current == ObjType::SimplePureAND) { + } else if(m_var_type_current == ObjType::SimplePureAND) { result = Context::EvalBlockAND(ctx, m_block_source, param.get()); - } else if (m_var_type_current == ObjType::SimplePureOR) { + } else if(m_var_type_current == ObjType::SimplePureOR) { result = Context::EvalBlockOR(ctx, m_block_source, param.get()); - } else if (m_var_type_current == ObjType::SimplePureXOR) { + } else if(m_var_type_current == ObjType::SimplePureXOR) { result = Context::EvalBlockXOR(ctx, m_block_source, param.get()); } else { LOG_RUNTIME("Call by name not implemted '%s'!", toString().c_str()); } - if (ctx) { + if(ctx) { ctx->pop_front(); } return result; - } else if (is_dictionary_type()) { + } else if(is_dictionary_type()) { ObjPtr result = Clone(); // Копия текущего объекта result->ConvertToArgs_(*args, false, ctx); // С обновленными полями, переданными в аргументах result->m_class_parents.push_back(shared()); // Текущйи объект становится базовым классом для вновь создаваемого return result; - } else if (args->size() > 1) { + } else if(args->size() > 1) { LOG_RUNTIME("Unsupported operation for data type %d '%s'", (int) m_var_type_current, toString().c_str()); } return Clone(); @@ -1067,49 +1070,49 @@ ObjPtr Obj::Call(Context *ctx, Obj * args) { void Obj::ConvertToArgs_(Obj &in, bool check_valid, Context * ctx) { bool named = false; bool is_ellipsis = false; - if (check_valid && size()) { - if (at(size() - 1).first.compare("...") == 0) { + if(check_valid && size()) { + if(at(size() - 1).first.compare("...") == 0) { is_ellipsis = true; erase(size() - 1); } } for (size_t i = 0; i < in.size(); i++) { - if (isInternalName(in.name(i))) { + if(isInternalName(in.name(i))) { continue; } - if (in.name(i).empty()) { + if(in.name(i).empty()) { // if(check_valid && named) { // LOG_RUNTIME("Position %d requires a named argument!", (int) i + 1); // } - if (i < size()) { - if (check_valid && at(i).second && at(i).second->getType() != ObjType::None) { - if (!canCast(in[i]->getType(), at(i).second->getType())) { + if(i < size()) { + if(check_valid && at(i).second && at(i).second->getType() != ObjType::None) { + if(!canCast(in[i]->getType(), at(i).second->getType())) { LOG_RUNTIME("Fail cast value '%s' to type '%s'", newlang::toString(in[i]->getType()), newlang::toString(at(i).second->getType())); } } - if (!at(i).second) { + if(!at(i).second) { at(i).second = Obj::CreateNone(); } - if (m_func_proto && i < m_func_proto->size()) { + if(m_func_proto && i < m_func_proto->size()) { at(i).second->m_is_reference = (*m_func_proto)[i]->isRef(); ObjType base_type = ObjType::None; - if (ctx) { + if(ctx) { base_type = typeFromString((*m_func_proto)[i]->m_type_name, ctx); } else { base_type = ctx->BaseTypeFromString((*m_func_proto)[i]->m_type_name); } ObjType limit_type = in[i]->getTypeAsLimit(); - if (!canCast(limit_type, base_type)) { + if(!canCast(limit_type, base_type)) { LOG_RUNTIME("Fail cast value '%s' to type '%s'", in[i]->toString().c_str(), (*m_func_proto)[i]->m_type_name.c_str()); } } at(i).second->op_assign(in[i]); } else { - if (check_valid && !is_ellipsis && m_func_proto && i >= m_func_proto->size()) { + if(check_valid && !is_ellipsis && m_func_proto && i >= m_func_proto->size()) { LOG_RUNTIME("Positional args overflow. Ptrototype '%s'!", m_func_proto ? m_func_proto->toString().c_str() : "Prototype not exists!"); } @@ -1118,24 +1121,24 @@ void Obj::ConvertToArgs_(Obj &in, bool check_valid, Context * ctx) { } else { named = true; auto find = select(in.name(i)); - if (find != end()) { - if (check_valid && *find && (*find)->getType() != in[i]->getType() && (*find)->getType() != ObjType::None) { + if(find != end()) { + if(check_valid && *find && (*find)->getType() != in[i]->getType() && (*find)->getType() != ObjType::None) { LOG_RUNTIME("Different type arg '%s' and '%s'", (*find)->toString().c_str(), in[i]->toString().c_str()); } //@todo Проверка ограничений размер данных при указаном типе - if (!*find) { + if(!*find) { *find = Obj::CreateNone(); } (*find)->op_assign(in[i]); } else { for (size_t pos = 0; pos < size(); pos++) { - if (!at(pos).first.empty() && at(pos).first.compare(in.at(i).first) == 0) { + if(!at(pos).first.empty() && at(pos).first.compare(in.at(i).first) == 0) { at(pos).second->op_assign(in[i]); goto done; } } - if (check_valid && !is_ellipsis) { + if(check_valid && !is_ellipsis) { LOG_RUNTIME("Named arg '%s' not found!", in.name(i).c_str()); } push_back(in.at(i)); @@ -1144,7 +1147,7 @@ void Obj::ConvertToArgs_(Obj &in, bool check_valid, Context * ctx) { } } } - if (check_valid) { + if(check_valid) { CheckArgsValid(); } @@ -1170,30 +1173,30 @@ void Obj::CheckArgsValid() const { * */ int Obj::op_compare(Obj & value) { - if (this == &value) { + if(this == &value) { return 0; } - if (is_scalar() && value.is_scalar()) { - if (is_floating() || value.is_floating()) { - if (GetValueAsNumber() < value.GetValueAsNumber()) { + if(is_scalar() && value.is_scalar()) { + if(is_floating() || value.is_floating()) { + if(GetValueAsNumber() < value.GetValueAsNumber()) { return -1; - } else if (GetValueAsNumber() > value.GetValueAsNumber()) { + } else if(GetValueAsNumber() > value.GetValueAsNumber()) { return 1; }; return 0; - } else if (is_complex() || value.is_complex()) { + } else if(is_complex() || value.is_complex()) { // Будет ошибка сравнения комплексных значений } else { - if (GetValueAsInteger() < value.GetValueAsInteger()) { + if(GetValueAsInteger() < value.GetValueAsInteger()) { return -1; - } else if (GetValueAsInteger() > value.GetValueAsInteger()) { + } else if(GetValueAsInteger() > value.GetValueAsInteger()) { return 1; }; return 0; } - } else if ((is_string_type() && value.is_string_type())) { - switch (m_var_type_current) { + } else if((is_string_type() && value.is_string_type())) { + switch(m_var_type_current) { case ObjType::StrChar: return m_str.compare(value.GetValueAsString()); @@ -1217,21 +1220,21 @@ int Obj::op_compare(Obj & value) { // bool Obj::op_equal(Obj & value) { - if (this == &value) { + if(this == &value) { return true; - } else if (is_tensor()) { + } else if(is_tensor()) { // Арифметические типы данных сравниваются как тензоры torch::Dtype summary_type = toTorchType( static_cast (std::max(static_cast (m_var_type_current), static_cast (value.m_var_type_current)))); try { - if (m_value.dim() == 0 || value.m_value.dim() == 0) { - if (m_value.dim() == 0 && value.m_value.dim() == 0) { + if(m_value.dim() == 0 || value.m_value.dim() == 0) { + if(m_value.dim() == 0 && value.m_value.dim() == 0) { ObjType type = fromTorchType(summary_type); - if (isIntegralType(type, true)) { + if(isIntegralType(type, true)) { return GetValueAsInteger() == value.GetValueAsInteger(); - } else if (isFloatingType(type)) { + } else if(isFloatingType(type)) { return GetValueAsNumber() == value.GetValueAsNumber(); } else { LOG_RUNTIME("Fail compare type '%s'!", newlang::toString(type)); @@ -1244,19 +1247,19 @@ bool Obj::op_equal(Obj & value) { } catch (std::exception e) { LOG_RUNTIME("Fail compare"); //, e.what()); } - } else if (is_bool_type()) { + } else if(is_bool_type()) { return GetValueAsBoolean() == value.GetValueAsBoolean(); - } else if (is_string_type()) { + } else if(is_string_type()) { return GetValueAsString().compare(value.GetValueAsString()) == 0; - } else if (is_dictionary_type() && value.is_dictionary_type()) { - if (size() != value.size()) { + } else if(is_dictionary_type() && value.is_dictionary_type()) { + if(size() != value.size()) { return false; } for (size_t i = 0; i < size(); i++) { - if (name(i).compare(value.name(i)) != 0) { + if(name(i).compare(value.name(i)) != 0) { return false; } - if (!at(i).second->op_equal(value[i])) { + if(!at(i).second->op_equal(value[i])) { return false; } @@ -1267,9 +1270,9 @@ bool Obj::op_equal(Obj & value) { } bool Obj::op_accurate(Obj & value) { - if (this == &value || (is_none_type() && value.is_none_type())) { + if(this == &value || (is_none_type() && value.is_none_type())) { return true; - } else if ((is_bool_type() && value.is_bool_type()) || (is_arithmetic_type() && value.is_arithmetic_type()) || + } else if((is_bool_type() && value.is_bool_type()) || (is_arithmetic_type() && value.is_arithmetic_type()) || (is_string_type() && value.is_string_type()) || (is_dictionary_type() && value.is_dictionary_type())) { return op_equal(value); @@ -1278,20 +1281,20 @@ bool Obj::op_accurate(Obj & value) { } ObjPtr Obj::op_bit_and_set(Obj &obj, bool strong) { - if (m_var_type_current == ObjType::Long) { - if (m_var_type_current == obj.m_var_type_current) { + if(m_var_type_current == ObjType::Long) { + if(m_var_type_current == obj.m_var_type_current) { m_value.bitwise_and_(obj.m_value); // m_values.integer &= obj.m_values.integer; return shared(); } - } else if (m_var_type_current == ObjType::None || obj.m_var_type_current == ObjType::None) { + } else if(m_var_type_current == ObjType::None || obj.m_var_type_current == ObjType::None) { Variable::clear_(); return shared(); - } else if (m_var_type_current == ObjType::Dictionary || m_var_type_current == ObjType::Class) { - if (obj.m_var_type_current == ObjType::Dictionary || obj.m_var_type_current == ObjType::Class) { + } else if(m_var_type_current == ObjType::Dictionary || m_var_type_current == ObjType::Class) { + if(obj.m_var_type_current == ObjType::Dictionary || obj.m_var_type_current == ObjType::Class) { size_t pos = 0; - while (pos < size()) { - if (!obj.exist(at(pos).second, strong)) { + while(pos < size()) { + if(!obj.exist(at(pos).second, strong)) { erase(pos); } else { pos++; @@ -1299,10 +1302,10 @@ ObjPtr Obj::op_bit_and_set(Obj &obj, bool strong) { } return shared(); } - } else if (is_tensor() && obj.is_tensor()) { + } else if(is_tensor() && obj.is_tensor()) { size_t pos = 0; - while (pos < size()) { - if (!obj.exist(at(pos).second, strong)) { + while(pos < size()) { + if(!obj.exist(at(pos).second, strong)) { erase(pos); } else { @@ -1314,68 +1317,72 @@ ObjPtr Obj::op_bit_and_set(Obj &obj, bool strong) { LOG_RUNTIME("Incompatible types %d and %d for '&' operator!", (int) m_var_type_current, (int) obj.m_var_type_current); } -bool Obj::op_class_test(ObjPtr obj, Context * ctx) { - if (obj->is_string_type()) { +bool Obj::op_class_test(ObjPtr obj, Context * ctx) const { + if(obj->is_string_type()) { return op_class_test(obj->GetValueAsString().c_str(), ctx); - } else if (!obj->m_class_name.empty()) { + } else if(!obj->m_class_name.empty()) { return op_class_test(obj->m_class_name.c_str(), ctx); - } else if (obj->is_type_name()) { + } else if(obj->is_type_name()) { return op_class_test(newlang::toString(obj->m_var_type_fixed), ctx); } else { return op_class_test(newlang::toString(obj->m_var_type_current), ctx); } } -bool Obj::op_class_test(const char *name, Context * ctx) { +bool Obj::op_class_test(const char *name, Context * ctx) const { ASSERT(name || *name); - if (!m_class_name.empty() && m_class_name.compare(name) == 0) { + if(!m_class_name.empty() && m_class_name.compare(name) == 0) { return true; } for (auto &elem : m_class_parents) { - if (elem->op_class_test(name, ctx)) { + if(elem->op_class_test(name, ctx)) { return true; } } bool has_error = false; ObjType type = typeFromString(name, ctx, &has_error); - if (has_error) { + if(has_error) { LOG_DEBUG("Type name %s not found!", name); return false; } ObjType check_type = m_var_type_current; - if (m_var_type_current == ObjType::Type || !m_var_is_init && m_var_type_current == ObjType::None) { + if(m_var_type_current == ObjType::Type || !m_var_is_init && m_var_type_current == ObjType::None) { check_type = m_var_type_fixed; } - return isContainsType(type, check_type); + if(isContainsType(type, check_type)) { + return true; + } + std::string class_name = newlang::toString(check_type); + return !class_name.empty() && class_name.compare(name) == 0; } bool Obj::op_duck_test_prop(Obj *base, Obj *value, bool strong) { - if (!value) { + if(!value) { return !strong; // Пустой объект равен любому при нечетком сравнении } - if (!base || base->m_var_type_current == ObjType::None) { + if(!base || base->m_var_type_current == ObjType::None) { // Итина при пустом текущем может быть только если образец тоже пустой return value->m_var_type_current == ObjType::None; } ObjPtr field; for (size_t i = 0; i < value->size(); i++) { - if (value->name(i).empty()) { + if(value->name(i).empty()) { field = (*base)[i]; } else { field = (*base)[value->name(i)]; } - if (!field) { + if(!field) { return false; } - if (strong || !((*value)[i]->getType() != ObjType::None)) { + if(strong || !((*value)[i]->getType() != ObjType::None)) { for (auto &elem : *value) { - if (!field->op_duck_test(elem.second, strong)) { + if(!field->op_duck_test(elem.second, strong)) { return false; } @@ -1386,22 +1393,22 @@ bool Obj::op_duck_test_prop(Obj *base, Obj *value, bool strong) { } ObjPtr Obj::op_pow_(Obj & obj) { - if (obj.is_arithmetic_type()) { - if (is_tensor()) { + if(obj.is_arithmetic_type()) { + if(is_tensor()) { m_value.pow_(obj.toTensor()); return shared(); - } else if (is_arithmetic_type()) { - if (is_integer()) { + } else if(is_arithmetic_type()) { + if(is_integer()) { SetValue_(static_cast (pow(GetValueAsInteger(), obj.GetValueAsInteger()) + 0.5)); return shared(); - } else if (isFloatingType(m_var_type_current)) { + } else if(isFloatingType(m_var_type_current)) { SetValue_(pow(GetValueAsNumber(), obj.GetValueAsNumber())); return shared(); } - } else if (m_var_type_current == ObjType::StrChar && obj.is_integer()) { + } else if(m_var_type_current == ObjType::StrChar && obj.is_integer()) { m_str = repeat(m_str, obj.GetValueAsInteger()); return shared(); - } else if (m_var_type_current == ObjType::StrWide && obj.is_integer()) { + } else if(m_var_type_current == ObjType::StrWide && obj.is_integer()) { m_wstr = repeat(m_wstr, obj.GetValueAsInteger()); return shared(); } @@ -1411,29 +1418,29 @@ ObjPtr Obj::op_pow_(Obj & obj) { bool Obj::op_duck_test(Obj *value, bool strong) { - if (!value || value->m_var_type_current == ObjType::None) { + if(!value || value->m_var_type_current == ObjType::None) { // Пустой объект совместим с любым объектом, // а при строгом сравнении только с таким же пустым return strong ? m_var_type_current == value->m_var_type_current : true; } - if (strong) { - if (value->is_simple()) { - if (m_var_type_current == value->m_var_type_current || (is_string_type() && value->is_string_type())) { + if(strong) { + if(value->is_simple()) { + if(m_var_type_current == value->m_var_type_current || (is_string_type() && value->is_string_type())) { return true; } return false; } return op_duck_test_prop(this, value, strong); } - if (value->m_var_type_current == ObjType::Long || value->m_var_type_current == ObjType::Double) { + if(value->m_var_type_current == ObjType::Long || value->m_var_type_current == ObjType::Double) { return (m_var_type_current == ObjType::Long || m_var_type_current == ObjType::Double); - } else if (is_string_type() && value->is_string_type()) { + } else if(is_string_type() && value->is_string_type()) { return true; - } else if (is_function() && value->is_function()) { + } else if(is_function() && value->is_function()) { return true; - } else if (value->m_var_type_current == ObjType::Dictionary || value->m_var_type_current == ObjType::Class) { - if (m_var_type_current == ObjType::Dictionary || m_var_type_current == ObjType::Class) { + } else if(value->m_var_type_current == ObjType::Dictionary || value->m_var_type_current == ObjType::Class) { + if(m_var_type_current == ObjType::Dictionary || m_var_type_current == ObjType::Class) { return op_duck_test_prop(this, value, strong); } @@ -1443,13 +1450,13 @@ bool Obj::op_duck_test(Obj *value, bool strong) { } std::string Obj::format(std::string format, Obj * args) { - if (args && !args->empty()) { + if(args && !args->empty()) { std::string name; std::string place; std::wstring wname; for (size_t i = 0; i < args->size(); i++) { - if (isInternalName(args->name(i))) { + if(isInternalName(args->name(i))) { continue; } @@ -1458,7 +1465,7 @@ std::string Obj::format(std::string format, Obj * args) { place = (*args)[i]->GetValueAsString(); format = std::regex_replace(format, std::regex(name), place); - if (!args->name(i).empty()) { + if(!args->name(i).empty()) { std::wstring wplace = utf8_decode(place); std::wstring temp = utf8_decode(format); @@ -1479,33 +1486,33 @@ std::string Obj::format(std::string format, Obj * args) { ObjPtr Obj::toShape_(ObjPtr dims) { std::vector array = dims->toIntVector(true); - if (is_tensor()) { + if(is_tensor()) { m_value.resize_(array); return shared(); } - if (array.size() > 1) { + if(array.size() > 1) { LOG_RUNTIME("More than one dimension is not supported!"); - } else if (array.size() == 0) { + } else if(array.size() == 0) { // Ноль измерений не у тензора только у None toType_(ObjType::None); return shared(); - } else if (size() == array[0]) { + } else if(size() == array[0]) { // Требуемый размер return shared(); } - if (m_var_type_current == ObjType::StrChar) { + if(m_var_type_current == ObjType::StrChar) { m_str.resize(array[0]); - } else if (m_var_type_current == ObjType::StrWide) { + } else if(m_var_type_current == ObjType::StrWide) { m_wstr.resize(array[0]); - } else if (is_dictionary_type()) { + } else if(is_dictionary_type()) { - if (size() > array[0]) { + if(size() > array[0]) { m_data.resize(array[0]); // Уменьшить размер } else { - while (size() < array[0]) { + while(size() < array[0]) { push_back(Obj::CreateNone()); } } @@ -1518,7 +1525,7 @@ ObjPtr Obj::toShape_(ObjPtr dims) { ObjPtr Obj::toType_(Obj * type) { ASSERT(type); - if (type->m_var_type_current != ObjType::Type) { + if(type->m_var_type_current != ObjType::Type) { LOG_RUNTIME("Fail type object '%s'!", type->toString().c_str()); } @@ -1527,35 +1534,35 @@ ObjPtr Obj::toType_(Obj * type) { } void Obj::toType_(ObjType target) { - if (m_var_type_current == target) { + if(m_var_type_current == target) { // Конвертировать не нужно return; - } else if (is_none_type() || target == ObjType::None) { + } else if(is_none_type() || target == ObjType::None) { // Любой тип при конвертации в пустой, просто очистить данные clear_(); m_var_type_current = target; return; - } else if (is_tensor()) { + } else if(is_tensor()) { // Из тензора конвертировать в другой тип - if (isTensor(target)) { + if(isTensor(target)) { m_value = m_value.toType(toTorchType(target)); m_var_type_current = target; Variable::clear_(); return; - } else if (isString(target)) { - if (target == ObjType::StrChar) { + } else if(isString(target)) { + if(target == ObjType::StrChar) { // В байтовую строку конвертируются только байтовый скаляр или одномерный байтовый тензор - if (!(m_value.dtype().toScalarType() == at::ScalarType::Byte || m_value.dtype().toScalarType() == at::ScalarType::Char)) { + if(!(m_value.dtype().toScalarType() == at::ScalarType::Byte || m_value.dtype().toScalarType() == at::ScalarType::Char)) { LOG_RUNTIME("Convert to byte string can 1-byte tensor only!"); } - if (m_value.dim() == 0) { + if(m_value.dim() == 0) { m_str.resize(1); m_str[0] = m_value.item().toInt(); - } else if (m_value.dim() == 1) { + } else if(m_value.dim() == 1) { m_str.clear(); for (int i = 0; i < m_value.size(0); i++) { m_str += m_value.index({i}).item().toChar(); @@ -1571,17 +1578,17 @@ void Obj::toType_(ObjType target) { ASSERT(target == ObjType::StrWide); // В символьную строку конвертируется любой целочисленный скаляр или одномерный тензор - if (!(m_value.dtype().toScalarType() == at::ScalarType::Byte || m_value.dtype().toScalarType() == at::ScalarType::Char || + if(!(m_value.dtype().toScalarType() == at::ScalarType::Byte || m_value.dtype().toScalarType() == at::ScalarType::Char || m_value.dtype().toScalarType() == at::ScalarType::Short || m_value.dtype().toScalarType() == at::ScalarType::Int)) { LOG_RUNTIME("Convert to wide string can 1..4 byte tensor only!"); } STATIC_ASSERT(sizeof (wchar_t) == sizeof (int32_t)); - if (m_value.dim() == 0) { + if(m_value.dim() == 0) { m_wstr.resize(1); m_wstr[0] = m_value.item().toInt(); - } else if (m_value.dim() == 1) { + } else if(m_value.dim() == 1) { m_wstr.clear(); for (int i = 0; i < m_value.size(0); i++) { m_wstr += m_value.index({i}).item().toInt(); @@ -1593,24 +1600,24 @@ void Obj::toType_(ObjType target) { m_var_type_current = target; return; } - } else if (isDictionary(target)) { + } else if(isDictionary(target)) { m_var_type_current = target; ConvertTensorToDict(m_value, *this); m_value.reset(); return; } - } else if (is_string_type()) { + } else if(is_string_type()) { // Из строки в другой тип данных - if (isString(target)) { + if(isString(target)) { // Строки хранятся в байтовом представлении и их ненужно конвертировать m_var_type_current = target; return; - } else if (isTensor(target)) { + } else if(isTensor(target)) { // Сконвертировать строку в тензор torch::Tensor std_data; std::wstring_convert < std::codecvt_utf8, wchar_t> converter; std::wstring temp; - if (m_var_type_current == ObjType::StrChar) { + if(m_var_type_current == ObjType::StrChar) { // Байтовая строка конвертируются в одномерный байтовый тензор std_data = torch::from_blob((void *) m_str.data(),{(int) m_str.size()}, torch::Dtype::Char); } else { // ObjType::StrWide @@ -1618,7 +1625,7 @@ void Obj::toType_(ObjType target) { STATIC_ASSERT(sizeof (wchar_t) == sizeof (int32_t)); std_data = torch::from_blob((void *) m_wstr.data(),{(int) m_wstr.size()}, torch::Dtype::Int); } - if (isGenericType(target) && !isContainsType(target, fromTorchType(std_data.scalar_type()))) { + if(isGenericType(target) && !isContainsType(target, fromTorchType(std_data.scalar_type()))) { m_value = std_data.toType(toTorchType(target)); } else { m_value = std_data.clone(); @@ -1629,7 +1636,7 @@ void Obj::toType_(ObjType target) { m_var_type_current = target; return; - } else if (isDictionary(target)) { + } else if(isDictionary(target)) { torch::Tensor temp; ConvertValueToTensor(this, temp); @@ -1641,16 +1648,16 @@ void Obj::toType_(ObjType target) { return; } - } else if (is_dictionary_type()) { + } else if(is_dictionary_type()) { // Из словаря в другой тип данных - if (isString(target)) { + if(isString(target)) { // Допустимо (обратная реализация чуть выше) LOG_RUNTIME("Not implemented!!!"); - } else if (isDictionary(target)) { + } else if(isDictionary(target)) { // Словрь в словарь - ничего не делаем m_var_type_current = target; return; - } else if (isTensor(target)) { + } else if(isTensor(target)) { ConvertDictToTensor(*this, m_value, target); @@ -1658,9 +1665,9 @@ void Obj::toType_(ObjType target) { return; } - } else if (m_var_type_current == ObjType::Range) { + } else if(m_var_type_current == ObjType::Range) { // Из диапазона в другой тип данных - if (isDictionary(target) || isTensor(target)) { + if(isDictionary(target) || isTensor(target)) { // В словарь ObjPtr temp = Obj::CreateDict(); @@ -1669,7 +1676,7 @@ void Obj::toType_(ObjType target) { Variable::clear_(); - if (isTensor(target)) { + if(isTensor(target)) { // В тензор ConvertDictToTensor(*temp.get(), m_value, target); m_var_type_current = target; @@ -1690,7 +1697,7 @@ int64_t newlang::ConcatData(Obj *dest, Obj &src, ConcatMode mode) { int64_t size = 0; ASSERT(dest); - if (!dest->m_var_is_init) { + if(!dest->m_var_is_init) { ObjPtr temp = src.toType(dest->m_var_type_current); temp->m_var_type_fixed = dest->m_var_type_current; @@ -1700,13 +1707,13 @@ int64_t newlang::ConcatData(Obj *dest, Obj &src, ConcatMode mode) { temp->ClonePropTo(*dest); dest->m_var_is_init = true; - } else if (dest->is_string_type()) { + } else if(dest->is_string_type()) { - if (dest->m_var_type_current == ObjType::StrChar) { + if(dest->m_var_type_current == ObjType::StrChar) { std::string add = src.GetValueAsString(); dest->m_str.append(add); size = add.size(); - } else if (dest->m_var_type_current == ObjType::StrWide) { + } else if(dest->m_var_type_current == ObjType::StrWide) { std::wstring add = src.GetValueAsStringWide(); dest->m_wstr.append(add); size = add.size(); @@ -1714,7 +1721,7 @@ int64_t newlang::ConcatData(Obj *dest, Obj &src, ConcatMode mode) { LOG_RUNTIME("Unknown string type %s!", dest->toString().c_str()); } - } else if (dest->is_dictionary_type()) { + } else if(dest->is_dictionary_type()) { ObjPtr temp = src.toType(ObjType::Dictionary); for (int i = 0; i < temp->size(); i++) { @@ -1722,13 +1729,13 @@ int64_t newlang::ConcatData(Obj *dest, Obj &src, ConcatMode mode) { size++; } - } else if (dest->is_tensor()) { + } else if(dest->is_tensor()) { - if (dest->m_var_type_current == src.m_var_type_current) { - if (dest->m_value.dim() == 0) { + if(dest->m_var_type_current == src.m_var_type_current) { + if(dest->m_value.dim() == 0) { dest->m_value.resize_(1); } - if (src.m_value.dim() == 0) { + if(src.m_value.dim() == 0) { src.m_value.resize_(1); } dest->m_value = torch::cat({dest->m_value, src.m_value}); @@ -1746,12 +1753,12 @@ int64_t newlang::ConcatData(Obj *dest, Obj &src, ConcatMode mode) { } void ShapeFromDict(const Obj *obj, std::vector &shape) { - if (obj && (obj->is_dictionary_type() || (obj->is_tensor() && !obj->is_scalar()))) { - if (!obj->size()) { + if(obj && (obj->is_dictionary_type() || (obj->is_tensor() && !obj->is_scalar()))) { + if(!obj->size()) { LOG_RUNTIME("Cannot tensor shape from empty dictionary!"); } shape.push_back(obj->size()); - if (obj->at(0).second) { + if(obj->at(0).second) { ShapeFromDict(obj->at(0).second.get(), shape); } } @@ -1766,34 +1773,34 @@ std::vector newlang::TensorShapeFromDict(const Obj * obj) { torch::Tensor newlang::ConvertToTensor(Obj *data, at::ScalarType type, bool reshape) { ASSERT(data); - if (data->is_tensor()) { + if(data->is_tensor()) { // Прообразование один в один - if (type == at::ScalarType::Undefined) { - if (data->is_scalar()) { + if(type == at::ScalarType::Undefined) { + if(data->is_scalar()) { return data->m_value.reshape({1}); } return data->m_value.clone(); } else { - if (data->is_scalar()) { + if(data->is_scalar()) { return data->m_value.reshape({1}).toType(type); } return data->m_value.clone().toType(type); } - } else if (data->m_var_type_current == ObjType::StrChar) { - if (type == at::ScalarType::Undefined) { + } else if(data->m_var_type_current == ObjType::StrChar) { + if(type == at::ScalarType::Undefined) { type = at::ScalarType::Char; } // В байтовую строку конвертируются только байтовый скаляр или одномерный байтовый тензор return torch::from_blob((void *) data->m_str.data(), data->m_str.size(), type).clone(); - } else if (data->m_var_type_current == ObjType::StrWide) { - if (type == at::ScalarType::Undefined) { + } else if(data->m_var_type_current == ObjType::StrWide) { + if(type == at::ScalarType::Undefined) { type = at::ScalarType::Int; } // В символьную строку конвертируется любой целочисленный скаляр или одномерный тензор return torch::from_blob((void *) data->m_wstr.data(), { (int) data->m_wstr.size() }, type).clone(); - } else if (data->is_range()) { + } else if(data->is_range()) { ASSERT(data->at("start")); ASSERT(data->at("stop")); @@ -1803,7 +1810,7 @@ torch::Tensor newlang::ConvertToTensor(Obj *data, at::ScalarType type, bool resh ASSERT(data->at("step")->is_arithmetic_type() || data->at("step")->is_bool_type()); ObjPtr dict = Obj::CreateDict(); - if (data->at("start")->is_floating() || data->at("stop")->is_floating() || data->at("step")->is_floating()) { + if(data->at("start")->is_floating() || data->at("stop")->is_floating() || data->at("step")->is_floating()) { double value = data->at("start")->GetValueAsNumber(); double stop = data->at("stop")->GetValueAsNumber(); double step = data->at("step")->GetValueAsNumber(); @@ -1821,40 +1828,40 @@ torch::Tensor newlang::ConvertToTensor(Obj *data, at::ScalarType type, bool resh } return ConvertToTensor(dict.get(), type, reshape); - } else if (data->is_dictionary_type()) { - if (type == at::ScalarType::Undefined) { + } else if(data->is_dictionary_type()) { + if(type == at::ScalarType::Undefined) { type = at::ScalarType::Char; } std::vector shape; - if (reshape) { + if(reshape) { shape = TensorShapeFromDict(data); ASSERT(shape.size()); } // Из словаря torch::Tensor result = ConvertToTensor(data->index_get({0}).get(), type, false); - if (result.dim() == 0) { + if(result.dim() == 0) { result.resize_(1); } for (int i = 1; i < data->size(); i++) { torch::Tensor temp = ConvertToTensor(data->index_get({i}).get(), type, false); - if (temp.dim() == 0) { + if(temp.dim() == 0) { temp.resize_(1); } result = torch::cat({result, temp}); } - if (reshape) { + if(reshape) { return result.reshape(shape); } return result; - } else if (data->is_none_type() || (data->is_dictionary_type() && data->size() == 0)) { + } else if(data->is_none_type() || (data->is_dictionary_type() && data->size() == 0)) { // Пустое значение или пустой словарь не конвертируются LOG_RUNTIME("Not implemented!"); - } else if (data->is_function()) { + } else if(data->is_function()) { // Как преобразовать функцию? И нужно ли это делать? LOG_RUNTIME("Not implemented!"); @@ -1864,7 +1871,7 @@ torch::Tensor newlang::ConvertToTensor(Obj *data, at::ScalarType type, bool resh } at::TensorOptions newlang::ConvertToTensorOptions(const Obj * obj) { - if (!obj || obj->is_none_type()) { + if(!obj || obj->is_none_type()) { return at::TensorOptions(); } @@ -1872,7 +1879,7 @@ at::TensorOptions newlang::ConvertToTensorOptions(const Obj * obj) { } at::DimnameList newlang::ConvertToDimnameList(const Obj * obj) { - if (!obj || obj->is_none_type()) { + if(!obj || obj->is_none_type()) { return {}; } @@ -1899,7 +1906,7 @@ ObjPtr Obj::CallNative(Context *ctx, Obj args) { ASSERT(m_var_type_current == ObjType::NativeFunc); ASSERT(m_func_proto); - if (!m_func_ptr) { + if(!m_func_ptr) { NL_CHECK(m_module_name.empty() || ctx, "You cannot load a module without access to the runtime context!"); m_func_ptr = ctx->m_runtime->GetProcAddress(m_func_mangle_name.empty() ? m_func_proto->m_text.c_str() : m_func_mangle_name.c_str(), m_module_name.empty() ? nullptr : m_module_name.c_str()); @@ -1915,16 +1922,16 @@ ObjPtr Obj::CallNative(Context *ctx, Obj args) { for (size_t i = 1; i < args.size(); i++) { ASSERT(args[i]); - if (args[i]->m_is_reference) { + if(args[i]->m_is_reference) { LOG_RUNTIME("Argument REFERENCE! %s", args[i]->toString().c_str()); } size_t pind = i - 1; // Индекс прототипа на единицу меньше из-за пустого нулевого аргумента ObjType type = args[i]->getTypeAsLimit(); - switch (type) { + switch(type) { case ObjType::Bool: - if (pind < check_count) { + if(pind < check_count) { NL_CHECK(!(*m_func_proto)[pind]->m_type_name.empty(), "Undefined type arg '%s'", (*m_func_proto)[pind]->toString().c_str()); NL_CHECK(canCast(type, typeFromString((*m_func_proto)[pind]->m_type_name, ctx)), "Fail cast from '%s' to '%s'", (*m_func_proto)[pind]->m_type_name.c_str(), newlang::toString(type)); @@ -1935,7 +1942,7 @@ ObjPtr Obj::CallNative(Context *ctx, Obj args) { break; case ObjType::Char: - if (pind < check_count) { + if(pind < check_count) { NL_CHECK(!(*m_func_proto)[pind]->m_type_name.empty(), "Undefined type arg '%s'", (*m_func_proto)[pind]->toString().c_str()); NL_CHECK(canCast(type, typeFromString((*m_func_proto)[pind]->m_type_name, ctx)), "Fail cast from '%s' to '%s'", (*m_func_proto)[pind]->m_type_name.c_str(), newlang::toString(type)); @@ -1946,7 +1953,7 @@ ObjPtr Obj::CallNative(Context *ctx, Obj args) { break; case ObjType::Short: - if (pind < check_count) { + if(pind < check_count) { NL_CHECK(!(*m_func_proto)[pind]->m_type_name.empty(), "Undefined type arg '%s'", (*m_func_proto)[pind]->toString().c_str()); NL_CHECK(canCast(type, typeFromString((*m_func_proto)[pind]->m_type_name, ctx)), "Fail cast from '%s' to '%s'", (*m_func_proto)[pind]->m_type_name.c_str(), newlang::toString(type)); @@ -1957,7 +1964,7 @@ ObjPtr Obj::CallNative(Context *ctx, Obj args) { break; case ObjType::Int: - if (pind < check_count) { + if(pind < check_count) { NL_CHECK(!(*m_func_proto)[pind]->m_type_name.empty(), "Undefined type arg '%s'", (*m_func_proto)[pind]->toString().c_str()); NL_CHECK(canCast(type, typeFromString((*m_func_proto)[pind]->m_type_name, ctx)), "Fail cast from '%s' to '%s'", (*m_func_proto)[pind]->m_type_name.c_str(), newlang::toString(type)); @@ -1968,7 +1975,7 @@ ObjPtr Obj::CallNative(Context *ctx, Obj args) { break; case ObjType::Long: - if (pind < check_count) { + if(pind < check_count) { NL_CHECK(!(*m_func_proto)[pind]->m_type_name.empty(), "Undefined type arg '%s'", (*m_func_proto)[pind]->toString().c_str()); NL_CHECK(canCast(type, typeFromString((*m_func_proto)[pind]->m_type_name, ctx)), "Fail cast from '%s' to '%s'", (*m_func_proto)[pind]->m_type_name.c_str(), newlang::toString(type)); @@ -1979,7 +1986,7 @@ ObjPtr Obj::CallNative(Context *ctx, Obj args) { break; case ObjType::Float: - if (pind < check_count) { + if(pind < check_count) { NL_CHECK(!(*m_func_proto)[pind]->m_type_name.empty(), "Undefined type arg '%s'", (*m_func_proto)[pind]->toString().c_str()); NL_CHECK(canCast(type, typeFromString((*m_func_proto)[pind]->m_type_name, ctx)), "Fail cast from '%s' to '%s'", (*m_func_proto)[pind]->m_type_name.c_str(), newlang::toString(type)); @@ -1990,7 +1997,7 @@ ObjPtr Obj::CallNative(Context *ctx, Obj args) { break; case ObjType::Double: - if (pind < check_count) { + if(pind < check_count) { NL_CHECK(!(*m_func_proto)[pind]->m_type_name.empty(), "Undefined type arg '%s'", (*m_func_proto)[pind]->toString().c_str()); NL_CHECK(canCast(type, typeFromString((*m_func_proto)[pind]->m_type_name, ctx)), "Fail cast from '%s' to '%s'", (*m_func_proto)[pind]->m_type_name.c_str(), newlang::toString(type)); @@ -2003,7 +2010,7 @@ ObjPtr Obj::CallNative(Context *ctx, Obj args) { case ObjType::StrWide: case ObjType::StrChar: ASSERT(type == ObjType::StrChar); - if (pind < check_count) { + if(pind < check_count) { NL_CHECK(!(*m_func_proto)[pind]->m_type_name.empty(), "Undefined type arg '%s'", (*m_func_proto)[pind]->toString().c_str()); NL_CHECK(canCast(type, typeFromString((*m_func_proto)[pind]->m_type_name, ctx)), "Fail cast from '%s' to '%s'", (*m_func_proto)[pind]->m_type_name.c_str(), newlang::toString(type)); @@ -2014,7 +2021,7 @@ ObjPtr Obj::CallNative(Context *ctx, Obj args) { break; case ObjType::Pointer: - if (pind < check_count) { + if(pind < check_count) { NL_CHECK(!(*m_func_proto)[pind]->m_type_name.empty(), "Undefined type arg '%s'", (*m_func_proto)[pind]->toString().c_str()); NL_CHECK(canCast(type, typeFromString((*m_func_proto)[pind]->m_type_name, ctx)), "Fail cast from '%s' to '%s'", (*m_func_proto)[pind]->m_type_name.c_str(), newlang::toString(type)); @@ -2027,7 +2034,7 @@ ObjPtr Obj::CallNative(Context *ctx, Obj args) { default: LOG_RUNTIME("Native arg '%s' not implemented!", args[i]->toString().c_str()); } - if (pind < check_count && (*m_func_proto)[pind]->GetType() && (*m_func_proto)[pind]->GetType()->m_text.compare("Format") == 0) { + if(pind < check_count && (*m_func_proto)[pind]->GetType() && (*m_func_proto)[pind]->GetType()->m_text.compare("Format") == 0) { NL_CHECK(ParsePrintfFormat(args, i), "Fail format string or type args!"); } } @@ -2043,7 +2050,7 @@ ObjPtr Obj::CallNative(Context *ctx, Obj args) { ObjType type = ctx->BaseTypeFromString(m_func_proto->m_type_name); - switch (type) { + switch(type) { case ObjType::Bool: result_ffi_type = &ffi_type_uint8; break; @@ -2083,31 +2090,31 @@ ObjPtr Obj::CallNative(Context *ctx, Obj args) { } ASSERT(m_func_abi == FFI_DEFAULT_ABI); // Нужны другие типы вызовов ??? - if (ffi_prep_cif(&m_cif, m_func_abi, m_args_type.size(), result_ffi_type, m_args_type.data()) == FFI_OK) { + if(ffi_prep_cif(&m_cif, m_func_abi, m_args_type.size(), result_ffi_type, m_args_type.data()) == FFI_OK) { ffi_call(&m_cif, FFI_FN(m_func_ptr), &res_value, m_args_ptr.data()); - if (result_ffi_type == &ffi_type_uint8) { + if(result_ffi_type == &ffi_type_uint8) { // Возвращаемый тип может быть как Byte, так и Bool return Obj::CreateValue(static_cast (res_value.integer), typeFromString(m_func_proto->m_type_name)); - } else if (result_ffi_type == &ffi_type_sint8) { + } else if(result_ffi_type == &ffi_type_sint8) { return Obj::CreateValue(static_cast (res_value.integer), ObjType::Char); - } else if (result_ffi_type == &ffi_type_sint16) { + } else if(result_ffi_type == &ffi_type_sint16) { return Obj::CreateValue(static_cast (res_value.integer), ObjType::Short); - } else if (result_ffi_type == &ffi_type_sint32) { + } else if(result_ffi_type == &ffi_type_sint32) { return Obj::CreateValue(static_cast (res_value.integer), ObjType::Int); - } else if (result_ffi_type == &ffi_type_sint64) { + } else if(result_ffi_type == &ffi_type_sint64) { return Obj::CreateValue(res_value.integer, ObjType::Long); - } else if (result_ffi_type == &ffi_type_float) { + } else if(result_ffi_type == &ffi_type_float) { return Obj::CreateValue(res_value.number, ObjType::Float); - } else if (result_ffi_type == &ffi_type_double) { + } else if(result_ffi_type == &ffi_type_double) { return Obj::CreateValue(res_value.number, ObjType::Double); - } else if (result_ffi_type == &ffi_type_pointer) { - if (type == ObjType::StrChar) { + } else if(result_ffi_type == &ffi_type_pointer) { + if(type == ObjType::StrChar) { return Obj::CreateString(reinterpret_cast (res_value.ptr)); - } else if (type == ObjType::StrWide) { + } else if(type == ObjType::StrWide) { return Obj::CreateString(reinterpret_cast (res_value.ptr)); - } else if (type == ObjType::Pointer) { + } else if(type == ObjType::Pointer) { ObjPtr result = ctx->GetTypeFromString(m_func_proto->m_type_name); result->m_func_ptr = (void *) res_value.ptr; result->m_var_is_init = true; @@ -2127,11 +2134,11 @@ ObjPtr Obj::CallNative(Context *ctx, Obj args) { bool newlang::ParsePrintfFormat(Obj args, size_t start) { - if (args.size() <= start || !args[start]) { + if(args.size() <= start || !args[start]) { LOG_WARNING("Missing format string!"); return false; } - if (!args[start]->is_string_type()) { + if(!args[start]->is_string_type()) { LOG_WARNING("Argument Format '%s' not string type!", args[start]->toString().c_str()); return false; } @@ -2145,9 +2152,9 @@ bool newlang::ParsePrintfFormat(Obj args, size_t start) { unsigned i = 0; unsigned aind = start + 1; ObjType cast; - while (i < types.size()) { + while(i < types.size()) { - if (aind < args.size()) { + if(aind < args.size()) { // if(types[i] & PA_FLAG_PTR == PA_FLAG_PTR) { // LOG_WARNING("Pointer arg '%u' not suppotred!", i); // result = false; @@ -2155,40 +2162,40 @@ bool newlang::ParsePrintfFormat(Obj args, size_t start) { // aind++; // continue; // } - switch (types[i] & ~PA_FLAG_MASK) { + switch(types[i] & ~PA_FLAG_MASK) { case PA_INT: - if (types[i] & PA_FLAG_MASK == 0) { + if(types[i] & PA_FLAG_MASK == 0) { cast = ObjType::Int; - } else if (types[i] & PA_FLAG_LONG == PA_FLAG_LONG) { + } else if(types[i] & PA_FLAG_LONG == PA_FLAG_LONG) { cast = ObjType::Long; - } else if (types[i] & PA_FLAG_SHORT == PA_FLAG_SHORT) { + } else if(types[i] & PA_FLAG_SHORT == PA_FLAG_SHORT) { cast = ObjType::Short; } - if (!canCast(args[aind]->m_var_type_current, cast)) { + if(!canCast(args[aind]->m_var_type_current, cast)) { LOG_WARNING("Cast '%s' to '%s' not supported!", newlang::toString(args[aind]->m_var_type_current), newlang::toString(cast)); result = false; } break; case PA_CHAR: - if (types[i] & PA_FLAG_MASK) { + if(types[i] & PA_FLAG_MASK) { LOG_WARNING("format modifier arg '%s' %u not supported!", newlang::toString(args[aind]->m_var_type_current), i); result = false; } cast = ObjType::Char; - if (!canCast(args[aind]->m_var_type_current, cast)) { + if(!canCast(args[aind]->m_var_type_current, cast)) { LOG_WARNING("Cast '%s' to '%s' not supported!", newlang::toString(args[aind]->m_var_type_current), newlang::toString(cast)); result = false; } break; case PA_STRING: - if (types[i] & PA_FLAG_MASK) { + if(types[i] & PA_FLAG_MASK) { LOG_WARNING("format modifier arg '%s' %u not supported!", newlang::toString(args[aind]->m_var_type_current), i); result = false; } cast = ObjType::StrChar; - if (!canCast(args[aind]->m_var_type_current, cast)) { + if(!canCast(args[aind]->m_var_type_current, cast)) { LOG_WARNING("Cast '%s' to '%s' not supported!", newlang::toString(args[aind]->m_var_type_current), newlang::toString(cast)); result = false; @@ -2196,12 +2203,12 @@ bool newlang::ParsePrintfFormat(Obj args, size_t start) { break; case PA_FLOAT: case PA_DOUBLE: - if (types[i] & PA_FLAG_MASK) { + if(types[i] & PA_FLAG_MASK) { LOG_WARNING("format modifier arg '%s' %u not supported!", newlang::toString(args[aind]->m_var_type_current), i); result = false; } cast = ObjType::Double; - if (!canCast(args[aind]->m_var_type_current, cast)) { + if(!canCast(args[aind]->m_var_type_current, cast)) { LOG_WARNING("Cast '%s' to '%s' not supported!", newlang::toString(args[aind]->m_var_type_current), newlang::toString(cast)); result = false; @@ -2221,7 +2228,7 @@ bool newlang::ParsePrintfFormat(Obj args, size_t start) { i++; aind++; } - if (aind != args.size()) { + if(aind != args.size()) { LOG_WARNING("Extra arguments more %u", i); return false; } @@ -2240,20 +2247,20 @@ void newlang::ConvertRangeToDict(Obj *from, Obj & to) { ASSERT(to.m_var_type_current == ObjType::Dictionary || to.m_var_type_current == ObjType::None); - if (!to.is_dictionary_type()) { + if(!to.is_dictionary_type()) { to.m_var_type_current = ObjType::Dictionary; } ObjPtr value = (*from)["start"]->Clone(); - if ((*value) < (*from)["stop"]) { + if((*value) < (*from)["stop"]) { ASSERT((*from)["step"]->GetValueAsNumber() > 0); - while ((*value) < (*from)["stop"]) { + while((*value) < (*from)["stop"]) { to.push_back(value->Clone()); (*value) += (*from)["step"]; } } else { ASSERT((*from)["step"]->GetValueAsNumber() < 0); - while ((*value) > (*from)["stop"]) { + while((*value) > (*from)["stop"]) { to.push_back(value->Clone()); (*value) += (*from)["step"]; } @@ -2277,7 +2284,7 @@ void newlang::ConvertStringToTensor(const std::wstring &from, torch::Tensor &to, template void ConvertTensorToStringTemplate(const torch::Tensor &from, T &to, std::vector *index) { - if (from.dim() == 0) { + if(from.dim() == 0) { ASSERT(index == nullptr); to = from.toType(at::ScalarType::Char).item(); @@ -2285,13 +2292,13 @@ template void ConvertTensorToStringTemplate(const torch::Tensor &fr } std::vector dims({0}); - if (index == nullptr) { + if(index == nullptr) { to.clear(); index = &dims; } int64_t pos = index->size(); - if (pos == from.dim()) { + if(pos == from.dim()) { for (int i = 0; i < from.size(pos - 1); i++) { (*index)[pos - 1] = i; to += from.index(*index).toType(at::ScalarType::Char).item(); @@ -2317,23 +2324,23 @@ void newlang::ConvertTensorToDict(const torch::Tensor &from, Obj &to, std::vecto to.m_var_is_init = false; ASSERT(to.m_var_type_current == ObjType::Dictionary || to.m_var_type_current == ObjType::None); - if (!to.is_dictionary_type()) { + if(!to.is_dictionary_type()) { to.m_var_type_current = ObjType::Dictionary; } - if (from.dim() == 0) { + if(from.dim() == 0) { ASSERT(index == nullptr); to.push_back(Obj::CreateTensor(from)); return; } std::vector dims({0}); - if (index == nullptr) { + if(index == nullptr) { index = &dims; } int64_t pos = index->size(); - if (pos == from.dim()) { + if(pos == from.dim()) { for (int i = 0; i < from.size(pos - 1); i++) { (*index)[pos - 1] = i; to.push_back(Obj::CreateTensor(from.index(*index))); @@ -2355,11 +2362,11 @@ void newlang::ConvertDictToTensor(Obj &from, torch::Tensor &to, ObjType type) { for (size_t i = 0; i < from.size(); i++) { ConvertValueToTensor(from.at(i).second.get(), temp, type); - if (temp.dim() == 0) { + if(temp.dim() == 0) { temp = temp.reshape({1}); } - if (to.dim() != 1 || to.size(0) == 0) { + if(to.dim() != 1 || to.size(0) == 0) { to = temp.clone(); } else { to = torch::cat({to, temp}); @@ -2372,24 +2379,24 @@ void newlang::ConvertDictToTensor(Obj &from, torch::Tensor &to, ObjType type) { void newlang::ConvertValueToTensor(Obj *from, torch::Tensor &to, ObjType type) { ASSERT(from); - if (from->is_tensor()) { + if(from->is_tensor()) { to = from->m_value.clone(); - if (type == ObjType::None || type == ObjType::Tensor) { + if(type == ObjType::None || type == ObjType::Tensor) { return; } to = to.toType(toTorchType(type)); // if (dims) { // to = to.reshape(*dims); // } - } else if (from->is_range()) { + } else if(from->is_range()) { ObjPtr temp = Obj::CreateNone(); ConvertRangeToDict(from, *temp.get()); ConvertDictToTensor(*temp.get(), to, type); - } else if (from->getType() == ObjType::StrChar) { + } else if(from->getType() == ObjType::StrChar) { ConvertStringToTensor(from->m_str, to, type); - } else if (from->getType() == ObjType::StrWide) { + } else if(from->getType() == ObjType::StrWide) { ConvertStringToTensor(from->m_wstr, to, type); - } else if (from->is_dictionary_type()) { + } else if(from->is_dictionary_type()) { ConvertDictToTensor(*from, to, type); } else { LOG_RUNTIME("Fail convert object type %s to tensor (%s)!", newlang::toString(from->getType()), from->toString().c_str()); @@ -2437,38 +2444,38 @@ ObjPtr Obj::CreateBaseType(ObjType type) { ObjPtr Obj::BaseTypeConstructor(const Context *ctx, Obj & args) { - if (args.empty() || !args[0]) { + if(args.empty() || !args[0]) { LOG_RUNTIME("Self simple type not defined!"); } ASSERT(args[0]->getType() == ObjType::Type); ObjPtr result = nullptr; - if (isArithmeticType(args[0]->m_var_type_fixed)) { + if(isArithmeticType(args[0]->m_var_type_fixed)) { result = ConstructorSimpleType_(ctx, args); - } else if (args[0]->m_var_type_fixed == ObjType::Dictionary) { + } else if(args[0]->m_var_type_fixed == ObjType::Dictionary) { result = ConstructorDictionary_(ctx, args); - } else if (args[0]->m_var_type_fixed == ObjType::Class) { + } else if(args[0]->m_var_type_fixed == ObjType::Class) { result = ConstructorClass_(ctx, args); - } else if (args[0]->m_var_type_fixed == ObjType::Struct || args[0]->m_var_type_fixed == ObjType::Union) { + } else if(args[0]->m_var_type_fixed == ObjType::Struct || args[0]->m_var_type_fixed == ObjType::Union) { result = ConstructorStruct_(ctx, args); - } else if (args[0]->m_var_type_fixed == ObjType::Enum) { + } else if(args[0]->m_var_type_fixed == ObjType::Enum) { result = ConstructorEnum_(ctx, args); - } else if (args[0]->m_var_type_fixed == ObjType::Return) { + } else if(args[0]->m_var_type_fixed == ObjType::Return) { result = ConstructorReturn_(ctx, args); - } else if (args[0]->m_var_type_fixed == ObjType::Break || args[0]->m_var_type_fixed == ObjType::Continue) { + } else if(args[0]->m_var_type_fixed == ObjType::Break || args[0]->m_var_type_fixed == ObjType::Continue) { result = ConstructorInterraption_(ctx, args, args[0]->m_var_type_fixed); - } else if (args[0]->m_var_type_fixed == ObjType::Error || args[0]->m_var_type_fixed == ObjType::ErrorParser + } else if(args[0]->m_var_type_fixed == ObjType::Error || args[0]->m_var_type_fixed == ObjType::ErrorParser || args[0]->m_var_type_fixed == ObjType::ErrorRunTime || args[0]->m_var_type_fixed == ObjType::ErrorSignal) { result = ConstructorError_(ctx, args); } else { result = args[0]->Clone(); - if (result) { + if(result) { result->m_is_const = false; } } - if (!result) { + if(!result) { LOG_RUNTIME("Create type '%s' error or not implemented!", newlang::toString(args[0]->m_var_type_fixed)); } @@ -2485,7 +2492,7 @@ ObjPtr Obj::ConstructorSimpleType_(const Context *ctx, Obj & args) { // Переданы значения для приведения типов // Но само значение пока не установлено ObjPtr result = args[0]->Clone(); - if (args.size() == 1) { + if(args.size() == 1) { // Копия существующего типа с возможностью редактирования result->m_is_const = false; return result; @@ -2493,13 +2500,13 @@ ObjPtr Obj::ConstructorSimpleType_(const Context *ctx, Obj & args) { std::vector dims; - if (result->m_dimensions) { + if(result->m_dimensions) { // Размерность указана for (size_t i = 0; i < result->m_dimensions->size(); i++) { Index ind = (*result->m_dimensions)[i]->toIndex(); - if (ind.is_integer()) { + if(ind.is_integer()) { dims.push_back(ind.integer()); - } else if (ind.is_boolean()) { + } else if(ind.is_boolean()) { dims.push_back(ind.boolean()); } else { LOG_RUNTIME("Non fixed dimension not implemented!"); @@ -2508,13 +2515,13 @@ ObjPtr Obj::ConstructorSimpleType_(const Context *ctx, Obj & args) { } - if (args.size() == 2) { + if(args.size() == 2) { // Передано единственное значение (нулевой аргумент - сам объект, т.е. :Тип(Значение) ) ObjPtr convert; // Если обобщенный тип данных, а сами данные принадлежат обощенному типу - if (isGenericType(result->m_var_type_fixed) && isContainsType(result->m_var_type_fixed, args[1]->getType())) { + if(isGenericType(result->m_var_type_fixed) && isContainsType(result->m_var_type_fixed, args[1]->getType())) { convert = args[1]->Clone(); } else { convert = args[1]->toType(result->m_var_type_fixed); @@ -2531,21 +2538,21 @@ ObjPtr Obj::ConstructorSimpleType_(const Context *ctx, Obj & args) { ObjPtr prev = nullptr; for (int i = 1; i < args.size(); i++) { - if (args[i]->getType() == ObjType::Ellipsis) { - if (!prev) { + if(args[i]->getType() == ObjType::Ellipsis) { + if(!prev) { LOG_RUNTIME("There is no previous item to repeat!"); } - if (i + 1 != args.size()) { + if(i + 1 != args.size()) { LOG_RUNTIME("Ellipsis is not the last element!"); } - if (dims.empty()) { + if(dims.empty()) { LOG_RUNTIME("Object has no dimensions!"); } int64_t full_size = 1; for (int i = 0; i < dims.size(); i++) { full_size *= dims[i]; } - if (full_size <= 0) { + if(full_size <= 0) { LOG_RUNTIME("Items count error for all dimensions!"); } @@ -2562,29 +2569,29 @@ ObjPtr Obj::ConstructorSimpleType_(const Context *ctx, Obj & args) { result->op_concat_(prev, ConcatMode::Append); } - if (args[0]->m_var_type_fixed != ObjType::Dictionary) { + if(args[0]->m_var_type_fixed != ObjType::Dictionary) { result = result->toType(args[0]->m_var_type_fixed); result->m_var_type_fixed = result->m_var_type_current; } } - if (!dims.empty()) { + if(!dims.empty()) { - if (isString(result->getType()) || isDictionary(result->getType())) { - if (dims.size() != 1) { + if(isString(result->getType()) || isDictionary(result->getType())) { + if(dims.size() != 1) { LOG_RUNTIME("Fail size for type '%s'!", newlang::toString(result->getType())); } result->resize_(dims[0], nullptr); - } else if (isTensor(result->getType())) { - if (dims.size() == 1 && dims[0] == 0) { + } else if(isTensor(result->getType())) { + if(dims.size() == 1 && dims[0] == 0) { // Скаляр - if (args.size() == 2 && args[0]->m_var_type_fixed == ObjType::Bool) { + if(args.size() == 2 && args[0]->m_var_type_fixed == ObjType::Bool) { result->m_value = torch::scalar_tensor(result->empty() ? 0 : 1, at::ScalarType::Bool); return result; - } else if (result->size() != 0) { + } else if(result->size() != 0) { LOG_RUNTIME("Only one value is required for a scalar!"); } dims.clear(); @@ -2618,10 +2625,10 @@ ObjPtr Obj::ConstructorClass_(const Context *ctx, Obj & args) { ObjPtr result = ConstructorDictionary_(ctx, args); result->m_var_type_fixed = ObjType::Class; for (int i = 0; i < result->size(); i++) { - if (result->name(i).empty()) { + if(result->name(i).empty()) { LOG_RUNTIME("Field pos %d has no name!", i); } - if (!result->select(result->name(i)).complete()) { + if(!result->select(result->name(i)).complete()) { LOG_RUNTIME("Field name '%s' at index %d already exists!", result->name(i).c_str(), i); } } @@ -2632,15 +2639,15 @@ ObjPtr Obj::ConstructorStruct_(const Context *ctx, Obj & args) { ObjPtr result = ConstructorClass_(ctx, args); result->m_var_type_fixed = ObjType::Struct; - if (!result->size()) { + if(!result->size()) { LOG_RUNTIME("Empty Struct not allowed!"); } for (int i = 0; i < result->size(); i++) { - if (!(*result)[i]) { + if(!(*result)[i]) { LOG_RUNTIME("Field '%s' at pos %d not defined!", result->name(i).c_str(), i); } - if (!(*result)[i] || !isSimpleType((*result)[i]->getType()) || isGenericType((*result)[i]->getType())) { + if(!(*result)[i] || !isSimpleType((*result)[i]->getType()) || isGenericType((*result)[i]->getType())) { LOG_RUNTIME("Field '%s' at pos %d not simple type! (%s)", result->name(i).c_str(), i, newlang::toString((*result)[i]->getType())); } } @@ -2660,8 +2667,8 @@ ObjPtr Obj::ConstructorEnum_(const Context *ctx, Obj & args) { std::string enum_name; for (int i = 1; i < args.size(); i++) { - if (args.name(i).empty()) { - if (args[i] && args[i]->is_string_type()) { + if(args.name(i).empty()) { + if(args[i] && args[i]->is_string_type()) { enum_name = args[i]->GetValueAsString(); } else { LOG_RUNTIME("Field pos %d has no name!", i); @@ -2669,14 +2676,14 @@ ObjPtr Obj::ConstructorEnum_(const Context *ctx, Obj & args) { } else { enum_name = args.name(i); - if (args[i] && (args[i]->is_integer() || args[i]->is_bool_type())) { + if(args[i] && (args[i]->is_integer() || args[i]->is_bool_type())) { val_int = args[i]->GetValueAsInteger(); - } else if (!args[i] || !args[i]->is_none_type()) { + } else if(!args[i] || !args[i]->is_none_type()) { LOG_RUNTIME("Field value '%s' %d must integer type!", args.name(i).c_str(), i); } } - if (!result->select(enum_name).complete()) { + if(!result->select(enum_name).complete()) { LOG_RUNTIME("Field value '%s' at index %d already exists!", enum_name.c_str(), i); } @@ -2697,7 +2704,7 @@ ObjPtr Obj::ConstructorError_(const Context *ctx, Obj & args) { ObjPtr result = ConstructorDictionary_(ctx, args); result->m_var_type_current = ObjType::Error; result->m_var_type_fixed = ObjType::Error; - if (!result->size()) { + if(!result->size()) { LOG_RUNTIME("Argument for type ':Error' required!"); } return result; @@ -2707,10 +2714,10 @@ ObjPtr Obj::ConstructorReturn_(const Context *ctx, Obj & args) { ObjPtr result = ConstructorDictionary_(ctx, args); result->m_var_type_current = ObjType::Return; result->m_var_type_fixed = ObjType::Return; - if (result->size() == 0) { + if(result->size() == 0) { result->push_back(Obj::Arg(Obj::CreateNone())); } - if (result->size() != 1) { + if(result->size() != 1) { LOG_RUNTIME("Multiple argument for type ':Return'!"); } return result; @@ -2720,7 +2727,7 @@ ObjPtr Obj::ConstructorInterraption_(const Context* ctx, Obj& args, ObjType type ObjPtr result = ConstructorDictionary_(ctx, args); result->m_var_type_current = type; result->m_var_type_fixed = type; - if (result->size()) { + if(result->size()) { LOG_RUNTIME("Argument for type %s not allowed!", newlang::toString(type)); } return result; diff --git a/core/object.h b/core/object.h index ca235d77..4de4b260 100644 --- a/core/object.h +++ b/core/object.h @@ -674,8 +674,8 @@ namespace newlang { * или сравнение должно зависить от того, есть ли в образце вложенные словари (классы) ?????????????? */ - bool op_class_test(ObjPtr obj, Context *ctx); - bool op_class_test(const char * name, Context *ctx); + bool op_class_test(ObjPtr obj, Context *ctx) const; + bool op_class_test(const char * name, Context *ctx) const; inline bool op_duck_test(ObjPtr obj, bool strong) { ASSERT(obj); diff --git a/core/parser.h b/core/parser.h index 37c4d2ed..437345b7 100644 --- a/core/parser.h +++ b/core/parser.h @@ -83,6 +83,106 @@ class Parser { void AstAddTerm(TermPtr &term); + typedef std::map MacrosStore; + + inline static const std::string MACROS_START = "\\\\"; + inline static const std::string MACROS_END = "\\\\\\"; + + static inline bool ParseNameMacro(const std::string &body, std::string &name, std::string &args) { + size_t len = 0; + // имя макроса должно быть в самом начале строки без пробелов + if (body.empty() || body[0] != '\\') { + return false; // Нет имени макроса + } + size_t pos = 1; + while (pos < body.size()) { + if (std::isspace(static_cast (body[pos])) || body[pos] == '(') { + name = body.substr(0, pos); + break; + } + pos++; + } + + if (pos == 0) { + LOG_DEBUG("Macro name not found!"); + return false; // Нет имени макроса + } + + // после имени без пробела жет быть открывающая скобка + if (body[pos] != '(') { + args.clear(); + return true; // Открывающей скобки нет, значит нет аргументов + } + size_t start = pos; + while (pos < body.size()) { + if (body[pos] == ')') { + args = body.substr(start, pos); + return true; + } + pos++; + } + LOG_DEBUG("Fail parse macro args!"); + return false; // Нет закрывающей скобки, косяк в аргументах + } + + static size_t ExtractMacros(std::string &text, MacrosStore &store) { + /* + * Сперва искать начало определения макроса \\, потом завершение определения макроса \\\ + * Вырезать тело определения макроса из строки парсинга и добавить макрос в хранилище. + */ + + size_t start = text.find(MACROS_START); // Начало макроса + size_t stop = std::string::npos; + if (start != std::string::npos) { + stop = text.find(MACROS_END, start + MACROS_START.size() + 1); + + if (stop == std::string::npos) { + LOG_RUNTIME("Macro termination symbol not found! Start at %d '%s'", (int) start, text.c_str()); + // throw Interrupt(ParserMessage(buffer, row, col, "%s", msg), Interrupt::Parser); + } + + std::string body = text.substr(start + MACROS_START.size(), stop - MACROS_START.size()); + std::string name; + std::string args; + if (!ParseNameMacro(body, name, args)) { + LOG_RUNTIME("Fail parse name macro! '%s'", body.c_str()); + // throw Interrupt(ParserMessage(buffer, row, col, "%s", msg), Interrupt::Parser); + } + + auto found = store.find(name); + if (found != store.end()) { + std::string f_name; + std::string f_args; + VERIFY(ParseNameMacro(found->second, f_name, f_args)); + if (f_args.empty() == args.empty()) { + LOG_RUNTIME("Macro %s arguments are duplicated! %s %s", name.c_str(), args.c_str(), f_args.c_str()); + // throw Interrupt(ParserMessage(buffer, row, col, "%s", msg), Interrupt::Parser); + } + } + store[name] = body; + + // Заменить определение макроса пробелами, кроме переводов строк, чтобы не съезжала позиция парсинга + std::string fill(stop + MACROS_END.size() - start, ' '); + + ASSERT(fill.size() > body.size()); + for (size_t i = 0; i < body.size(); i++) { + if (body[i] == '\n') { + fill[i] = '\n'; + } + } + text.replace(start, stop + MACROS_END.size(), fill); + } + return store.size(); + } + + static bool ExpandMacros(std::string &text, MacrosStore &store) { + /* + * Искать макросы и заменять их в строке на развернутые определения из хранилища. + */ + return false; + } + + private: TermPtr &m_ast; diff --git a/core/parser.y b/core/parser.y index f8c80377..75311e95 100644 --- a/core/parser.y +++ b/core/parser.y @@ -1502,10 +1502,24 @@ seq_item: condition { $$ = $1; } - | MACRO assign_op MACRO_BODY + | MACRO { - $$ = $2; - $$->Append($1, Term::LEFT); + $$ = $1; + } + | MACRO call + { + $$ = $1; + $$->Append($call, Term::LEFT); + } + | MACRO MACRO_BODY + { + $$ = $1; + $$->Append($2, Term::RIGHT); + } + | MACRO call MACRO_BODY + { + $$ = $1; + $$->Append($call, Term::LEFT); $$->Append($3, Term::RIGHT); } diff --git a/core/test/parser_test.cpp b/core/test/parser_test.cpp index 340bc9d8..83ac3e33 100644 --- a/core/test/parser_test.cpp +++ b/core/test/parser_test.cpp @@ -24,7 +24,7 @@ class ParserTest : public ::testing::Test { int Count(TermID token_id) { int result = 0; for (size_t c = 0; c < ast->size(); c++) { - if ((*ast)[c]->m_id == token_id) { + if((*ast)[c]->m_id == token_id) { result++; } } @@ -1714,6 +1714,99 @@ TEST_F(ParserTest, Exit) { ASSERT_TRUE(Parse("--:class(arg)--;;")); } + +// | MACRO +// { +// $$ = $1; +// } +// | MACRO call +// { +// $$ = $1; +// $$->SetArgs($call); +// } +// | MACRO MACRO_BODY +// { +// $$ = $1; +// $$->Append($2, Term::RIGHT); +// } +// | MACRO call MACRO_BODY +// { +// $$ = $1; +// $$->SetArgs($call); +// $$->Append($3, Term::RIGHT); +// } + +/* + * \\macro body body body body body body body body body\\\ + * \\macro() body\\\ + * \\macro(arg1) \$arg1 body\\\ + * \\macro(arg1, arg2) \$arg1 \$arg2 \$* body\\\ + * \\if(cond) [ cond ] -> \\\ + * \\elseif(cond) ,[ cond ] -> \\\ + * \\else ,[_] -> \\\ + * + * \if(cond) {} [ cond ] -> {} + * \elseif(cond) {} ,[ cond ] -> {} + * \else {}; ,[_] -> {}; + * + * \\while(cond) [cond] -->> \\\ + * \while(cond) {}; [cond] -->> {}; + * + * \\dowhile(cond) <<--[cond]\\\ + * \do {} \dowhile(cond); {}<<--[cond] + * + * \\return --\\\ + * \\return(...) --\$*--\\\ + * \\throw(...) --:Error(\$*)--\\\ + * \return; + * \return(); + * \return(100); + * + * \\match(val, op) [\$val] \$op>\\\ + * \\case(val) [\$val]-->\\\ + * + * \match(val, ~) { + * \case(val) {}; + * }; + * + */ + +int TestExtract(const char * text, Parser::MacrosStore & list, int n_count = 0) { + std::string str(text); + int ret = Parser::ExtractMacros(str, list); + + int counter = 0; + for (int i = 0; i < str.size(); i++) { + if(str[i] == '\n') { + counter++; + } else { + ASSERT(str[i] == ' '); + } + } + ASSERT(counter == n_count); + return ret; +} + +TEST_F(ParserTest, Macro1) { + Parser::MacrosStore macros; + + ASSERT_EQ(1, TestExtract("\\\\macro 12345\\\\\\", macros)); + ASSERT_TRUE(macros.find("\\macro") != macros.end()); + ASSERT_STREQ("macro 12345", macros.find("\\macro")->second.c_str()); + + ASSERT_EQ(2, TestExtract("\\\\macro2() 123\\\\\\", macros)); + ASSERT_TRUE(macros.find("\\macro2") != macros.end()); + ASSERT_STREQ("macro2() 123", macros.find("\\macro2")->second.c_str()); + + ASSERT_EQ(3, TestExtract("\\\\macro3(name)12345\\\\\\", macros)); + ASSERT_TRUE(macros.find("\\macro3") != macros.end()); + ASSERT_STREQ("macro3(name)12345", macros.find("\\macro3")->second.c_str()); + + ASSERT_EQ(4, TestExtract("\\\\macro4(name, name2) 12345\n\n6789\\\\\\;", macros, 2)); + ASSERT_TRUE(macros.find("\\macro4") != macros.end()); + ASSERT_STREQ("macro4(name, name2) 12345\n\n6789", macros.find("\\macro4")->second.c_str()); +} + TEST_F(ParserTest, HelloWorld) { ASSERT_TRUE(Parse("hello(str=\"\") := { printf(format:Format, ...):Int := @import('printf'); printf('%s', $1); $str;};")); // ASSERT_STREQ("!!!!!!!!!!!!!!", ast->toString().c_str()); diff --git a/core/types.h b/core/types.h index c2cee4c3..5f48c830 100644 --- a/core/types.h +++ b/core/types.h @@ -765,8 +765,12 @@ void ParserException(const char *msg, std::string &buffer, int row, int col); return !name.empty() && name[0] == ':'; } + inline bool isMacro(const std::string_view name) { + return !name.empty() && name[0] == '\\'; + } + inline bool isLocalAny(const char *name) { - return name && !(name[0] == '$' || name[0] == '@' || name[0] == ':' || name[0] == '%'); + return name && !(name[0] == '$' || name[0] == '@' || name[0] == ':' || name[0] == '%' || name[0] == '\\'); } inline bool isMutableName(const std::string name) { From 6936390f178b57a1dcda55dcf01866ecbdd162cf Mon Sep 17 00:00:00 2001 From: Aleksandr Ryabikov Date: Sat, 25 Jun 2022 14:26:18 +0300 Subject: [PATCH 03/31] =?UTF-8?q?=D0=9F=D0=B0=D1=80=D1=81=D0=B5=D1=80=20?= =?UTF-8?q?=D0=BC=D0=B0=D0=BA=D1=80=D0=BE=D1=81=D0=BE=D0=B2=20=D1=81=20?= =?UTF-8?q?=D1=82=D0=B5=D1=81=D1=82=D0=B0=D0=BC=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/parser.h | 379 +++++++++++++++++++++++++------------- core/parser.y | 18 +- core/term.h | 17 -- core/test/parser_test.cpp | 240 ++++++++++++++++++++---- core/types.h | 18 +- 5 files changed, 471 insertions(+), 201 deletions(-) diff --git a/core/parser.h b/core/parser.h index 437345b7..97ce4421 100644 --- a/core/parser.h +++ b/core/parser.h @@ -11,182 +11,297 @@ namespace newlang { -/** The Driver class brings together all components. It creates an instance of - * the Parser and Scanner classes and connects them. Then the input stream is - * fed into the scanner object and the parser gets it's token - * sequence. Furthermore the driver object is available in the grammar rules as - * a parameter. Therefore the driver class contains a reference to the - * structure into which the parsed data is saved. */ -class Parser { -public: + /** The Driver class brings together all components. It creates an instance of + * the Parser and Scanner classes and connects them. Then the input stream is + * fed into the scanner object and the parser gets it's token + * sequence. Furthermore the driver object is available in the grammar rules as + * a parameter. Therefore the driver class contains a reference to the + * structure into which the parsed data is saved. */ + class Parser { + public: - /// construct a new parser driver context - // Parser(class CalcContext& calc); + /// construct a new parser driver context + // Parser(class CalcContext& calc); - Parser(TermPtr &ast); + Parser(TermPtr &ast); - /// enable debug output in the flex scanner - bool trace_scanning; + /// enable debug output in the flex scanner + bool trace_scanning; - /// enable debug output in the bison parser - bool trace_parsing; + /// enable debug output in the bison parser + bool trace_parsing; - /// stream name (file or input stream) used for error messages. - std::string streamname; + /// stream name (file or input stream) used for error messages. + std::string streamname; - std::istringstream m_stream; + std::istringstream m_stream; - /** Invoke the scanner and parser for a stream. - * @param in input stream - * @param sname stream name for error messages - * @return true if successfully parsed - */ - bool parse_stream(std::istream& in, const std::string_view sname = "stream input"); + /** Invoke the scanner and parser for a stream. + * @param in input stream + * @param sname stream name for error messages + * @return true if successfully parsed + */ + bool parse_stream(std::istream& in, const std::string_view sname = "stream input"); - /** Invoke the scanner and parser on an input string. - * @param input input string - * @param sname stream name for error messages - * @return true if successfully parsed - */ - bool parse_string(const std::string_view input, const std::string_view sname = "string stream"); + /** Invoke the scanner and parser on an input string. + * @param input input string + * @param sname stream name for error messages + * @return true if successfully parsed + */ + bool parse_string(const std::string_view input, const std::string_view sname = "string stream"); - /** Invoke the scanner and parser on a file. Use parse_stream with a - * std::ifstream if detection of file reading errors is required. - * @param filename input file name - * @return true if successfully parsed - */ - bool parse_file(const std::string_view filename); + /** Invoke the scanner and parser on a file. Use parse_stream with a + * std::ifstream if detection of file reading errors is required. + * @param filename input file name + * @return true if successfully parsed + */ + bool parse_file(const std::string_view filename); - // To demonstrate pure handling of parse errors, instead of - // simply dumping them on the standard error output, we will pass - // them to the driver using the following two member functions. + // To demonstrate pure handling of parse errors, instead of + // simply dumping them on the standard error output, we will pass + // them to the driver using the following two member functions. - /** Error handling with associated line number. This can be modified to - * output the error e.g. to a dialog box. */ - void error(const class location& l, const std::string& m); + /** Error handling with associated line number. This can be modified to + * output the error e.g. to a dialog box. */ + void error(const class location& l, const std::string& m); - /** General error handling. This can be modified to output the error - * e.g. to a dialog box. */ - void error(const std::string_view m); + /** General error handling. This can be modified to output the error + * e.g. to a dialog box. */ + void error(const std::string_view m); - /** Pointer to the current lexer instance, this is used to connect the - * parser to the scanner. It is used in the yylex macro. */ - class Scanner* lexer; + /** Pointer to the current lexer instance, this is used to connect the + * parser to the scanner. It is used in the yylex macro. */ + class Scanner* lexer; - /** Reference to the calculator context filled during parsing of the - * expressions. */ - // class CalcContext& calc; + /** Reference to the calculator context filled during parsing of the + * expressions. */ + // class CalcContext& calc; - TermPtr Parse(const std::string_view str); - static TermPtr ParseString(const std::string_view str); + TermPtr Parse(const std::string_view str); + static TermPtr ParseString(const std::string_view str); - void AstAddTerm(TermPtr &term); + void AstAddTerm(TermPtr &term); - typedef std::map MacrosStore; + typedef std::map MacrosStore; + typedef std::vector MacrosArgs; - inline static const std::string MACROS_START = "\\\\"; - inline static const std::string MACROS_END = "\\\\\\"; + inline static const std::string MACROS_START = "\\\\"; + inline static const std::string MACROS_END = "\\\\\\"; - static inline bool ParseNameMacro(const std::string &body, std::string &name, std::string &args) { - size_t len = 0; - // имя макроса должно быть в самом начале строки без пробелов - if (body.empty() || body[0] != '\\') { - return false; // Нет имени макроса - } - size_t pos = 1; - while (pos < body.size()) { - if (std::isspace(static_cast (body[pos])) || body[pos] == '(') { - name = body.substr(0, pos); - break; + static inline std::string ParseMacroName(const std::string &body) { + // имя макроса должно быть в самом начале строки без пробелов и начинаться на один слешь + if (body.size() < 3 || body[0] != '\\' || body[1] == '\\') { + return std::string(); // Нет имени макроса + } + for (size_t i = 0; i < body.size(); i++) { + if (std::isspace(static_cast (body[i]))) { + return body.substr(0, i); + } else if (body[i] == '(') { + return body.substr(0, i + 1); // Для макросов с аргументами имя включает открывающую скобку + } } - pos++; + return body; // Макрос без тела } - if (pos == 0) { - LOG_DEBUG("Macro name not found!"); - return false; // Нет имени макроса - } + static inline MacrosArgs ParseMacroArgs(const std::string &body) { + std::string name = ParseMacroName(body); + MacrosArgs result; - // после имени без пробела жет быть открывающая скобка - if (body[pos] != '(') { - args.clear(); - return true; // Открывающей скобки нет, значит нет аргументов - } - size_t start = pos; - while (pos < body.size()) { - if (body[pos] == ')') { - args = body.substr(start, pos); - return true; + if (name.size() < 2 || name[name.size() - 1] != '(') { + return result; // Нет имени макроса или аргументов } - pos++; + + std::string arg; + for (size_t i = name.size(); i < body.size(); i++) { + if (body[i] == ',' || body[i] == ')') { + if (!arg.empty()) { + trim(arg); + result.push_back(arg); // новый аргумент макроса + arg.clear(); + } else if (body[i] == ',') { + LOG_RUNTIME("Macro argument missing!"); + } + } + if (body[i] == ')') { + return result; // Аругменты закончились + } else { + if (body[i] != ',') { + arg.append(1, body[i]); // имя аргумента + } + } + } + // Нет закрывающей скобки + LOG_RUNTIME("Closing bracket not found!"); } - LOG_DEBUG("Fail parse macro args!"); - return false; // Нет закрывающей скобки, косяк в аргументах - } - - static size_t ExtractMacros(std::string &text, MacrosStore &store) { - /* - * Сперва искать начало определения макроса \\, потом завершение определения макроса \\\ - * Вырезать тело определения макроса из строки парсинга и добавить макрос в хранилище. + + /** + * Искать в строке text начало определения макроса \\, потом завершение определения макроса \\\ + * Вырезать тело определения макроса из строки и добавить макрос в хранилище store. + * @param text Строка для парсинга + * @param store Хранилище макросов + * @param fill Удалять ли макрос из входной строки + * @return Истина, если была произведена замена, иначе ложь */ + static bool ExtractMacros(std::string &text, MacrosStore &store, bool fill = true) { - size_t start = text.find(MACROS_START); // Начало макроса - size_t stop = std::string::npos; - if (start != std::string::npos) { - stop = text.find(MACROS_END, start + MACROS_START.size() + 1); + ASSERT(MACROS_START.size() == 2); + ASSERT(MACROS_END.size() == 3); - if (stop == std::string::npos) { - LOG_RUNTIME("Macro termination symbol not found! Start at %d '%s'", (int) start, text.c_str()); - // throw Interrupt(ParserMessage(buffer, row, col, "%s", msg), Interrupt::Parser); - } + size_t start = text.find(MACROS_START); // Начало макроса + size_t stop = std::string::npos; + if (start != std::string::npos) { + stop = text.find(MACROS_END, start + MACROS_START.size() + 1); - std::string body = text.substr(start + MACROS_START.size(), stop - MACROS_START.size()); - std::string name; - std::string args; - if (!ParseNameMacro(body, name, args)) { - LOG_RUNTIME("Fail parse name macro! '%s'", body.c_str()); - // throw Interrupt(ParserMessage(buffer, row, col, "%s", msg), Interrupt::Parser); - } + if (stop == std::string::npos) { + LOG_RUNTIME("Macro termination symbol not found! Start at %d '%s'", (int) start, text.c_str()); + // throw Interrupt(ParserMessage(buffer, row, col, "%s", msg), Interrupt::Parser); + } - auto found = store.find(name); - if (found != store.end()) { - std::string f_name; - std::string f_args; - VERIFY(ParseNameMacro(found->second, f_name, f_args)); - if (f_args.empty() == args.empty()) { - LOG_RUNTIME("Macro %s arguments are duplicated! %s %s", name.c_str(), args.c_str(), f_args.c_str()); + std::string body = text.substr(start + MACROS_START.size() - 1, stop - start - MACROS_START.size() + 1); + std::string name = ParseMacroName(body); + if (name.empty()) { + LOG_RUNTIME("Fail parse name macro! '%s'", body.c_str()); // throw Interrupt(ParserMessage(buffer, row, col, "%s", msg), Interrupt::Parser); } + + auto found = store.find(name); + if (found != store.end()) { + LOG_RUNTIME("Macro name %s are duplicated!", name.c_str()); + // throw Interrupt(ParserMessage(buffer, row, col, "%s", msg), Interrupt::Parser); + } + store[name] = body; + + if (fill) { + // Заменить определение макроса пробелами, кроме переводов строк, чтобы не съезжала позиция парсинга + std::string fill(stop + MACROS_END.size() - start, ' '); + + ASSERT(fill.size() > body.size()); + for (size_t i = 0; i < body.size(); i++) { + if (body[i] == '\n') { + fill[i + 1] = '\n'; + } + } + text.replace(start, stop + MACROS_END.size(), fill); + } + return true; } - store[name] = body; + return false; + } - // Заменить определение макроса пробелами, кроме переводов строк, чтобы не съезжала позиция парсинга - std::string fill(stop + MACROS_END.size() - start, ' '); + static std::string ExpandMacro(const std::string ¯o, const std::string &text) { + + std::string name = ParseMacroName(macro); + MacrosArgs args = ParseMacroArgs(macro); + + std::string body_base; + std::string result(text); + + if (name[name.size() - 1] != '(') { + body_base = macro.substr(name.size() + 1); + } else { + size_t pos = name.size(); + while (pos < macro.size()) { + if (macro[pos] == ')') { + // Аругменты закончились + body_base = macro.substr(pos + 1); + break; + } + pos++; + } + if (body_base.empty()) { + // Нет закрывающей скобки + LOG_RUNTIME("Closing bracket not found! '%s'", macro.c_str()); + } + } - ASSERT(fill.size() > body.size()); - for (size_t i = 0; i < body.size(); i++) { - if (body[i] == '\n') { - fill[i] = '\n'; + size_t pos_start = 0; + size_t pos_end = 0; + while ((pos_start + name.size() - 1) < result.size()) { + pos_start = result.find(name, pos_start); + if (pos_start == std::string::npos) { + break; + } + + pos_end = pos_start + name.size(); + + if (name[name.size() - 1] != '(') { + + result.replace(pos_start, pos_end - pos_start, body_base); + + } else { + + size_t bracet_count = 0; + while (pos_end < result.size()) { + if (result[pos_end] == '(') { + bracet_count++; + } else if (result[pos_end] == ')') { + if (bracet_count == 0) { + pos_end++; + break; + } else { + bracet_count--; + } + } + pos_end++; + } + if (pos_end > result.size()) { + // Нет закрывающей скобки + LOG_RUNTIME("Closing bracket not found! '%s'", result.c_str()); + } + + + MacrosArgs args_define = ParseMacroArgs(result.substr(pos_start, pos_end)); + if (args_define.empty()) { + + result.replace(pos_start, pos_end - pos_start, body_base); + + } else { + + std::string body(body_base); + + for (size_t i = 0; i < args.size() && i < args_define.size(); i++) { + // Заменить аргумент по имени + std::string arg_name = "\\\\\\$" + args[i]; + body = std::regex_replace(body, std::regex(arg_name), args_define[i]); + } + + std::string summary; + for (size_t i = 0; i < args_define.size(); i++) { + // Заменить аргумент по номеру + std::string arg_num = "\\\\\\$" + std::to_string(i + 1); + body = std::regex_replace(body, std::regex(arg_num), args_define[i]); + + if (!summary.empty()) { + summary += ","; + } + summary += args_define[i]; + } + body = std::regex_replace(body, std::regex("\\\\\\$\\*"), summary); + + result.replace(pos_start, pos_end - pos_start, body); + } } } - text.replace(start, stop + MACROS_END.size(), fill); + return result; } - return store.size(); - } - static bool ExpandMacros(std::string &text, MacrosStore &store) { - /* - * Искать макросы и заменять их в строке на развернутые определения из хранилища. + /** + * Развернуть макросы во входной строке + * @param text Входная строка + * @param store Храниличе макросов + * @return */ - return false; - } + static bool ExpandMacros(std::string &text, MacrosStore &store) { + + return false; + } -private: - TermPtr &m_ast; + private: + TermPtr &m_ast; -}; + }; } // namespace example diff --git a/core/parser.y b/core/parser.y index 75311e95..6ec43768 100644 --- a/core/parser.y +++ b/core/parser.y @@ -1504,23 +1504,11 @@ seq_item: condition } | MACRO { - $$ = $1; + $$ = $1; // Их быть не должно, т.к. макросы должны раскрываться до парсинга синтаксиса } - | MACRO call + | MACRO_BODY { - $$ = $1; - $$->Append($call, Term::LEFT); - } - | MACRO MACRO_BODY - { - $$ = $1; - $$->Append($2, Term::RIGHT); - } - | MACRO call MACRO_BODY - { - $$ = $1; - $$->Append($call, Term::LEFT); - $$->Append($3, Term::RIGHT); + $$ = $1; // Их быть не должно, т.к. макросы должны раскрываться до парсинга синтаксиса } sequence: seq_item diff --git a/core/term.h b/core/term.h index dddfd403..835fc952 100644 --- a/core/term.h +++ b/core/term.h @@ -1091,22 +1091,5 @@ namespace newlang { std::ostream & operator<<(std::ostream &out, newlang::TermPtr & var); std::ostream & operator<<(std::ostream &out, newlang::TermPtr var); - - constexpr const char* ws = " \t\n\r\f\v"; - - inline std::string & rtrim(std::string& s, const char* t = ws) { - s.erase(s.find_last_not_of(t) + 1); - return s; - } - - inline std::string & ltrim(std::string& s, const char* t = ws) { - s.erase(0, s.find_first_not_of(t)); - return s; - } - - inline std::string & trim(std::string& s, const char* t = ws) { - return ltrim(rtrim(s, t), t); - } - } #endif // INCLUDED_NEWLANG_TERM_ diff --git a/core/test/parser_test.cpp b/core/test/parser_test.cpp index 83ac3e33..f44a542b 100644 --- a/core/test/parser_test.cpp +++ b/core/test/parser_test.cpp @@ -24,7 +24,7 @@ class ParserTest : public ::testing::Test { int Count(TermID token_id) { int result = 0; for (size_t c = 0; c < ast->size(); c++) { - if((*ast)[c]->m_id == token_id) { + if ((*ast)[c]->m_id == token_id) { result++; } } @@ -1749,11 +1749,11 @@ TEST_F(ParserTest, Exit) { * \elseif(cond) {} ,[ cond ] -> {} * \else {}; ,[_] -> {}; * - * \\while(cond) [cond] -->> \\\ - * \while(cond) {}; [cond] -->> {}; + * \\while(cond) [cond] <<->> \\\ + * \while(cond) {}; [cond] <<->> {}; * - * \\dowhile(cond) <<--[cond]\\\ - * \do {} \dowhile(cond); {}<<--[cond] + * \\dowhile(cond) <<->>[cond]\\\ + * {} \dowhile(cond); {}<<->>[cond] * * \\return --\\\ * \\return(...) --\$*--\\\ @@ -1771,40 +1771,208 @@ TEST_F(ParserTest, Exit) { * */ -int TestExtract(const char * text, Parser::MacrosStore & list, int n_count = 0) { - std::string str(text); - int ret = Parser::ExtractMacros(str, list); - - int counter = 0; - for (int i = 0; i < str.size(); i++) { - if(str[i] == '\n') { - counter++; - } else { - ASSERT(str[i] == ' '); - } - } - ASSERT(counter == n_count); - return ret; -} - -TEST_F(ParserTest, Macro1) { +TEST_F(ParserTest, MacroName) { + std::string body = "\\macro"; + ASSERT_STREQ("\\macro", Parser::ParseMacroName(body).c_str()); + body = "\\macro "; + ASSERT_STREQ("\\macro", Parser::ParseMacroName(body).c_str()); + body = "\\macro()"; + ASSERT_STREQ("\\macro(", Parser::ParseMacroName(body).c_str()); + body = "\\macro(123)"; + ASSERT_STREQ("\\macro(", Parser::ParseMacroName(body).c_str()); + body = "\\macro ()"; + ASSERT_STREQ("\\macro", Parser::ParseMacroName(body).c_str()); + body = "\\macro)"; + body = "\\macro\n"; + ASSERT_STREQ("\\macro", Parser::ParseMacroName(body).c_str()); + body = "\\macro)"; + ASSERT_STREQ("\\macro)", Parser::ParseMacroName(body).c_str()); + body = "\\\\macro()"; + ASSERT_STREQ("", Parser::ParseMacroName(body).c_str()); + body = "macro"; + ASSERT_STREQ("", Parser::ParseMacroName(body).c_str()); + body = ""; + ASSERT_STREQ("", Parser::ParseMacroName(body).c_str()); +} + +TEST_F(ParserTest, MacroArgs) { + Parser::MacrosArgs args; + std::string body = "\\macro"; + args = Parser::ParseMacroArgs(body); + ASSERT_EQ(0, args.size()); + + body = "\\macro "; + args = Parser::ParseMacroArgs(body); + ASSERT_EQ(0, args.size()); + + body = "\\macro()"; + args = Parser::ParseMacroArgs(body); + ASSERT_EQ(0, args.size()); + + body = "\\macro(123)"; + args = Parser::ParseMacroArgs(body); + ASSERT_EQ(1, args.size()); + ASSERT_STREQ("123", args[0].c_str()); + + body = "\\macro(1,2, 3 )"; + args = Parser::ParseMacroArgs(body); + ASSERT_EQ(3, args.size()); + ASSERT_STREQ("1", args[0].c_str()); + ASSERT_STREQ("2", args[1].c_str()); + ASSERT_STREQ("3", args[2].c_str()); + + body = "\\macro(1,2, 3 )"; + args = Parser::ParseMacroArgs(body); + ASSERT_EQ(3, args.size()); + ASSERT_STREQ("1", args[0].c_str()); + ASSERT_STREQ("2", args[1].c_str()); + ASSERT_STREQ("3", args[2].c_str()); + + body = "\\macro(11,22, 3 33 )"; + args = Parser::ParseMacroArgs(body); + ASSERT_EQ(3, args.size()); + ASSERT_STREQ("11", args[0].c_str()); + ASSERT_STREQ("22", args[1].c_str()); + ASSERT_STREQ("3 33", args[2].c_str()); + + body = "\\macro(11, ...)"; + args = Parser::ParseMacroArgs(body); + ASSERT_EQ(2, args.size()); + ASSERT_STREQ("11", args[0].c_str()); + ASSERT_STREQ("...", args[1].c_str()); + + body = "\\macro)"; + args = Parser::ParseMacroArgs(body); + ASSERT_EQ(0, args.size()); + + body = "\\macro\n"; + args = Parser::ParseMacroArgs(body); + ASSERT_EQ(0, args.size()); + + body = "\\macro)"; + args = Parser::ParseMacroArgs(body); + ASSERT_EQ(0, args.size()); + + body = "\\\\macro()"; + args = Parser::ParseMacroArgs(body); + ASSERT_EQ(0, args.size()); + + body = "macro"; + args = Parser::ParseMacroArgs(body); + ASSERT_EQ(0, args.size()); + + body = ""; + args = Parser::ParseMacroArgs(body); + ASSERT_EQ(0, args.size()); +} + +TEST_F(ParserTest, MacroExtract) { Parser::MacrosStore macros; - ASSERT_EQ(1, TestExtract("\\\\macro 12345\\\\\\", macros)); + std::string body = "\\\\macro 12345\\\\\\"; + ASSERT_TRUE(Parser::ExtractMacros(body, macros)); + ASSERT_EQ(1, macros.size()); ASSERT_TRUE(macros.find("\\macro") != macros.end()); - ASSERT_STREQ("macro 12345", macros.find("\\macro")->second.c_str()); - - ASSERT_EQ(2, TestExtract("\\\\macro2() 123\\\\\\", macros)); - ASSERT_TRUE(macros.find("\\macro2") != macros.end()); - ASSERT_STREQ("macro2() 123", macros.find("\\macro2")->second.c_str()); - - ASSERT_EQ(3, TestExtract("\\\\macro3(name)12345\\\\\\", macros)); - ASSERT_TRUE(macros.find("\\macro3") != macros.end()); - ASSERT_STREQ("macro3(name)12345", macros.find("\\macro3")->second.c_str()); - - ASSERT_EQ(4, TestExtract("\\\\macro4(name, name2) 12345\n\n6789\\\\\\;", macros, 2)); - ASSERT_TRUE(macros.find("\\macro4") != macros.end()); - ASSERT_STREQ("macro4(name, name2) 12345\n\n6789", macros.find("\\macro4")->second.c_str()); + ASSERT_STREQ("\\macro 12345", macros.find("\\macro")->second.c_str()); + ASSERT_STREQ(" ", body.c_str()); + + body = "\\\\macro2() 123\\\\\\"; + ASSERT_TRUE(Parser::ExtractMacros(body, macros)); + ASSERT_EQ(2, macros.size()); + ASSERT_TRUE(macros.find("\\macro2(") != macros.end()); + ASSERT_STREQ("\\macro2() 123", macros.find("\\macro2(")->second.c_str()); + ASSERT_STREQ(" ", body.c_str()); + + body = "\\\\macro3(name)12345\\\\\\"; + ASSERT_TRUE(Parser::ExtractMacros(body, macros)); + ASSERT_EQ(3, macros.size()); + ASSERT_TRUE(macros.find("\\macro3(") != macros.end()); + ASSERT_STREQ("\\macro3(name)12345", macros.find("\\macro3(")->second.c_str()); + ASSERT_STREQ(" ", body.c_str()); + + body = "\\\\macro4(name, name2) 12345\n\n6789\\\\\\"; + ASSERT_TRUE(Parser::ExtractMacros(body, macros)); + ASSERT_EQ(4, macros.size()); + ASSERT_TRUE(macros.find("\\macro3(") != macros.end()); + ASSERT_STREQ("\\macro4(name, name2) 12345\n\n6789", macros.find("\\macro4(")->second.c_str()); + ASSERT_STREQ(" \n\n ", body.c_str()); +} + +TEST_F(ParserTest, ExpandMacro) { + + std::string macro = "\\macro 12345"; + std::string body = "\\macro"; + std::string result = Parser::ExpandMacro(macro, body); + ASSERT_STREQ("12345", result.c_str()); + + body = "\\macro \\macro"; + result = Parser::ExpandMacro(macro, body); + ASSERT_STREQ("12345 12345", result.c_str()); + + body = "\\macro \\macro \\macro"; + result = Parser::ExpandMacro(macro, body); + ASSERT_STREQ("12345 12345 12345", result.c_str()); + + macro = "\\macro() 12345"; + body = "\\macro \\macro \\macro"; + result = Parser::ExpandMacro(macro, body); + ASSERT_STREQ("\\macro \\macro \\macro", result.c_str()); + + macro = "\\macro()12345"; + body = "\\macro() \\macro() \\macro"; + result = Parser::ExpandMacro(macro, body); + ASSERT_STREQ("12345 12345 \\macro", result.c_str()); + + macro = "\\macro()12345"; + body = "\\macro(88) \\macro(99) \\macro"; + result = Parser::ExpandMacro(macro, body); + ASSERT_STREQ("12345 12345 \\macro", result.c_str()); + + + macro = "\\macro(arg)\\$arg"; + body = "\\macro(88)"; + result = Parser::ExpandMacro(macro, body); + ASSERT_STREQ("88", result.c_str()); + + macro = "\\macro(arg)no arg \\$arg"; + body = "\\macro(99)"; + result = Parser::ExpandMacro(macro, body); + ASSERT_STREQ("no arg 99", result.c_str()); + + macro = "\\macro(arg) no arg \\$arg no arg"; + body = "\\macro(88) \\macro(99)"; + result = Parser::ExpandMacro(macro, body); + ASSERT_STREQ(" no arg 88 no arg no arg 99 no arg", result.c_str()); + + macro = "\\macro(arg1,arg2) \\$arg1 arg \\$arg2 \\$arg2"; + body = "\\macro(88,99)"; + result = Parser::ExpandMacro(macro, body); + ASSERT_STREQ(" 88 arg 99 99", result.c_str()); + + macro = "\\macro(arg1,arg2) \\$arg1 \\$arg2 \\$arg2"; + body = "\\macro(1,2) \\macro(3,44)"; + result = Parser::ExpandMacro(macro, body); + ASSERT_STREQ(" 1 2 2 3 44 44", result.c_str()); + + macro = "\\macro(arg1,arg2) \\$1 \\$2 \\$1"; + body = "\\macro(1,2) \\macro(3,44)"; + result = Parser::ExpandMacro(macro, body); + ASSERT_STREQ(" 1 2 1 3 44 3", result.c_str()); + + macro = "\\macro(arg1,arg2)\\$*"; + body = "\\macro(1,2)"; + result = Parser::ExpandMacro(macro, body); + ASSERT_STREQ("1,2", result.c_str()); + + macro = "\\macro(arg1,arg2)\\$* \\$1 \\$arg2\\$*"; + body = "\\macro(1,2)"; + result = Parser::ExpandMacro(macro, body); + ASSERT_STREQ("1,2 1 21,2", result.c_str()); + + macro = "\\macro(arg1,arg2)\\$* \\$1 \\$arg2\\$*"; + body = "\\macro(1,2)\\macro(1,2)"; + result = Parser::ExpandMacro(macro, body); + ASSERT_STREQ("1,2 1 21,21,2 1 21,2", result.c_str()); } TEST_F(ParserTest, HelloWorld) { diff --git a/core/types.h b/core/types.h index 5f48c830..e207b7d0 100644 --- a/core/types.h +++ b/core/types.h @@ -5,6 +5,22 @@ namespace newlang { + static constexpr const char* ws = " \t\n\r\f\v"; + + inline std::string & rtrim(std::string& s, const char* t = ws) { + s.erase(s.find_last_not_of(t) + 1); + return s; + } + + inline std::string & ltrim(std::string& s, const char* t = ws) { + s.erase(0, s.find_first_not_of(t)); + return s; + } + + inline std::string & trim(std::string& s, const char* t = ws) { + return ltrim(rtrim(s, t), t); + } + typedef at::indexing::TensorIndex Index; typedef at::IntArrayRef Dimension; @@ -554,7 +570,7 @@ void ParserException(const char *msg, std::string &buffer, int row, int col); if (set.dim() != 0) { self = set.clone(); return; - + ASSERT(set.dim() == 0); } From 9ccbb4dc8c164a56cf2d8616a0759850511b2fff Mon Sep 17 00:00:00 2001 From: Aleksandr Ryabikov Date: Sat, 25 Jun 2022 21:05:11 +0300 Subject: [PATCH 04/31] =?UTF-8?q?=D0=92=20=D0=BF=D1=80=D0=BE=D1=86=D0=B5?= =?UTF-8?q?=D1=81=D1=81=D0=B5=20=D0=BE=D1=82=D0=BB=D0=B0=D0=B4=D0=BA=D0=B8?= =?UTF-8?q?=20=D0=BC=D0=B0=D0=BA=D1=80=D0=BE=D1=81=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/context.cpp | 351 +++++++++--------- core/context.h | 8 +- core/nlc.h | 15 +- core/parser.cpp | 13 +- core/parser.h | 63 ++-- .../{newlang_test.cpp => compiler_test.cpp} | 138 +------ core/test/eval_test.cpp | 318 +++++----------- core/test/object_test.cpp | 88 +++++ core/test/parser_test.cpp | 124 +++++-- 9 files changed, 519 insertions(+), 599 deletions(-) rename core/test/{newlang_test.cpp => compiler_test.cpp} (79%) diff --git a/core/context.cpp b/core/context.cpp index da397910..1324cb59 100644 --- a/core/context.cpp +++ b/core/context.cpp @@ -42,12 +42,12 @@ std::map Context::m_ops; std::map Context::m_builtin_calls; std::map Context::m_types; std::map Context::m_funcs; -std::map Context::m_macros; +Parser::MacrosStore Context::m_macros; Context::Context(RuntimePtr global) { m_runtime = global; - if(Context::m_funcs.empty()) { + if (Context::m_funcs.empty()) { VERIFY(CreateBuiltin("min(arg, ...)", (void *) &min, ObjType::TRANSPARENT)); VERIFY(CreateBuiltin("мин(arg, ...)", (void *) &min, ObjType::TRANSPARENT)); @@ -62,7 +62,7 @@ Context::Context(RuntimePtr global) { } - if(Context::m_types.empty()) { + if (Context::m_types.empty()) { VERIFY(RegisterTypeHierarchy(ObjType::None,{})); VERIFY(RegisterTypeHierarchy(ObjType::Any,{})); @@ -136,7 +136,7 @@ Context::Context(RuntimePtr global) { } - if(Context::m_builtin_calls.empty()) { + if (Context::m_builtin_calls.empty()) { #define REGISTER_FUNC(name, func) \ ASSERT(Context::m_builtin_calls.find(name) == Context::m_builtin_calls.end()); \ Context::m_builtin_calls[name] = &Context::func_##func; @@ -146,7 +146,7 @@ Context::Context(RuntimePtr global) { #undef REGISTER_FUNC } - if(Context::m_ops.empty()) { + if (Context::m_ops.empty()) { #define REGISTER_OP(op, func) \ ASSERT(Context::m_ops.find(op) == Context::m_ops.end()); \ Context::m_ops[op] = &Context::op_##func; @@ -164,7 +164,7 @@ bool Context::CreateBuiltin(const char *prototype, void *func, ObjType type) { std::string func_dump(prototype); func_dump += " := {};"; - TermPtr proto = Parser::ParseString(func_dump); + TermPtr proto = Parser::ParseString(func_dump, &m_macros); ASSERT(proto->Left() && !proto->Left()->getText().empty()); ObjPtr obj = Obj::CreateFunc(this, proto->Left(), type, proto->Left()->getText()); @@ -172,7 +172,7 @@ bool Context::CreateBuiltin(const char *prototype, void *func, ObjType type) { obj->m_var_is_init = true; auto found = m_funcs.find(proto->Left()->getText()); - if(found != m_funcs.end()) { + if (found != m_funcs.end()) { LOG_DEBUG("Buildin function %s already exists!", proto->Left()->toString().c_str()); return false; } @@ -183,7 +183,7 @@ bool Context::CreateBuiltin(const char *prototype, void *func, ObjType type) { inline ObjType newlang::typeFromString(const std::string type, Context *ctx, bool *has_error) { - if(ctx) { + if (ctx) { return ctx->BaseTypeFromString(type, has_error); } @@ -192,15 +192,15 @@ inline ObjType newlang::typeFromString(const std::string type, Context *ctx, boo return ObjType:: name; \ } - if(type.empty()) { + if (type.empty()) { return ObjType::None; - } else if(type.compare("_") == 0) { + } else if (type.compare("_") == 0) { return ObjType::None; } NL_TYPES(DEFINE_CASE) #undef DEFINE_CASE - if(has_error) { + if (has_error) { *has_error = true; return ObjType::None; @@ -209,16 +209,16 @@ inline ObjType newlang::typeFromString(const std::string type, Context *ctx, boo } ObjPtr Context::RegisterObject(ObjPtr var) { - if(!var || var->getName().empty()) { + if (!var || var->getName().empty()) { LOG_RUNTIME("Empty object name %s", var ? var->toString().c_str() : ""); } ASSERT(var->m_namespace.empty()); - if(isGlobal(var->getName())) { + if (isGlobal(var->getName())) { var->getName() = var->getName().substr(1); m_global_terms.push_back(var, var->getName()); } - if(isLocal(var->getName())) { + if (isLocal(var->getName())) { var->getName() = var->getName().substr(1); } push_back(var, var->getName()); @@ -241,7 +241,7 @@ ObjPtr Context::ExecStr(Context *ctx, TermPtr term, Obj *args) { // auto previous_handler = signal(SIGABRT, &NewLangSignalHandler); // try { - switch(term->m_id) { + switch (term->m_id) { case TermID::END: return eval_END(ctx, term, args); @@ -269,10 +269,7 @@ ObjPtr Context::ExecStr(Context *ctx, TermPtr term, Obj *args) { } ObjPtr Context::eval_END(Context *ctx, const TermPtr &term, Obj *args) { - ASSERT(term && term->m_text.compare("") == 0); - LOG_RUNTIME("eval_END: %s", term->toString().c_str()); - - return nullptr; + return Obj::CreateNone(); } ObjPtr Context::eval_UNKNOWN(Context *ctx, const TermPtr &term, Obj *args) { @@ -465,7 +462,7 @@ ObjPtr Context::CREATE_OR_ASSIGN(Context *ctx, const TermPtr &term, Obj *local_v std::vector list_obj; // Список реальных переменных ассоциированных с терминами TermPtr next = term->Left(); - while(next && next->getTermID() != TermID::END) { + while (next && next->getTermID() != TermID::END) { list_term.push_back(next); next = next->m_comma_seq; } @@ -474,41 +471,41 @@ ObjPtr Context::CREATE_OR_ASSIGN(Context *ctx, const TermPtr &term, Obj *local_v bool is_ellipsis = false; for (auto & elem : list_term) { - if(elem->getTermID() == TermID::ELLIPSIS) { + if (elem->getTermID() == TermID::ELLIPSIS) { //@todo добавить поддержку многоточия с левой стороный оператора присвоения NL_PARSER(elem, "Ellipsis on the left side in assignment not implemented!"); - if(is_ellipsis) { + if (is_ellipsis) { NL_PARSER(elem, "Multiple ellipsis on the left side of the assignment!"); } is_ellipsis = true; result = Obj::CreateType(ObjType::Ellipsis); - } else if(elem->getTermID() == TermID::NONE) { + } else if (elem->getTermID() == TermID::NONE) { result = Obj::CreateNone(); } else { auto found = ctx->select(elem->m_text); - if(found.complete() && mode == CreateMode::ASSIGN_ONLY) { + if (found.complete() && mode == CreateMode::ASSIGN_ONLY) { NL_PARSER(elem, "Variable '%s' not found!", elem->m_text.c_str()); } - if(!found.complete()) { + if (!found.complete()) { result = (*found).lock(); // Но она может быть возвращена как локальная } - if(result && mode == CreateMode::CREATE_ONLY) { + if (result && mode == CreateMode::CREATE_ONLY) { NL_PARSER(elem, "Variable '%s' already exists!", elem->m_text.c_str()); } - if(!term->Right()) { // Удаление глобальной переменной + if (!term->Right()) { // Удаление глобальной переменной ctx->erase(found); } else { - if(!result && (mode == CreateMode::ASSIGN_ONLY)) { + if (!result && (mode == CreateMode::ASSIGN_ONLY)) { NL_PARSER(term->Left(), "Object '%s' not found!", term->Left()->m_text.c_str()); } - if(!result) { + if (!result) { result = CreateLVal(ctx, elem, local_vars); - if(!result) { + if (!result) { NL_PARSER(term->Left(), "Fail create lvalue object!"); } } @@ -517,7 +514,7 @@ ObjPtr Context::CREATE_OR_ASSIGN(Context *ctx, const TermPtr &term, Obj *local_v list_obj.push_back(result); } - if(!term->Right()) { + if (!term->Right()) { // Для удаления переменных все сделано return result; } @@ -525,38 +522,38 @@ ObjPtr Context::CREATE_OR_ASSIGN(Context *ctx, const TermPtr &term, Obj *local_v // Что присваиваем (правая часть выражения) - пока единичный объект // @todo В будущем можно будет сделать сахар для обмена значениями при одинаковом кол-ве объектов у оператора присваивания // a, b = b, a; a, b, c = c, b, a; и т.д. - if(term->Right() && term->Right()->getTermID() != TermID::ELLIPSIS && term->Right()->m_comma_seq) { + if (term->Right() && term->Right()->getTermID() != TermID::ELLIPSIS && term->Right()->m_comma_seq) { NL_PARSER(term->Right()->Right(), "Multiple assignments not implemented!"); } ObjPtr rval; - if(term->Right()->getTermID() == TermID::ELLIPSIS) { + if (term->Right()->getTermID() == TermID::ELLIPSIS) { ASSERT(term->Right()->Right()); rval = ExecStr(ctx, term->Right()->Right(), local_vars); } else { rval = ExecStr(ctx, term->Right(), local_vars); } - if(!rval) { + if (!rval) { NL_PARSER(term->Right(), "Object is missing or expression is not evaluated!"); } ASSERT(list_obj.size() == list_term.size()); - if(term->Right()->getTermID() == TermID::ELLIPSIS) { - if(rval->is_dictionary_type() || rval->is_tensor()) { - if(rval->is_scalar()) { + if (term->Right()->getTermID() == TermID::ELLIPSIS) { + if (rval->is_dictionary_type() || rval->is_tensor()) { + if (rval->is_scalar()) { LOG_RUNTIME("Fail expand scalar!"); } for (int i = 0; i < list_obj.size() - 1; i++) { - if(list_term[i]->getTermID() != TermID::NONE) { - if(i < rval->size()) { + if (list_term[i]->getTermID() != TermID::NONE) { + if (i < rval->size()) { list_obj[i]->SetValue_((*rval)[i]); //->Clone() } else { list_obj[i]->SetValue_(Obj::CreateNone()); } } } - if(list_obj.size() - 1 < rval->size()) { + if (list_obj.size() - 1 < rval->size()) { // Удалить первые элементы rval->resize_(-(rval->size() - (list_obj.size() - 1)), nullptr); } else { @@ -573,10 +570,10 @@ ObjPtr Context::CREATE_OR_ASSIGN(Context *ctx, const TermPtr &term, Obj *local_v // Присвоеить единственное значение всем элементам с левой стороны оператора присовения for (int i = 0; i < list_obj.size(); i++) { - if(isType(list_term[i]->m_text)) { + if (isType(list_term[i]->m_text)) { // Новый тип - if(ctx->m_types.find(list_term[i]->m_text) != ctx->m_types.end()) { + if (ctx->m_types.find(list_term[i]->m_text) != ctx->m_types.end()) { LOG_RUNTIME("Type name '%s' already exists!", list_term[i]->m_text.c_str()); } @@ -587,11 +584,11 @@ ObjPtr Context::CREATE_OR_ASSIGN(Context *ctx, const TermPtr &term, Obj *local_v ctx->m_types[list_term[i]->m_text] = result; - } else if(list_term[i]->getTermID() == TermID::NONE) { + } else if (list_term[i]->getTermID() == TermID::NONE) { // Skip } else { list_obj[i]->SetValue_(rval); - if(list_obj[i]->m_var_type_current == ObjType::FUNCTION && (rval->m_var_type_current == ObjType::BLOCK || rval->m_var_type_current == ObjType::BLOCK_TRY)) { + if (list_obj[i]->m_var_type_current == ObjType::FUNCTION && (rval->m_var_type_current == ObjType::BLOCK || rval->m_var_type_current == ObjType::BLOCK_TRY)) { list_obj[i]->m_var_type_current = ObjType::EVAL_FUNCTION; } result = list_obj[i]; @@ -630,8 +627,8 @@ ObjPtr Context::eval_FUNCTION(Context *ctx, const TermPtr &term, Obj * args) { ASSERT(ctx); auto found = ctx->select(term->Left()->m_text); - if(!term->Right()) { - if(!found.complete()) { + if (!term->Right()) { + if (!found.complete()) { ctx->erase(found); return Obj::Yes(); } @@ -639,22 +636,22 @@ ObjPtr Context::eval_FUNCTION(Context *ctx, const TermPtr &term, Obj * args) { } ObjPtr lval = CreateLVal(ctx, term->Left(), args); - if(!lval) { + if (!lval) { NL_PARSER(term->Left(), "Fail create lvalue object!"); } - if(term->Right()->getTermID() == TermID::CALL) { + if (term->Right()->getTermID() == TermID::CALL) { lval->SetValue_(CreateRVal(ctx, term->Right())); } else { - if(term->getTermID() == TermID::FUNCTION) { + if (term->getTermID() == TermID::FUNCTION) { lval->m_var_type_current = ObjType::EVAL_FUNCTION; - } else if(term->getTermID() == TermID::TRANSPARENT) { + } else if (term->getTermID() == TermID::TRANSPARENT) { lval->m_var_type_current = ObjType::SimplePureFunc; - } else if(term->getTermID() == TermID::SIMPLE_AND) { + } else if (term->getTermID() == TermID::SIMPLE_AND) { lval->m_var_type_current = ObjType::SimplePureAND; - } else if(term->getTermID() == TermID::SIMPLE_OR) { + } else if (term->getTermID() == TermID::SIMPLE_OR) { lval->m_var_type_current = ObjType::SimplePureOR; - } else if(term->getTermID() == TermID::SIMPLE_XOR) { + } else if (term->getTermID() == TermID::SIMPLE_XOR) { lval->m_var_type_current = ObjType::SimplePureXOR; } else { @@ -732,7 +729,7 @@ ObjPtr Context::eval_WHILE(Context *ctx, const TermPtr &term, Obj * args) { ObjPtr result = Obj::CreateNone(); ObjPtr cond = ExecStr(ctx, term->Left(), args); - while(cond->GetValueAsBoolean()) { + while (cond->GetValueAsBoolean()) { result = CreateRVal(ctx, term->Right(), args); cond = ExecStr(ctx, term->Left(), args); @@ -749,7 +746,7 @@ ObjPtr Context::eval_UNTIL(Context *ctx, const TermPtr &term, Obj * args) { do { result = CreateRVal(ctx, term->Left(), args); cond = ExecStr(ctx, term->Right(), args); - } while(cond->GetValueAsBoolean()); + } while (cond->GetValueAsBoolean()); return result; } @@ -767,7 +764,7 @@ ObjPtr Context::eval_FOLLOW(Context *ctx, const TermPtr &term, Obj * args) { ASSERT(term->m_follow[i]->Left()); ObjPtr cond = ExecStr(ctx, term->m_follow[i]->Left(), args); - if(cond->GetValueAsBoolean() || (i + 1 == term->m_follow.size() && cond->is_none_type())) { + if (cond->GetValueAsBoolean() || (i + 1 == term->m_follow.size() && cond->is_none_type())) { return CreateRVal(ctx, term->m_follow[i]->Right(), args); } @@ -776,7 +773,7 @@ ObjPtr Context::eval_FOLLOW(Context *ctx, const TermPtr &term, Obj * args) { } bool Context::MatchCompare(Obj &match, ObjPtr &value, MatchMode mode, Context *ctx) { - switch(mode) { + switch (mode) { case MatchMode::EQUAL: return match.op_equal(value); case MatchMode::STRICT: @@ -796,7 +793,7 @@ bool Context::MatchEstimate(Obj &match, const TermPtr &match_item, MatchMode mod ObjPtr cond = CreateRVal(ctx, match_item, args); - if(cond->is_none_type() || MatchCompare(match, cond, mode, ctx)) { + if (cond->is_none_type() || MatchCompare(match, cond, mode, ctx)) { return true; } else { for (int i = 0; i < match_item->m_follow.size(); i++) { @@ -804,7 +801,7 @@ bool Context::MatchEstimate(Obj &match, const TermPtr &match_item, MatchMode mod ASSERT(match_item->m_follow[i]); cond = CreateRVal(ctx, match_item->m_follow[i], args); - if(cond->is_none_type() || MatchCompare(match, cond, mode, ctx)) { + if (cond->is_none_type() || MatchCompare(match, cond, mode, ctx)) { return true; } @@ -826,15 +823,15 @@ ObjPtr Context::eval_MATCHING(Context *ctx, const TermPtr &term, Obj * args) { ASSERT(term->Right()); MatchMode mode; - if(term->m_text.compare("==>") == 0) { + if (term->m_text.compare("==>") == 0) { mode = MatchMode::EQUAL; - } else if(term->m_text.compare("===>") == 0) { + } else if (term->m_text.compare("===>") == 0) { mode = MatchMode::STRICT; - } else if(term->m_text.compare("~>") == 0) { + } else if (term->m_text.compare("~>") == 0) { mode = MatchMode::TYPE_NAME; - } else if(term->m_text.compare("~~>") == 0) { + } else if (term->m_text.compare("~~>") == 0) { mode = MatchMode::TYPE_EQUAL; - } else if(term->m_text.compare("~~~>") == 0) { + } else if (term->m_text.compare("~~~>") == 0) { mode = MatchMode::TYPE_STRICT; } else { NL_PARSER(term, "Unknown pattern matching type!"); @@ -849,7 +846,7 @@ ObjPtr Context::eval_MATCHING(Context *ctx, const TermPtr &term, Obj * args) { ObjPtr cond = CreateRVal(ctx, list->Left(), args); - if(MatchEstimate(*cond.get(), list->Left(), mode, ctx, args)) { + if (MatchEstimate(*cond.get(), list->Left(), mode, ctx, args)) { return CreateRVal(ctx, list->Right(), args); } else { for (int i = 0; i < list->m_block.size(); i++) { @@ -857,7 +854,7 @@ ObjPtr Context::eval_MATCHING(Context *ctx, const TermPtr &term, Obj * args) { ASSERT(list->m_block[i]->Left()); ASSERT(list->m_block[i]->Right()); - if(MatchEstimate(*cond.get(), list->m_block[i]->Left(), mode, ctx, args)) { + if (MatchEstimate(*cond.get(), list->m_block[i]->Left(), mode, ctx, args)) { return CreateRVal(ctx, list->m_block[i]->Right(), args); } @@ -895,7 +892,7 @@ ObjPtr Context::eval_SOURCE(Context *ctx, const TermPtr &term, Obj * args) { */ ObjPtr Context::eval_OPERATOR(Context *ctx, const TermPtr &term, Obj * args) { - if(Context::m_ops.find(term->m_text) == Context::m_ops.end()) { + if (Context::m_ops.find(term->m_text) == Context::m_ops.end()) { LOG_RUNTIME("Eval op '%s' not exist!", term->m_text.c_str()); } @@ -1031,7 +1028,7 @@ ObjPtr Context::op_BIT_XOR_(Context *ctx, const TermPtr &term, Obj * args) { ObjPtr Context::op_PLUS(Context *ctx, const TermPtr &term, Obj * args) { ASSERT(term); ASSERT(term->Right()); - if(term->Left()) { + if (term->Left()) { return ExecStr(ctx, term->Left(), args)->operator+(ExecStr(ctx, term->Right(), args)); } @@ -1041,7 +1038,7 @@ ObjPtr Context::op_PLUS(Context *ctx, const TermPtr &term, Obj * args) { ObjPtr Context::op_MINUS(Context *ctx, const TermPtr &term, Obj * args) { ASSERT(term); ASSERT(term->Right()); - if(term->Left()) { + if (term->Left()) { return ExecStr(ctx, term->Left(), args)->operator-(ExecStr(ctx, term->Right(), args)); } @@ -1161,7 +1158,7 @@ ObjPtr Context::op_TYPE_EQ(Context *ctx, const TermPtr &term, Obj * args) { ASSERT(term->Left()); ASSERT(term->Right()); - if(isType(term->Right()->GetFullName())) { + if (isType(term->Right()->GetFullName())) { return Obj::CreateBool(ExecStr(ctx, term->Left(), args)->op_class_test(term->Right()->GetFullName().c_str(), ctx)); } return Obj::CreateBool(ExecStr(ctx, term->Left(), args)->op_class_test(ExecStr(ctx, term->Right(), args), ctx)); @@ -1187,7 +1184,7 @@ ObjPtr Context::op_TYPE_NE(Context *ctx, const TermPtr &term, Obj * args) { ASSERT(term); ASSERT(term->Left()); ASSERT(term->Right()); - if(isType(term->Right()->GetFullName())) { + if (isType(term->Right()->GetFullName())) { return Obj::CreateBool(!ExecStr(ctx, term->Left(), args)->op_class_test(term->Right()->GetFullName().c_str(), ctx)); } return Obj::CreateBool(!ExecStr(ctx, term->Left(), args)->op_class_test(ExecStr(ctx, term->Right(), args), ctx)); @@ -1264,8 +1261,8 @@ ObjPtr Context::eval_EXIT(Context *ctx, const TermPtr &term, Obj * args) { ObjPtr ret = nullptr; bool is_return_data = (bool)term->Right(); - if(is_return_data) { - if(isType(term->Right()->GetFullName())) { + if (is_return_data) { + if (isType(term->Right()->GetFullName())) { ret = CreateRVal(ctx, term->Right(), args); } else { ret = ctx->GetTypeFromString(Interrupt::Return); @@ -1282,7 +1279,7 @@ ObjPtr Context::eval_EXIT(Context *ctx, const TermPtr &term, Obj * args) { ObjPtr Context::CallBlock(Context *ctx, const TermPtr &block, Obj * local_vars) { ObjPtr result = Obj::CreateNone(); ASSERT(block); - if(!block->m_block.empty()) { + if (!block->m_block.empty()) { for (size_t i = 0; i < block->m_block.size(); i++) { result = ExecStr(ctx, block->m_block[i], local_vars); } @@ -1301,16 +1298,16 @@ ObjPtr Context::CallBlockTry(Context *ctx, const TermPtr &block, Obj * local_var ASSERT(obj.m_obj); - if(!block->m_class_name.empty()) { + if (!block->m_class_name.empty()) { type_return = block->m_class_name; } - if(obj.m_obj->op_class_test(type_return.c_str(), ctx)) { - if(block->m_class_name.empty()) { + if (obj.m_obj->op_class_test(type_return.c_str(), ctx)) { + if (block->m_class_name.empty()) { // Только при возврате значения :Return ASSERT(obj.m_obj->size() == 1); return (*obj.m_obj)[0]; } - } else if(!block->m_class_name.empty()) { + } else if (!block->m_class_name.empty()) { throw; // Объект возврата не соответствует требуемому типу } result = obj.m_obj; @@ -1320,17 +1317,17 @@ ObjPtr Context::CallBlockTry(Context *ctx, const TermPtr &block, Obj * local_var ObjPtr Context::EvalBlockAND(Context *ctx, const TermPtr &block, Obj * local_vars) { ObjPtr result = nullptr; - if(block->GetTokenID() == TermID::BLOCK) { + if (block->GetTokenID() == TermID::BLOCK) { for (size_t i = 0; i < block->m_block.size(); i++) { result = ExecStr(ctx, block->m_block[i], local_vars); - if(!result || !result->GetValueAsBoolean()) { + if (!result || !result->GetValueAsBoolean()) { return Obj::No(); } } } else { result = ExecStr(ctx, block, local_vars); } - if(!result || !result->GetValueAsBoolean()) { + if (!result || !result->GetValueAsBoolean()) { return Obj::No(); } @@ -1339,17 +1336,17 @@ ObjPtr Context::EvalBlockAND(Context *ctx, const TermPtr &block, Obj * local_var ObjPtr Context::EvalBlockOR(Context *ctx, const TermPtr &block, Obj * local_vars) { ObjPtr result = nullptr; - if(block->GetTokenID() == TermID::BLOCK) { + if (block->GetTokenID() == TermID::BLOCK) { for (size_t i = 0; i < block->m_block.size(); i++) { result = ExecStr(ctx, block->m_block[i], local_vars); - if(result && result->GetValueAsBoolean()) { + if (result && result->GetValueAsBoolean()) { return Obj::Yes(); } } } else { result = ExecStr(ctx, block, local_vars); } - if(result && result->GetValueAsBoolean()) { + if (result && result->GetValueAsBoolean()) { return Obj::Yes(); } @@ -1359,16 +1356,16 @@ ObjPtr Context::EvalBlockOR(Context *ctx, const TermPtr &block, Obj * local_vars ObjPtr Context::EvalBlockXOR(Context *ctx, const TermPtr &block, Obj * local_vars) { ObjPtr result; size_t xor_counter = 0; - if(block->GetTokenID() == TermID::BLOCK) { + if (block->GetTokenID() == TermID::BLOCK) { for (size_t i = 0; i < block->m_block.size(); i++) { result = ExecStr(ctx, block->m_block[i], local_vars); - if(result && result->GetValueAsBoolean()) { + if (result && result->GetValueAsBoolean()) { xor_counter++; } } } else { result = ExecStr(ctx, block, local_vars); - if(result && result->GetValueAsBoolean()) { + if (result && result->GetValueAsBoolean()) { xor_counter++; } @@ -1381,12 +1378,12 @@ ObjPtr Context::CreateNative(const char *proto, const char *module, bool lazzy, TermPtr term; try { // Термин или термин + тип парсятся без ошибок - term = Parser::ParseString(proto); + term = Parser::ParseString(proto, &m_macros); } catch (std::exception &e) { try { std::string func(proto); func += ":={}"; - term = Parser::ParseString(func)->Left(); + term = Parser::ParseString(func, &m_macros)->Left(); } catch (std::exception &e) { LOG_RUNTIME("Fail parsing prototype '%s'!", e.what()); @@ -1403,13 +1400,13 @@ ObjPtr Context::CreateNative(TermPtr proto, const char *module, bool lazzy, cons ObjPtr result; ObjType type; - if(proto->GetTokenID() == TermID::TERM) { - if(proto->m_type_name.empty()) { + if (proto->GetTokenID() == TermID::TERM) { + if (proto->m_type_name.empty()) { LOG_RUNTIME("Cannot create native variable without specifying the type!"); } type = typeFromString(proto->m_type_name, this); - switch(type) { + switch (type) { case ObjType::Bool: // case ObjType::Byte: case ObjType::Char: @@ -1423,7 +1420,7 @@ ObjPtr Context::CreateNative(TermPtr proto, const char *module, bool lazzy, cons default: LOG_RUNTIME("Creating a variable with type '%s' is not supported!", proto->m_type_name.c_str()); } - } else if(proto->GetTokenID() == TermID::CALL) { + } else if (proto->GetTokenID() == TermID::CALL) { type = ObjType::NativeFunc; } @@ -1433,20 +1430,20 @@ ObjPtr Context::CreateNative(TermPtr proto, const char *module, bool lazzy, cons *const_cast (&result->m_func_proto) = proto; result->m_func_abi = abi; - if(mangle_name) { + if (mangle_name) { result->m_func_mangle_name = mangle_name; } - if(module) { + if (module) { result->m_module_name = module; } - if(lazzy) { + if (lazzy) { result->m_func_ptr = nullptr; } else { result->m_func_ptr = m_runtime->GetProcAddress( result->m_func_mangle_name.empty() ? proto->m_text.c_str() : result->m_func_mangle_name.c_str(), module); - if(result->is_function() || type == ObjType::Pointer) { + if (result->is_function() || type == ObjType::Pointer) { NL_CHECK(result->m_func_ptr, "Error getting address '%s' from '%s'!", proto->toString().c_str(), module); - } else if(result->m_func_ptr && result->is_tensor()) { + } else if (result->m_func_ptr && result->is_tensor()) { result->m_value = torch::from_blob(result->m_func_ptr, { }, toTorchType(type)); result->m_var_is_init = true; @@ -1459,11 +1456,11 @@ ObjPtr Context::CreateNative(TermPtr proto, const char *module, bool lazzy, cons } void *RunTime::GetProcAddress(const char *name, const char *module) { - if(module && module[0]) { - if(m_modules.find(module) == m_modules.end()) { + if (module && module[0]) { + if (m_modules.find(module) == m_modules.end()) { LoadModule(module, false, nullptr); } - if(m_modules.find(module) == m_modules.end()) { + if (m_modules.find(module) == m_modules.end()) { LOG_WARNING("Fail load module '%s'!", module); return nullptr; @@ -1475,9 +1472,9 @@ void *RunTime::GetProcAddress(const char *name, const char *module) { ObjPtr Context::FindSessionTerm(const char *name, bool current_only) { auto found = select(MakeName(name)); - while(!found.complete()) { + while (!found.complete()) { ObjPtr obj = found.data().second.lock(); - if(obj) { + if (obj) { return obj; } @@ -1500,15 +1497,15 @@ ObjPtr Context::FindSessionTerm(const char *name, bool current_only) { */ ObjPtr Context::FindTerm(const std::string name) { ObjPtr result = FindSessionTerm(name.c_str()); - if(!result && isType(name)) { + if (!result && isType(name)) { return GetTypeFromString(name); } - if(!result) { + if (!result) { return GetObject(name.c_str()); } - if(result || isLocalAny(name.c_str()) || isLocal(name)) { + if (result || isLocalAny(name.c_str()) || isLocal(name)) { return result; } @@ -1516,7 +1513,7 @@ ObjPtr Context::FindTerm(const std::string name) { } ObjPtr Context::GetTerm(const std::string name, bool is_ref) { - if(isType(name)) { + if (isType(name)) { return GetTypeFromString(name); } @@ -1526,7 +1523,7 @@ ObjPtr Context::GetTerm(const std::string name, bool is_ref) { std::string newlang::GetFileExt(const char *str) { std::string filename(str); std::string::size_type idx = filename.rfind('.'); - if(idx != std::string::npos) { + if (idx != std::string::npos) { return filename.substr(idx); } @@ -1536,7 +1533,7 @@ std::string newlang::GetFileExt(const char *str) { std::string newlang::AddDefaultFileExt(const char *str, const char *ext_default) { std::string filename(str); std::string file_ext = GetFileExt(str); - if(file_ext.empty() && !filename.empty() && filename.compare(".") != 0) { + if (file_ext.empty() && !filename.empty() && filename.compare(".") != 0) { filename.append(ext_default); } @@ -1546,11 +1543,11 @@ std::string newlang::AddDefaultFileExt(const char *str, const char *ext_default) std::string newlang::ReplaceFileExt(const char *str, const char *ext_old, const char *ext_new) { std::string filename(str); std::string file_ext = GetFileExt(str); - if(file_ext.compare(ext_old) == 0) { + if (file_ext.compare(ext_old) == 0) { filename = filename.substr(0, filename.length() - file_ext.length()); } file_ext = GetFileExt(filename.c_str()); - if(file_ext.compare(".") != 0 && file_ext.compare(ext_new) != 0 && !filename.empty() && + if (file_ext.compare(".") != 0 && file_ext.compare(ext_new) != 0 && !filename.empty() && filename.compare(".") != 0) { filename.append(ext_new); @@ -1575,9 +1572,9 @@ ObjPtr Context::CreateLVal(Context *ctx, TermPtr term, Obj * args) { auto iter = ctx->select(term->m_text); - if(!iter.complete()) { + if (!iter.complete()) { ObjPtr obj = (*iter).lock(); - if(obj) { + if (obj) { return obj; } } @@ -1594,24 +1591,24 @@ ObjPtr Context::CreateLVal(Context *ctx, TermPtr term, Obj * args) { *const_cast (&result->m_func_proto) = term; TermPtr type = term->GetType(); - if(term->IsFunction() || term->getTermID() == TermID::CALL) { + if (term->IsFunction() || term->getTermID() == TermID::CALL) { result->m_var_type_current = ObjType::FUNCTION; result->m_var_type_fixed = result->m_var_type_current; *const_cast (&result->m_func_proto) = term; - } else if(type) { + } else if (type) { result->m_var_type_current = typeFromString(type->getText().c_str(), ctx); result->m_var_type_fixed = result->m_var_type_current; - if(result->is_tensor()) { + if (result->is_tensor()) { std::vector dims; - if(type->m_dims.size()) { + if (type->m_dims.size()) { for (size_t i = 0; i < type->m_dims.size(); i++) { NL_CHECK(type->m_dims[i]->getName().empty(), "Dimension named not supported!"); ObjPtr temp = CreateRVal(ctx, type->m_dims[i]); - if(!temp) { + if (!temp) { NL_PARSER(type, "Term not found!"); } - if(!temp->is_integer()) { + if (!temp->is_integer()) { NL_PARSER(type, "Term type not integer!"); } @@ -1621,7 +1618,7 @@ ObjPtr Context::CreateLVal(Context *ctx, TermPtr term, Obj * args) { result->m_value = torch::empty(dims, toTorchType(result->m_var_type_current)); } } - if(!isType(term->m_text)) { + if (!isType(term->m_text)) { ctx->RegisterObject(result); } return result; @@ -1638,7 +1635,7 @@ ObjPtr Context::CreateRVal(Context *ctx, const char *source, Obj * local_vars) { void Context::ItemTensorEval_(torch::Tensor &tensor, c10::IntArrayRef shape, std::vector &ind, const int64_t pos, ObjPtr &obj, ObjPtr & args) { ASSERT(pos < ind.size()); - if(pos + 1 < ind.size()) { + if (pos + 1 < ind.size()) { for (ind[pos] = 0; ind[pos].integer() < shape[pos]; ind[pos] = ind[pos].integer() + 1) { ItemTensorEval_(tensor, shape, ind, pos + 1, obj, args); } @@ -1649,7 +1646,7 @@ void Context::ItemTensorEval_(torch::Tensor &tensor, c10::IntArrayRef shape, std for (ind[pos] = 0; ind[pos].integer() < shape[pos]; ind[pos] = ind[pos].integer() + 1) { - switch(type) { + switch (type) { case ObjType::Char: case ObjType::Short: case ObjType::Int: @@ -1671,7 +1668,7 @@ void Context::ItemTensorEval_(torch::Tensor &tensor, c10::IntArrayRef shape, std } void Context::ItemTensorEval(torch::Tensor &self, ObjPtr obj, ObjPtr args) { - if(self.dim() == 0) { + if (self.dim() == 0) { signed char *ptr_char = nullptr; short *ptr_short = nullptr; @@ -1680,7 +1677,7 @@ void Context::ItemTensorEval(torch::Tensor &self, ObjPtr obj, ObjPtr args) { float *ptr_float = nullptr; double *ptr_double = nullptr; - switch(fromTorchType(self.scalar_type())) { + switch (fromTorchType(self.scalar_type())) { case ObjType::Char: ptr_char = self.data_ptr(); ASSERT(ptr_char); @@ -1727,12 +1724,12 @@ std::vector GetTensorShape(Context *ctx, TermPtr type, Obj * local_vars std::vector result(type->size()); for (int i = 0; i < type->size(); i++) { ObjPtr temp = ctx->CreateRVal(ctx, type->at(i).second, local_vars); - if(temp->is_integer() || temp->is_bool_type()) { + if (temp->is_integer() || temp->is_bool_type()) { result[i] = temp->GetValueAsInteger(); } else { NL_PARSER(type->at(i).second, "Measurement dimension can be an integer only!"); } - if(result[i] <= 0) { + if (result[i] <= 0) { NL_PARSER(type->at(i).second, "Dimension size can be greater than zero!"); } @@ -1771,36 +1768,36 @@ std::vector Context::MakeIndex(Context *ctx, TermPtr term, Obj * local_va std::vector result; - if(!term->size()) { + if (!term->size()) { NL_PARSER(term, "Index not found!"); } for (int i = 0; i < term->size(); i++) { - if(!term->name(i).empty() || (term->at(i).second && term->at(i).second->IsString())) { + if (!term->name(i).empty() || (term->at(i).second && term->at(i).second->IsString())) { NL_PARSER(term, "Named index not support '%d'!", i); } - if(!term->at(i).second) { + if (!term->at(i).second) { NL_PARSER(term, "Empty index '%d'!", i); } - if(term->at(i).second->getTermID() == TermID::ELLIPSIS) { + if (term->at(i).second->getTermID() == TermID::ELLIPSIS) { result.push_back(Index("...")); } else { ObjPtr temp = ctx->CreateRVal(ctx, term->at(i).second, local_vars); - if(temp->is_none_type()) { + if (temp->is_none_type()) { result.push_back(Index(at::indexing::None)); - } else if(temp->is_integer() || temp->is_bool_type()) { + } else if (temp->is_integer() || temp->is_bool_type()) { - if(temp->is_scalar()) { + if (temp->is_scalar()) { result.push_back(Index(temp->GetValueAsInteger())); - } else if(temp->m_value.dim() == 1) { + } else if (temp->m_value.dim() == 1) { result.push_back(Index(temp->m_value)); } else { NL_PARSER(term->at(i).second, "Extra dimensions index not support '%d'!", i); } - } else if(temp->is_range()) { + } else if (temp->is_range()) { int64_t start = temp->at("start")->GetValueAsInteger(); int64_t stop = temp->at("stop")->GetValueAsInteger(); @@ -1818,7 +1815,7 @@ std::vector Context::MakeIndex(Context *ctx, TermPtr term, Obj * local_va ObjPtr Context::CreateRVal(Context *ctx, TermPtr term, Obj * local_vars) { - if(!term) { + if (!term) { ASSERT(term); } ASSERT(local_vars); @@ -1841,13 +1838,13 @@ ObjPtr Context::CreateRVal(Context *ctx, TermPtr term, Obj * local_vars) { bool has_error; std::vector sizes; at::Scalar torch_scalar; - switch(term->getTermID()) { + switch (term->getTermID()) { case TermID::INTEGER: val_int = parseInteger(term->getText().c_str()); NL_TYPECHECK(term, newlang::toString(typeFromLimit(val_int)), term->m_type_name); // Соответстствует ли тип значению? result->m_var_type_current = typeFromLimit(val_int); - if(term->GetType()) { + if (term->GetType()) { result->m_var_type_fixed = typeFromString(term->m_type_name, ctx); result->m_var_type_current = result->m_var_type_fixed; } @@ -1859,7 +1856,7 @@ ObjPtr Context::CreateRVal(Context *ctx, TermPtr term, Obj * local_vars) { NL_TYPECHECK(term, newlang::toString(typeFromLimit(val_dbl)), term->m_type_name); // Соответстствует ли тип значению? result->m_var_type_current = typeFromLimit(val_dbl); - if(term->GetType()) { + if (term->GetType()) { result->m_var_type_fixed = typeFromString(term->m_type_name, ctx); result->m_var_type_current = result->m_var_type_fixed; } @@ -1901,7 +1898,7 @@ ObjPtr Context::CreateRVal(Context *ctx, TermPtr term, Obj * local_vars) { return result; case TermID::TERM: - if(term->GetType()) { + if (term->GetType()) { result->m_var_type_current = typeFromString(term->GetType()->m_text, ctx); result->m_var_type_fixed = result->m_var_type_current; @@ -1910,21 +1907,21 @@ ObjPtr Context::CreateRVal(Context *ctx, TermPtr term, Obj * local_vars) { // Check BuildInType has_error = false; typeFromString(term->GetType()->m_text, nullptr, &has_error); - if(has_error) { + if (has_error) { result->m_class_name = term->GetType()->m_text; } return result; } - if(term->m_text.compare("_") == 0) { + if (term->m_text.compare("_") == 0) { result->m_var_type_current = ObjType::None; return result; - } else if(term->m_text.compare("$") == 0) { + } else if (term->m_text.compare("$") == 0) { result->m_var_type_current = ObjType::Dictionary; result->m_var_name = "$"; size_t pos = 0; - while(ctx && pos < ctx->size()) { - if(ctx->at(pos).second.lock()) { + while (ctx && pos < ctx->size()) { + if (ctx->at(pos).second.lock()) { result->push_back(Obj::CreateString(ctx->at(pos).first)); // result->push_back(Obj::Arg(ctx->at(pos).first)); pos++; @@ -1934,11 +1931,11 @@ ObjPtr Context::CreateRVal(Context *ctx, TermPtr term, Obj * local_vars) { } result->m_var_is_init = true; return result; - } else if(term->m_text.compare("@") == 0) { - } else if(term->m_text.compare("%") == 0) { + } else if (term->m_text.compare("@") == 0) { + } else if (term->m_text.compare("%") == 0) { } - if(isLocal(term->m_text.c_str())) { + if (isLocal(term->m_text.c_str())) { full_name = MakeName(term->m_text); return local_vars->at(full_name); } else { @@ -1946,31 +1943,31 @@ ObjPtr Context::CreateRVal(Context *ctx, TermPtr term, Obj * local_vars) { // Типы данных обрабатываются тут, а не в вызовах функций (TermID::CALL) - if(term->size()) { + if (term->size()) { Obj args(ctx, term, true, local_vars); result = result->Call(ctx, &args); } } - if(!result) { + if (!result) { // Делать ислкючение или возвращать объект "ошибка" ????? LOG_RUNTIME("Term '%s' not found!", term->GetFullName().c_str()); } field = term->m_right; - if(field && field->getTermID() == TermID::FIELD) { - while(field) { + if (field && field->getTermID() == TermID::FIELD) { + while (field) { result = result->at(field->getText()); field = field->m_right; ASSERT(!field); // Нужно выполнять, а не просто получать значение поля } - } else if(field && field->getTermID() == TermID::INDEX) { - while(field) { + } else if (field && field->getTermID() == TermID::INDEX) { + while (field) { result = result->index_get(MakeIndex(ctx, field, local_vars)); field = field->m_right; ASSERT(!field); // Нужно выполнять, а не просто получать значение поля } - } else if(field) { + } else if (field) { LOG_RUNTIME("Not implemented! %s", field->toString().c_str()); } @@ -1984,7 +1981,7 @@ ObjPtr Context::CreateRVal(Context *ctx, TermPtr term, Obj * local_vars) { has_error = false; type = typeFromString(term->GetFullName(), ctx, &has_error); - if(has_error) { + if (has_error) { LOG_RUNTIME("Type name '%s' undefined!", term->GetFullName().c_str()); } ASSERT(result); @@ -2000,7 +1997,7 @@ ObjPtr Context::CreateRVal(Context *ctx, TermPtr term, Obj * local_vars) { for (size_t i = 0; i < term->size(); i++) { - if((*term)[i]->GetTokenID() == TermID::FILLING) { + if ((*term)[i]->GetTokenID() == TermID::FILLING) { // Заполнение значений вызовом функции // :Type(1, 2, 3, ... rand() ... ); @@ -2012,34 +2009,34 @@ ObjPtr Context::CreateRVal(Context *ctx, TermPtr term, Obj * local_vars) { ObjPtr expr = ctx->FindTerm((*term)[i]->Right()->GetFullName()); - if((*term)[i]->Right()->getTermID() != TermID::CALL) { + if ((*term)[i]->Right()->getTermID() != TermID::CALL) { LOG_RUNTIME("Operator filling supported function call only!"); } - if(i + 1 != term->size()) { + if (i + 1 != term->size()) { LOG_RUNTIME("Function filling is supported for the last argument only!"); } - if(!result->m_dimensions || !result->m_dimensions->size()) { + if (!result->m_dimensions || !result->m_dimensions->size()) { LOG_RUNTIME("Object has no dimensions!"); } int64_t full_size = 1; for (int dim_index = 0; dim_index < result->m_dimensions->size(); dim_index++) { - if(!(*result->m_dimensions)[dim_index]->is_integer()) { + if (!(*result->m_dimensions)[dim_index]->is_integer()) { LOG_RUNTIME("Dimension index for function filling support integer value only!"); } full_size *= (*result->m_dimensions)[dim_index]->GetValueAsInteger(); } - if(full_size <= 0) { + if (full_size <= 0) { LOG_RUNTIME("Items count error for all dimensions!"); } - if(expr->size()) { + if (expr->size()) { LOG_RUNTIME("Argument in function for filling not implemented!"); } @@ -2049,24 +2046,24 @@ ObjPtr Context::CreateRVal(Context *ctx, TermPtr term, Obj * local_vars) { break; - } else if((*term)[i]->GetTokenID() == TermID::ELLIPSIS) { + } else if ((*term)[i]->GetTokenID() == TermID::ELLIPSIS) { - if(!term->name(i).empty()) { + if (!term->name(i).empty()) { LOG_RUNTIME("Named ellipsys not implemented!"); } - if((*term)[i]->Right()) { + if ((*term)[i]->Right()) { bool named = ((*term)[i]->Left() && (*term)[i]->Left()->getTermID() == TermID::ELLIPSIS); ObjPtr exp = CreateRVal(ctx, (*term)[i]->Right()); - if(!exp->is_dictionary_type()) { + if (!exp->is_dictionary_type()) { LOG_RUNTIME("Expansion operator applies to dictionary only!"); } for (int index = 0; index < exp->size(); index++) { - if(named) { + if (named) { args->push_back((*exp)[index], exp->name(index).empty() ? "" : exp->name(index)); } else { args->push_back((*exp)[index]); @@ -2077,7 +2074,7 @@ ObjPtr Context::CreateRVal(Context *ctx, TermPtr term, Obj * local_vars) { } } - if(term->name(i).empty()) { + if (term->name(i).empty()) { args->push_back(CreateRVal(ctx, (*term)[i], local_vars)); } else { args->push_back(CreateRVal(ctx, (*term)[i], local_vars), term->name(i).c_str()); @@ -2097,20 +2094,20 @@ ObjPtr Context::CreateRVal(Context *ctx, TermPtr term, Obj * local_vars) { temp = ctx->GetTerm(term->GetFullName().c_str(), term->isRef()); - if(!temp) { + if (!temp) { ASSERT(temp); } args = Obj::CreateDict(); for (size_t i = 0; i < term->size(); i++) { - if(term->name(i).empty()) { + if (term->name(i).empty()) { args->push_back(CreateRVal(ctx, (*term)[i], local_vars)); } else { args->push_back(CreateRVal(ctx, (*term)[i], local_vars), term->name(i).c_str()); } } - if(term->getTermID() == TermID::EXIT) { + if (term->getTermID() == TermID::EXIT) { return result; } @@ -2122,19 +2119,19 @@ ObjPtr Context::CreateRVal(Context *ctx, TermPtr term, Obj * local_vars) { case TermID::DICT: result->m_var_type_current = ObjType::Dictionary; for (size_t i = 0; i < term->size(); i++) { - if(term->name(i).empty()) { + if (term->name(i).empty()) { result->push_back(CreateRVal(ctx, (*term)[i], local_vars)); } else { result->push_back(CreateRVal(ctx, (*term)[i], local_vars), term->name(i).c_str()); } } result->m_var_is_init = true; - if(term->getTermID() == TermID::TENSOR) { + if (term->getTermID() == TermID::TENSOR) { result->m_var_type_fixed = typeFromString(term->m_type_name, ctx); type = getSummaryTensorType(result, result->m_var_type_fixed); - if(type != ObjType::None) { + if (type != ObjType::None) { result->m_value = ConvertToTensor(result.get(), toTorchType(type)); } else { result->m_var_is_init = false; @@ -2149,7 +2146,7 @@ ObjPtr Context::CreateRVal(Context *ctx, TermPtr term, Obj * local_vars) { case TermID::ARGUMENT: val_int = IndexArg(term); - if(val_int < local_vars->size()) { + if (val_int < local_vars->size()) { return local_vars->at(val_int).second; } LOG_RUNTIME("Argument '%s' not exist!", term->toString().c_str()); @@ -2173,7 +2170,7 @@ ObjPtr Context::CreateRVal(Context *ctx, TermPtr term, Obj * local_vars) { result->push_back(CreateRVal(ctx, (*term)[i], local_vars), term->name(i).c_str()); } - if(result->size() == 2) { + if (result->size() == 2) { result->push_back(Obj::CreateValue(1, ObjType::None), "step"); } diff --git a/core/context.h b/core/context.h index 4c674e60..400984bf 100644 --- a/core/context.h +++ b/core/context.h @@ -135,7 +135,7 @@ class Context : public Variable< std::weak_ptr > { static std::map m_ops; static std::map m_builtin_calls; - static std::map m_macros; ///< Хотя макросы и могут обработываться в рантайме, но доступны только для парсера + static Parser::MacrosStore m_macros; ///< Хотя макросы и могут обработываться в рантайме, но доступны они только для парсера static void Reset() { m_types.clear(); @@ -154,7 +154,7 @@ class Context : public Variable< std::weak_ptr > { } inline ObjPtr ExecStr(const std::string &source) { - TermPtr exec = Parser::ParseString(source); + TermPtr exec = Parser::ParseString(source, &m_macros); if (exec->m_id == TermID::BLOCK) { exec->m_id = TermID::CALL_BLOCK; } else if (exec->m_id == TermID::BLOCK_TRY) { @@ -164,7 +164,7 @@ class Context : public Variable< std::weak_ptr > { } inline ObjPtr ExecStr(const std::string_view str, Obj *args) { - return ExecStr(this, Parser::ParseString(str), args); + return ExecStr(this, Parser::ParseString(str, &m_macros), args); } inline static ObjPtr ExecStr(Context *ctx, TermPtr term) { @@ -411,7 +411,7 @@ class Context : public Variable< std::weak_ptr > { std::string func_dump(prototype); func_dump += " := {};"; - TermPtr proto = Parser::ParseString(func_dump); + TermPtr proto = Parser::ParseString(func_dump, &m_macros); ObjPtr obj = Obj::CreateFunc(this, proto->Left(), type, proto->Left()->getName().empty() ? proto->Left()->getText() : proto->Left()->getName()); diff --git a/core/nlc.h b/core/nlc.h index 3b4764dc..6b88980c 100644 --- a/core/nlc.h +++ b/core/nlc.h @@ -594,13 +594,14 @@ class NLC { break; } else if (!buff.empty()) { try { - TermPtr term = Parser::ParseString(utf8_encode(buff)); - - if (!term) { - LOG_RUNTIME("Eval expression empty!"); - } - - ObjPtr res = Context::ExecStr(&m_ctx, term, m_args.get()); +// TermPtr term = m_ctx.ExecStr(utf8_encode(buff)); +// +// if (!term) { +// LOG_RUNTIME("Eval expression empty!"); +// } + std::string input = utf8_encode(buff); + + ObjPtr res = m_ctx.ExecStr(input, m_args.get()); if (res) { diff --git a/core/parser.cpp b/core/parser.cpp index 6d82d3a7..30b92030 100644 --- a/core/parser.cpp +++ b/core/parser.cpp @@ -34,10 +34,13 @@ bool Parser::parse_string(const std::string_view input, const std::string_view s return parse_stream(iss, sname.begin()); } -TermPtr Parser::Parse(const std::string_view str) { +TermPtr Parser::Parse(const std::string_view input, MacrosStore *store) { + + std::string parse_string = ParseAllMacros(input, store); + m_ast = Term::Create(TermID::END, ""); - m_ast->SetSource(std::make_shared(str)); - m_stream.str(*m_ast->m_source); + m_ast->SetSource(std::make_shared(input)); + m_stream.str(parse_string); Scanner scanner(&m_stream, &std::cout, m_ast->m_source); lexer = &scanner; @@ -52,10 +55,10 @@ TermPtr Parser::Parse(const std::string_view str) { return m_ast; } -TermPtr Parser::ParseString(const std::string_view str) { +TermPtr Parser::ParseString(const std::string_view str, MacrosStore *store) { TermPtr ast = Term::Create(TermID::END, ""); Parser p(ast); - return p.Parse(str); + return p.Parse(str, store); } void Parser::error(const class location& l, const std::string& m) { diff --git a/core/parser.h b/core/parser.h index 97ce4421..858836e8 100644 --- a/core/parser.h +++ b/core/parser.h @@ -20,9 +20,6 @@ namespace newlang { class Parser { public: - /// construct a new parser driver context - // Parser(class CalcContext& calc); - Parser(TermPtr &ast); /// enable debug output in the flex scanner @@ -78,17 +75,19 @@ namespace newlang { * expressions. */ // class CalcContext& calc; - TermPtr Parse(const std::string_view str); - static TermPtr ParseString(const std::string_view str); - void AstAddTerm(TermPtr &term); - typedef std::map MacrosStore; + typedef std::vector MacrosArgs; + typedef std::map> MacrosStore; inline static const std::string MACROS_START = "\\\\"; inline static const std::string MACROS_END = "\\\\\\"; + + TermPtr Parse(const std::string_view str, MacrosStore *store = nullptr); + static TermPtr ParseString(const std::string_view str, MacrosStore *store = nullptr); + static inline std::string ParseMacroName(const std::string &body) { // имя макроса должно быть в самом начале строки без пробелов и начинаться на один слешь if (body.size() < 3 || body[0] != '\\' || body[1] == '\\') { @@ -115,20 +114,21 @@ namespace newlang { std::string arg; for (size_t i = name.size(); i < body.size(); i++) { if (body[i] == ',' || body[i] == ')') { + trim(arg); if (!arg.empty()) { - trim(arg); + if (arg.find(".") != std::string::npos && arg.compare("...") != 0) { + LOG_RUNTIME("Macro argument name failure '%s'!", arg.c_str()); + } result.push_back(arg); // новый аргумент макроса arg.clear(); } else if (body[i] == ',') { LOG_RUNTIME("Macro argument missing!"); } + } else { + arg.append(1, body[i]); // имя аргумента } if (body[i] == ')') { return result; // Аругменты закончились - } else { - if (body[i] != ',') { - arg.append(1, body[i]); // имя аргумента - } } } // Нет закрывающей скобки @@ -174,7 +174,7 @@ namespace newlang { if (fill) { // Заменить определение макроса пробелами, кроме переводов строк, чтобы не съезжала позиция парсинга - std::string fill(stop + MACROS_END.size() - start, ' '); + std::string fill(stop - start + MACROS_END.size(), ' '); ASSERT(fill.size() > body.size()); for (size_t i = 0; i < body.size(); i++) { @@ -182,7 +182,7 @@ namespace newlang { fill[i + 1] = '\n'; } } - text.replace(start, stop + MACROS_END.size(), fill); + text.replace(start, fill.size(), fill); } return true; } @@ -198,18 +198,23 @@ namespace newlang { std::string result(text); if (name[name.size() - 1] != '(') { - body_base = macro.substr(name.size() + 1); + body_base = macro.substr(name.size()); + if (!body_base.empty() && std::isspace(static_cast (body_base[0]))) { + body_base = body_base.erase(0, 1); + } } else { + bool done = false; size_t pos = name.size(); while (pos < macro.size()) { if (macro[pos] == ')') { // Аругменты закончились body_base = macro.substr(pos + 1); + done = true; break; } pos++; } - if (body_base.empty()) { + if (!done) { // Нет закрывающей скобки LOG_RUNTIME("Closing bracket not found! '%s'", macro.c_str()); } @@ -262,8 +267,10 @@ namespace newlang { for (size_t i = 0; i < args.size() && i < args_define.size(); i++) { // Заменить аргумент по имени - std::string arg_name = "\\\\\\$" + args[i]; - body = std::regex_replace(body, std::regex(arg_name), args_define[i]); + if (args[i].compare("...") != 0) { + std::string arg_name = "\\\\\\$" + args[i]; + body = std::regex_replace(body, std::regex(arg_name), args_define[i]); + } } std::string summary; @@ -286,15 +293,19 @@ namespace newlang { return result; } - /** - * Развернуть макросы во входной строке - * @param text Входная строка - * @param store Храниличе макросов - * @return - */ - static bool ExpandMacros(std::string &text, MacrosStore &store) { + static std::string ParseAllMacros(const std::string_view input, MacrosStore *store) { + std::string result(input); + if (store) { + bool done; + do { + done = ExtractMacros(result, *store); + } while (done); - return false; + for (auto &elem : *store) { + result = ExpandMacro(elem.second, result); + } + } + return result; } diff --git a/core/test/newlang_test.cpp b/core/test/compiler_test.cpp similarity index 79% rename from core/test/newlang_test.cpp rename to core/test/compiler_test.cpp index 009b7f21..a3c047f3 100644 --- a/core/test/newlang_test.cpp +++ b/core/test/compiler_test.cpp @@ -13,7 +13,7 @@ using namespace newlang; -TEST(NewLang, Example1) { +TEST(Compiler, EvalExample) { TermPtr p; Parser parser(p); @@ -34,7 +34,7 @@ TEST(NewLang, Example1) { ASSERT_EQ(0, op->size()); } -TEST(NewLang, MangleName) { +TEST(Compiler, MangleName) { EXPECT_STREQ("newlang_min", MangleName("мин").c_str()) << MangleName("мин"); EXPECT_STREQ("newlang_maks", MangleName("макс").c_str()) << MangleName("макс"); @@ -422,7 +422,7 @@ bool str_cmp_strart(const char *base_str, const char *cmp_str) { // world!\\n\")")->GetValueAsString().c_str()); // } -TEST(NewLang, DISABLED_Function) { +TEST(Compiler, DISABLED_Function) { const char *func_text = "func_sum(arg1, arg2) :- {$arg1 + $arg2;};\n" @@ -503,137 +503,7 @@ TEST(NewLang, DISABLED_Function) { file.close(); } -TEST(NewLang, String) { - - ObjPtr str_byte = Obj::CreateString("byte"); - ASSERT_STREQ("byte", str_byte->GetValueAsString().c_str()); - ASSERT_EQ(4, str_byte->size()); - ASSERT_EQ(4, str_byte->m_str.size()); - ASSERT_STREQ("b", (*str_byte)[0]->GetValueAsString().c_str()); - ASSERT_STREQ("y", (*str_byte)[1]->GetValueAsString().c_str()); - ASSERT_STREQ("t", (*str_byte)[2]->GetValueAsString().c_str()); - ASSERT_STREQ("e", (*str_byte)[3]->GetValueAsString().c_str()); - - str_byte->op_set_index(0, "B"); - str_byte->op_set_index(1, "Y"); - ASSERT_STREQ("BYte", str_byte->GetValueAsString().c_str()); - str_byte->op_set_index(2, "T"); - str_byte->op_set_index(3, "E"); - ASSERT_STREQ("BYTE", str_byte->GetValueAsString().c_str()); - - ObjPtr str_char = Obj::CreateString(L"строка"); - ASSERT_EQ(6, str_char->size()); - ASSERT_EQ(6, str_char->m_wstr.size()); - - ASSERT_STREQ("с", (*str_char)[0]->GetValueAsString().c_str()); - ASSERT_STREQ("т", (*str_char)[1]->GetValueAsString().c_str()); - ASSERT_STREQ("р", (*str_char)[2]->GetValueAsString().c_str()); - ASSERT_STREQ("о", (*str_char)[3]->GetValueAsString().c_str()); - ASSERT_STREQ("к", (*str_char)[4]->GetValueAsString().c_str()); - ASSERT_STREQ("а", (*str_char)[5]->GetValueAsString().c_str()); - - str_char->op_set_index(0, "С"); - str_char->op_set_index(1, "Т"); - ASSERT_STREQ("СТрока", str_char->GetValueAsString().c_str()); - str_char->op_set_index(2, "Р"); - str_char->op_set_index(3, "О"); - ASSERT_STREQ("СТРОка", str_char->GetValueAsString().c_str()); - - - ObjPtr format = Obj::CreateString("$1 $2 ${name}"); - ObjPtr str1 = (*format)(nullptr); - ASSERT_STREQ("$1 $2 ${name}", str1->GetValueAsString().c_str()); - - ObjPtr str2 = (*format)(nullptr, Obj::Arg(100)); - ASSERT_STREQ("100 $2 ${name}", str2->GetValueAsString().c_str()); - - ObjPtr str3 = (*format)(nullptr, Obj::Arg(-1), Obj::Arg("222")); - ASSERT_STREQ("-1 222 ${name}", str3->GetValueAsString().c_str()); - - ObjPtr str4 = (*format)(nullptr, Obj::Arg("value", "name")); - ASSERT_STREQ("value $2 value", str4->GetValueAsString().c_str()); - - format = Obj::CreateString("$nameno ${имя1} $name $имя"); - ObjPtr str5 = (*format)(nullptr, Obj::Arg("value", "name"), Obj::Arg("УТФ8-УТФ8", "имя"), Obj::Arg("УТФ8", "имя1")); - ASSERT_STREQ("valueno УТФ8 value УТФ8-УТФ8", str5->GetValueAsString().c_str()); -} - -TEST(NewLang, Tensor) { - - // Байтовые строки - ObjPtr str = Obj::CreateString("test"); - ObjPtr t_str = Obj::CreateTensor(str->toTensor()); - ASSERT_EQ(t_str->m_var_type_current, ObjType::Char) << toString(t_str->m_var_type_current); - ASSERT_EQ(4, t_str->size()); - EXPECT_STREQ(t_str->toType(ObjType::StrWide)->GetValueAsString().c_str(), "test"); - - ASSERT_EQ(t_str->index_get({0})->GetValueAsInteger(), 't'); - ASSERT_EQ(t_str->index_get({1})->GetValueAsInteger(), 'e'); - ASSERT_EQ(t_str->index_get({2})->GetValueAsInteger(), 's'); - ASSERT_EQ(t_str->index_get({3})->GetValueAsInteger(), 't'); - - t_str->index_set_({1}, Obj::CreateString("E")); - t_str->index_set_({2}, Obj::CreateString("S")); - - EXPECT_STREQ(t_str->toType(ObjType::StrWide)->GetValueAsString().c_str(), "tESt"); - - // Символьные сторки - ObjPtr wstr = Obj::CreateString(L"ТЕСТ"); - ObjPtr t_wstr = Obj::CreateTensor(wstr->toTensor()); - ASSERT_EQ(t_wstr->m_var_type_current, ObjType::Int); - ASSERT_EQ(4, t_wstr->size()); - EXPECT_STREQ(t_wstr->toType(ObjType::StrWide)->GetValueAsString().c_str(), "ТЕСТ"); - - ASSERT_EQ(t_wstr->index_get({0})->GetValueAsInteger(), L'Т'); - ASSERT_EQ(t_wstr->index_get({1})->GetValueAsInteger(), L'Е'); - ASSERT_EQ(t_wstr->index_get({2})->GetValueAsInteger(), L'С'); - ASSERT_EQ(t_wstr->index_get({3})->GetValueAsInteger(), L'Т'); - - t_wstr->index_set_({1}, Obj::CreateString(L"е")); - t_wstr->index_set_({2}, Obj::CreateString(L"с")); - - EXPECT_STREQ(t_wstr->toType(ObjType::StrWide)->GetValueAsString().c_str(), "ТесТ"); - - - - - // ObjPtr dict = Context::CreateRVal(nullptr, "(1, [10,20,30,],)"); - // - // ASSERT_TRUE(dict); - // ASSERT_EQ(2, dict->size()); - // ASSERT_EQ(0, (*dict)[0]->size()); - // ASSERT_EQ(3, (*dict)[1]->size()); - // - // ASSERT_EQ(1, (*dict)[0]->GetValueAsInteger()); - // - // ASSERT_EQ(10, (*(*dict)[1])[0]->GetValueAsInteger()); - // ASSERT_EQ(20, (*(*dict)[1])[1]->GetValueAsInteger()); - // ASSERT_EQ(30, (*(*dict)[1])[2]->GetValueAsInteger()); - // - // ObjPtr t_dict = Obj::CreateTensor(dict, ObjType::Int); - // - // ASSERT_EQ(4, t_dict->size()); - // ASSERT_EQ(t_dict->index_get({0})->GetValueAsInteger(), 1); - // ASSERT_EQ(t_dict->index_get({1})->GetValueAsInteger(), 10); - // ASSERT_EQ(t_dict->index_get({2})->GetValueAsInteger(), 20); - // ASSERT_EQ(t_dict->index_get({3})->GetValueAsInteger(), 30); - // - // - // ObjPtr diag = Context::CreateRVal(nullptr, "[[ [ [1,], [2,22,], [3, 33, 333.0,] ] ]]"); - // - // ObjPtr t_diag = Obj::CreateTensor(diag, ObjType::Float); - // - // ASSERT_EQ(6, t_diag->size()); - // ASSERT_EQ(t_diag->index_get({0})->GetValueAsNumber(), 1); - // ASSERT_EQ(t_diag->index_get({1})->GetValueAsNumber(), 2); - // ASSERT_EQ(t_diag->index_get({2})->GetValueAsNumber(), 22); - // ASSERT_EQ(t_diag->index_get({3})->GetValueAsNumber(), 3); - // ASSERT_EQ(t_diag->index_get({4})->GetValueAsNumber(), 33); - // ASSERT_EQ(t_diag->index_get({5})->GetValueAsNumber(), 333); - -} - -TEST(NewLang, DISABLED_FuncsTypes) { +TEST(Compiler, DISABLED_FuncsTypes) { /* * - Проверка типов аргументов при вызове функций diff --git a/core/test/eval_test.cpp b/core/test/eval_test.cpp index 2ecd6cac..04ff3b5e 100644 --- a/core/test/eval_test.cpp +++ b/core/test/eval_test.cpp @@ -743,226 +743,110 @@ TEST(Eval, Convert) { // EXPECT_TRUE(dlsym(nullptr, "_ZN7newlang4CharEPKNS_7ContextERKNS_6ObjectE")); // EXPECT_TRUE(dlsym(nullptr, "_ZN7newlang6Short_EPNS_7ContextERNS_6ObjectE")); +} +TEST(Eval, Macros) { - // ASSERT_TRUE(opts->GetProcAddress(MangaledFunc("Bool").c_str())); - // ASSERT_TRUE(opts->GetProcAddress(MangaledFunc("Char").c_str())); - // ASSERT_TRUE(opts->GetProcAddress(MangaledFunc("Short").c_str())); - // ASSERT_TRUE(opts->GetProcAddress(MangaledFunc("Int").c_str())); - // ASSERT_TRUE(opts->GetProcAddress(MangaledFunc("Long").c_str())); - // // ASSERT_TRUE(opts->GetProcAddress(MangaledFunc("Half").c_str())); - // ASSERT_TRUE(opts->GetProcAddress(MangaledFunc("Float").c_str())); - // ASSERT_TRUE(opts->GetProcAddress(MangaledFunc("Double").c_str())); - // ASSERT_TRUE(opts->GetProcAddress(MangaledFunc("ComplexFloat").c_str())); - // ASSERT_TRUE(opts->GetProcAddress(MangaledFunc("ComplexDouble").c_str())); - // // ASSERT_TRUE(opts->GetProcAddress(MangaledFunc("BFloat16").c_str())); - // ASSERT_TRUE(opts->GetProcAddress(MangaledFunc("StrChar").c_str())); - // ASSERT_TRUE(opts->GetProcAddress(MangaledFunc("StrWide").c_str())); - // ASSERT_TRUE(opts->GetProcAddress(MangaledFunc("Dictionary").c_str())); - // ASSERT_TRUE(opts->GetProcAddress(MangaledFunc("Class").c_str())); - // ASSERT_TRUE(opts->GetProcAddress(MangaledFunc("None").c_str())); - // ASSERT_TRUE(opts->GetProcAddress(MangaledFunc("Integer").c_str())); - // ASSERT_TRUE(opts->GetProcAddress(MangaledFunc("Number").c_str())); - // ASSERT_TRUE(opts->GetProcAddress(MangaledFunc("Complex").c_str())); - // ASSERT_TRUE(opts->GetProcAddress(MangaledFunc("String").c_str())); - // - // - // ObjPtr byte = Obj::CreateValue(1, ObjType::Bool); - // ASSERT_EQ(ObjType::Bool, byte->m_var_type_current) << toString(byte->m_var_type_current); - // - // ASSERT_TRUE(ctx.CallByName("Char", Obj::Arg(byte))); - // ASSERT_EQ(ObjType::Char, ctx.CallByName("Char", Obj::Arg(byte))->m_var_type_current) << toString(byte->m_var_type_current); - // ASSERT_EQ(ObjType::Bool, byte->m_var_type_current) << toString(byte->m_var_type_current); - // - // ASSERT_EQ(ObjType::Char, newlang_Char(nullptr, Obj::Arg(byte))->m_var_type_current) << toString(byte->m_var_type_current); - // // ASSERT_STREQ("1", newlang_Char(nullptr, Obj::Arg(byte))->toString().c_str()); - // - // ASSERT_EQ(ObjType::Short, newlang_Short(nullptr, Obj::Arg(byte))->m_var_type_current) << toString(byte->m_var_type_current); - // ASSERT_EQ(ObjType::Int, newlang_Int(nullptr, Obj::Arg(byte))->m_var_type_current) << toString(byte->m_var_type_current); - // ASSERT_EQ(ObjType::Long, newlang_Long(nullptr, Obj::Arg(byte))->m_var_type_current) << toString(byte->m_var_type_current); - // // ASSERT_EQ(ObjType::Half, newlang_Half(nullptr, Obj::Arg(byte))->m_var_type) << toString(byte->m_var_type); - // ASSERT_EQ(ObjType::Float, newlang_Float(nullptr, Obj::Arg(byte))->m_var_type_current) << toString(byte->m_var_type_current); - // ASSERT_EQ(ObjType::Double, newlang_Double(nullptr, Obj::Arg(byte))->m_var_type_current) << toString(byte->m_var_type_current); - // - // ASSERT_EQ(ObjType::Long, newlang_Integer(nullptr, Obj::Arg(byte))->m_var_type_current) << toString(byte->m_var_type_current); - // ASSERT_EQ(ObjType::Float, newlang_Number(nullptr, Obj::Arg(byte))->m_var_type_current) << toString(byte->m_var_type_current); - // - // // ASSERT_EQ(ObjType::Byte, newlang_Byte_(nullptr, Obj::Arg(byte))->m_var_type) << toString(byte->m_var_type); - // // ASSERT_EQ(ObjType::Byte, byte->m_var_type) << toString(byte->m_var_type); - // - // - // // ASSERT_EQ(ObjType::Byte, ctx.CallByName("Byte_", Obj::Arg(byte))->m_var_type) << toString(byte->m_var_type); - // // ASSERT_EQ(ObjType::Byte, byte->m_var_type) << toString(byte->m_var_type); - // - // // @todo Для работы функций mutable функций требуется передача по ссылкам !!!!!!!!!!!!1 - // - // // ASSERT_EQ(ObjType::Char, ctx.CallByName("Char_", Obj::Arg(byte))->m_var_type) << toString(byte->m_var_type); - // // ASSERT_EQ(ObjType::Char, byte->m_var_type) << toString(byte->m_var_type); - // // - // // ASSERT_EQ(ObjType::Double, ctx.CallByName("Double_", Obj::Arg(byte))->m_var_type) << toString(byte->m_var_type); - // // ASSERT_EQ(ObjType::Double, byte->m_var_type) << toString(byte->m_var_type); - // - // // Obj::CreateFromType(); - // - // ObjPtr value = Obj::CreateNone(); - // ObjPtr range1 = Obj::CreateRange(0, 0.99, 0.1); - // - // ASSERT_TRUE(range1); - // ASSERT_EQ(range1->getType(), ObjType::Range); - // - // ASSERT_NO_THROW(ConvertRangeToDict(range1.get(), *value.get())); - // ASSERT_TRUE(value); - // - // ASSERT_EQ(value->getType(), ObjType::Dictionary); - // ASSERT_EQ(10, value->size()); - // - // ASSERT_DOUBLE_EQ(0, (*value)[0]->GetValueAsNumber()); - // ASSERT_DOUBLE_EQ(0.1, (*value)[1]->GetValueAsNumber()); - // ASSERT_DOUBLE_EQ(0.2, (*value)[2]->GetValueAsNumber()); - // ASSERT_DOUBLE_EQ(0.3, (*value)[3]->GetValueAsNumber()); - // ASSERT_DOUBLE_EQ(0.4, (*value)[4]->GetValueAsNumber()); - // ASSERT_DOUBLE_EQ(0.5, (*value)[5]->GetValueAsNumber()); - // ASSERT_DOUBLE_EQ(0.6, (*value)[6]->GetValueAsNumber()); - // ASSERT_DOUBLE_EQ(0.7, (*value)[7]->GetValueAsNumber()); - // ASSERT_DOUBLE_EQ(0.8, (*value)[8]->GetValueAsNumber()); - // ASSERT_DOUBLE_EQ(0.9, (*value)[9]->GetValueAsNumber()); - // - // - // ObjPtr range2 = Obj::CreateRange(0, -5); - // - // ASSERT_TRUE(range2); - // ASSERT_EQ(range2->getType(), ObjType::Range); - // ASSERT_EQ(0, (*range2)["start"]->GetValueAsInteger()); - // ASSERT_EQ(-5, (*range2)["stop"]->GetValueAsInteger()); - // ASSERT_EQ(-1, (*range2)["step"]->GetValueAsInteger()); - // - // ASSERT_NO_THROW(ConvertRangeToDict(range2.get(), *value.get())); - // ASSERT_TRUE(value); - // - // ASSERT_EQ(value->getType(), ObjType::Dictionary); - // ASSERT_EQ(15, value->size()); - // - // ASSERT_EQ(0, (*value)[10]->GetValueAsInteger()); - // ASSERT_EQ(-1, (*value)[11]->GetValueAsInteger()); - // ASSERT_EQ(-2, (*value)[12]->GetValueAsInteger()); - // ASSERT_EQ(-3, (*value)[13]->GetValueAsInteger()); - // ASSERT_EQ(-4, (*value)[14]->GetValueAsInteger()); - // - // torch::Tensor tensor1 = torch::empty({0}); - // ASSERT_NO_THROW(ConvertStringToTensor("test", tensor1)); - // - // ASSERT_EQ(1, tensor1.dim()); - // ASSERT_EQ(4, tensor1.size(0)); - // ASSERT_EQ('t', tensor1.index({0}).item()); - // ASSERT_EQ('e', tensor1.index({1}).item()); - // ASSERT_EQ('s', tensor1.index({2}).item()); - // ASSERT_EQ('t', tensor1.index({3}).item()); - // - // torch::Tensor tensor2 = torch::empty({0}); - // ASSERT_NO_THROW(ConvertStringToTensor(L"TESTЁ", tensor2)); - // ASSERT_EQ(1, tensor2.dim()); - // ASSERT_EQ(5, tensor2.size(0)); - // ASSERT_EQ(L'T', tensor2.index({0}).item()); - // ASSERT_EQ(L'E', tensor2.index({1}).item()); - // ASSERT_EQ(L'S', tensor2.index({2}).item()); - // ASSERT_EQ(L'T', tensor2.index({3}).item()); - // ASSERT_EQ(L'Ё', tensor2.index({4}).item()); - // - // torch::Tensor tensor_utf = torch::empty({0}); - // ASSERT_NO_THROW(ConvertStringToTensor(L"Русё", tensor_utf)); - // ASSERT_EQ(1, tensor_utf.dim()); - // ASSERT_EQ(4, tensor_utf.size(0)); - // ASSERT_EQ(L'Р', tensor_utf.index({0}).item()); - // ASSERT_EQ(L'у', tensor_utf.index({1}).item()); - // ASSERT_EQ(L'с', tensor_utf.index({2}).item()); - // ASSERT_EQ(L'ё', tensor_utf.index({3}).item()); - // - // - // std::string str1; - // ASSERT_NO_THROW(ConvertTensorToString(torch::range(1, 4, 1), str1)); - // ASSERT_STREQ("\x1\x2\x3\x4", str1.c_str()); - // - // std::wstring str2; - // ASSERT_NO_THROW(ConvertTensorToString(torch::range(0x1001, 0x4008, 0x1002), str2)); - // ASSERT_EQ(4, str2.size()); - // ASSERT_EQ(L'\x10\x01', str2[0]); - // ASSERT_EQ(L'\x20\x03', str2[1]); - // ASSERT_EQ(L'\x30\x05', str2[2]); - // ASSERT_EQ(L'\x40\x07', str2[3]); - // - // // ASSERT_EQ(0x1001, str2[0]); - // // ASSERT_EQ(0x2003, str2[1]); - // // ASSERT_EQ(0x3005, str2[2]); - // // ASSERT_EQ(0x4007, str2[3]); - // - // std::string str3; - // int array[8] = {1, 2, 3, 4, 5, 6, 7, 8}; - // torch::Tensor tensor4 = torch::from_blob(array,{2, 4}, at::kInt); - // - // ASSERT_EQ(2, tensor4.dim()); - // ASSERT_EQ(2, tensor4.size(0)); - // ASSERT_EQ(4, tensor4.size(1)); - // ASSERT_NO_THROW(ConvertTensorToString(tensor4, str1)); - // ASSERT_STREQ("\x1\x2\x3\x4\x5\x6\x7\x8", str1.c_str()); - // - // - // ObjPtr dict1 = Obj::CreateNone(); - // ASSERT_NO_THROW(ConvertTensorToDict(tensor1, *dict1.get())); - // ASSERT_EQ(4, dict1->size()); - // ASSERT_EQ('t', (*dict1)[0]->GetValueAsInteger()); - // ASSERT_EQ('e', (*dict1)[1]->GetValueAsInteger()); - // ASSERT_EQ('s', (*dict1)[2]->GetValueAsInteger()); - // ASSERT_EQ('t', (*dict1)[3]->GetValueAsInteger()); - // - // ASSERT_NO_THROW(ConvertTensorToDict(tensor4, *dict1.get())); - // ASSERT_EQ(12, dict1->size()); - // ASSERT_EQ('t', (*dict1)[0]->GetValueAsInteger()); - // ASSERT_EQ('e', (*dict1)[1]->GetValueAsInteger()); - // ASSERT_EQ('s', (*dict1)[2]->GetValueAsInteger()); - // ASSERT_EQ('t', (*dict1)[3]->GetValueAsInteger()); - // ASSERT_EQ(1, (*dict1)[4]->GetValueAsInteger()); - // ASSERT_EQ(2, (*dict1)[5]->GetValueAsInteger()); - // ASSERT_EQ(3, (*dict1)[6]->GetValueAsInteger()); - // ASSERT_EQ(4, (*dict1)[7]->GetValueAsInteger()); - // ASSERT_EQ(5, (*dict1)[8]->GetValueAsInteger()); - // ASSERT_EQ(6, (*dict1)[9]->GetValueAsInteger()); - // ASSERT_EQ(7, (*dict1)[10]->GetValueAsInteger()); - // ASSERT_EQ(8, (*dict1)[11]->GetValueAsInteger()); - // - // ASSERT_NO_THROW(ConvertTensorToDict(tensor2, *dict1.get())); - // ASSERT_EQ(17, dict1->size()); - // - // ASSERT_EQ(L'T', (*dict1)[12]->GetValueAsInteger()); - // ASSERT_EQ(L'E', (*dict1)[13]->GetValueAsInteger()); - // ASSERT_EQ(L'S', (*dict1)[14]->GetValueAsInteger()); - // ASSERT_EQ(L'T', (*dict1)[15]->GetValueAsInteger()); - // ASSERT_EQ(L'Ё', (*dict1)[16]->GetValueAsInteger()); - // - // torch::Tensor result = torch::empty({0}); - // ASSERT_NO_THROW(ConvertDictToTensor(*dict1.get(), result)); - // ASSERT_EQ(1, result.dim()); - // ASSERT_EQ(17, result.size(0)); - // - // - // ASSERT_EQ('t', result.index({0}).item()) << TensorToString(result) << "\n"; - // ASSERT_EQ('e', result.index({1}).item()); - // ASSERT_EQ('s', result[2].item()); - // ASSERT_EQ('t', result[3].item()); - // ASSERT_EQ(1, result[4].item()); - // ASSERT_EQ(2, result[5].item()); - // ASSERT_EQ(3, result[6].item()); - // ASSERT_EQ(4, result[7].item()); - // ASSERT_EQ(5, result[8].item()); - // ASSERT_EQ(6, result[9].item()); - // ASSERT_EQ(7, result[10].item()); - // ASSERT_EQ(8, result[11].item()); - // - // ASSERT_EQ(L'T', result[12].item()); - // ASSERT_EQ(L'E', result[13].item()); - // ASSERT_EQ(L'S', result[14].item()); - // ASSERT_EQ(L'T', result[15].item()); - // ASSERT_EQ(L'Ё', result[16].item()); + Context::Reset(); + Context ctx(RunTime::Init()); + + ASSERT_EQ(0, Context::m_macros.size()); + ObjPtr none = ctx.ExecStr("\\\\macro\\\\\\"); + + ASSERT_EQ(1, Context::m_macros.size()); + none = ctx.ExecStr("\\\\macro2 2\\\\\\"); + ASSERT_EQ(2, Context::m_macros.size()); + + none = ctx.ExecStr("\\\\macro3() 3\\\\\\"); + ASSERT_EQ(3, Context::m_macros.size()); + + none = ctx.ExecStr("\\\\macro4(arg) \\$arg\\\\\\"); + ASSERT_EQ(4, Context::m_macros.size()); + + + ObjPtr result = ctx.ExecStr("\\macro"); + ASSERT_TRUE(result); + ASSERT_TRUE(result->is_none_type()); + + result = ctx.ExecStr("\\macro2"); + ASSERT_TRUE(result); + ASSERT_TRUE(result->is_integer()); + ASSERT_EQ(2, result->GetValueAsInteger()); + + result = ctx.ExecStr("\\macro3()"); + ASSERT_TRUE(result); + ASSERT_TRUE(result->is_integer()); + ASSERT_EQ(3, result->GetValueAsInteger()); + + result = ctx.ExecStr("\\macro4(999)"); + ASSERT_TRUE(result); + ASSERT_TRUE(result->is_integer()); + ASSERT_EQ(999, result->GetValueAsInteger()); + + result = ctx.ExecStr("\\macro4(999);\\macro;\\macro4(42)"); + ASSERT_TRUE(result); + ASSERT_TRUE(result->is_integer()); + ASSERT_EQ(42, result->GetValueAsInteger()); + +} + +TEST(Eval, MacroDSL) { + + Context::Reset(); + Context ctx(RunTime::Init()); + + + const char * dsl = "" + "\\\\if(cond) [\\$cond]-->\\\\\\" + "\\\\elseif(cond) ,[\\$cond]-->\\\\\\" + "\\\\else ,[_]-->\\\\\\" + "" + "\\\\while(cond) [\\$cond]-->>\\\\\\" + "\\\\dowhile(cond) <<--[\\$cond]\\\\\\" + "\\\\return --\\\\\\" + "\\\\return(...) --\\$*--\\\\\\" + ""; + + ASSERT_EQ(0, Context::m_macros.size()); + ObjPtr none = ctx.ExecStr(dsl); + ASSERT_EQ(7, Context::m_macros.size()); + + ObjPtr count = ctx.ExecStr("@count:=0;"); + ASSERT_TRUE(count); + ASSERT_EQ(0, count->GetValueAsInteger()); + + const char * run_raw = "" + "count:=5;" + "[count<10]-->>{{" + " [count>5]-->{" + " --100--;" + " }; " + " count+=1;" + "}};"; + + ObjPtr result = ctx.ExecStr(run_raw); + ASSERT_TRUE(result); + ASSERT_TRUE(result->is_integer()); + ASSERT_EQ(6, count->GetValueAsInteger()); + ASSERT_EQ(100, result->GetValueAsInteger()); + const char * run_macro = "" + "count:=5;" + "\\while(count<10){{" + " \\if(count>5){" + " \\return(42);" + " };" + " count+=1;" + "}};" + ""; + + + + result = ctx.ExecStr(run_macro); + ASSERT_TRUE(result); + ASSERT_TRUE(result->is_integer()); + ASSERT_EQ(4, count->GetValueAsInteger()); + ASSERT_EQ(42, result->GetValueAsInteger()); } class OpEvalTest : public ::testing::Test { diff --git a/core/test/object_test.cpp b/core/test/object_test.cpp index ba514fd2..c3448d35 100644 --- a/core/test/object_test.cpp +++ b/core/test/object_test.cpp @@ -73,6 +73,59 @@ TEST(ObjTest, String) { Obj str2; str2.SetValue_(std::string("test2")); ASSERT_EQ(ObjType::StrChar, str2.getType()) << toString(str2.getType()); + + ObjPtr str_byte = Obj::CreateString("byte"); + ASSERT_STREQ("byte", str_byte->GetValueAsString().c_str()); + ASSERT_EQ(4, str_byte->size()); + ASSERT_EQ(4, str_byte->m_str.size()); + ASSERT_STREQ("b", (*str_byte)[0]->GetValueAsString().c_str()); + ASSERT_STREQ("y", (*str_byte)[1]->GetValueAsString().c_str()); + ASSERT_STREQ("t", (*str_byte)[2]->GetValueAsString().c_str()); + ASSERT_STREQ("e", (*str_byte)[3]->GetValueAsString().c_str()); + + str_byte->op_set_index(0, "B"); + str_byte->op_set_index(1, "Y"); + ASSERT_STREQ("BYte", str_byte->GetValueAsString().c_str()); + str_byte->op_set_index(2, "T"); + str_byte->op_set_index(3, "E"); + ASSERT_STREQ("BYTE", str_byte->GetValueAsString().c_str()); + + ObjPtr str_char = Obj::CreateString(L"строка"); + ASSERT_EQ(6, str_char->size()); + ASSERT_EQ(6, str_char->m_wstr.size()); + + ASSERT_STREQ("с", (*str_char)[0]->GetValueAsString().c_str()); + ASSERT_STREQ("т", (*str_char)[1]->GetValueAsString().c_str()); + ASSERT_STREQ("р", (*str_char)[2]->GetValueAsString().c_str()); + ASSERT_STREQ("о", (*str_char)[3]->GetValueAsString().c_str()); + ASSERT_STREQ("к", (*str_char)[4]->GetValueAsString().c_str()); + ASSERT_STREQ("а", (*str_char)[5]->GetValueAsString().c_str()); + + str_char->op_set_index(0, "С"); + str_char->op_set_index(1, "Т"); + ASSERT_STREQ("СТрока", str_char->GetValueAsString().c_str()); + str_char->op_set_index(2, "Р"); + str_char->op_set_index(3, "О"); + ASSERT_STREQ("СТРОка", str_char->GetValueAsString().c_str()); + + + ObjPtr format = Obj::CreateString("$1 $2 ${name}"); + ObjPtr str11 = (*format)(nullptr); + ASSERT_STREQ("$1 $2 ${name}", str11->GetValueAsString().c_str()); + + ObjPtr str22 = (*format)(nullptr, Obj::Arg(100)); + ASSERT_STREQ("100 $2 ${name}", str22->GetValueAsString().c_str()); + + ObjPtr str3 = (*format)(nullptr, Obj::Arg(-1), Obj::Arg("222")); + ASSERT_STREQ("-1 222 ${name}", str3->GetValueAsString().c_str()); + + ObjPtr str4 = (*format)(nullptr, Obj::Arg("value", "name")); + ASSERT_STREQ("value $2 value", str4->GetValueAsString().c_str()); + + format = Obj::CreateString("$nameno ${имя1} $name $имя"); + ObjPtr str5 = (*format)(nullptr, Obj::Arg("value", "name"), Obj::Arg("УТФ8-УТФ8", "имя"), Obj::Arg("УТФ8", "имя1")); + ASSERT_STREQ("valueno УТФ8 value УТФ8-УТФ8", str5->GetValueAsString().c_str()); + } TEST(ObjTest, Dict) { @@ -641,6 +694,41 @@ TEST(ObjTest, Tensor) { ASSERT_EQ(2, t1->m_value.dim()); ASSERT_EQ(2, t1->m_value.size(0)); ASSERT_EQ(3, t1->m_value.size(1)); + + // Байтовые строки + ObjPtr str = Obj::CreateString("test"); + ObjPtr t_str = Obj::CreateTensor(str->toTensor()); + ASSERT_EQ(t_str->m_var_type_current, ObjType::Char) << toString(t_str->m_var_type_current); + ASSERT_EQ(4, t_str->size()); + EXPECT_STREQ(t_str->toType(ObjType::StrWide)->GetValueAsString().c_str(), "test"); + + ASSERT_EQ(t_str->index_get({0})->GetValueAsInteger(), 't'); + ASSERT_EQ(t_str->index_get({1})->GetValueAsInteger(), 'e'); + ASSERT_EQ(t_str->index_get({2})->GetValueAsInteger(), 's'); + ASSERT_EQ(t_str->index_get({3})->GetValueAsInteger(), 't'); + + t_str->index_set_({1}, Obj::CreateString("E")); + t_str->index_set_({2}, Obj::CreateString("S")); + + EXPECT_STREQ(t_str->toType(ObjType::StrWide)->GetValueAsString().c_str(), "tESt"); + + // Символьные сторки + ObjPtr wstr = Obj::CreateString(L"ТЕСТ"); + ObjPtr t_wstr = Obj::CreateTensor(wstr->toTensor()); + ASSERT_EQ(t_wstr->m_var_type_current, ObjType::Int); + ASSERT_EQ(4, t_wstr->size()); + EXPECT_STREQ(t_wstr->toType(ObjType::StrWide)->GetValueAsString().c_str(), "ТЕСТ"); + + ASSERT_EQ(t_wstr->index_get({0})->GetValueAsInteger(), L'Т'); + ASSERT_EQ(t_wstr->index_get({1})->GetValueAsInteger(), L'Е'); + ASSERT_EQ(t_wstr->index_get({2})->GetValueAsInteger(), L'С'); + ASSERT_EQ(t_wstr->index_get({3})->GetValueAsInteger(), L'Т'); + + t_wstr->index_set_({1}, Obj::CreateString(L"е")); + t_wstr->index_set_({2}, Obj::CreateString(L"с")); + + EXPECT_STREQ(t_wstr->toType(ObjType::StrWide)->GetValueAsString().c_str(), "ТесТ"); + } #endif // UNITTEST \ No newline at end of file diff --git a/core/test/parser_test.cpp b/core/test/parser_test.cpp index f44a542b..ac1a9088 100644 --- a/core/test/parser_test.cpp +++ b/core/test/parser_test.cpp @@ -1714,28 +1714,6 @@ TEST_F(ParserTest, Exit) { ASSERT_TRUE(Parse("--:class(arg)--;;")); } - -// | MACRO -// { -// $$ = $1; -// } -// | MACRO call -// { -// $$ = $1; -// $$->SetArgs($call); -// } -// | MACRO MACRO_BODY -// { -// $$ = $1; -// $$->Append($2, Term::RIGHT); -// } -// | MACRO call MACRO_BODY -// { -// $$ = $1; -// $$->SetArgs($call); -// $$->Append($3, Term::RIGHT); -// } - /* * \\macro body body body body body body body body body\\\ * \\macro() body\\\ @@ -1793,6 +1771,8 @@ TEST_F(ParserTest, MacroName) { ASSERT_STREQ("", Parser::ParseMacroName(body).c_str()); body = ""; ASSERT_STREQ("", Parser::ParseMacroName(body).c_str()); + body = "\\return(...) --\\$*--"; + ASSERT_STREQ("\\return(", Parser::ParseMacroName(body).c_str()); } TEST_F(ParserTest, MacroArgs) { @@ -1841,6 +1821,24 @@ TEST_F(ParserTest, MacroArgs) { ASSERT_STREQ("11", args[0].c_str()); ASSERT_STREQ("...", args[1].c_str()); + body = "\\return(...) --\\$*--"; + args = Parser::ParseMacroArgs(body); + ASSERT_EQ(1, args.size()); + ASSERT_STREQ("...", args[0].c_str()); + + ASSERT_ANY_THROW( + body = "\\macro(,)"; + args = Parser::ParseMacroArgs(body); + ); + ASSERT_ANY_THROW( + body = "\\macro( , )"; + args = Parser::ParseMacroArgs(body); + ); + ASSERT_ANY_THROW( + body = "\\macro(,,)"; + args = Parser::ParseMacroArgs(body); + ); + body = "\\macro)"; args = Parser::ParseMacroArgs(body); ASSERT_EQ(0, args.size()); @@ -1876,12 +1874,12 @@ TEST_F(ParserTest, MacroExtract) { ASSERT_STREQ("\\macro 12345", macros.find("\\macro")->second.c_str()); ASSERT_STREQ(" ", body.c_str()); - body = "\\\\macro2() 123\\\\\\"; + body = "\\\\macro2()123\\\\\\"; ASSERT_TRUE(Parser::ExtractMacros(body, macros)); ASSERT_EQ(2, macros.size()); ASSERT_TRUE(macros.find("\\macro2(") != macros.end()); - ASSERT_STREQ("\\macro2() 123", macros.find("\\macro2(")->second.c_str()); - ASSERT_STREQ(" ", body.c_str()); + ASSERT_STREQ("\\macro2()123", macros.find("\\macro2(")->second.c_str()); + ASSERT_STREQ(" ", body.c_str()); body = "\\\\macro3(name)12345\\\\\\"; ASSERT_TRUE(Parser::ExtractMacros(body, macros)); @@ -1896,6 +1894,42 @@ TEST_F(ParserTest, MacroExtract) { ASSERT_TRUE(macros.find("\\macro3(") != macros.end()); ASSERT_STREQ("\\macro4(name, name2) 12345\n\n6789", macros.find("\\macro4(")->second.c_str()); ASSERT_STREQ(" \n\n ", body.c_str()); + + body = "\\\\empty\\\\\\"; + ASSERT_TRUE(Parser::ExtractMacros(body, macros)); + ASSERT_EQ(5, macros.size()); + ASSERT_TRUE(macros.find("\\empty") != macros.end()); + ASSERT_STREQ("\\empty", macros.find("\\empty")->second.c_str()); + ASSERT_STREQ(" ", body.c_str()); + + body = "\\\\empty( )\\\\\\"; + ASSERT_TRUE(Parser::ExtractMacros(body, macros)); + ASSERT_EQ(6, macros.size()); + ASSERT_TRUE(macros.find("\\empty(") != macros.end()); + ASSERT_STREQ("\\empty( )", macros.find("\\empty(")->second.c_str()); + ASSERT_STREQ(" ", body.c_str()); + + body = "\\\\m1\\\\\\\\\\m2() \\\\\\\\\\m3\\\\\\"; + size_t size = body.size(); + ASSERT_TRUE(Parser::ExtractMacros(body, macros)); + ASSERT_EQ(7, macros.size()); + ASSERT_EQ(size, body.size()); + ASSERT_STREQ(" \\\\m2() \\\\\\\\\\m3\\\\\\", body.c_str()); + + ASSERT_TRUE(Parser::ExtractMacros(body, macros)); + ASSERT_EQ(8, macros.size()); + ASSERT_EQ(size, body.size()); + ASSERT_STREQ(" \\\\m3\\\\\\", body.c_str()); + + ASSERT_TRUE(Parser::ExtractMacros(body, macros)); + ASSERT_EQ(9, macros.size()); + ASSERT_EQ(size, body.size()); + ASSERT_STREQ(" ", body.c_str()); + + std::string result = Parser::ParseAllMacros("\\macro \\macro2() \\macro", ¯os); + ASSERT_STREQ("12345 123 12345", result.c_str()); + + } TEST_F(ParserTest, ExpandMacro) { @@ -1917,18 +1951,18 @@ TEST_F(ParserTest, ExpandMacro) { body = "\\macro \\macro \\macro"; result = Parser::ExpandMacro(macro, body); ASSERT_STREQ("\\macro \\macro \\macro", result.c_str()); - + macro = "\\macro()12345"; body = "\\macro() \\macro() \\macro"; result = Parser::ExpandMacro(macro, body); ASSERT_STREQ("12345 12345 \\macro", result.c_str()); - + macro = "\\macro()12345"; body = "\\macro(88) \\macro(99) \\macro"; result = Parser::ExpandMacro(macro, body); ASSERT_STREQ("12345 12345 \\macro", result.c_str()); - - + + macro = "\\macro(arg)\\$arg"; body = "\\macro(88)"; result = Parser::ExpandMacro(macro, body); @@ -1973,6 +2007,38 @@ TEST_F(ParserTest, ExpandMacro) { body = "\\macro(1,2)\\macro(1,2)"; result = Parser::ExpandMacro(macro, body); ASSERT_STREQ("1,2 1 21,21,2 1 21,2", result.c_str()); + + macro = "\\\\return --\\\\\\"; + body = "\\return(100);"; + result = Parser::ExpandMacro(macro, body); + ASSERT_STREQ("\\return(100);", result.c_str()); + + macro = "\\return(...) --\\$*--"; + body = "\\return(100);"; + result = Parser::ExpandMacro(macro, body); + ASSERT_STREQ("--100--;", result.c_str()); + +} + +TEST_F(ParserTest, MacroDSL) { + + Parser::MacrosStore macros; + std::string dsl = "" + "\\\\if(cond) [\\$cond]-->\\\\\\" + "\\\\elseif(cond) ,[\\$cond]-->\\\\\\" + "\\\\else ,[_]-->\\\\\\" + "" + "\\\\while(cond) [\\$cond]<<->>\\\\\\" + "\\\\dowhile(cond) <<->>[\\$cond]\\\\\\" + "\\\\return --\\\\\\" + "\\\\return(...) --\\$*--\\\\\\" + ""; + + while (Parser::ExtractMacros(dsl, macros)) + ; + ASSERT_EQ(7, macros.size()); + + } TEST_F(ParserTest, HelloWorld) { From 2f6d6b3821d9b92ec981d1557d639233e09bae18 Mon Sep 17 00:00:00 2001 From: Aleksandr Ryabikov Date: Sat, 25 Jun 2022 22:11:28 +0300 Subject: [PATCH 05/31] =?UTF-8?q?=D0=98=D1=81=D0=BF=D1=80=D0=B0=D0=B2?= =?UTF-8?q?=D0=B8=D0=BB=20=D1=82=D0=B5=D1=81=D1=82=D1=8B=20=D0=B4=D0=BB?= =?UTF-8?q?=D1=8F=20=D0=BF=D1=80=D0=BE=D0=B2=D0=B5=D1=80=D0=BA=D0=B8=20DSL?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/test/eval_test.cpp | 22 +++++++++++++--------- core/test/parser_test.cpp | 2 +- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/core/test/eval_test.cpp b/core/test/eval_test.cpp index 04ff3b5e..9bd0d979 100644 --- a/core/test/eval_test.cpp +++ b/core/test/eval_test.cpp @@ -817,11 +817,13 @@ TEST(Eval, MacroDSL) { const char * run_raw = "" "count:=5;" - "[count<10]-->>{{" - " [count>5]-->{" - " --100--;" - " }; " - " count+=1;" + "(){{" + " [count<10]-->>{" + " [count>5]-->{" + " --100--;" + " }; " + " count+=1;" + " };" "}};"; ObjPtr result = ctx.ExecStr(run_raw); @@ -832,11 +834,13 @@ TEST(Eval, MacroDSL) { const char * run_macro = "" "count:=5;" - "\\while(count<10){{" - " \\if(count>5){" + "(){{" + " \\while(count<10){" + " \\if(count>5){" " \\return(42);" " };" - " count+=1;" + " count+=1;" + " };" "}};" ""; @@ -845,7 +849,7 @@ TEST(Eval, MacroDSL) { result = ctx.ExecStr(run_macro); ASSERT_TRUE(result); ASSERT_TRUE(result->is_integer()); - ASSERT_EQ(4, count->GetValueAsInteger()); + ASSERT_EQ(6, count->GetValueAsInteger()); ASSERT_EQ(42, result->GetValueAsInteger()); } diff --git a/core/test/parser_test.cpp b/core/test/parser_test.cpp index ac1a9088..e71a8e62 100644 --- a/core/test/parser_test.cpp +++ b/core/test/parser_test.cpp @@ -2013,7 +2013,7 @@ TEST_F(ParserTest, ExpandMacro) { result = Parser::ExpandMacro(macro, body); ASSERT_STREQ("\\return(100);", result.c_str()); - macro = "\\return(...) --\\$*--"; + macro = "\\return(...)--\\$*--"; body = "\\return(100);"; result = Parser::ExpandMacro(macro, body); ASSERT_STREQ("--100--;", result.c_str()); From cac8b79f59b94eaa6a6251ecd89daff7012b3d95 Mon Sep 17 00:00:00 2001 From: Aleksandr Ryabikov Date: Sun, 26 Jun 2022 16:42:36 +0300 Subject: [PATCH 06/31] =?UTF-8?q?=D0=A1=D0=B4=D0=B5=D0=BB=D0=B0=D0=BD?= =?UTF-8?q?=D1=8B=20=D0=BC=D0=B0=D0=BA=D1=80=D0=BE=D1=81=D1=8B=20=D1=81=20?= =?UTF-8?q?=D1=82=D0=B5=D1=81=D1=82=D0=B0=D0=BC=D0=B8=20+=20=D0=B8=D0=B7?= =?UTF-8?q?=D0=BC=D0=B5=D0=BD=D0=B5=D0=BD=D1=82=20=D1=81=D0=B8=D0=BD=D1=82?= =?UTF-8?q?=D0=B0=D0=BA=D1=81=D0=B8=D1=81=20=D1=86=D0=B8=D0=BA=D0=BB=D0=BE?= =?UTF-8?q?=D0=B2=20=D0=B8=20=D0=BD=D0=B5=D0=B1=D0=BE=D0=BB=D1=8C=D1=88?= =?UTF-8?q?=D0=BE=D0=B9=20=D1=80=D0=B5=D1=84=D0=B0=D0=BA=D1=82=D0=BE=D1=80?= =?UTF-8?q?=D0=B8=D0=BD=D0=B3=20API?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/builtin.cpp | 32 +- core/context.cpp | 486 ++++++++++--------- core/context.h | 650 +++++++++++++------------ core/lexer.l | 6 +- core/nlc.h | 978 +++++++++++++++++++------------------- core/object.cpp | 2 +- core/parser.y | 9 +- core/term.h | 7 +- core/test/alg_test.cpp | 58 +-- core/test/eval_test.cpp | 71 ++- core/test/nlc_test.cpp | 2 +- core/test/object_test.cpp | 22 +- core/test/parser_test.cpp | 116 ++--- docs/syntax.md | 8 +- 14 files changed, 1250 insertions(+), 1197 deletions(-) diff --git a/core/builtin.cpp b/core/builtin.cpp index 359914a6..32351099 100644 --- a/core/builtin.cpp +++ b/core/builtin.cpp @@ -13,12 +13,12 @@ using namespace newlang; namespace newlang { NEWLANG_TRANSPARENT(min) { - if (in.size() < 2) { + if(in.size() < 2) { LOG_RUNTIME("Empty argument list parameter!"); } ObjPtr out = in.at(1).second; for (size_t i = 2; i < in.size(); i++) { - if (*in.at(i).second < out) { + if(*in.at(i).second < out) { out = in.at(i).second; } } @@ -26,12 +26,12 @@ namespace newlang { } NEWLANG_TRANSPARENT(max) { - if (in.size() < 2) { + if(in.size() < 2) { LOG_RUNTIME("Empty argument list parameter!"); } ObjPtr out = in.at(1).second; for (size_t i = 2; i < in.size(); i++) { - if (*in.at(i).second > out) { + if(*in.at(i).second > out) { out = in.at(i).second; } } @@ -39,28 +39,28 @@ namespace newlang { } NEWLANG_FUNCTION(clone) { - if (in.size() != 2) { + if(in.size() != 2) { LOG_RUNTIME("Bad argument count parameter!"); } return in[1]->Clone(nullptr); } NEWLANG_FUNCTION(const_) { - if (in.size() != 2) { + if(in.size() != 2) { LOG_RUNTIME("Bad argument count parameter!"); } return in[1]->MakeConst(); } NEWLANG_FUNCTION(mutable_) { - if (in.size() != 2) { + if(in.size() != 2) { LOG_RUNTIME("Bad argument count parameter!"); } return in[1]->MakeMutable(); } NEWLANG_FUNCTION(import) { - if (!ctx) { + if(!ctx) { LOG_RUNTIME("No access to context!"); } return ctx->CreateNative(in.at(1).second->GetValueAsString().c_str(), @@ -68,17 +68,17 @@ namespace newlang { } NEWLANG_FUNCTION(eval) { - if (!ctx) { + if(!ctx) { LOG_RUNTIME("No access to context!"); } - return ctx->ExecStr(in.at(1).second->GetValueAsString().c_str()); + return ctx->ExecStr(in.at(1).second->GetValueAsString().c_str(), &in, true); } NEWLANG_FUNCTION(exec) { - if (!ctx) { + if(!ctx) { LOG_RUNTIME("No access to context!"); } - return ctx->ExecFile(in.at(1).second->GetValueAsString().c_str()); + return ctx->ExecFile(in.at(1).second->GetValueAsString().c_str(), &in, true); } NEWLANG_TRANSPARENT(help) { @@ -99,17 +99,17 @@ namespace newlang { bool BuiltInTorchDirect::CheckDirect(CompileInfo &ci, TermPtr &term, std::string &output) { - if (term->size() == 0 && m_tensor_noarg.find(term->getText()) != m_tensor_noarg.end()) { + if(term->size() == 0 && m_tensor_noarg.find(term->getText()) != m_tensor_noarg.end()) { output += "->asTensor_()." + term->getText() + "(), " + output; return true; - } else if (term->size() == 1) { + } else if(term->size() == 1) { - if ((*term)[0]->IsScalar() && m_tensor_scalar.find(term->getText()) != m_tensor_scalar.end()) { + if((*term)[0]->IsScalar() && m_tensor_scalar.find(term->getText()) != m_tensor_scalar.end()) { output += "->asTensor_()." + term->getText() + "(" + (*term)[0]->getText() + "), " + output; return true; - } else if ((*term)[0]->getTermID() == TermID::TERM) { + } else if((*term)[0]->getTermID() == TermID::TERM) { std::string temp; NewLang::GetImpl(ci, (*term)[0], temp); output += "->asTensor_()." + term->getText() + "(" + temp + "->asTensor_()), " + output; diff --git a/core/context.cpp b/core/context.cpp index 1324cb59..54cc9113 100644 --- a/core/context.cpp +++ b/core/context.cpp @@ -47,7 +47,7 @@ Parser::MacrosStore Context::m_macros; Context::Context(RuntimePtr global) { m_runtime = global; - if (Context::m_funcs.empty()) { + if(Context::m_funcs.empty()) { VERIFY(CreateBuiltin("min(arg, ...)", (void *) &min, ObjType::TRANSPARENT)); VERIFY(CreateBuiltin("мин(arg, ...)", (void *) &min, ObjType::TRANSPARENT)); @@ -62,7 +62,7 @@ Context::Context(RuntimePtr global) { } - if (Context::m_types.empty()) { + if(Context::m_types.empty()) { VERIFY(RegisterTypeHierarchy(ObjType::None,{})); VERIFY(RegisterTypeHierarchy(ObjType::Any,{})); @@ -136,7 +136,7 @@ Context::Context(RuntimePtr global) { } - if (Context::m_builtin_calls.empty()) { + if(Context::m_builtin_calls.empty()) { #define REGISTER_FUNC(name, func) \ ASSERT(Context::m_builtin_calls.find(name) == Context::m_builtin_calls.end()); \ Context::m_builtin_calls[name] = &Context::func_##func; @@ -146,7 +146,7 @@ Context::Context(RuntimePtr global) { #undef REGISTER_FUNC } - if (Context::m_ops.empty()) { + if(Context::m_ops.empty()) { #define REGISTER_OP(op, func) \ ASSERT(Context::m_ops.find(op) == Context::m_ops.end()); \ Context::m_ops[op] = &Context::op_##func; @@ -172,7 +172,7 @@ bool Context::CreateBuiltin(const char *prototype, void *func, ObjType type) { obj->m_var_is_init = true; auto found = m_funcs.find(proto->Left()->getText()); - if (found != m_funcs.end()) { + if(found != m_funcs.end()) { LOG_DEBUG("Buildin function %s already exists!", proto->Left()->toString().c_str()); return false; } @@ -183,7 +183,7 @@ bool Context::CreateBuiltin(const char *prototype, void *func, ObjType type) { inline ObjType newlang::typeFromString(const std::string type, Context *ctx, bool *has_error) { - if (ctx) { + if(ctx) { return ctx->BaseTypeFromString(type, has_error); } @@ -192,15 +192,15 @@ inline ObjType newlang::typeFromString(const std::string type, Context *ctx, boo return ObjType:: name; \ } - if (type.empty()) { + if(type.empty()) { return ObjType::None; - } else if (type.compare("_") == 0) { + } else if(type.compare("_") == 0) { return ObjType::None; } NL_TYPES(DEFINE_CASE) #undef DEFINE_CASE - if (has_error) { + if(has_error) { *has_error = true; return ObjType::None; @@ -209,16 +209,16 @@ inline ObjType newlang::typeFromString(const std::string type, Context *ctx, boo } ObjPtr Context::RegisterObject(ObjPtr var) { - if (!var || var->getName().empty()) { + if(!var || var->getName().empty()) { LOG_RUNTIME("Empty object name %s", var ? var->toString().c_str() : ""); } ASSERT(var->m_namespace.empty()); - if (isGlobal(var->getName())) { + if(isGlobal(var->getName())) { var->getName() = var->getName().substr(1); m_global_terms.push_back(var, var->getName()); } - if (isLocal(var->getName())) { + if(isLocal(var->getName())) { var->getName() = var->getName().substr(1); } push_back(var, var->getName()); @@ -232,40 +232,48 @@ void newlang::NewLangSignalHandler(int signal) { //#include "StdCapture.h" -ObjPtr Context::ExecStr(Context *ctx, TermPtr term, Obj *args) { +ObjPtr Context::ExecStr(Context *ctx, TermPtr term, Obj *args, bool int_catch) { // StdCapture Capture; // // Capture.BeginCapture(); - // auto previous_handler = signal(SIGABRT, &NewLangSignalHandler); - // try { + auto previous_handler = signal(SIGABRT, &NewLangSignalHandler); + try { - switch (term->m_id) { - case TermID::END: - return eval_END(ctx, term, args); + switch(term->m_id) { + case TermID::END: + return eval_END(ctx, term, args); #define DEFINE_CASE(name) \ case TermID::name: \ return eval_##name(ctx, term, args); - NL_TERMS(DEFINE_CASE) + NL_TERMS(DEFINE_CASE) #undef DEFINE_CASE + } + } catch (Interrupt &obj) { + + signal(SIGABRT, previous_handler); + ASSERT(obj.m_obj); + + if(int_catch && obj.m_obj->getType() == ObjType::Return) { + + ASSERT(obj.m_obj->size() == 1); + return (*obj.m_obj)[0]; // Возврат данных + + } else if(int_catch) { + ASSERT(obj.m_obj); + return obj.m_obj; // Прерывания анализуирются выше по уровню + } + + throw; // Пробросить прерывание дальше } - // } catch (Interruption &err) { - // - // signal(SIGABRT, previous_handler); - // - //// if (err.m_obj && err.m_obj->m_class_name.compare(Interruption::Parser) == 0) { - //// } else { - // throw; - //// } - // // Capture.EndCapture(); - // } + signal(SIGABRT, previous_handler); - return eval_UNKNOWN(ctx, term, args); + return Obj::CreateNone(); } ObjPtr Context::eval_END(Context *ctx, const TermPtr &term, Obj *args) { @@ -305,13 +313,13 @@ ObjPtr Context::eval_BLOCK_TRY(Context *ctx, const TermPtr &term, Obj *args) { ObjPtr Context::eval_CALL_BLOCK(Context *ctx, const TermPtr &term, Obj *args) { ASSERT(term && term->getTermID() == TermID::CALL_BLOCK); - return CallBlock(ctx, term, args); + return CallBlock(ctx, term, args, false); } ObjPtr Context::eval_CALL_TRY(Context *ctx, const TermPtr &term, Obj *args) { ASSERT(term && term->getTermID() == TermID::CALL_TRY); - return CallBlockTry(ctx, term, args); + return CallBlock(ctx, term, args, true); } ObjPtr Context::eval_ITERATOR_QQ(Context *ctx, const TermPtr &term, Obj *args) { @@ -462,7 +470,7 @@ ObjPtr Context::CREATE_OR_ASSIGN(Context *ctx, const TermPtr &term, Obj *local_v std::vector list_obj; // Список реальных переменных ассоциированных с терминами TermPtr next = term->Left(); - while (next && next->getTermID() != TermID::END) { + while(next && next->getTermID() != TermID::END) { list_term.push_back(next); next = next->m_comma_seq; } @@ -471,41 +479,41 @@ ObjPtr Context::CREATE_OR_ASSIGN(Context *ctx, const TermPtr &term, Obj *local_v bool is_ellipsis = false; for (auto & elem : list_term) { - if (elem->getTermID() == TermID::ELLIPSIS) { + if(elem->getTermID() == TermID::ELLIPSIS) { //@todo добавить поддержку многоточия с левой стороный оператора присвоения NL_PARSER(elem, "Ellipsis on the left side in assignment not implemented!"); - if (is_ellipsis) { + if(is_ellipsis) { NL_PARSER(elem, "Multiple ellipsis on the left side of the assignment!"); } is_ellipsis = true; result = Obj::CreateType(ObjType::Ellipsis); - } else if (elem->getTermID() == TermID::NONE) { + } else if(elem->getTermID() == TermID::NONE) { result = Obj::CreateNone(); } else { auto found = ctx->select(elem->m_text); - if (found.complete() && mode == CreateMode::ASSIGN_ONLY) { + if(found.complete() && mode == CreateMode::ASSIGN_ONLY) { NL_PARSER(elem, "Variable '%s' not found!", elem->m_text.c_str()); } - if (!found.complete()) { + if(!found.complete()) { result = (*found).lock(); // Но она может быть возвращена как локальная } - if (result && mode == CreateMode::CREATE_ONLY) { + if(result && mode == CreateMode::CREATE_ONLY) { NL_PARSER(elem, "Variable '%s' already exists!", elem->m_text.c_str()); } - if (!term->Right()) { // Удаление глобальной переменной + if(!term->Right()) { // Удаление глобальной переменной ctx->erase(found); } else { - if (!result && (mode == CreateMode::ASSIGN_ONLY)) { + if(!result && (mode == CreateMode::ASSIGN_ONLY)) { NL_PARSER(term->Left(), "Object '%s' not found!", term->Left()->m_text.c_str()); } - if (!result) { + if(!result) { result = CreateLVal(ctx, elem, local_vars); - if (!result) { + if(!result) { NL_PARSER(term->Left(), "Fail create lvalue object!"); } } @@ -514,7 +522,7 @@ ObjPtr Context::CREATE_OR_ASSIGN(Context *ctx, const TermPtr &term, Obj *local_v list_obj.push_back(result); } - if (!term->Right()) { + if(!term->Right()) { // Для удаления переменных все сделано return result; } @@ -522,38 +530,38 @@ ObjPtr Context::CREATE_OR_ASSIGN(Context *ctx, const TermPtr &term, Obj *local_v // Что присваиваем (правая часть выражения) - пока единичный объект // @todo В будущем можно будет сделать сахар для обмена значениями при одинаковом кол-ве объектов у оператора присваивания // a, b = b, a; a, b, c = c, b, a; и т.д. - if (term->Right() && term->Right()->getTermID() != TermID::ELLIPSIS && term->Right()->m_comma_seq) { + if(term->Right() && term->Right()->getTermID() != TermID::ELLIPSIS && term->Right()->m_comma_seq) { NL_PARSER(term->Right()->Right(), "Multiple assignments not implemented!"); } ObjPtr rval; - if (term->Right()->getTermID() == TermID::ELLIPSIS) { + if(term->Right()->getTermID() == TermID::ELLIPSIS) { ASSERT(term->Right()->Right()); - rval = ExecStr(ctx, term->Right()->Right(), local_vars); + rval = ExecStr(ctx, term->Right()->Right(), local_vars, false); } else { - rval = ExecStr(ctx, term->Right(), local_vars); + rval = ExecStr(ctx, term->Right(), local_vars, false); } - if (!rval) { + if(!rval) { NL_PARSER(term->Right(), "Object is missing or expression is not evaluated!"); } ASSERT(list_obj.size() == list_term.size()); - if (term->Right()->getTermID() == TermID::ELLIPSIS) { - if (rval->is_dictionary_type() || rval->is_tensor()) { - if (rval->is_scalar()) { + if(term->Right()->getTermID() == TermID::ELLIPSIS) { + if(rval->is_dictionary_type() || rval->is_tensor()) { + if(rval->is_scalar()) { LOG_RUNTIME("Fail expand scalar!"); } for (int i = 0; i < list_obj.size() - 1; i++) { - if (list_term[i]->getTermID() != TermID::NONE) { - if (i < rval->size()) { + if(list_term[i]->getTermID() != TermID::NONE) { + if(i < rval->size()) { list_obj[i]->SetValue_((*rval)[i]); //->Clone() } else { list_obj[i]->SetValue_(Obj::CreateNone()); } } } - if (list_obj.size() - 1 < rval->size()) { + if(list_obj.size() - 1 < rval->size()) { // Удалить первые элементы rval->resize_(-(rval->size() - (list_obj.size() - 1)), nullptr); } else { @@ -570,10 +578,10 @@ ObjPtr Context::CREATE_OR_ASSIGN(Context *ctx, const TermPtr &term, Obj *local_v // Присвоеить единственное значение всем элементам с левой стороны оператора присовения for (int i = 0; i < list_obj.size(); i++) { - if (isType(list_term[i]->m_text)) { + if(isType(list_term[i]->m_text)) { // Новый тип - if (ctx->m_types.find(list_term[i]->m_text) != ctx->m_types.end()) { + if(ctx->m_types.find(list_term[i]->m_text) != ctx->m_types.end()) { LOG_RUNTIME("Type name '%s' already exists!", list_term[i]->m_text.c_str()); } @@ -584,11 +592,11 @@ ObjPtr Context::CREATE_OR_ASSIGN(Context *ctx, const TermPtr &term, Obj *local_v ctx->m_types[list_term[i]->m_text] = result; - } else if (list_term[i]->getTermID() == TermID::NONE) { + } else if(list_term[i]->getTermID() == TermID::NONE) { // Skip } else { list_obj[i]->SetValue_(rval); - if (list_obj[i]->m_var_type_current == ObjType::FUNCTION && (rval->m_var_type_current == ObjType::BLOCK || rval->m_var_type_current == ObjType::BLOCK_TRY)) { + if(list_obj[i]->m_var_type_current == ObjType::FUNCTION && (rval->m_var_type_current == ObjType::BLOCK || rval->m_var_type_current == ObjType::BLOCK_TRY)) { list_obj[i]->m_var_type_current = ObjType::EVAL_FUNCTION; } result = list_obj[i]; @@ -627,8 +635,8 @@ ObjPtr Context::eval_FUNCTION(Context *ctx, const TermPtr &term, Obj * args) { ASSERT(ctx); auto found = ctx->select(term->Left()->m_text); - if (!term->Right()) { - if (!found.complete()) { + if(!term->Right()) { + if(!found.complete()) { ctx->erase(found); return Obj::Yes(); } @@ -636,22 +644,22 @@ ObjPtr Context::eval_FUNCTION(Context *ctx, const TermPtr &term, Obj * args) { } ObjPtr lval = CreateLVal(ctx, term->Left(), args); - if (!lval) { + if(!lval) { NL_PARSER(term->Left(), "Fail create lvalue object!"); } - if (term->Right()->getTermID() == TermID::CALL) { + if(term->Right()->getTermID() == TermID::CALL) { lval->SetValue_(CreateRVal(ctx, term->Right())); } else { - if (term->getTermID() == TermID::FUNCTION) { + if(term->getTermID() == TermID::FUNCTION) { lval->m_var_type_current = ObjType::EVAL_FUNCTION; - } else if (term->getTermID() == TermID::TRANSPARENT) { + } else if(term->getTermID() == TermID::TRANSPARENT) { lval->m_var_type_current = ObjType::SimplePureFunc; - } else if (term->getTermID() == TermID::SIMPLE_AND) { + } else if(term->getTermID() == TermID::SIMPLE_AND) { lval->m_var_type_current = ObjType::SimplePureAND; - } else if (term->getTermID() == TermID::SIMPLE_OR) { + } else if(term->getTermID() == TermID::SIMPLE_OR) { lval->m_var_type_current = ObjType::SimplePureOR; - } else if (term->getTermID() == TermID::SIMPLE_XOR) { + } else if(term->getTermID() == TermID::SIMPLE_XOR) { lval->m_var_type_current = ObjType::SimplePureXOR; } else { @@ -728,25 +736,58 @@ ObjPtr Context::eval_WHILE(Context *ctx, const TermPtr &term, Obj * args) { ASSERT(term->Right()); ObjPtr result = Obj::CreateNone(); - ObjPtr cond = ExecStr(ctx, term->Left(), args); - while (cond->GetValueAsBoolean()) { + ObjPtr cond = ExecStr(ctx, term->Left(), args, false); + while(cond->GetValueAsBoolean()) { + + try { + + LOG_DEBUG("result %s", result->toString().c_str()); + + result = CreateRVal(ctx, term->Right(), args, false); + cond = ExecStr(ctx, term->Left(), args, false); - result = CreateRVal(ctx, term->Right(), args); - cond = ExecStr(ctx, term->Left(), args); + } catch (Interrupt &obj) { + + ASSERT(obj.m_obj); + + if(obj.m_obj->getType() == ObjType::Break) { + break; + } else if(obj.m_obj->getType() == ObjType::Continue) { + continue; + } else { + throw; // Пробросить прерывание дальше + } + } } return result; } -ObjPtr Context::eval_UNTIL(Context *ctx, const TermPtr &term, Obj * args) { +ObjPtr Context::eval_DOWHILE(Context *ctx, const TermPtr &term, Obj * args) { ASSERT(term->Left()); ASSERT(term->Right()); ObjPtr result; ObjPtr cond; do { - result = CreateRVal(ctx, term->Left(), args); - cond = ExecStr(ctx, term->Right(), args); - } while (cond->GetValueAsBoolean()); + try { + + result = CreateRVal(ctx, term->Left(), args, false); + cond = ExecStr(ctx, term->Right(), args, false); + + } catch (Interrupt &obj) { + + ASSERT(obj.m_obj); + + if(obj.m_obj->getType() == ObjType::Break) { + break; + } else if(obj.m_obj->getType() == ObjType::Continue) { + continue; + } else { + throw; // Пробросить прерывание дальше + } + } + + } while(cond->GetValueAsBoolean()); return result; } @@ -762,18 +803,18 @@ ObjPtr Context::eval_FOLLOW(Context *ctx, const TermPtr &term, Obj * args) { for (int i = 0; i < term->m_follow.size(); i++) { ASSERT(term->m_follow[i]->Left()); - ObjPtr cond = ExecStr(ctx, term->m_follow[i]->Left(), args); + ObjPtr cond = ExecStr(ctx, term->m_follow[i]->Left(), args, false); - if (cond->GetValueAsBoolean() || (i + 1 == term->m_follow.size() && cond->is_none_type())) { + if(cond->GetValueAsBoolean() || (i + 1 == term->m_follow.size() && cond->is_none_type())) { - return CreateRVal(ctx, term->m_follow[i]->Right(), args); + return CreateRVal(ctx, term->m_follow[i]->Right(), args, false); } } return Obj::CreateNone(); } bool Context::MatchCompare(Obj &match, ObjPtr &value, MatchMode mode, Context *ctx) { - switch (mode) { + switch(mode) { case MatchMode::EQUAL: return match.op_equal(value); case MatchMode::STRICT: @@ -793,7 +834,7 @@ bool Context::MatchEstimate(Obj &match, const TermPtr &match_item, MatchMode mod ObjPtr cond = CreateRVal(ctx, match_item, args); - if (cond->is_none_type() || MatchCompare(match, cond, mode, ctx)) { + if(cond->is_none_type() || MatchCompare(match, cond, mode, ctx)) { return true; } else { for (int i = 0; i < match_item->m_follow.size(); i++) { @@ -801,7 +842,7 @@ bool Context::MatchEstimate(Obj &match, const TermPtr &match_item, MatchMode mod ASSERT(match_item->m_follow[i]); cond = CreateRVal(ctx, match_item->m_follow[i], args); - if (cond->is_none_type() || MatchCompare(match, cond, mode, ctx)) { + if(cond->is_none_type() || MatchCompare(match, cond, mode, ctx)) { return true; } @@ -823,15 +864,15 @@ ObjPtr Context::eval_MATCHING(Context *ctx, const TermPtr &term, Obj * args) { ASSERT(term->Right()); MatchMode mode; - if (term->m_text.compare("==>") == 0) { + if(term->m_text.compare("==>") == 0) { mode = MatchMode::EQUAL; - } else if (term->m_text.compare("===>") == 0) { + } else if(term->m_text.compare("===>") == 0) { mode = MatchMode::STRICT; - } else if (term->m_text.compare("~>") == 0) { + } else if(term->m_text.compare("~>") == 0) { mode = MatchMode::TYPE_NAME; - } else if (term->m_text.compare("~~>") == 0) { + } else if(term->m_text.compare("~~>") == 0) { mode = MatchMode::TYPE_EQUAL; - } else if (term->m_text.compare("~~~>") == 0) { + } else if(term->m_text.compare("~~~>") == 0) { mode = MatchMode::TYPE_STRICT; } else { NL_PARSER(term, "Unknown pattern matching type!"); @@ -846,7 +887,7 @@ ObjPtr Context::eval_MATCHING(Context *ctx, const TermPtr &term, Obj * args) { ObjPtr cond = CreateRVal(ctx, list->Left(), args); - if (MatchEstimate(*cond.get(), list->Left(), mode, ctx, args)) { + if(MatchEstimate(*cond.get(), list->Left(), mode, ctx, args)) { return CreateRVal(ctx, list->Right(), args); } else { for (int i = 0; i < list->m_block.size(); i++) { @@ -854,7 +895,7 @@ ObjPtr Context::eval_MATCHING(Context *ctx, const TermPtr &term, Obj * args) { ASSERT(list->m_block[i]->Left()); ASSERT(list->m_block[i]->Right()); - if (MatchEstimate(*cond.get(), list->m_block[i]->Left(), mode, ctx, args)) { + if(MatchEstimate(*cond.get(), list->m_block[i]->Left(), mode, ctx, args)) { return CreateRVal(ctx, list->m_block[i]->Right(), args); } @@ -892,7 +933,7 @@ ObjPtr Context::eval_SOURCE(Context *ctx, const TermPtr &term, Obj * args) { */ ObjPtr Context::eval_OPERATOR(Context *ctx, const TermPtr &term, Obj * args) { - if (Context::m_ops.find(term->m_text) == Context::m_ops.end()) { + if(Context::m_ops.find(term->m_text) == Context::m_ops.end()) { LOG_RUNTIME("Eval op '%s' not exist!", term->m_text.c_str()); } @@ -1028,7 +1069,7 @@ ObjPtr Context::op_BIT_XOR_(Context *ctx, const TermPtr &term, Obj * args) { ObjPtr Context::op_PLUS(Context *ctx, const TermPtr &term, Obj * args) { ASSERT(term); ASSERT(term->Right()); - if (term->Left()) { + if(term->Left()) { return ExecStr(ctx, term->Left(), args)->operator+(ExecStr(ctx, term->Right(), args)); } @@ -1038,7 +1079,7 @@ ObjPtr Context::op_PLUS(Context *ctx, const TermPtr &term, Obj * args) { ObjPtr Context::op_MINUS(Context *ctx, const TermPtr &term, Obj * args) { ASSERT(term); ASSERT(term->Right()); - if (term->Left()) { + if(term->Left()) { return ExecStr(ctx, term->Left(), args)->operator-(ExecStr(ctx, term->Right(), args)); } @@ -1158,7 +1199,7 @@ ObjPtr Context::op_TYPE_EQ(Context *ctx, const TermPtr &term, Obj * args) { ASSERT(term->Left()); ASSERT(term->Right()); - if (isType(term->Right()->GetFullName())) { + if(isType(term->Right()->GetFullName())) { return Obj::CreateBool(ExecStr(ctx, term->Left(), args)->op_class_test(term->Right()->GetFullName().c_str(), ctx)); } return Obj::CreateBool(ExecStr(ctx, term->Left(), args)->op_class_test(ExecStr(ctx, term->Right(), args), ctx)); @@ -1184,7 +1225,7 @@ ObjPtr Context::op_TYPE_NE(Context *ctx, const TermPtr &term, Obj * args) { ASSERT(term); ASSERT(term->Left()); ASSERT(term->Right()); - if (isType(term->Right()->GetFullName())) { + if(isType(term->Right()->GetFullName())) { return Obj::CreateBool(!ExecStr(ctx, term->Left(), args)->op_class_test(term->Right()->GetFullName().c_str(), ctx)); } return Obj::CreateBool(!ExecStr(ctx, term->Left(), args)->op_class_test(ExecStr(ctx, term->Right(), args), ctx)); @@ -1261,9 +1302,9 @@ ObjPtr Context::eval_EXIT(Context *ctx, const TermPtr &term, Obj * args) { ObjPtr ret = nullptr; bool is_return_data = (bool)term->Right(); - if (is_return_data) { - if (isType(term->Right()->GetFullName())) { - ret = CreateRVal(ctx, term->Right(), args); + if(is_return_data) { + if(isType(term->Right()->GetFullName())) { + ret = CreateRVal(ctx, term->Right(), args, false); } else { ret = ctx->GetTypeFromString(Interrupt::Return); ret = ret->Call(ctx, Obj::Arg(CreateRVal(ctx, term->Right(), args))); @@ -1276,38 +1317,35 @@ ObjPtr Context::eval_EXIT(Context *ctx, const TermPtr &term, Obj * args) { throw Interrupt(ret); } -ObjPtr Context::CallBlock(Context *ctx, const TermPtr &block, Obj * local_vars) { - ObjPtr result = Obj::CreateNone(); - ASSERT(block); - if (!block->m_block.empty()) { - for (size_t i = 0; i < block->m_block.size(); i++) { - result = ExecStr(ctx, block->m_block[i], local_vars); - } - } else { - result = ExecStr(ctx, block, local_vars); - } - return result; -} - -ObjPtr Context::CallBlockTry(Context *ctx, const TermPtr &block, Obj * local_vars) { +ObjPtr Context::CallBlock(Context *ctx, const TermPtr &block, Obj * local_vars, bool int_catch) { ObjPtr result = Obj::CreateNone(); std::string type_return(Interrupt::Return); try { - result = CallBlock(ctx, block, local_vars); + if(!block->m_block.empty()) { + for (size_t i = 0; i < block->m_block.size(); i++) { + result = ExecStr(ctx, block->m_block[i], local_vars, false); + } + } else { + result = ExecStr(ctx, block, local_vars, false); + } } catch (Interrupt &obj) { + if(!int_catch) { + throw; + } + ASSERT(obj.m_obj); - if (!block->m_class_name.empty()) { + if(!block->m_class_name.empty()) { type_return = block->m_class_name; } - if (obj.m_obj->op_class_test(type_return.c_str(), ctx)) { - if (block->m_class_name.empty()) { + if(obj.m_obj->op_class_test(type_return.c_str(), ctx)) { + if(block->m_class_name.empty()) { // Только при возврате значения :Return ASSERT(obj.m_obj->size() == 1); return (*obj.m_obj)[0]; } - } else if (!block->m_class_name.empty()) { + } else if(!block->m_class_name.empty()) { throw; // Объект возврата не соответствует требуемому типу } result = obj.m_obj; @@ -1317,17 +1355,17 @@ ObjPtr Context::CallBlockTry(Context *ctx, const TermPtr &block, Obj * local_var ObjPtr Context::EvalBlockAND(Context *ctx, const TermPtr &block, Obj * local_vars) { ObjPtr result = nullptr; - if (block->GetTokenID() == TermID::BLOCK) { + if(block->GetTokenID() == TermID::BLOCK) { for (size_t i = 0; i < block->m_block.size(); i++) { - result = ExecStr(ctx, block->m_block[i], local_vars); - if (!result || !result->GetValueAsBoolean()) { + result = ExecStr(ctx, block->m_block[i], local_vars, false); + if(!result || !result->GetValueAsBoolean()) { return Obj::No(); } } } else { - result = ExecStr(ctx, block, local_vars); + result = ExecStr(ctx, block, local_vars, false); } - if (!result || !result->GetValueAsBoolean()) { + if(!result || !result->GetValueAsBoolean()) { return Obj::No(); } @@ -1336,17 +1374,17 @@ ObjPtr Context::EvalBlockAND(Context *ctx, const TermPtr &block, Obj * local_var ObjPtr Context::EvalBlockOR(Context *ctx, const TermPtr &block, Obj * local_vars) { ObjPtr result = nullptr; - if (block->GetTokenID() == TermID::BLOCK) { + if(block->GetTokenID() == TermID::BLOCK) { for (size_t i = 0; i < block->m_block.size(); i++) { - result = ExecStr(ctx, block->m_block[i], local_vars); - if (result && result->GetValueAsBoolean()) { + result = ExecStr(ctx, block->m_block[i], local_vars, false); + if(result && result->GetValueAsBoolean()) { return Obj::Yes(); } } } else { - result = ExecStr(ctx, block, local_vars); + result = ExecStr(ctx, block, local_vars, false); } - if (result && result->GetValueAsBoolean()) { + if(result && result->GetValueAsBoolean()) { return Obj::Yes(); } @@ -1356,16 +1394,16 @@ ObjPtr Context::EvalBlockOR(Context *ctx, const TermPtr &block, Obj * local_vars ObjPtr Context::EvalBlockXOR(Context *ctx, const TermPtr &block, Obj * local_vars) { ObjPtr result; size_t xor_counter = 0; - if (block->GetTokenID() == TermID::BLOCK) { + if(block->GetTokenID() == TermID::BLOCK) { for (size_t i = 0; i < block->m_block.size(); i++) { - result = ExecStr(ctx, block->m_block[i], local_vars); - if (result && result->GetValueAsBoolean()) { + result = ExecStr(ctx, block->m_block[i], local_vars, false); + if(result && result->GetValueAsBoolean()) { xor_counter++; } } } else { - result = ExecStr(ctx, block, local_vars); - if (result && result->GetValueAsBoolean()) { + result = ExecStr(ctx, block, local_vars, false); + if(result && result->GetValueAsBoolean()) { xor_counter++; } @@ -1400,13 +1438,13 @@ ObjPtr Context::CreateNative(TermPtr proto, const char *module, bool lazzy, cons ObjPtr result; ObjType type; - if (proto->GetTokenID() == TermID::TERM) { - if (proto->m_type_name.empty()) { + if(proto->GetTokenID() == TermID::TERM) { + if(proto->m_type_name.empty()) { LOG_RUNTIME("Cannot create native variable without specifying the type!"); } type = typeFromString(proto->m_type_name, this); - switch (type) { + switch(type) { case ObjType::Bool: // case ObjType::Byte: case ObjType::Char: @@ -1420,7 +1458,7 @@ ObjPtr Context::CreateNative(TermPtr proto, const char *module, bool lazzy, cons default: LOG_RUNTIME("Creating a variable with type '%s' is not supported!", proto->m_type_name.c_str()); } - } else if (proto->GetTokenID() == TermID::CALL) { + } else if(proto->GetTokenID() == TermID::CALL) { type = ObjType::NativeFunc; } @@ -1430,20 +1468,20 @@ ObjPtr Context::CreateNative(TermPtr proto, const char *module, bool lazzy, cons *const_cast (&result->m_func_proto) = proto; result->m_func_abi = abi; - if (mangle_name) { + if(mangle_name) { result->m_func_mangle_name = mangle_name; } - if (module) { + if(module) { result->m_module_name = module; } - if (lazzy) { + if(lazzy) { result->m_func_ptr = nullptr; } else { result->m_func_ptr = m_runtime->GetProcAddress( result->m_func_mangle_name.empty() ? proto->m_text.c_str() : result->m_func_mangle_name.c_str(), module); - if (result->is_function() || type == ObjType::Pointer) { + if(result->is_function() || type == ObjType::Pointer) { NL_CHECK(result->m_func_ptr, "Error getting address '%s' from '%s'!", proto->toString().c_str(), module); - } else if (result->m_func_ptr && result->is_tensor()) { + } else if(result->m_func_ptr && result->is_tensor()) { result->m_value = torch::from_blob(result->m_func_ptr, { }, toTorchType(type)); result->m_var_is_init = true; @@ -1456,11 +1494,11 @@ ObjPtr Context::CreateNative(TermPtr proto, const char *module, bool lazzy, cons } void *RunTime::GetProcAddress(const char *name, const char *module) { - if (module && module[0]) { - if (m_modules.find(module) == m_modules.end()) { + if(module && module[0]) { + if(m_modules.find(module) == m_modules.end()) { LoadModule(module, false, nullptr); } - if (m_modules.find(module) == m_modules.end()) { + if(m_modules.find(module) == m_modules.end()) { LOG_WARNING("Fail load module '%s'!", module); return nullptr; @@ -1472,9 +1510,9 @@ void *RunTime::GetProcAddress(const char *name, const char *module) { ObjPtr Context::FindSessionTerm(const char *name, bool current_only) { auto found = select(MakeName(name)); - while (!found.complete()) { + while(!found.complete()) { ObjPtr obj = found.data().second.lock(); - if (obj) { + if(obj) { return obj; } @@ -1497,15 +1535,15 @@ ObjPtr Context::FindSessionTerm(const char *name, bool current_only) { */ ObjPtr Context::FindTerm(const std::string name) { ObjPtr result = FindSessionTerm(name.c_str()); - if (!result && isType(name)) { + if(!result && isType(name)) { return GetTypeFromString(name); } - if (!result) { + if(!result) { return GetObject(name.c_str()); } - if (result || isLocalAny(name.c_str()) || isLocal(name)) { + if(result || isLocalAny(name.c_str()) || isLocal(name)) { return result; } @@ -1513,7 +1551,7 @@ ObjPtr Context::FindTerm(const std::string name) { } ObjPtr Context::GetTerm(const std::string name, bool is_ref) { - if (isType(name)) { + if(isType(name)) { return GetTypeFromString(name); } @@ -1523,7 +1561,7 @@ ObjPtr Context::GetTerm(const std::string name, bool is_ref) { std::string newlang::GetFileExt(const char *str) { std::string filename(str); std::string::size_type idx = filename.rfind('.'); - if (idx != std::string::npos) { + if(idx != std::string::npos) { return filename.substr(idx); } @@ -1533,7 +1571,7 @@ std::string newlang::GetFileExt(const char *str) { std::string newlang::AddDefaultFileExt(const char *str, const char *ext_default) { std::string filename(str); std::string file_ext = GetFileExt(str); - if (file_ext.empty() && !filename.empty() && filename.compare(".") != 0) { + if(file_ext.empty() && !filename.empty() && filename.compare(".") != 0) { filename.append(ext_default); } @@ -1543,11 +1581,11 @@ std::string newlang::AddDefaultFileExt(const char *str, const char *ext_default) std::string newlang::ReplaceFileExt(const char *str, const char *ext_old, const char *ext_new) { std::string filename(str); std::string file_ext = GetFileExt(str); - if (file_ext.compare(ext_old) == 0) { + if(file_ext.compare(ext_old) == 0) { filename = filename.substr(0, filename.length() - file_ext.length()); } file_ext = GetFileExt(filename.c_str()); - if (file_ext.compare(".") != 0 && file_ext.compare(ext_new) != 0 && !filename.empty() && + if(file_ext.compare(".") != 0 && file_ext.compare(ext_new) != 0 && !filename.empty() && filename.compare(".") != 0) { filename.append(ext_new); @@ -1572,9 +1610,9 @@ ObjPtr Context::CreateLVal(Context *ctx, TermPtr term, Obj * args) { auto iter = ctx->select(term->m_text); - if (!iter.complete()) { + if(!iter.complete()) { ObjPtr obj = (*iter).lock(); - if (obj) { + if(obj) { return obj; } } @@ -1591,24 +1629,24 @@ ObjPtr Context::CreateLVal(Context *ctx, TermPtr term, Obj * args) { *const_cast (&result->m_func_proto) = term; TermPtr type = term->GetType(); - if (term->IsFunction() || term->getTermID() == TermID::CALL) { + if(term->IsFunction() || term->getTermID() == TermID::CALL) { result->m_var_type_current = ObjType::FUNCTION; result->m_var_type_fixed = result->m_var_type_current; *const_cast (&result->m_func_proto) = term; - } else if (type) { + } else if(type) { result->m_var_type_current = typeFromString(type->getText().c_str(), ctx); result->m_var_type_fixed = result->m_var_type_current; - if (result->is_tensor()) { + if(result->is_tensor()) { std::vector dims; - if (type->m_dims.size()) { + if(type->m_dims.size()) { for (size_t i = 0; i < type->m_dims.size(); i++) { NL_CHECK(type->m_dims[i]->getName().empty(), "Dimension named not supported!"); ObjPtr temp = CreateRVal(ctx, type->m_dims[i]); - if (!temp) { + if(!temp) { NL_PARSER(type, "Term not found!"); } - if (!temp->is_integer()) { + if(!temp->is_integer()) { NL_PARSER(type, "Term type not integer!"); } @@ -1618,24 +1656,24 @@ ObjPtr Context::CreateLVal(Context *ctx, TermPtr term, Obj * args) { result->m_value = torch::empty(dims, toTorchType(result->m_var_type_current)); } } - if (!isType(term->m_text)) { + if(!isType(term->m_text)) { ctx->RegisterObject(result); } return result; } -ObjPtr Context::CreateRVal(Context *ctx, const char *source, Obj * local_vars) { +ObjPtr Context::CreateRVal(Context *ctx, const char *source, Obj * local_vars, bool no_catch) { TermPtr ast; Parser parser(ast); parser.Parse(source); - return CreateRVal(ctx, ast, local_vars); + return CreateRVal(ctx, ast, local_vars, no_catch); } void Context::ItemTensorEval_(torch::Tensor &tensor, c10::IntArrayRef shape, std::vector &ind, const int64_t pos, ObjPtr &obj, ObjPtr & args) { ASSERT(pos < ind.size()); - if (pos + 1 < ind.size()) { + if(pos + 1 < ind.size()) { for (ind[pos] = 0; ind[pos].integer() < shape[pos]; ind[pos] = ind[pos].integer() + 1) { ItemTensorEval_(tensor, shape, ind, pos + 1, obj, args); } @@ -1646,7 +1684,7 @@ void Context::ItemTensorEval_(torch::Tensor &tensor, c10::IntArrayRef shape, std for (ind[pos] = 0; ind[pos].integer() < shape[pos]; ind[pos] = ind[pos].integer() + 1) { - switch (type) { + switch(type) { case ObjType::Char: case ObjType::Short: case ObjType::Int: @@ -1668,7 +1706,7 @@ void Context::ItemTensorEval_(torch::Tensor &tensor, c10::IntArrayRef shape, std } void Context::ItemTensorEval(torch::Tensor &self, ObjPtr obj, ObjPtr args) { - if (self.dim() == 0) { + if(self.dim() == 0) { signed char *ptr_char = nullptr; short *ptr_short = nullptr; @@ -1677,7 +1715,7 @@ void Context::ItemTensorEval(torch::Tensor &self, ObjPtr obj, ObjPtr args) { float *ptr_float = nullptr; double *ptr_double = nullptr; - switch (fromTorchType(self.scalar_type())) { + switch(fromTorchType(self.scalar_type())) { case ObjType::Char: ptr_char = self.data_ptr(); ASSERT(ptr_char); @@ -1724,12 +1762,12 @@ std::vector GetTensorShape(Context *ctx, TermPtr type, Obj * local_vars std::vector result(type->size()); for (int i = 0; i < type->size(); i++) { ObjPtr temp = ctx->CreateRVal(ctx, type->at(i).second, local_vars); - if (temp->is_integer() || temp->is_bool_type()) { + if(temp->is_integer() || temp->is_bool_type()) { result[i] = temp->GetValueAsInteger(); } else { NL_PARSER(type->at(i).second, "Measurement dimension can be an integer only!"); } - if (result[i] <= 0) { + if(result[i] <= 0) { NL_PARSER(type->at(i).second, "Dimension size can be greater than zero!"); } @@ -1768,36 +1806,36 @@ std::vector Context::MakeIndex(Context *ctx, TermPtr term, Obj * local_va std::vector result; - if (!term->size()) { + if(!term->size()) { NL_PARSER(term, "Index not found!"); } for (int i = 0; i < term->size(); i++) { - if (!term->name(i).empty() || (term->at(i).second && term->at(i).second->IsString())) { + if(!term->name(i).empty() || (term->at(i).second && term->at(i).second->IsString())) { NL_PARSER(term, "Named index not support '%d'!", i); } - if (!term->at(i).second) { + if(!term->at(i).second) { NL_PARSER(term, "Empty index '%d'!", i); } - if (term->at(i).second->getTermID() == TermID::ELLIPSIS) { + if(term->at(i).second->getTermID() == TermID::ELLIPSIS) { result.push_back(Index("...")); } else { ObjPtr temp = ctx->CreateRVal(ctx, term->at(i).second, local_vars); - if (temp->is_none_type()) { + if(temp->is_none_type()) { result.push_back(Index(at::indexing::None)); - } else if (temp->is_integer() || temp->is_bool_type()) { + } else if(temp->is_integer() || temp->is_bool_type()) { - if (temp->is_scalar()) { + if(temp->is_scalar()) { result.push_back(Index(temp->GetValueAsInteger())); - } else if (temp->m_value.dim() == 1) { + } else if(temp->m_value.dim() == 1) { result.push_back(Index(temp->m_value)); } else { NL_PARSER(term->at(i).second, "Extra dimensions index not support '%d'!", i); } - } else if (temp->is_range()) { + } else if(temp->is_range()) { int64_t start = temp->at("start")->GetValueAsInteger(); int64_t stop = temp->at("stop")->GetValueAsInteger(); @@ -1813,9 +1851,9 @@ std::vector Context::MakeIndex(Context *ctx, TermPtr term, Obj * local_va return result; } -ObjPtr Context::CreateRVal(Context *ctx, TermPtr term, Obj * local_vars) { +ObjPtr Context::CreateRVal(Context *ctx, TermPtr term, Obj * local_vars, bool int_catch) { - if (!term) { + if(!term) { ASSERT(term); } ASSERT(local_vars); @@ -1838,13 +1876,13 @@ ObjPtr Context::CreateRVal(Context *ctx, TermPtr term, Obj * local_vars) { bool has_error; std::vector sizes; at::Scalar torch_scalar; - switch (term->getTermID()) { + switch(term->getTermID()) { case TermID::INTEGER: val_int = parseInteger(term->getText().c_str()); NL_TYPECHECK(term, newlang::toString(typeFromLimit(val_int)), term->m_type_name); // Соответстствует ли тип значению? result->m_var_type_current = typeFromLimit(val_int); - if (term->GetType()) { + if(term->GetType()) { result->m_var_type_fixed = typeFromString(term->m_type_name, ctx); result->m_var_type_current = result->m_var_type_fixed; } @@ -1856,7 +1894,7 @@ ObjPtr Context::CreateRVal(Context *ctx, TermPtr term, Obj * local_vars) { NL_TYPECHECK(term, newlang::toString(typeFromLimit(val_dbl)), term->m_type_name); // Соответстствует ли тип значению? result->m_var_type_current = typeFromLimit(val_dbl); - if (term->GetType()) { + if(term->GetType()) { result->m_var_type_fixed = typeFromString(term->m_type_name, ctx); result->m_var_type_current = result->m_var_type_fixed; } @@ -1898,7 +1936,7 @@ ObjPtr Context::CreateRVal(Context *ctx, TermPtr term, Obj * local_vars) { return result; case TermID::TERM: - if (term->GetType()) { + if(term->GetType()) { result->m_var_type_current = typeFromString(term->GetType()->m_text, ctx); result->m_var_type_fixed = result->m_var_type_current; @@ -1907,21 +1945,21 @@ ObjPtr Context::CreateRVal(Context *ctx, TermPtr term, Obj * local_vars) { // Check BuildInType has_error = false; typeFromString(term->GetType()->m_text, nullptr, &has_error); - if (has_error) { + if(has_error) { result->m_class_name = term->GetType()->m_text; } return result; } - if (term->m_text.compare("_") == 0) { + if(term->m_text.compare("_") == 0) { result->m_var_type_current = ObjType::None; return result; - } else if (term->m_text.compare("$") == 0) { + } else if(term->m_text.compare("$") == 0) { result->m_var_type_current = ObjType::Dictionary; result->m_var_name = "$"; size_t pos = 0; - while (ctx && pos < ctx->size()) { - if (ctx->at(pos).second.lock()) { + while(ctx && pos < ctx->size()) { + if(ctx->at(pos).second.lock()) { result->push_back(Obj::CreateString(ctx->at(pos).first)); // result->push_back(Obj::Arg(ctx->at(pos).first)); pos++; @@ -1931,11 +1969,11 @@ ObjPtr Context::CreateRVal(Context *ctx, TermPtr term, Obj * local_vars) { } result->m_var_is_init = true; return result; - } else if (term->m_text.compare("@") == 0) { - } else if (term->m_text.compare("%") == 0) { + } else if(term->m_text.compare("@") == 0) { + } else if(term->m_text.compare("%") == 0) { } - if (isLocal(term->m_text.c_str())) { + if(isLocal(term->m_text.c_str())) { full_name = MakeName(term->m_text); return local_vars->at(full_name); } else { @@ -1943,31 +1981,31 @@ ObjPtr Context::CreateRVal(Context *ctx, TermPtr term, Obj * local_vars) { // Типы данных обрабатываются тут, а не в вызовах функций (TermID::CALL) - if (term->size()) { + if(term->size()) { Obj args(ctx, term, true, local_vars); result = result->Call(ctx, &args); } } - if (!result) { + if(!result) { // Делать ислкючение или возвращать объект "ошибка" ????? LOG_RUNTIME("Term '%s' not found!", term->GetFullName().c_str()); } field = term->m_right; - if (field && field->getTermID() == TermID::FIELD) { - while (field) { + if(field && field->getTermID() == TermID::FIELD) { + while(field) { result = result->at(field->getText()); field = field->m_right; ASSERT(!field); // Нужно выполнять, а не просто получать значение поля } - } else if (field && field->getTermID() == TermID::INDEX) { - while (field) { + } else if(field && field->getTermID() == TermID::INDEX) { + while(field) { result = result->index_get(MakeIndex(ctx, field, local_vars)); field = field->m_right; ASSERT(!field); // Нужно выполнять, а не просто получать значение поля } - } else if (field) { + } else if(field) { LOG_RUNTIME("Not implemented! %s", field->toString().c_str()); } @@ -1981,7 +2019,7 @@ ObjPtr Context::CreateRVal(Context *ctx, TermPtr term, Obj * local_vars) { has_error = false; type = typeFromString(term->GetFullName(), ctx, &has_error); - if (has_error) { + if(has_error) { LOG_RUNTIME("Type name '%s' undefined!", term->GetFullName().c_str()); } ASSERT(result); @@ -1997,7 +2035,7 @@ ObjPtr Context::CreateRVal(Context *ctx, TermPtr term, Obj * local_vars) { for (size_t i = 0; i < term->size(); i++) { - if ((*term)[i]->GetTokenID() == TermID::FILLING) { + if((*term)[i]->GetTokenID() == TermID::FILLING) { // Заполнение значений вызовом функции // :Type(1, 2, 3, ... rand() ... ); @@ -2009,34 +2047,34 @@ ObjPtr Context::CreateRVal(Context *ctx, TermPtr term, Obj * local_vars) { ObjPtr expr = ctx->FindTerm((*term)[i]->Right()->GetFullName()); - if ((*term)[i]->Right()->getTermID() != TermID::CALL) { + if((*term)[i]->Right()->getTermID() != TermID::CALL) { LOG_RUNTIME("Operator filling supported function call only!"); } - if (i + 1 != term->size()) { + if(i + 1 != term->size()) { LOG_RUNTIME("Function filling is supported for the last argument only!"); } - if (!result->m_dimensions || !result->m_dimensions->size()) { + if(!result->m_dimensions || !result->m_dimensions->size()) { LOG_RUNTIME("Object has no dimensions!"); } int64_t full_size = 1; for (int dim_index = 0; dim_index < result->m_dimensions->size(); dim_index++) { - if (!(*result->m_dimensions)[dim_index]->is_integer()) { + if(!(*result->m_dimensions)[dim_index]->is_integer()) { LOG_RUNTIME("Dimension index for function filling support integer value only!"); } full_size *= (*result->m_dimensions)[dim_index]->GetValueAsInteger(); } - if (full_size <= 0) { + if(full_size <= 0) { LOG_RUNTIME("Items count error for all dimensions!"); } - if (expr->size()) { + if(expr->size()) { LOG_RUNTIME("Argument in function for filling not implemented!"); } @@ -2046,24 +2084,24 @@ ObjPtr Context::CreateRVal(Context *ctx, TermPtr term, Obj * local_vars) { break; - } else if ((*term)[i]->GetTokenID() == TermID::ELLIPSIS) { + } else if((*term)[i]->GetTokenID() == TermID::ELLIPSIS) { - if (!term->name(i).empty()) { + if(!term->name(i).empty()) { LOG_RUNTIME("Named ellipsys not implemented!"); } - if ((*term)[i]->Right()) { + if((*term)[i]->Right()) { bool named = ((*term)[i]->Left() && (*term)[i]->Left()->getTermID() == TermID::ELLIPSIS); ObjPtr exp = CreateRVal(ctx, (*term)[i]->Right()); - if (!exp->is_dictionary_type()) { + if(!exp->is_dictionary_type()) { LOG_RUNTIME("Expansion operator applies to dictionary only!"); } for (int index = 0; index < exp->size(); index++) { - if (named) { + if(named) { args->push_back((*exp)[index], exp->name(index).empty() ? "" : exp->name(index)); } else { args->push_back((*exp)[index]); @@ -2074,7 +2112,7 @@ ObjPtr Context::CreateRVal(Context *ctx, TermPtr term, Obj * local_vars) { } } - if (term->name(i).empty()) { + if(term->name(i).empty()) { args->push_back(CreateRVal(ctx, (*term)[i], local_vars)); } else { args->push_back(CreateRVal(ctx, (*term)[i], local_vars), term->name(i).c_str()); @@ -2094,20 +2132,20 @@ ObjPtr Context::CreateRVal(Context *ctx, TermPtr term, Obj * local_vars) { temp = ctx->GetTerm(term->GetFullName().c_str(), term->isRef()); - if (!temp) { + if(!temp) { ASSERT(temp); } args = Obj::CreateDict(); for (size_t i = 0; i < term->size(); i++) { - if (term->name(i).empty()) { + if(term->name(i).empty()) { args->push_back(CreateRVal(ctx, (*term)[i], local_vars)); } else { args->push_back(CreateRVal(ctx, (*term)[i], local_vars), term->name(i).c_str()); } } - if (term->getTermID() == TermID::EXIT) { + if(term->getTermID() == TermID::EXIT) { return result; } @@ -2119,19 +2157,19 @@ ObjPtr Context::CreateRVal(Context *ctx, TermPtr term, Obj * local_vars) { case TermID::DICT: result->m_var_type_current = ObjType::Dictionary; for (size_t i = 0; i < term->size(); i++) { - if (term->name(i).empty()) { + if(term->name(i).empty()) { result->push_back(CreateRVal(ctx, (*term)[i], local_vars)); } else { result->push_back(CreateRVal(ctx, (*term)[i], local_vars), term->name(i).c_str()); } } result->m_var_is_init = true; - if (term->getTermID() == TermID::TENSOR) { + if(term->getTermID() == TermID::TENSOR) { result->m_var_type_fixed = typeFromString(term->m_type_name, ctx); type = getSummaryTensorType(result, result->m_var_type_fixed); - if (type != ObjType::None) { + if(type != ObjType::None) { result->m_value = ConvertToTensor(result.get(), toTorchType(type)); } else { result->m_var_is_init = false; @@ -2146,16 +2184,16 @@ ObjPtr Context::CreateRVal(Context *ctx, TermPtr term, Obj * local_vars) { case TermID::ARGUMENT: val_int = IndexArg(term); - if (val_int < local_vars->size()) { + if(val_int < local_vars->size()) { return local_vars->at(val_int).second; } LOG_RUNTIME("Argument '%s' not exist!", term->toString().c_str()); case TermID::BLOCK: - return CallBlock(ctx, term, local_vars); + return CallBlock(ctx, term, local_vars, false); case TermID::BLOCK_TRY: - return CallBlockTry(ctx, term, local_vars); + return CallBlock(ctx, term, local_vars, int_catch); case TermID::ELLIPSIS: result->m_var_type_current = ObjType::Ellipsis; @@ -2170,7 +2208,7 @@ ObjPtr Context::CreateRVal(Context *ctx, TermPtr term, Obj * local_vars) { result->push_back(CreateRVal(ctx, (*term)[i], local_vars), term->name(i).c_str()); } - if (result->size() == 2) { + if(result->size() == 2) { result->push_back(Obj::CreateValue(1, ObjType::None), "step"); } diff --git a/core/context.h b/core/context.h index 400984bf..37dcd6aa 100644 --- a/core/context.h +++ b/core/context.h @@ -10,39 +10,39 @@ namespace newlang { -std::string GetFileExt(const char * str); -std::string AddDefaultFileExt(const char * str, const char *ext_default); -std::string ReplaceFileExt(const char * str, const char *ext_old, const char *ext_new); -std::string ReadFile(const char *fileName); + std::string GetFileExt(const char * str); + std::string AddDefaultFileExt(const char * str, const char *ext_default); + std::string ReplaceFileExt(const char * str, const char *ext_old, const char *ext_new); + std::string ReadFile(const char *fileName); -bool Tranliterate(const wchar_t c, std::wstring &str); -std::string MangleName(const char * name); + bool Tranliterate(const wchar_t c, std::wstring &str); + std::string MangleName(const char * name); -std::string MangaledFuncCPP(const char *name, const char *space = nullptr); -std::string MangaledFunc(const std::string name); + std::string MangaledFuncCPP(const char *name, const char *space = nullptr); + std::string MangaledFunc(const std::string name); -inline std::string MakeName(std::string name) { - if (!name.empty() && (name[0] == '$' || name[0] == '@' || name[0] == '%')) { - return name.substr(1); + inline std::string MakeName(std::string name) { + if (!name.empty() && (name[0] == '$' || name[0] == '@' || name[0] == '%')) { + return name.substr(1); + } + return name; } - return name; -} -inline std::string MakeLocalName(std::string name) { - return MangleName(MakeName(name).c_str()); -} + inline std::string MakeLocalName(std::string name) { + return MangleName(MakeName(name).c_str()); + } -/* - * Класс контекст предназначен для хранения контекста среды выполнения при вызове функций. - * С его помощью передаются переменные среды окружения, параметры и аргументы приложения, входные и выходные параметры функций, - * текущие локальные и глобальные переменныеи, создание и доступ к итераторам и т.д. - * - * - * - */ -class ContextCursor; + /* + * Класс контекст предназначен для хранения контекста среды выполнения при вызове функций. + * С его помощью передаются переменные среды окружения, параметры и аргументы приложения, входные и выходные параметры функций, + * текущие локальные и глобальные переменныеи, создание и доступ к итераторам и т.д. + * + * + * + */ + class ContextCursor; -typedef std::map ProtoType; + typedef std::map ProtoType; #define NL_OPS(_) \ @@ -103,414 +103,410 @@ typedef std::map ProtoType; _("export", NOT_SUPPORT)\ _("local", NOT_SUPPORT) -class Context : public Variable< std::weak_ptr > { -public: + class Context : public Variable< std::weak_ptr > { + public: - static ObjPtr eval_END(Context *ctx, const TermPtr & term, Obj *args); - static ObjPtr func_NOT_SUPPORT(Context *ctx, const TermPtr & term, Obj *args); + static ObjPtr eval_END(Context *ctx, const TermPtr & term, Obj *args); + static ObjPtr func_NOT_SUPPORT(Context *ctx, const TermPtr & term, Obj *args); - enum class CreateMode { - CREATE_ONLY, - CREATE_OR_ASSIGN, - ASSIGN_ONLY, - }; - static ObjPtr CREATE_OR_ASSIGN(Context *ctx, const TermPtr & term, Obj *args, CreateMode mode); + enum class CreateMode { + CREATE_ONLY, + CREATE_OR_ASSIGN, + ASSIGN_ONLY, + }; + static ObjPtr CREATE_OR_ASSIGN(Context *ctx, const TermPtr & term, Obj *args, CreateMode mode); #define DEFINE_CASE(name) \ static ObjPtr eval_ ## name(Context *ctx, const TermPtr &term, Obj *args); - NL_TERMS(DEFINE_CASE); + NL_TERMS(DEFINE_CASE); #undef DEFINE_CASE #define PROTO_OP(_, func) \ static ObjPtr op_ ## func(Context *ctx, const TermPtr &term, Obj *args); - NL_OPS(PROTO_OP); + NL_OPS(PROTO_OP); #undef PROTO_OP - typedef ObjPtr(*EvalFunction)(Context *ctx, const TermPtr & term, Obj *args); - - static std::map m_ops; - static std::map m_builtin_calls; - static Parser::MacrosStore m_macros; ///< Хотя макросы и могут обработываться в рантайме, но доступны они только для парсера + typedef ObjPtr(*EvalFunction)(Context *ctx, const TermPtr & term, Obj *args); - static void Reset() { - m_types.clear(); - m_funcs.clear(); - m_macros.clear(); - m_ops.clear(); - m_builtin_calls.clear(); - } + static std::map m_ops; + static std::map m_builtin_calls; + static Parser::MacrosStore m_macros; ///< Хотя макросы и могут обработываться в рантайме, но доступны они только для парсера - inline ObjPtr ExecFile(const std::string &filename) { - std::string source = ReadFile(filename.c_str()); - if (source.empty()) { - LOG_RUNTIME("Empty source or file '%s' not found!", filename.c_str()); + static void Reset() { + m_types.clear(); + m_funcs.clear(); + m_macros.clear(); + m_ops.clear(); + m_builtin_calls.clear(); } - return ExecStr(source); - } - inline ObjPtr ExecStr(const std::string &source) { - TermPtr exec = Parser::ParseString(source, &m_macros); - if (exec->m_id == TermID::BLOCK) { - exec->m_id = TermID::CALL_BLOCK; - } else if (exec->m_id == TermID::BLOCK_TRY) { - exec->m_id = TermID::CALL_TRY; + inline ObjPtr ExecFile(const std::string &filename, Obj *args = nullptr, bool int_catch = true) { + std::string source = ReadFile(filename.c_str()); + if (source.empty()) { + LOG_RUNTIME("Empty source or file '%s' not found!", filename.c_str()); + } + return ExecStr(source, args, int_catch); } - return ExecStr(this, exec); - } - inline ObjPtr ExecStr(const std::string_view str, Obj *args) { - return ExecStr(this, Parser::ParseString(str, &m_macros), args); - } + inline ObjPtr ExecStr(const std::string_view str, Obj *args = nullptr, bool int_catch = false) { + TermPtr exec = Parser::ParseString(str, &m_macros); + if (exec->m_id == TermID::BLOCK) { + exec->m_id = TermID::CALL_BLOCK; + } else if (exec->m_id == TermID::BLOCK_TRY) { + exec->m_id = TermID::CALL_TRY; + } + ObjPtr temp; + if (args == nullptr) { + temp = Obj::CreateNone(); + args = temp.get(); + } + return ExecStr(this, exec, args, int_catch); + } - inline static ObjPtr ExecStr(Context *ctx, TermPtr term) { - Obj args; - return ExecStr(ctx, term, &args); - } - static ObjPtr ExecStr(Context *ctx, TermPtr term, Obj *args); + static ObjPtr ExecStr(Context *ctx, TermPtr term, Obj *args, bool int_catch = false); - static ObjPtr ExpandAssign(Context *ctx, TermPtr lvar, TermPtr rval, Obj *args, CreateMode mode); - static ObjPtr ExpandCreate(Context *ctx, TermPtr lvar, TermPtr rval, Obj *args); + static ObjPtr ExpandAssign(Context *ctx, TermPtr lvar, TermPtr rval, Obj *args, CreateMode mode); + static ObjPtr ExpandCreate(Context *ctx, TermPtr lvar, TermPtr rval, Obj *args); - Context(RuntimePtr global); + Context(RuntimePtr global); - static std::map m_types; - typedef std::variant> FuncItem; - static std::map m_funcs; // Системный и встроенные функции + static std::map m_types; + typedef std::variant> FuncItem; + static std::map m_funcs; // Системный и встроенные функции - inline static ObjPtr CreateLVal(Context *ctx, TermPtr type) { - Obj args; - return CreateLVal(ctx, type, &args); - } + inline static ObjPtr CreateLVal(Context *ctx, TermPtr type) { + Obj args; + return CreateLVal(ctx, type, &args); + } - inline static ObjPtr CreateRVal(Context *ctx, TermPtr term) { - Obj args; - return CreateRVal(ctx, term, &args); - } + inline static ObjPtr CreateRVal(Context *ctx, TermPtr term, bool int_catch = true) { + Obj args; + return CreateRVal(ctx, term, &args, int_catch); + } - inline static ObjPtr CreateRVal(Context *ctx, const char *source) { - Obj args; - return CreateRVal(ctx, source, &args); - } + inline static ObjPtr CreateRVal(Context *ctx, const char *source, bool int_catch = true) { + Obj args; + return CreateRVal(ctx, source, &args, int_catch); + } - static ObjPtr CreateLVal(Context *ctx, TermPtr type, Obj *args); - static ObjPtr CreateRVal(Context *ctx, TermPtr term, Obj *args); - static ObjPtr CreateRVal(Context *ctx, const char *source, Obj *args); + static ObjPtr CreateLVal(Context *ctx, TermPtr type, Obj *args); + static ObjPtr CreateRVal(Context *ctx, TermPtr term, Obj *args, bool int_catch = true); + static ObjPtr CreateRVal(Context *ctx, const char *source, Obj *args, bool int_catch = true); - static std::vector MakeIndex(Context *ctx, TermPtr term, Obj *local_vars); + static std::vector MakeIndex(Context *ctx, TermPtr term, Obj *local_vars); - void ItemTensorEval_(torch::Tensor &tensor, c10::IntArrayRef shape, std::vector &ind, const int64_t pos, ObjPtr & obj, ObjPtr &args); - void ItemTensorEval(torch::Tensor &tensor, ObjPtr obj, ObjPtr args); + void ItemTensorEval_(torch::Tensor &tensor, c10::IntArrayRef shape, std::vector &ind, const int64_t pos, ObjPtr & obj, ObjPtr &args); + void ItemTensorEval(torch::Tensor &tensor, ObjPtr obj, ObjPtr args); - void ReadBuiltInProto(ProtoType & proto); + void ReadBuiltInProto(ProtoType & proto); - bool CreateBuiltin(const char * prototype, void * func, ObjType type); - ObjPtr RegisterObject(ObjPtr var); + bool CreateBuiltin(const char * prototype, void * func, ObjType type); + ObjPtr RegisterObject(ObjPtr var); - ObjPtr RemoveObject(const char * name) { - std::string str(name); - if (str.size() && (str[0] == '$' || str[0] == '@')) { - str = str.substr(1); - } - auto found = select(name); - if (!found.complete()) { - erase(found); - return Obj::Yes(); + ObjPtr RemoveObject(const char * name) { + std::string str(name); + if (str.size() && (str[0] == '$' || str[0] == '@')) { + str = str.substr(1); + } + auto found = select(name); + if (!found.complete()) { + erase(found); + return Obj::Yes(); + } + return Obj::No(); } - return Obj::No(); - } - ObjPtr GetObject(const std::string name) { - std::string str(name); - if (str.size() && (str[0] == '$' || str[0] == '@')) { - str = str.substr(1); - } - auto found = select(str); - if (!found.complete()) { - return (*found).lock(); - } - auto func = m_funcs.find(str); - if (func != m_funcs.end()) { - if (std::holds_alternative(func->second)) { - return std::get(func->second); + ObjPtr GetObject(const std::string name) { + std::string str(name); + if (str.size() && (str[0] == '$' || str[0] == '@')) { + str = str.substr(1); } - ASSERT(std::holds_alternative> (func->second)); - return std::get> (func->second)[0]; + auto found = select(str); + if (!found.complete()) { + return (*found).lock(); + } + auto func = m_funcs.find(str); + if (func != m_funcs.end()) { + if (std::holds_alternative(func->second)) { + return std::get(func->second); + } + ASSERT(std::holds_alternative> (func->second)); + return std::get> (func->second)[0]; + } + return nullptr; } - return nullptr; - } - RuntimePtr m_runtime; // Глобальный контекс, если к нему есть доступ - Variable m_global_terms; + RuntimePtr m_runtime; // Глобальный контекс, если к нему есть доступ + Variable m_global_terms; - virtual ~Context() { - } + virtual ~Context() { + } - ObjPtr GetTerm(const std::string name, bool is_ref); - ObjPtr FindTerm(const std::string name); - ObjPtr FindSessionTerm(const char *name, bool current_only = false); + ObjPtr GetTerm(const std::string name, bool is_ref); + ObjPtr FindTerm(const std::string name); + ObjPtr FindSessionTerm(const char *name, bool current_only = false); - ObjPtr CreateSessionTerm(ObjPtr obj, const char *name); + ObjPtr CreateSessionTerm(ObjPtr obj, const char *name); - ObjPtr FindGlobalTerm(TermPtr term); + ObjPtr FindGlobalTerm(TermPtr term); - ObjPtr FindGlobalTerm(const std::string name) { - auto found = m_global_terms.select(MakeName(name)); - if (!found.complete()) { + ObjPtr FindGlobalTerm(const std::string name) { + auto found = m_global_terms.select(MakeName(name)); + if (!found.complete()) { - return *found; + return *found; + } + return GetObject(name); } - return GetObject(name); - } - void RegisterInContext(ObjPtr &args) { - RegisterInContext(*args); - } + void RegisterInContext(ObjPtr &args) { + RegisterInContext(*args); + } - void RegisterInContext(Obj &args) { - for (int i = static_cast (args.size()) - 1; args.size() && i >= 0; i--) { - push_front(args.at(i).second, args.at(i).first); + void RegisterInContext(Obj &args) { + for (int i = static_cast (args.size()) - 1; args.size() && i >= 0; i--) { + push_front(args.at(i).second, args.at(i).first); + } } - } - void UnRegisterInContext(Obj &args) { - for (int i = static_cast (args.size()) - 1; args.size() && i >= 0; i--) { - pop_front(); + void UnRegisterInContext(Obj &args) { + for (int i = static_cast (args.size()) - 1; args.size() && i >= 0; i--) { + pop_front(); + } } - } - static ObjPtr CallBlock(Context *ctx, const TermPtr &block, Obj *local_vars); - static ObjPtr CallBlockTry(Context *ctx, const TermPtr &block, Obj *local_vars); + static ObjPtr CallBlock(Context *ctx, const TermPtr &block, Obj *local_vars, bool int_catch); - static ObjPtr EvalBlockAND(Context *ctx, const TermPtr &block, Obj *local_vars); - static ObjPtr EvalBlockOR(Context *ctx, const TermPtr &block, Obj *local_vars); - static ObjPtr EvalBlockXOR(Context *ctx, const TermPtr &block, Obj *local_vars); + static ObjPtr EvalBlockAND(Context *ctx, const TermPtr &block, Obj *local_vars); + static ObjPtr EvalBlockOR(Context *ctx, const TermPtr &block, Obj *local_vars); + static ObjPtr EvalBlockXOR(Context *ctx, const TermPtr &block, Obj *local_vars); - ObjPtr CreateNative(const char *proto, const char *module = nullptr, bool lazzy = false, const char *mangle_name = nullptr, ffi_abi abi = FFI_DEFAULT_ABI); - ObjPtr CreateNative(TermPtr proto, const char *module = nullptr, bool lazzy = false, const char *mangle_name = nullptr, ffi_abi abi = FFI_DEFAULT_ABI); - ObjPtr CreateNative(Obj args); + ObjPtr CreateNative(const char *proto, const char *module = nullptr, bool lazzy = false, const char *mangle_name = nullptr, ffi_abi abi = FFI_DEFAULT_ABI); + ObjPtr CreateNative(TermPtr proto, const char *module = nullptr, bool lazzy = false, const char *mangle_name = nullptr, ffi_abi abi = FFI_DEFAULT_ABI); + ObjPtr CreateNative(Obj args); - static bool pred_compare(const std::string_view find, const std::string_view str) { - size_t pos = 0; - while (pos < find.size() && pos < str.size()) { - if (find[pos] != str[pos]) { - return false; + static bool pred_compare(const std::string_view find, const std::string_view str) { + size_t pos = 0; + while (pos < find.size() && pos < str.size()) { + if (find[pos] != str[pos]) { + return false; + } + pos++; } - pos++; + return find.empty() || (pos && find.size() == pos); } - return find.empty() || (pos && find.size() == pos); - } - std::vector SelectPredict(std::wstring_view wstart, size_t overage_count = 0) { - return SelectPredict(utf8_encode(wstart), overage_count); - } - - std::vector SelectPredict(std::string_view start, size_t overage_count = 0) { - - std::vector result; - - bool find_local = false; - bool find_global = false; - bool find_types = false; - - std::string prefix; - - if (isGlobal(start)) { - prefix = start[0]; - start.remove_prefix(1); - find_global = true; - } else if (isLocal(start)) { - prefix = start[0]; - start.remove_prefix(1); - find_local = true; - } else if (isType(start)) { - // prefix = start[0]; - // start.remove_prefix(1); - find_types = true; - } else { - find_local = true; - find_global = true; - find_types = true; + std::vector SelectPredict(std::wstring_view wstart, size_t overage_count = 0) { + return SelectPredict(utf8_encode(wstart), overage_count); } + std::vector SelectPredict(std::string_view start, size_t overage_count = 0) { + + std::vector result; + + bool find_local = false; + bool find_global = false; + bool find_types = false; + + std::string prefix; + + if (isGlobal(start)) { + prefix = start[0]; + start.remove_prefix(1); + find_global = true; + } else if (isLocal(start)) { + prefix = start[0]; + start.remove_prefix(1); + find_local = true; + } else if (isType(start)) { + // prefix = start[0]; + // start.remove_prefix(1); + find_types = true; + } else { + find_local = true; + find_global = true; + find_types = true; + } + - if (find_local) { - for (int i = 0; i < size(); i++) { - if (pred_compare(start, at(i).first)) { - ObjPtr object = at(i).second.lock(); - if (object && object->is_function()) { - result.push_back(utf8_decode(prefix + at(i).first) + L"("); - } else if (object) { - result.push_back(utf8_decode(prefix + at(i).first)); - } - if (result.size() > overage_count + 1) { - break; + if (find_local) { + for (int i = 0; i < size(); i++) { + if (pred_compare(start, at(i).first)) { + ObjPtr object = at(i).second.lock(); + if (object && object->is_function()) { + result.push_back(utf8_decode(prefix + at(i).first) + L"("); + } else if (object) { + result.push_back(utf8_decode(prefix + at(i).first)); + } + if (result.size() > overage_count + 1) { + break; + } } } } - } - if (find_global) { - for (int i = 0; i < m_global_terms.size(); i++) { - if (pred_compare(start, m_global_terms.at(i).first)) { - if (m_global_terms.at(i).second->is_function()) { - result.push_back(utf8_decode(prefix + m_global_terms.at(i).first) + L"("); - } else { - result.push_back(utf8_decode(prefix + m_global_terms.at(i).first)); - } - if (result.size() > overage_count + 1) { - break; + if (find_global) { + for (int i = 0; i < m_global_terms.size(); i++) { + if (pred_compare(start, m_global_terms.at(i).first)) { + if (m_global_terms.at(i).second->is_function()) { + result.push_back(utf8_decode(prefix + m_global_terms.at(i).first) + L"("); + } else { + result.push_back(utf8_decode(prefix + m_global_terms.at(i).first)); + } + if (result.size() > overage_count + 1) { + break; + } } } - } - for (auto &elem : m_funcs) { + for (auto &elem : m_funcs) { - if (pred_compare(start, elem.first)) { - result.push_back(utf8_decode(prefix + elem.first) + L"("); - if (result.size() > overage_count + 1) { - break; + if (pred_compare(start, elem.first)) { + result.push_back(utf8_decode(prefix + elem.first) + L"("); + if (result.size() > overage_count + 1) { + break; + } } } } - } - if (find_types) { - for (auto &elem : m_types) { - if (pred_compare(start, elem.first)) { - result.push_back(utf8_decode(elem.first)); - if (result.size() > overage_count + 1) { - break; + if (find_types) { + for (auto &elem : m_types) { + if (pred_compare(start, elem.first)) { + result.push_back(utf8_decode(elem.first)); + if (result.size() > overage_count + 1) { + break; + } } } } - } - return result; + return result; - } - - inline ObjPtr ConvertType(const ObjType type, const Dimension *dims, ObjPtr obj, const ObjPtr obj2 = nullptr) { - ObjPtr result = obj->Clone(); - ConvertType_(type, dims, result, obj2); - return result; - } - void ConvertType_(const ObjType type, const Dimension *dims, ObjPtr obj, const ObjPtr obj2 = nullptr); + } - ObjPtr CreateConvertTypeFunc(const char *prototype, void *func, ObjType type) { - ASSERT(prototype); - ASSERT(func); + inline ObjPtr ConvertType(const ObjType type, const Dimension *dims, ObjPtr obj, const ObjPtr obj2 = nullptr) { + ObjPtr result = obj->Clone(); + ConvertType_(type, dims, result, obj2); + return result; + } + void ConvertType_(const ObjType type, const Dimension *dims, ObjPtr obj, const ObjPtr obj2 = nullptr); - std::string func_dump(prototype); - func_dump += " := {};"; + ObjPtr CreateConvertTypeFunc(const char *prototype, void *func, ObjType type) { + ASSERT(prototype); + ASSERT(func); - TermPtr proto = Parser::ParseString(func_dump, &m_macros); - ObjPtr obj = - Obj::CreateFunc(this, proto->Left(), type, - proto->Left()->getName().empty() ? proto->Left()->getText() : proto->Left()->getName()); - obj->m_func_ptr = func; + std::string func_dump(prototype); + func_dump += " := {};"; - return obj; - } - - /** - * Функция для организации встроенных типов в иерархию наследования. - * Другие функции: CreateBaseType - создает базовые типы данных (для расширения классов требуется контекст) - * и BaseTypeConstructor - функция обратного вызова при создании нового объекта базового типа данных - * @param type - Базовый тип данных \ref ObjType - * @param parents - Список сторок с именами родительских типов - * @return - Успешность регистрации базовго типа в иерархии - */ - bool RegisterTypeHierarchy(ObjType type, std::vector parents) { - // std::array < std::string, sizeof...(parents) > list = {parents...}; + TermPtr proto = Parser::ParseString(func_dump, &m_macros); + ObjPtr obj = + Obj::CreateFunc(this, proto->Left(), type, + proto->Left()->getName().empty() ? proto->Left()->getText() : proto->Left()->getName()); + obj->m_func_ptr = func; - std::string type_name(toString(type)); - auto base = m_types.find(type_name); - if (base != m_types.end()) { - return false; + return obj; } - ObjPtr result = Obj::CreateBaseType(type); - ASSERT(result->m_var_type_fixed == type); - ASSERT(result->m_var_type_current == ObjType::Type); - ASSERT(!type_name.empty() && result->m_class_name.compare(type_name) == 0); - ASSERT(result->m_class_parents.empty()); - - for (auto &parent : parents) { - auto iter = m_types.find(parent); - if (iter == m_types.end()) { - LOG_DEBUG("Parent type '%s' not found!", parent.c_str()); + /** + * Функция для организации встроенных типов в иерархию наследования. + * Другие функции: CreateBaseType - создает базовые типы данных (для расширения классов требуется контекст) + * и BaseTypeConstructor - функция обратного вызова при создании нового объекта базового типа данных + * @param type - Базовый тип данных \ref ObjType + * @param parents - Список сторок с именами родительских типов + * @return - Успешность регистрации базовго типа в иерархии + */ + bool RegisterTypeHierarchy(ObjType type, std::vector parents) { + // std::array < std::string, sizeof...(parents) > list = {parents...}; + + std::string type_name(toString(type)); + auto base = m_types.find(type_name); + if (base != m_types.end()) { return false; } - for (auto &elem : result->m_class_parents) { - ASSERT(elem); - if (!elem->m_class_name.empty() && elem->m_class_name.compare(parent) == 0) { - LOG_DEBUG("The type '%s' already exists in the parents of '%s'!", parent.c_str(), type_name.c_str()); + + ObjPtr result = Obj::CreateBaseType(type); + ASSERT(result->m_var_type_fixed == type); + ASSERT(result->m_var_type_current == ObjType::Type); + ASSERT(!type_name.empty() && result->m_class_name.compare(type_name) == 0); + ASSERT(result->m_class_parents.empty()); + + for (auto &parent : parents) { + auto iter = m_types.find(parent); + if (iter == m_types.end()) { + LOG_DEBUG("Parent type '%s' not found!", parent.c_str()); return false; } + for (auto &elem : result->m_class_parents) { + ASSERT(elem); + if (!elem->m_class_name.empty() && elem->m_class_name.compare(parent) == 0) { + LOG_DEBUG("The type '%s' already exists in the parents of '%s'!", parent.c_str(), type_name.c_str()); + return false; + } + } + ASSERT(iter->first.compare(parent) == 0); + result->m_class_parents.push_back(iter->second); } - ASSERT(iter->first.compare(parent) == 0); - result->m_class_parents.push_back(iter->second); + m_types[type_name] = result; + return true; } - m_types[type_name] = result; - return true; - } - ObjType BaseTypeFromString(const std::string & type, bool *has_error = nullptr) { - ObjPtr obj_type = GetTypeFromString(type, has_error); + ObjType BaseTypeFromString(const std::string & type, bool *has_error = nullptr) { + ObjPtr obj_type = GetTypeFromString(type, has_error); - if (obj_type == nullptr) { - if (has_error) { - *has_error = true; - return ObjType::None; + if (obj_type == nullptr) { + if (has_error) { + *has_error = true; + return ObjType::None; + } + LOG_RUNTIME("Type name '%s' not found!", type.c_str()); } - LOG_RUNTIME("Type name '%s' not found!", type.c_str()); + return obj_type->m_var_type_fixed; } - return obj_type->m_var_type_fixed; - } - ObjPtr GetTypeFromString(const std::string & type, bool *has_error = nullptr) { - if (type.empty()) { - return Obj::CreateNone(); - } - auto result = m_types.find(type); - if (result == m_types.end()) { - if (has_error) { - *has_error = true; - return nullptr; + ObjPtr GetTypeFromString(const std::string & type, bool *has_error = nullptr) { + if (type.empty()) { + return Obj::CreateNone(); } - LOG_RUNTIME("Type name '%s' not found!", type.c_str()); + auto result = m_types.find(type); + if (result == m_types.end()) { + if (has_error) { + *has_error = true; + return nullptr; + } + LOG_RUNTIME("Type name '%s' not found!", type.c_str()); + } + return result->second; } - return result->second; - } - enum class MatchMode { - EQUAL, - STRICT, - TYPE_NAME, - TYPE_EQUAL, - TYPE_STRICT, - }; - static bool MatchCompare(Obj &match, ObjPtr &value, MatchMode mode, Context *ctx); - static bool MatchEstimate(Obj &match, const TermPtr &match_item, MatchMode mode, Context *ctx, Obj * args); + enum class MatchMode { + EQUAL, + STRICT, + TYPE_NAME, + TYPE_EQUAL, + TYPE_STRICT, + }; + static bool MatchCompare(Obj &match, ObjPtr &value, MatchMode mode, Context *ctx); + static bool MatchEstimate(Obj &match, const TermPtr &match_item, MatchMode mode, Context *ctx, Obj * args); - SCOPE(protected) : - size_t GetCount(); - ObjPtr GetIndex(size_t index); + SCOPE(protected) : + size_t GetCount(); + ObjPtr GetIndex(size_t index); -private: + private: - Context(const Context&) = delete; - const Context& operator=(const Context&) = delete; + Context(const Context&) = delete; + const Context& operator=(const Context&) = delete; -}; + }; } #endif //INCLUDED_NEWLANG_CONTEXT_ diff --git a/core/lexer.l b/core/lexer.l index a4bb5057..157e6c14 100644 --- a/core/lexer.l +++ b/core/lexer.l @@ -351,10 +351,8 @@ term [$@%]({ualpha}|[_])?({name})? {macro} YY_TOKEN(MACRO); ".." YY_TOKEN(RANGE); "..." YY_TOKEN(ELLIPSIS); -"->>" YY_TOKEN(WHILE); -"-->>" YY_TOKEN(WHILE); -"<<-" YY_TOKEN(UNTIL); -"<<--" YY_TOKEN(UNTIL); +"<<->>" YY_TOKEN_ONLY(REPEAT); +"<<-->>" YY_TOKEN_ONLY(REPEAT); "->" YY_TOKEN(FOLLOW); "-->" YY_TOKEN(FOLLOW); "~>" YY_TOKEN(MATCHING); diff --git a/core/nlc.h b/core/nlc.h index 6b88980c..3ff10474 100644 --- a/core/nlc.h +++ b/core/nlc.h @@ -36,8 +36,8 @@ namespace newlang { #define NLC_FILE_HISTORY ".nlc_history" -class NLC { -public: + class NLC { + public: #define NLC_MODE(_) \ _(ERROR, 0) \ @@ -47,587 +47,587 @@ class NLC { _(EVAL, 4) \ _(EXEC, 5) - // _(COMPILE, 6) + // _(COMPILE, 6) - enum class Mode : uint8_t { + enum class Mode : uint8_t { #define DEFINE_ENUM(name, value) name = value, - NLC_MODE(DEFINE_ENUM) + NLC_MODE(DEFINE_ENUM) #undef DEFINE_ENUM - }; + }; - inline const char* toString(Mode mode) { + inline const char* toString(Mode mode) { #define DEFINE_CASE(name, _) \ case Mode::name: \ return #name; - switch (mode) { - NLC_MODE(DEFINE_CASE) - default: - LOG_ERROR("UNKNOWN MODE %d", static_cast (mode)); - return "UNKNOWN MODE"; - } + switch (mode) { + NLC_MODE(DEFINE_CASE) + default: + LOG_ERROR("UNKNOWN MODE %d", static_cast (mode)); + return "UNKNOWN MODE"; + } #undef DEFINE_CASE - } - - - std::string m_path; //< Имя исполняемого файла - Mode m_mode; //< Режим выполнения - std::vector m_modules; //< Список модулей, которые загружаются перед выполнением - std::vector m_load_only; //< Список модулей, которые предварительно загружаются перед выполнением без инициализации - bool m_no_default; //< Не загружать модуль default.nlp (модуль по умолчанию) - std::string m_ifile; //< Имя входного файла (если есть) - std::string m_ofile; //< Имя выходного файла (если есть) - bool m_is_silent; //< Нужно ли выводит сообщения - std::string m_output; //< Информация для вывода, в т.ч. при ошибке о текст подсказки - std::string m_eval; //< Входная информация для выполнения - Context m_ctx; - ObjPtr m_args; - std::map m_local_vars; //< Локальные переменные и объекты, которые создаются интерпретатором - - utils::Logger::LogLevelType m_loglevel_save; - utils::Logger::FuncCallback *m_log_callback_save; - void *m_log_callback_arg_save; - - NLC() : m_ctx(RunTime::Init()) { - m_mode = Mode::ERROR; - m_log_callback_save = nullptr; - m_log_callback_arg_save = nullptr; - } - - NLC(int argc, const char** argv) : m_ctx(RunTime::Init(argc, argv)) { - m_mode = Mode::ERROR; - m_log_callback_save = nullptr; - m_log_callback_arg_save = nullptr; - ParseArgs(argc, argv); - } - - NLC(const char * str) : NLC() { - std::vector split = SplitString(str, " "); - std::vector argv; - for (size_t i = 0; i < split.size(); i++) { - argv.push_back(split[i].data()); } - ParseArgs(argv.size(), argv.data()); - } - - virtual ~NLC() { - utils::Logger::Instance()->SetCallback(m_log_callback_save, m_log_callback_arg_save); - } - - static std::vector SplitString(const char * str, const char *delim) { - - std::vector result; - std::string s(str); - - size_t pos; - size_t end; - s.erase(0, s.find_first_not_of(delim)); - while (!s.empty()) { - pos = s.find(delim); - if (pos == std::string::npos) { - result.push_back(s); - break; - } else { - result.push_back(s.substr(0, pos)); - s.erase(0, pos); - } - s.erase(0, s.find_first_not_of(delim)); + + + std::string m_path; //< Имя исполняемого файла + Mode m_mode; //< Режим выполнения + std::vector m_modules; //< Список модулей, которые загружаются перед выполнением + std::vector m_load_only; //< Список модулей, которые предварительно загружаются перед выполнением без инициализации + bool m_no_default; //< Не загружать модуль default.nlp (модуль по умолчанию) + std::string m_ifile; //< Имя входного файла (если есть) + std::string m_ofile; //< Имя выходного файла (если есть) + bool m_is_silent; //< Нужно ли выводит сообщения + std::string m_output; //< Информация для вывода, в т.ч. при ошибке о текст подсказки + std::string m_eval; //< Входная информация для выполнения + Context m_ctx; + ObjPtr m_args; + std::map m_local_vars; //< Локальные переменные и объекты, которые создаются интерпретатором + + utils::Logger::LogLevelType m_loglevel_save; + utils::Logger::FuncCallback *m_log_callback_save; + void *m_log_callback_arg_save; + + NLC() : m_ctx(RunTime::Init()) { + m_mode = Mode::ERROR; + m_log_callback_save = nullptr; + m_log_callback_arg_save = nullptr; } - return result; - } - static void LoggerCallback(void *param, utils::Logger::LogLevelType level, const char * str, bool flush) { - NLC *nlc = static_cast (param); - if (nlc && nlc->m_is_silent) { - return; + NLC(int argc, const char** argv) : m_ctx(RunTime::Init(argc, argv)) { + m_mode = Mode::ERROR; + m_log_callback_save = nullptr; + m_log_callback_arg_save = nullptr; + ParseArgs(argc, argv); } - fprintf(stdout, "%s", str); - if (flush) { - fflush(stdout); + + NLC(const char * str) : NLC() { + std::vector split = SplitString(str, " "); + std::vector argv; + for (size_t i = 0; i < split.size(); i++) { + argv.push_back(split[i].data()); + } + ParseArgs(argv.size(), argv.data()); } - if (nlc) { - nlc->m_output += str; + + virtual ~NLC() { + utils::Logger::Instance()->SetCallback(m_log_callback_save, m_log_callback_arg_save); } - } - bool ParseArgs(int argc, const char** argv) { + static std::vector SplitString(const char * str, const char *delim) { + + std::vector result; + std::string s(str); - if (!argc || !argv) { - m_output = "Bad args nullptr"; - return false; + size_t pos; + size_t end; + s.erase(0, s.find_first_not_of(delim)); + while (!s.empty()) { + pos = s.find(delim); + if (pos == std::string::npos) { + result.push_back(s); + break; + } else { + result.push_back(s.substr(0, pos)); + s.erase(0, pos); + } + s.erase(0, s.find_first_not_of(delim)); + } + return result; } - m_args = Obj::CreateDict(); - for (int i = 0; i < argc; i++) { - std::vector split = SplitString(argv[i], "="); - if (split.size() > 1) { - m_args->push_back(Obj::CreateString(split[0]), &argv[i][split[0].size() + 1]); - } else { - m_args->push_back(Obj::CreateString(argv[i])); + static void LoggerCallback(void *param, utils::Logger::LogLevelType level, const char * str, bool flush) { + NLC *nlc = static_cast (param); + if (nlc && nlc->m_is_silent) { + return; + } + fprintf(stdout, "%s", str); + if (flush) { + fflush(stdout); + } + if (nlc) { + nlc->m_output += str; } } + bool ParseArgs(int argc, const char** argv) { - m_mode = Mode::INTERACTIVE; - if (argc) { - m_path = argv[0]; - } else { - m_path.clear(); - } - m_eval.clear(); - m_modules.clear(); - m_load_only.clear(); - m_no_default = false; - m_ifile.clear(); - m_ofile.clear(); - m_output.clear(); - m_is_silent = false; - - bool is_debug = false; - bool is_help = false; - bool is_ver = false; - std::string load_list; - std::string load_only; - std::string compile; - std::string exec; - std::string eval; - - utils::Logger::Instance()->SaveCallback(m_log_callback_save, m_log_callback_arg_save); - m_loglevel_save = utils::Logger::Instance()->GetLogLevel(); - utils::Logger::Instance()->Clear(); - utils::Logger::Instance()->SetCallback(&LoggerCallback, this); - - auto cli - = lyra::help(is_help).description("Description!!!!!!!!!!!!!!!!!!") - | lyra::opt(is_ver) ["-v"] ["--version"]("Version New Lang Compiler.") - | lyra::opt(is_debug) ["-d"] ["--debug"]("Debug detail mode.") - | lyra::opt(m_is_silent) ["-s"] ["--silent"]("Silent mode without message output.") - | lyra::opt(m_ofile, "filename") ["-o"]["--output"] ("Output file name.") - | lyra::opt(load_list, "list") ["-l"] ["--load"]("List of load modules.") - | lyra::opt(load_only, "list") ["--load-only"]("List of load only modules (without init module after load).") - | lyra::opt(compile, "filename") ["-c"] ["--compile"]("Compile input file and build NLM module.") - | lyra::opt(exec, "filename") ["-x"] ["--exec"]("Compile and make module, load and eXecute main module function.") - | lyra::opt(m_ifile, "filename") ["-e"] ["--eval"]("Evaluate file in interpreter mode.") - | lyra::arg(m_eval, "expression") ("Evaluate expression excluding compilation.") - ; - - - auto result = cli.parse({argc, argv}); - if (!result) { - m_mode = Mode::ERROR; - m_output = result.message(); - return false; - } + if (!argc || !argv) { + m_output = "Bad args nullptr"; + return false; + } - if (is_debug) { - utils::Logger::Instance()->SetLogLevel(LOG_LEVEL_DEBUG); - } + m_args = Obj::CreateDict(); + for (int i = 0; i < argc; i++) { + std::vector split = SplitString(argv[i], "="); + if (split.size() > 1) { + m_args->push_back(Obj::CreateString(split[0]), &argv[i][split[0].size() + 1]); + } else { + m_args->push_back(Obj::CreateString(argv[i])); + } + } - if (is_help) { - m_mode = Mode::HELP; - std::ostringstream out; - out << cli; - m_output = out.str(); - return true; - } - if (is_ver) { - m_mode = Mode::VERSION; - m_output = "Version info"; - return true; - } + m_mode = Mode::INTERACTIVE; + if (argc) { + m_path = argv[0]; + } else { + m_path.clear(); + } + m_eval.clear(); + m_modules.clear(); + m_load_only.clear(); + m_no_default = false; + m_ifile.clear(); + m_ofile.clear(); + m_output.clear(); + m_is_silent = false; + + bool is_debug = false; + bool is_help = false; + bool is_ver = false; + std::string load_list; + std::string load_only; + std::string compile; + std::string exec; + std::string eval; + + utils::Logger::Instance()->SaveCallback(m_log_callback_save, m_log_callback_arg_save); + m_loglevel_save = utils::Logger::Instance()->GetLogLevel(); + utils::Logger::Instance()->Clear(); + utils::Logger::Instance()->SetCallback(&LoggerCallback, this); + + auto cli + = lyra::help(is_help).description("Description!!!!!!!!!!!!!!!!!!") + | lyra::opt(is_ver) ["-v"] ["--version"]("Version New Lang Compiler.") + | lyra::opt(is_debug) ["-d"] ["--debug"]("Debug detail mode.") + | lyra::opt(m_is_silent) ["-s"] ["--silent"]("Silent mode without message output.") + | lyra::opt(m_ofile, "filename") ["-o"]["--output"] ("Output file name.") + | lyra::opt(load_list, "list") ["-l"] ["--load"]("List of load modules.") + | lyra::opt(load_only, "list") ["--load-only"]("List of load only modules (without init module after load).") + | lyra::opt(compile, "filename") ["-c"] ["--compile"]("Compile input file and build NLM module.") + | lyra::opt(exec, "filename") ["-x"] ["--exec"]("Compile and make module, load and eXecute main module function.") + | lyra::opt(m_ifile, "filename") ["-e"] ["--eval"]("Evaluate file in interpreter mode.") + | lyra::arg(m_eval, "expression") ("Evaluate expression excluding compilation.") + ; + + + auto result = cli.parse({argc, argv}); + if (!result) { + m_mode = Mode::ERROR; + m_output = result.message(); + return false; + } + + if (is_debug) { + utils::Logger::Instance()->SetLogLevel(LOG_LEVEL_DEBUG); + } - m_modules = SplitString(load_list.c_str(), ","); - m_load_only = SplitString(load_only.c_str(), ","); + if (is_help) { + m_mode = Mode::HELP; + std::ostringstream out; + out << cli; + m_output = out.str(); + return true; + } - int cnt = 0; - cnt += !compile.empty(); - cnt += !exec.empty(); - cnt += !m_ifile.empty(); - cnt += !m_eval.empty(); + if (is_ver) { + m_mode = Mode::VERSION; + m_output = "Version info"; + return true; + } - if (cnt > 1) { - m_mode = Mode::ERROR; - m_output = "Select only one mode: Compile, eXec or Eval!"; - // } else if (!compile.empty()) { - // m_mode = Mode::COMPILE; - // m_ifile = compile; - // } else if (!exec.empty()) { - // m_mode = Mode::EXEC; - // m_ifile = exec; - } else if (!m_eval.empty() || !m_ifile.empty()) { - m_mode = Mode::EVAL; - } else { - m_mode = Mode::INTERACTIVE; + m_modules = SplitString(load_list.c_str(), ","); + m_load_only = SplitString(load_only.c_str(), ","); + + int cnt = 0; + cnt += !compile.empty(); + cnt += !exec.empty(); + cnt += !m_ifile.empty(); + cnt += !m_eval.empty(); + + if (cnt > 1) { + m_mode = Mode::ERROR; + m_output = "Select only one mode: Compile, eXec or Eval!"; + // } else if (!compile.empty()) { + // m_mode = Mode::COMPILE; + // m_ifile = compile; + // } else if (!exec.empty()) { + // m_mode = Mode::EXEC; + // m_ifile = exec; + } else if (!m_eval.empty() || !m_ifile.empty()) { + m_mode = Mode::EVAL; + } else { + m_mode = Mode::INTERACTIVE; + } + + return m_mode != Mode::ERROR; } - return m_mode != Mode::ERROR; - } - - int Run() { - try { - //#warning EVAL - // ASSERT(false); - // for (auto &elem : m_load_only) { - // if (!m_ctx.m_info.global->LoadModule(AddDefaultFileExt(elem.c_str(), ".nlm").c_str(), false, &m_ctx)) { - // LOG_RUNTIME("Fail load-only module '%s'", AddDefaultFileExt(elem.c_str(), ".nlm").c_str()); - // } - // } - // - // for (auto &elem : m_modules) { - // if (!m_ctx.m_info.global->LoadModule(AddDefaultFileExt(elem.c_str(), ".nlm").c_str(), true, &m_ctx)) { - // LOG_RUNTIME("Fail load or init module '%s'", AddDefaultFileExt(elem.c_str(), ".nlm").c_str()); - // } - // } - - if (m_mode == Mode::ERROR || m_mode == Mode::VERSION || m_mode == Mode::HELP) { - LOG_INFO("%s", m_output.c_str()); - return 0; - // } else if (m_mode == Mode::COMPILE || m_mode == Mode::EXEC) { - // - // if (m_ifile.empty()) { - // LOG_RUNTIME("Empty input file!"); - // m_ifile = AddDefaultFileExt(m_ifile.c_str(), ".nlp"); - // } - // if (m_ofile.empty()) { - // m_ofile = m_ifile; - // m_ofile = ReplaceFileExt(m_ofile.c_str(), ".nlp", ".nlm"); - // } else { - // m_ofile = AddDefaultFileExt(m_ofile.c_str(), ".nlm"); + int Run() { + try { + //#warning EVAL + // ASSERT(false); + // for (auto &elem : m_load_only) { + // if (!m_ctx.m_info.global->LoadModule(AddDefaultFileExt(elem.c_str(), ".nlm").c_str(), false, &m_ctx)) { + // LOG_RUNTIME("Fail load-only module '%s'", AddDefaultFileExt(elem.c_str(), ".nlm").c_str()); // } + // } // - // switch (m_mode) { - // case Mode::COMPILE: - // // if (!m_ctx.m_runtime->m_info.global->CompileModule(m_ifile.c_str(), m_ofile.c_str())) { - // LOG_RUNTIME("Compile file '%s' fail!", m_ifile.c_str()); - // // } - // break; - // case Mode::EXEC: - //#warning EVAL - // ASSERT(false); - // // ObjPtr result = NewLang::ExecModule(m_ifile.c_str(), m_ofile.c_str(), true, &m_ctx); - // // m_output = result->GetValueAsString(); - // break; + // for (auto &elem : m_modules) { + // if (!m_ctx.m_info.global->LoadModule(AddDefaultFileExt(elem.c_str(), ".nlm").c_str(), true, &m_ctx)) { + // LOG_RUNTIME("Fail load or init module '%s'", AddDefaultFileExt(elem.c_str(), ".nlm").c_str()); // } - } else if (m_mode == Mode::EVAL) { - if (!m_eval.empty() && !m_ifile.empty()) { - LOG_RUNTIME("Error at the same time specified a source file '%s' and an expression '%s' !", m_ifile.c_str(), m_eval.c_str()); - } else if (!m_ifile.empty()) { - m_eval = ReadFile(m_ifile.c_str()); - if (m_eval.empty()) { - LOG_RUNTIME("Fail read or empty source file '%s'!", m_ifile.c_str()); + // } + + if (m_mode == Mode::ERROR || m_mode == Mode::VERSION || m_mode == Mode::HELP) { + LOG_INFO("%s", m_output.c_str()); + return 0; + // } else if (m_mode == Mode::COMPILE || m_mode == Mode::EXEC) { + // + // if (m_ifile.empty()) { + // LOG_RUNTIME("Empty input file!"); + // m_ifile = AddDefaultFileExt(m_ifile.c_str(), ".nlp"); + // } + // if (m_ofile.empty()) { + // m_ofile = m_ifile; + // m_ofile = ReplaceFileExt(m_ofile.c_str(), ".nlp", ".nlm"); + // } else { + // m_ofile = AddDefaultFileExt(m_ofile.c_str(), ".nlm"); + // } + // + // switch (m_mode) { + // case Mode::COMPILE: + // // if (!m_ctx.m_runtime->m_info.global->CompileModule(m_ifile.c_str(), m_ofile.c_str())) { + // LOG_RUNTIME("Compile file '%s' fail!", m_ifile.c_str()); + // // } + // break; + // case Mode::EXEC: + //#warning EVAL + // ASSERT(false); + // // ObjPtr result = NewLang::ExecModule(m_ifile.c_str(), m_ofile.c_str(), true, &m_ctx); + // // m_output = result->GetValueAsString(); + // break; + // } + } else if (m_mode == Mode::EVAL) { + if (!m_eval.empty() && !m_ifile.empty()) { + LOG_RUNTIME("Error at the same time specified a source file '%s' and an expression '%s' !", m_ifile.c_str(), m_eval.c_str()); + } else if (!m_ifile.empty()) { + m_eval = ReadFile(m_ifile.c_str()); + if (m_eval.empty()) { + LOG_RUNTIME("Fail read or empty source file '%s'!", m_ifile.c_str()); + } + } + TermPtr term; + Parser p(term); + p.Parse(m_eval.c_str()); + if (!term || m_eval.empty()) { + LOG_RUNTIME("Eval expression empty!"); } - } - TermPtr term; - Parser p(term); - p.Parse(m_eval.c_str()); - if (!term || m_eval.empty()) { - LOG_RUNTIME("Eval expression empty!"); - } - ObjPtr result = Context::ExecStr(&m_ctx, term, m_args.get()); + ObjPtr result = Context::ExecStr(&m_ctx, term, m_args.get(), true); - if (result && m_local_vars.find(result.get()) == m_local_vars.end()) { - m_local_vars[result.get()] = result; - } + if (result && m_local_vars.find(result.get()) == m_local_vars.end()) { + m_local_vars[result.get()] = result; + } - m_output = result->GetValueAsString(); + m_output = result->GetValueAsString(); - if (!m_ofile.empty()) { - std::ofstream out(m_ofile); - out << m_output; - out.close(); - } - if (!m_output.empty()) { - utils::Logger::LogLevelType save_level = utils::Logger::Instance()->GetLogLevel(); - utils::Logger::Instance()->SetLogLevel(LOG_LEVEL_INFO); - LOG_INFO("%s", m_output.c_str()); - utils::Logger::Instance()->SetLogLevel(save_level); + if (!m_ofile.empty()) { + std::ofstream out(m_ofile); + out << m_output; + out.close(); + } + if (!m_output.empty()) { + utils::Logger::LogLevelType save_level = utils::Logger::Instance()->GetLogLevel(); + utils::Logger::Instance()->SetLogLevel(LOG_LEVEL_INFO); + LOG_INFO("%s", m_output.c_str()); + utils::Logger::Instance()->SetLogLevel(save_level); + } + } else { + ASSERT(m_mode == Mode::INTERACTIVE); + Interative(); + // LOG_INFO("%s", m_output.c_str()); } - } else { - ASSERT(m_mode == Mode::INTERACTIVE); - Interative(); - // LOG_INFO("%s", m_output.c_str()); - } - } catch (Interrupt &err) { - // Вывод информации об ошибке синтаксиса при парсинге без информации о точке вызова макроса LOG_INFO - utils::Logger::LogLevelType save_level = utils::Logger::Instance()->GetLogLevel(); - utils::Logger::Instance()->SetLogLevel(LOG_LEVEL_INFO); - LOG_INFO("%s", err.what()); - utils::Logger::Instance()->SetLogLevel(save_level); - return 1; - } catch (...) { - return 1; + } catch (Interrupt &err) { + // Вывод информации об ошибке синтаксиса при парсинге без информации о точке вызова макроса LOG_INFO + utils::Logger::LogLevelType save_level = utils::Logger::Instance()->GetLogLevel(); + utils::Logger::Instance()->SetLogLevel(LOG_LEVEL_INFO); + LOG_INFO("%s", err.what()); + utils::Logger::Instance()->SetLogLevel(save_level); + return 1; + } catch (...) { + return 1; + } + return 0; } - return 0; - } - bool IsDelimiter(wchar_t c) { - return c == L' ' || c == L'&' || c == L'=' || c == L';' || c == L',' - || c == L'+' || c == L'-' || c == L'*' || c == L'/' - || c == L'<' || c == L'>' || c == L'|' || c == L'~' || c == L'^'; - } + bool IsDelimiter(wchar_t c) { + return c == L' ' || c == L'&' || c == L'=' || c == L';' || c == L',' + || c == L'+' || c == L'-' || c == L'*' || c == L'/' + || c == L'<' || c == L'>' || c == L'|' || c == L'~' || c == L'^'; + } - bool Interative() { + bool Interative() { - std::string output; - std::vector history; + std::string output; + std::vector history; - std::ifstream infile; - infile.open(NLC_FILE_HISTORY); - while (infile.is_open() && getline(infile, output)) { - history.push_back(output); - } - infile.close(); + std::ifstream infile; + infile.open(NLC_FILE_HISTORY); + while (infile.is_open() && getline(infile, output)) { + history.push_back(output); + } + infile.close(); - std::ofstream filehistory; - filehistory.open(NLC_FILE_HISTORY, std::ios::app); + std::ofstream filehistory; + filehistory.open(NLC_FILE_HISTORY, std::ios::app); - const char* title = ">"; - COLOR_TYPE title_color = "1"; - COLOR_TYPE predict_color = "80"; - COLOR_TYPE main_color = "0"; + const char* title = ">"; + COLOR_TYPE title_color = "1"; + COLOR_TYPE predict_color = "80"; + COLOR_TYPE main_color = "0"; - std::wstring buff; + std::wstring buff; - // Cursor offset in buffer for moving - int offset = 0; + // Cursor offset in buffer for moving + int offset = 0; - color_print("Type ", predict_color); - color_print("help()", main_color); - color_print(" for help about ", predict_color); - color_print("NewLang", title_color); - color_print(" syntax and commands or ", predict_color); - color_print("--", main_color); - color_print(" to exit the program.\n", predict_color); + color_print("Type ", predict_color); + color_print("help()", main_color); + color_print(" for help about ", predict_color); + color_print("NewLang", title_color); + color_print(" syntax and commands or ", predict_color); + color_print("--", main_color); + color_print(" to exit the program.\n", predict_color); - // Calculate title length - int title_len = (short) strlen(title); - bool show_all = false; + // Calculate title length + int title_len = (short) strlen(title); + bool show_all = false; - while (1) { + while (1) { - int history_pos = history.size(); + int history_pos = history.size(); - while (1) { - // Print title with title color - clear_line(); - color_print(title, title_color); - printf(title_len != 0 ? " " : ""); - fflush(stdout); + while (1) { + // Print title with title color + clear_line(); + color_print(title, title_color); + printf(title_len != 0 ? " " : ""); + fflush(stdout); - // Get length of last word in input - short space_offset = 0; - while (buff.size() && space_offset < buff.size() && !IsDelimiter(buff[buff.size() - space_offset - 1])) {//buff[buff.size() - space_offset - 1] != L' ') { - space_offset += 1; - } + // Get length of last word in input + short space_offset = 0; + while (buff.size() && space_offset < buff.size() && !IsDelimiter(buff[buff.size() - space_offset - 1])) {//buff[buff.size() - space_offset - 1] != L' ') { + space_offset += 1; + } - // Print current buffer - color_print(utf8_encode(buff).c_str(), main_color); - fflush(stdout); + // Print current buffer + color_print(utf8_encode(buff).c_str(), main_color); + fflush(stdout); - std::vector predict; + std::vector predict; - predict.clear(); - if (space_offset) { - size_t overflow = 5; + predict.clear(); + if (space_offset) { + size_t overflow = 5; - predict = m_ctx.SelectPredict(&buff[buff.size() - space_offset], overflow); // Не более 5 примеров продолжения + predict = m_ctx.SelectPredict(&buff[buff.size() - space_offset], overflow); // Не более 5 примеров продолжения - if (predict.size()) { - if (show_all) { - // Показать все варинанты - std::wstring helper; - for (int i = 0; i < overflow; i++) { - if (i >= predict.size()) { - break; + if (predict.size()) { + if (show_all) { + // Показать все варинанты + std::wstring helper; + for (int i = 0; i < overflow; i++) { + if (i >= predict.size()) { + break; + } + if (!helper.empty()) { + helper += L" "; + } + helper += predict[i]; } - if (!helper.empty()) { - helper += L" "; + if (predict.size() >= overflow) { + helper += L" ..."; // и есть еще } - helper += predict[i]; - } - if (predict.size() >= overflow) { - helper += L" ..."; // и есть еще - } - color_print(utf8_encode(helper.substr(space_offset)).c_str(), predict_color); - } else { - std::wstring show(predict[0]); - if (space_offset <= show.size()) { - if (predict.size() > 1) { // Присутсвует более одного варианта - show += L"..."; + color_print(utf8_encode(helper.substr(space_offset)).c_str(), predict_color); + } else { + std::wstring show(predict[0]); + if (space_offset <= show.size()) { + if (predict.size() > 1) { // Присутсвует более одного варианта + show += L"..."; + } + color_print(utf8_encode(show.substr(space_offset)).c_str(), predict_color); } - color_print(utf8_encode(show.substr(space_offset)).c_str(), predict_color); } } } - } - // Move cursor to buffer end - short x = (short) (buff.size() + title_len + (title_len != 0) + 1 - offset); - set_cursor_x(x); - - // Read character from console - int ch = _getch(); - - // Wait next symbol if character in ignore keys - if (is_ignore_key(ch)) { - continue; - }// Return buffer if ENTER was pressed - else if (ch == KEY_ENTER) { - if (!buff.empty() && (history.size() == 0 || (history.size() && history[history.size() - 1].compare(utf8_encode(buff)) != 0))) { - history.push_back(utf8_encode(buff)); - filehistory << utf8_encode(buff) << "\n"; - filehistory.flush(); - } - break; - }// Keyboard interrupt handler for Windows + // Move cursor to buffer end + short x = (short) (buff.size() + title_len + (title_len != 0) + 1 - offset); + set_cursor_x(x); + + // Read character from console + int ch = _getch(); + + // Wait next symbol if character in ignore keys + if (is_ignore_key(ch)) { + continue; + }// Return buffer if ENTER was pressed + else if (ch == KEY_ENTER) { + if (!buff.empty() && (history.size() == 0 || (history.size() && history[history.size() - 1].compare(utf8_encode(buff)) != 0))) { + history.push_back(utf8_encode(buff)); + filehistory << utf8_encode(buff) << "\n"; + filehistory.flush(); + } + break; + }// Keyboard interrupt handler for Windows #if defined(OS_WINDOWS) - else if (ch == CTRL_C) { - predictions_free(pred); - tree_free(rules); - free(buff); - exit(0); - } + else if (ch == CTRL_C) { + predictions_free(pred); + tree_free(rules); + free(buff); + exit(0); + } #endif - // Edit buffer like backspace if BACKSPACE was pressed - else if (ch == KEY_BACKSPACE) { - if (buff.size() && buff.size() - offset >= 1) { - // Delete character from buffer - for (unsigned i = (unsigned int) (buff.size() - offset - 1); i < buff.size() - 1; i++) { - buff[i] = buff[i + 1]; + // Edit buffer like backspace if BACKSPACE was pressed + else if (ch == KEY_BACKSPACE) { + if (buff.size() && buff.size() - offset >= 1) { + // Delete character from buffer + for (unsigned i = (unsigned int) (buff.size() - offset - 1); i < buff.size() - 1; i++) { + buff[i] = buff[i + 1]; + } + buff.resize(buff.size() - 1); } - buff.resize(buff.size() - 1); - } - // Apply prediction if TAB was pressed - } else if (ch == KEY_TAB) { + // Apply prediction if TAB was pressed + } else if (ch == KEY_TAB) { - if (predict.size() == 1 || (predict.size() > 1 && show_all)) { - if (space_offset < predict[0].size()) { - buff.append(predict[0].substr(space_offset)); + if (predict.size() == 1 || (predict.size() > 1 && show_all)) { + if (space_offset < predict[0].size()) { + buff.append(predict[0].substr(space_offset)); + } + show_all = false; + } else { + show_all = true; } - show_all = false; - } else { - show_all = true; - } - }// Arrows and Delete keys handler - else if ( - ch == SPECIAL_SEQ_1 + }// Arrows and Delete keys handler + else if ( + ch == SPECIAL_SEQ_1 #if defined(OS_WINDOWS) - || ch + || ch #elif defined(OS_UNIX) - && _getch() + && _getch() #endif - == SPECIAL_SEQ_2 - ) { - switch (_getch()) { - case KEY_LEFT: - // Increase offset from the end of the buffer if left key pressed - offset = (offset < buff.size()) ? (offset + 1) : buff.size(); - break; - case KEY_RIGHT: - // Decrease offset from the end of the buffer if left key pressed - offset = (offset > 0) ? offset - 1 : 0; - break; - case KEY_UP: - if (!history.empty() && history_pos > 0) { - clear_line(); - history_pos--; - buff = utf8_decode(history[history_pos]); - } - break; - case KEY_DOWN: - if (!history.empty() && history_pos + 1 < history.size()) { - clear_line(); - history_pos++; - buff = utf8_decode(history[history_pos]); - } - break; - case KEY_DEL: // Edit buffer like DELETE key + == SPECIAL_SEQ_2 + ) { + switch (_getch()) { + case KEY_LEFT: + // Increase offset from the end of the buffer if left key pressed + offset = (offset < buff.size()) ? (offset + 1) : buff.size(); + break; + case KEY_RIGHT: + // Decrease offset from the end of the buffer if left key pressed + offset = (offset > 0) ? offset - 1 : 0; + break; + case KEY_UP: + if (!history.empty() && history_pos > 0) { + clear_line(); + history_pos--; + buff = utf8_decode(history[history_pos]); + } + break; + case KEY_DOWN: + if (!history.empty() && history_pos + 1 < history.size()) { + clear_line(); + history_pos++; + buff = utf8_decode(history[history_pos]); + } + break; + case KEY_DEL: // Edit buffer like DELETE key #if defined(OS_UNIX) - if (_getch() == KEY_DEL_AFTER) + if (_getch() == KEY_DEL_AFTER) #endif - { - if (buff.size() && offset != 0) { - // Delete character from buffer - for (unsigned i = (unsigned int) (buff.size() - offset); i < buff.size() - 1; i++) { - buff[i] = buff[i + 1]; + { + if (buff.size() && offset != 0) { + // Delete character from buffer + for (unsigned i = (unsigned int) (buff.size() - offset); i < buff.size() - 1; i++) { + buff[i] = buff[i + 1]; + } + buff.resize(buff.size() - 1); + offset -= 1; } - buff.resize(buff.size() - 1); - offset -= 1; } - } - break; - default: - break; - } - }// Add character to buffer considering - // offset if any key was pressed - else { - - int w_ch; - if (!(ch & 0x80)) { - w_ch = ch; - } else if ((ch & 0xE0) == 0xC0) { // двухбайтовые UTF8 - w_ch = ch & 0x1F; - w_ch <<= 6; - ch = _getch(); - w_ch |= (ch & 0x3F); - } else { - LOG_ERROR("Unsupported char %d", ch); - w_ch = 0; - } + break; + default: + break; + } + }// Add character to buffer considering + // offset if any key was pressed + else { + + int w_ch; + if (!(ch & 0x80)) { + w_ch = ch; + } else if ((ch & 0xE0) == 0xC0) { // двухбайтовые UTF8 + w_ch = ch & 0x1F; + w_ch <<= 6; + ch = _getch(); + w_ch |= (ch & 0x3F); + } else { + LOG_ERROR("Unsupported char %d", ch); + w_ch = 0; + } - buff += w_ch; + buff += w_ch; + } } - } - std::string result; - if (buff.compare(L"--") == 0 || buff.compare(L"--;") == 0) { - printf("\n"); - break; - } else if (!buff.empty()) { - try { -// TermPtr term = m_ctx.ExecStr(utf8_encode(buff)); -// -// if (!term) { -// LOG_RUNTIME("Eval expression empty!"); -// } - std::string input = utf8_encode(buff); - - ObjPtr res = m_ctx.ExecStr(input, m_args.get()); - - if (res) { - - if (m_local_vars.find(res.get()) == m_local_vars.end()) { - m_local_vars[res.get()] = res; + std::string result; + if (buff.compare(L"--") == 0 || buff.compare(L"--;") == 0) { + printf("\n"); + break; + } else if (!buff.empty()) { + try { + // TermPtr term = m_ctx.ExecStr(utf8_encode(buff)); + // + // if (!term) { + // LOG_RUNTIME("Eval expression empty!"); + // } + std::string input = utf8_encode(buff); + + ObjPtr res = m_ctx.ExecStr(input, m_args.get(), true); + + if (res) { + + if (m_local_vars.find(res.get()) == m_local_vars.end()) { + m_local_vars[res.get()] = res; + } + + result = res->GetValueAsString(); + } else { + result = "nullptr"; } - - result = res->GetValueAsString(); - } else { - result = "nullptr"; - } - } catch (std::exception &err) { - result = err.what(); + } catch (std::exception &err) { + result = err.what(); + } + buff.clear(); } - buff.clear(); + printf("\n%s\n", result.c_str()); + show_all = false; } - printf("\n%s\n", result.c_str()); - show_all = false; - } - filehistory.close(); - return 0; - } + filehistory.close(); + return 0; + } -}; + }; } diff --git a/core/object.cpp b/core/object.cpp index 12e66c1b..224ffc65 100644 --- a/core/object.cpp +++ b/core/object.cpp @@ -1035,7 +1035,7 @@ ObjPtr Obj::Call(Context *ctx, Obj * args) { } else if(m_var_type_current == ObjType::NativeFunc) { result = CallNative(ctx, *param.get()); } else if(m_var_type_current == ObjType::EVAL_FUNCTION || m_var_type_current == ObjType::SimplePureFunc) { - result = Context::CallBlock(ctx, m_block_source, param.get()); + result = Context::CallBlock(ctx, m_block_source, param.get(), false); } else if(m_var_type_current == ObjType::SimplePureAND) { result = Context::EvalBlockAND(ctx, m_block_source, param.get()); } else if(m_var_type_current == ObjType::SimplePureOR) { diff --git a/core/parser.y b/core/parser.y index 6ec43768..75447a48 100644 --- a/core/parser.y +++ b/core/parser.y @@ -365,8 +365,7 @@ star_arg = [STAR] STAR ID %token FOLLOW %token MATCHING -%token WHILE -%token UNTIL +%token REPEAT %token ARGUMENT @@ -1400,15 +1399,17 @@ follow: if_then } -repeat: match_cond WHILE body +repeat: match_cond REPEAT body { $$=$2; + $$->SetTermID(TermID::WHILE); $$->Append($match_cond, Term::LEFT); $$->Append($body, Term::RIGHT); } - | body UNTIL match_cond + | body REPEAT match_cond { $$=$2; + $$->SetTermID(TermID::DOWHILE); $$->Append($body, Term::LEFT); $$->Append($match_cond, Term::RIGHT); } diff --git a/core/term.h b/core/term.h index 835fc952..18c6b759 100644 --- a/core/term.h +++ b/core/term.h @@ -58,7 +58,7 @@ namespace newlang { _(FOLLOW) \ _(MATCHING) \ _(WHILE) \ - _(UNTIL) \ + _(DOWHILE) \ \ _(RANGE) \ _(ELLIPSIS) \ @@ -512,13 +512,13 @@ namespace newlang { case TermID::WHILE: // [cond] <-> repeat; result = "[" + result + "]"; - result += m_text; + result += m_text; ASSERT(m_right); result += m_right->toString(); result += ";"; return result; - case TermID::UNTIL: + case TermID::DOWHILE: result = result; result += m_text + "["; ASSERT(m_right); @@ -808,7 +808,6 @@ namespace newlang { return item; } - inline bool ConvertSequenceToBlock(TermID id, bool force = true) { if (!force && !m_sequence && !IsBlock()) { diff --git a/core/test/alg_test.cpp b/core/test/alg_test.cpp index 4db2703a..644ff968 100644 --- a/core/test/alg_test.cpp +++ b/core/test/alg_test.cpp @@ -110,12 +110,12 @@ TEST(Alg, Repeat) { result = ctx.ExecStr("result -= 1"); ASSERT_EQ(3, result->GetValueAsInteger()); - counter = ctx.ExecStr("[result -= 1] ->> {counter += 1}"); + counter = ctx.ExecStr("[result -= 1] <<->> {counter += 1}"); ASSERT_TRUE(counter); ASSERT_EQ(2, counter->GetValueAsInteger()); - counter = ctx.ExecStr("{result += 1; counter += 1} <<- [result < 10]"); + counter = ctx.ExecStr("{result += 1; counter += 1} <<->> [result < 10]"); ASSERT_EQ(10, result->GetValueAsInteger()); ASSERT_TRUE(counter); @@ -237,7 +237,7 @@ TEST(Alg, Foreach) { ObjPtr summa = ctx.ExecStr("summa := 0"); - temp = ctx.ExecStr("counter = 0; [dict] ->> {counter, dict := ... dict; summa += counter}"); + temp = ctx.ExecStr("counter = 0; [dict] <<-->> {counter, dict := ... dict; summa += counter}"); ASSERT_TRUE(temp); ASSERT_TRUE(temp->is_integer()); ASSERT_EQ(150, temp->GetValueAsInteger()); @@ -250,7 +250,7 @@ TEST(Alg, Foreach) { summa = ctx.ExecStr("summa := 0"); dict = ctx.ExecStr("dict := (1,2,3,4,5,)"); - temp = ctx.ExecStr("item := 0; [dict] ->> {item, dict := ... dict; summa += item}"); + temp = ctx.ExecStr("item := 0; [dict] <<->> {item, dict := ... dict; summa += item}"); ASSERT_TRUE(temp); ASSERT_TRUE(temp->is_integer()); ASSERT_EQ(15, temp->GetValueAsInteger()); @@ -325,7 +325,7 @@ TEST(Alg, Foreach) { ObjPtr summa2 = ctx.ExecStr("summa := 0"); ObjPtr tensor2 = ctx.ExecStr("tensor := [10,20,30,40,50,60,]"); - ObjPtr temp2 = ctx.ExecStr("item2 := 0; [tensor] ->> {item2, tensor := ... tensor; summa += item2}"); + ObjPtr temp2 = ctx.ExecStr("item2 := 0; [tensor] <<->> {item2, tensor := ... tensor; summa += item2}"); ASSERT_TRUE(temp2); ASSERT_TRUE(temp2->is_integer()); ASSERT_EQ(210, temp2->GetValueAsInteger()); @@ -344,7 +344,7 @@ TEST(Alg, Foreach) { ASSERT_EQ(0, (*tensor_size)[5]->GetValueAsInteger()); ASSERT_EQ(10, (*tensor_size)[6]->GetValueAsInteger()); ASSERT_EQ(40, (*tensor_size)[9]->GetValueAsInteger()); - + } TEST(Alg, Return) { @@ -384,7 +384,7 @@ TEST(Alg, Return) { * }}:Break * dict := (10,20,30,40,50,60,70,80,); * :Break := :Return; - * [dict] ->> {{ + * [dict] <<->> {{ * item, dict := ... dict; * summa += item; * [summa > 100] -> --:Break--; @@ -393,7 +393,7 @@ TEST(Alg, Return) { * * :Continue := :Return; * dict := (10,20,30,40,50,60,70,80,); - * [dict] ->> { + * [dict] <<->> { * {{ * item, dict := ... dict; * summa += item; @@ -456,7 +456,7 @@ TEST(Alg, Return) { ObjPtr value = nullptr; try { - result = ctx.ExecStr("--"); + result = ctx.ExecStr("--", nullptr, false); } catch (Interrupt &except) { ASSERT_EQ(ObjType::Return, except.m_obj->getType()); ASSERT_EQ(1, except.m_obj->size()); @@ -465,7 +465,7 @@ TEST(Alg, Return) { ASSERT_FALSE(result); try { - result = ctx.ExecStr("--100--"); + result = ctx.ExecStr("--100--", nullptr, false); } catch (Interrupt &except) { ASSERT_EQ(ObjType::Return, except.m_obj->getType()); ASSERT_EQ(1, except.m_obj->size()); @@ -474,7 +474,7 @@ TEST(Alg, Return) { ASSERT_FALSE(result); try { - result = ctx.ExecStr("--'Тест'--"); + result = ctx.ExecStr("--'Тест'--", nullptr, false); } catch (Interrupt &except) { ASSERT_EQ(ObjType::Return, except.m_obj->getType()); ASSERT_EQ(1, except.m_obj->size()); @@ -483,7 +483,7 @@ TEST(Alg, Return) { ASSERT_FALSE(result); try { - result = ctx.ExecStr("--:Int--"); + result = ctx.ExecStr("--:Int--", nullptr, false); } catch (Interrupt &except) { ASSERT_STREQ(":Int", except.m_obj->m_class_name.c_str()); ASSERT_EQ(0, except.m_obj->size()); @@ -492,7 +492,7 @@ TEST(Alg, Return) { ASSERT_FALSE(result); try { - result = ctx.ExecStr("--:Error()--"); + result = ctx.ExecStr("--:Error()--", nullptr, false); } catch (Interrupt &except) { ASSERT_EQ(ObjType::Error, except.m_obj->getType()); ASSERT_EQ(1, except.m_obj->size()); @@ -502,7 +502,7 @@ TEST(Alg, Return) { try { - result = ctx.ExecStr("--:Error('ТЕКСТ')--"); + result = ctx.ExecStr("--:Error('ТЕКСТ')--", nullptr, false); } catch (Interrupt &except) { ASSERT_EQ(ObjType::Error, except.m_obj->getType()); ASSERT_EQ(1, except.m_obj->size()); @@ -513,23 +513,23 @@ TEST(Alg, Return) { result.reset(); - ASSERT_NO_THROW(result = ctx.ExecStr("(){count := 1; count += 1; count += 1; count += 1; count += 1;};");); + ASSERT_NO_THROW(result = ctx.ExecStr("(){count := 1; count += 1; count += 1; count += 1; count += 1;};", nullptr, false);); ASSERT_TRUE(result); ASSERT_TRUE(result->is_integer()); ASSERT_EQ(5, result->GetValueAsInteger()); result.reset(); - ASSERT_NO_THROW(result = ctx.ExecStr("(){count := 1; count += 1; count += 1; count += 1; count += 1;}; 99");); + ASSERT_NO_THROW(result = ctx.ExecStr("(){count := 1; count += 1; count += 1; count += 1; count += 1;}; 99", nullptr, false);); ASSERT_TRUE(result); ASSERT_TRUE(result->is_integer()); ASSERT_EQ(99, result->GetValueAsInteger()); result.reset(); - ASSERT_ANY_THROW(result = ctx.ExecStr("(){count := 1; count += 1; count += 1; --55--; count += 1; count += 1;}; 5555");); + ASSERT_ANY_THROW(result = ctx.ExecStr("(){count := 1; count += 1; count += 1; --55--; count += 1; count += 1;}; 5555", nullptr, false);); ASSERT_FALSE(result); result.reset(); - ASSERT_NO_THROW(result = ctx.ExecStr("(){{count := 1; count += 1; count += 1; --77--; count += 1; count += 1;}}");); + ASSERT_NO_THROW(result = ctx.ExecStr("(){{count := 1; count += 1; count += 1; --77--; count += 1; count += 1;}}", nullptr, true);); ASSERT_TRUE(result); ASSERT_TRUE(result->is_integer()); ASSERT_EQ(77, result->GetValueAsInteger()); @@ -541,35 +541,35 @@ TEST(Alg, Return) { ASSERT_EQ(7777, result->GetValueAsInteger()); result.reset(); - ASSERT_ANY_THROW(result = ctx.ExecStr("(){ (){count := 1; count += 1; count += 1; --:Error(88)--; count += 1; count += 1}; 8888; }");); + ASSERT_ANY_THROW(result = ctx.ExecStr("(){ (){count := 1; count += 1; count += 1; --:Error(88)--; count += 1; count += 1}; 8888; }", nullptr, false);); ASSERT_FALSE(result); result.reset(); - ASSERT_NO_THROW(result = ctx.ExecStr("(){ (){{count := 1; count += 1; count += 1; --:Error(99)--; count += 1; count += 1}}; 888}");); + ASSERT_NO_THROW(result = ctx.ExecStr("(){ (){{count := 1; count += 1; count += 1; --:Error(99)--; count += 1; count += 1}}; 888}", nullptr, false);); ASSERT_TRUE(result); ASSERT_TRUE(result->is_integer()); ASSERT_EQ(888, result->GetValueAsInteger()); result.reset(); - ASSERT_NO_THROW(result = ctx.ExecStr("(){ (){{count := 1; count += 1; count += 1; --:Error(99)--; count += 1; count += 1}}; }");); + ASSERT_NO_THROW(result = ctx.ExecStr("(){ (){{count := 1; count += 1; count += 1; --:Error(99)--; count += 1; count += 1}}; }", nullptr, false);); ASSERT_TRUE(result); ASSERT_EQ(1, result->size()); ASSERT_EQ(99, (*result)[0]->GetValueAsInteger()); result.reset(); - ASSERT_NO_THROW(result = ctx.ExecStr("(){ (){{count := 1; count += 1; count += 1; --:Error(33)--; count += 1; count += 1}}; }");); + ASSERT_NO_THROW(result = ctx.ExecStr("(){ (){{count := 1; count += 1; count += 1; --:Error(33)--; count += 1; count += 1}}; }", nullptr, false);); ASSERT_TRUE(result); ASSERT_EQ(1, result->size()); ASSERT_EQ(33, (*result)[0]->GetValueAsInteger()); result.reset(); - ASSERT_NO_THROW(result = ctx.ExecStr("(){ (){{count := 1; count += 1; count += 1; --:Error(44)--; count += 1; count += 1}}; 9999; }");); + ASSERT_NO_THROW(result = ctx.ExecStr("(){ (){{count := 1; count += 1; count += 1; --:Error(44)--; count += 1; count += 1}}; 9999; }", nullptr, false);); ASSERT_TRUE(result); ASSERT_EQ(9999, result->GetValueAsInteger()); result.reset(); // Не должен перехватытвать другой класс объекта - ASSERT_ANY_THROW(result = ctx.ExecStr("(){ (){{count := 1; count += 1; count += 1; --:Error(55)--; count += 1; count += 1}}:ErrorRunTime; }");); + ASSERT_ANY_THROW(result = ctx.ExecStr("(){ (){{count := 1; count += 1; count += 1; --:Error(55)--; count += 1; count += 1}}:ErrorRunTime; }", nullptr, false);); ASSERT_FALSE(result); @@ -583,7 +583,7 @@ TEST(Alg, Return) { result.reset(); // Не должен перехватытвать другой класс объекта, но его перехватывает внешний блок - ASSERT_NO_THROW(result = ctx.ExecStr("(){{ (){{count := 1; count += 1; count += 1; --:Error(66)--; count += 1; count += 1}}:ErrorRunTime; 777; }}");); + ASSERT_NO_THROW(result = ctx.ExecStr("(){{ (){{count := 1; count += 1; count += 1; --:Error(66)--; count += 1; count += 1}}:ErrorRunTime; 777; }}", nullptr, false);); ASSERT_TRUE(result); ASSERT_TRUE(result->is_error()); ASSERT_STREQ(":Error(66)", result->toString().c_str()); @@ -591,24 +591,24 @@ TEST(Alg, Return) { result.reset(); // Должен перехватытвать прерывание и вернуть его как обычный объект без исключения из внешнего блока - ASSERT_NO_THROW(result = ctx.ExecStr("(){ (){{count := 1; count += 1; count += 1; --:ErrorRunTime(77)--; count += 1; count += 1}}:ErrorRunTime }");); + ASSERT_NO_THROW(result = ctx.ExecStr("(){ (){{count := 1; count += 1; count += 1; --:ErrorRunTime(77)--; count += 1; count += 1}}:ErrorRunTime }", nullptr, false);); ASSERT_TRUE(result); ASSERT_EQ(1, result->size()); ASSERT_EQ(77, (*result)[0]->GetValueAsInteger()); result.reset(); - ASSERT_NO_THROW(result = ctx.ExecStr("(){ (){{count := 1; count += 1; count += 1; --:ErrorRunTime(88)--; count += 1; count += 1}}:ErrorRunTime; 9999; }");); + ASSERT_NO_THROW(result = ctx.ExecStr("(){ (){{count := 1; count += 1; count += 1; --:ErrorRunTime(88)--; count += 1; count += 1}}:ErrorRunTime; 9999; }", nullptr, false);); ASSERT_TRUE(result); ASSERT_EQ(9999, result->GetValueAsInteger()); result.reset(); - ASSERT_NO_THROW(result = ctx.ExecStr("(){ (){{count := 1; count += 1; count += 1; --:ErrorRunTime(77)--; count += 1; count += 1}}:Error }");); + ASSERT_NO_THROW(result = ctx.ExecStr("(){ (){{count := 1; count += 1; count += 1; --:ErrorRunTime(77)--; count += 1; count += 1}}:Error }", nullptr, false);); ASSERT_TRUE(result); ASSERT_EQ(1, result->size()); ASSERT_EQ(77, (*result)[0]->GetValueAsInteger()); result.reset(); - ASSERT_NO_THROW(result = ctx.ExecStr("(){ (){{count := 1; count += 1; count += 1; --:ErrorRunTime(88)--; count += 1; count += 1}}:Error; 9999; }");); + ASSERT_NO_THROW(result = ctx.ExecStr("(){ (){{count := 1; count += 1; count += 1; --:ErrorRunTime(88)--; count += 1; count += 1}}:Error; 9999; }", nullptr, false);); ASSERT_TRUE(result); ASSERT_EQ(9999, result->GetValueAsInteger()); } diff --git a/core/test/eval_test.cpp b/core/test/eval_test.cpp index 9bd0d979..32260a02 100644 --- a/core/test/eval_test.cpp +++ b/core/test/eval_test.cpp @@ -540,7 +540,7 @@ TEST(Eval, Fileio) { Context::Reset(); Context ctx(RunTime::Init()); - ASSERT_NO_THROW(ctx.ExecFile("nlp/fileio.nlp")); + ASSERT_NO_THROW(ctx.ExecFile("nlp/fileio.nlp", nullptr, false)); ASSERT_TRUE(ctx.FindTerm("fopen")); ASSERT_TRUE(ctx.FindTerm("fputs")); @@ -795,21 +795,45 @@ TEST(Eval, MacroDSL) { Context::Reset(); Context ctx(RunTime::Init()); + /* + * Для следующего релиза: + * - Макросы + * - Синтаксис циклов к единому виду + * - Обработка в циклах вовзврата, ошибок, break и continue + * - Примеры программ в обычном виде + * - Сборка nlc под Windows и выпуск в виде бинарника + * + * - Расширение методов Obj за счет вызовов torch + * - Примеры программ для тензорных вычислений + * + */ const char * dsl = "" "\\\\if(cond) [\\$cond]-->\\\\\\" - "\\\\elseif(cond) ,[\\$cond]-->\\\\\\" + "\\\\elif(cond) ,[\\$cond]-->\\\\\\" "\\\\else ,[_]-->\\\\\\" "" - "\\\\while(cond) [\\$cond]-->>\\\\\\" - "\\\\dowhile(cond) <<--[\\$cond]\\\\\\" + "\\\\while(cond) [\\$cond]<<-->>\\\\\\" + "\\\\dowhile(cond) <<-->>[\\$cond]\\\\\\" + "" + "\\\\break --:Break--\\\\\\" + "\\\\continue --:Continue--\\\\\\" + "" "\\\\return --\\\\\\" "\\\\return(...) --\\$*--\\\\\\" + "\\\\error(...) --:Error(\\$*)--\\\\\\" + "" + "\\\\true 1\\\\\\" + "\\\\yes 1\\\\\\" + "\\\\false 0\\\\\\" + "\\\\no 0\\\\\\" + "" + "\\\\this $0\\\\\\" ""; ASSERT_EQ(0, Context::m_macros.size()); ObjPtr none = ctx.ExecStr(dsl); - ASSERT_EQ(7, Context::m_macros.size()); + ASSERT_TRUE(Context::m_macros.size() > 10); ObjPtr count = ctx.ExecStr("@count:=0;"); ASSERT_TRUE(count); @@ -817,16 +841,15 @@ TEST(Eval, MacroDSL) { const char * run_raw = "" "count:=5;" - "(){{" - " [count<10]-->>{" - " [count>5]-->{" - " --100--;" - " }; " - " count+=1;" - " };" - "}};"; + "[count<10]<<-->>{{" + " [count>5]-->{" + " --100--;" + " }; " + " count+=1;" + "}};" + ; - ObjPtr result = ctx.ExecStr(run_raw); + ObjPtr result = ctx.ExecStr(run_raw, nullptr, true); ASSERT_TRUE(result); ASSERT_TRUE(result->is_integer()); ASSERT_EQ(6, count->GetValueAsInteger()); @@ -834,19 +857,17 @@ TEST(Eval, MacroDSL) { const char * run_macro = "" "count:=5;" - "(){{" - " \\while(count<10){" - " \\if(count>5){" - " \\return(42);" - " };" - " count+=1;" + "\\while(count<10){{" + " \\if(count>5){" + " \\return(42);" " };" + " count+=1;" "}};" ""; - result = ctx.ExecStr(run_macro); + result = ctx.ExecStr(run_macro, nullptr, true); ASSERT_TRUE(result); ASSERT_TRUE(result->is_integer()); ASSERT_EQ(6, count->GetValueAsInteger()); @@ -865,7 +886,7 @@ class OpEvalTest : public ::testing::Test { const char *Test(std::string eval, Obj &vars) { eval += ";"; m_result = m_ctx.ExecStr(eval, &vars); - if (m_result) { + if(m_result) { m_string = m_result->GetValueAsString(); return m_string.c_str(); } @@ -1214,11 +1235,11 @@ TEST(EvalOp, InstanceName) { for (auto &elem : test_name) { res.reset(); - ASSERT_NO_THROW(res = ctx.ExecStr(elem.first)) << elem.first; + ASSERT_NO_THROW(res = ctx.ExecStr(elem.first, nullptr, false)) << elem.first; EXPECT_TRUE(res) << elem.first; - if (res) { + if(res) { EXPECT_TRUE(res->is_bool_type()) << elem.first; - if (elem.second) { + if(elem.second) { EXPECT_TRUE(res->GetValueAsBoolean()) << elem.first; } else { EXPECT_FALSE(res->GetValueAsBoolean()) << elem.first; diff --git a/core/test/nlc_test.cpp b/core/test/nlc_test.cpp index bbcb8657..2890ef9c 100644 --- a/core/test/nlc_test.cpp +++ b/core/test/nlc_test.cpp @@ -141,7 +141,7 @@ TEST(NLC, EvalHelloWorld) { out.close(); NLC run; - ObjPtr result = run.m_ctx.ExecStr(cmd); + ObjPtr result = run.m_ctx.ExecStr(cmd, nullptr, true); ASSERT_TRUE(result); ASSERT_STREQ("Привет, мир!\n", result->GetValueAsString().c_str()); } diff --git a/core/test/object_test.cpp b/core/test/object_test.cpp index c3448d35..b6ef3fc0 100644 --- a/core/test/object_test.cpp +++ b/core/test/object_test.cpp @@ -125,7 +125,7 @@ TEST(ObjTest, String) { format = Obj::CreateString("$nameno ${имя1} $name $имя"); ObjPtr str5 = (*format)(nullptr, Obj::Arg("value", "name"), Obj::Arg("УТФ8-УТФ8", "имя"), Obj::Arg("УТФ8", "имя1")); ASSERT_STREQ("valueno УТФ8 value УТФ8-УТФ8", str5->GetValueAsString().c_str()); - + } TEST(ObjTest, Dict) { @@ -135,7 +135,7 @@ TEST(ObjTest, Dict) { Obj var(ObjType::Dictionary); ASSERT_TRUE(var.empty()); EXPECT_ANY_THROW(var[0]); - + ASSERT_EQ(0, var.size()); ObjPtr var2 = ctx.ExecStr("(,)"); @@ -173,7 +173,7 @@ TEST(ObjTest, AsMap) { ASSERT_TRUE(map->empty()); EXPECT_ANY_THROW((*map)["test1"]); ASSERT_EQ(0, map->size()); - + ObjPtr temp = Obj::CreateString("Test"); map->push_back(temp, "test1"); map->push_back(Obj::CreateValue(100, ObjType::None), "test2"); @@ -389,12 +389,12 @@ TEST(ObjTest, Print) { ObjPtr obj_empty = Obj::CreateType(ObjType::Class, "name"); ASSERT_STREQ("name=()", obj_empty->toString().c_str()) << obj_empty; -// ObjPtr var_obj = Obj::CreateFrom("obj", obj_empty); -// ASSERT_STREQ("obj=name()", var_obj->toString().c_str()) << var_obj; -// -// var_int->m_var_name = "int"; -// var_obj->push_back((*var_int.get())(nullptr)); -// ASSERT_STREQ("obj=name(int=100)", var_obj->toString().c_str()) << var_obj; + // ObjPtr var_obj = Obj::CreateFrom("obj", obj_empty); + // ASSERT_STREQ("obj=name()", var_obj->toString().c_str()) << var_obj; + // + // var_int->m_var_name = "int"; + // var_obj->push_back((*var_int.get())(nullptr)); + // ASSERT_STREQ("obj=name(int=100)", var_obj->toString().c_str()) << var_obj; } @@ -694,7 +694,7 @@ TEST(ObjTest, Tensor) { ASSERT_EQ(2, t1->m_value.dim()); ASSERT_EQ(2, t1->m_value.size(0)); ASSERT_EQ(3, t1->m_value.size(1)); - + // Байтовые строки ObjPtr str = Obj::CreateString("test"); ObjPtr t_str = Obj::CreateTensor(str->toTensor()); @@ -728,7 +728,7 @@ TEST(ObjTest, Tensor) { t_wstr->index_set_({2}, Obj::CreateString(L"с")); EXPECT_STREQ(t_wstr->toType(ObjType::StrWide)->GetValueAsString().c_str(), "ТесТ"); - + } #endif // UNITTEST \ No newline at end of file diff --git a/core/test/parser_test.cpp b/core/test/parser_test.cpp index e71a8e62..e431c4f6 100644 --- a/core/test/parser_test.cpp +++ b/core/test/parser_test.cpp @@ -1486,26 +1486,26 @@ TEST_F(ParserTest, BlockTry) { } TEST_F(ParserTest, Repeat) { - ASSERT_TRUE(Parse("[val] -->> val;")); - ASSERT_TRUE(Parse("val <<-- [val];;")); - ASSERT_TRUE(Parse("[val] -->> {val;};")); - ASSERT_TRUE(Parse("[val] -->> {val;};;")); - ASSERT_TRUE(Parse("[val] -->> {val;};")); - ASSERT_TRUE(Parse("[val] -->> {val;};;")); - - ASSERT_TRUE(Parse("val <<- [val()];")); - ASSERT_TRUE(Parse("val <<- [val()];;")); - ASSERT_TRUE(Parse("[val()] -->> {val();};")); - ASSERT_TRUE(Parse("[val()] -->> {val();};;")); - ASSERT_TRUE(Parse("[val()] -->> {val();};")); - ASSERT_TRUE(Parse("[val()] -->> {val();};;")); - - ASSERT_TRUE(Parse("[val()] -->> {val()};val();")); - ASSERT_TRUE(Parse("val <<-- [val()];val();")); - ASSERT_TRUE(Parse("[val()] -->> {val();val();};")); - ASSERT_TRUE(Parse("[val()] -->> {val();val();};;")); - ASSERT_TRUE(Parse("[val()] -->> {val();val();};")); - ASSERT_TRUE(Parse("[val()] -->> {val();val();};;")); + ASSERT_TRUE(Parse("[val] <<-->> val;")); + ASSERT_TRUE(Parse("val <<-->> [val];;")); + ASSERT_TRUE(Parse("[val] <<-->> {val;};")); + ASSERT_TRUE(Parse("[val] <<-->> {val;};;")); + ASSERT_TRUE(Parse("[val] <<-->> {val;};")); + ASSERT_TRUE(Parse("[val] <<-->> {val;};;")); + + ASSERT_TRUE(Parse("val <<->> [val()];")); + ASSERT_TRUE(Parse("val <<->> [val()];;")); + ASSERT_TRUE(Parse("[val()] <<-->> {val();};")); + ASSERT_TRUE(Parse("[val()] <<-->> {val();};;")); + ASSERT_TRUE(Parse("[val()] <<-->> {val();};")); + ASSERT_TRUE(Parse("[val()] <<-->> {val();};;")); + + ASSERT_TRUE(Parse("[val()] <<-->> {val()};val();")); + ASSERT_TRUE(Parse("val <<-->> [val()];val();")); + ASSERT_TRUE(Parse("[val()] <<-->> {val();val();};")); + ASSERT_TRUE(Parse("[val()] <<-->> {val();val();};;")); + ASSERT_TRUE(Parse("[val()] <<-->> {val();val();};")); + ASSERT_TRUE(Parse("[val()] <<-->> {val();val();};;")); } TEST_F(ParserTest, Operators) { @@ -1539,67 +1539,67 @@ TEST_F(ParserTest, Operators) { } TEST_F(ParserTest, DISABLED_Repeat0) { - ASSERT_TRUE(Parse("[human || $ttttt && 123 != test[0].field ] -->> if_1;")); - ASSERT_STREQ("[human || $ttttt && 123 != test[0].field]-->>{if_1;};", ast->toString().c_str()); + ASSERT_TRUE(Parse("[human || $ttttt && 123 != test[0].field ] <<-->> if_1;")); + ASSERT_STREQ("[human || $ttttt && 123 != test[0].field]<<-->>{if_1;};", ast->toString().c_str()); } TEST_F(ParserTest, Repeat1) { - ASSERT_TRUE(Parse("[test == human] -->> if_1;")); - ASSERT_STREQ("[test==human]-->>if_1;", ast->toString().c_str()); + ASSERT_TRUE(Parse("[test == human] <<-->> if_1;")); + ASSERT_STREQ("[test==human]<<-->>if_1;", ast->toString().c_str()); } TEST_F(ParserTest, Repeat2) { - ASSERT_TRUE(Parse("[test != human] -->> {if_1;};")); - ASSERT_STREQ("[test!=human]-->>{if_1;};", ast->toString().c_str()); + ASSERT_TRUE(Parse("[test != human] <<-->> {if_1;};")); + ASSERT_STREQ("[test!=human]<<-->>{if_1;};", ast->toString().c_str()); - ASSERT_TRUE(Parse("{if_1;} <<-- [test != human];")); - ASSERT_STREQ("{if_1;}<<--[test!=human];", ast->toString().c_str()); + ASSERT_TRUE(Parse("{if_1;} <<-->> [test != human];")); + ASSERT_STREQ("{if_1;}<<-->>[test!=human];", ast->toString().c_str()); } TEST_F(ParserTest, Repeat3) { - ASSERT_TRUE(Parse("[test != human] -->> {if_1;if_2;then3;};")); - ASSERT_STREQ("[test!=human]-->>{if_1; if_2; then3;};", ast->toString().c_str()); + ASSERT_TRUE(Parse("[test != human] <<-->> {if_1;if_2;then3;};")); + ASSERT_STREQ("[test!=human]<<-->>{if_1; if_2; then3;};", ast->toString().c_str()); - ASSERT_TRUE(Parse("{if_1;if_2;then3;} <<-- [test != human];")); - ASSERT_STREQ("{if_1; if_2; then3;}<<--[test!=human];", ast->toString().c_str()); + ASSERT_TRUE(Parse("{if_1;if_2;then3;} <<-->> [test != human];")); + ASSERT_STREQ("{if_1; if_2; then3;}<<-->>[test!=human];", ast->toString().c_str()); } TEST_F(ParserTest, Repeat4) { - ASSERT_TRUE(Parse("[test()] -->> {if_1;if_2;then3;};")); - ASSERT_STREQ("[test()]-->>{if_1; if_2; then3;};", ast->toString().c_str()); + ASSERT_TRUE(Parse("[test()] <<-->> {if_1;if_2;then3;};")); + ASSERT_STREQ("[test()]<<-->>{if_1; if_2; then3;};", ast->toString().c_str()); - ASSERT_TRUE(Parse("[test()] -->> {if_1;if_2;then3;};")); - ASSERT_STREQ("[test()]-->>{if_1; if_2; then3;};", ast->toString().c_str()); + ASSERT_TRUE(Parse("[test()] <<-->> {if_1;if_2;then3;};")); + ASSERT_STREQ("[test()]<<-->>{if_1; if_2; then3;};", ast->toString().c_str()); - ASSERT_TRUE(Parse("{if_1;if_2;then3;} <<-- [test()];")); - ASSERT_STREQ("{if_1; if_2; then3;}<<--[test()];", ast->toString().c_str()); + ASSERT_TRUE(Parse("{if_1;if_2;then3;} <<-->> [test()];")); + ASSERT_STREQ("{if_1; if_2; then3;}<<-->>[test()];", ast->toString().c_str()); - ASSERT_TRUE(Parse("{if_1;if_2;then3;} <<-- [test()];")); - ASSERT_STREQ("{if_1; if_2; then3;}<<--[test()];", ast->toString().c_str()); + ASSERT_TRUE(Parse("{if_1;if_2;then3;} <<-->> [test()];")); + ASSERT_STREQ("{if_1; if_2; then3;}<<-->>[test()];", ast->toString().c_str()); } TEST_F(ParserTest, Repeat5) { - ASSERT_TRUE(Parse(" [ test! ]-->> {if_1;if_2;then3;};")); - ASSERT_STREQ("[test!]-->>{if_1; if_2; then3;};", ast->toString().c_str()); + ASSERT_TRUE(Parse(" [ test! ]<<-->> {if_1;if_2;then3;};")); + ASSERT_STREQ("[test!]<<-->>{if_1; if_2; then3;};", ast->toString().c_str()); - ASSERT_TRUE(Parse(" [test!] -->> {if_1;if_2;then3;};")); - ASSERT_STREQ("[test!]-->>{if_1; if_2; then3;};", ast->toString().c_str()); + ASSERT_TRUE(Parse(" [test!] <<-->> {if_1;if_2;then3;};")); + ASSERT_STREQ("[test!]<<-->>{if_1; if_2; then3;};", ast->toString().c_str()); - ASSERT_TRUE(Parse("{if_1;if_2;then3;}<<--[test!];")); - ASSERT_STREQ("{if_1; if_2; then3;}<<--[test!];", ast->toString().c_str()); + ASSERT_TRUE(Parse("{if_1;if_2;then3;}<<-->>[test!];")); + ASSERT_STREQ("{if_1; if_2; then3;}<<-->>[test!];", ast->toString().c_str()); - ASSERT_TRUE(Parse("{if_1;if_2;then3;}<<--[test!];")); - ASSERT_STREQ("{if_1; if_2; then3;}<<--[test!];", ast->toString().c_str()); + ASSERT_TRUE(Parse("{if_1;if_2;then3;}<<-->>[test!];")); + ASSERT_STREQ("{if_1; if_2; then3;}<<-->>[test!];", ast->toString().c_str()); } TEST_F(ParserTest, Repeat6) { - ASSERT_TRUE(Parse("[test!] -->> {if_1;if_2;then3;};")); - ASSERT_STREQ("[test!]-->>{if_1; if_2; then3;};", ast->toString().c_str()); + ASSERT_TRUE(Parse("[test!] <<-->> {if_1;if_2;then3;};")); + ASSERT_STREQ("[test!]<<-->>{if_1; if_2; then3;};", ast->toString().c_str()); } TEST_F(ParserTest, Repeat7) { - ASSERT_TRUE(Parse("[test[0].@field != $test()!!] -->> if_1;")); - ASSERT_STREQ("[test[0].@field!=$test()!!]-->>if_1;", ast->toString().c_str()); + ASSERT_TRUE(Parse("[test[0].@field != $test()!!] <<-->> if_1;")); + ASSERT_STREQ("[test[0].@field!=$test()!!]<<-->>if_1;", ast->toString().c_str()); } TEST_F(ParserTest, Range) { @@ -1608,16 +1608,16 @@ TEST_F(ParserTest, Range) { } TEST_F(ParserTest, Range1) { - ASSERT_TRUE(Parse("[i!] -->> call();")); - ASSERT_STREQ("[i!]-->>call();", ast->toString().c_str()); + ASSERT_TRUE(Parse("[i!] <<-->> call();")); + ASSERT_STREQ("[i!]<<-->>call();", ast->toString().c_str()); - ASSERT_TRUE(Parse("call() <<-- [i!];")); - ASSERT_STREQ("call()<<--[i!];", ast->toString().c_str()); + ASSERT_TRUE(Parse("call() <<-->> [i!];")); + ASSERT_STREQ("call()<<-->>[i!];", ast->toString().c_str()); } TEST_F(ParserTest, Range2) { - ASSERT_TRUE(Parse("[i()] -->> @error(\"Error\");")); - ASSERT_STREQ("[i()]-->>@error(\"Error\");", ast->toString().c_str()); + ASSERT_TRUE(Parse("[i()] <<-->> @error(\"Error\");")); + ASSERT_STREQ("[i()]<<-->>@error(\"Error\");", ast->toString().c_str()); } TEST_F(ParserTest, DISABLED_Follow0) { diff --git a/docs/syntax.md b/docs/syntax.md index 84d86d7a..5eb2671e 100644 --- a/docs/syntax.md +++ b/docs/syntax.md @@ -380,17 +380,17 @@ $value := (f1=1, f2="2",); ## Операторы циклов -Для указания операторов циклов используются управлялюящие **->>** или **-->>** (с двумя стрелками по направлению от проверки условия к телу цикла). И в заисимости от расположения условия и тела цикла, он может быть с предусловием (*while*) или постусловием (*do while*). Хотя пока эти синтаксические конструкции не "отлежались" и их можно считать временными из-за того, что их легко перепутать с условным оператором, и, возможно, имеет смысл заменить разные операторы цикла одной единственной конструкцией вида: **<-->** или **<<->>**, котрая сильнее отличается от оператора следования. +Для указания операторов циклов используются управлялюящие **<<->>** или **<<-->>** (с двумя стрелками по направлению от проверки условия к телу цикла). И в заисимости от расположения условия и тела цикла, он может быть с предусловием (*while*) или постусловием (*do while*). Хотя пока эти синтаксические конструкции не "отлежались" и их можно считать временными из-за того, что их легко перепутать с условным оператором, и, возможно, имеет смысл заменить разные операторы цикла одной единственной конструкцией вида: **<-->** или **<<->>**, котрая сильнее отличается от оператора следования. Но в настоящий момент циклы реализованы вот так: ``` -[условие while] ->> { +[условие while] <<->> { тело цикла while }; { тело цикла do while -} <<-- [условие do while]; +} <<-->> [условие do while]; ``` Реализация цикла foreach на примере суммирования всех элементов словаря (или одномерного тензора) @@ -398,7 +398,7 @@ $value := (f1=1, f2="2",); ``` summa := 0; dict := (1,2,3,4,5,); -[ dict ] -->> { # Условие цикла, пока есть данные +[ dict ] <<-->> { # Условие цикла, пока есть данные item, dict := ... dict; # Результат оператора раскрытия словаря - первый его элемент перемещается в item summa += item; # Вычисление суммы всех элементов словаря }; From 70cc083039c631d039fcd190dc500e89f11ce4d7 Mon Sep 17 00:00:00 2001 From: Aleksandr Ryabikov Date: Mon, 27 Jun 2022 20:02:38 +0300 Subject: [PATCH 07/31] =?UTF-8?q?=D0=9A=D0=BE=D0=BC=D0=BF=D0=B8=D0=BB?= =?UTF-8?q?=D1=8F=D1=86=D0=B8=D1=8F=20=D0=BF=D0=BE=D0=B4=20Windows=20(?= =?UTF-8?q?=D0=BD=D0=B5=20=D0=BB=D0=B8=D0=BD=D0=BA=D1=83=D0=B5=D1=82=D1=81?= =?UTF-8?q?=D1=8F,=20=D0=BD=D0=B5=D0=BA=D0=BE=D1=82=D0=BE=D1=80=D1=8B?= =?UTF-8?q?=D0=B5=20=D1=82=D0=B5=D1=81=D1=82=D1=8B=20=D0=BD=D0=B5=20=D0=BF?= =?UTF-8?q?=D1=80=D0=BE=D1=85=D0=BE=D0=B4=D1=8F=D1=82=20=D0=B8=D0=B7-?= =?UTF-8?q?=D0=B7=D0=B0=20=D0=BE=D1=82=D0=BB=D1=8E=D1=87=D0=B5=D0=BD=D0=BD?= =?UTF-8?q?=D0=BE=D0=B3=D0=BE=20=D0=BA=D0=BE=D0=B4=D0=B0=20=D0=BD=D0=B5=20?= =?UTF-8?q?=D0=BF=D0=BE=D0=B4=D0=B4=D0=B5=D1=80=D0=B6=D0=B8=D0=B2=D0=B0?= =?UTF-8?q?=D0=B5=D0=BC=D0=BE=D0=B3=D0=BE=20=D0=B2=20=D0=B2=D0=B8=D0=BD?= =?UTF-8?q?=D0=B4=D0=B5,=20=D0=BD=D0=BE=20=D1=81=D0=B0=D0=BC=20=D0=BA?= =?UTF-8?q?=D0=BE=D0=B4=20=D1=83=D0=B6=D0=B5=20=D1=81=D0=BE=D0=B1=D0=B8?= =?UTF-8?q?=D1=80=D0=B0=D0=B5=D1=82=D1=81=D1=8F=20!!!!!)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 6 + contrib/FlexLexer.h | 220 ++++++++ contrib/build.cmd | 3 + contrib/logger/logger.cpp | 2 +- contrib/logger/logger.h | 11 +- core/Makefile | 138 ++--- core/builtin.cpp | 4 +- core/context.cpp | 97 ++-- core/context.h | 12 +- core/fraction.h | 510 ++++++++--------- core/lexer.l | 4 +- core/nbproject/Makefile-Debug.mk | 12 +- core/nbproject/Makefile-GCOV.mk | 12 +- core/nbproject/Makefile-LLVM.mk | 12 +- core/nbproject/Makefile-LLVM_GCC.mk | 12 +- core/nbproject/Makefile-Release.mk | 12 +- core/nbproject/Makefile-UnitTest-Win32.mk | 304 ++++++++++ core/nbproject/Makefile-UnitTest-Win64.mk | 304 ++++++++++ core/nbproject/Makefile-UnitTest.mk | 12 +- core/nbproject/Makefile-UnitTest_LLVM.mk | 12 +- core/nbproject/Makefile-impl.mk | 2 +- core/nbproject/Makefile-variables.mk | 16 + core/nbproject/Package-UnitTest-Win32.bash | 76 +++ core/nbproject/Package-UnitTest-Win64.bash | 76 +++ core/nbproject/configurations.xml | 627 ++++++++++++++++++++- core/nbproject/project.xml | 8 + core/newlang.cpp | 204 +++---- core/newlang.h | 12 +- core/nlc.cpp | 20 + core/nlc.h | 73 +-- core/object.cpp | 382 +++++++------ core/object.h | 140 +++-- core/parser.cpp | 14 +- core/parser.h | 6 +- core/parser.y | 6 +- core/pch.cpp | 2 + core/pch.h | 18 +- core/term.h | 13 +- core/test/compiler_test.cpp | 4 +- core/test/eval_test.cpp | 26 +- core/test/lexer_test.cpp | 4 +- core/test/nlc_test.cpp | 22 +- core/test/object_test.cpp | 44 +- core/test/parser_test.cpp | 4 +- core/types.h | 24 +- core/variable.h | 34 +- core/warning_pop.h | 2 +- core/warning_push.h | 16 +- nlc-win/nlc.sln | 31 + nlc-win/nlc.vcxproj | 217 +++++++ 50 files changed, 2899 insertions(+), 923 deletions(-) create mode 100644 contrib/FlexLexer.h create mode 100644 contrib/build.cmd create mode 100644 core/nbproject/Makefile-UnitTest-Win32.mk create mode 100644 core/nbproject/Makefile-UnitTest-Win64.mk create mode 100644 core/nbproject/Package-UnitTest-Win32.bash create mode 100644 core/nbproject/Package-UnitTest-Win64.bash create mode 100644 core/pch.cpp create mode 100644 nlc-win/nlc.sln create mode 100644 nlc-win/nlc.vcxproj diff --git a/.gitignore b/.gitignore index c25360f9..9248be16 100644 --- a/.gitignore +++ b/.gitignore @@ -6,10 +6,16 @@ contrib/* **/CMakeCache.txt **/*.cmake **/newlang-unit-tests +**/newlang-unit-tests.exe **/nlc +**/nlc.exe **/DartConfiguration.tcl Makefile +**/*.i +**/*.vcxproj.filters +**/*.vcxproj.user + core/syntax_help.cpp core/version.* docs/syntax.txt diff --git a/contrib/FlexLexer.h b/contrib/FlexLexer.h new file mode 100644 index 00000000..c4dad2b1 --- /dev/null +++ b/contrib/FlexLexer.h @@ -0,0 +1,220 @@ +// -*-C++-*- +// FlexLexer.h -- define interfaces for lexical analyzer classes generated +// by flex + +// Copyright (c) 1993 The Regents of the University of California. +// All rights reserved. +// +// This code is derived from software contributed to Berkeley by +// Kent Williams and Tom Epperly. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: + +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. + +// Neither the name of the University nor the names of its contributors +// may be used to endorse or promote products derived from this software +// without specific prior written permission. + +// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR +// IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE. + +// This file defines FlexLexer, an abstract class which specifies the +// external interface provided to flex C++ lexer objects, and yyFlexLexer, +// which defines a particular lexer class. +// +// If you want to create multiple lexer classes, you use the -P flag +// to rename each yyFlexLexer to some other xxFlexLexer. You then +// include in your other sources once per lexer class: +// +// #undef yyFlexLexer +// #define yyFlexLexer xxFlexLexer +// #include +// +// #undef yyFlexLexer +// #define yyFlexLexer zzFlexLexer +// #include +// ... + +#ifndef __FLEX_LEXER_H +// Never included before - need to define base class. +#define __FLEX_LEXER_H + +#include + +extern "C++" { + +struct yy_buffer_state; +typedef int yy_state_type; + +class FlexLexer +{ +public: + virtual ~FlexLexer() { } + + const char* YYText() const { return yytext; } + int YYLeng() const { return yyleng; } + + virtual void + yy_switch_to_buffer( yy_buffer_state* new_buffer ) = 0; + virtual yy_buffer_state* yy_create_buffer( std::istream* s, int size ) = 0; + virtual yy_buffer_state* yy_create_buffer( std::istream& s, int size ) = 0; + virtual void yy_delete_buffer( yy_buffer_state* b ) = 0; + virtual void yyrestart( std::istream* s ) = 0; + virtual void yyrestart( std::istream& s ) = 0; + + virtual int yylex() = 0; + + // Call yylex with new input/output sources. + int yylex( std::istream& new_in, std::ostream& new_out ) + { + switch_streams( new_in, new_out ); + return yylex(); + } + + int yylex( std::istream* new_in, std::ostream* new_out = 0) + { + switch_streams( new_in, new_out ); + return yylex(); + } + + // Switch to new input/output streams. A nil stream pointer + // indicates "keep the current one". + virtual void switch_streams( std::istream* new_in, + std::ostream* new_out ) = 0; + virtual void switch_streams( std::istream& new_in, + std::ostream& new_out ) = 0; + + int lineno() const { return yylineno; } + + int debug() const { return yy_flex_debug; } + void set_debug( int flag ) { yy_flex_debug = flag; } + +protected: + char* yytext; + int yyleng; + int yylineno; // only maintained if you use %option yylineno + int yy_flex_debug; // only has effect with -d or "%option debug" +}; + +} +#endif // FLEXLEXER_H + +#if defined(yyFlexLexer) || ! defined(yyFlexLexerOnce) +// Either this is the first time through (yyFlexLexerOnce not defined), +// or this is a repeated include to define a different flavor of +// yyFlexLexer, as discussed in the flex manual. +# define yyFlexLexerOnce + +extern "C++" { + +class yyFlexLexer : public FlexLexer { +public: + // arg_yyin and arg_yyout default to the cin and cout, but we + // only make that assignment when initializing in yylex(). + yyFlexLexer( std::istream& arg_yyin, std::ostream& arg_yyout ); + yyFlexLexer( std::istream* arg_yyin = 0, std::ostream* arg_yyout = 0 ); +private: + void ctor_common(); + +public: + + virtual ~yyFlexLexer(); + + void yy_switch_to_buffer( yy_buffer_state* new_buffer ); + yy_buffer_state* yy_create_buffer( std::istream* s, int size ); + yy_buffer_state* yy_create_buffer( std::istream& s, int size ); + void yy_delete_buffer( yy_buffer_state* b ); + void yyrestart( std::istream* s ); + void yyrestart( std::istream& s ); + + void yypush_buffer_state( yy_buffer_state* new_buffer ); + void yypop_buffer_state(); + + virtual int yylex(); + virtual void switch_streams( std::istream& new_in, std::ostream& new_out ); + virtual void switch_streams( std::istream* new_in = 0, std::ostream* new_out = 0 ); + virtual int yywrap(); + +protected: + virtual int LexerInput( char* buf, int max_size ); + virtual void LexerOutput( const char* buf, int size ); + virtual void LexerError( const char* msg ); + + void yyunput( int c, char* buf_ptr ); + int yyinput(); + + void yy_load_buffer_state(); + void yy_init_buffer( yy_buffer_state* b, std::istream& s ); + void yy_flush_buffer( yy_buffer_state* b ); + + int yy_start_stack_ptr; + int yy_start_stack_depth; + int* yy_start_stack; + + void yy_push_state( int new_state ); + void yy_pop_state(); + int yy_top_state(); + + yy_state_type yy_get_previous_state(); + yy_state_type yy_try_NUL_trans( yy_state_type current_state ); + int yy_get_next_buffer(); + + std::istream yyin; // input source for default LexerInput + std::ostream yyout; // output sink for default LexerOutput + + // yy_hold_char holds the character lost when yytext is formed. + char yy_hold_char; + + // Number of characters read into yy_ch_buf. + int yy_n_chars; + + // Points to current character in buffer. + char* yy_c_buf_p; + + int yy_init; // whether we need to initialize + int yy_start; // start state number + + // Flag which is used to allow yywrap()'s to do buffer switches + // instead of setting up a fresh yyin. A bit of a hack ... + int yy_did_buffer_switch_on_eof; + + + size_t yy_buffer_stack_top; /**< index of top of stack. */ + size_t yy_buffer_stack_max; /**< capacity of stack. */ + yy_buffer_state ** yy_buffer_stack; /**< Stack as an array. */ + void yyensure_buffer_stack(void); + + // The following are not always needed, but may be depending + // on use of certain flex features (like REJECT or yymore()). + + yy_state_type yy_last_accepting_state; + char* yy_last_accepting_cpos; + + yy_state_type* yy_state_buf; + yy_state_type* yy_state_ptr; + + char* yy_full_match; + int* yy_full_state; + int yy_full_lp; + + int yy_lp; + int yy_looking_for_trail_begin; + + int yy_more_flag; + int yy_more_len; + int yy_more_offset; + int yy_prev_more_offset; +}; + +} + +#endif // yyFlexLexer || ! yyFlexLexerOnce diff --git a/contrib/build.cmd b/contrib/build.cmd new file mode 100644 index 00000000..b4e2984e --- /dev/null +++ b/contrib/build.cmd @@ -0,0 +1,3 @@ + +C:\msys64\usr\bin\bash -lc "cd /z/NewLang/newlang/contrib/libffi && ./configure --build=x86_64-w64-mingw32 --host=x86_64-w64-mingw32 --prefix=`pwd`/win64 --enable-static --disable-shared --disable-docs && make && make install" + diff --git a/contrib/logger/logger.cpp b/contrib/logger/logger.cpp index 283bed06..469dfe3b 100644 --- a/contrib/logger/logger.cpp +++ b/contrib/logger/logger.cpp @@ -1,4 +1,4 @@ -#include +//#include #include #include diff --git a/contrib/logger/logger.h b/contrib/logger/logger.h index bc44d57d..d7163ab3 100644 --- a/contrib/logger/logger.h +++ b/contrib/logger/logger.h @@ -5,11 +5,14 @@ #include -#include -#include #include #include +#ifndef _MSC_VER +#include +#include +#endif + #define LOG_EXCEPT_LEVEL(EXCEPT, LEVEL, PREFIX, ...) throw EXCEPT(std::string(LOG_MAKE(LEVEL, PREFIX, ##__VA_ARGS__))) #define LOG_EXCEPT(EXCEPT, ...) LOG_EXCEPT_LEVEL(EXCEPT, LOG_LEVEL_ERROR, "E:", ##__VA_ARGS__) #define LOG_CALLSTACK(EXCEPT_TYPE, ...) LOG_PRINT_CALLSTACK(); LOG_EXCEPT(EXCEPT_TYPE, ##__VA_ARGS__) @@ -40,7 +43,7 @@ #ifndef ASSERT -#if defined(__cplusplus) && defined(__cpp_exceptions) +#if defined(__cplusplus) && defined(__cpp_exceptions) && defined(__unix__) #include // Выброс исключения на PC для тестирования нештатной ситуации @@ -89,6 +92,8 @@ #if defined(__cplusplus) + +#include #include #include "mcucpp/static_assert.h" diff --git a/core/Makefile b/core/Makefile index fece1dae..2daa2c6a 100644 --- a/core/Makefile +++ b/core/Makefile @@ -68,75 +68,75 @@ build: .build-post .build-pre: # Add your pre 'build' code here... - @if [ ! -d "temp" ]; then \ - @mkdir temp; \ - fi - pandoc -t plain ../docs/syntax.md > ../docs/syntax.txt - ../contrib/text2cpp/output/bin/text2cpp ../docs/syntax.txt syntax_help.cpp newlang_syntax_help c - - - @if [ "$(GIT_TAG_VERSION)" != "v$(VERSION_MAJOR).$(VERSION_MINOR).$(VERSION_PATCH)" ]; then \ - echo "Git TAG $(GIT_TAG_VERSION) differ version v$(VERSION_MAJOR).$(VERSION_MINOR).$(VERSION_PATCH)"; \ - exit 1; \ - fi - @if [ -z $(GIT_SHORT_HASH) ]; then \ - echo Undefined version for build; \ - exit 1; \ - fi - @if [ -f $(VERSION_HEADER) ]; then \ - rm $(VERSION_HEADER); \ - fi - - @echo "/** @file $(VERSION_HEADER)" > $(VERSION_HEADER) - @echo "* Auto generate file for identification current build" >> $(VERSION_HEADER) - @echo "* Date build $(DATE_BUILD)" >> $(VERSION_HEADER) - @echo "*/" >> $(VERSION_HEADER) - @echo "" >> $(VERSION_HEADER) - - @echo "#include " >> $(VERSION_HEADER) - - @echo "extern const uint8_t VERSION_MAJOR;" >> $(VERSION_HEADER) - @echo "extern const uint8_t VERSION_MINOR;" >> $(VERSION_HEADER) - @echo "extern const uint8_t VERSION_PATCH;" >> $(VERSION_HEADER) - @echo "extern const uint16_t VERSION_BUILD;" >> $(VERSION_HEADER) - @echo "" >> $(VERSION_HEADER) - - @echo "#define VERSION ($(VERSION_MAJOR) << 4 | $(VERSION_MINOR))" >> $(VERSION_HEADER) - @echo "#define VERSION_GIT_SOURCE \"$(GIT_SOURCE_ID)\"" >> $(VERSION_HEADER) - @echo "#define VERSION_DATE_BUILD_STR \"$(DATE_BUILD)\"" >> $(VERSION_HEADER) - @echo "#define VERSION_SOURCE_FULL_ID \"$(GIT_SOURCE_ID) $(DATE_BUILD)\"" >> $(VERSION_HEADER) - @echo "" >> $(VERSION_HEADER) - - @echo "extern const char * GIT_SOURCE;" >> $(VERSION_HEADER) - @echo "extern const char * DATE_BUILD_STR;" >> $(VERSION_HEADER) - @echo "extern const char * SOURCE_FULL_ID; " >> $(VERSION_HEADER) - @echo "" >> $(VERSION_HEADER) - - @if [ -f $(VERSION_FILE) ]; then \ - rm $(VERSION_FILE); \ - fi - - @echo "/** @file $(VERSION_FILE)" > $(VERSION_FILE) - @echo "* Auto generate file for identification current build" >> $(VERSION_FILE) - @echo "* Date build $(DATE_BUILD)" >> $(VERSION_FILE) - @echo "*/" >> $(VERSION_FILE) - @echo "" >> $(VERSION_FILE) - - @echo "#include " >> $(VERSION_FILE) - @echo "#include " >> $(VERSION_FILE) - @echo "" >> $(VERSION_FILE) - - @echo "const uint8_t VERSION_MAJOR=$(VERSION_MAJOR);" >> $(VERSION_FILE) - @echo "const uint8_t VERSION_MINOR=$(VERSION_MINOR);" >> $(VERSION_FILE) - @echo "const uint8_t VERSION_PATCH=$(VERSION_PATCH);" >> $(VERSION_FILE) - @echo "" >> $(VERSION_FILE) - - @echo "const char * GIT_SOURCE = VERSION_GIT_SOURCE;" >> $(VERSION_FILE) - @echo "const char * DATE_BUILD_STR = VERSION_DATE_BUILD_STR;" >> $(VERSION_FILE) - @echo "const char * SOURCE_FULL_ID = VERSION_SOURCE_FULL_ID;" >> $(VERSION_FILE) - @echo "" >> $(VERSION_FILE) - - @echo Mark version $(GIT_SOURCE_ID) $(DATE_BUILD) +# @if [ ! -d "temp" ]; then \ +# @mkdir temp; \ +# fi +# pandoc -t plain ../docs/syntax.md > ../docs/syntax.txt +# ../contrib/text2cpp/output/bin/text2cpp ../docs/syntax.txt syntax_help.cpp newlang_syntax_help c +# +# +# @if [ "$(GIT_TAG_VERSION)" != "v$(VERSION_MAJOR).$(VERSION_MINOR).$(VERSION_PATCH)" ]; then \ +# echo "Git TAG $(GIT_TAG_VERSION) differ version v$(VERSION_MAJOR).$(VERSION_MINOR).$(VERSION_PATCH)"; \ +# exit 1; \ +# fi +# @if [ -z $(GIT_SHORT_HASH) ]; then \ +# echo Undefined version for build; \ +# exit 1; \ +# fi +# @if [ -f $(VERSION_HEADER) ]; then \ +# rm $(VERSION_HEADER); \ +# fi +# +# @echo "/** @file $(VERSION_HEADER)" > $(VERSION_HEADER) +# @echo "* Auto generate file for identification current build" >> $(VERSION_HEADER) +# @echo "* Date build $(DATE_BUILD)" >> $(VERSION_HEADER) +# @echo "*/" >> $(VERSION_HEADER) +# @echo "" >> $(VERSION_HEADER) +# +# @echo "#include " >> $(VERSION_HEADER) +# +# @echo "extern const uint8_t VERSION_MAJOR;" >> $(VERSION_HEADER) +# @echo "extern const uint8_t VERSION_MINOR;" >> $(VERSION_HEADER) +# @echo "extern const uint8_t VERSION_PATCH;" >> $(VERSION_HEADER) +# @echo "extern const uint16_t VERSION_BUILD;" >> $(VERSION_HEADER) +# @echo "" >> $(VERSION_HEADER) +# +# @echo "#define VERSION ($(VERSION_MAJOR) << 4 | $(VERSION_MINOR))" >> $(VERSION_HEADER) +# @echo "#define VERSION_GIT_SOURCE \"$(GIT_SOURCE_ID)\"" >> $(VERSION_HEADER) +# @echo "#define VERSION_DATE_BUILD_STR \"$(DATE_BUILD)\"" >> $(VERSION_HEADER) +# @echo "#define VERSION_SOURCE_FULL_ID \"$(GIT_SOURCE_ID) $(DATE_BUILD)\"" >> $(VERSION_HEADER) +# @echo "" >> $(VERSION_HEADER) +# +# @echo "extern const char * GIT_SOURCE;" >> $(VERSION_HEADER) +# @echo "extern const char * DATE_BUILD_STR;" >> $(VERSION_HEADER) +# @echo "extern const char * SOURCE_FULL_ID; " >> $(VERSION_HEADER) +# @echo "" >> $(VERSION_HEADER) +# +# @if [ -f $(VERSION_FILE) ]; then \ +# rm $(VERSION_FILE); \ +# fi +# +# @echo "/** @file $(VERSION_FILE)" > $(VERSION_FILE) +# @echo "* Auto generate file for identification current build" >> $(VERSION_FILE) +# @echo "* Date build $(DATE_BUILD)" >> $(VERSION_FILE) +# @echo "*/" >> $(VERSION_FILE) +# @echo "" >> $(VERSION_FILE) +# +# @echo "#include " >> $(VERSION_FILE) +# @echo "#include " >> $(VERSION_FILE) +# @echo "" >> $(VERSION_FILE) +# +# @echo "const uint8_t VERSION_MAJOR=$(VERSION_MAJOR);" >> $(VERSION_FILE) +# @echo "const uint8_t VERSION_MINOR=$(VERSION_MINOR);" >> $(VERSION_FILE) +# @echo "const uint8_t VERSION_PATCH=$(VERSION_PATCH);" >> $(VERSION_FILE) +# @echo "" >> $(VERSION_FILE) +# +# @echo "const char * GIT_SOURCE = VERSION_GIT_SOURCE;" >> $(VERSION_FILE) +# @echo "const char * DATE_BUILD_STR = VERSION_DATE_BUILD_STR;" >> $(VERSION_FILE) +# @echo "const char * SOURCE_FULL_ID = VERSION_SOURCE_FULL_ID;" >> $(VERSION_FILE) +# @echo "" >> $(VERSION_FILE) +# +# @echo Mark version $(GIT_SOURCE_ID) $(DATE_BUILD) .build-post: .build-impl diff --git a/core/builtin.cpp b/core/builtin.cpp index 32351099..0037b723 100644 --- a/core/builtin.cpp +++ b/core/builtin.cpp @@ -17,7 +17,7 @@ namespace newlang { LOG_RUNTIME("Empty argument list parameter!"); } ObjPtr out = in.at(1).second; - for (size_t i = 2; i < in.size(); i++) { + for (int i = 2; i < in.size(); i++) { if(*in.at(i).second < out) { out = in.at(i).second; } @@ -30,7 +30,7 @@ namespace newlang { LOG_RUNTIME("Empty argument list parameter!"); } ObjPtr out = in.at(1).second; - for (size_t i = 2; i < in.size(); i++) { + for (int i = 2; i < in.size(); i++) { if(*in.at(i).second > out) { out = in.at(i).second; } diff --git a/core/context.cpp b/core/context.cpp index 54cc9113..917a2f20 100644 --- a/core/context.cpp +++ b/core/context.cpp @@ -49,16 +49,16 @@ Context::Context(RuntimePtr global) { if(Context::m_funcs.empty()) { - VERIFY(CreateBuiltin("min(arg, ...)", (void *) &min, ObjType::TRANSPARENT)); - VERIFY(CreateBuiltin("мин(arg, ...)", (void *) &min, ObjType::TRANSPARENT)); - VERIFY(CreateBuiltin("max(arg, ...)", (void *) &max, ObjType::TRANSPARENT)); - VERIFY(CreateBuiltin("макс(arg, ...)", (void *) &max, ObjType::TRANSPARENT)); + VERIFY(CreateBuiltin("min(arg, ...)", (void *) &min, ObjType::PureFunc)); + VERIFY(CreateBuiltin("мин(arg, ...)", (void *) &min, ObjType::PureFunc)); + VERIFY(CreateBuiltin("max(arg, ...)", (void *) &max, ObjType::PureFunc)); + VERIFY(CreateBuiltin("макс(arg, ...)", (void *) &max, ObjType::PureFunc)); - VERIFY(CreateBuiltin("import(arg, module='', lazzy=0)", (void *) &import, ObjType::FUNCTION)); + VERIFY(CreateBuiltin("import(arg, module='', lazzy=0)", (void *) &import, ObjType::Function)); - VERIFY(CreateBuiltin("eval(string:String)", (void *) &eval, ObjType::FUNCTION)); - VERIFY(CreateBuiltin("exec(filename:String)", (void *) &exec, ObjType::FUNCTION)); - VERIFY(CreateBuiltin("help(...)", (void *) &help, ObjType::TRANSPARENT)); + VERIFY(CreateBuiltin("eval(string:String)", (void *) &eval, ObjType::Function)); + VERIFY(CreateBuiltin("exec(filename:String)", (void *) &exec, ObjType::Function)); + VERIFY(CreateBuiltin("help(...)", (void *) &help, ObjType::PureFunc)); } @@ -226,9 +226,12 @@ ObjPtr Context::RegisterObject(ObjPtr var) { return var; } +#ifndef _MSC_VER + void newlang::NewLangSignalHandler(int signal) { throw Interrupt("Signal SIGABRT received", Interrupt::Abort); } +#endif //#include "StdCapture.h" @@ -238,7 +241,9 @@ ObjPtr Context::ExecStr(Context *ctx, TermPtr term, Obj *args, bool int_catch) { // // Capture.BeginCapture(); +#ifndef _MSC_VER auto previous_handler = signal(SIGABRT, &NewLangSignalHandler); +#endif try { switch(term->m_id) { @@ -256,7 +261,10 @@ ObjPtr Context::ExecStr(Context *ctx, TermPtr term, Obj *args, bool int_catch) { } } catch (Interrupt &obj) { +#ifndef _MSC_VER signal(SIGABRT, previous_handler); +#endif + ASSERT(obj.m_obj); if(int_catch && obj.m_obj->getType() == ObjType::Return) { @@ -271,7 +279,10 @@ ObjPtr Context::ExecStr(Context *ctx, TermPtr term, Obj *args, bool int_catch) { throw; // Пробросить прерывание дальше } + +#ifndef _MSC_VER signal(SIGABRT, previous_handler); +#endif return Obj::CreateNone(); } @@ -561,9 +572,9 @@ ObjPtr Context::CREATE_OR_ASSIGN(Context *ctx, const TermPtr &term, Obj *local_v } } } - if(list_obj.size() - 1 < rval->size()) { + if(static_cast (list_obj.size()) - 1 < rval->size()) { // Удалить первые элементы - rval->resize_(-(rval->size() - (list_obj.size() - 1)), nullptr); + rval->resize_(-(rval->size() - (static_cast (list_obj.size()) - 1)), nullptr); } else { rval->resize_(0, nullptr); } @@ -596,7 +607,7 @@ ObjPtr Context::CREATE_OR_ASSIGN(Context *ctx, const TermPtr &term, Obj *local_v // Skip } else { list_obj[i]->SetValue_(rval); - if(list_obj[i]->m_var_type_current == ObjType::FUNCTION && (rval->m_var_type_current == ObjType::BLOCK || rval->m_var_type_current == ObjType::BLOCK_TRY)) { + if(list_obj[i]->m_var_type_current == ObjType::Function && (rval->m_var_type_current == ObjType::BLOCK || rval->m_var_type_current == ObjType::BLOCK_TRY)) { list_obj[i]->m_var_type_current = ObjType::EVAL_FUNCTION; } result = list_obj[i]; @@ -628,7 +639,7 @@ ObjPtr Context::eval_APPEND(Context *ctx, const TermPtr &term, Obj * args) { } ObjPtr Context::eval_FUNCTION(Context *ctx, const TermPtr &term, Obj * args) { - ASSERT(term && (term->getTermID() == TermID::FUNCTION || term->getTermID() == TermID::TRANSPARENT || + ASSERT(term && (term->getTermID() == TermID::FUNCTION || term->getTermID() == TermID::PUREFUNC || term->getTermID() == TermID::SIMPLE_AND || term->getTermID() == TermID::SIMPLE_OR || term->getTermID() == TermID::SIMPLE_XOR)); ASSERT(term->Left()); @@ -653,7 +664,7 @@ ObjPtr Context::eval_FUNCTION(Context *ctx, const TermPtr &term, Obj * args) { } else { if(term->getTermID() == TermID::FUNCTION) { lval->m_var_type_current = ObjType::EVAL_FUNCTION; - } else if(term->getTermID() == TermID::TRANSPARENT) { + } else if(term->getTermID() == TermID::PUREFUNC) { lval->m_var_type_current = ObjType::SimplePureFunc; } else if(term->getTermID() == TermID::SIMPLE_AND) { lval->m_var_type_current = ObjType::SimplePureAND; @@ -688,7 +699,7 @@ ObjPtr Context::eval_SIMPLE_XOR(Context *ctx, const TermPtr &term, Obj * args) { return eval_FUNCTION(ctx, term, args); } -ObjPtr Context::eval_TRANSPARENT(Context *ctx, const TermPtr &term, Obj * args) { +ObjPtr Context::eval_PUREFUNC(Context *ctx, const TermPtr &term, Obj * args) { return eval_FUNCTION(ctx, term, args); } @@ -815,9 +826,9 @@ ObjPtr Context::eval_FOLLOW(Context *ctx, const TermPtr &term, Obj * args) { bool Context::MatchCompare(Obj &match, ObjPtr &value, MatchMode mode, Context *ctx) { switch(mode) { - case MatchMode::EQUAL: + case MatchMode::MatchEqual: return match.op_equal(value); - case MatchMode::STRICT: + case MatchMode::MatchStrict: return match.op_accurate(value); case MatchMode::TYPE_NAME: return match.op_class_test(value, ctx); @@ -865,9 +876,9 @@ ObjPtr Context::eval_MATCHING(Context *ctx, const TermPtr &term, Obj * args) { MatchMode mode; if(term->m_text.compare("==>") == 0) { - mode = MatchMode::EQUAL; + mode = MatchMode::MatchEqual; } else if(term->m_text.compare("===>") == 0) { - mode = MatchMode::STRICT; + mode = MatchMode::MatchStrict; } else if(term->m_text.compare("~>") == 0) { mode = MatchMode::TYPE_NAME; } else if(term->m_text.compare("~~>") == 0) { @@ -1417,7 +1428,7 @@ ObjPtr Context::CreateNative(const char *proto, const char *module, bool lazzy, try { // Термин или термин + тип парсятся без ошибок term = Parser::ParseString(proto, &m_macros); - } catch (std::exception &e) { + } catch (std::exception &) { try { std::string func(proto); func += ":={}"; @@ -1503,9 +1514,17 @@ void *RunTime::GetProcAddress(const char *name, const char *module) { return nullptr; } +#ifndef _MSC_VER return dlsym(m_modules[module]->GetHandle(), name); +#else + return nullptr; +#endif } +#ifndef _MSC_VER return dlsym(nullptr, name); +#else + return nullptr; +#endif } ObjPtr Context::FindSessionTerm(const char *name, bool current_only) { @@ -1631,7 +1650,7 @@ ObjPtr Context::CreateLVal(Context *ctx, TermPtr term, Obj * args) { TermPtr type = term->GetType(); if(term->IsFunction() || term->getTermID() == TermID::CALL) { - result->m_var_type_current = ObjType::FUNCTION; + result->m_var_type_current = ObjType::Function; result->m_var_type_fixed = result->m_var_type_current; *const_cast (&result->m_func_proto) = term; } else if(type) { @@ -1672,8 +1691,8 @@ ObjPtr Context::CreateRVal(Context *ctx, const char *source, Obj * local_vars, b void Context::ItemTensorEval_(torch::Tensor &tensor, c10::IntArrayRef shape, std::vector &ind, const int64_t pos, ObjPtr &obj, ObjPtr & args) { - ASSERT(pos < ind.size()); - if(pos + 1 < ind.size()) { + ASSERT(pos < static_cast (ind.size())); + if(pos + 1 < static_cast (ind.size())) { for (ind[pos] = 0; ind[pos].integer() < shape[pos]; ind[pos] = ind[pos].integer() + 1) { ItemTensorEval_(tensor, shape, ind, pos + 1, obj, args); } @@ -1719,32 +1738,32 @@ void Context::ItemTensorEval(torch::Tensor &self, ObjPtr obj, ObjPtr args) { case ObjType::Char: ptr_char = self.data_ptr(); ASSERT(ptr_char); - *ptr_char = obj->Call(this)->GetValueAsInteger(); //, args)->GetValueAsInteger(); + *ptr_char = static_cast (obj->Call(this)->GetValueAsInteger()); return; case ObjType::Short: ptr_short = self.data_ptr(); ASSERT(ptr_short); - *ptr_short = obj->Call(this)->GetValueAsInteger(); // args + *ptr_short = static_cast (obj->Call(this)->GetValueAsInteger()); return; case ObjType::Int: ptr_int = self.data_ptr(); ASSERT(ptr_int); - *ptr_int = obj->Call(this)->GetValueAsInteger(); // args + *ptr_int = static_cast (obj->Call(this)->GetValueAsInteger()); return; case ObjType::Long: ptr_long = self.data_ptr(); ASSERT(ptr_long); - *ptr_long = obj->Call(this)->GetValueAsInteger(); // args + *ptr_long = static_cast (obj->Call(this)->GetValueAsInteger()); return; case ObjType::Float: ptr_float = self.data_ptr(); ASSERT(ptr_float); - *ptr_float = obj->Call(this)->GetValueAsNumber(); // args + *ptr_float = static_cast (obj->Call(this)->GetValueAsNumber()); return; case ObjType::Double: ptr_double = self.data_ptr(); ASSERT(ptr_double); - *ptr_double = obj->Call(this)->GetValueAsNumber(); // args + *ptr_double = static_cast (obj->Call(this)->GetValueAsNumber()); return; } @@ -1837,9 +1856,9 @@ std::vector Context::MakeIndex(Context *ctx, TermPtr term, Obj * local_va } } else if(temp->is_range()) { - int64_t start = temp->at("start")->GetValueAsInteger(); - int64_t stop = temp->at("stop")->GetValueAsInteger(); - int64_t step = temp->at("step")->GetValueAsInteger(); + int64_t start = temp->at("start").second->GetValueAsInteger(); + int64_t stop = temp->at("stop").second->GetValueAsInteger(); + int64_t step = temp->at("step").second->GetValueAsInteger(); result.push_back(Index(at::indexing::Slice(start, stop, step))); } else { @@ -1868,9 +1887,7 @@ ObjPtr Context::CreateRVal(Context *ctx, TermPtr term, Obj * local_vars, bool in result = Obj::CreateNone(); result->m_is_reference = term->m_is_ref; - char *ptr; int64_t val_int; - int64_t count; double val_dbl; ObjType type; bool has_error; @@ -1957,7 +1974,7 @@ ObjPtr Context::CreateRVal(Context *ctx, TermPtr term, Obj * local_vars, bool in } else if(term->m_text.compare("$") == 0) { result->m_var_type_current = ObjType::Dictionary; result->m_var_name = "$"; - size_t pos = 0; + int pos = 0; while(ctx && pos < ctx->size()) { if(ctx->at(pos).second.lock()) { result->push_back(Obj::CreateString(ctx->at(pos).first)); @@ -1975,7 +1992,7 @@ ObjPtr Context::CreateRVal(Context *ctx, TermPtr term, Obj * local_vars, bool in if(isLocal(term->m_text.c_str())) { full_name = MakeName(term->m_text); - return local_vars->at(full_name); + return local_vars->at(full_name).second; } else { result = ctx->GetTerm(term->GetFullName().c_str(), term->isRef()); @@ -1995,7 +2012,7 @@ ObjPtr Context::CreateRVal(Context *ctx, TermPtr term, Obj * local_vars, bool in field = term->m_right; if(field && field->getTermID() == TermID::FIELD) { while(field) { - result = result->at(field->getText()); + result = result->at(field->getText()).second; field = field->m_right; ASSERT(!field); // Нужно выполнять, а не просто получать значение поля } @@ -2032,7 +2049,7 @@ ObjPtr Context::CreateRVal(Context *ctx, TermPtr term, Obj * local_vars, bool in } args = Obj::CreateDict(); - for (size_t i = 0; i < term->size(); i++) { + for (int i = 0; i < term->size(); i++) { if((*term)[i]->GetTokenID() == TermID::FILLING) { @@ -2137,7 +2154,7 @@ ObjPtr Context::CreateRVal(Context *ctx, TermPtr term, Obj * local_vars, bool in } args = Obj::CreateDict(); - for (size_t i = 0; i < term->size(); i++) { + for (int i = 0; i < term->size(); i++) { if(term->name(i).empty()) { args->push_back(CreateRVal(ctx, (*term)[i], local_vars)); } else { @@ -2156,7 +2173,7 @@ ObjPtr Context::CreateRVal(Context *ctx, TermPtr term, Obj * local_vars, bool in case TermID::TENSOR: case TermID::DICT: result->m_var_type_current = ObjType::Dictionary; - for (size_t i = 0; i < term->size(); i++) { + for (int i = 0; i < term->size(); i++) { if(term->name(i).empty()) { result->push_back(CreateRVal(ctx, (*term)[i], local_vars)); } else { @@ -2203,7 +2220,7 @@ ObjPtr Context::CreateRVal(Context *ctx, TermPtr term, Obj * local_vars, bool in case TermID::RANGE: - for (size_t i = 0; i < term->size(); i++) { + for (int i = 0; i < term->size(); i++) { ASSERT(!term->name(i).empty()); result->push_back(CreateRVal(ctx, (*term)[i], local_vars), term->name(i).c_str()); } diff --git a/core/context.h b/core/context.h index 37dcd6aa..da2186fa 100644 --- a/core/context.h +++ b/core/context.h @@ -305,11 +305,11 @@ namespace newlang { return find.empty() || (pos && find.size() == pos); } - std::vector SelectPredict(std::wstring_view wstart, size_t overage_count = 0) { + std::vector SelectPredict(std::wstring wstart, size_t overage_count = 0) { return SelectPredict(utf8_encode(wstart), overage_count); } - std::vector SelectPredict(std::string_view start, size_t overage_count = 0) { + std::vector SelectPredict(std::string start, size_t overage_count = 0) { std::vector result; @@ -321,11 +321,11 @@ namespace newlang { if (isGlobal(start)) { prefix = start[0]; - start.remove_prefix(1); + start = start.substr(1); find_global = true; } else if (isLocal(start)) { prefix = start[0]; - start.remove_prefix(1); + start = start.substr(1); find_local = true; } else if (isType(start)) { // prefix = start[0]; @@ -488,8 +488,8 @@ namespace newlang { } enum class MatchMode { - EQUAL, - STRICT, + MatchEqual, + MatchStrict, TYPE_NAME, TYPE_EQUAL, TYPE_STRICT, diff --git a/core/fraction.h b/core/fraction.h index 8a6a865f..e5384126 100644 --- a/core/fraction.h +++ b/core/fraction.h @@ -1,261 +1,261 @@ #ifndef FRACTION_H #define FRACTION_H -#include -#include - -#include -#include - -class BigNum { - SCOPE(private) : - BIGNUM *m_value; - BN_CTX *m_ctx; - bool m_is_init; -public: - -#define CHECK_INIT(value) if (!(value)->m_is_init) { LOG_RUNTIME("Fail init!!!"); } - - BigNum() : m_value(nullptr), m_ctx(nullptr) { - m_is_init = false; - m_value = BN_new(); - m_ctx = BN_CTX_new(); - } - - BigNum(std::string str) { - SetFromString(str); - } - - virtual ~BigNum() { - if (m_value) { - BN_free(m_value); - m_value = nullptr; - } - if (m_ctx) { - BN_CTX_free(m_ctx); - m_ctx = nullptr; - } - } - - int64_t GetAsInteger() { - CHECK_INIT(this); - - int64_t result = BN_get_word(m_value); - if (result == ~0) { - LOG_RUNTIME("Bignum integer overflow!"); - } - - if (BN_is_negative(m_value)) { - result = -result; - } - return result; - } - - double GetAsNumber() { - CHECK_INIT(this); - //@todo Refactor convert big integer to double! - return GetAsInteger(); - } - - inline bool SetFromString(const std::string str) { - m_is_init = true; - return BN_dec2bn(&m_value, str.c_str()); - } - - std::string GetAsString() { - CHECK_INIT(this); - char * number_str = BN_bn2dec(m_value); - std::string result(number_str); - OPENSSL_free(number_str); - return result; - } - - BigNum &add(BigNum &val) { - CHECK_INIT(this); - CHECK_INIT(&val); - - BigNum temp; - if (!BN_add(temp.m_value, m_value, val.m_value)) { - LOG_RUNTIME("Bignum operation fail!"); - } - std::swap(temp.m_value, m_value); - return *this; - } - - BigNum &sub(BigNum &val) { - CHECK_INIT(this); - CHECK_INIT(&val); - - BigNum temp; - if (!BN_sub(temp.m_value, m_value, val.m_value)) { - LOG_RUNTIME("Bignum operation fail!"); - } - std::swap(temp.m_value, m_value); - return *this; - } - - BigNum &mul(BigNum &val) { - CHECK_INIT(this); - CHECK_INIT(&val); - - BigNum temp; - if (!BN_mul(temp.m_value, m_value, val.m_value, m_ctx)) { - LOG_RUNTIME("Bignum operation fail!"); - } - std::swap(temp.m_value, m_value); - return *this; - } - - BigNum &div(BigNum &val, BigNum &rem) { - CHECK_INIT(this); - CHECK_INIT(&val); - - BigNum dv; - BigNum rm; - if (!BN_div(dv.m_value, rm.m_value, m_value, val.m_value, m_ctx)) { - LOG_RUNTIME("Bignum operation fail!"); - } - std::swap(dv.m_value, m_value); - std::swap(rm.m_value, rem.m_value); - rem.m_is_init = true; - return *this; - } - -}; - -class Fraction { -private: - // Числитель - BigNum m_numerator; - // Знаменатель - BigNum m_denominator; - - // Функция нужна для сокращения дроби - void reduce(); -public: - // Конструктор принимает значения числителя и знаменателя - - Fraction(BigNum & numerator, BigNum &denominator) { - m_numerator = numerator; - m_denominator = denominator; - } - - Fraction(const std::string &numerator, const std::string &denominator) { - // m_numerator = numerator; - // m_denominator = denominator; - } - - // Fraction(const std::string &string) { - // // Выбрасываем исключение, если не задана строка - // assert(string == ""); - // // Ищем знак '/' - // int pos = string.find("/"); - // - // // Если символ не найден - то вся строка является числом - // if (pos == std::string::npos) { - // m_numerator = stoi(string); - // m_denominator = 1; - // } else { - // // Числитель - левая часть - // m_numerator = std::stoi(string.substr(0, pos)); - // // Знаменатель - правая часть - // m_denominator = std::stoi(string.substr(pos, string.length())); - // - // // Знаменатель не должен быть равен нулю - // assert(m_denominator == 0); - // } - // } - // // Возвращаем дробь в виде строки - // - // std::string toString() { - // std::string fraction = ""; - // if (m_numerator == 0) { - // fraction.append("0"); - // return fraction; - // } - // - // fraction.append(std::to_string(m_numerator)); - // if (m_denominator != 1) { - // fraction.append("/"); - // fraction.append(std::to_string(m_denominator)); - // } - // return fraction; - // } - // // Геттеры - // - // int getNumerator() const { - // return m_numerator; - // } - // - // int getDenominator() const { - // return m_denominator; - // } - - - // // Наибольший общий делитель - // // (англ.) greatest common divisor - // - // static int gcd(int a, int b) { - // while (b > 0) { - // int c = a % b; - // a = b; - // b = c; - // } - // return a; - // } - // - // // Наименьшее общее кратное - // // (англ.) least common multiple - // - // static int lcm(int a, int b) { - // return gcd(a, b) * a * b; - // } - //public void reduce () - //{ - // BigInteger num = BigInteger.valueOf(numerator); - // int gcd = num.gcd(BigInteger.valueOf(denominator)).intValue(); - // - // this.denominator /= gcd; - // this.numerator /= gcd; - // - //} - - Fraction& operator*(const Fraction &fraction) { - LOG_RUNTIME("Not implemented!"); - // m_numerator = m_numerator * fraction.getNumerator(); - // m_denominator = m_denominator * fraction.getDenominator(); - // reduce(); - return *this; - } - - Fraction& operator/(const Fraction &fraction) { - LOG_RUNTIME("Not implemented!"); - // m_numerator = m_numerator * fraction.getDenominator(); - // m_denominator = m_denominator * fraction.getNumerator(); - // reduce(); - return *this; - } - - Fraction& operator-(const Fraction &fraction) { - LOG_RUNTIME("Not implemented!"); - // int relNumerator = m_numerator * fraction.getDenominator(); - // m_numerator = m_numerator * fraction.getDenominator() - m_denominator * fraction.getNumerator(); - // m_denominator = gcd(m_denominator, fraction.getDenominator()); - // reduce(); - return *this; - } - - Fraction& operator+(const Fraction &fraction) { - LOG_RUNTIME("Not implemented!"); - // int unionDenominator = lcm(m_denominator, fraction.getDenominator()); - // int relNumerator = m_numerator * unionDenominator; - // int mulNumerator = fraction.m_numerator * unionDenominator; - // m_numerator = relNumerator * mulNumerator; - // m_denominator = unionDenominator; - // reduce(); - return *this; - } -}; +//#include +//#include +// +//#include +//#include +// +//class BigNum { +// SCOPE(private) : +// BIGNUM *m_value; +// BN_CTX *m_ctx; +// bool m_is_init; +//public: +// +//#define CHECK_INIT(value) if (!(value)->m_is_init) { LOG_RUNTIME("Fail init!!!"); } +// +// BigNum() : m_value(nullptr), m_ctx(nullptr) { +// m_is_init = false; +// m_value = BN_new(); +// m_ctx = BN_CTX_new(); +// } +// +// BigNum(std::string str) { +// SetFromString(str); +// } +// +// virtual ~BigNum() { +// if (m_value) { +// BN_free(m_value); +// m_value = nullptr; +// } +// if (m_ctx) { +// BN_CTX_free(m_ctx); +// m_ctx = nullptr; +// } +// } +// +// int64_t GetAsInteger() { +// CHECK_INIT(this); +// +// int64_t result = BN_get_word(m_value); +// if (result == ~0) { +// LOG_RUNTIME("Bignum integer overflow!"); +// } +// +// if (BN_is_negative(m_value)) { +// result = -result; +// } +// return result; +// } +// +// double GetAsNumber() { +// CHECK_INIT(this); +// //@todo Refactor convert big integer to double! +// return GetAsInteger(); +// } +// +// inline bool SetFromString(const std::string str) { +// m_is_init = true; +// return BN_dec2bn(&m_value, str.c_str()); +// } +// +// std::string GetAsString() { +// CHECK_INIT(this); +// char * number_str = BN_bn2dec(m_value); +// std::string result(number_str); +// OPENSSL_free(number_str); +// return result; +// } +// +// BigNum &add(BigNum &val) { +// CHECK_INIT(this); +// CHECK_INIT(&val); +// +// BigNum temp; +// if (!BN_add(temp.m_value, m_value, val.m_value)) { +// LOG_RUNTIME("Bignum operation fail!"); +// } +// std::swap(temp.m_value, m_value); +// return *this; +// } +// +// BigNum &sub(BigNum &val) { +// CHECK_INIT(this); +// CHECK_INIT(&val); +// +// BigNum temp; +// if (!BN_sub(temp.m_value, m_value, val.m_value)) { +// LOG_RUNTIME("Bignum operation fail!"); +// } +// std::swap(temp.m_value, m_value); +// return *this; +// } +// +// BigNum &mul(BigNum &val) { +// CHECK_INIT(this); +// CHECK_INIT(&val); +// +// BigNum temp; +// if (!BN_mul(temp.m_value, m_value, val.m_value, m_ctx)) { +// LOG_RUNTIME("Bignum operation fail!"); +// } +// std::swap(temp.m_value, m_value); +// return *this; +// } +// +// BigNum &div(BigNum &val, BigNum &rem) { +// CHECK_INIT(this); +// CHECK_INIT(&val); +// +// BigNum dv; +// BigNum rm; +// if (!BN_div(dv.m_value, rm.m_value, m_value, val.m_value, m_ctx)) { +// LOG_RUNTIME("Bignum operation fail!"); +// } +// std::swap(dv.m_value, m_value); +// std::swap(rm.m_value, rem.m_value); +// rem.m_is_init = true; +// return *this; +// } +// +//}; +// +//class Fraction { +//private: +// // Числитель +// BigNum m_numerator; +// // Знаменатель +// BigNum m_denominator; +// +// // Функция нужна для сокращения дроби +// void reduce(); +//public: +// // Конструктор принимает значения числителя и знаменателя +// +// Fraction(BigNum & numerator, BigNum &denominator) { +// m_numerator = numerator; +// m_denominator = denominator; +// } +// +// Fraction(const std::string &numerator, const std::string &denominator) { +// // m_numerator = numerator; +// // m_denominator = denominator; +// } +// +// // Fraction(const std::string &string) { +// // // Выбрасываем исключение, если не задана строка +// // assert(string == ""); +// // // Ищем знак '/' +// // int pos = string.find("/"); +// // +// // // Если символ не найден - то вся строка является числом +// // if (pos == std::string::npos) { +// // m_numerator = stoi(string); +// // m_denominator = 1; +// // } else { +// // // Числитель - левая часть +// // m_numerator = std::stoi(string.substr(0, pos)); +// // // Знаменатель - правая часть +// // m_denominator = std::stoi(string.substr(pos, string.length())); +// // +// // // Знаменатель не должен быть равен нулю +// // assert(m_denominator == 0); +// // } +// // } +// // // Возвращаем дробь в виде строки +// // +// // std::string toString() { +// // std::string fraction = ""; +// // if (m_numerator == 0) { +// // fraction.append("0"); +// // return fraction; +// // } +// // +// // fraction.append(std::to_string(m_numerator)); +// // if (m_denominator != 1) { +// // fraction.append("/"); +// // fraction.append(std::to_string(m_denominator)); +// // } +// // return fraction; +// // } +// // // Геттеры +// // +// // int getNumerator() const { +// // return m_numerator; +// // } +// // +// // int getDenominator() const { +// // return m_denominator; +// // } +// +// +// // // Наибольший общий делитель +// // // (англ.) greatest common divisor +// // +// // static int gcd(int a, int b) { +// // while (b > 0) { +// // int c = a % b; +// // a = b; +// // b = c; +// // } +// // return a; +// // } +// // +// // // Наименьшее общее кратное +// // // (англ.) least common multiple +// // +// // static int lcm(int a, int b) { +// // return gcd(a, b) * a * b; +// // } +// //public void reduce () +// //{ +// // BigInteger num = BigInteger.valueOf(numerator); +// // int gcd = num.gcd(BigInteger.valueOf(denominator)).intValue(); +// // +// // this.denominator /= gcd; +// // this.numerator /= gcd; +// // +// //} +// +// Fraction& operator*(const Fraction &fraction) { +// LOG_RUNTIME("Not implemented!"); +// // m_numerator = m_numerator * fraction.getNumerator(); +// // m_denominator = m_denominator * fraction.getDenominator(); +// // reduce(); +// return *this; +// } +// +// Fraction& operator/(const Fraction &fraction) { +// LOG_RUNTIME("Not implemented!"); +// // m_numerator = m_numerator * fraction.getDenominator(); +// // m_denominator = m_denominator * fraction.getNumerator(); +// // reduce(); +// return *this; +// } +// +// Fraction& operator-(const Fraction &fraction) { +// LOG_RUNTIME("Not implemented!"); +// // int relNumerator = m_numerator * fraction.getDenominator(); +// // m_numerator = m_numerator * fraction.getDenominator() - m_denominator * fraction.getNumerator(); +// // m_denominator = gcd(m_denominator, fraction.getDenominator()); +// // reduce(); +// return *this; +// } +// +// Fraction& operator+(const Fraction &fraction) { +// LOG_RUNTIME("Not implemented!"); +// // int unionDenominator = lcm(m_denominator, fraction.getDenominator()); +// // int relNumerator = m_numerator * unionDenominator; +// // int mulNumerator = fraction.m_numerator * unionDenominator; +// // m_numerator = relNumerator * mulNumerator; +// // m_denominator = unionDenominator; +// // reduce(); +// return *this; +// } +//}; #endif /* FRACTION_H */ diff --git a/core/lexer.l b/core/lexer.l index 157e6c14..8864f84f 100644 --- a/core/lexer.l +++ b/core/lexer.l @@ -370,8 +370,8 @@ term [$@%]({ualpha}|[_])?({name})? "{{" YY_TOKEN_ONLY(TRY_BEGIN); "}}" YY_TOKEN_ONLY(TRY_END); -"::-" YY_TOKEN(TRANSPARENT); -":-" YY_TOKEN(TRANSPARENT); +"::-" YY_TOKEN(PUREFUNC); +":-" YY_TOKEN(PUREFUNC); "::&&=" YY_TOKEN(SIMPLE_AND); ":&&=" YY_TOKEN(SIMPLE_AND); "::||=" YY_TOKEN(SIMPLE_OR); diff --git a/core/nbproject/Makefile-Debug.mk b/core/nbproject/Makefile-Debug.mk index 316abe27..20216c34 100644 --- a/core/nbproject/Makefile-Debug.mk +++ b/core/nbproject/Makefile-Debug.mk @@ -48,10 +48,10 @@ OBJECTFILES= \ ${OBJECTDIR}/syntax_help.o \ ${OBJECTDIR}/term.o \ ${OBJECTDIR}/test/alg_test.o \ + ${OBJECTDIR}/test/compiler_test.o \ ${OBJECTDIR}/test/eval_test.o \ ${OBJECTDIR}/test/fraction_test.o \ ${OBJECTDIR}/test/lexer_test.o \ - ${OBJECTDIR}/test/newlang_test.o \ ${OBJECTDIR}/test/nlc_test.o \ ${OBJECTDIR}/test/object_test.o \ ${OBJECTDIR}/test/parser_test.o \ @@ -204,6 +204,11 @@ ${OBJECTDIR}/test/alg_test.o: test/alg_test.cpp pch.h.gch ${RM} "$@.d" $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/alg_test.o test/alg_test.cpp +${OBJECTDIR}/test/compiler_test.o: test/compiler_test.cpp pch.h.gch + ${MKDIR} -p ${OBJECTDIR}/test + ${RM} "$@.d" + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/compiler_test.o test/compiler_test.cpp + ${OBJECTDIR}/test/eval_test.o: test/eval_test.cpp pch.h.gch ${MKDIR} -p ${OBJECTDIR}/test ${RM} "$@.d" @@ -219,11 +224,6 @@ ${OBJECTDIR}/test/lexer_test.o: test/lexer_test.cpp pch.h.gch ${RM} "$@.d" $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/lexer_test.o test/lexer_test.cpp -${OBJECTDIR}/test/newlang_test.o: test/newlang_test.cpp pch.h.gch - ${MKDIR} -p ${OBJECTDIR}/test - ${RM} "$@.d" - $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/newlang_test.o test/newlang_test.cpp - ${OBJECTDIR}/test/nlc_test.o: test/nlc_test.cpp pch.h.gch ${MKDIR} -p ${OBJECTDIR}/test ${RM} "$@.d" diff --git a/core/nbproject/Makefile-GCOV.mk b/core/nbproject/Makefile-GCOV.mk index 2943cc53..00a0fbff 100644 --- a/core/nbproject/Makefile-GCOV.mk +++ b/core/nbproject/Makefile-GCOV.mk @@ -50,10 +50,10 @@ OBJECTFILES= \ ${OBJECTDIR}/syntax_help.o \ ${OBJECTDIR}/term.o \ ${OBJECTDIR}/test/alg_test.o \ + ${OBJECTDIR}/test/compiler_test.o \ ${OBJECTDIR}/test/eval_test.o \ ${OBJECTDIR}/test/fraction_test.o \ ${OBJECTDIR}/test/lexer_test.o \ - ${OBJECTDIR}/test/newlang_test.o \ ${OBJECTDIR}/test/nlc_test.o \ ${OBJECTDIR}/test/object_test.o \ ${OBJECTDIR}/test/parser_test.o \ @@ -184,6 +184,11 @@ ${OBJECTDIR}/test/alg_test.o: test/alg_test.cpp ${RM} "$@.d" $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/alg_test.o test/alg_test.cpp +${OBJECTDIR}/test/compiler_test.o: test/compiler_test.cpp + ${MKDIR} -p ${OBJECTDIR}/test + ${RM} "$@.d" + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/compiler_test.o test/compiler_test.cpp + ${OBJECTDIR}/test/eval_test.o: test/eval_test.cpp ${MKDIR} -p ${OBJECTDIR}/test ${RM} "$@.d" @@ -199,11 +204,6 @@ ${OBJECTDIR}/test/lexer_test.o: test/lexer_test.cpp ${RM} "$@.d" $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/lexer_test.o test/lexer_test.cpp -${OBJECTDIR}/test/newlang_test.o: test/newlang_test.cpp - ${MKDIR} -p ${OBJECTDIR}/test - ${RM} "$@.d" - $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/newlang_test.o test/newlang_test.cpp - ${OBJECTDIR}/test/nlc_test.o: test/nlc_test.cpp ${MKDIR} -p ${OBJECTDIR}/test ${RM} "$@.d" diff --git a/core/nbproject/Makefile-LLVM.mk b/core/nbproject/Makefile-LLVM.mk index fb756104..d33fd1a1 100644 --- a/core/nbproject/Makefile-LLVM.mk +++ b/core/nbproject/Makefile-LLVM.mk @@ -49,10 +49,10 @@ OBJECTFILES= \ ${OBJECTDIR}/syntax_help.o \ ${OBJECTDIR}/term.o \ ${OBJECTDIR}/test/alg_test.o \ + ${OBJECTDIR}/test/compiler_test.o \ ${OBJECTDIR}/test/eval_test.o \ ${OBJECTDIR}/test/fraction_test.o \ ${OBJECTDIR}/test/lexer_test.o \ - ${OBJECTDIR}/test/newlang_test.o \ ${OBJECTDIR}/test/nlc_test.o \ ${OBJECTDIR}/test/object_test.o \ ${OBJECTDIR}/test/parser_test.o \ @@ -178,6 +178,11 @@ ${OBJECTDIR}/test/alg_test.o: test/alg_test.cpp ${RM} "$@.d" $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I/usr/lib/llvm-12/lib/clang/12.0.1/include -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I.. -std=c++14 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/alg_test.o test/alg_test.cpp +${OBJECTDIR}/test/compiler_test.o: test/compiler_test.cpp + ${MKDIR} -p ${OBJECTDIR}/test + ${RM} "$@.d" + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I/usr/lib/llvm-12/lib/clang/12.0.1/include -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I.. -std=c++14 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/compiler_test.o test/compiler_test.cpp + ${OBJECTDIR}/test/eval_test.o: test/eval_test.cpp ${MKDIR} -p ${OBJECTDIR}/test ${RM} "$@.d" @@ -193,11 +198,6 @@ ${OBJECTDIR}/test/lexer_test.o: test/lexer_test.cpp ${RM} "$@.d" $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I/usr/lib/llvm-12/lib/clang/12.0.1/include -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I.. -std=c++14 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/lexer_test.o test/lexer_test.cpp -${OBJECTDIR}/test/newlang_test.o: test/newlang_test.cpp - ${MKDIR} -p ${OBJECTDIR}/test - ${RM} "$@.d" - $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I/usr/lib/llvm-12/lib/clang/12.0.1/include -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I.. -std=c++14 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/newlang_test.o test/newlang_test.cpp - ${OBJECTDIR}/test/nlc_test.o: test/nlc_test.cpp ${MKDIR} -p ${OBJECTDIR}/test ${RM} "$@.d" diff --git a/core/nbproject/Makefile-LLVM_GCC.mk b/core/nbproject/Makefile-LLVM_GCC.mk index 04602d2b..49758c5e 100644 --- a/core/nbproject/Makefile-LLVM_GCC.mk +++ b/core/nbproject/Makefile-LLVM_GCC.mk @@ -49,10 +49,10 @@ OBJECTFILES= \ ${OBJECTDIR}/syntax_help.o \ ${OBJECTDIR}/term.o \ ${OBJECTDIR}/test/alg_test.o \ + ${OBJECTDIR}/test/compiler_test.o \ ${OBJECTDIR}/test/eval_test.o \ ${OBJECTDIR}/test/fraction_test.o \ ${OBJECTDIR}/test/lexer_test.o \ - ${OBJECTDIR}/test/newlang_test.o \ ${OBJECTDIR}/test/nlc_test.o \ ${OBJECTDIR}/test/object_test.o \ ${OBJECTDIR}/test/parser_test.o \ @@ -178,6 +178,11 @@ ${OBJECTDIR}/test/alg_test.o: test/alg_test.cpp ${RM} "$@.d" $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I.. -std=c++14 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/alg_test.o test/alg_test.cpp +${OBJECTDIR}/test/compiler_test.o: test/compiler_test.cpp + ${MKDIR} -p ${OBJECTDIR}/test + ${RM} "$@.d" + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I.. -std=c++14 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/compiler_test.o test/compiler_test.cpp + ${OBJECTDIR}/test/eval_test.o: test/eval_test.cpp ${MKDIR} -p ${OBJECTDIR}/test ${RM} "$@.d" @@ -193,11 +198,6 @@ ${OBJECTDIR}/test/lexer_test.o: test/lexer_test.cpp ${RM} "$@.d" $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I.. -std=c++14 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/lexer_test.o test/lexer_test.cpp -${OBJECTDIR}/test/newlang_test.o: test/newlang_test.cpp - ${MKDIR} -p ${OBJECTDIR}/test - ${RM} "$@.d" - $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I.. -std=c++14 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/newlang_test.o test/newlang_test.cpp - ${OBJECTDIR}/test/nlc_test.o: test/nlc_test.cpp ${MKDIR} -p ${OBJECTDIR}/test ${RM} "$@.d" diff --git a/core/nbproject/Makefile-Release.mk b/core/nbproject/Makefile-Release.mk index df796044..782e417a 100644 --- a/core/nbproject/Makefile-Release.mk +++ b/core/nbproject/Makefile-Release.mk @@ -49,10 +49,10 @@ OBJECTFILES= \ ${OBJECTDIR}/syntax_help.o \ ${OBJECTDIR}/term.o \ ${OBJECTDIR}/test/alg_test.o \ + ${OBJECTDIR}/test/compiler_test.o \ ${OBJECTDIR}/test/eval_test.o \ ${OBJECTDIR}/test/fraction_test.o \ ${OBJECTDIR}/test/lexer_test.o \ - ${OBJECTDIR}/test/newlang_test.o \ ${OBJECTDIR}/test/nlc_test.o \ ${OBJECTDIR}/test/object_test.o \ ${OBJECTDIR}/test/parser_test.o \ @@ -164,6 +164,11 @@ ${OBJECTDIR}/test/alg_test.o: test/alg_test.cpp ${RM} "$@.d" $(COMPILE.cc) -O3 -Werror -I.. -std=c++14 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/alg_test.o test/alg_test.cpp +${OBJECTDIR}/test/compiler_test.o: test/compiler_test.cpp + ${MKDIR} -p ${OBJECTDIR}/test + ${RM} "$@.d" + $(COMPILE.cc) -O3 -Werror -I.. -std=c++14 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/compiler_test.o test/compiler_test.cpp + ${OBJECTDIR}/test/eval_test.o: test/eval_test.cpp ${MKDIR} -p ${OBJECTDIR}/test ${RM} "$@.d" @@ -179,11 +184,6 @@ ${OBJECTDIR}/test/lexer_test.o: test/lexer_test.cpp ${RM} "$@.d" $(COMPILE.cc) -O3 -Werror -I.. -std=c++14 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/lexer_test.o test/lexer_test.cpp -${OBJECTDIR}/test/newlang_test.o: test/newlang_test.cpp - ${MKDIR} -p ${OBJECTDIR}/test - ${RM} "$@.d" - $(COMPILE.cc) -O3 -Werror -I.. -std=c++14 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/newlang_test.o test/newlang_test.cpp - ${OBJECTDIR}/test/nlc_test.o: test/nlc_test.cpp ${MKDIR} -p ${OBJECTDIR}/test ${RM} "$@.d" diff --git a/core/nbproject/Makefile-UnitTest-Win32.mk b/core/nbproject/Makefile-UnitTest-Win32.mk new file mode 100644 index 00000000..ecd27b30 --- /dev/null +++ b/core/nbproject/Makefile-UnitTest-Win32.mk @@ -0,0 +1,304 @@ +# +# Generated Makefile - do not edit! +# +# Edit the Makefile in the project folder instead (../Makefile). Each target +# has a -pre and a -post target defined where you can add customized code. +# +# This makefile implements configuration specific macros and targets. + + +# Environment +MKDIR=mkdir +CP=cp +GREP=grep +NM=nm +CCADMIN=CCadmin +RANLIB=ranlib +CC=i686-w64-mingw32-gcc-9.3-posix +CCC=i686-w64-mingw32-g++-posix +CXX=i686-w64-mingw32-g++-posix +FC=gfortran +AS=i686-w64-mingw32-as + +# Macros +CND_PLATFORM=Win32-i686-Linux +CND_DLIB_EXT=so +CND_CONF=UnitTest-Win32 +CND_DISTDIR=dist +CND_BUILDDIR=build + +# Include project Makefile +include Makefile + +# Object Directory +OBJECTDIR=${CND_BUILDDIR}/${CND_CONF}/${CND_PLATFORM} + +# Object Files +OBJECTFILES= \ + ${OBJECTDIR}/_ext/1e501df/gtest-all.o \ + ${OBJECTDIR}/_ext/1e501df/gtest_main.o \ + ${OBJECTDIR}/_ext/e16507f5/logger.o \ + ${OBJECTDIR}/builtin.o \ + ${OBJECTDIR}/context.o \ + ${OBJECTDIR}/lexer.o \ + ${OBJECTDIR}/lexer.yy.o \ + ${OBJECTDIR}/newlang.o \ + ${OBJECTDIR}/nlc.o \ + ${OBJECTDIR}/object.o \ + ${OBJECTDIR}/parser.o \ + ${OBJECTDIR}/parser.yy.o \ + ${OBJECTDIR}/syntax_help.o \ + ${OBJECTDIR}/term.o \ + ${OBJECTDIR}/test/alg_test.o \ + ${OBJECTDIR}/test/compiler_test.o \ + ${OBJECTDIR}/test/eval_test.o \ + ${OBJECTDIR}/test/fraction_test.o \ + ${OBJECTDIR}/test/lexer_test.o \ + ${OBJECTDIR}/test/nlc_test.o \ + ${OBJECTDIR}/test/object_test.o \ + ${OBJECTDIR}/test/parser_test.o \ + ${OBJECTDIR}/variable.o \ + ${OBJECTDIR}/version.o + + +# C Compiler Flags +CFLAGS= + +# CC Compiler Flags +CCFLAGS=-std=c++17 --no-gnu-unique -Wno-trigraphs -Winvalid-pch -Werror=return-type -Wmaybe-uninitialized -Wuninitialized -Wformat -Wmaybe-uninitialized +CXXFLAGS=-std=c++17 --no-gnu-unique -Wno-trigraphs -Winvalid-pch -Werror=return-type -Wmaybe-uninitialized -Wuninitialized -Wformat -Wmaybe-uninitialized + +# Fortran Compiler Flags +FFLAGS= + +# Assembler Flags +ASFLAGS= + +# Link Libraries and Options +LDLIBSOPTIONS=-L../contrib/libtorch/lib -Wl,-rpath,'../contrib/libtorch/lib' -lpthread -ldl ../contrib/libffi/output/lib/libffi.a -lcrypto -lLLVM-13 -ltorch -lc10 -ltorch_cpu + +# Build Targets +.build-conf: ${BUILD_SUBPROJECTS} + "${MAKE}" -f nbproject/Makefile-${CND_CONF}.mk newlang_test + +newlang_test: ../contrib/libffi/output/lib/libffi.a + +newlang_test: ${OBJECTFILES} + ${LINK.cc} -o newlang_test ${OBJECTFILES} ${LDLIBSOPTIONS} -Wl,--export-dynamic + +${OBJECTDIR}/_ext/1e501df/gtest-all.o: ../contrib/googletest/googletest/src/gtest-all.cc + ${MKDIR} -p ${OBJECTDIR}/_ext/1e501df + ${RM} "$@.d" + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -I/usr/lib/llvm-13/include -std=c++14 -Wno-error -Wno-all -Wno-extra -Wno-ctor-dtor-privacy -Wno-undef -Wno-sign-compare -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/_ext/1e501df/gtest-all.o ../contrib/googletest/googletest/src/gtest-all.cc + +${OBJECTDIR}/_ext/1e501df/gtest_main.o: ../contrib/googletest/googletest/src/gtest_main.cc + ${MKDIR} -p ${OBJECTDIR}/_ext/1e501df + ${RM} "$@.d" + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -I/usr/lib/llvm-13/include -std=c++14 -Wno-error -Wno-all -Wno-extra -Wno-ctor-dtor-privacy -Wno-undef -Wno-sign-compare -Wno-conversion -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/_ext/1e501df/gtest_main.o ../contrib/googletest/googletest/src/gtest_main.cc + +${OBJECTDIR}/_ext/e16507f5/logger.o: ../contrib/logger/logger.cpp + ${MKDIR} -p ${OBJECTDIR}/_ext/e16507f5 + ${RM} "$@.d" + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -I/usr/lib/llvm-13/include -std=c++14 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/_ext/e16507f5/logger.o ../contrib/logger/logger.cpp + +${OBJECTDIR}/builtin.o: builtin.cpp parser.h parser.yy.h pch.h.gch location.hh + ${MKDIR} -p ${OBJECTDIR} + ${RM} "$@.d" + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -I/usr/lib/llvm-13/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/builtin.o builtin.cpp + +: builtin.h pch.h.gch + @echo Выполнение шага пользовательского сборки + + +${OBJECTDIR}/context.o: context.cpp parser.h parser.yy.h pch.h.gch location.hh + ${MKDIR} -p ${OBJECTDIR} + ${RM} "$@.d" + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -I/usr/lib/llvm-13/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/context.o context.cpp + +: context.h pch.h.gch + @echo Выполнение шага пользовательского сборки + + +${OBJECTDIR}/lexer.o: lexer.cpp location.hh + ${MKDIR} -p ${OBJECTDIR} + ${RM} "$@.d" + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -I/usr/lib/llvm-13/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/lexer.o lexer.cpp + +: lexer.h parser.yy.h parser.yy.cpp location.hh pch.h.gch + @echo Выполнение шага пользовательского сборки + + +.NO_PARALLEL:lexer.yy.cpp lexer.yy.h +lexer.yy.cpp lexer.yy.h: lexer.l parser.y parser.yy.h parser.yy.cpp location.hh term.h + @echo + ./compile_syntax.sh + +${OBJECTDIR}/lexer.yy.o: lexer.yy.cpp parser.y parser.yy.h parser.yy.cpp location.hh + ${MKDIR} -p ${OBJECTDIR} + ${RM} "$@.d" + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -I/usr/lib/llvm-13/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/lexer.yy.o lexer.yy.cpp + +: lexer.yy.h pch.h.gch + @echo Выполнение шага пользовательского сборки + + +${OBJECTDIR}/newlang.o: newlang.cpp parser.h parser.yy.h pch.h.gch location.hh + ${MKDIR} -p ${OBJECTDIR} + ${RM} "$@.d" + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -I/usr/lib/llvm-13/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/newlang.o newlang.cpp + +: newlang.h pch.h.gch + @echo Выполнение шага пользовательского сборки + + +${OBJECTDIR}/nlc.o: nlc.cpp parser.h parser.yy.h pch.h.gch location.hh + ${MKDIR} -p ${OBJECTDIR} + ${RM} "$@.d" + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -I/usr/lib/llvm-13/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/nlc.o nlc.cpp + +${OBJECTDIR}/object.o: object.cpp parser.h parser.yy.h pch.h.gch location.hh + ${MKDIR} -p ${OBJECTDIR} + ${RM} "$@.d" + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -I/usr/lib/llvm-13/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/object.o object.cpp + +: object.h pch.h.gch + @echo Выполнение шага пользовательского сборки + + +${OBJECTDIR}/parser.o: parser.cpp parser.h parser.yy.h pch.h.gch location.hh + ${MKDIR} -p ${OBJECTDIR} + ${RM} "$@.d" + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -I/usr/lib/llvm-13/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/parser.o parser.cpp + +: parser.h pch.h.gch + @echo Выполнение шага пользовательского сборки + + +.NO_PARALLEL:parser.yy.h parser.yy.cpp location.hh +parser.yy.h parser.yy.cpp location.hh: parser.y + @echo ************* Bison compile ************* + ./compile_syntax.sh + +${OBJECTDIR}/parser.yy.o: parser.yy.cpp parser.y + ${MKDIR} -p ${OBJECTDIR} + ${RM} "$@.d" + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -I/usr/lib/llvm-13/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/parser.yy.o parser.yy.cpp + +: parser.yy.h parser.y pch.h.gch + @echo Выполнение шага пользовательского сборки + + +pch.h.gch: pch.h + @echo Выполнение шага пользовательского сборки + g++ -o pch.h.gch -c pch.h -g -I.. -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include --no-gnu-unique -Wno-trigraphs -Winvalid-pch -Werror=return-type -Wmaybe-uninitialized -Wuninitialized -Wformat -Wmaybe-uninitialized -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I.. -I../contrib/tensorboard_logger/include -I/usr/lib/llvm-13/include -std=c++17 + +${OBJECTDIR}/syntax_help.o: syntax_help.cpp + ${MKDIR} -p ${OBJECTDIR} + ${RM} "$@.d" + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -I/usr/lib/llvm-13/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/syntax_help.o syntax_help.cpp + +${OBJECTDIR}/term.o: term.cpp parser.h parser.yy.h pch.h.gch location.hh + ${MKDIR} -p ${OBJECTDIR} + ${RM} "$@.d" + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -I/usr/lib/llvm-13/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/term.o term.cpp + +: term.h parser.yy.cpp location.hh pch.h.gch + @echo Выполнение шага пользовательского сборки + + +${OBJECTDIR}/test/alg_test.o: test/alg_test.cpp pch.h.gch + ${MKDIR} -p ${OBJECTDIR}/test + ${RM} "$@.d" + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -I/usr/lib/llvm-13/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/alg_test.o test/alg_test.cpp + +${OBJECTDIR}/test/compiler_test.o: test/compiler_test.cpp pch.h.gch + ${MKDIR} -p ${OBJECTDIR}/test + ${RM} "$@.d" + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -I/usr/lib/llvm-13/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/compiler_test.o test/compiler_test.cpp + +${OBJECTDIR}/test/eval_test.o: test/eval_test.cpp pch.h.gch + ${MKDIR} -p ${OBJECTDIR}/test + ${RM} "$@.d" + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -I/usr/lib/llvm-13/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/eval_test.o test/eval_test.cpp + +${OBJECTDIR}/test/fraction_test.o: test/fraction_test.cpp + ${MKDIR} -p ${OBJECTDIR}/test + ${RM} "$@.d" + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -I/usr/lib/llvm-13/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/fraction_test.o test/fraction_test.cpp + +${OBJECTDIR}/test/lexer_test.o: test/lexer_test.cpp pch.h.gch + ${MKDIR} -p ${OBJECTDIR}/test + ${RM} "$@.d" + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -I/usr/lib/llvm-13/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/lexer_test.o test/lexer_test.cpp + +${OBJECTDIR}/test/nlc_test.o: test/nlc_test.cpp pch.h.gch + ${MKDIR} -p ${OBJECTDIR}/test + ${RM} "$@.d" + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -I/usr/lib/llvm-13/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/nlc_test.o test/nlc_test.cpp + +${OBJECTDIR}/test/object_test.o: test/object_test.cpp pch.h.gch + ${MKDIR} -p ${OBJECTDIR}/test + ${RM} "$@.d" + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -I/usr/lib/llvm-13/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/object_test.o test/object_test.cpp + +${OBJECTDIR}/test/parser_test.o: test/parser_test.cpp pch.h.gch + ${MKDIR} -p ${OBJECTDIR}/test + ${RM} "$@.d" + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -I/usr/lib/llvm-13/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/parser_test.o test/parser_test.cpp + +: types.h pch.h.gch + @echo Выполнение шага пользовательского сборки + + +${OBJECTDIR}/variable.o: variable.cpp pch.h.gch + ${MKDIR} -p ${OBJECTDIR} + ${RM} "$@.d" + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -I/usr/lib/llvm-13/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/variable.o variable.cpp + +: variable.h pch.h.gch + @echo Выполнение шага пользовательского сборки + + +${OBJECTDIR}/version.o: version.c + ${MKDIR} -p ${OBJECTDIR} + ${RM} "$@.d" + $(COMPILE.c) -g -s -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DUMP -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -std=c11 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/version.o version.c + +: warning_pop.h parser.yy.cpp location.hh + @echo Выполнение шага пользовательского сборки + + +: warning_push.h parser.yy.cpp location.hh + @echo Выполнение шага пользовательского сборки + + +# Subprojects +.build-subprojects: + +# Clean Targets +.clean-conf: ${CLEAN_SUBPROJECTS} + ${RM} -r ${CND_BUILDDIR}/${CND_CONF} + ${RM} + ${RM} + ${RM} + ${RM} lexer.yy.cpp lexer.yy.h + ${RM} + ${RM} + ${RM} + ${RM} + ${RM} parser.yy.h parser.yy.cpp location.hh + ${RM} + ${RM} pch.h.gch + ${RM} + ${RM} + ${RM} + ${RM} + ${RM} + +# Subprojects +.clean-subprojects: + +# Enable dependency checking +.dep.inc: .depcheck-impl + +include .dep.inc diff --git a/core/nbproject/Makefile-UnitTest-Win64.mk b/core/nbproject/Makefile-UnitTest-Win64.mk new file mode 100644 index 00000000..93a61d9e --- /dev/null +++ b/core/nbproject/Makefile-UnitTest-Win64.mk @@ -0,0 +1,304 @@ +# +# Generated Makefile - do not edit! +# +# Edit the Makefile in the project folder instead (../Makefile). Each target +# has a -pre and a -post target defined where you can add customized code. +# +# This makefile implements configuration specific macros and targets. + + +# Environment +MKDIR=mkdir +CP=cp +GREP=grep +NM=nm +CCADMIN=CCadmin +RANLIB=ranlib +CC=x86_64-w64-mingw32-gcc-9.3-posix +CCC=x86_64-w64-mingw32-g++-posix +CXX=x86_64-w64-mingw32-g++-posix +FC=gfortran +AS=x86_64-w64-mingw32-as + +# Macros +CND_PLATFORM=Win64-x86_64-Linux +CND_DLIB_EXT=so +CND_CONF=UnitTest-Win64 +CND_DISTDIR=dist +CND_BUILDDIR=build + +# Include project Makefile +include Makefile + +# Object Directory +OBJECTDIR=${CND_BUILDDIR}/${CND_CONF}/${CND_PLATFORM} + +# Object Files +OBJECTFILES= \ + ${OBJECTDIR}/_ext/1e501df/gtest-all.o \ + ${OBJECTDIR}/_ext/1e501df/gtest_main.o \ + ${OBJECTDIR}/_ext/e16507f5/logger.o \ + ${OBJECTDIR}/builtin.o \ + ${OBJECTDIR}/context.o \ + ${OBJECTDIR}/lexer.o \ + ${OBJECTDIR}/lexer.yy.o \ + ${OBJECTDIR}/newlang.o \ + ${OBJECTDIR}/nlc.o \ + ${OBJECTDIR}/object.o \ + ${OBJECTDIR}/parser.o \ + ${OBJECTDIR}/parser.yy.o \ + ${OBJECTDIR}/syntax_help.o \ + ${OBJECTDIR}/term.o \ + ${OBJECTDIR}/test/alg_test.o \ + ${OBJECTDIR}/test/compiler_test.o \ + ${OBJECTDIR}/test/eval_test.o \ + ${OBJECTDIR}/test/fraction_test.o \ + ${OBJECTDIR}/test/lexer_test.o \ + ${OBJECTDIR}/test/nlc_test.o \ + ${OBJECTDIR}/test/object_test.o \ + ${OBJECTDIR}/test/parser_test.o \ + ${OBJECTDIR}/variable.o \ + ${OBJECTDIR}/version.o + + +# C Compiler Flags +CFLAGS= + +# CC Compiler Flags +CCFLAGS=-std=c++17 --no-gnu-unique -Wno-trigraphs -Winvalid-pch -Werror=return-type -Wmaybe-uninitialized -Wuninitialized -Wformat -Wmaybe-uninitialized +CXXFLAGS=-std=c++17 --no-gnu-unique -Wno-trigraphs -Winvalid-pch -Werror=return-type -Wmaybe-uninitialized -Wuninitialized -Wformat -Wmaybe-uninitialized + +# Fortran Compiler Flags +FFLAGS= + +# Assembler Flags +ASFLAGS= + +# Link Libraries and Options +LDLIBSOPTIONS=-L../contrib/libtorch/lib -Wl,-rpath,'../contrib/libtorch/lib' -lpthread -ldl ../contrib/libffi/output/lib/libffi.a -lcrypto -lLLVM-13 -ltorch -lc10 -ltorch_cpu + +# Build Targets +.build-conf: ${BUILD_SUBPROJECTS} + "${MAKE}" -f nbproject/Makefile-${CND_CONF}.mk newlang_test + +newlang_test: ../contrib/libffi/output/lib/libffi.a + +newlang_test: ${OBJECTFILES} + ${LINK.cc} -o newlang_test ${OBJECTFILES} ${LDLIBSOPTIONS} -Wl,--export-dynamic -static-libgcc -static-libstdc++ + +${OBJECTDIR}/_ext/1e501df/gtest-all.o: ../contrib/googletest/googletest/src/gtest-all.cc + ${MKDIR} -p ${OBJECTDIR}/_ext/1e501df + ${RM} "$@.d" + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch-win/include/torch/csrc/api/include -I../contrib/libtorch-win/include -I../contrib/tensorboard_logger/include -I/usr/share/mingw-w64/include/ -std=c++14 -Wno-error -Wno-all -Wno-extra -Wno-ctor-dtor-privacy -Wno-undef -Wno-sign-compare -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/_ext/1e501df/gtest-all.o ../contrib/googletest/googletest/src/gtest-all.cc + +${OBJECTDIR}/_ext/1e501df/gtest_main.o: ../contrib/googletest/googletest/src/gtest_main.cc + ${MKDIR} -p ${OBJECTDIR}/_ext/1e501df + ${RM} "$@.d" + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch-win/include/torch/csrc/api/include -I../contrib/libtorch-win/include -I../contrib/tensorboard_logger/include -I/usr/share/mingw-w64/include/ -std=c++14 -Wno-error -Wno-all -Wno-extra -Wno-ctor-dtor-privacy -Wno-undef -Wno-sign-compare -Wno-conversion -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/_ext/1e501df/gtest_main.o ../contrib/googletest/googletest/src/gtest_main.cc + +${OBJECTDIR}/_ext/e16507f5/logger.o: ../contrib/logger/logger.cpp + ${MKDIR} -p ${OBJECTDIR}/_ext/e16507f5 + ${RM} "$@.d" + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch-win/include/torch/csrc/api/include -I../contrib/libtorch-win/include -I../contrib/tensorboard_logger/include -I/usr/share/mingw-w64/include/ -std=c++14 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/_ext/e16507f5/logger.o ../contrib/logger/logger.cpp + +${OBJECTDIR}/builtin.o: builtin.cpp parser.h parser.yy.h pch.h.gch location.hh + ${MKDIR} -p ${OBJECTDIR} + ${RM} "$@.d" + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch-win/include/torch/csrc/api/include -I../contrib/libtorch-win/include -I../contrib/tensorboard_logger/include -I/usr/share/mingw-w64/include/ -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/builtin.o builtin.cpp + +: builtin.h pch.h.gch + @echo Выполнение шага пользовательского сборки + + +${OBJECTDIR}/context.o: context.cpp parser.h parser.yy.h pch.h.gch location.hh + ${MKDIR} -p ${OBJECTDIR} + ${RM} "$@.d" + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch-win/include/torch/csrc/api/include -I../contrib/libtorch-win/include -I../contrib/tensorboard_logger/include -I/usr/share/mingw-w64/include/ -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/context.o context.cpp + +: context.h pch.h.gch + @echo Выполнение шага пользовательского сборки + + +${OBJECTDIR}/lexer.o: lexer.cpp location.hh + ${MKDIR} -p ${OBJECTDIR} + ${RM} "$@.d" + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch-win/include/torch/csrc/api/include -I../contrib/libtorch-win/include -I../contrib/tensorboard_logger/include -I/usr/share/mingw-w64/include/ -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/lexer.o lexer.cpp + +: lexer.h parser.yy.h parser.yy.cpp location.hh pch.h.gch + @echo Выполнение шага пользовательского сборки + + +.NO_PARALLEL:lexer.yy.cpp lexer.yy.h +lexer.yy.cpp lexer.yy.h: lexer.l parser.y parser.yy.h parser.yy.cpp location.hh term.h + @echo + ./compile_syntax.sh + +${OBJECTDIR}/lexer.yy.o: lexer.yy.cpp parser.y parser.yy.h parser.yy.cpp location.hh + ${MKDIR} -p ${OBJECTDIR} + ${RM} "$@.d" + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch-win/include/torch/csrc/api/include -I../contrib/libtorch-win/include -I../contrib/tensorboard_logger/include -I/usr/share/mingw-w64/include/ -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/lexer.yy.o lexer.yy.cpp + +: lexer.yy.h pch.h.gch + @echo Выполнение шага пользовательского сборки + + +${OBJECTDIR}/newlang.o: newlang.cpp parser.h parser.yy.h pch.h.gch location.hh + ${MKDIR} -p ${OBJECTDIR} + ${RM} "$@.d" + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch-win/include/torch/csrc/api/include -I../contrib/libtorch-win/include -I../contrib/tensorboard_logger/include -I/usr/share/mingw-w64/include/ -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/newlang.o newlang.cpp + +: newlang.h pch.h.gch + @echo Выполнение шага пользовательского сборки + + +${OBJECTDIR}/nlc.o: nlc.cpp parser.h parser.yy.h pch.h.gch location.hh + ${MKDIR} -p ${OBJECTDIR} + ${RM} "$@.d" + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch-win/include/torch/csrc/api/include -I../contrib/libtorch-win/include -I../contrib/tensorboard_logger/include -I/usr/share/mingw-w64/include/ -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/nlc.o nlc.cpp + +${OBJECTDIR}/object.o: object.cpp parser.h parser.yy.h pch.h.gch location.hh + ${MKDIR} -p ${OBJECTDIR} + ${RM} "$@.d" + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch-win/include/torch/csrc/api/include -I../contrib/libtorch-win/include -I../contrib/tensorboard_logger/include -I/usr/share/mingw-w64/include/ -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/object.o object.cpp + +: object.h pch.h.gch + @echo Выполнение шага пользовательского сборки + + +${OBJECTDIR}/parser.o: parser.cpp parser.h parser.yy.h pch.h.gch location.hh + ${MKDIR} -p ${OBJECTDIR} + ${RM} "$@.d" + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch-win/include/torch/csrc/api/include -I../contrib/libtorch-win/include -I../contrib/tensorboard_logger/include -I/usr/share/mingw-w64/include/ -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/parser.o parser.cpp + +: parser.h pch.h.gch + @echo Выполнение шага пользовательского сборки + + +.NO_PARALLEL:parser.yy.h parser.yy.cpp location.hh +parser.yy.h parser.yy.cpp location.hh: parser.y + @echo ************* Bison compile ************* + ./compile_syntax.sh + +${OBJECTDIR}/parser.yy.o: parser.yy.cpp parser.y + ${MKDIR} -p ${OBJECTDIR} + ${RM} "$@.d" + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch-win/include/torch/csrc/api/include -I../contrib/libtorch-win/include -I../contrib/tensorboard_logger/include -I/usr/share/mingw-w64/include/ -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/parser.yy.o parser.yy.cpp + +: parser.yy.h parser.y pch.h.gch + @echo Выполнение шага пользовательского сборки + + +pch.h.gch: pch.h + @echo Выполнение шага пользовательского сборки + g++ -o pch.h.gch -c pch.h -g -I.. -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include --no-gnu-unique -Wno-trigraphs -Winvalid-pch -Werror=return-type -Wmaybe-uninitialized -Wuninitialized -Wformat -Wmaybe-uninitialized -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I.. -I../contrib/tensorboard_logger/include -I/usr/lib/llvm-13/include -I/usr/include -std=c++17 + +${OBJECTDIR}/syntax_help.o: syntax_help.cpp + ${MKDIR} -p ${OBJECTDIR} + ${RM} "$@.d" + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch-win/include/torch/csrc/api/include -I../contrib/libtorch-win/include -I../contrib/tensorboard_logger/include -I/usr/share/mingw-w64/include/ -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/syntax_help.o syntax_help.cpp + +${OBJECTDIR}/term.o: term.cpp parser.h parser.yy.h pch.h.gch location.hh + ${MKDIR} -p ${OBJECTDIR} + ${RM} "$@.d" + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch-win/include/torch/csrc/api/include -I../contrib/libtorch-win/include -I../contrib/tensorboard_logger/include -I/usr/share/mingw-w64/include/ -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/term.o term.cpp + +: term.h parser.yy.cpp location.hh pch.h.gch + @echo Выполнение шага пользовательского сборки + + +${OBJECTDIR}/test/alg_test.o: test/alg_test.cpp pch.h.gch + ${MKDIR} -p ${OBJECTDIR}/test + ${RM} "$@.d" + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch-win/include/torch/csrc/api/include -I../contrib/libtorch-win/include -I../contrib/tensorboard_logger/include -I/usr/share/mingw-w64/include/ -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/alg_test.o test/alg_test.cpp + +${OBJECTDIR}/test/compiler_test.o: test/compiler_test.cpp pch.h.gch + ${MKDIR} -p ${OBJECTDIR}/test + ${RM} "$@.d" + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch-win/include/torch/csrc/api/include -I../contrib/libtorch-win/include -I../contrib/tensorboard_logger/include -I/usr/share/mingw-w64/include/ -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/compiler_test.o test/compiler_test.cpp + +${OBJECTDIR}/test/eval_test.o: test/eval_test.cpp pch.h.gch + ${MKDIR} -p ${OBJECTDIR}/test + ${RM} "$@.d" + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch-win/include/torch/csrc/api/include -I../contrib/libtorch-win/include -I../contrib/tensorboard_logger/include -I/usr/share/mingw-w64/include/ -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/eval_test.o test/eval_test.cpp + +${OBJECTDIR}/test/fraction_test.o: test/fraction_test.cpp + ${MKDIR} -p ${OBJECTDIR}/test + ${RM} "$@.d" + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch-win/include/torch/csrc/api/include -I../contrib/libtorch-win/include -I../contrib/tensorboard_logger/include -I/usr/share/mingw-w64/include/ -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/fraction_test.o test/fraction_test.cpp + +${OBJECTDIR}/test/lexer_test.o: test/lexer_test.cpp pch.h.gch + ${MKDIR} -p ${OBJECTDIR}/test + ${RM} "$@.d" + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch-win/include/torch/csrc/api/include -I../contrib/libtorch-win/include -I../contrib/tensorboard_logger/include -I/usr/share/mingw-w64/include/ -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/lexer_test.o test/lexer_test.cpp + +${OBJECTDIR}/test/nlc_test.o: test/nlc_test.cpp pch.h.gch + ${MKDIR} -p ${OBJECTDIR}/test + ${RM} "$@.d" + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch-win/include/torch/csrc/api/include -I../contrib/libtorch-win/include -I../contrib/tensorboard_logger/include -I/usr/share/mingw-w64/include/ -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/nlc_test.o test/nlc_test.cpp + +${OBJECTDIR}/test/object_test.o: test/object_test.cpp pch.h.gch + ${MKDIR} -p ${OBJECTDIR}/test + ${RM} "$@.d" + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch-win/include/torch/csrc/api/include -I../contrib/libtorch-win/include -I../contrib/tensorboard_logger/include -I/usr/share/mingw-w64/include/ -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/object_test.o test/object_test.cpp + +${OBJECTDIR}/test/parser_test.o: test/parser_test.cpp pch.h.gch + ${MKDIR} -p ${OBJECTDIR}/test + ${RM} "$@.d" + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch-win/include/torch/csrc/api/include -I../contrib/libtorch-win/include -I../contrib/tensorboard_logger/include -I/usr/share/mingw-w64/include/ -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/parser_test.o test/parser_test.cpp + +: types.h pch.h.gch + @echo Выполнение шага пользовательского сборки + + +${OBJECTDIR}/variable.o: variable.cpp pch.h.gch + ${MKDIR} -p ${OBJECTDIR} + ${RM} "$@.d" + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch-win/include/torch/csrc/api/include -I../contrib/libtorch-win/include -I../contrib/tensorboard_logger/include -I/usr/share/mingw-w64/include/ -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/variable.o variable.cpp + +: variable.h pch.h.gch + @echo Выполнение шага пользовательского сборки + + +${OBJECTDIR}/version.o: version.c + ${MKDIR} -p ${OBJECTDIR} + ${RM} "$@.d" + $(COMPILE.c) -g -s -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DUMP -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I/usr/share/mingw-w64/include/ -std=c11 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/version.o version.c + +: warning_pop.h parser.yy.cpp location.hh + @echo Выполнение шага пользовательского сборки + + +: warning_push.h parser.yy.cpp location.hh + @echo Выполнение шага пользовательского сборки + + +# Subprojects +.build-subprojects: + +# Clean Targets +.clean-conf: ${CLEAN_SUBPROJECTS} + ${RM} -r ${CND_BUILDDIR}/${CND_CONF} + ${RM} + ${RM} + ${RM} + ${RM} lexer.yy.cpp lexer.yy.h + ${RM} + ${RM} + ${RM} + ${RM} + ${RM} parser.yy.h parser.yy.cpp location.hh + ${RM} + ${RM} pch.h.gch + ${RM} + ${RM} + ${RM} + ${RM} + ${RM} + +# Subprojects +.clean-subprojects: + +# Enable dependency checking +.dep.inc: .depcheck-impl + +include .dep.inc diff --git a/core/nbproject/Makefile-UnitTest.mk b/core/nbproject/Makefile-UnitTest.mk index 600fa49c..c87502db 100644 --- a/core/nbproject/Makefile-UnitTest.mk +++ b/core/nbproject/Makefile-UnitTest.mk @@ -50,10 +50,10 @@ OBJECTFILES= \ ${OBJECTDIR}/syntax_help.o \ ${OBJECTDIR}/term.o \ ${OBJECTDIR}/test/alg_test.o \ + ${OBJECTDIR}/test/compiler_test.o \ ${OBJECTDIR}/test/eval_test.o \ ${OBJECTDIR}/test/fraction_test.o \ ${OBJECTDIR}/test/lexer_test.o \ - ${OBJECTDIR}/test/newlang_test.o \ ${OBJECTDIR}/test/nlc_test.o \ ${OBJECTDIR}/test/object_test.o \ ${OBJECTDIR}/test/parser_test.o \ @@ -211,6 +211,11 @@ ${OBJECTDIR}/test/alg_test.o: test/alg_test.cpp pch.h.gch ${RM} "$@.d" $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -I/usr/lib/llvm-13/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/alg_test.o test/alg_test.cpp +${OBJECTDIR}/test/compiler_test.o: test/compiler_test.cpp pch.h.gch + ${MKDIR} -p ${OBJECTDIR}/test + ${RM} "$@.d" + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -I/usr/lib/llvm-13/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/compiler_test.o test/compiler_test.cpp + ${OBJECTDIR}/test/eval_test.o: test/eval_test.cpp pch.h.gch ${MKDIR} -p ${OBJECTDIR}/test ${RM} "$@.d" @@ -226,11 +231,6 @@ ${OBJECTDIR}/test/lexer_test.o: test/lexer_test.cpp pch.h.gch ${RM} "$@.d" $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -I/usr/lib/llvm-13/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/lexer_test.o test/lexer_test.cpp -${OBJECTDIR}/test/newlang_test.o: test/newlang_test.cpp pch.h.gch - ${MKDIR} -p ${OBJECTDIR}/test - ${RM} "$@.d" - $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -I/usr/lib/llvm-13/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/newlang_test.o test/newlang_test.cpp - ${OBJECTDIR}/test/nlc_test.o: test/nlc_test.cpp pch.h.gch ${MKDIR} -p ${OBJECTDIR}/test ${RM} "$@.d" diff --git a/core/nbproject/Makefile-UnitTest_LLVM.mk b/core/nbproject/Makefile-UnitTest_LLVM.mk index e2351714..c77d3036 100644 --- a/core/nbproject/Makefile-UnitTest_LLVM.mk +++ b/core/nbproject/Makefile-UnitTest_LLVM.mk @@ -50,10 +50,10 @@ OBJECTFILES= \ ${OBJECTDIR}/syntax_help.o \ ${OBJECTDIR}/term.o \ ${OBJECTDIR}/test/alg_test.o \ + ${OBJECTDIR}/test/compiler_test.o \ ${OBJECTDIR}/test/eval_test.o \ ${OBJECTDIR}/test/fraction_test.o \ ${OBJECTDIR}/test/lexer_test.o \ - ${OBJECTDIR}/test/newlang_test.o \ ${OBJECTDIR}/test/nlc_test.o \ ${OBJECTDIR}/test/object_test.o \ ${OBJECTDIR}/test/parser_test.o \ @@ -184,6 +184,11 @@ ${OBJECTDIR}/test/alg_test.o: test/alg_test.cpp ${RM} "$@.d" $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I/usr/lib/llvm-12/lib/clang/12.0.1/include -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I.. -std=c++14 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/alg_test.o test/alg_test.cpp +${OBJECTDIR}/test/compiler_test.o: test/compiler_test.cpp + ${MKDIR} -p ${OBJECTDIR}/test + ${RM} "$@.d" + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I/usr/lib/llvm-12/lib/clang/12.0.1/include -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I.. -std=c++14 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/compiler_test.o test/compiler_test.cpp + ${OBJECTDIR}/test/eval_test.o: test/eval_test.cpp ${MKDIR} -p ${OBJECTDIR}/test ${RM} "$@.d" @@ -199,11 +204,6 @@ ${OBJECTDIR}/test/lexer_test.o: test/lexer_test.cpp ${RM} "$@.d" $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I/usr/lib/llvm-12/lib/clang/12.0.1/include -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I.. -std=c++14 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/lexer_test.o test/lexer_test.cpp -${OBJECTDIR}/test/newlang_test.o: test/newlang_test.cpp - ${MKDIR} -p ${OBJECTDIR}/test - ${RM} "$@.d" - $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I/usr/lib/llvm-12/lib/clang/12.0.1/include -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I.. -std=c++14 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/newlang_test.o test/newlang_test.cpp - ${OBJECTDIR}/test/nlc_test.o: test/nlc_test.cpp ${MKDIR} -p ${OBJECTDIR}/test ${RM} "$@.d" diff --git a/core/nbproject/Makefile-impl.mk b/core/nbproject/Makefile-impl.mk index 9cfb5df7..4a538ba8 100644 --- a/core/nbproject/Makefile-impl.mk +++ b/core/nbproject/Makefile-impl.mk @@ -31,7 +31,7 @@ DEFAULTCONF=Debug CONF=${DEFAULTCONF} # All Configurations -ALLCONFS=Debug Release UnitTest UnitTest_LLVM GCOV LLVM LLVM_GCC +ALLCONFS=Debug Release UnitTest UnitTest_LLVM GCOV LLVM LLVM_GCC UnitTest-Win64 UnitTest-Win32 # build diff --git a/core/nbproject/Makefile-variables.mk b/core/nbproject/Makefile-variables.mk index de49585a..20be51dd 100644 --- a/core/nbproject/Makefile-variables.mk +++ b/core/nbproject/Makefile-variables.mk @@ -62,6 +62,22 @@ CND_ARTIFACT_PATH_LLVM_GCC=dist/LLVM_GCC/GNU-Linux/core CND_PACKAGE_DIR_LLVM_GCC=dist/LLVM_GCC/GNU-Linux/package CND_PACKAGE_NAME_LLVM_GCC=core.tar CND_PACKAGE_PATH_LLVM_GCC=dist/LLVM_GCC/GNU-Linux/package/core.tar +# UnitTest-Win64 configuration +CND_PLATFORM_UnitTest-Win64=Win64-x86_64-Linux +CND_ARTIFACT_DIR_UnitTest-Win64= +CND_ARTIFACT_NAME_UnitTest-Win64=newlang_test +CND_ARTIFACT_PATH_UnitTest-Win64=newlang_test +CND_PACKAGE_DIR_UnitTest-Win64=dist/UnitTest-Win64/Win64-x86_64-Linux/package +CND_PACKAGE_NAME_UnitTest-Win64=core.tar +CND_PACKAGE_PATH_UnitTest-Win64=dist/UnitTest-Win64/Win64-x86_64-Linux/package/core.tar +# UnitTest-Win32 configuration +CND_PLATFORM_UnitTest-Win32=Win32-i686-Linux +CND_ARTIFACT_DIR_UnitTest-Win32= +CND_ARTIFACT_NAME_UnitTest-Win32=newlang_test +CND_ARTIFACT_PATH_UnitTest-Win32=newlang_test +CND_PACKAGE_DIR_UnitTest-Win32=dist/UnitTest-Win32/Win32-i686-Linux/package +CND_PACKAGE_NAME_UnitTest-Win32=core.tar +CND_PACKAGE_PATH_UnitTest-Win32=dist/UnitTest-Win32/Win32-i686-Linux/package/core.tar # # include compiler specific variables # diff --git a/core/nbproject/Package-UnitTest-Win32.bash b/core/nbproject/Package-UnitTest-Win32.bash new file mode 100644 index 00000000..2688e4d0 --- /dev/null +++ b/core/nbproject/Package-UnitTest-Win32.bash @@ -0,0 +1,76 @@ +#!/bin/bash -x + +# +# Generated - do not edit! +# + +# Macros +TOP=`pwd` +CND_PLATFORM=Win32-i686-Linux +CND_CONF=UnitTest-Win32 +CND_DISTDIR=dist +CND_BUILDDIR=build +CND_DLIB_EXT=so +NBTMPDIR=${CND_BUILDDIR}/${CND_CONF}/${CND_PLATFORM}/tmp-packaging +TMPDIRNAME=tmp-packaging +OUTPUT_PATH=newlang_test +OUTPUT_BASENAME=newlang_test +PACKAGE_TOP_DIR=core/ + +# Functions +function checkReturnCode +{ + rc=$? + if [ $rc != 0 ] + then + exit $rc + fi +} +function makeDirectory +# $1 directory path +# $2 permission (optional) +{ + mkdir -p "$1" + checkReturnCode + if [ "$2" != "" ] + then + chmod $2 "$1" + checkReturnCode + fi +} +function copyFileToTmpDir +# $1 from-file path +# $2 to-file path +# $3 permission +{ + cp "$1" "$2" + checkReturnCode + if [ "$3" != "" ] + then + chmod $3 "$2" + checkReturnCode + fi +} + +# Setup +cd "${TOP}" +mkdir -p ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package +rm -rf ${NBTMPDIR} +mkdir -p ${NBTMPDIR} + +# Copy files and create directories and links +cd "${TOP}" +makeDirectory "${NBTMPDIR}/core/bin" +copyFileToTmpDir "${OUTPUT_PATH}" "${NBTMPDIR}/${PACKAGE_TOP_DIR}bin/${OUTPUT_BASENAME}" 0755 + + +# Generate tar file +cd "${TOP}" +rm -f ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/core.tar +cd ${NBTMPDIR} +tar -vcf ../../../../${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/core.tar * +checkReturnCode + +# Cleanup +cd "${TOP}" +rm -rf ${NBTMPDIR} diff --git a/core/nbproject/Package-UnitTest-Win64.bash b/core/nbproject/Package-UnitTest-Win64.bash new file mode 100644 index 00000000..318ca153 --- /dev/null +++ b/core/nbproject/Package-UnitTest-Win64.bash @@ -0,0 +1,76 @@ +#!/bin/bash -x + +# +# Generated - do not edit! +# + +# Macros +TOP=`pwd` +CND_PLATFORM=Win64-x86_64-Linux +CND_CONF=UnitTest-Win64 +CND_DISTDIR=dist +CND_BUILDDIR=build +CND_DLIB_EXT=so +NBTMPDIR=${CND_BUILDDIR}/${CND_CONF}/${CND_PLATFORM}/tmp-packaging +TMPDIRNAME=tmp-packaging +OUTPUT_PATH=newlang_test +OUTPUT_BASENAME=newlang_test +PACKAGE_TOP_DIR=core/ + +# Functions +function checkReturnCode +{ + rc=$? + if [ $rc != 0 ] + then + exit $rc + fi +} +function makeDirectory +# $1 directory path +# $2 permission (optional) +{ + mkdir -p "$1" + checkReturnCode + if [ "$2" != "" ] + then + chmod $2 "$1" + checkReturnCode + fi +} +function copyFileToTmpDir +# $1 from-file path +# $2 to-file path +# $3 permission +{ + cp "$1" "$2" + checkReturnCode + if [ "$3" != "" ] + then + chmod $3 "$2" + checkReturnCode + fi +} + +# Setup +cd "${TOP}" +mkdir -p ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package +rm -rf ${NBTMPDIR} +mkdir -p ${NBTMPDIR} + +# Copy files and create directories and links +cd "${TOP}" +makeDirectory "${NBTMPDIR}/core/bin" +copyFileToTmpDir "${OUTPUT_PATH}" "${NBTMPDIR}/${PACKAGE_TOP_DIR}bin/${OUTPUT_BASENAME}" 0755 + + +# Generate tar file +cd "${TOP}" +rm -f ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/core.tar +cd ${NBTMPDIR} +tar -vcf ../../../../${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/core.tar * +checkReturnCode + +# Cleanup +cd "${TOP}" +rm -rf ${NBTMPDIR} diff --git a/core/nbproject/configurations.xml b/core/nbproject/configurations.xml index f9cefb1f..add5a9b5 100644 --- a/core/nbproject/configurations.xml +++ b/core/nbproject/configurations.xml @@ -15,10 +15,10 @@ test/alg_test.cpp + test/compiler_test.cpp test/eval_test.cpp test/fraction_test.cpp test/lexer_test.cpp - test/newlang_test.cpp test/nlc_test.cpp test/object_test.cpp test/parser_test.cpp @@ -322,19 +322,19 @@ pch.h.gch - + pch.h.gch - - - + pch.h.gch - + + + pch.h.gch @@ -511,14 +511,14 @@ + + - - @@ -770,19 +770,19 @@ pch.h.gch - + pch.h.gch - - - + pch.h.gch - + + + pch.h.gch @@ -1044,14 +1044,14 @@ + + - - @@ -1259,14 +1259,14 @@ + + - - @@ -1502,14 +1502,14 @@ + + - - @@ -1741,14 +1741,14 @@ + + - - @@ -1779,5 +1779,590 @@ + + + Win64-x86_64|GNU + true + false + + + + true + 10 + + .. + ../contrib/googletest/googletest + ../contrib/googletest/googletest/include + /usr/share/mingw-w64/include/ + + + DEBUG + LOG_LEVEL_NORMAL=LOG_LEVEL_DUMP + UNITTEST + + + + + .. + ../contrib/googletest/googletest + ../contrib/googletest/googletest/include + ../contrib/Lyra/include + ../contrib/libtorch-win/include/torch/csrc/api/include + ../contrib/libtorch-win/include + ../contrib/tensorboard_logger/include + /usr/share/mingw-w64/include/ + + -std=c++17 --no-gnu-unique -Wno-trigraphs -Winvalid-pch -Werror=return-type -Wmaybe-uninitialized -Wuninitialized -Wformat -Wmaybe-uninitialized + + DEBUG + LOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG + PDC_WIDE + UNITTEST + + false + + + newlang_test + + ../contrib/libtorch/lib + + + ../contrib/libtorch/lib + + + PosixThreads + DynamicLinking + ../contrib/libffi/output/lib/libffi.a + crypto + LLVM-13 + torch + c10 + torch_cpu + + -Wl,--export-dynamic -static-libgcc -static-libstdc++ + + + + + + + -Wno-error -Wno-all -Wno-extra -Wno-ctor-dtor-privacy -Wno-undef -Wno-sign-compare + + + + + -Wno-error -Wno-all -Wno-extra -Wno-ctor-dtor-privacy -Wno-undef -Wno-sign-compare -Wno-conversion + + + + + + + + + + + + + + + + + + + + + 0 + parser.h parser.yy.h pch.h.gch location.hh + + + + + pch.h.gch + + + + + parser.h parser.yy.h pch.h.gch location.hh + + + + + pch.h.gch + + + + + + + location.hh + + + + + parser.yy.h parser.yy.cpp location.hh pch.h.gch + + + + + ./compile_syntax.sh + + lexer.yy.cpp lexer.yy.h + parser.y parser.yy.h parser.yy.cpp location.hh term.h + + + + + parser.y parser.yy.h parser.yy.cpp location.hh + + + + + pch.h.gch + + + + + + + parser.h parser.yy.h pch.h.gch location.hh + + + + + pch.h.gch + + + + + parser.h parser.yy.h pch.h.gch location.hh + + + + + + + + + parser.h parser.yy.h pch.h.gch location.hh + + + + + pch.h.gch + + + + + parser.h parser.yy.h pch.h.gch location.hh + + + + + pch.h.gch + + + + + ./compile_syntax.sh + ************* Bison compile ************* + parser.yy.h parser.yy.cpp location.hh + + + + + parser.y + + + + + parser.y pch.h.gch + + + + + g++ -o pch.h.gch -c pch.h -g -I.. -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include --no-gnu-unique -Wno-trigraphs -Winvalid-pch -Werror=return-type -Wmaybe-uninitialized -Wuninitialized -Wformat -Wmaybe-uninitialized -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I.. -I../contrib/tensorboard_logger/include -I/usr/lib/llvm-13/include -I/usr/include -std=c++17 + pch.h.gch + + + + + + + + + parser.h parser.yy.h pch.h.gch location.hh + + + + + parser.yy.cpp location.hh pch.h.gch + + + + + pch.h.gch + + + + + pch.h.gch + + + + + pch.h.gch + + + + + + + pch.h.gch + + + + + pch.h.gch + + + + + pch.h.gch + + + + + pch.h.gch + + + + + pch.h.gch + + + + + pch.h.gch + + + + + pch.h.gch + + + + + + + + + parser.yy.cpp location.hh + + + + + parser.yy.cpp location.hh + + + + + + Win32-i686|GNU + true + false + + + + true + 10 + + .. + ../contrib/googletest/googletest + ../contrib/googletest/googletest/include + + + DEBUG + LOG_LEVEL_NORMAL=LOG_LEVEL_DUMP + UNITTEST + + + + + .. + ../contrib/googletest/googletest + ../contrib/googletest/googletest/include + ../contrib/Lyra/include + ../contrib/libtorch/include/torch/csrc/api/include + ../contrib/libtorch/include + ../contrib/tensorboard_logger/include + /usr/lib/llvm-13/include + + -std=c++17 --no-gnu-unique -Wno-trigraphs -Winvalid-pch -Werror=return-type -Wmaybe-uninitialized -Wuninitialized -Wformat -Wmaybe-uninitialized + + DEBUG + LOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG + PDC_WIDE + UNITTEST + + false + + + newlang_test + + ../contrib/libtorch/lib + + + ../contrib/libtorch/lib + + + PosixThreads + DynamicLinking + ../contrib/libffi/output/lib/libffi.a + crypto + LLVM-13 + torch + c10 + torch_cpu + + -Wl,--export-dynamic + + + + + + + -Wno-error -Wno-all -Wno-extra -Wno-ctor-dtor-privacy -Wno-undef -Wno-sign-compare + + + + + -Wno-error -Wno-all -Wno-extra -Wno-ctor-dtor-privacy -Wno-undef -Wno-sign-compare -Wno-conversion + + + + + + + + + + + + + + + + + + + + + 0 + parser.h parser.yy.h pch.h.gch location.hh + + + + + pch.h.gch + + + + + parser.h parser.yy.h pch.h.gch location.hh + + + + + pch.h.gch + + + + + + + location.hh + + + + + parser.yy.h parser.yy.cpp location.hh pch.h.gch + + + + + ./compile_syntax.sh + + lexer.yy.cpp lexer.yy.h + parser.y parser.yy.h parser.yy.cpp location.hh term.h + + + + + parser.y parser.yy.h parser.yy.cpp location.hh + + + + + pch.h.gch + + + + + + + parser.h parser.yy.h pch.h.gch location.hh + + + + + pch.h.gch + + + + + parser.h parser.yy.h pch.h.gch location.hh + + + + + + + + + parser.h parser.yy.h pch.h.gch location.hh + + + + + pch.h.gch + + + + + parser.h parser.yy.h pch.h.gch location.hh + + + + + pch.h.gch + + + + + ./compile_syntax.sh + ************* Bison compile ************* + parser.yy.h parser.yy.cpp location.hh + + + + + parser.y + + + + + parser.y pch.h.gch + + + + + g++ -o pch.h.gch -c pch.h -g -I.. -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include --no-gnu-unique -Wno-trigraphs -Winvalid-pch -Werror=return-type -Wmaybe-uninitialized -Wuninitialized -Wformat -Wmaybe-uninitialized -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I.. -I../contrib/tensorboard_logger/include -I/usr/lib/llvm-13/include -std=c++17 + pch.h.gch + + + + + + + + + parser.h parser.yy.h pch.h.gch location.hh + + + + + parser.yy.cpp location.hh pch.h.gch + + + + + pch.h.gch + + + + + pch.h.gch + + + + + pch.h.gch + + + + + + + pch.h.gch + + + + + pch.h.gch + + + + + pch.h.gch + + + + + pch.h.gch + + + + + pch.h.gch + + + + + pch.h.gch + + + + + pch.h.gch + + + + + + + + + parser.yy.cpp location.hh + + + + + parser.yy.cpp location.hh + + + diff --git a/core/nbproject/project.xml b/core/nbproject/project.xml index 0c860edf..0c2ab82e 100644 --- a/core/nbproject/project.xml +++ b/core/nbproject/project.xml @@ -41,6 +41,14 @@ LLVM_GCC 1 + + UnitTest-Win64 + 1 + + + UnitTest-Win32 + 1 + false diff --git a/core/newlang.cpp b/core/newlang.cpp index ca314e3c..e418f2bc 100644 --- a/core/newlang.cpp +++ b/core/newlang.cpp @@ -206,6 +206,7 @@ std::string NewLang::WriteSimpleBody_(CompileInfo &ci, TermPtr &func) { // result += (*func_op)(ci, func, FunctionStep::COMPLETE); // // return result; + return ""; } bool newlang::Tranliterate(const wchar_t c, std::wstring &str) { @@ -633,7 +634,7 @@ std::string NewLang::MakeCppFileVariable(CompileInfo &ci, TermPtr &var, std::ost std::string NewLang::MakeCppFileCallArgs(CompileInfo &ci, TermPtr &args, TermPtr proto) { std::string result; - for (size_t i = 0; i < args->size(); i++) { + for (int i = 0; i < args->size(); i++) { if(i) { result += ", "; } @@ -728,48 +729,48 @@ bool NewLang::MakeCppFile(TermPtr ast, std::ostream &out, const char * source, C } bool NewLang::Execute(const char *exec, std::string *out, int *exit_code) { - int status; - pid_t pid; - - int mypipe[2]; - pipe(mypipe); - - pid = fork(); - if(pid < 0) { - LOG_ERROR("Fork fail"); - return false; - } else if(!pid) { - close(mypipe[0]); /* close unused in */ - dup2(mypipe[1], 1); /* stdout to pipe out */ - - execl("/bin/bash", "bash", "-c", exec, NULL); - - close(mypipe[1]); - _exit(EXIT_SUCCESS); - } - - pid = wait(&status); - - /* parent process */ - close(mypipe[1]); /* close unused out */ - - char buf[1024] = ""; - ssize_t nbytes; - /* read from pipe in */ - while((nbytes = read(mypipe[0], buf, sizeof (buf))) > 0) { - if(out) { - out->append(buf, nbytes); - } - } - close(mypipe[0]); - - if(WIFEXITED(status)) { - if(exit_code) { - - *exit_code = WEXITSTATUS(status); - } - return true; - } +// int status; +// pid_t pid; +// +// int mypipe[2]; +// pipe(mypipe); +// +// pid = fork(); +// if(pid < 0) { +// LOG_ERROR("Fork fail"); +// return false; +// } else if(!pid) { +// close(mypipe[0]); /* close unused in */ +// dup2(mypipe[1], 1); /* stdout to pipe out */ +// +// execl("/bin/bash", "bash", "-c", exec, NULL); +// +// close(mypipe[1]); +// _exit(EXIT_SUCCESS); +// } +// +// pid = wait(&status); +// +// /* parent process */ +// close(mypipe[1]); /* close unused out */ +// +// char buf[1024] = ""; +// ssize_t nbytes; +// /* read from pipe in */ +// while((nbytes = read(mypipe[0], buf, sizeof (buf))) > 0) { +// if(out) { +// out->append(buf, nbytes); +// } +// } +// close(mypipe[0]); +// +// if(WIFEXITED(status)) { +// if(exit_code) { +// +// *exit_code = WEXITSTATUS(status); +// } +// return true; +// } return false; } @@ -970,62 +971,63 @@ bool NewLang::CompileModule(const char* filename, const char* output) { bool NewLang::GccMakeModule(const char * in_file, const char * module, const char * opts, std::string *out, int *exit_code) { - char temp[MAXPATHLEN]; - if(!getcwd(temp, sizeof (temp))) { - return false; - } + //char temp[MAXPATHLEN]; + //if(!getcwd(temp, sizeof (temp))) { + // return false; + //} - std::string dir(temp); + //std::string dir(temp); - std::string out_file(dir); + //std::string out_file(dir); - out_file.append("/"); - out_file.append(module); - // out_file.append(".so"); + //out_file.append("/"); + //out_file.append(module); + //// out_file.append(".so"); - if(!opts) { - struct stat file_src; - struct stat file_so; - if(lstat(in_file, &file_src) == 0 && lstat(out_file.c_str(), &file_so) == 0) { - if(file_src.st_mtime < file_so.st_mtime && file_so.st_size) { - LOG_DEBUG("Skip build %s", out_file.c_str()); - return true; - } - } - } + //if(!opts) { + // struct stat file_src; + // struct stat file_so; + // if(lstat(in_file, &file_src) == 0 && lstat(out_file.c_str(), &file_so) == 0) { + // if(file_src.st_mtime < file_so.st_mtime && file_so.st_size) { + // LOG_DEBUG("Skip build %s", out_file.c_str()); + // return true; + // } + // } + //} - std::remove(out_file.c_str()); + //std::remove(out_file.c_str()); - //g++ -std=c++17 -c -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -MMD -MP -MF "test_gen.cpp.o.d" -o test_out.o test_gen.cpp + ////g++ -std=c++17 -c -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -MMD -MP -MF "test_gen.cpp.o.d" -o test_out.o test_gen.cpp - std::string exec("cd "); - exec.append(dir); - exec.append(" && "); + //std::string exec("cd "); + //exec.append(dir); + //exec.append(" && "); - exec.append("g++ -std=c++14 -Werror=return-type -c -g -fPIC -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG "); - if(opts) { - exec.append(opts); - } - exec.append(" -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/torch/include/torch/csrc/api/include -I../contrib/torch/include -MMD -MP -MF \""); - exec.append(in_file); - exec.append(".o.d\" -o "); - exec.append(in_file); - exec.append(".o "); - exec.append(in_file); + //exec.append("g++ -std=c++14 -Werror=return-type -c -g -fPIC -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG "); + //if(opts) { + // exec.append(opts); + //} + //exec.append(" -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/torch/include/torch/csrc/api/include -I../contrib/torch/include -MMD -MP -MF \""); + //exec.append(in_file); + //exec.append(".o.d\" -o "); + //exec.append(in_file); + //exec.append(".o "); + //exec.append(in_file); - exec.append(" && "); + //exec.append(" && "); - //g++ -o test_gen.so test_gen.o -shared -fPIC - exec.append("g++ -o "); - exec.append(out_file); - exec.append(" "); - exec.append(in_file); - exec.append(".o -shared -fPIC"); + ////g++ -o test_gen.so test_gen.o -shared -fPIC + //exec.append("g++ -o "); + //exec.append(out_file); + //exec.append(" "); + //exec.append(in_file); + //exec.append(".o -shared -fPIC"); - LOG_DEBUG("%s", exec.c_str()); + //LOG_DEBUG("%s", exec.c_str()); - return Execute(exec.c_str(), out, exit_code); + //return Execute(exec.c_str(), out, exit_code); + return false; } NewLang::NewLang(RuntimePtr rt) : m_runtime(rt) { @@ -1200,14 +1202,14 @@ ObjPtr NewLang::GetIndexField(Context *ctx, ObjPtr obj, TermPtr term, bool creat // } // return lval; // -// } else if(term_id == TermID::SIMPLE || term_id == TermID::FUNCTION || term_id == TermID::TRANSPARENT) { +// } else if(term_id == TermID::SIMPLE || term_id == TermID::FUNCTION || term_id == TermID::PUREFUNC) { // if(!make_function) { // Игнорировать определения функций при выполнении // // Ничего не делаем // ObjType type; // switch(term_id) { // case TermID::SIMPLE: -// case TermID::TRANSPARENT: -// type = ObjType::TRANSPARENT; +// case TermID::PUREFUNC: +// type = ObjType::PUREFUNC; // break; // case TermID::FUNCTION: // type = ObjType::FUNCTION; @@ -1277,8 +1279,8 @@ bool RunTime::LoadModule(const char *name_str, bool init, Context *ctx, const ch // ObjType type; // switch(proto->getTermID()) { // case TermID::SIMPLE: -// case TermID::TRANSPARENT: -// type = ObjType::TRANSPARENT; +// case TermID::PUREFUNC: +// type = ObjType::PUREFUNC; // break; // case TermID::FUNCTION: // type = ObjType::FUNCTION; @@ -1386,7 +1388,7 @@ bool CheckClearFunction(TermPtr term) { // } // // for (auto &elem : m_global_funcs) { -// if((elem.second->m_func_source) && ((elem.second->m_func_source)->getTermID() == TermID::SIMPLE || (elem.second->m_func_source)->getTermID() == TermID::TRANSPARENT)) { +// if((elem.second->m_func_source) && ((elem.second->m_func_source)->getTermID() == TermID::SIMPLE || (elem.second->m_func_source)->getTermID() == TermID::PUREFUNC)) { // TermPtr term = (elem.second->m_func_source)->Right(); // if(!CheckClearFunction(term)) { // LOG_DEBUG("The function '%s' cannot be saved because it is not clean!", elem.second->m_func_source->Left()->toString().c_str()); @@ -1404,8 +1406,8 @@ bool CheckClearFunction(TermPtr term) { // return RunTime::Instance()->ExecModule(name, ReplaceFileExt(name, ".ctx", ".nlm").c_str(), true, ctx)->getType() != ObjType::Error; //} -ObjPtr RunTime::ExecModule(const char *module, const char *output, bool cached, Context * ctx) { - std::string source = ReadFile(module); +ObjPtr RunTime::ExecModule(const char *mod, const char *output, bool cached, Context * ctx) { + /*std::string source = ReadFile(mod); Obj args; if(cached && access(output, F_OK) != -1 && LoadModule(output, true)) { if(m_modules[output]->m_source && *(m_modules[output]->m_source) && source.compare(*(m_modules[output]->m_source)) == 0) { @@ -1417,8 +1419,9 @@ ObjPtr RunTime::ExecModule(const char *module, const char *output, bool cached, } if(NewLang::CompileModule(module, output) && LoadModule(output)) { return m_modules[output]->Main(ctx, args); - } - LOG_RUNTIME("Fail compile module '%s' form file '%s'.", output, module); + }*/ + LOG_RUNTIME("Fail compile module '%s' form file '%s'.", output, mod); + return nullptr; } void NewLang::ReplaceSourceVariable(CompileInfo &ci, size_t count, std::string &body) { @@ -1449,7 +1452,6 @@ std::string NewLang::GetImpl(CompileInfo &ci, TermPtr term, std::string &output) std::string temp; std::string temp2; - size_t index; std::vector iters; TermPtr proto; TermPtr proto2; @@ -1490,7 +1492,7 @@ std::string NewLang::GetImpl(CompileInfo &ci, TermPtr term, std::string &output) case TermID::DICT: temp = ""; - for (size_t i = 0; i < term->size(); i++) { + for (int i = 0; i < term->size(); i++) { if(!temp.empty()) { temp += ", "; } @@ -1663,7 +1665,7 @@ std::string NewLang::GetImpl(CompileInfo &ci, TermPtr term, std::string &output) ASSERT(term->Left()); result = BeginIterators(ci, term->Left(), output, iters); - for (size_t i = 0; i < iters.size(); i++) { + for (int i = 0; i < iters.size(); i++) { output += ci.GetIndent(i) + "while(!" + iters[i] + ".complete()) {\n"; } @@ -1771,7 +1773,7 @@ std::string NewLang::MakeIteratorCallArgs_(CompileInfo &ci, TermPtr args, std::v std::string result; size_t iter_pos = 0; - for (size_t i = 0; i < args->size(); i++) { + for (int i = 0; i < args->size(); i++) { std::string impl; if(i) { @@ -1815,7 +1817,7 @@ std::string NewLang::BeginIterators(CompileInfo &ci, TermPtr args, std::string & // Аргументы функции с локальным доступом по имени или ииндексу if(args->size()) { - for (size_t i = 0; i < args->size(); i++) { + for (int i = 0; i < args->size(); i++) { if((*args)[i]->GetTokenID() == TermID::ITERATOR) { std::string name; if((*args)[i]->getText().compare("!") == 0) { diff --git a/core/newlang.h b/core/newlang.h index 187e804a..5b3d8ec0 100644 --- a/core/newlang.h +++ b/core/newlang.h @@ -40,7 +40,7 @@ T repeat(T str, const std::size_t n) { } class Context; -class CompileInfo; +struct CompileInfo; class Module { public: @@ -56,14 +56,22 @@ class Module { bool Load(const char *name) { m_name = name; +#ifdef _MSC_VER + m_handle = nullptr; +#else m_handle = dlopen(name, RTLD_LAZY | RTLD_LOCAL); // Для GCC нужно собирать с --no-gnu-unique для замены модулей в рантайме +#endif return m_handle; } virtual ~Module() { //Если динамическая библиотека экпортировала функцию, названную _fini, то эта функция вызывается перед выгрузкой библиотеки. if (m_handle) { +#ifdef _MSC_VER + m_handle = nullptr; +#else dlclose(m_handle); +#endif } m_handle = nullptr; } @@ -159,7 +167,7 @@ struct CompileInfo { size_t indent; - std::string GetIndent(int offset = 0) { + std::string GetIndent(int64_t offset = 0) { return repeat(std::string(NEWLANG_INDENT_OP), indent + offset); } diff --git a/core/nlc.cpp b/core/nlc.cpp index 989d7524..3d21d9fd 100644 --- a/core/nlc.cpp +++ b/core/nlc.cpp @@ -5,6 +5,26 @@ using namespace std; using namespace newlang; +#ifdef _MSC_VER + +#pragma comment(lib, "torch.lib") +#pragma comment(lib, "torch_cpu.lib") +#pragma comment(lib, "c10.lib") +#pragma comment(lib, "libffi.a") + +//#pragma comment(lib, "pthreadpool.lib") +//#pragma comment(lib, "libprotoc.lib") +//#pragma comment(lib, "XNNPACK.lib") +//#pragma comment(lib, "dnnl.lib") +//#pragma comment(lib, "asmjit.lib") +//#pragma comment(lib, "cpuinfo.lib") +// +//#pragma comment(lib, "clog.lib") +//#pragma comment(lib, "fbgemm.lib") +//#pragma comment(lib, "kineto.lib") + +#endif + #ifndef UNITTEST int main(int argc, char** argv) { diff --git a/core/nlc.h b/core/nlc.h index 3ff10474..93249a64 100644 --- a/core/nlc.h +++ b/core/nlc.h @@ -40,12 +40,12 @@ namespace newlang { public: #define NLC_MODE(_) \ - _(ERROR, 0) \ - _(HELP, 1)\ - _(VERSION, 2)\ - _(INTERACTIVE, 3)\ - _(EVAL, 4) \ - _(EXEC, 5) + _(ModeError, 0) \ + _(ModeHelp, 1)\ + _(ModeVersion, 2)\ + _(ModeInter, 3)\ + _(ModeEval, 4) \ + _(ModeExec, 5) // _(COMPILE, 6) @@ -89,13 +89,13 @@ namespace newlang { void *m_log_callback_arg_save; NLC() : m_ctx(RunTime::Init()) { - m_mode = Mode::ERROR; + m_mode = Mode::ModeError; m_log_callback_save = nullptr; m_log_callback_arg_save = nullptr; } NLC(int argc, const char** argv) : m_ctx(RunTime::Init(argc, argv)) { - m_mode = Mode::ERROR; + m_mode = Mode::ModeError; m_log_callback_save = nullptr; m_log_callback_arg_save = nullptr; ParseArgs(argc, argv); @@ -120,7 +120,6 @@ namespace newlang { std::string s(str); size_t pos; - size_t end; s.erase(0, s.find_first_not_of(delim)); while (!s.empty()) { pos = s.find(delim); @@ -150,7 +149,7 @@ namespace newlang { } } - bool ParseArgs(int argc, const char** argv) { + bool ParseArgs(int64_t argc, const char** argv) { if (!argc || !argv) { m_output = "Bad args nullptr"; @@ -168,7 +167,7 @@ namespace newlang { } - m_mode = Mode::INTERACTIVE; + m_mode = Mode::ModeInter; if (argc) { m_path = argv[0]; } else { @@ -212,9 +211,9 @@ namespace newlang { ; - auto result = cli.parse({argc, argv}); + auto result = cli.parse({static_cast(argc), argv}); if (!result) { - m_mode = Mode::ERROR; + m_mode = Mode::ModeError; m_output = result.message(); return false; } @@ -224,7 +223,7 @@ namespace newlang { } if (is_help) { - m_mode = Mode::HELP; + m_mode = Mode::ModeHelp; std::ostringstream out; out << cli; m_output = out.str(); @@ -232,7 +231,7 @@ namespace newlang { } if (is_ver) { - m_mode = Mode::VERSION; + m_mode = Mode::ModeVersion; m_output = "Version info"; return true; } @@ -247,7 +246,7 @@ namespace newlang { cnt += !m_eval.empty(); if (cnt > 1) { - m_mode = Mode::ERROR; + m_mode = Mode::ModeError; m_output = "Select only one mode: Compile, eXec or Eval!"; // } else if (!compile.empty()) { // m_mode = Mode::COMPILE; @@ -256,12 +255,12 @@ namespace newlang { // m_mode = Mode::EXEC; // m_ifile = exec; } else if (!m_eval.empty() || !m_ifile.empty()) { - m_mode = Mode::EVAL; + m_mode = Mode::ModeEval; } else { - m_mode = Mode::INTERACTIVE; + m_mode = Mode::ModeInter; } - return m_mode != Mode::ERROR; + return m_mode != Mode::ModeError; } int Run() { @@ -280,7 +279,7 @@ namespace newlang { // } // } - if (m_mode == Mode::ERROR || m_mode == Mode::VERSION || m_mode == Mode::HELP) { + if (m_mode == Mode::ModeError || m_mode == Mode::ModeVersion || m_mode == Mode::ModeHelp) { LOG_INFO("%s", m_output.c_str()); return 0; // } else if (m_mode == Mode::COMPILE || m_mode == Mode::EXEC) { @@ -309,7 +308,7 @@ namespace newlang { // // m_output = result->GetValueAsString(); // break; // } - } else if (m_mode == Mode::EVAL) { + } else if (m_mode == Mode::ModeEval) { if (!m_eval.empty() && !m_ifile.empty()) { LOG_RUNTIME("Error at the same time specified a source file '%s' and an expression '%s' !", m_ifile.c_str(), m_eval.c_str()); } else if (!m_ifile.empty()) { @@ -345,7 +344,7 @@ namespace newlang { utils::Logger::Instance()->SetLogLevel(save_level); } } else { - ASSERT(m_mode == Mode::INTERACTIVE); + ASSERT(m_mode == Mode::ModeInter); Interative(); // LOG_INFO("%s", m_output.c_str()); } @@ -388,14 +387,20 @@ namespace newlang { const char* title = ">"; +#ifdef _MSC_VER + COLOR_TYPE title_color = 0; + COLOR_TYPE predict_color = 0; + COLOR_TYPE main_color = 0; +#else COLOR_TYPE title_color = "1"; COLOR_TYPE predict_color = "80"; COLOR_TYPE main_color = "0"; +#endif std::wstring buff; // Cursor offset in buffer for moving - int offset = 0; + int64_t offset = 0; color_print("Type ", predict_color); color_print("help()", main_color); @@ -411,7 +416,7 @@ namespace newlang { while (1) { - int history_pos = history.size(); + int64_t history_pos = history.size(); while (1) { // Print title with title color @@ -486,14 +491,14 @@ namespace newlang { } break; }// Keyboard interrupt handler for Windows -#if defined(OS_WINDOWS) - else if (ch == CTRL_C) { - predictions_free(pred); - tree_free(rules); - free(buff); - exit(0); - } -#endif +//#if defined(OS_WINDOWS) +// else if (ch == CTRL_C) { +// predictions_free(pred); +// tree_free(rules); +// free(buff); +// exit(0); +// } +//#endif // Edit buffer like backspace if BACKSPACE was pressed else if (ch == KEY_BACKSPACE) { if (buff.size() && buff.size() - offset >= 1) { @@ -528,7 +533,7 @@ namespace newlang { switch (_getch()) { case KEY_LEFT: // Increase offset from the end of the buffer if left key pressed - offset = (offset < buff.size()) ? (offset + 1) : buff.size(); + offset = (offset < static_cast(buff.size())) ? (offset + 1) : buff.size(); break; case KEY_RIGHT: // Decrease offset from the end of the buffer if left key pressed @@ -542,7 +547,7 @@ namespace newlang { } break; case KEY_DOWN: - if (!history.empty() && history_pos + 1 < history.size()) { + if (!history.empty() && history_pos + 1 < static_cast(history.size())) { clear_line(); history_pos++; buff = utf8_decode(history[history_pos]); diff --git a/core/object.cpp b/core/object.cpp index 224ffc65..d5c64c37 100644 --- a/core/object.cpp +++ b/core/object.cpp @@ -89,7 +89,7 @@ int64_t Obj::resize_(int64_t size, ObjPtr fill, const std::string name) { } else { // Если размер отрицательный - добавить или удалить вначале size = -size; - if(m_data.size() > size) { + if(static_cast (m_data.size()) > size) { if(m_var_type_current == ObjType::StrChar) { m_str.erase(0, size); return m_str.size(); @@ -98,7 +98,7 @@ int64_t Obj::resize_(int64_t size, ObjPtr fill, const std::string name) { m_str.erase(0, size); return m_wstr.size(); } - } else if(m_data.size() < size) { + } else if(static_cast (m_data.size()) < size) { if(m_var_type_current == ObjType::StrChar) { m_str.insert(0, size, ' '); return m_str.size(); @@ -175,13 +175,13 @@ int64_t Obj::resize_(int64_t size, ObjPtr fill, const std::string name) { const Variable::PairType & Obj::at(int64_t index) const { if(m_var_type_current == ObjType::StrChar) { - if(index < m_str.size()) { + if(index < static_cast (m_str.size())) { m_str_pair = pair(CreateString(std::string(1, m_str[index]))); return m_str_pair; } LOG_RUNTIME("Index '%lu' not exists in byte string '%s'!", static_cast (index), m_str.c_str()); } else if(m_var_type_current == ObjType::StrWide) { - if(index < m_wstr.size()) { + if(index < static_cast (m_wstr.size())) { m_str_pair = pair(CreateString(std::wstring(1, m_wstr[index]))); return m_str_pair; } @@ -197,13 +197,13 @@ const Variable::PairType & Obj::at(int64_t index) const { Variable::PairType & Obj::at(int64_t index) { if(m_var_type_current == ObjType::StrChar) { - if(index < m_str.size()) { + if(index < static_cast (m_str.size())) { m_str_pair = pair(CreateString(std::string(1, m_str[index]))); return m_str_pair; } LOG_RUNTIME("Index '%lu' not exists in byte string '%s'!", static_cast (index), m_str.c_str()); } else if(m_var_type_current == ObjType::StrWide) { - if(index < m_wstr.size()) { + if(index < static_cast (m_wstr.size())) { m_str_pair = pair(CreateString(std::wstring(1, m_wstr[index]))); return m_str_pair; } @@ -222,7 +222,7 @@ const ObjPtr Obj::index_get(const std::vector &index) const { if(index.size() != 1 || !index[0].is_integer()) { LOG_RUNTIME("The index must be an integer value '%s'!", IndexToString(index).c_str()); } - if(index[0].integer() < m_str.size()) { + if(index[0].integer() < static_cast (m_str.size())) { return CreateString(std::string(1, m_str[index[0].integer()])); } LOG_RUNTIME("Index '%s' not exists in byte string '%s'!", IndexToString(index).c_str(), m_str.c_str()); @@ -230,7 +230,7 @@ const ObjPtr Obj::index_get(const std::vector &index) const { if(index.size() != 1 || !index[0].is_integer()) { LOG_RUNTIME("The index must be an integer value '%s'!", IndexToString(index).c_str()); } - if(index[0].integer() < m_wstr.size()) { + if(index[0].integer() < static_cast (m_wstr.size())) { return CreateString(std::wstring(1, m_wstr[index[0].integer()])); } LOG_RUNTIME("Index '%s' not exists in byte string '%s'!", IndexToString(index).c_str(), "WIDE"); @@ -251,7 +251,7 @@ ObjPtr Obj::index_set_(const std::vector &index, const ObjPtr value) { if(index.size() != 1 || !index[0].is_integer()) { LOG_RUNTIME("The index must be an integer value '%s'!", IndexToString(index).c_str()); } - if(index[0].integer() < m_str.size()) { + if(index[0].integer() < static_cast (m_str.size())) { m_str.erase(index[0].integer(), 1); m_str.insert(index[0].integer(), value->toType(ObjType::StrChar)->m_str); m_var_is_init = true; @@ -262,7 +262,7 @@ ObjPtr Obj::index_set_(const std::vector &index, const ObjPtr value) { if(index.size() != 1 || !index[0].is_integer()) { LOG_RUNTIME("The index must be an integer value '%s'!", IndexToString(index).c_str()); } - if(index[0].integer() < m_wstr.size()) { + if(index[0].integer() < static_cast (m_wstr.size())) { m_wstr.erase(index[0].integer(), 1); m_wstr.insert(index[0].integer(), value->toType(ObjType::StrWide)->m_wstr); m_var_is_init = true; @@ -334,7 +334,7 @@ ObjType newlang::getSummaryTensorType(ObjPtr &obj, ObjType start) { LOG_RUNTIME("Tensor does not support named data or dimensions '%s'!", obj->getName().c_str()); } if(obj->is_dictionary_type()) { - for (size_t i = 0; i < obj->size(); i++) { + for (int i = 0; i < obj->size(); i++) { result = getSummaryTensorType(obj->at(i).second, result); } return result; @@ -376,7 +376,7 @@ ObjPtr Obj::operator+=(Obj value) { if(value.m_var_type_current == ObjType::None) { return shared(); } else if(value.m_var_type_current == ObjType::Class || value.m_var_type_current == ObjType::Dictionary) { - for (size_t i = 0; i < value.size(); i++) { + for (int i = 0; i < value.size(); i++) { push_back(value.at(i)); } return shared(); @@ -406,7 +406,7 @@ ObjPtr Obj::operator-=(Obj value) { if(value.m_var_type_current == ObjType::None) { return shared(); } else if(value.m_var_type_current == ObjType::Class || value.m_var_type_current == ObjType::Dictionary) { - for (size_t i = 0; i < value.size(); i++) { + for (int i = 0; i < value.size(); i++) { auto found = select(value.name(i)); if(!found.complete()) { erase(found); @@ -588,7 +588,6 @@ std::string Obj::toString(bool deep) const { if(!m_var_name.empty()) { result.append("="); } - size_t dot, last; std::stringstream ss; @@ -633,11 +632,11 @@ std::string Obj::toString(bool deep) const { return result; case ObjType::Range: // name:=(1,second="two",3,,5) - result = at("start")->GetValueAsString(); + result = at("start").second->GetValueAsString(); result += ".."; - result += at("stop")->GetValueAsString(); + result += at("stop").second->GetValueAsString(); result += ".."; - result += at("step")->GetValueAsString(); + result += at("step").second->GetValueAsString(); return result; case ObjType::Struct: @@ -697,8 +696,8 @@ std::string Obj::toString(bool deep) const { return result; case ObjType::NativeFunc: - case ObjType::FUNCTION: // name:={function code} - case ObjType::TRANSPARENT: // name=>{function code} + case ObjType::Function: // name:={function code} + case ObjType::PureFunc: // name=>{function code} ASSERT(m_func_proto); result += m_func_proto->m_text; result += "("; @@ -779,14 +778,14 @@ std::string Obj::toString(bool deep) const { void TensorToString_(const torch::Tensor &tensor, c10::IntArrayRef shape, std::vector &ind, const int64_t pos, std::stringstream & str) { std::string intend; - ASSERT(pos < ind.size()); + ASSERT(pos < static_cast (ind.size())); str << "["; - if(shape.size() > 1 && pos + 1 < ind.size()) { + if(shape.size() > 1 && pos + 1 < static_cast (ind.size())) { str << "\n"; intend = std::string((pos + 1) * 2, ' '); str << intend; } - if(pos + 1 < ind.size()) { + if(pos + 1 < static_cast (ind.size())) { bool comma = false; for (ind[pos] = 0; ind[pos].integer() < shape[pos]; ind[pos] = ind[pos].integer() + 1) { if(comma) { @@ -849,7 +848,6 @@ std::string newlang::TensorToString(const torch::Tensor & tensor) { std::string Obj::GetValueAsString() const { std::string result; std::string temp; - size_t dot, last; std::stringstream ss; TEST_INIT_(); @@ -880,8 +878,8 @@ std::string Obj::GetValueAsString() const { return utf8_encode(m_wstr); case ObjType::NativeFunc: - case ObjType::FUNCTION: - case ObjType::TRANSPARENT: + case ObjType::Function: + case ObjType::PureFunc: case ObjType::EVAL_FUNCTION: case ObjType::SimplePureFunc: case ObjType::SimplePureAND: @@ -922,7 +920,7 @@ std::string Obj::GetValueAsString() const { ObjPtr Obj::CreateFunc(std::string prototype, FunctionType *func_addr, ObjType type) { ASSERT(func_addr); - ASSERT(type == ObjType::FUNCTION || type == ObjType::TRANSPARENT); + ASSERT(type == ObjType::Function || type == ObjType::PureFunc); TermPtr proto = Parser::ParseString(std::string(prototype + ":={}")); @@ -937,7 +935,7 @@ ObjPtr Obj::CreateFunc(std::string prototype, FunctionType *func_addr, ObjType t } ObjPtr Obj::CreateFunc(Context *ctx, TermPtr proto, ObjType type, const std::string var_name) { - ASSERT(type == ObjType::FUNCTION || type == ObjType::TRANSPARENT); + ASSERT(type == ObjType::Function || type == ObjType::PureFunc); ObjPtr result = std::make_shared(type, var_name.c_str(), proto); Obj local; Obj args(ctx, proto, false, &local); @@ -964,7 +962,7 @@ Obj::Obj(Context *ctx, const TermPtr term, bool as_value, Obj * local_vars) { *const_cast (&m_func_proto) = term; - for (size_t i = 0; i < term->size(); i++) { + for (int i = 0; i < term->size(); i++) { if(term->name(i).empty()) { if(as_value) { // Не именованный аргумент @@ -982,7 +980,7 @@ Obj::Obj(Context *ctx, const TermPtr term, bool as_value, Obj * local_vars) { bool Obj::CheckArgs() const { bool has_error = false; bool named = false; - for (size_t start = 0; start < size(); start++) { + for (int start = 0; start < size(); start++) { if(at(start).first.empty()) { // Аргумент не имеет имени LOG_ERROR("Argument %d has no name!", (int) start + 1); @@ -996,7 +994,7 @@ bool Obj::CheckArgs() const { } } else { named = true; - for (size_t i = start + 1; i < size(); i++) { + for (int64_t i = start + 1; i < size(); i++) { if(at(start).first.compare(at(i).first) == 0) { LOG_ERROR("Duplicate named argument '%s'!", at(start).first.c_str()); has_error = true; @@ -1020,7 +1018,7 @@ ObjPtr Obj::Call(Context *ctx, Obj * args) { } else { param = Obj::CreateDict(); } - param->ConvertToArgs_(*args, true, ctx); + param->ConvertToArgs_(args, true, ctx); param->push_front(pair(shared(), "$0")); // Self if(ctx) { @@ -1028,9 +1026,9 @@ ObjPtr Obj::Call(Context *ctx, Obj * args) { } ObjPtr result; - if(m_var_type_current == ObjType::FUNCTION) { + if(m_var_type_current == ObjType::Function) { result = (*reinterpret_cast (m_func_ptr))(ctx, *param.get()); // Непосредственно вызов функции - } else if(m_var_type_current == ObjType::TRANSPARENT || (m_var_type_current == ObjType::Type && m_func_ptr)) { + } else if(m_var_type_current == ObjType::PureFunc || (m_var_type_current == ObjType::Type && m_func_ptr)) { result = (*reinterpret_cast (m_func_ptr))(ctx, *param.get()); // Непосредственно вызов функции } else if(m_var_type_current == ObjType::NativeFunc) { result = CallNative(ctx, *param.get()); @@ -1055,7 +1053,7 @@ ObjPtr Obj::Call(Context *ctx, Obj * args) { } else if(is_dictionary_type()) { ObjPtr result = Clone(); // Копия текущего объекта - result->ConvertToArgs_(*args, false, ctx); // С обновленными полями, переданными в аргументах + result->ConvertToArgs_(args, false, ctx); // С обновленными полями, переданными в аргументах result->m_class_parents.push_back(shared()); // Текущйи объект становится базовым классом для вновь создаваемого return result; @@ -1067,7 +1065,12 @@ ObjPtr Obj::Call(Context *ctx, Obj * args) { // Обновить параметры для вызова функции или элементы у словаря при создании копии -void Obj::ConvertToArgs_(Obj &in, bool check_valid, Context * ctx) { +void Obj::ConvertToArgs_(Obj *in, bool check_valid, Context * ctx) { + + if(!in) { + return; + } + bool named = false; bool is_ellipsis = false; if(check_valid && size()) { @@ -1076,20 +1079,20 @@ void Obj::ConvertToArgs_(Obj &in, bool check_valid, Context * ctx) { erase(size() - 1); } } - for (size_t i = 0; i < in.size(); i++) { + for (int i = 0; i < in->size(); i++) { - if(isInternalName(in.name(i))) { + if(isInternalName(in->name(i))) { continue; } - if(in.name(i).empty()) { + if(in->name(i).empty()) { // if(check_valid && named) { // LOG_RUNTIME("Position %d requires a named argument!", (int) i + 1); // } if(i < size()) { if(check_valid && at(i).second && at(i).second->getType() != ObjType::None) { - if(!canCast(in[i]->getType(), at(i).second->getType())) { - LOG_RUNTIME("Fail cast value '%s' to type '%s'", newlang::toString(in[i]->getType()), + if(!canCast((*in)[i]->getType(), at(i).second->getType())) { + LOG_RUNTIME("Fail cast value '%s' to type '%s'", newlang::toString((*in)[i]->getType()), newlang::toString(at(i).second->getType())); } } @@ -1104,10 +1107,10 @@ void Obj::ConvertToArgs_(Obj &in, bool check_valid, Context * ctx) { } else { base_type = ctx->BaseTypeFromString((*m_func_proto)[i]->m_type_name); } - ObjType limit_type = in[i]->getTypeAsLimit(); + ObjType limit_type = (*in)[i]->getTypeAsLimit(); if(!canCast(limit_type, base_type)) { LOG_RUNTIME("Fail cast value '%s' to type '%s'", - in[i]->toString().c_str(), (*m_func_proto)[i]->m_type_name.c_str()); + (*in)[i]->toString().c_str(), (*m_func_proto)[i]->m_type_name.c_str()); } } at(i).second->op_assign(in[i]); @@ -1116,15 +1119,15 @@ void Obj::ConvertToArgs_(Obj &in, bool check_valid, Context * ctx) { LOG_RUNTIME("Positional args overflow. Ptrototype '%s'!", m_func_proto ? m_func_proto->toString().c_str() : "Prototype not exists!"); } - push_back(in.at(i)); + push_back(in->at(i)); } } else { named = true; - auto find = select(in.name(i)); + auto find = select(in->name(i)); if(find != end()) { - if(check_valid && *find && (*find)->getType() != in[i]->getType() && (*find)->getType() != ObjType::None) { + if(check_valid && *find && (*find)->getType() != (*in)[i]->getType() && (*find)->getType() != ObjType::None) { LOG_RUNTIME("Different type arg '%s' and '%s'", (*find)->toString().c_str(), - in[i]->toString().c_str()); + (*in)[i]->toString().c_str()); } //@todo Проверка ограничений размер данных при указаном типе if(!*find) { @@ -1132,16 +1135,16 @@ void Obj::ConvertToArgs_(Obj &in, bool check_valid, Context * ctx) { } (*find)->op_assign(in[i]); } else { - for (size_t pos = 0; pos < size(); pos++) { - if(!at(pos).first.empty() && at(pos).first.compare(in.at(i).first) == 0) { + for (int pos = 0; pos < size(); pos++) { + if(!at(pos).first.empty() && at(pos).first.compare(in->at(i).first) == 0) { at(pos).second->op_assign(in[i]); goto done; } } if(check_valid && !is_ellipsis) { - LOG_RUNTIME("Named arg '%s' not found!", in.name(i).c_str()); + LOG_RUNTIME("Named arg '%s' not found!", in->name(i).c_str()); } - push_back(in.at(i)); + push_back(in->at(i)); done: ; } @@ -1155,7 +1158,7 @@ void Obj::ConvertToArgs_(Obj &in, bool check_valid, Context * ctx) { void Obj::CheckArgsValid() const { bool named = false; - for (size_t i = 0; i < Variable::size(); i++) { + for (int i = 0; i < Variable::size(); i++) { // if(!at(i).second) { // // LOG_RUNTIME("Argument %d '%s' missed!", (int) i + 1, at(i).first.c_str()); @@ -1255,7 +1258,7 @@ bool Obj::op_equal(Obj & value) { if(size() != value.size()) { return false; } - for (size_t i = 0; i < size(); i++) { + for (int64_t i = 0; i < static_cast (size()); i++) { if(name(i).compare(value.name(i)) != 0) { return false; } @@ -1292,7 +1295,7 @@ ObjPtr Obj::op_bit_and_set(Obj &obj, bool strong) { return shared(); } else if(m_var_type_current == ObjType::Dictionary || m_var_type_current == ObjType::Class) { if(obj.m_var_type_current == ObjType::Dictionary || obj.m_var_type_current == ObjType::Class) { - size_t pos = 0; + int pos = 0; while(pos < size()) { if(!obj.exist(at(pos).second, strong)) { erase(pos); @@ -1303,7 +1306,7 @@ ObjPtr Obj::op_bit_and_set(Obj &obj, bool strong) { return shared(); } } else if(is_tensor() && obj.is_tensor()) { - size_t pos = 0; + int pos = 0; while(pos < size()) { if(!obj.exist(at(pos).second, strong)) { erase(pos); @@ -1371,7 +1374,7 @@ bool Obj::op_duck_test_prop(Obj *base, Obj *value, bool strong) { return value->m_var_type_current == ObjType::None; } ObjPtr field; - for (size_t i = 0; i < value->size(); i++) { + for (int i = 0; i < value->size(); i++) { if(value->name(i).empty()) { field = (*base)[i]; } else { @@ -1454,7 +1457,7 @@ std::string Obj::format(std::string format, Obj * args) { std::string name; std::string place; std::wstring wname; - for (size_t i = 0; i < args->size(); i++) { + for (int i = 0; i < args->size(); i++) { if(isInternalName(args->name(i))) { continue; @@ -1583,7 +1586,7 @@ void Obj::toType_(ObjType target) { LOG_RUNTIME("Convert to wide string can 1..4 byte tensor only!"); } - STATIC_ASSERT(sizeof (wchar_t) == sizeof (int32_t)); + STATIC_ASSERT(sizeof (wchar_t) <= sizeof (int32_t)); if(m_value.dim() == 0) { m_wstr.resize(1); @@ -1622,8 +1625,14 @@ void Obj::toType_(ObjType target) { std_data = torch::from_blob((void *) m_str.data(),{(int) m_str.size()}, torch::Dtype::Char); } else { // ObjType::StrWide ASSERT(m_var_type_current == ObjType::StrWide); - STATIC_ASSERT(sizeof (wchar_t) == sizeof (int32_t)); - std_data = torch::from_blob((void *) m_wstr.data(),{(int) m_wstr.size()}, torch::Dtype::Int); + if(sizeof (wchar_t) == sizeof (int32_t)) { + std_data = torch::from_blob((void *) m_wstr.data(),{(int) m_wstr.size()}, torch::Dtype::Int); + } else if(sizeof (wchar_t) == sizeof (int16_t)) { + std_data = torch::from_blob((void *) m_wstr.data(),{(int) m_wstr.size()}, torch::Dtype::Short); + } else { + LOG_RUNTIME("Unsupport wchar_t size '%d'!!!", (int) sizeof (wchar_t)); + } + std_data = std_data.toType(torch::Dtype::Int); } if(isGenericType(target) && !isContainsType(target, fromTorchType(std_data.scalar_type()))) { m_value = std_data.toType(toTorchType(target)); @@ -1802,26 +1811,26 @@ torch::Tensor newlang::ConvertToTensor(Obj *data, at::ScalarType type, bool resh }, type).clone(); } else if(data->is_range()) { - ASSERT(data->at("start")); - ASSERT(data->at("stop")); - ASSERT(data->at("step")); - ASSERT(data->at("start")->is_arithmetic_type() || data->at("start")->is_bool_type()); - ASSERT(data->at("stop")->is_arithmetic_type() || data->at("stop")->is_bool_type()); - ASSERT(data->at("step")->is_arithmetic_type() || data->at("step")->is_bool_type()); + ASSERT(data->at("start").second); + ASSERT(data->at("stop").second); + ASSERT(data->at("step").second); + ASSERT(data->at("start").second->is_arithmetic_type() || data->at("start").second->is_bool_type()); + ASSERT(data->at("stop").second->is_arithmetic_type() || data->at("stop").second->is_bool_type()); + ASSERT(data->at("step").second->is_arithmetic_type() || data->at("step").second->is_bool_type()); ObjPtr dict = Obj::CreateDict(); - if(data->at("start")->is_floating() || data->at("stop")->is_floating() || data->at("step")->is_floating()) { - double value = data->at("start")->GetValueAsNumber(); - double stop = data->at("stop")->GetValueAsNumber(); - double step = data->at("step")->GetValueAsNumber(); + if(data->at("start").second->is_floating() || data->at("stop").second->is_floating() || data->at("step").second->is_floating()) { + double value = data->at("start").second->GetValueAsNumber(); + double stop = data->at("stop").second->GetValueAsNumber(); + double step = data->at("step").second->GetValueAsNumber(); for (; value < stop; value += step) { dict->push_back(Obj::CreateValue(value, ObjType::None)); } type = toTorchType(ObjType::Double); } else { - int64_t value = data->at("start")->GetValueAsInteger(); - int64_t stop = data->at("stop")->GetValueAsInteger(); - int64_t step = data->at("step")->GetValueAsInteger(); + int64_t value = data->at("start").second->GetValueAsInteger(); + int64_t stop = data->at("stop").second->GetValueAsInteger(); + int64_t step = data->at("step").second->GetValueAsInteger(); for (; value < stop; value += step) { dict->push_back(Obj::CreateValue(value, ObjType::None)); } @@ -1919,7 +1928,7 @@ ObjPtr Obj::CallNative(Context *ctx, Obj args) { size_t check_count = is_ellipsis ? m_func_proto->size() - 1 : m_func_proto->size(); // Пропустить нулевой аргумент для нативных функций - for (size_t i = 1; i < args.size(); i++) { + for (int i = 1; i < args.size(); i++) { ASSERT(args[i]); if(args[i]->m_is_reference) { @@ -2090,7 +2099,7 @@ ObjPtr Obj::CallNative(Context *ctx, Obj args) { } ASSERT(m_func_abi == FFI_DEFAULT_ABI); // Нужны другие типы вызовов ??? - if(ffi_prep_cif(&m_cif, m_func_abi, m_args_type.size(), result_ffi_type, m_args_type.data()) == FFI_OK) { + if(ffi_prep_cif(&m_cif, m_func_abi, static_cast (m_args_type.size()), result_ffi_type, m_args_type.data()) == FFI_OK) { ffi_call(&m_cif, FFI_FN(m_func_ptr), &res_value, m_args_ptr.data()); @@ -2134,105 +2143,106 @@ ObjPtr Obj::CallNative(Context *ctx, Obj args) { bool newlang::ParsePrintfFormat(Obj args, size_t start) { - if(args.size() <= start || !args[start]) { - LOG_WARNING("Missing format string!"); - return false; - } - if(!args[start]->is_string_type()) { - LOG_WARNING("Argument Format '%s' not string type!", args[start]->toString().c_str()); - return false; - } - - std::string format = args[start]->GetValueAsString(); - size_t count = parse_printf_format(format.c_str(), 0, nullptr); - std::vector types(count); - - parse_printf_format(format.c_str(), types.size(), types.data()); - bool result = true; - unsigned i = 0; - unsigned aind = start + 1; - ObjType cast; - while(i < types.size()) { - - if(aind < args.size()) { - // if(types[i] & PA_FLAG_PTR == PA_FLAG_PTR) { - // LOG_WARNING("Pointer arg '%u' not suppotred!", i); - // result = false; - // i++; - // aind++; - // continue; - // } - switch(types[i] & ~PA_FLAG_MASK) { - case PA_INT: - if(types[i] & PA_FLAG_MASK == 0) { - cast = ObjType::Int; - } else if(types[i] & PA_FLAG_LONG == PA_FLAG_LONG) { - cast = ObjType::Long; - } else if(types[i] & PA_FLAG_SHORT == PA_FLAG_SHORT) { - cast = ObjType::Short; - } - if(!canCast(args[aind]->m_var_type_current, cast)) { - LOG_WARNING("Cast '%s' to '%s' not supported!", newlang::toString(args[aind]->m_var_type_current), - newlang::toString(cast)); - result = false; - } - break; - case PA_CHAR: - if(types[i] & PA_FLAG_MASK) { - LOG_WARNING("format modifier arg '%s' %u not supported!", newlang::toString(args[aind]->m_var_type_current), i); - result = false; - } - cast = ObjType::Char; - if(!canCast(args[aind]->m_var_type_current, cast)) { - LOG_WARNING("Cast '%s' to '%s' not supported!", newlang::toString(args[aind]->m_var_type_current), - newlang::toString(cast)); - result = false; - } - break; - case PA_STRING: - if(types[i] & PA_FLAG_MASK) { - LOG_WARNING("format modifier arg '%s' %u not supported!", newlang::toString(args[aind]->m_var_type_current), i); - result = false; - } - cast = ObjType::StrChar; - if(!canCast(args[aind]->m_var_type_current, cast)) { - LOG_WARNING("Cast '%s' to '%s' not supported!", newlang::toString(args[aind]->m_var_type_current), - newlang::toString(cast)); - result = false; - } - break; - case PA_FLOAT: - case PA_DOUBLE: - if(types[i] & PA_FLAG_MASK) { - LOG_WARNING("format modifier arg '%s' %u not supported!", newlang::toString(args[aind]->m_var_type_current), i); - result = false; - } - cast = ObjType::Double; - if(!canCast(args[aind]->m_var_type_current, cast)) { - LOG_WARNING("Cast '%s' to '%s' not supported!", newlang::toString(args[aind]->m_var_type_current), - newlang::toString(cast)); - result = false; - } - break; - default: - LOG_WARNING("Arg '%u' not supported!", i); - // PA_WCHAR, /* wide char */ - // PA_WSTRING, /* const wchar_t *, wide character string */ - // PA_POINTER, /* void * */ - result = false; - } - } else { - LOG_WARNING("Missing argument %u", i); - return false; - } - i++; - aind++; - } - if(aind != args.size()) { - LOG_WARNING("Extra arguments more %u", i); - return false; - } - return result; + //if(args.size() <= start || !args[start]) { + // LOG_WARNING("Missing format string!"); + // return false; + //} + //if(!args[start]->is_string_type()) { + // LOG_WARNING("Argument Format '%s' not string type!", args[start]->toString().c_str()); + // return false; + //} + + //std::string format = args[start]->GetValueAsString(); + //size_t count = parse_printf_format(format.c_str(), 0, nullptr); + //std::vector types(count); + + //parse_printf_format(format.c_str(), types.size(), types.data()); + //bool result = true; + //unsigned i = 0; + //unsigned aind = start + 1; + //ObjType cast; + //while(i < types.size()) { + + // if(aind < args.size()) { + // // if(types[i] & PA_FLAG_PTR == PA_FLAG_PTR) { + // // LOG_WARNING("Pointer arg '%u' not suppotred!", i); + // // result = false; + // // i++; + // // aind++; + // // continue; + // // } + // switch(types[i] & ~PA_FLAG_MASK) { + // case PA_INT: + // if(types[i] & PA_FLAG_MASK == 0) { + // cast = ObjType::Int; + // } else if(types[i] & PA_FLAG_LONG == PA_FLAG_LONG) { + // cast = ObjType::Long; + // } else if(types[i] & PA_FLAG_SHORT == PA_FLAG_SHORT) { + // cast = ObjType::Short; + // } + // if(!canCast(args[aind]->m_var_type_current, cast)) { + // LOG_WARNING("Cast '%s' to '%s' not supported!", newlang::toString(args[aind]->m_var_type_current), + // newlang::toString(cast)); + // result = false; + // } + // break; + // case PA_CHAR: + // if(types[i] & PA_FLAG_MASK) { + // LOG_WARNING("format modifier arg '%s' %u not supported!", newlang::toString(args[aind]->m_var_type_current), i); + // result = false; + // } + // cast = ObjType::Char; + // if(!canCast(args[aind]->m_var_type_current, cast)) { + // LOG_WARNING("Cast '%s' to '%s' not supported!", newlang::toString(args[aind]->m_var_type_current), + // newlang::toString(cast)); + // result = false; + // } + // break; + // case PA_STRING: + // if(types[i] & PA_FLAG_MASK) { + // LOG_WARNING("format modifier arg '%s' %u not supported!", newlang::toString(args[aind]->m_var_type_current), i); + // result = false; + // } + // cast = ObjType::StrChar; + // if(!canCast(args[aind]->m_var_type_current, cast)) { + // LOG_WARNING("Cast '%s' to '%s' not supported!", newlang::toString(args[aind]->m_var_type_current), + // newlang::toString(cast)); + // result = false; + // } + // break; + // case PA_FLOAT: + // case PA_DOUBLE: + // if(types[i] & PA_FLAG_MASK) { + // LOG_WARNING("format modifier arg '%s' %u not supported!", newlang::toString(args[aind]->m_var_type_current), i); + // result = false; + // } + // cast = ObjType::Double; + // if(!canCast(args[aind]->m_var_type_current, cast)) { + // LOG_WARNING("Cast '%s' to '%s' not supported!", newlang::toString(args[aind]->m_var_type_current), + // newlang::toString(cast)); + // result = false; + // } + // break; + // default: + // LOG_WARNING("Arg '%u' not supported!", i); + // // PA_WCHAR, /* wide char */ + // // PA_WSTRING, /* const wchar_t *, wide character string */ + // // PA_POINTER, /* void * */ + // result = false; + // } + // } else { + // LOG_WARNING("Missing argument %u", i); + // return false; + // } + // i++; + // aind++; + //} + //if(aind != args.size()) { + // LOG_WARNING("Extra arguments more %u", i); + // return false; + //} + //return result; + return false; } void newlang::ConvertRangeToDict(Obj *from, Obj & to) { @@ -2241,9 +2251,9 @@ void newlang::ConvertRangeToDict(Obj *from, Obj & to) { ASSERT(from); ASSERT(from->is_range()); - ASSERT(from->at("start")); - ASSERT(from->at("stop")); - ASSERT(from->at("step")); + ASSERT(from->at("start").second); + ASSERT(from->at("stop").second); + ASSERT(from->at("step").second); ASSERT(to.m_var_type_current == ObjType::Dictionary || to.m_var_type_current == ObjType::None); @@ -2278,8 +2288,14 @@ void newlang::ConvertStringToTensor(const std::string &from, torch::Tensor &to, void newlang::ConvertStringToTensor(const std::wstring &from, torch::Tensor &to, ObjType type) { ASSERT(!from.empty()); ASSERT(type == ObjType::None || type == ObjType::Int || type == ObjType::Tensor); - STATIC_ASSERT(sizeof (wchar_t) == sizeof (int)); - to = torch::from_blob((void *) from.data(),{(int64_t) from.size()}, at::ScalarType::Int).clone(); + if(sizeof (wchar_t) == sizeof (int32_t)) { + to = torch::from_blob((void *) from.data(),{(int) from.size()}, torch::Dtype::Int); + } else if(sizeof (wchar_t) == sizeof (int16_t)) { + to = torch::from_blob((void *) from.data(),{(int) from.size()}, torch::Dtype::Short); + } else { + LOG_RUNTIME("Unsupport wchar_t size '%d'!!!", (int) sizeof (wchar_t)); + } + to = to.toType(torch::Dtype::Int).clone(); } template void ConvertTensorToStringTemplate(const torch::Tensor &from, T &to, std::vector *index) { @@ -2291,9 +2307,10 @@ template void ConvertTensorToStringTemplate(const torch::Tensor &fr return; } - std::vector dims({0}); + std::vector dims; if(index == nullptr) { to.clear(); + dims.push_back(Index(0)); index = &dims; } @@ -2334,8 +2351,9 @@ void newlang::ConvertTensorToDict(const torch::Tensor &from, Obj &to, std::vecto return; } - std::vector dims({0}); + std::vector dims; if(index == nullptr) { + dims.push_back(Index(0)); index = &dims; } @@ -2359,7 +2377,7 @@ void newlang::ConvertTensorToDict(const torch::Tensor &from, Obj &to, std::vecto void newlang::ConvertDictToTensor(Obj &from, torch::Tensor &to, ObjType type) { torch::Tensor temp; - for (size_t i = 0; i < from.size(); i++) { + for (int i = 0; i < from.size(); i++) { ConvertValueToTensor(from.at(i).second.get(), temp, type); if(temp.dim() == 0) { @@ -2502,7 +2520,7 @@ ObjPtr Obj::ConstructorSimpleType_(const Context *ctx, Obj & args) { if(result->m_dimensions) { // Размерность указана - for (size_t i = 0; i < result->m_dimensions->size(); i++) { + for (int i = 0; i < result->m_dimensions->size(); i++) { Index ind = (*result->m_dimensions)[i]->toIndex(); if(ind.is_integer()) { dims.push_back(ind.integer()); diff --git a/core/object.h b/core/object.h index 4de4b260..c518d935 100644 --- a/core/object.h +++ b/core/object.h @@ -46,20 +46,28 @@ namespace newlang { */ int64_t ConcatData(Obj *dest, Obj &src, ConcatMode mode = ConcatMode::Error); - inline std::string utf8_encode(const std::wstring_view source) { - try { - return std::wstring_convert < std::codecvt_utf8>().to_bytes(source.cbegin(), source.cend()); - } catch (std::exception &err) { - return err.what(); + // Convert a wide Unicode string to an UTF8 string + + inline std::string utf8_encode(const std::wstring wstr) { + std::string utf8line; + + if (wstr.empty()) { + return utf8line; } + utf8line = std::wstring_convert < std::codecvt_utf8>().to_bytes(wstr.c_str()); + return utf8line; } - inline std::wstring utf8_decode(const std::string_view source) { - try { - return std::wstring_convert < std::codecvt_utf8>().from_bytes(source.cbegin(), source.cend()); - } catch (std::exception &err) { - return std::wstring_convert < std::codecvt_utf8>().from_bytes(err.what()); + // Convert an UTF8 string to a wide Unicode String + + inline std::wstring utf8_decode(const std::string str) { + std::wstring wide_line; + + if (str.empty()) { + return wide_line; } + wide_line = std::wstring_convert < std::codecvt_utf8>().from_bytes(str.c_str()); + return wide_line; } ObjType getSummaryTensorType(ObjPtr & obj, ObjType start); @@ -97,28 +105,28 @@ namespace newlang { m_var_type_fixed = fixed; } - template < typename T > - Obj(T data, typename std::enable_if::value>::type* = 0) { - m_var_type_current = ObjType::Dictionary; - m_var_type_fixed = ObjType::Dictionary; - m_dimensions = nullptr; - push_front(Arg(data)); - } - - template < typename T > - Obj(T &data, typename std::enable_if::value>::type* = 0) { - m_var_type_current = ObjType::Dictionary; - m_var_type_fixed = ObjType::Dictionary; - m_dimensions = nullptr; - push_front(Arg(data)); - } + // template < typename T > + // Obj(T data, typename std::enable_if::value>::type* = 0) { + // m_var_type_current = ObjType::Dictionary; + // m_var_type_fixed = ObjType::Dictionary; + // m_dimensions = nullptr; + // push_front(Arg(data, nullptr)); + // } + // + // template < typename T > + // Obj(T &data, typename std::enable_if::value>::type* = 0) { + // m_var_type_current = ObjType::Dictionary; + // m_var_type_fixed = ObjType::Dictionary; + // m_dimensions = nullptr; + // push_front(Arg(data, nullptr)); + // } Obj(Context *ctx, const TermPtr term, bool as_value, Obj *local_vars); - template - inline Obj(A arg, T... rest) : Obj(rest...) { - push_front(Arg(arg)); - } + // template + // inline Obj(A arg, T... rest) : Obj(rest...) { + // push_front(Arg(arg)); + // } [[nodiscard]] static inline PairType ArgNull(const std::string name = "") { @@ -135,23 +143,20 @@ namespace newlang { return Variable::pair(value, name); } - template - typename std::enable_if::value, PairType>::type - __attribute__ ((warn_unused_result)) - static inline Arg(T value) { - return value; - } + // template + // typename std::enable_if::value, PairType>::type + // static inline Arg(T value) { + // return value; + // } template typename std::enable_if::value || std::is_same::value, PairType>::type - __attribute__ ((warn_unused_result)) static inline Arg(T value, const std::string name = "") { return pair(CreateString(value), name); } template typename std::enable_if::value && !std::is_pointer::value && !std::is_same::value, PairType>::type - __attribute__ ((warn_unused_result)) static inline Arg(T value, const std::string name = "") { return Variable::pair(CreateValue(value, ObjType::None), name); } @@ -160,7 +165,7 @@ namespace newlang { try { return shared_from_this(); } catch (std::bad_weak_ptr &err) { - LOG_RUNTIME("Exception thrown bad_weak_ptr!"); + LOG_RUNTIME("Exception thrown bad_weak_ptr! %s", err.what()); } } @@ -282,7 +287,7 @@ namespace newlang { [[nodiscard]] inline bool is_other_type() const { - return !(is_none_type() || is_bool_type() | is_arithmetic_type() || is_string_type() || is_dictionary_type()); + return !(is_none_type() || is_bool_type() || is_arithmetic_type() || is_string_type() || is_dictionary_type()); } [[nodiscard]] @@ -384,24 +389,33 @@ namespace newlang { return Variable::empty(); } - inline ObjPtr at(const std::string_view name) { - return Variable::at(name.begin()).second; - } + // virtual ObjPtr at(const std::string name) { + // return Variable::at(name.begin()).second; + // } + // + // virtual ObjPtr at(const std::string name) const { + // Obj * const obj = (Obj * const) this; + // return obj->Variable::at(name.begin()).second; + // // return Variable::at(name.begin()).second; + // } - inline ObjPtr at(const std::string_view name) const { + Variable::PairType & at(const std::string_view name) const { Obj * const obj = (Obj * const) this; - return obj->Variable::at(name.begin()).second; - // return Variable::at(name.begin()).second; + return obj->Variable::at(name); + } + + Variable::PairType & at(const std::string_view name) override { + return Variable::at(name); } Variable::PairType & at(const int64_t index) override; const Variable::PairType & at(const int64_t index) const override; - ObjPtr & at(ObjPtr find) { + Variable::PairType & at(ObjPtr find) { if (!find->is_string_type()) { LOG_RUNTIME("Value must be a string type %d", (int) find->getType()); } - return Variable::at(find->GetValueAsString()).second; + return Variable::at(find->GetValueAsString()); } bool exist(ObjPtr &find, bool strong); @@ -425,8 +439,12 @@ namespace newlang { template typename std::enable_if::value, ObjPtr>::type inline operator()(Context *ctx, T ... args) { - Obj list = Obj(args...); - return Call(ctx, &list); + auto list = {args...}; + Obj arg; + for (auto &elem : list) { + arg.push_back(elem); + } + return Call(ctx, &arg); } inline ObjPtr Call(Context *ctx) { @@ -437,8 +455,12 @@ namespace newlang { template typename std::enable_if::value, ObjPtr>::type inline Call(Context *ctx, T ... args) { - Obj list = Obj(args...); - return Call(ctx, &list); + auto list = {args...}; + Obj arg; + for (auto &elem : list) { + arg.push_back(elem); + } + return Call(ctx, &arg); } ObjPtr Call(Context *ctx, Obj *args); @@ -953,7 +975,7 @@ namespace newlang { case ObjType::Float: case ObjType::Double: case ObjType::Number: - return m_value.item(); + return static_cast (m_value.item()); case ObjType::StrWide: return std::stoll(m_wstr); @@ -982,7 +1004,7 @@ namespace newlang { default: if (is_simple()) { - return GetValueAsInteger(); + return static_cast (GetValueAsInteger()); } } LOG_RUNTIME("Data type incompatible %s", toString().c_str()); @@ -1243,7 +1265,7 @@ namespace newlang { std::vector toIntVector(bool raise = true) const { std::vector result; - for (size_t i = 0; i < size(); i++) { + for (int i = 0; i < size(); i++) { if (raise && !at(i).second->is_integer()) { LOG_RUNTIME("Item does not contain an integer value! '%s'", at(i).second->GetValueAsString().c_str()); } @@ -1610,7 +1632,7 @@ namespace newlang { m_var_is_init = true; return; - } else if ((is_none_type() || m_var_type_current == ObjType::FUNCTION) && value->is_function()) { + } else if ((is_none_type() || m_var_type_current == ObjType::Function) && value->is_function()) { //@todo Check function type args !!! std::string old_name = m_var_name; @@ -1620,7 +1642,7 @@ namespace newlang { m_var_is_init = true; return; - } else if ((is_none_type() || m_var_type_current == ObjType::FUNCTION || m_var_type_current == ObjType::EVAL_FUNCTION) && (value->m_var_type_current == ObjType::BLOCK || value->m_var_type_current == ObjType::BLOCK_TRY)) { + } else if ((is_none_type() || m_var_type_current == ObjType::Function || m_var_type_current == ObjType::EVAL_FUNCTION) && (value->m_var_type_current == ObjType::BLOCK || value->m_var_type_current == ObjType::BLOCK_TRY)) { //@todo Check function type args !!! // std::string old_name = m_var_name; @@ -1671,9 +1693,9 @@ namespace newlang { static ObjPtr CreateFunc(Context *ctx, TermPtr proto, ObjType type, const std::string var_name = ""); - static ObjPtr CreateFunc(std::string proto, FunctionType *func_addr, ObjType type = ObjType::FUNCTION); + static ObjPtr CreateFunc(std::string proto, FunctionType *func_addr, ObjType type = ObjType::Function); - ObjPtr ConvertToArgs(Obj &args, bool check_valid, Context *ctx) const { + ObjPtr ConvertToArgs(Obj *args, bool check_valid, Context *ctx) const { ObjPtr result = Clone(); result->ConvertToArgs_(args, check_valid, ctx); @@ -1690,7 +1712,7 @@ namespace newlang { protected: - void ConvertToArgs_(Obj &args, bool check_valid, Context *ctx = nullptr); // Обновить параметры для вызова функции или элементы у словаря при создании копии + void ConvertToArgs_(Obj *args, bool check_valid, Context *ctx = nullptr); // Обновить параметры для вызова функции или элементы у словаря при создании копии public: diff --git a/core/parser.cpp b/core/parser.cpp index 30b92030..2eb0e772 100644 --- a/core/parser.cpp +++ b/core/parser.cpp @@ -11,7 +11,7 @@ Parser::Parser(TermPtr &ast) : m_ast(ast) { m_ast = Term::Create(TermID::END, ""); } -bool Parser::parse_stream(std::istream& in, const std::string_view sname) { +bool Parser::parse_stream(std::istream& in, const std::string sname) { streamname = sname; Scanner scanner(&in); @@ -23,15 +23,15 @@ bool Parser::parse_stream(std::istream& in, const std::string_view sname) { return (parser.parse() == 0); } -bool Parser::parse_file(const std::string_view filename) { - std::ifstream in(filename.begin()); +bool Parser::parse_file(const std::string filename) { + std::ifstream in(filename); if (!in.good()) return false; - return parse_stream(in, filename.begin()); + return parse_stream(in, filename.c_str()); } -bool Parser::parse_string(const std::string_view input, const std::string_view sname) { - std::istringstream iss(input.begin()); - return parse_stream(iss, sname.begin()); +bool Parser::parse_string(const std::string input, const std::string sname) { + std::istringstream iss(input.c_str()); + return parse_stream(iss, sname.c_str()); } TermPtr Parser::Parse(const std::string_view input, MacrosStore *store) { diff --git a/core/parser.h b/core/parser.h index 858836e8..efdde680 100644 --- a/core/parser.h +++ b/core/parser.h @@ -39,21 +39,21 @@ namespace newlang { * @param sname stream name for error messages * @return true if successfully parsed */ - bool parse_stream(std::istream& in, const std::string_view sname = "stream input"); + bool parse_stream(std::istream& in, const std::string sname = "stream input"); /** Invoke the scanner and parser on an input string. * @param input input string * @param sname stream name for error messages * @return true if successfully parsed */ - bool parse_string(const std::string_view input, const std::string_view sname = "string stream"); + bool parse_string(const std::string input, const std::string sname = "string stream"); /** Invoke the scanner and parser on a file. Use parse_stream with a * std::ifstream if detection of file reading errors is required. * @param filename input file name * @return true if successfully parsed */ - bool parse_file(const std::string_view filename); + bool parse_file(const std::string filename); // To demonstrate pure handling of parse errors, instead of // simply dumping them on the standard error output, we will pass diff --git a/core/parser.y b/core/parser.y index 75447a48..4f40b466 100644 --- a/core/parser.y +++ b/core/parser.y @@ -1,7 +1,7 @@ %{ /*** C/C++ Declarations ***/ -#include +#include "pch.h" #include #include @@ -382,7 +382,7 @@ star_arg = [STAR] STAR ID %token ITERATOR "!!" %token ITERATOR_QQ "??" -%token TRANSPARENT +%token PUREFUNC %token SIMPLE_AND %token SIMPLE_OR %token SIMPLE_XOR @@ -996,7 +996,7 @@ assign_op: /* '=' { $$ = $1; } - | TRANSPARENT /* ::- :- */ + | PUREFUNC /* ::- :- */ { $$ = $1; } diff --git a/core/pch.cpp b/core/pch.cpp new file mode 100644 index 00000000..f6b7b1ff --- /dev/null +++ b/core/pch.cpp @@ -0,0 +1,2 @@ + +#include "pch.h" diff --git a/core/pch.h b/core/pch.h index 1b1b92b4..21dbdf9c 100644 --- a/core/pch.h +++ b/core/pch.h @@ -28,25 +28,39 @@ #include #include #include -#include +//#include #include #include #include #include + +#ifdef _MSC_VER + +#include +#include +#include +#include +#include + +#else + #include #include #include #include +#include + +#endif + #include #include #include #include -#include #include #include diff --git a/core/term.h b/core/term.h index 18c6b759..2feea294 100644 --- a/core/term.h +++ b/core/term.h @@ -52,7 +52,7 @@ namespace newlang { _(SIMPLE_AND) \ _(SIMPLE_OR) \ _(SIMPLE_XOR) \ - _(TRANSPARENT) \ + _(PUREFUNC) \ _(ITERATOR) \ _(ITERATOR_QQ)\ _(FOLLOW) \ @@ -100,6 +100,7 @@ namespace newlang { } size_t IndexArg(TermPtr term); + std::string ParserMessage(std::string &buffer, int row, int col, const char *format, ...); class Term : public Variable, public std::enable_shared_from_this { public: @@ -175,7 +176,7 @@ namespace newlang { } inline bool IsFunction() { - return m_id == TermID::FUNCTION || m_id == TermID::TRANSPARENT || m_id == TermID::SIMPLE_AND || m_id == TermID::SIMPLE_OR || m_id == TermID::SIMPLE_XOR; + return m_id == TermID::FUNCTION || m_id == TermID::PUREFUNC || m_id == TermID::SIMPLE_AND || m_id == TermID::SIMPLE_OR || m_id == TermID::SIMPLE_XOR; } inline bool IsVariable() { @@ -270,8 +271,8 @@ namespace newlang { ASSERT(this != Left().get()); result += Left()->toString(); } + TermPtr temp; - size_t dot, last; bool test; switch (m_id) { case TermID::END:// name= @@ -415,7 +416,7 @@ namespace newlang { } return result; case TermID::FUNCTION: - case TermID::TRANSPARENT: + case TermID::PUREFUNC: result += " " + m_text + " "; result.insert(0, m_namespace); @@ -424,7 +425,7 @@ namespace newlang { if (m_right->GetTokenID() != TermID::SOURCE && !result.empty() && result[result.size() - 1] != ';') { result += ";"; } - for (size_t i = 0; i < m_right->size(); i++) { + for (int i = 0; i < m_right->size(); i++) { result += m_right->at(i).second->toString(); } // result += "};"; @@ -699,7 +700,7 @@ namespace newlang { if (m_type && m_type.get() != this) { m_type->SetSource(source); } - for (size_t i = 0; i < size(); i++) { + for (int i = 0; i < size(); i++) { at(i).second->SetSource(m_source); } for (auto &elem : m_block) { diff --git a/core/test/compiler_test.cpp b/core/test/compiler_test.cpp index a3c047f3..e8a678f6 100644 --- a/core/test/compiler_test.cpp +++ b/core/test/compiler_test.cpp @@ -438,7 +438,7 @@ TEST(Compiler, DISABLED_Function) { TermPtr func1 = funcs->BlockCode()[0]; - ASSERT_EQ(TermID::TRANSPARENT, func1->GetTokenID()); + ASSERT_EQ(TermID::PUREFUNC, func1->GetTokenID()); ASSERT_TRUE(func1->Left()); ASSERT_EQ(2, func1->Left()->size()); @@ -465,7 +465,7 @@ TEST(Compiler, DISABLED_Function) { TermPtr func2 = funcs->BlockCode()[1]; - ASSERT_EQ(TermID::TRANSPARENT, func2->GetTokenID()); + ASSERT_EQ(TermID::PUREFUNC, func2->GetTokenID()); ASSERT_TRUE(func2->Left()); ASSERT_EQ(2, func2->Left()->size()); diff --git a/core/test/eval_test.cpp b/core/test/eval_test.cpp index 32260a02..c7fbd6c7 100644 --- a/core/test/eval_test.cpp +++ b/core/test/eval_test.cpp @@ -883,9 +883,9 @@ class OpEvalTest : public ::testing::Test { OpEvalTest() : m_ctx(RunTime::Init()) { } - const char *Test(std::string eval, Obj &vars) { + const char *Test(std::string eval, Obj *vars) { eval += ";"; - m_result = m_ctx.ExecStr(eval, &vars); + m_result = m_ctx.ExecStr(eval, vars); if(m_result) { m_string = m_result->GetValueAsString(); return m_string.c_str(); @@ -899,7 +899,7 @@ class OpEvalTest : public ::testing::Test { const char *Test(const char *eval) { Obj vars; - return Test(eval, vars); + return Test(eval, &vars); } }; @@ -947,11 +947,11 @@ TEST_F(OpEvalTest, Ops) { ASSERT_STREQ("$=('var1',)", Test("$")); ASSERT_STREQ("100", Test("var1")); - Obj vars(Obj::Arg(var1, "var1")); + ObjPtr vars = Obj::CreateDict(Obj::Arg(var1, "var1")); ASSERT_ANY_THROW(Test("$var1")); - ASSERT_NO_THROW(Test("$var1", vars)); - ASSERT_STREQ("100", Test("$var1", vars)); + ASSERT_NO_THROW(Test("$var1", vars.get())); + ASSERT_STREQ("100", Test("$var1", vars.get())); ASSERT_STREQ("20", Test("var2:=9+11")); ObjPtr var2 = m_result; @@ -960,21 +960,21 @@ TEST_F(OpEvalTest, Ops) { ASSERT_STREQ("20", Test("var2")); ASSERT_ANY_THROW(Test("$var2")); - ASSERT_ANY_THROW(Test("$var2", vars)); - vars.push_back(Obj::Arg(var2, "var2")); + ASSERT_ANY_THROW(Test("$var2", vars.get())); + vars->push_back(Obj::Arg(var2, "var2")); - ASSERT_NO_THROW(Test("$var2", vars)); - ASSERT_STREQ("20", Test("$var2", vars)); + ASSERT_NO_THROW(Test("$var2", vars.get())); + ASSERT_STREQ("20", Test("$var2", vars.get())); ASSERT_STREQ("100", Test("var1")); ASSERT_STREQ("120", Test("var1+=var2")); ASSERT_STREQ("$=('var1', 'var2',)", Test("$")); ASSERT_ANY_THROW(Test("$var1")); - ASSERT_NO_THROW(Test("$var1", vars)); - ASSERT_STREQ("120", Test("$var1", vars)); + ASSERT_NO_THROW(Test("$var1", vars.get())); + ASSERT_STREQ("120", Test("$var1", vars.get())); - vars.clear_(); + vars->clear_(); m_result.reset(); var1.reset(); ASSERT_STREQ("$=('var2',)", Test("$")); diff --git a/core/test/lexer_test.cpp b/core/test/lexer_test.cpp index a4ffad62..86b10820 100644 --- a/core/test/lexer_test.cpp +++ b/core/test/lexer_test.cpp @@ -25,7 +25,7 @@ class Lexer : public ::testing::Test { void TearDown() { } - int Parse(const char *str) { + int64_t Parse(const char *str) { std::istringstream strstr(str); Scanner lexer(&strstr); @@ -291,7 +291,7 @@ TEST_F(Lexer, CodeSource) { TEST_F(Lexer, Assign) { ASSERT_EQ(5, Parse(":= :- :&&= :||= :^^=")); EXPECT_EQ(1, Count(TermID::CREATE_OR_ASSIGN)); - EXPECT_EQ(1, Count(TermID::TRANSPARENT)); + EXPECT_EQ(1, Count(TermID::PUREFUNC)); EXPECT_EQ(1, Count(TermID::SIMPLE_AND)); EXPECT_EQ(1, Count(TermID::SIMPLE_OR)); EXPECT_EQ(1, Count(TermID::SIMPLE_XOR)); diff --git a/core/test/nlc_test.cpp b/core/test/nlc_test.cpp index 2890ef9c..f153aa34 100644 --- a/core/test/nlc_test.cpp +++ b/core/test/nlc_test.cpp @@ -15,24 +15,24 @@ TEST(NLC, Options) { NLC nlc0; ASSERT_TRUE(nlc0.m_path.empty()); - ASSERT_EQ(NLC::Mode::ERROR, nlc0.m_mode); + ASSERT_EQ(NLC::Mode::ModeError, nlc0.m_mode); NLC nlc1(""); ASSERT_TRUE(nlc1.m_path.empty()); - ASSERT_EQ(NLC::Mode::ERROR, nlc1.m_mode); + ASSERT_EQ(NLC::Mode::ModeError, nlc1.m_mode); NLC nlc2("path"); ASSERT_STREQ("path", nlc2.m_path.c_str()); - ASSERT_EQ(NLC::Mode::INTERACTIVE, nlc2.m_mode) << nlc2.m_output; + ASSERT_EQ(NLC::Mode::ModeInter, nlc2.m_mode) << nlc2.m_output; NLC nlc3(" path --help "); ASSERT_STREQ("path", nlc3.m_path.c_str()); - ASSERT_EQ(NLC::Mode::HELP, nlc3.m_mode); + ASSERT_EQ(NLC::Mode::ModeHelp, nlc3.m_mode); ASSERT_FALSE(nlc3.m_output.empty()) << nlc3.m_output; NLC nlc4("path -v"); ASSERT_STREQ("path", nlc4.m_path.c_str()); - ASSERT_EQ(NLC::Mode::VERSION, nlc4.m_mode); + ASSERT_EQ(NLC::Mode::ModeVersion, nlc4.m_mode); // NLC nlc5("path --output=output_file -cinput_file"); // ASSERT_STREQ("path", nlc5.m_path.c_str()); @@ -55,14 +55,14 @@ TEST(NLC, Options) { NLC nlc9("path --load=module2.nlm call(arg1,100)"); ASSERT_STREQ("path", nlc9.m_path.c_str()); - ASSERT_EQ(NLC::Mode::EVAL, nlc9.m_mode); + ASSERT_EQ(NLC::Mode::ModeEval, nlc9.m_mode); ASSERT_EQ(1, nlc9.m_modules.size()); ASSERT_STREQ("module2.nlm", nlc9.m_modules[0].c_str()); ASSERT_STREQ("call(arg1,100)", nlc9.m_eval.c_str()); NLC nlc10("path --load=module2.nlm,module3.nlm 100+200"); ASSERT_STREQ("path", nlc10.m_path.c_str()); - ASSERT_EQ(NLC::Mode::EVAL, nlc10.m_mode); + ASSERT_EQ(NLC::Mode::ModeEval, nlc10.m_mode); ASSERT_EQ(2, nlc10.m_modules.size()); ASSERT_STREQ("module2.nlm", nlc10.m_modules[0].c_str()); ASSERT_STREQ("module3.nlm", nlc10.m_modules[1].c_str()); @@ -70,7 +70,7 @@ TEST(NLC, Options) { NLC nlc11("path --load=module2.nlm,, --load-only=,tt1,tt2,tt3 \"100+200\""); ASSERT_STREQ("path", nlc11.m_path.c_str()); - ASSERT_EQ(NLC::Mode::EVAL, nlc11.m_mode) << nlc11.m_output; + ASSERT_EQ(NLC::Mode::ModeEval, nlc11.m_mode) << nlc11.m_output; ASSERT_EQ(1, nlc11.m_modules.size()); ASSERT_STREQ("module2.nlm", nlc11.m_modules[0].c_str()); ASSERT_STREQ("\"100+200\"", nlc11.m_eval.c_str()); @@ -112,11 +112,11 @@ TEST(NLC, FileFunc) { TEST(NLC, Eval) { NLC nlc6("path --badarg --output=output_file"); - ASSERT_EQ(NLC::Mode::EVAL, nlc6.m_mode); + ASSERT_EQ(NLC::Mode::ModeEval, nlc6.m_mode); ASSERT_EQ(1, nlc6.Run()); NLC nlc7("path func(bad!,,args)"); - ASSERT_EQ(NLC::Mode::EVAL, nlc7.m_mode) << nlc7.m_output; + ASSERT_EQ(NLC::Mode::ModeEval, nlc7.m_mode) << nlc7.m_output; ASSERT_EQ(1, nlc7.Run()); } @@ -473,7 +473,7 @@ TEST(NLC, EvalHelloWorld) { //// Parser parser(ast); //// parser.Parse("brother(arg1, arg2)"); //// ObjPtr filter_brother = Obj::CreateFunc(nullptr, ast, -/// ObjType::TRANSPARENT); / filter_brother->m_function = (void +/// ObjType::PUREFUNC); / filter_brother->m_function = (void ///*)&test_brother; / Object filt_args(Obj::Arg(filter_brother)); //// //// diff --git a/core/test/object_test.cpp b/core/test/object_test.cpp index b6ef3fc0..6db24bcb 100644 --- a/core/test/object_test.cpp +++ b/core/test/object_test.cpp @@ -509,14 +509,14 @@ TEST(Args, All) { // ASSERT_FALSE(proto1.m_is_ellipsis); - Obj arg_999(Obj::CreateValue(999, ObjType::None)); - EXPECT_EQ(ObjType::Short, arg_999[0]->getType()) << torch::toString(toTorchType(arg_999[0]->getType())); + ObjPtr arg_999(Obj::CreateValue(999, ObjType::None)); + EXPECT_EQ(ObjType::Short, (*arg_999)[0]->getType()) << torch::toString(toTorchType((*arg_999)[0]->getType())); - Obj arg_empty_named(Obj::Arg()); - ASSERT_EQ(ObjType::None, arg_empty_named[0]->getType()); + ObjPtr arg_empty_named = Obj::CreateDict(Obj::Arg()); + ASSERT_EQ(ObjType::None, (*arg_empty_named)[0]->getType()); - Obj arg_123_named(Obj::Arg(123, "named")); - EXPECT_EQ(ObjType::Char, arg_123_named[0]->getType()) << torch::toString(toTorchType(arg_123_named[0]->getType())); + ObjPtr arg_123_named = Obj::CreateDict(Obj::Arg(123, "named")); + EXPECT_EQ(ObjType::Char, (*arg_123_named)[0]->getType()) << torch::toString(toTorchType((*arg_123_named)[0]->getType())); ObjPtr arg_999_123_named = Obj::CreateDict(); ASSERT_EQ(0, arg_999_123_named->size()); @@ -525,9 +525,9 @@ TEST(Args, All) { *arg_999_123_named += arg_123_named; ASSERT_EQ(2, arg_999_123_named->size()); - ASSERT_ANY_THROW(proto1.ConvertToArgs(arg_999, true, nullptr)); // Прототип не принимает позиционных аргументов + ASSERT_ANY_THROW(proto1.ConvertToArgs(arg_999.get(), true, nullptr)); // Прототип не принимает позиционных аргументов - ASSERT_ANY_THROW(proto1.ConvertToArgs(arg_empty_named, true, nullptr)); // Прототип не принимает именованных аргументов + ASSERT_ANY_THROW(proto1.ConvertToArgs(arg_empty_named.get(), true, nullptr)); // Прототип не принимает именованных аргументов ASSERT_TRUE(p.Parse("test(arg1)")); @@ -537,16 +537,16 @@ TEST(Args, All) { ASSERT_STREQ("arg1", proto2.name(0).c_str()); ASSERT_EQ(nullptr, proto2.at(0).second); - ObjPtr o_arg_999 = proto2.ConvertToArgs(arg_999, true, nullptr); + ObjPtr o_arg_999 = proto2.ConvertToArgs(arg_999.get(), true, nullptr); ASSERT_TRUE((*o_arg_999)[0]); ASSERT_STREQ("999", (*o_arg_999)[0]->toString().c_str()); // proto2[0].reset(); // Иначе типы гурментов буду отличаться - ObjPtr o_arg_empty_named = proto2.ConvertToArgs(arg_empty_named, false, nullptr); + ObjPtr o_arg_empty_named = proto2.ConvertToArgs(arg_empty_named.get(), false, nullptr); ASSERT_TRUE((*o_arg_empty_named)[0]); ASSERT_STREQ("_", (*o_arg_empty_named)[0]->toString().c_str()); - ASSERT_ANY_THROW(proto2.ConvertToArgs(arg_123_named, true, nullptr)); // Имя аругмента отличается + ASSERT_ANY_THROW(proto2.ConvertToArgs(arg_123_named.get(), true, nullptr)); // Имя аругмента отличается // Нормальный вызов @@ -560,21 +560,21 @@ TEST(Args, All) { ASSERT_STREQ("...", proto3.name(1).c_str()); ASSERT_FALSE(proto3.at(1).second); - ObjPtr proto3_arg = proto3.ConvertToArgs(arg_999, true, nullptr); + ObjPtr proto3_arg = proto3.ConvertToArgs(arg_999.get(), true, nullptr); ASSERT_EQ(1, proto3_arg->size()); ASSERT_TRUE((*proto3_arg)[0]); ASSERT_STREQ("999", (*proto3_arg)[0]->toString().c_str()); ASSERT_STREQ("empty", proto3_arg->name(0).c_str()); // Дополнительный аргумент - Obj arg_extra(Obj::CreateValue(999, ObjType::None), Obj::Arg(123, "named")); + ObjPtr arg_extra = Obj::CreateDict(Obj::Arg(Obj::CreateValue(999, ObjType::None)), Obj::Arg(123, "named")); - ASSERT_EQ(2, arg_extra.size()); - EXPECT_EQ(ObjType::Short, arg_extra[0]->getType()) << torch::toString(toTorchType(arg_extra[0]->getType())); - EXPECT_EQ(ObjType::Char, arg_extra[1]->getType()) << torch::toString(toTorchType(arg_extra[1]->getType())); + ASSERT_EQ(2, arg_extra->size()); + EXPECT_EQ(ObjType::Short, (*arg_extra)[0]->getType()) << torch::toString(toTorchType((*arg_extra)[0]->getType())); + EXPECT_EQ(ObjType::Char, (*arg_extra)[1]->getType()) << torch::toString(toTorchType((*arg_extra)[1]->getType())); - ObjPtr proto3_extra = proto3.ConvertToArgs(arg_extra, true, nullptr); + ObjPtr proto3_extra = proto3.ConvertToArgs(arg_extra.get(), true, nullptr); ASSERT_EQ(2, proto3_extra->size()); ASSERT_STREQ("999", (*proto3_extra)[0]->toString().c_str()); ASSERT_STREQ("empty", proto3_extra->name(0).c_str()); @@ -600,9 +600,9 @@ TEST(Args, All) { ASSERT_STREQ("arg1", proto_str.at(0).first.c_str()); ASSERT_EQ(nullptr, proto_str[0]); - Obj arg_str(Obj::Arg(L"СТРОКА", "str"), Obj::Arg(555, "arg1")); + ObjPtr arg_str = Obj::CreateDict(Obj::Arg(L"СТРОКА", "str"), Obj::Arg(555, "arg1")); - ObjPtr proto_str_arg = proto_str.ConvertToArgs(arg_str, true, nullptr); + ObjPtr proto_str_arg = proto_str.ConvertToArgs(arg_str.get(), true, nullptr); ASSERT_STREQ("arg1", proto_str_arg->at(0).first.c_str()); ASSERT_TRUE(proto_str_arg->at(0).second); ASSERT_STREQ("555", (*proto_str_arg)[0]->toString().c_str()); @@ -618,7 +618,7 @@ TEST(Args, All) { ASSERT_STREQ("arg1", proto_any.at(0).first.c_str()); ASSERT_EQ(nullptr, proto_any.at(0).second); - ObjPtr any = proto_any.ConvertToArgs(arg_str, true, nullptr); + ObjPtr any = proto_any.ConvertToArgs(arg_str.get(), true, nullptr); ASSERT_EQ(2, any->size()); ASSERT_STREQ("arg1", any->at(0).first.c_str()); ASSERT_TRUE(any->at(0).second); @@ -630,8 +630,8 @@ TEST(Args, All) { // ASSERT_TRUE(p.Parse("min(arg, ...) := {}")); Obj min_proto(&ctx, ast->Left(), false, &local); - Obj min_args(Obj::Arg(200), Obj::Arg(100), Obj::Arg(300)); // min(200,100,300) - ObjPtr min_arg = min_proto.ConvertToArgs(min_args, true, nullptr); + ObjPtr min_args = Obj::CreateDict(Obj::Arg(200), Obj::Arg(100), Obj::Arg(300)); + ObjPtr min_arg = min_proto.ConvertToArgs(min_args.get(), true, nullptr); ASSERT_EQ(3, min_arg->size()); ASSERT_STREQ("200", (*min_arg)[0]->toString().c_str()); diff --git a/core/test/parser_test.cpp b/core/test/parser_test.cpp index e431c4f6..6d8734b2 100644 --- a/core/test/parser_test.cpp +++ b/core/test/parser_test.cpp @@ -23,7 +23,7 @@ class ParserTest : public ::testing::Test { int Count(TermID token_id) { int result = 0; - for (size_t c = 0; c < ast->size(); c++) { + for (int c = 0; c < ast->size(); c++) { if ((*ast)[c]->m_id == token_id) { result++; } @@ -665,7 +665,7 @@ TEST_F(ParserTest, Iterator) { ASSERT_EQ(1, arg->size()); ASSERT_STREQ("arg", (*arg)[0]->getText().c_str()); -#pragma GCC warning "ITERATOR" +// #pragma GCC warning "ITERATOR" // ASSERT_TRUE(Parse("term(arg=value)??(100)")); // ASSERT_STREQ("??", ast->getText().c_str()); // ASSERT_EQ(1, ast->getItemCount()); diff --git a/core/types.h b/core/types.h index e207b7d0..7141e1af 100644 --- a/core/types.h +++ b/core/types.h @@ -29,7 +29,7 @@ class Obj; class Context; class NewLang; class RunTime; -class CompileInfo; +struct CompileInfo; typedef std::shared_ptr TermPtr; typedef std::shared_ptr ObjPtr; @@ -76,7 +76,7 @@ void ParserException(const char *msg, std::string &buffer, int row, int col); do { \ std::string empty; \ std::string message = \ - ParserMessage(term->m_source ? *term->m_source : empty, term->m_line, term->m_col, format, ##__VA_ARGS__); \ + newlang::ParserMessage(term->m_source ? *term->m_source : empty, term->m_line, term->m_col, format, ##__VA_ARGS__); \ LOG_EXCEPT_LEVEL(Interrupt, LOG_LEVEL_INFO, "", "%s", message.c_str()); \ } while (0) @@ -97,7 +97,7 @@ void ParserException(const char *msg, std::string &buffer, int row, int col); message += "' (" __FILE__ ":" TO_STR(__LINE__) ")"; \ LOG_EXCEPT_LEVEL( \ Interrupt, LOG_LEVEL_INFO, "", "%s", \ - ParserMessage(*term->m_source, term->m_line, term->m_col, "%s", message.c_str()).c_str()); \ + newlang::ParserMessage(*term->m_source, term->m_line, term->m_col, "%s", message.c_str()).c_str()); \ } \ } while (0) @@ -148,9 +148,8 @@ void ParserException(const char *msg, std::string &buffer, int row, int col); \ _(Pointer, 64) \ _(NativeFunc, 65) \ - _(FUNCTION, 100) \ + _(Function, 100) \ _(PureFunc, 101) \ - _(TRANSPARENT, 102) \ \ _(Range, 104) \ _(Dictionary, 105) \ @@ -165,7 +164,6 @@ void ParserException(const char *msg, std::string &buffer, int row, int col); _(SimplePureXOR, 114) \ \ _(Eval, 118) \ - _(Function, 119) \ _(Other, 120) \ _(Plain, 121) \ _(Struct, 201) \ @@ -285,14 +283,18 @@ void ParserException(const char *msg, std::string &buffer, int row, int col); #define DEFINE_ENUM(name, value) name = static_cast(value), NL_TYPES(DEFINE_ENUM) #undef DEFINE_ENUM + _NumOptions }; + constexpr uint16_t NumObjTypes = static_cast (ObjType::_NumOptions); + + #define MAKE_TYPE_NAME(type_name) type_name inline const char *toString(ObjType type) { #define DEFINE_CASE(name, _) \ case ObjType::name: \ - return MAKE_TYPE_NAME(":"#name); + return MAKE_TYPE_NAME(":" #name); switch (type) { NL_TYPES(DEFINE_CASE) @@ -334,7 +336,7 @@ void ParserException(const char *msg, std::string &buffer, int row, int col); } inline bool isFunction(ObjType t) { - return t == ObjType::TRANSPARENT || t == ObjType::FUNCTION || t == ObjType::NativeFunc || + return t == ObjType::PureFunc || t == ObjType::Function || t == ObjType::NativeFunc || t == ObjType::EVAL_FUNCTION || t == ObjType::PureFunc || t == ObjType::SimplePureAND || t == ObjType::SimplePureOR || t == ObjType::SimplePureXOR; } @@ -608,7 +610,7 @@ void ParserException(const char *msg, std::string &buffer, int row, int col); case ObjType::Long: ptr_long = self.data_ptr(); ASSERT(ptr_long); - *ptr_long = set.item().toLong(); + *ptr_long = static_cast (set.item().toLong()); return; case ObjType::Float: ptr_float = self.data_ptr(); @@ -653,7 +655,7 @@ void ParserException(const char *msg, std::string &buffer, int row, int col); } else if (ObjType::Long == type) { auto acc_long = self.accessor(); for (int i = 0; i < acc_long.size(0); i++) { - acc_long[i] = set.item().toLong(); + acc_long[i] = static_cast (set.item().toLong()); } return; } else if (ObjType::Float == type) { @@ -707,7 +709,7 @@ void ParserException(const char *msg, std::string &buffer, int row, int col); auto acc_long = self.accessor(); for (int i = 0; i < acc_long.size(0); i++) { for (int j = 0; j < acc_long.size(1); j++) { - acc_long[i][j] = set.item().toLong(); + acc_long[i][j] = static_cast (set.item().toLong()); } } return; diff --git a/core/variable.h b/core/variable.h index 01080a07..14a9fa75 100644 --- a/core/variable.h +++ b/core/variable.h @@ -137,7 +137,7 @@ namespace newlang { } inline Type & insert(int64_t index, Type value, const std::string &name = "") { - if (index < 0 || index >= m_data.size()) { + if (index < 0 || index >= static_cast(m_data.size())) { LOG_RUNTIME("Index '%ld' not exists!", index); } return m_data.insert(m_data.begin() + index, std::pair(name, value))->second; @@ -145,11 +145,11 @@ namespace newlang { virtual PairType & at(const int64_t index) { if (index >= 0) { - if (index < m_data.size()) { + if (index < static_cast(m_data.size())) { return m_data.at(index); } } else { - if (-index < m_data.size()) { + if (-index < static_cast(m_data.size())) { return m_data.at(m_data.size() + index); } } @@ -158,29 +158,29 @@ namespace newlang { virtual const PairType & at(const int64_t index) const { if (index >= 0) { - if (index < m_data.size()) { + if (index < static_cast(m_data.size())) { return m_data.at(index); } } else { - if (-index < m_data.size()) { + if (-index < static_cast(m_data.size())) { return m_data.at(m_data.size() + index); } } LOG_RUNTIME("Index '%ld' not exists!", index); } - template - typename std::enable_if>::value, Type &>::type - inline at(N * name) { - return at(std::string(name)); - } +// template +// typename std::enable_if>::value, Type &>::type +// inline at(N * name) { +// return at(std::string(name)); +// } - virtual PairType & at(const std::string name) { + virtual PairType & at(const std::string_view name) { iterator found = select(name); if (found != m_data.end()) { return found.data(); } - LOG_RUNTIME("Property '%s' not found!", name.c_str()); + LOG_RUNTIME("Property '%s' not found!", name.begin()); } // template @@ -231,9 +231,9 @@ namespace newlang { } else { // Если размер отрицательный - добавить или удалить вначале size = -size; - if (m_data.size() > size) { + if (static_cast(m_data.size()) > size) { m_data.erase(m_data.begin(), m_data.begin() + (m_data.size() - size)); - } else if (m_data.size() < size) { + } else if (static_cast(m_data.size()) < size) { m_data.insert(m_data.begin(), (m_data.size() - size), std::pair(name, fill)); } else { m_data.clear(); @@ -335,7 +335,7 @@ namespace newlang { search_loop(); } - iterator(DataType &data, const std::string & find_key) : m_data(data), m_find_key(true), m_key(find_key), m_func(nullptr), m_found(data.begin()) { + iterator(DataType &data, const std::string_view find_key) : m_data(data), m_find_key(true), m_key(find_key), m_func(nullptr), m_found(data.begin()) { search_loop(); } @@ -373,7 +373,7 @@ namespace newlang { const std::string m_key; typename DataType::iterator m_found; - const CompareFuncType *m_func; + CompareFuncType *m_func; Variable m_func_args; const void *m_func_extra; }; @@ -423,7 +423,7 @@ namespace newlang { // return select(); // } - virtual iterator select(const std::string & key) { + virtual iterator select(const std::string_view key) { return iterator(m_data, key); } diff --git a/core/warning_pop.h b/core/warning_pop.h index c08bd12d..ad91d6d6 100644 --- a/core/warning_pop.h +++ b/core/warning_pop.h @@ -10,6 +10,6 @@ #elif _MSC_VER -#error MS compiler not testesd! +#pragma warning(pop) #endif diff --git a/core/warning_push.h b/core/warning_push.h index d6e385bf..124c11f0 100644 --- a/core/warning_push.h +++ b/core/warning_push.h @@ -36,11 +36,25 @@ #pragma GCC diagnostic ignored "-Wnon-virtual-dtor" #pragma GCC diagnostic ignored "-Weffc++" #pragma GCC diagnostic ignored "-Wunused-parameter" +#pragma GCC diagnostic ignored "-Wattributes" + #elif _MSC_VER -#error MS compiler not testesd! +#pragma warning(push) +#pragma warning(disable : 4244) +#pragma warning(disable : 4251) +#pragma warning(disable : 4624) +#pragma warning(disable : 4067) +#pragma warning(disable : 4275) +#pragma warning(disable : 4101) +#pragma warning(disable : 4267) +#pragma warning(disable : 4015) +#pragma warning(disable : 4014) +#pragma warning(disable : 4067) +#pragma warning(disable : 4005) #endif + diff --git a/nlc-win/nlc.sln b/nlc-win/nlc.sln new file mode 100644 index 00000000..1f158990 --- /dev/null +++ b/nlc-win/nlc.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.2.32616.157 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "nlc", "nlc.vcxproj", "{EAD3DACB-5C02-4BC6-98EB-79F6AD3198BF}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {EAD3DACB-5C02-4BC6-98EB-79F6AD3198BF}.Debug|x64.ActiveCfg = Debug|x64 + {EAD3DACB-5C02-4BC6-98EB-79F6AD3198BF}.Debug|x64.Build.0 = Debug|x64 + {EAD3DACB-5C02-4BC6-98EB-79F6AD3198BF}.Debug|x86.ActiveCfg = Debug|Win32 + {EAD3DACB-5C02-4BC6-98EB-79F6AD3198BF}.Debug|x86.Build.0 = Debug|Win32 + {EAD3DACB-5C02-4BC6-98EB-79F6AD3198BF}.Release|x64.ActiveCfg = Release|x64 + {EAD3DACB-5C02-4BC6-98EB-79F6AD3198BF}.Release|x64.Build.0 = Release|x64 + {EAD3DACB-5C02-4BC6-98EB-79F6AD3198BF}.Release|x86.ActiveCfg = Release|Win32 + {EAD3DACB-5C02-4BC6-98EB-79F6AD3198BF}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {5038341E-F14E-4850-B05D-ECDA4F492DF6} + EndGlobalSection +EndGlobal diff --git a/nlc-win/nlc.vcxproj b/nlc-win/nlc.vcxproj new file mode 100644 index 00000000..5e2fa0ae --- /dev/null +++ b/nlc-win/nlc.vcxproj @@ -0,0 +1,217 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 16.0 + Win32Proj + {ead3dacb-5c02-4bc6-98eb-79f6ad3198bf} + NewLang + 10.0 + nlc-win + + + + Application + true + v143 + Unicode + + + Application + false + v143 + true + Unicode + + + Application + true + v143 + Unicode + + + Application + false + v143 + true + Unicode + + + + + + + + + + + + + + + + + + + + + $(VC_IncludePath);$(WindowsSDK_IncludePath);..;../..;../contrib/;../contrib/googletest/googletest;../contrib/googletest/googletest/include;../contrib/Lyra/include;../contrib/libtorch-win/include;../contrib/libtorch-win/include/torch/csrc/api/include;../contrib/tensorboard_logger/include;../contrib/libffi/win64/include + ..\contrib\libffi\win64\lib;..\contrib\libtorch-win\lib;$(LibraryPath) + + + + Level3 + true + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + true + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + Level3 + true + _DEBUG;_CONSOLE;DEBUG;LOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG;PDC_WIDE;UNITTEST;_SILENCE_CXX17_ITERATOR_BASE_CLASS_DEPRECATION_WARNING;_SILENCE_CXX17_RESULT_OF_DEPRECATION_WARNING;_SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING;_SILENCE_CXX17_ADAPTOR_TYPEDEFS_DEPRECATION_WARNING;NOMINMAX;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + false + stdcpp17 + Use + pch.h + stdc17 + pch.h.pch + false + + + Console + true + + + true + + + copy /y ..\contrib\libtorch-win\lib\*.dll $(TargetDir) + + + + + Level3 + true + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + NotUsing + + + NotUsing + + + NotUsing + + + + + NotUsing + + + NotUsing + 4244;4005;%(DisableSpecificWarnings) + + + + + + + NotUsing + + + Create + + + NotUsing + + + + + + + + + + + + + NotUsing + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From 8027f7004258ccd023cb4ecdb12af06244e24835 Mon Sep 17 00:00:00 2001 From: Aleksandr Ryabikov Date: Mon, 27 Jun 2022 22:12:22 +0300 Subject: [PATCH 08/31] =?UTF-8?q?=D0=98=D1=81=D0=BF=D0=BE=D0=BB=D0=BD?= =?UTF-8?q?=D1=8F=D0=B5=D0=BC=D1=8B=D0=B9=20=D1=84=D0=B0=D0=B9=D0=BB=20?= =?UTF-8?q?=D1=81=D0=BE=D0=B1=D1=80=D0=B0=D0=BB=D1=81=D1=8F=20=D0=BF=D0=BE?= =?UTF-8?q?=D0=B4=20=D0=B2=D0=B8=D0=BD=D0=B4=D1=83=20=D0=B8=20=D0=B4=D0=B0?= =?UTF-8?q?=D0=B6=D0=B5=20=D0=B7=D0=B0=D0=BF=D1=83=D1=81=D1=82=D0=B8=D0=BB?= =?UTF-8?q?=D1=81=D1=8F!?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- contrib/build.cmd | 2 +- core/context.cpp | 18 +++++++++--------- core/nlc.cpp | 2 +- core/object.cpp | 20 ++++++++++---------- core/object.h | 2 +- core/test/alg_test.cpp | 5 +++-- core/test/compiler_test.cpp | 3 ++- core/test/eval_test.cpp | 6 +++--- core/test/fraction_test.cpp | 2 ++ core/test/lexer_test.cpp | 4 ++-- core/test/nlc_test.cpp | 4 ++-- core/test/object_test.cpp | 3 ++- core/test/parser_test.cpp | 4 ++-- core/types.h | 30 +++++++++++++++--------------- nlc-win/nlc.vcxproj | 2 ++ 15 files changed, 57 insertions(+), 50 deletions(-) diff --git a/contrib/build.cmd b/contrib/build.cmd index b4e2984e..f9c00d4a 100644 --- a/contrib/build.cmd +++ b/contrib/build.cmd @@ -1,3 +1,3 @@ -C:\msys64\usr\bin\bash -lc "cd /z/NewLang/newlang/contrib/libffi && ./configure --build=x86_64-w64-mingw32 --host=x86_64-w64-mingw32 --prefix=`pwd`/win64 --enable-static --disable-shared --disable-docs && make && make install" +C:\msys64\usr\bin\bash -lc "cd /z/NewLang/newlang/contrib/libffi && ./configure --build=x86_64-w64-mingw32 --host=x86_64-w64-mingw32 --prefix=`pwd`/win64 --enable-static --disable-docs && make && make install" diff --git a/core/context.cpp b/core/context.cpp index 917a2f20..3b516dbf 100644 --- a/core/context.cpp +++ b/core/context.cpp @@ -1728,9 +1728,9 @@ void Context::ItemTensorEval(torch::Tensor &self, ObjPtr obj, ObjPtr args) { if(self.dim() == 0) { signed char *ptr_char = nullptr; - short *ptr_short = nullptr; - int *ptr_int = nullptr; - long *ptr_long = nullptr; + int16_t *ptr_short = nullptr; + int32_t *ptr_int = nullptr; + int64_t *ptr_long = nullptr; float *ptr_float = nullptr; double *ptr_double = nullptr; @@ -1741,19 +1741,19 @@ void Context::ItemTensorEval(torch::Tensor &self, ObjPtr obj, ObjPtr args) { *ptr_char = static_cast (obj->Call(this)->GetValueAsInteger()); return; case ObjType::Short: - ptr_short = self.data_ptr(); + ptr_short = self.data_ptr(); ASSERT(ptr_short); - *ptr_short = static_cast (obj->Call(this)->GetValueAsInteger()); + *ptr_short = static_cast (obj->Call(this)->GetValueAsInteger()); return; case ObjType::Int: - ptr_int = self.data_ptr(); + ptr_int = self.data_ptr(); ASSERT(ptr_int); - *ptr_int = static_cast (obj->Call(this)->GetValueAsInteger()); + *ptr_int = static_cast (obj->Call(this)->GetValueAsInteger()); return; case ObjType::Long: - ptr_long = self.data_ptr(); + ptr_long = self.data_ptr(); ASSERT(ptr_long); - *ptr_long = static_cast (obj->Call(this)->GetValueAsInteger()); + *ptr_long = static_cast (obj->Call(this)->GetValueAsInteger()); return; case ObjType::Float: ptr_float = self.data_ptr(); diff --git a/core/nlc.cpp b/core/nlc.cpp index 3d21d9fd..17838f01 100644 --- a/core/nlc.cpp +++ b/core/nlc.cpp @@ -10,7 +10,7 @@ using namespace newlang; #pragma comment(lib, "torch.lib") #pragma comment(lib, "torch_cpu.lib") #pragma comment(lib, "c10.lib") -#pragma comment(lib, "libffi.a") +#pragma comment(lib, "libffi.dll.a") //#pragma comment(lib, "pthreadpool.lib") //#pragma comment(lib, "libprotoc.lib") diff --git a/core/object.cpp b/core/object.cpp index d5c64c37..044947d8 100644 --- a/core/object.cpp +++ b/core/object.cpp @@ -179,16 +179,16 @@ const Variable::PairType & Obj::at(int64_t index) const { m_str_pair = pair(CreateString(std::string(1, m_str[index]))); return m_str_pair; } - LOG_RUNTIME("Index '%lu' not exists in byte string '%s'!", static_cast (index), m_str.c_str()); + LOG_RUNTIME("Index '%ld' not exists in byte string '%s'!", index, m_str.c_str()); } else if(m_var_type_current == ObjType::StrWide) { if(index < static_cast (m_wstr.size())) { m_str_pair = pair(CreateString(std::wstring(1, m_wstr[index]))); return m_str_pair; } - LOG_RUNTIME("Index '%lu' not exists in byte string '%s'!", static_cast (index), "WIDE"); + LOG_RUNTIME("Index '%ld' not exists in byte string '%s'!", index, "WIDE"); } else if(is_tensor()) { - torch::Tensor t = m_value.index({(int) index}); + torch::Tensor t = m_value.index({index}); m_str_pair = pair(Obj::CreateTensor(t)); return m_str_pair; } @@ -201,13 +201,13 @@ Variable::PairType & Obj::at(int64_t index) { m_str_pair = pair(CreateString(std::string(1, m_str[index]))); return m_str_pair; } - LOG_RUNTIME("Index '%lu' not exists in byte string '%s'!", static_cast (index), m_str.c_str()); + LOG_RUNTIME("Index '%ld' not exists in byte string '%s'!", index, m_str.c_str()); } else if(m_var_type_current == ObjType::StrWide) { if(index < static_cast (m_wstr.size())) { m_str_pair = pair(CreateString(std::wstring(1, m_wstr[index]))); return m_str_pair; } - LOG_RUNTIME("Index '%lu' not exists in byte string '%s'!", static_cast (index), "WIDE"); + LOG_RUNTIME("Index '%ld' not exists in byte string '%s'!", index, "WIDE"); } else if(is_tensor()) { torch::Tensor t = m_value.index({(int) index}); @@ -287,23 +287,23 @@ ObjPtr Obj::index_set_(const std::vector &index, const ObjPtr value) { LOG_RUNTIME("Don`t set index '%s' in object '%s'!", IndexToString(index).c_str(), toString().c_str()); } -ObjPtr Obj::op_set_index(size_t index, std::string value) { +ObjPtr Obj::op_set_index(int64_t index, std::string value) { if(m_var_type_current == ObjType::StrChar) { - if(index < m_str.size()) { + if(index < static_cast(m_str.size())) { m_str.erase(index, 1); m_str.insert(index, value); m_var_is_init = true; return shared(); } - LOG_RUNTIME("Index '%lu' not exists in byte string '%s'!", static_cast (index), m_str.c_str()); + LOG_RUNTIME("Index '%ld' not exists in byte string '%s'!", index, m_str.c_str()); } else if(m_var_type_current == ObjType::StrWide) { - if(index < m_wstr.size()) { + if(index < static_cast(m_wstr.size())) { m_wstr.erase(index, 1); m_wstr.insert(index, utf8_decode(value)); m_var_is_init = true; return shared(); } - LOG_RUNTIME("Index '%lu' not exists in byte string '%s'!", static_cast (index), "WIDE"); + LOG_RUNTIME("Index '%ld' not exists in byte string '%s'!", index, "WIDE"); } // at(index).second.set_(value); (*at(index).second) = value; diff --git a/core/object.h b/core/object.h index c518d935..d40e3cb9 100644 --- a/core/object.h +++ b/core/object.h @@ -1462,7 +1462,7 @@ namespace newlang { inline ObjPtr op_set_index(ObjPtr index, ObjPtr value) { return op_set_index(index->GetValueAsInteger(), value->GetValueAsString()); } - ObjPtr op_set_index(size_t index, std::string value); + ObjPtr op_set_index(int64_t index, std::string value); template < typename T> typename std::enable_if::value, void>::type diff --git a/core/test/alg_test.cpp b/core/test/alg_test.cpp index 644ff968..fd0ec66f 100644 --- a/core/test/alg_test.cpp +++ b/core/test/alg_test.cpp @@ -1,7 +1,8 @@ -#include "core/parser.h" +#include "pch.h" + #ifdef UNITTEST -#include +#include "core/parser.h" #include diff --git a/core/test/compiler_test.cpp b/core/test/compiler_test.cpp index e8a678f6..b2b730e0 100644 --- a/core/test/compiler_test.cpp +++ b/core/test/compiler_test.cpp @@ -1,6 +1,7 @@ +#include "pch.h" + #ifdef UNITTEST -#include "core/pch.h" #include "core/term.h" #include diff --git a/core/test/eval_test.cpp b/core/test/eval_test.cpp index c7fbd6c7..e162dc36 100644 --- a/core/test/eval_test.cpp +++ b/core/test/eval_test.cpp @@ -1,7 +1,7 @@ -#include "core/parser.h" -#ifdef UNITTEST +#include "pch.h" -#include +#ifdef UNITTEST +#include "core/parser.h" #include diff --git a/core/test/fraction_test.cpp b/core/test/fraction_test.cpp index ffa84fc3..4ff8be01 100644 --- a/core/test/fraction_test.cpp +++ b/core/test/fraction_test.cpp @@ -1,3 +1,5 @@ +#include "pch.h" + //#ifdef UNITTEST // //#include "core/pch.h" diff --git a/core/test/lexer_test.cpp b/core/test/lexer_test.cpp index 86b10820..17cd8e54 100644 --- a/core/test/lexer_test.cpp +++ b/core/test/lexer_test.cpp @@ -1,6 +1,6 @@ -#ifdef UNITTEST +#include "pch.h" -#include "core/pch.h" +#ifdef UNITTEST #include #include diff --git a/core/test/nlc_test.cpp b/core/test/nlc_test.cpp index f153aa34..8e7616fc 100644 --- a/core/test/nlc_test.cpp +++ b/core/test/nlc_test.cpp @@ -1,6 +1,6 @@ -#ifdef UNITTEST +#include "pch.h" -#include "core/pch.h" +#ifdef UNITTEST #include #include diff --git a/core/test/object_test.cpp b/core/test/object_test.cpp index 6db24bcb..e3164610 100644 --- a/core/test/object_test.cpp +++ b/core/test/object_test.cpp @@ -1,6 +1,7 @@ +#include "pch.h" + #ifdef UNITTEST -#include "core/pch.h" #include "core/fraction.h" #include diff --git a/core/test/parser_test.cpp b/core/test/parser_test.cpp index 6d8734b2..5737f7a7 100644 --- a/core/test/parser_test.cpp +++ b/core/test/parser_test.cpp @@ -1,6 +1,6 @@ -#ifdef UNITTEST +#include "pch.h" -#include "core/pch.h" +#ifdef UNITTEST #include #include diff --git a/core/types.h b/core/types.h index 7141e1af..53d4888d 100644 --- a/core/types.h +++ b/core/types.h @@ -578,9 +578,9 @@ void ParserException(const char *msg, std::string &buffer, int row, int col); bool *ptr_boll = nullptr; signed char *ptr_char = nullptr; - short *ptr_short = nullptr; - int *ptr_int = nullptr; - long *ptr_long = nullptr; + int16_t *ptr_short = nullptr; + int32_t *ptr_int = nullptr; + int64_t *ptr_long = nullptr; float *ptr_float = nullptr; double *ptr_double = nullptr; @@ -598,19 +598,19 @@ void ParserException(const char *msg, std::string &buffer, int row, int col); *ptr_char = set.item().toChar(); return; case ObjType::Short: - ptr_short = self.data_ptr(); + ptr_short = self.data_ptr(); ASSERT(ptr_short); *ptr_short = set.item().toShort(); return; case ObjType::Int: - ptr_int = self.data_ptr(); + ptr_int = self.data_ptr(); ASSERT(ptr_int); *ptr_int = set.item().toInt(); return; case ObjType::Long: - ptr_long = self.data_ptr(); + ptr_long = self.data_ptr(); ASSERT(ptr_long); - *ptr_long = static_cast (set.item().toLong()); + *ptr_long = static_cast (set.item().toLong()); return; case ObjType::Float: ptr_float = self.data_ptr(); @@ -641,21 +641,21 @@ void ParserException(const char *msg, std::string &buffer, int row, int col); } return; } else if (ObjType::Short == type) { - auto acc_short = self.accessor(); + auto acc_short = self.accessor(); for (int i = 0; i < acc_short.size(0); i++) { acc_short[i] = set.item().toShort(); } return; } else if (ObjType::Int == type) { - auto acc_int = self.accessor(); + auto acc_int = self.accessor(); for (int i = 0; i < acc_int.size(0); i++) { acc_int[i] = set.item().toInt(); } return; } else if (ObjType::Long == type) { - auto acc_long = self.accessor(); + auto acc_long = self.accessor(); for (int i = 0; i < acc_long.size(0); i++) { - acc_long[i] = static_cast (set.item().toLong()); + acc_long[i] = static_cast (set.item().toLong()); } return; } else if (ObjType::Float == type) { @@ -690,7 +690,7 @@ void ParserException(const char *msg, std::string &buffer, int row, int col); } return; } else if (ObjType::Short == type) { - auto acc_short = self.accessor(); + auto acc_short = self.accessor(); for (int i = 0; i < acc_short.size(0); i++) { for (int j = 0; j < acc_short.size(1); j++) { acc_short[i][j] = set.item().toShort(); @@ -698,7 +698,7 @@ void ParserException(const char *msg, std::string &buffer, int row, int col); } return; } else if (ObjType::Int == type) { - auto acc_int = self.accessor(); + auto acc_int = self.accessor(); for (int i = 0; i < acc_int.size(0); i++) { for (int j = 0; j < acc_int.size(1); j++) { acc_int[i][j] = set.item().toInt(); @@ -706,10 +706,10 @@ void ParserException(const char *msg, std::string &buffer, int row, int col); } return; } else if (ObjType::Long == type) { - auto acc_long = self.accessor(); + auto acc_long = self.accessor(); for (int i = 0; i < acc_long.size(0); i++) { for (int j = 0; j < acc_long.size(1); j++) { - acc_long[i][j] = static_cast (set.item().toLong()); + acc_long[i][j] = static_cast (set.item().toLong()); } } return; diff --git a/nlc-win/nlc.vcxproj b/nlc-win/nlc.vcxproj index 5e2fa0ae..8aa89cc4 100644 --- a/nlc-win/nlc.vcxproj +++ b/nlc-win/nlc.vcxproj @@ -115,10 +115,12 @@ stdc17 pch.h.pch false + true Console true + $(OutDir)nlc$(TargetExt) true From a7d6194a8a56cae2725831eb40c1ca2f288c3f83 Mon Sep 17 00:00:00 2001 From: Aleksandr Ryabikov Date: Wed, 29 Jun 2022 14:48:37 +0300 Subject: [PATCH 09/31] =?UTF-8?q?=D0=A0=D0=B5=D0=BE=D1=80=D0=B3=D0=B0?= =?UTF-8?q?=D0=BD=D0=B8=D0=B7=D0=B0=D1=86=D0=B8=D1=8F=20=D0=B8=D1=81=D1=85?= =?UTF-8?q?=D0=BE=D0=B4=D0=BD=D0=B8=D0=BA=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 6 +- contrib/logger/logger.cpp | 4 +- core/Makefile | 211 ------------------ {core/nlp => examples}/fileio.nlp | 0 {core => src}/.dep.inc | 0 {core => src}/.gitignore | 9 +- {core => src}/autocomplete.h | 2 +- {core => src}/builtin.cpp | 6 +- {core => src}/builtin.h | 6 +- {core => src}/compile_syntax.sh | 0 {core => src}/context.cpp | 40 +++- {core => src}/context.h | 5 +- {core => src}/dsl.nlp | 0 {core => src}/fraction.h | 0 {core => src}/lexer.cpp | 0 {core => src}/lexer.h | 0 {core => src}/lexer.l | 4 +- {core => src}/nbproject/Makefile-Debug.mk | 0 {core => src}/nbproject/Makefile-GCOV.mk | 0 {core => src}/nbproject/Makefile-LLVM.mk | 8 +- {core => src}/nbproject/Makefile-LLVM_GCC.mk | 8 +- {core => src}/nbproject/Makefile-Release.mk | 6 +- .../nbproject/Makefile-UnitTest-Win32.mk | 0 .../nbproject/Makefile-UnitTest-Win64.mk | 0 {core => src}/nbproject/Makefile-UnitTest.mk | 55 ++--- .../nbproject/Makefile-UnitTest_LLVM.mk | 8 +- {core => src}/nbproject/Makefile-impl.mk | 2 +- {core => src}/nbproject/Makefile-variables.mk | 58 ++--- {core => src}/nbproject/Package-Debug.bash | 8 +- {core => src}/nbproject/Package-GCOV.bash | 8 +- {core => src}/nbproject/Package-LLVM.bash | 12 +- {core => src}/nbproject/Package-LLVM_GCC.bash | 12 +- {core => src}/nbproject/Package-Release.bash | 12 +- .../nbproject/Package-UnitTest-Win32.bash | 8 +- .../nbproject/Package-UnitTest-Win64.bash | 8 +- {core => src}/nbproject/Package-UnitTest.bash | 12 +- .../nbproject/Package-UnitTest_LLVM.bash | 12 +- {core => src}/nbproject/configurations.xml | 45 ++-- src/nbproject/project.properties | 1 + {core => src}/nbproject/project.xml | 2 +- {core => src}/newlang.cpp | 6 +- {core => src}/newlang.h | 8 +- {core => src}/nlc.cpp | 2 +- {core => src}/nlc.h | 8 +- {core => src}/object.cpp | 28 +-- {core => src}/object.h | 12 +- {core => src}/parser.cpp | 2 +- {core => src}/parser.h | 6 +- {core => src}/parser.y | 4 +- {core => src}/pch.cpp | 0 {core => src}/pch.h | 6 +- {core => src}/term.cpp | 2 +- {core => src}/term.h | 8 +- {core => src}/test/alg_test.cpp | 10 +- {core => src}/test/compiler_test.cpp | 10 +- {core => src}/test/eval_test.cpp | 12 +- {core => src}/test/fraction_test.cpp | 8 +- {core => src}/test/lexer_test.cpp | 12 +- {core => src}/test/nlc_test.cpp | 8 +- {core => src}/test/object_test.cpp | 18 +- {core => src}/test/parser_test.cpp | 20 +- {core => src}/types.h | 2 +- {core => src}/variable.cpp | 2 +- {core => src}/variable.h | 208 +++++++++++++---- {core => src}/warning_pop.h | 0 {core => src}/warning_push.h | 0 {nlc-win => src/win}/nlc.sln | 0 {nlc-win => src/win}/nlc.vcxproj | 109 ++++----- 68 files changed, 506 insertions(+), 583 deletions(-) delete mode 100644 core/Makefile rename {core/nlp => examples}/fileio.nlp (100%) rename {core => src}/.dep.inc (100%) rename {core => src}/.gitignore (51%) rename {core => src}/autocomplete.h (99%) rename {core => src}/builtin.cpp (99%) rename {core => src}/builtin.h (96%) rename {core => src}/compile_syntax.sh (100%) rename {core => src}/context.cpp (99%) rename {core => src}/context.h (99%) rename {core => src}/dsl.nlp (100%) rename {core => src}/fraction.h (100%) rename {core => src}/lexer.cpp (100%) rename {core => src}/lexer.h (100%) rename {core => src}/lexer.l (99%) rename {core => src}/nbproject/Makefile-Debug.mk (100%) rename {core => src}/nbproject/Makefile-GCOV.mk (100%) rename {core => src}/nbproject/Makefile-LLVM.mk (97%) rename {core => src}/nbproject/Makefile-LLVM_GCC.mk (97%) rename {core => src}/nbproject/Makefile-Release.mk (97%) rename {core => src}/nbproject/Makefile-UnitTest-Win32.mk (100%) rename {core => src}/nbproject/Makefile-UnitTest-Win64.mk (100%) rename {core => src}/nbproject/Makefile-UnitTest.mk (52%) rename {core => src}/nbproject/Makefile-UnitTest_LLVM.mk (98%) rename {core => src}/nbproject/Makefile-impl.mk (99%) rename {core => src}/nbproject/Makefile-variables.mk (66%) rename {core => src}/nbproject/Package-Debug.bash (89%) rename {core => src}/nbproject/Package-GCOV.bash (89%) rename {core => src}/nbproject/Package-LLVM.bash (84%) rename {core => src}/nbproject/Package-LLVM_GCC.bash (84%) rename {core => src}/nbproject/Package-Release.bash (84%) rename {core => src}/nbproject/Package-UnitTest-Win32.bash (89%) rename {core => src}/nbproject/Package-UnitTest-Win64.bash (89%) rename {core => src}/nbproject/Package-UnitTest.bash (85%) rename {core => src}/nbproject/Package-UnitTest_LLVM.bash (84%) rename {core => src}/nbproject/configurations.xml (99%) create mode 100644 src/nbproject/project.properties rename {core => src}/nbproject/project.xml (98%) rename {core => src}/newlang.cpp (99%) rename {core => src}/newlang.h (99%) rename {core => src}/nlc.cpp (96%) rename {core => src}/nlc.h (99%) rename {core => src}/object.cpp (99%) rename {core => src}/object.h (99%) rename {core => src}/parser.cpp (99%) rename {core => src}/parser.h (99%) rename {core => src}/parser.y (99%) rename {core => src}/pch.cpp (100%) rename {core => src}/pch.h (92%) rename {core => src}/term.cpp (95%) rename {core => src}/term.h (99%) rename {core => src}/test/alg_test.cpp (99%) rename {core => src}/test/compiler_test.cpp (99%) rename {core => src}/test/eval_test.cpp (99%) rename {core => src}/test/fraction_test.cpp (92%) rename {core => src}/test/lexer_test.cpp (98%) rename {core => src}/test/nlc_test.cpp (99%) rename {core => src}/test/object_test.cpp (99%) rename {core => src}/test/parser_test.cpp (99%) rename {core => src}/types.h (99%) rename {core => src}/variable.cpp (99%) rename {core => src}/variable.h (71%) rename {core => src}/warning_pop.h (100%) rename {core => src}/warning_push.h (100%) rename {nlc-win => src/win}/nlc.sln (100%) rename {nlc-win => src/win}/nlc.vcxproj (73%) diff --git a/.gitignore b/.gitignore index 9248be16..2839195e 100644 --- a/.gitignore +++ b/.gitignore @@ -16,9 +16,11 @@ Makefile **/*.vcxproj.filters **/*.vcxproj.user -core/syntax_help.cpp -core/version.* +**/syntax_help.cpp +**/version.* docs/syntax.txt +output +**/*temp* # Binaries diff --git a/contrib/logger/logger.cpp b/contrib/logger/logger.cpp index 469dfe3b..160cbdf4 100644 --- a/contrib/logger/logger.cpp +++ b/contrib/logger/logger.cpp @@ -5,9 +5,9 @@ #include -#include +#include "warning_push.h" #include -#include +#include "warning_pop.h" using namespace utils; diff --git a/core/Makefile b/core/Makefile deleted file mode 100644 index 2daa2c6a..00000000 --- a/core/Makefile +++ /dev/null @@ -1,211 +0,0 @@ -# -# There exist several targets which are by default empty and which can be -# used for execution of your targets. These targets are usually executed -# before and after some main targets. They are: -# -# .build-pre: called before 'build' target -# .build-post: called after 'build' target -# .clean-pre: called before 'clean' target -# .clean-post: called after 'clean' target -# .clobber-pre: called before 'clobber' target -# .clobber-post: called after 'clobber' target -# .all-pre: called before 'all' target -# .all-post: called after 'all' target -# .help-pre: called before 'help' target -# .help-post: called after 'help' target -# -# Targets beginning with '.' are not intended to be called on their own. -# -# Main targets can be executed directly, and they are: -# -# build build a specific configuration -# clean remove built files from a configuration -# clobber remove all built files -# all build all configurations -# help print help mesage -# -# Targets .build-impl, .clean-impl, .clobber-impl, .all-impl, and -# .help-impl are implemented in nbproject/makefile-impl.mk. -# -# Available make variables: -# -# CND_BASEDIR base directory for relative paths -# CND_DISTDIR default top distribution directory (build artifacts) -# CND_BUILDDIR default top build directory (object files, ...) -# CONF name of current configuration -# CND_PLATFORM_${CONF} platform name (current configuration) -# CND_ARTIFACT_DIR_${CONF} directory of build artifact (current configuration) -# CND_ARTIFACT_NAME_${CONF} name of build artifact (current configuration) -# CND_ARTIFACT_PATH_${CONF} path to build artifact (current configuration) -# CND_PACKAGE_DIR_${CONF} directory of package (current configuration) -# CND_PACKAGE_NAME_${CONF} name of package (current configuration) -# CND_PACKAGE_PATH_${CONF} path to package (current configuration) -# -# NOCDDL - - -# Environment -MKDIR=mkdir -CP=cp -CCADMIN=CCadmin - - -VERSION_MAJOR=0 -VERSION_MINOR=1 -VERSION_PATCH=0 -VERSION_HEADER="version.h" -VERSION_FILE="version.c" - - -GIT_TAG_VERSION=$(shell git describe --abbrev=0 --tags) -GIT_SHORT_HASH=$(shell git rev-parse --short HEAD) -GIT_SOURCE_ID=$(GIT_TAG_VERSION)-$(GIT_SHORT_HASH) -DATE_BUILD=$(shell date +'%y.%m.%d %H:%M:%S') - -# build -build: .build-post - -.build-pre: -# Add your pre 'build' code here... - -# @if [ ! -d "temp" ]; then \ -# @mkdir temp; \ -# fi -# pandoc -t plain ../docs/syntax.md > ../docs/syntax.txt -# ../contrib/text2cpp/output/bin/text2cpp ../docs/syntax.txt syntax_help.cpp newlang_syntax_help c -# -# -# @if [ "$(GIT_TAG_VERSION)" != "v$(VERSION_MAJOR).$(VERSION_MINOR).$(VERSION_PATCH)" ]; then \ -# echo "Git TAG $(GIT_TAG_VERSION) differ version v$(VERSION_MAJOR).$(VERSION_MINOR).$(VERSION_PATCH)"; \ -# exit 1; \ -# fi -# @if [ -z $(GIT_SHORT_HASH) ]; then \ -# echo Undefined version for build; \ -# exit 1; \ -# fi -# @if [ -f $(VERSION_HEADER) ]; then \ -# rm $(VERSION_HEADER); \ -# fi -# -# @echo "/** @file $(VERSION_HEADER)" > $(VERSION_HEADER) -# @echo "* Auto generate file for identification current build" >> $(VERSION_HEADER) -# @echo "* Date build $(DATE_BUILD)" >> $(VERSION_HEADER) -# @echo "*/" >> $(VERSION_HEADER) -# @echo "" >> $(VERSION_HEADER) -# -# @echo "#include " >> $(VERSION_HEADER) -# -# @echo "extern const uint8_t VERSION_MAJOR;" >> $(VERSION_HEADER) -# @echo "extern const uint8_t VERSION_MINOR;" >> $(VERSION_HEADER) -# @echo "extern const uint8_t VERSION_PATCH;" >> $(VERSION_HEADER) -# @echo "extern const uint16_t VERSION_BUILD;" >> $(VERSION_HEADER) -# @echo "" >> $(VERSION_HEADER) -# -# @echo "#define VERSION ($(VERSION_MAJOR) << 4 | $(VERSION_MINOR))" >> $(VERSION_HEADER) -# @echo "#define VERSION_GIT_SOURCE \"$(GIT_SOURCE_ID)\"" >> $(VERSION_HEADER) -# @echo "#define VERSION_DATE_BUILD_STR \"$(DATE_BUILD)\"" >> $(VERSION_HEADER) -# @echo "#define VERSION_SOURCE_FULL_ID \"$(GIT_SOURCE_ID) $(DATE_BUILD)\"" >> $(VERSION_HEADER) -# @echo "" >> $(VERSION_HEADER) -# -# @echo "extern const char * GIT_SOURCE;" >> $(VERSION_HEADER) -# @echo "extern const char * DATE_BUILD_STR;" >> $(VERSION_HEADER) -# @echo "extern const char * SOURCE_FULL_ID; " >> $(VERSION_HEADER) -# @echo "" >> $(VERSION_HEADER) -# -# @if [ -f $(VERSION_FILE) ]; then \ -# rm $(VERSION_FILE); \ -# fi -# -# @echo "/** @file $(VERSION_FILE)" > $(VERSION_FILE) -# @echo "* Auto generate file for identification current build" >> $(VERSION_FILE) -# @echo "* Date build $(DATE_BUILD)" >> $(VERSION_FILE) -# @echo "*/" >> $(VERSION_FILE) -# @echo "" >> $(VERSION_FILE) -# -# @echo "#include " >> $(VERSION_FILE) -# @echo "#include " >> $(VERSION_FILE) -# @echo "" >> $(VERSION_FILE) -# -# @echo "const uint8_t VERSION_MAJOR=$(VERSION_MAJOR);" >> $(VERSION_FILE) -# @echo "const uint8_t VERSION_MINOR=$(VERSION_MINOR);" >> $(VERSION_FILE) -# @echo "const uint8_t VERSION_PATCH=$(VERSION_PATCH);" >> $(VERSION_FILE) -# @echo "" >> $(VERSION_FILE) -# -# @echo "const char * GIT_SOURCE = VERSION_GIT_SOURCE;" >> $(VERSION_FILE) -# @echo "const char * DATE_BUILD_STR = VERSION_DATE_BUILD_STR;" >> $(VERSION_FILE) -# @echo "const char * SOURCE_FULL_ID = VERSION_SOURCE_FULL_ID;" >> $(VERSION_FILE) -# @echo "" >> $(VERSION_FILE) -# -# @echo Mark version $(GIT_SOURCE_ID) $(DATE_BUILD) - - -.build-post: .build-impl -# Add your post 'build' code here... - - -# clean -clean: .clean-post - -.clean-pre: -# Add your pre 'clean' code here... - -.clean-post: .clean-impl -# Add your post 'clean' code here... - - -# clobber -clobber: .clobber-post - -.clobber-pre: -# Add your pre 'clobber' code here... - -.clobber-post: .clobber-impl -# Add your post 'clobber' code here... - - -# all -all: .all-post - -.all-pre: -# Add your pre 'all' code here... - -.all-post: .all-impl -# Add your post 'all' code here... - - -# build tests -build-tests: .build-tests-post - -.build-tests-pre: -# Add your pre 'build-tests' code here... - -.build-tests-post: .build-tests-impl -# Add your post 'build-tests' code here... - - -# run tests -test: .test-post - -.test-pre: build-tests -# Add your pre 'test' code here... - -.test-post: .test-impl -# Add your post 'test' code here... - - -# help -help: .help-post - -.help-pre: -# Add your pre 'help' code here... - -.help-post: .help-impl -# Add your post 'help' code here... - - - -# include project implementation makefile -include nbproject/Makefile-impl.mk - -# include project make variables -include nbproject/Makefile-variables.mk diff --git a/core/nlp/fileio.nlp b/examples/fileio.nlp similarity index 100% rename from core/nlp/fileio.nlp rename to examples/fileio.nlp diff --git a/core/.dep.inc b/src/.dep.inc similarity index 100% rename from core/.dep.inc rename to src/.dep.inc diff --git a/core/.gitignore b/src/.gitignore similarity index 51% rename from core/.gitignore rename to src/.gitignore index fcaf320e..7768376b 100644 --- a/core/.gitignore +++ b/src/.gitignore @@ -3,11 +3,6 @@ lexer.yy.cpp location.hh parser.yy.h parser.yy.cpp -*.temp.* -*.temp -*.yy.gv -*.yy.output -brother.sh -hello.sh +*.gv +*.output **/gcov** -newlang_test \ No newline at end of file diff --git a/core/autocomplete.h b/src/autocomplete.h similarity index 99% rename from core/autocomplete.h rename to src/autocomplete.h index 083b701c..75065c59 100644 --- a/core/autocomplete.h +++ b/src/autocomplete.h @@ -36,7 +36,7 @@ #endif #endif -#include +#include #define MAX_OF(x, y) (((x) > (y)) ? (x) : (y)) diff --git a/core/builtin.cpp b/src/builtin.cpp similarity index 99% rename from core/builtin.cpp rename to src/builtin.cpp index 0037b723..af77b44d 100644 --- a/core/builtin.cpp +++ b/src/builtin.cpp @@ -1,9 +1,9 @@ #include "pch.h" -#include +#include -#include -#include +#include +#include using namespace newlang; diff --git a/core/builtin.h b/src/builtin.h similarity index 96% rename from core/builtin.h rename to src/builtin.h index 52d3e848..3230fb9c 100644 --- a/core/builtin.h +++ b/src/builtin.h @@ -4,9 +4,9 @@ #include "pch.h" -#include -#include -#include +#include +#include +#include #define FUNC_DIRECT(NAME, FUNC) \ newlang::ObjPtr FUNC(newlang::Context *ctx, newlang::Obj &in);\ diff --git a/core/compile_syntax.sh b/src/compile_syntax.sh similarity index 100% rename from core/compile_syntax.sh rename to src/compile_syntax.sh diff --git a/core/context.cpp b/src/context.cpp similarity index 99% rename from core/context.cpp rename to src/context.cpp index 3b516dbf..ca1023c0 100644 --- a/core/context.cpp +++ b/src/context.cpp @@ -1,10 +1,10 @@ #include "contrib/logger/logger.h" #include "pch.h" -#include -#include -#include -#include +#include +#include +#include +#include #include #include @@ -1527,7 +1527,19 @@ void *RunTime::GetProcAddress(const char *name, const char *module) { #endif } +void Context::CleanUp() { + auto iter = begin(); + while(iter != end()) { + if(iter->second.expired()) { + iter = erase(iter); + } else { + iter++; + } + } +} + ObjPtr Context::FindSessionTerm(const char *name, bool current_only) { + CleanUp(); auto found = select(MakeName(name)); while(!found.complete()) { ObjPtr obj = found.data().second.lock(); @@ -1627,6 +1639,8 @@ ObjPtr Context::CreateLVal(Context *ctx, TermPtr term, Obj * args) { ASSERT(term); ASSERT(!term->m_text.empty()); + ctx->CleanUp(); + auto iter = ctx->select(term->m_text); if(!iter.complete()) { @@ -1972,18 +1986,22 @@ ObjPtr Context::CreateRVal(Context *ctx, TermPtr term, Obj * local_vars, bool in result->m_var_type_current = ObjType::None; return result; } else if(term->m_text.compare("$") == 0) { + result->m_var_type_current = ObjType::Dictionary; result->m_var_name = "$"; - int pos = 0; - while(ctx && pos < ctx->size()) { - if(ctx->at(pos).second.lock()) { - result->push_back(Obj::CreateString(ctx->at(pos).first)); - // result->push_back(Obj::Arg(ctx->at(pos).first)); - pos++; + + ASSERT(ctx); + + auto iter = ctx->m_data.begin(); + while(iter != ctx->m_data.end()) { + if(!iter->second.expired()) { + result->push_back(Obj::CreateString(iter->first)); + iter++; } else { - ctx->erase(pos); + iter = ctx->m_data.erase(iter); } } + result->m_var_is_init = true; return result; } else if(term->m_text.compare("@") == 0) { diff --git a/core/context.h b/src/context.h similarity index 99% rename from core/context.h rename to src/context.h index da2186fa..6e6873ab 100644 --- a/core/context.h +++ b/src/context.h @@ -4,8 +4,8 @@ #include "pch.h" -#include -#include +#include +#include namespace newlang { @@ -251,6 +251,7 @@ namespace newlang { ObjPtr GetTerm(const std::string name, bool is_ref); ObjPtr FindTerm(const std::string name); ObjPtr FindSessionTerm(const char *name, bool current_only = false); + void CleanUp(); ObjPtr CreateSessionTerm(ObjPtr obj, const char *name); diff --git a/core/dsl.nlp b/src/dsl.nlp similarity index 100% rename from core/dsl.nlp rename to src/dsl.nlp diff --git a/core/fraction.h b/src/fraction.h similarity index 100% rename from core/fraction.h rename to src/fraction.h diff --git a/core/lexer.cpp b/src/lexer.cpp similarity index 100% rename from core/lexer.cpp rename to src/lexer.cpp diff --git a/core/lexer.h b/src/lexer.h similarity index 100% rename from core/lexer.h rename to src/lexer.h diff --git a/core/lexer.l b/src/lexer.l similarity index 99% rename from core/lexer.l rename to src/lexer.l index 8864f84f..4949b23d 100644 --- a/core/lexer.l +++ b/src/lexer.l @@ -30,8 +30,8 @@ #include "lexer.h" -#include -#include +#include +#include using namespace newlang; diff --git a/core/nbproject/Makefile-Debug.mk b/src/nbproject/Makefile-Debug.mk similarity index 100% rename from core/nbproject/Makefile-Debug.mk rename to src/nbproject/Makefile-Debug.mk diff --git a/core/nbproject/Makefile-GCOV.mk b/src/nbproject/Makefile-GCOV.mk similarity index 100% rename from core/nbproject/Makefile-GCOV.mk rename to src/nbproject/Makefile-GCOV.mk diff --git a/core/nbproject/Makefile-LLVM.mk b/src/nbproject/Makefile-LLVM.mk similarity index 97% rename from core/nbproject/Makefile-LLVM.mk rename to src/nbproject/Makefile-LLVM.mk index d33fd1a1..88ca82a9 100644 --- a/core/nbproject/Makefile-LLVM.mk +++ b/src/nbproject/Makefile-LLVM.mk @@ -78,13 +78,13 @@ LDLIBSOPTIONS=../contrib/PDCurses/x11/libXCurses.a -lXaw -lXmu -lXt -lX11 -lXpm # Build Targets .build-conf: ${BUILD_SUBPROJECTS} - "${MAKE}" -f nbproject/Makefile-${CND_CONF}.mk ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/core + "${MAKE}" -f nbproject/Makefile-${CND_CONF}.mk ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/src -${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/core: ../contrib/PDCurses/x11/libXCurses.a +${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/src: ../contrib/PDCurses/x11/libXCurses.a -${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/core: ${OBJECTFILES} +${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/src: ${OBJECTFILES} ${MKDIR} -p ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM} - ${LINK.cc} -o ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/core ${OBJECTFILES} ${LDLIBSOPTIONS} `llvm-config-12 --libs --ldflags` -fno-rtti -fuse-ld=lld-12 -stdlib=libstdc++ + ${LINK.cc} -o ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/src ${OBJECTFILES} ${LDLIBSOPTIONS} `llvm-config-12 --libs --ldflags` -fno-rtti -fuse-ld=lld-12 -stdlib=libstdc++ ${OBJECTDIR}/_ext/1e501df/gtest-all.o: ../contrib/googletest/googletest/src/gtest-all.cc ${MKDIR} -p ${OBJECTDIR}/_ext/1e501df diff --git a/core/nbproject/Makefile-LLVM_GCC.mk b/src/nbproject/Makefile-LLVM_GCC.mk similarity index 97% rename from core/nbproject/Makefile-LLVM_GCC.mk rename to src/nbproject/Makefile-LLVM_GCC.mk index 49758c5e..96b8f9c7 100644 --- a/core/nbproject/Makefile-LLVM_GCC.mk +++ b/src/nbproject/Makefile-LLVM_GCC.mk @@ -78,13 +78,13 @@ LDLIBSOPTIONS=-L/usr/lib/llvm-12/lib ../contrib/PDCurses/x11/libXCurses.a -lXaw # Build Targets .build-conf: ${BUILD_SUBPROJECTS} - "${MAKE}" -f nbproject/Makefile-${CND_CONF}.mk ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/core + "${MAKE}" -f nbproject/Makefile-${CND_CONF}.mk ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/src -${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/core: ../contrib/PDCurses/x11/libXCurses.a +${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/src: ../contrib/PDCurses/x11/libXCurses.a -${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/core: ${OBJECTFILES} +${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/src: ${OBJECTFILES} ${MKDIR} -p ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM} - ${LINK.cc} -o ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/core ${OBJECTFILES} ${LDLIBSOPTIONS} + ${LINK.cc} -o ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/src ${OBJECTFILES} ${LDLIBSOPTIONS} ${OBJECTDIR}/_ext/1e501df/gtest-all.o: ../contrib/googletest/googletest/src/gtest-all.cc ${MKDIR} -p ${OBJECTDIR}/_ext/1e501df diff --git a/core/nbproject/Makefile-Release.mk b/src/nbproject/Makefile-Release.mk similarity index 97% rename from core/nbproject/Makefile-Release.mk rename to src/nbproject/Makefile-Release.mk index 782e417a..b37eaf57 100644 --- a/core/nbproject/Makefile-Release.mk +++ b/src/nbproject/Makefile-Release.mk @@ -78,11 +78,11 @@ LDLIBSOPTIONS=-lpthread # Build Targets .build-conf: ${BUILD_SUBPROJECTS} - "${MAKE}" -f nbproject/Makefile-${CND_CONF}.mk ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/core + "${MAKE}" -f nbproject/Makefile-${CND_CONF}.mk ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/src -${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/core: ${OBJECTFILES} +${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/src: ${OBJECTFILES} ${MKDIR} -p ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM} - ${LINK.cc} -o ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/core ${OBJECTFILES} ${LDLIBSOPTIONS} + ${LINK.cc} -o ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/src ${OBJECTFILES} ${LDLIBSOPTIONS} ${OBJECTDIR}/_ext/1e501df/gtest-all.o: ../contrib/googletest/googletest/src/gtest-all.cc ${MKDIR} -p ${OBJECTDIR}/_ext/1e501df diff --git a/core/nbproject/Makefile-UnitTest-Win32.mk b/src/nbproject/Makefile-UnitTest-Win32.mk similarity index 100% rename from core/nbproject/Makefile-UnitTest-Win32.mk rename to src/nbproject/Makefile-UnitTest-Win32.mk diff --git a/core/nbproject/Makefile-UnitTest-Win64.mk b/src/nbproject/Makefile-UnitTest-Win64.mk similarity index 100% rename from core/nbproject/Makefile-UnitTest-Win64.mk rename to src/nbproject/Makefile-UnitTest-Win64.mk diff --git a/core/nbproject/Makefile-UnitTest.mk b/src/nbproject/Makefile-UnitTest.mk similarity index 52% rename from core/nbproject/Makefile-UnitTest.mk rename to src/nbproject/Makefile-UnitTest.mk index c87502db..929bebe2 100644 --- a/core/nbproject/Makefile-UnitTest.mk +++ b/src/nbproject/Makefile-UnitTest.mk @@ -79,32 +79,33 @@ LDLIBSOPTIONS=-L../contrib/libtorch/lib -Wl,-rpath,'../contrib/libtorch/lib' -lp # Build Targets .build-conf: ${BUILD_SUBPROJECTS} - "${MAKE}" -f nbproject/Makefile-${CND_CONF}.mk newlang_test + "${MAKE}" -f nbproject/Makefile-${CND_CONF}.mk ../output/nlc_unit_test -newlang_test: ../contrib/libffi/output/lib/libffi.a +../output/nlc_unit_test: ../contrib/libffi/output/lib/libffi.a -newlang_test: ${OBJECTFILES} - ${LINK.cc} -o newlang_test ${OBJECTFILES} ${LDLIBSOPTIONS} -Wl,--export-dynamic +../output/nlc_unit_test: ${OBJECTFILES} + ${MKDIR} -p ../output + ${LINK.cc} -o ../output/nlc_unit_test ${OBJECTFILES} ${LDLIBSOPTIONS} -Wl,--export-dynamic ${OBJECTDIR}/_ext/1e501df/gtest-all.o: ../contrib/googletest/googletest/src/gtest-all.cc ${MKDIR} -p ${OBJECTDIR}/_ext/1e501df ${RM} "$@.d" - $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -I/usr/lib/llvm-13/include -std=c++14 -Wno-error -Wno-all -Wno-extra -Wno-ctor-dtor-privacy -Wno-undef -Wno-sign-compare -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/_ext/1e501df/gtest-all.o ../contrib/googletest/googletest/src/gtest-all.cc + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I. -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -I/usr/lib/llvm-13/include -std=c++14 -Wno-error -Wno-all -Wno-extra -Wno-ctor-dtor-privacy -Wno-undef -Wno-sign-compare -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/_ext/1e501df/gtest-all.o ../contrib/googletest/googletest/src/gtest-all.cc ${OBJECTDIR}/_ext/1e501df/gtest_main.o: ../contrib/googletest/googletest/src/gtest_main.cc ${MKDIR} -p ${OBJECTDIR}/_ext/1e501df ${RM} "$@.d" - $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -I/usr/lib/llvm-13/include -std=c++14 -Wno-error -Wno-all -Wno-extra -Wno-ctor-dtor-privacy -Wno-undef -Wno-sign-compare -Wno-conversion -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/_ext/1e501df/gtest_main.o ../contrib/googletest/googletest/src/gtest_main.cc + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I. -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -I/usr/lib/llvm-13/include -std=c++14 -Wno-error -Wno-all -Wno-extra -Wno-ctor-dtor-privacy -Wno-undef -Wno-sign-compare -Wno-conversion -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/_ext/1e501df/gtest_main.o ../contrib/googletest/googletest/src/gtest_main.cc ${OBJECTDIR}/_ext/e16507f5/logger.o: ../contrib/logger/logger.cpp ${MKDIR} -p ${OBJECTDIR}/_ext/e16507f5 ${RM} "$@.d" - $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -I/usr/lib/llvm-13/include -std=c++14 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/_ext/e16507f5/logger.o ../contrib/logger/logger.cpp + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I. -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -I/usr/lib/llvm-13/include -std=c++14 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/_ext/e16507f5/logger.o ../contrib/logger/logger.cpp ${OBJECTDIR}/builtin.o: builtin.cpp parser.h parser.yy.h pch.h.gch location.hh ${MKDIR} -p ${OBJECTDIR} ${RM} "$@.d" - $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -I/usr/lib/llvm-13/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/builtin.o builtin.cpp + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I. -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -I/usr/lib/llvm-13/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/builtin.o builtin.cpp : builtin.h pch.h.gch @echo Выполнение шага пользовательского сборки @@ -113,7 +114,7 @@ ${OBJECTDIR}/builtin.o: builtin.cpp parser.h parser.yy.h pch.h.gch location.hh ${OBJECTDIR}/context.o: context.cpp parser.h parser.yy.h pch.h.gch location.hh ${MKDIR} -p ${OBJECTDIR} ${RM} "$@.d" - $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -I/usr/lib/llvm-13/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/context.o context.cpp + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I. -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -I/usr/lib/llvm-13/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/context.o context.cpp : context.h pch.h.gch @echo Выполнение шага пользовательского сборки @@ -122,7 +123,7 @@ ${OBJECTDIR}/context.o: context.cpp parser.h parser.yy.h pch.h.gch location.hh ${OBJECTDIR}/lexer.o: lexer.cpp location.hh ${MKDIR} -p ${OBJECTDIR} ${RM} "$@.d" - $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -I/usr/lib/llvm-13/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/lexer.o lexer.cpp + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I. -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -I/usr/lib/llvm-13/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/lexer.o lexer.cpp : lexer.h parser.yy.h parser.yy.cpp location.hh pch.h.gch @echo Выполнение шага пользовательского сборки @@ -136,7 +137,7 @@ lexer.yy.cpp lexer.yy.h: lexer.l parser.y parser.yy.h parser.yy.cpp location.hh ${OBJECTDIR}/lexer.yy.o: lexer.yy.cpp parser.y parser.yy.h parser.yy.cpp location.hh ${MKDIR} -p ${OBJECTDIR} ${RM} "$@.d" - $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -I/usr/lib/llvm-13/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/lexer.yy.o lexer.yy.cpp + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I. -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -I/usr/lib/llvm-13/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/lexer.yy.o lexer.yy.cpp : lexer.yy.h pch.h.gch @echo Выполнение шага пользовательского сборки @@ -145,7 +146,7 @@ ${OBJECTDIR}/lexer.yy.o: lexer.yy.cpp parser.y parser.yy.h parser.yy.cpp locatio ${OBJECTDIR}/newlang.o: newlang.cpp parser.h parser.yy.h pch.h.gch location.hh ${MKDIR} -p ${OBJECTDIR} ${RM} "$@.d" - $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -I/usr/lib/llvm-13/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/newlang.o newlang.cpp + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I. -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -I/usr/lib/llvm-13/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/newlang.o newlang.cpp : newlang.h pch.h.gch @echo Выполнение шага пользовательского сборки @@ -154,12 +155,12 @@ ${OBJECTDIR}/newlang.o: newlang.cpp parser.h parser.yy.h pch.h.gch location.hh ${OBJECTDIR}/nlc.o: nlc.cpp parser.h parser.yy.h pch.h.gch location.hh ${MKDIR} -p ${OBJECTDIR} ${RM} "$@.d" - $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -I/usr/lib/llvm-13/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/nlc.o nlc.cpp + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I. -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -I/usr/lib/llvm-13/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/nlc.o nlc.cpp ${OBJECTDIR}/object.o: object.cpp parser.h parser.yy.h pch.h.gch location.hh ${MKDIR} -p ${OBJECTDIR} ${RM} "$@.d" - $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -I/usr/lib/llvm-13/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/object.o object.cpp + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I. -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -I/usr/lib/llvm-13/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/object.o object.cpp : object.h pch.h.gch @echo Выполнение шага пользовательского сборки @@ -168,7 +169,7 @@ ${OBJECTDIR}/object.o: object.cpp parser.h parser.yy.h pch.h.gch location.hh ${OBJECTDIR}/parser.o: parser.cpp parser.h parser.yy.h pch.h.gch location.hh ${MKDIR} -p ${OBJECTDIR} ${RM} "$@.d" - $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -I/usr/lib/llvm-13/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/parser.o parser.cpp + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I. -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -I/usr/lib/llvm-13/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/parser.o parser.cpp : parser.h pch.h.gch @echo Выполнение шага пользовательского сборки @@ -182,7 +183,7 @@ parser.yy.h parser.yy.cpp location.hh: parser.y ${OBJECTDIR}/parser.yy.o: parser.yy.cpp parser.y ${MKDIR} -p ${OBJECTDIR} ${RM} "$@.d" - $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -I/usr/lib/llvm-13/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/parser.yy.o parser.yy.cpp + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I. -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -I/usr/lib/llvm-13/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/parser.yy.o parser.yy.cpp : parser.yy.h parser.y pch.h.gch @echo Выполнение шага пользовательского сборки @@ -195,12 +196,12 @@ pch.h.gch: pch.h ${OBJECTDIR}/syntax_help.o: syntax_help.cpp ${MKDIR} -p ${OBJECTDIR} ${RM} "$@.d" - $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -I/usr/lib/llvm-13/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/syntax_help.o syntax_help.cpp + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I. -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -I/usr/lib/llvm-13/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/syntax_help.o syntax_help.cpp ${OBJECTDIR}/term.o: term.cpp parser.h parser.yy.h pch.h.gch location.hh ${MKDIR} -p ${OBJECTDIR} ${RM} "$@.d" - $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -I/usr/lib/llvm-13/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/term.o term.cpp + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I. -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -I/usr/lib/llvm-13/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/term.o term.cpp : term.h parser.yy.cpp location.hh pch.h.gch @echo Выполнение шага пользовательского сборки @@ -209,42 +210,42 @@ ${OBJECTDIR}/term.o: term.cpp parser.h parser.yy.h pch.h.gch location.hh ${OBJECTDIR}/test/alg_test.o: test/alg_test.cpp pch.h.gch ${MKDIR} -p ${OBJECTDIR}/test ${RM} "$@.d" - $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -I/usr/lib/llvm-13/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/alg_test.o test/alg_test.cpp + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I. -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -I/usr/lib/llvm-13/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/alg_test.o test/alg_test.cpp ${OBJECTDIR}/test/compiler_test.o: test/compiler_test.cpp pch.h.gch ${MKDIR} -p ${OBJECTDIR}/test ${RM} "$@.d" - $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -I/usr/lib/llvm-13/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/compiler_test.o test/compiler_test.cpp + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I. -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -I/usr/lib/llvm-13/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/compiler_test.o test/compiler_test.cpp ${OBJECTDIR}/test/eval_test.o: test/eval_test.cpp pch.h.gch ${MKDIR} -p ${OBJECTDIR}/test ${RM} "$@.d" - $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -I/usr/lib/llvm-13/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/eval_test.o test/eval_test.cpp + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I. -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -I/usr/lib/llvm-13/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/eval_test.o test/eval_test.cpp ${OBJECTDIR}/test/fraction_test.o: test/fraction_test.cpp ${MKDIR} -p ${OBJECTDIR}/test ${RM} "$@.d" - $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -I/usr/lib/llvm-13/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/fraction_test.o test/fraction_test.cpp + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I. -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -I/usr/lib/llvm-13/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/fraction_test.o test/fraction_test.cpp ${OBJECTDIR}/test/lexer_test.o: test/lexer_test.cpp pch.h.gch ${MKDIR} -p ${OBJECTDIR}/test ${RM} "$@.d" - $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -I/usr/lib/llvm-13/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/lexer_test.o test/lexer_test.cpp + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I. -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -I/usr/lib/llvm-13/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/lexer_test.o test/lexer_test.cpp ${OBJECTDIR}/test/nlc_test.o: test/nlc_test.cpp pch.h.gch ${MKDIR} -p ${OBJECTDIR}/test ${RM} "$@.d" - $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -I/usr/lib/llvm-13/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/nlc_test.o test/nlc_test.cpp + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I. -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -I/usr/lib/llvm-13/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/nlc_test.o test/nlc_test.cpp ${OBJECTDIR}/test/object_test.o: test/object_test.cpp pch.h.gch ${MKDIR} -p ${OBJECTDIR}/test ${RM} "$@.d" - $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -I/usr/lib/llvm-13/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/object_test.o test/object_test.cpp + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I. -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -I/usr/lib/llvm-13/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/object_test.o test/object_test.cpp ${OBJECTDIR}/test/parser_test.o: test/parser_test.cpp pch.h.gch ${MKDIR} -p ${OBJECTDIR}/test ${RM} "$@.d" - $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -I/usr/lib/llvm-13/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/parser_test.o test/parser_test.cpp + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I. -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -I/usr/lib/llvm-13/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/parser_test.o test/parser_test.cpp : types.h pch.h.gch @echo Выполнение шага пользовательского сборки @@ -253,7 +254,7 @@ ${OBJECTDIR}/test/parser_test.o: test/parser_test.cpp pch.h.gch ${OBJECTDIR}/variable.o: variable.cpp pch.h.gch ${MKDIR} -p ${OBJECTDIR} ${RM} "$@.d" - $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -I/usr/lib/llvm-13/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/variable.o variable.cpp + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I. -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -I/usr/lib/llvm-13/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/variable.o variable.cpp : variable.h pch.h.gch @echo Выполнение шага пользовательского сборки diff --git a/core/nbproject/Makefile-UnitTest_LLVM.mk b/src/nbproject/Makefile-UnitTest_LLVM.mk similarity index 98% rename from core/nbproject/Makefile-UnitTest_LLVM.mk rename to src/nbproject/Makefile-UnitTest_LLVM.mk index c77d3036..26665fb4 100644 --- a/core/nbproject/Makefile-UnitTest_LLVM.mk +++ b/src/nbproject/Makefile-UnitTest_LLVM.mk @@ -79,13 +79,13 @@ LDLIBSOPTIONS=-lpthread -ldl ../contrib/PDCurses/x11/libXCurses.a -lXaw -lXmu -l # Build Targets .build-conf: ${BUILD_SUBPROJECTS} - "${MAKE}" -f nbproject/Makefile-${CND_CONF}.mk ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/core + "${MAKE}" -f nbproject/Makefile-${CND_CONF}.mk ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/src -${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/core: ../contrib/PDCurses/x11/libXCurses.a +${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/src: ../contrib/PDCurses/x11/libXCurses.a -${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/core: ${OBJECTFILES} +${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/src: ${OBJECTFILES} ${MKDIR} -p ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM} - ${LINK.cc} -o ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/core ${OBJECTFILES} ${LDLIBSOPTIONS} `llvm-config-12 --libs --ldflags` -stdlib=libstdc++ -fuse-ld=lld-12 -g + ${LINK.cc} -o ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/src ${OBJECTFILES} ${LDLIBSOPTIONS} `llvm-config-12 --libs --ldflags` -stdlib=libstdc++ -fuse-ld=lld-12 -g ${OBJECTDIR}/_ext/1e501df/gtest-all.o: ../contrib/googletest/googletest/src/gtest-all.cc ${MKDIR} -p ${OBJECTDIR}/_ext/1e501df diff --git a/core/nbproject/Makefile-impl.mk b/src/nbproject/Makefile-impl.mk similarity index 99% rename from core/nbproject/Makefile-impl.mk rename to src/nbproject/Makefile-impl.mk index 4a538ba8..f394bd32 100644 --- a/core/nbproject/Makefile-impl.mk +++ b/src/nbproject/Makefile-impl.mk @@ -24,7 +24,7 @@ CLEAN_SUBPROJECTS=${CLEAN_SUBPROJECTS_${SUBPROJECTS}} # Project Name -PROJECTNAME=core +PROJECTNAME=src # Active Configuration DEFAULTCONF=Debug diff --git a/core/nbproject/Makefile-variables.mk b/src/nbproject/Makefile-variables.mk similarity index 66% rename from core/nbproject/Makefile-variables.mk rename to src/nbproject/Makefile-variables.mk index 20be51dd..fa7ef8fa 100644 --- a/core/nbproject/Makefile-variables.mk +++ b/src/nbproject/Makefile-variables.mk @@ -12,72 +12,72 @@ CND_ARTIFACT_DIR_Debug= CND_ARTIFACT_NAME_Debug=nlc CND_ARTIFACT_PATH_Debug=nlc CND_PACKAGE_DIR_Debug=dist/Debug/GNU-Linux/package -CND_PACKAGE_NAME_Debug=core.tar -CND_PACKAGE_PATH_Debug=dist/Debug/GNU-Linux/package/core.tar +CND_PACKAGE_NAME_Debug=src.tar +CND_PACKAGE_PATH_Debug=dist/Debug/GNU-Linux/package/src.tar # Release configuration CND_PLATFORM_Release=GNU-Linux CND_ARTIFACT_DIR_Release=dist/Release/GNU-Linux -CND_ARTIFACT_NAME_Release=core -CND_ARTIFACT_PATH_Release=dist/Release/GNU-Linux/core +CND_ARTIFACT_NAME_Release=src +CND_ARTIFACT_PATH_Release=dist/Release/GNU-Linux/src CND_PACKAGE_DIR_Release=dist/Release/GNU-Linux/package -CND_PACKAGE_NAME_Release=core.tar -CND_PACKAGE_PATH_Release=dist/Release/GNU-Linux/package/core.tar +CND_PACKAGE_NAME_Release=src.tar +CND_PACKAGE_PATH_Release=dist/Release/GNU-Linux/package/src.tar # UnitTest configuration CND_PLATFORM_UnitTest=GNU-Linux -CND_ARTIFACT_DIR_UnitTest= -CND_ARTIFACT_NAME_UnitTest=newlang_test -CND_ARTIFACT_PATH_UnitTest=newlang_test +CND_ARTIFACT_DIR_UnitTest=../output +CND_ARTIFACT_NAME_UnitTest=nlc_unit_test +CND_ARTIFACT_PATH_UnitTest=../output/nlc_unit_test CND_PACKAGE_DIR_UnitTest=dist/UnitTest/GNU-Linux/package -CND_PACKAGE_NAME_UnitTest=core.tar -CND_PACKAGE_PATH_UnitTest=dist/UnitTest/GNU-Linux/package/core.tar +CND_PACKAGE_NAME_UnitTest=src.tar +CND_PACKAGE_PATH_UnitTest=dist/UnitTest/GNU-Linux/package/src.tar # UnitTest_LLVM configuration CND_PLATFORM_UnitTest_LLVM=CLang-Linux CND_ARTIFACT_DIR_UnitTest_LLVM=dist/UnitTest_LLVM/CLang-Linux -CND_ARTIFACT_NAME_UnitTest_LLVM=core -CND_ARTIFACT_PATH_UnitTest_LLVM=dist/UnitTest_LLVM/CLang-Linux/core +CND_ARTIFACT_NAME_UnitTest_LLVM=src +CND_ARTIFACT_PATH_UnitTest_LLVM=dist/UnitTest_LLVM/CLang-Linux/src CND_PACKAGE_DIR_UnitTest_LLVM=dist/UnitTest_LLVM/CLang-Linux/package -CND_PACKAGE_NAME_UnitTest_LLVM=core.tar -CND_PACKAGE_PATH_UnitTest_LLVM=dist/UnitTest_LLVM/CLang-Linux/package/core.tar +CND_PACKAGE_NAME_UnitTest_LLVM=src.tar +CND_PACKAGE_PATH_UnitTest_LLVM=dist/UnitTest_LLVM/CLang-Linux/package/src.tar # GCOV configuration CND_PLATFORM_GCOV=GNU-Linux CND_ARTIFACT_DIR_GCOV=dist CND_ARTIFACT_NAME_GCOV=gcov.run CND_ARTIFACT_PATH_GCOV=dist/gcov.run CND_PACKAGE_DIR_GCOV=dist/GCOV/GNU-Linux/package -CND_PACKAGE_NAME_GCOV=core.tar -CND_PACKAGE_PATH_GCOV=dist/GCOV/GNU-Linux/package/core.tar +CND_PACKAGE_NAME_GCOV=src.tar +CND_PACKAGE_PATH_GCOV=dist/GCOV/GNU-Linux/package/src.tar # LLVM configuration CND_PLATFORM_LLVM=CLang-Linux CND_ARTIFACT_DIR_LLVM=dist/LLVM/CLang-Linux -CND_ARTIFACT_NAME_LLVM=core -CND_ARTIFACT_PATH_LLVM=dist/LLVM/CLang-Linux/core +CND_ARTIFACT_NAME_LLVM=src +CND_ARTIFACT_PATH_LLVM=dist/LLVM/CLang-Linux/src CND_PACKAGE_DIR_LLVM=dist/LLVM/CLang-Linux/package -CND_PACKAGE_NAME_LLVM=core.tar -CND_PACKAGE_PATH_LLVM=dist/LLVM/CLang-Linux/package/core.tar +CND_PACKAGE_NAME_LLVM=src.tar +CND_PACKAGE_PATH_LLVM=dist/LLVM/CLang-Linux/package/src.tar # LLVM_GCC configuration CND_PLATFORM_LLVM_GCC=GNU-Linux CND_ARTIFACT_DIR_LLVM_GCC=dist/LLVM_GCC/GNU-Linux -CND_ARTIFACT_NAME_LLVM_GCC=core -CND_ARTIFACT_PATH_LLVM_GCC=dist/LLVM_GCC/GNU-Linux/core +CND_ARTIFACT_NAME_LLVM_GCC=src +CND_ARTIFACT_PATH_LLVM_GCC=dist/LLVM_GCC/GNU-Linux/src CND_PACKAGE_DIR_LLVM_GCC=dist/LLVM_GCC/GNU-Linux/package -CND_PACKAGE_NAME_LLVM_GCC=core.tar -CND_PACKAGE_PATH_LLVM_GCC=dist/LLVM_GCC/GNU-Linux/package/core.tar +CND_PACKAGE_NAME_LLVM_GCC=src.tar +CND_PACKAGE_PATH_LLVM_GCC=dist/LLVM_GCC/GNU-Linux/package/src.tar # UnitTest-Win64 configuration CND_PLATFORM_UnitTest-Win64=Win64-x86_64-Linux CND_ARTIFACT_DIR_UnitTest-Win64= CND_ARTIFACT_NAME_UnitTest-Win64=newlang_test CND_ARTIFACT_PATH_UnitTest-Win64=newlang_test CND_PACKAGE_DIR_UnitTest-Win64=dist/UnitTest-Win64/Win64-x86_64-Linux/package -CND_PACKAGE_NAME_UnitTest-Win64=core.tar -CND_PACKAGE_PATH_UnitTest-Win64=dist/UnitTest-Win64/Win64-x86_64-Linux/package/core.tar +CND_PACKAGE_NAME_UnitTest-Win64=src.tar +CND_PACKAGE_PATH_UnitTest-Win64=dist/UnitTest-Win64/Win64-x86_64-Linux/package/src.tar # UnitTest-Win32 configuration CND_PLATFORM_UnitTest-Win32=Win32-i686-Linux CND_ARTIFACT_DIR_UnitTest-Win32= CND_ARTIFACT_NAME_UnitTest-Win32=newlang_test CND_ARTIFACT_PATH_UnitTest-Win32=newlang_test CND_PACKAGE_DIR_UnitTest-Win32=dist/UnitTest-Win32/Win32-i686-Linux/package -CND_PACKAGE_NAME_UnitTest-Win32=core.tar -CND_PACKAGE_PATH_UnitTest-Win32=dist/UnitTest-Win32/Win32-i686-Linux/package/core.tar +CND_PACKAGE_NAME_UnitTest-Win32=src.tar +CND_PACKAGE_PATH_UnitTest-Win32=dist/UnitTest-Win32/Win32-i686-Linux/package/src.tar # # include compiler specific variables # diff --git a/core/nbproject/Package-Debug.bash b/src/nbproject/Package-Debug.bash similarity index 89% rename from core/nbproject/Package-Debug.bash rename to src/nbproject/Package-Debug.bash index 25f5c978..099748da 100644 --- a/core/nbproject/Package-Debug.bash +++ b/src/nbproject/Package-Debug.bash @@ -15,7 +15,7 @@ NBTMPDIR=${CND_BUILDDIR}/${CND_CONF}/${CND_PLATFORM}/tmp-packaging TMPDIRNAME=tmp-packaging OUTPUT_PATH=nlc OUTPUT_BASENAME=nlc -PACKAGE_TOP_DIR=core/ +PACKAGE_TOP_DIR=src/ # Functions function checkReturnCode @@ -60,15 +60,15 @@ mkdir -p ${NBTMPDIR} # Copy files and create directories and links cd "${TOP}" -makeDirectory "${NBTMPDIR}/core/bin" +makeDirectory "${NBTMPDIR}/src/bin" copyFileToTmpDir "${OUTPUT_PATH}" "${NBTMPDIR}/${PACKAGE_TOP_DIR}bin/${OUTPUT_BASENAME}" 0755 # Generate tar file cd "${TOP}" -rm -f ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/core.tar +rm -f ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/src.tar cd ${NBTMPDIR} -tar -vcf ../../../../${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/core.tar * +tar -vcf ../../../../${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/src.tar * checkReturnCode # Cleanup diff --git a/core/nbproject/Package-GCOV.bash b/src/nbproject/Package-GCOV.bash similarity index 89% rename from core/nbproject/Package-GCOV.bash rename to src/nbproject/Package-GCOV.bash index db8f1339..cb214c15 100644 --- a/core/nbproject/Package-GCOV.bash +++ b/src/nbproject/Package-GCOV.bash @@ -15,7 +15,7 @@ NBTMPDIR=${CND_BUILDDIR}/${CND_CONF}/${CND_PLATFORM}/tmp-packaging TMPDIRNAME=tmp-packaging OUTPUT_PATH=dist/gcov.run OUTPUT_BASENAME=gcov.run -PACKAGE_TOP_DIR=core/ +PACKAGE_TOP_DIR=src/ # Functions function checkReturnCode @@ -60,15 +60,15 @@ mkdir -p ${NBTMPDIR} # Copy files and create directories and links cd "${TOP}" -makeDirectory "${NBTMPDIR}/core/bin" +makeDirectory "${NBTMPDIR}/src/bin" copyFileToTmpDir "${OUTPUT_PATH}" "${NBTMPDIR}/${PACKAGE_TOP_DIR}bin/${OUTPUT_BASENAME}" 0755 # Generate tar file cd "${TOP}" -rm -f ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/core.tar +rm -f ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/src.tar cd ${NBTMPDIR} -tar -vcf ../../../../${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/core.tar * +tar -vcf ../../../../${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/src.tar * checkReturnCode # Cleanup diff --git a/core/nbproject/Package-LLVM.bash b/src/nbproject/Package-LLVM.bash similarity index 84% rename from core/nbproject/Package-LLVM.bash rename to src/nbproject/Package-LLVM.bash index 68968c2b..762237a5 100644 --- a/core/nbproject/Package-LLVM.bash +++ b/src/nbproject/Package-LLVM.bash @@ -13,9 +13,9 @@ CND_BUILDDIR=build CND_DLIB_EXT=so NBTMPDIR=${CND_BUILDDIR}/${CND_CONF}/${CND_PLATFORM}/tmp-packaging TMPDIRNAME=tmp-packaging -OUTPUT_PATH=${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/core -OUTPUT_BASENAME=core -PACKAGE_TOP_DIR=core/ +OUTPUT_PATH=${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/src +OUTPUT_BASENAME=src +PACKAGE_TOP_DIR=src/ # Functions function checkReturnCode @@ -60,15 +60,15 @@ mkdir -p ${NBTMPDIR} # Copy files and create directories and links cd "${TOP}" -makeDirectory "${NBTMPDIR}/core/bin" +makeDirectory "${NBTMPDIR}/src/bin" copyFileToTmpDir "${OUTPUT_PATH}" "${NBTMPDIR}/${PACKAGE_TOP_DIR}bin/${OUTPUT_BASENAME}" 0755 # Generate tar file cd "${TOP}" -rm -f ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/core.tar +rm -f ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/src.tar cd ${NBTMPDIR} -tar -vcf ../../../../${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/core.tar * +tar -vcf ../../../../${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/src.tar * checkReturnCode # Cleanup diff --git a/core/nbproject/Package-LLVM_GCC.bash b/src/nbproject/Package-LLVM_GCC.bash similarity index 84% rename from core/nbproject/Package-LLVM_GCC.bash rename to src/nbproject/Package-LLVM_GCC.bash index 2fd46cec..8a618787 100644 --- a/core/nbproject/Package-LLVM_GCC.bash +++ b/src/nbproject/Package-LLVM_GCC.bash @@ -13,9 +13,9 @@ CND_BUILDDIR=build CND_DLIB_EXT=so NBTMPDIR=${CND_BUILDDIR}/${CND_CONF}/${CND_PLATFORM}/tmp-packaging TMPDIRNAME=tmp-packaging -OUTPUT_PATH=${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/core -OUTPUT_BASENAME=core -PACKAGE_TOP_DIR=core/ +OUTPUT_PATH=${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/src +OUTPUT_BASENAME=src +PACKAGE_TOP_DIR=src/ # Functions function checkReturnCode @@ -60,15 +60,15 @@ mkdir -p ${NBTMPDIR} # Copy files and create directories and links cd "${TOP}" -makeDirectory "${NBTMPDIR}/core/bin" +makeDirectory "${NBTMPDIR}/src/bin" copyFileToTmpDir "${OUTPUT_PATH}" "${NBTMPDIR}/${PACKAGE_TOP_DIR}bin/${OUTPUT_BASENAME}" 0755 # Generate tar file cd "${TOP}" -rm -f ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/core.tar +rm -f ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/src.tar cd ${NBTMPDIR} -tar -vcf ../../../../${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/core.tar * +tar -vcf ../../../../${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/src.tar * checkReturnCode # Cleanup diff --git a/core/nbproject/Package-Release.bash b/src/nbproject/Package-Release.bash similarity index 84% rename from core/nbproject/Package-Release.bash rename to src/nbproject/Package-Release.bash index 4e7b7a57..afe93308 100644 --- a/core/nbproject/Package-Release.bash +++ b/src/nbproject/Package-Release.bash @@ -13,9 +13,9 @@ CND_BUILDDIR=build CND_DLIB_EXT=so NBTMPDIR=${CND_BUILDDIR}/${CND_CONF}/${CND_PLATFORM}/tmp-packaging TMPDIRNAME=tmp-packaging -OUTPUT_PATH=${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/core -OUTPUT_BASENAME=core -PACKAGE_TOP_DIR=core/ +OUTPUT_PATH=${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/src +OUTPUT_BASENAME=src +PACKAGE_TOP_DIR=src/ # Functions function checkReturnCode @@ -60,15 +60,15 @@ mkdir -p ${NBTMPDIR} # Copy files and create directories and links cd "${TOP}" -makeDirectory "${NBTMPDIR}/core/bin" +makeDirectory "${NBTMPDIR}/src/bin" copyFileToTmpDir "${OUTPUT_PATH}" "${NBTMPDIR}/${PACKAGE_TOP_DIR}bin/${OUTPUT_BASENAME}" 0755 # Generate tar file cd "${TOP}" -rm -f ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/core.tar +rm -f ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/src.tar cd ${NBTMPDIR} -tar -vcf ../../../../${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/core.tar * +tar -vcf ../../../../${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/src.tar * checkReturnCode # Cleanup diff --git a/core/nbproject/Package-UnitTest-Win32.bash b/src/nbproject/Package-UnitTest-Win32.bash similarity index 89% rename from core/nbproject/Package-UnitTest-Win32.bash rename to src/nbproject/Package-UnitTest-Win32.bash index 2688e4d0..4dc908e8 100644 --- a/core/nbproject/Package-UnitTest-Win32.bash +++ b/src/nbproject/Package-UnitTest-Win32.bash @@ -15,7 +15,7 @@ NBTMPDIR=${CND_BUILDDIR}/${CND_CONF}/${CND_PLATFORM}/tmp-packaging TMPDIRNAME=tmp-packaging OUTPUT_PATH=newlang_test OUTPUT_BASENAME=newlang_test -PACKAGE_TOP_DIR=core/ +PACKAGE_TOP_DIR=src/ # Functions function checkReturnCode @@ -60,15 +60,15 @@ mkdir -p ${NBTMPDIR} # Copy files and create directories and links cd "${TOP}" -makeDirectory "${NBTMPDIR}/core/bin" +makeDirectory "${NBTMPDIR}/src/bin" copyFileToTmpDir "${OUTPUT_PATH}" "${NBTMPDIR}/${PACKAGE_TOP_DIR}bin/${OUTPUT_BASENAME}" 0755 # Generate tar file cd "${TOP}" -rm -f ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/core.tar +rm -f ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/src.tar cd ${NBTMPDIR} -tar -vcf ../../../../${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/core.tar * +tar -vcf ../../../../${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/src.tar * checkReturnCode # Cleanup diff --git a/core/nbproject/Package-UnitTest-Win64.bash b/src/nbproject/Package-UnitTest-Win64.bash similarity index 89% rename from core/nbproject/Package-UnitTest-Win64.bash rename to src/nbproject/Package-UnitTest-Win64.bash index 318ca153..67c969d8 100644 --- a/core/nbproject/Package-UnitTest-Win64.bash +++ b/src/nbproject/Package-UnitTest-Win64.bash @@ -15,7 +15,7 @@ NBTMPDIR=${CND_BUILDDIR}/${CND_CONF}/${CND_PLATFORM}/tmp-packaging TMPDIRNAME=tmp-packaging OUTPUT_PATH=newlang_test OUTPUT_BASENAME=newlang_test -PACKAGE_TOP_DIR=core/ +PACKAGE_TOP_DIR=src/ # Functions function checkReturnCode @@ -60,15 +60,15 @@ mkdir -p ${NBTMPDIR} # Copy files and create directories and links cd "${TOP}" -makeDirectory "${NBTMPDIR}/core/bin" +makeDirectory "${NBTMPDIR}/src/bin" copyFileToTmpDir "${OUTPUT_PATH}" "${NBTMPDIR}/${PACKAGE_TOP_DIR}bin/${OUTPUT_BASENAME}" 0755 # Generate tar file cd "${TOP}" -rm -f ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/core.tar +rm -f ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/src.tar cd ${NBTMPDIR} -tar -vcf ../../../../${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/core.tar * +tar -vcf ../../../../${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/src.tar * checkReturnCode # Cleanup diff --git a/core/nbproject/Package-UnitTest.bash b/src/nbproject/Package-UnitTest.bash similarity index 85% rename from core/nbproject/Package-UnitTest.bash rename to src/nbproject/Package-UnitTest.bash index 36e3fa9f..f8d93c6b 100644 --- a/core/nbproject/Package-UnitTest.bash +++ b/src/nbproject/Package-UnitTest.bash @@ -13,9 +13,9 @@ CND_BUILDDIR=build CND_DLIB_EXT=so NBTMPDIR=${CND_BUILDDIR}/${CND_CONF}/${CND_PLATFORM}/tmp-packaging TMPDIRNAME=tmp-packaging -OUTPUT_PATH=newlang_test -OUTPUT_BASENAME=newlang_test -PACKAGE_TOP_DIR=core/ +OUTPUT_PATH=../output/nlc_unit_test +OUTPUT_BASENAME=nlc_unit_test +PACKAGE_TOP_DIR=src/ # Functions function checkReturnCode @@ -60,15 +60,15 @@ mkdir -p ${NBTMPDIR} # Copy files and create directories and links cd "${TOP}" -makeDirectory "${NBTMPDIR}/core/bin" +makeDirectory "${NBTMPDIR}/src/bin" copyFileToTmpDir "${OUTPUT_PATH}" "${NBTMPDIR}/${PACKAGE_TOP_DIR}bin/${OUTPUT_BASENAME}" 0755 # Generate tar file cd "${TOP}" -rm -f ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/core.tar +rm -f ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/src.tar cd ${NBTMPDIR} -tar -vcf ../../../../${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/core.tar * +tar -vcf ../../../../${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/src.tar * checkReturnCode # Cleanup diff --git a/core/nbproject/Package-UnitTest_LLVM.bash b/src/nbproject/Package-UnitTest_LLVM.bash similarity index 84% rename from core/nbproject/Package-UnitTest_LLVM.bash rename to src/nbproject/Package-UnitTest_LLVM.bash index 9f4d6e8a..ed605924 100644 --- a/core/nbproject/Package-UnitTest_LLVM.bash +++ b/src/nbproject/Package-UnitTest_LLVM.bash @@ -13,9 +13,9 @@ CND_BUILDDIR=build CND_DLIB_EXT=so NBTMPDIR=${CND_BUILDDIR}/${CND_CONF}/${CND_PLATFORM}/tmp-packaging TMPDIRNAME=tmp-packaging -OUTPUT_PATH=${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/core -OUTPUT_BASENAME=core -PACKAGE_TOP_DIR=core/ +OUTPUT_PATH=${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/src +OUTPUT_BASENAME=src +PACKAGE_TOP_DIR=src/ # Functions function checkReturnCode @@ -60,15 +60,15 @@ mkdir -p ${NBTMPDIR} # Copy files and create directories and links cd "${TOP}" -makeDirectory "${NBTMPDIR}/core/bin" +makeDirectory "${NBTMPDIR}/src/bin" copyFileToTmpDir "${OUTPUT_PATH}" "${NBTMPDIR}/${PACKAGE_TOP_DIR}bin/${OUTPUT_BASENAME}" 0755 # Generate tar file cd "${TOP}" -rm -f ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/core.tar +rm -f ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/src.tar cd ${NBTMPDIR} -tar -vcf ../../../../${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/core.tar * +tar -vcf ../../../../${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/src.tar * checkReturnCode # Cleanup diff --git a/core/nbproject/configurations.xml b/src/nbproject/configurations.xml similarity index 99% rename from core/nbproject/configurations.xml rename to src/nbproject/configurations.xml index add5a9b5..0149e624 100644 --- a/core/nbproject/configurations.xml +++ b/src/nbproject/configurations.xml @@ -10,8 +10,8 @@ - - nlp/fileio.nlp + + ../examples/fileio.nlp test/alg_test.cpp @@ -87,7 +87,7 @@ parser.y - /home/rsashka/SOURCE/PUBLIC/NewLang/newlang/core/test + /home/rsashka/SOURCE/PUBLIC/NewLang/newlang/test Makefile @@ -186,6 +186,8 @@ + + @@ -258,8 +260,6 @@ - - parser.h parser.yy.h pch.h.gch location.hh @@ -440,6 +440,8 @@ + + @@ -478,8 +480,6 @@ - - @@ -563,6 +563,7 @@ + . .. ../contrib/googletest/googletest ../contrib/googletest/googletest/include @@ -582,7 +583,7 @@ false - newlang_test + ../output/nlc_unit_test ../contrib/libtorch/lib @@ -634,6 +635,8 @@ + + @@ -706,8 +709,6 @@ - - parser.h parser.yy.h pch.h.gch location.hh @@ -946,6 +947,8 @@ + + @@ -996,8 +999,6 @@ - - @@ -1161,6 +1162,8 @@ + + @@ -1211,8 +1214,6 @@ - - @@ -1404,6 +1405,8 @@ + + @@ -1454,8 +1457,6 @@ - - @@ -1643,6 +1644,8 @@ + + @@ -1693,8 +1696,6 @@ - - @@ -1874,6 +1875,8 @@ + + @@ -1946,8 +1949,6 @@ - - parser.h parser.yy.h pch.h.gch location.hh @@ -2166,6 +2167,8 @@ + + @@ -2238,8 +2241,6 @@ - - parser.h parser.yy.h pch.h.gch location.hh diff --git a/src/nbproject/project.properties b/src/nbproject/project.properties new file mode 100644 index 00000000..59cb8932 --- /dev/null +++ b/src/nbproject/project.properties @@ -0,0 +1 @@ +#Wed Jun 29 14:41:54 MSK 2022 diff --git a/core/nbproject/project.xml b/src/nbproject/project.xml similarity index 98% rename from core/nbproject/project.xml rename to src/nbproject/project.xml index 0c2ab82e..bb662e83 100644 --- a/core/nbproject/project.xml +++ b/src/nbproject/project.xml @@ -10,7 +10,7 @@ UTF-8 - /home/rsashka/SOURCE/PUBLIC/NewLang/newlang/core/test + /home/rsashka/SOURCE/PUBLIC/NewLang/newlang/test diff --git a/core/newlang.cpp b/src/newlang.cpp similarity index 99% rename from core/newlang.cpp rename to src/newlang.cpp index e418f2bc..7960754f 100644 --- a/core/newlang.cpp +++ b/src/newlang.cpp @@ -1,8 +1,8 @@ #include "pch.h" -#include -#include -#include +#include +#include +#include using namespace newlang; diff --git a/core/newlang.h b/src/newlang.h similarity index 99% rename from core/newlang.h rename to src/newlang.h index 5b3d8ec0..c3ace487 100644 --- a/core/newlang.h +++ b/src/newlang.h @@ -6,10 +6,10 @@ #include "term.h" #include "builtin.h" -#include -#include -#include -#include +#include +#include +#include +#include //#include namespace newlang { diff --git a/core/nlc.cpp b/src/nlc.cpp similarity index 96% rename from core/nlc.cpp rename to src/nlc.cpp index 17838f01..ecd50995 100644 --- a/core/nlc.cpp +++ b/src/nlc.cpp @@ -1,6 +1,6 @@ #include "pch.h" -#include +#include using namespace std; using namespace newlang; diff --git a/core/nlc.h b/src/nlc.h similarity index 99% rename from core/nlc.h rename to src/nlc.h index 93249a64..d96b52c2 100644 --- a/core/nlc.h +++ b/src/nlc.h @@ -4,12 +4,12 @@ #include "pch.h" -#include +#include #include -#include +#include -#include -#include +#include +#include // * 30.04.2021 diff --git a/core/object.cpp b/src/object.cpp similarity index 99% rename from core/object.cpp rename to src/object.cpp index 044947d8..19eacc55 100644 --- a/core/object.cpp +++ b/src/object.cpp @@ -1,13 +1,13 @@ #include "contrib/logger/logger.h" -#include "core/types.h" -#include "core/variable.h" +#include "types.h" +#include "variable.h" #include "pch.h" -#include -#include -#include -#include +#include +#include +#include +#include using namespace newlang; @@ -289,7 +289,7 @@ ObjPtr Obj::index_set_(const std::vector &index, const ObjPtr value) { ObjPtr Obj::op_set_index(int64_t index, std::string value) { if(m_var_type_current == ObjType::StrChar) { - if(index < static_cast(m_str.size())) { + if(index < static_cast (m_str.size())) { m_str.erase(index, 1); m_str.insert(index, value); m_var_is_init = true; @@ -297,7 +297,7 @@ ObjPtr Obj::op_set_index(int64_t index, std::string value) { } LOG_RUNTIME("Index '%ld' not exists in byte string '%s'!", index, m_str.c_str()); } else if(m_var_type_current == ObjType::StrWide) { - if(index < static_cast(m_wstr.size())) { + if(index < static_cast (m_wstr.size())) { m_wstr.erase(index, 1); m_wstr.insert(index, utf8_decode(value)); m_var_is_init = true; @@ -850,7 +850,9 @@ std::string Obj::GetValueAsString() const { std::string temp; std::stringstream ss; - TEST_INIT_(); + if(!m_var_is_init) { + LOG_RUNTIME("Object not initialized '%s'!", toString().c_str()); + } switch(m_var_type_current) { case ObjType::None: @@ -1067,9 +1069,7 @@ ObjPtr Obj::Call(Context *ctx, Obj * args) { void Obj::ConvertToArgs_(Obj *in, bool check_valid, Context * ctx) { - if(!in) { - return; - } + ASSERT(in); bool named = false; bool is_ellipsis = false; @@ -1113,7 +1113,7 @@ void Obj::ConvertToArgs_(Obj *in, bool check_valid, Context * ctx) { (*in)[i]->toString().c_str(), (*m_func_proto)[i]->m_type_name.c_str()); } } - at(i).second->op_assign(in[i]); + at(i).second->op_assign((*in)[i]); } else { if(check_valid && !is_ellipsis && m_func_proto && i >= m_func_proto->size()) { LOG_RUNTIME("Positional args overflow. Ptrototype '%s'!", @@ -1133,7 +1133,7 @@ void Obj::ConvertToArgs_(Obj *in, bool check_valid, Context * ctx) { if(!*find) { *find = Obj::CreateNone(); } - (*find)->op_assign(in[i]); + (*find)->op_assign((*in)[i]); } else { for (int pos = 0; pos < size(); pos++) { if(!at(pos).first.empty() && at(pos).first.compare(in->at(i).first) == 0) { diff --git a/core/object.h b/src/object.h similarity index 99% rename from core/object.h rename to src/object.h index d40e3cb9..c8dae921 100644 --- a/core/object.h +++ b/src/object.h @@ -2,10 +2,10 @@ #ifndef INCLUDED_NEWLANG_OBJECT_ #define INCLUDED_NEWLANG_OBJECT_ -#include +#include -#include -#include +#include +#include namespace newlang { @@ -440,11 +440,11 @@ namespace newlang { typename std::enable_if::value, ObjPtr>::type inline operator()(Context *ctx, T ... args) { auto list = {args...}; - Obj arg; + ObjPtr arg = Obj::CreateDict(); for (auto &elem : list) { - arg.push_back(elem); + arg->push_back(elem); } - return Call(ctx, &arg); + return Call(ctx, arg.get()); } inline ObjPtr Call(Context *ctx) { diff --git a/core/parser.cpp b/src/parser.cpp similarity index 99% rename from core/parser.cpp rename to src/parser.cpp index 2eb0e772..5f7ba8b9 100644 --- a/core/parser.cpp +++ b/src/parser.cpp @@ -3,7 +3,7 @@ #include "parser.h" #include "lexer.h" -#include +#include using namespace newlang; diff --git a/core/parser.h b/src/parser.h similarity index 99% rename from core/parser.h rename to src/parser.h index efdde680..819d54c4 100644 --- a/core/parser.h +++ b/src/parser.h @@ -3,11 +3,11 @@ #include "pch.h" -#include +#include -#include +#include #include "parser.yy.h" -#include +#include namespace newlang { diff --git a/core/parser.y b/src/parser.y similarity index 99% rename from core/parser.y rename to src/parser.y index 4f40b466..461cfd49 100644 --- a/core/parser.y +++ b/src/parser.y @@ -3,8 +3,8 @@ #include "pch.h" -#include -#include +#include +#include #include "parser.h" #include "lexer.h" diff --git a/core/pch.cpp b/src/pch.cpp similarity index 100% rename from core/pch.cpp rename to src/pch.cpp diff --git a/core/pch.h b/src/pch.h similarity index 92% rename from core/pch.h rename to src/pch.h index 21dbdf9c..9a7c0275 100644 --- a/core/pch.h +++ b/src/pch.h @@ -56,14 +56,14 @@ #endif -#include +#include "warning_push.h" #include #include #include -#include +#include "warning_pop.h" -#include +#include "types.h" #undef LOG_RUNTIME #define LOG_RUNTIME(...) LOG_EXCEPT(newlang::Interrupt, ##__VA_ARGS__) diff --git a/core/term.cpp b/src/term.cpp similarity index 95% rename from core/term.cpp rename to src/term.cpp index 23796781..96992780 100644 --- a/core/term.cpp +++ b/src/term.cpp @@ -1,5 +1,5 @@ #include "pch.h" -#include +#include using namespace newlang; diff --git a/core/term.h b/src/term.h similarity index 99% rename from core/term.h rename to src/term.h index 2feea294..e7c9c342 100644 --- a/core/term.h +++ b/src/term.h @@ -2,14 +2,14 @@ #ifndef INCLUDED_NEWLANG_TERM_ #define INCLUDED_NEWLANG_TERM_ -#include +#include "pch.h" -#include +#include "warning_push.h" #include "location.hh" #include "parser.h" -#include +#include "warning_pop.h" -#include +#include "variable.h" namespace newlang { diff --git a/core/test/alg_test.cpp b/src/test/alg_test.cpp similarity index 99% rename from core/test/alg_test.cpp rename to src/test/alg_test.cpp index fd0ec66f..f6550232 100644 --- a/core/test/alg_test.cpp +++ b/src/test/alg_test.cpp @@ -2,16 +2,16 @@ #ifdef UNITTEST -#include "core/parser.h" +#include "parser.h" #include -#include -#include +#include +#include #include -#include -#include +#include +#include using namespace newlang; diff --git a/core/test/compiler_test.cpp b/src/test/compiler_test.cpp similarity index 99% rename from core/test/compiler_test.cpp rename to src/test/compiler_test.cpp index b2b730e0..3abc8041 100644 --- a/core/test/compiler_test.cpp +++ b/src/test/compiler_test.cpp @@ -2,14 +2,14 @@ #ifdef UNITTEST -#include "core/term.h" +#include "term.h" -#include +#include #include -#include +#include -#include -#include +#include +#include using namespace newlang; diff --git a/core/test/eval_test.cpp b/src/test/eval_test.cpp similarity index 99% rename from core/test/eval_test.cpp rename to src/test/eval_test.cpp index e162dc36..bc0a3420 100644 --- a/core/test/eval_test.cpp +++ b/src/test/eval_test.cpp @@ -1,16 +1,16 @@ #include "pch.h" #ifdef UNITTEST -#include "core/parser.h" +#include "parser.h" #include -#include -#include +#include +#include #include -#include -#include +#include +#include using namespace newlang; @@ -540,7 +540,7 @@ TEST(Eval, Fileio) { Context::Reset(); Context ctx(RunTime::Init()); - ASSERT_NO_THROW(ctx.ExecFile("nlp/fileio.nlp", nullptr, false)); + ASSERT_NO_THROW(ctx.ExecFile("../examples/fileio.nlp", nullptr, false)); ASSERT_TRUE(ctx.FindTerm("fopen")); ASSERT_TRUE(ctx.FindTerm("fputs")); diff --git a/core/test/fraction_test.cpp b/src/test/fraction_test.cpp similarity index 92% rename from core/test/fraction_test.cpp rename to src/test/fraction_test.cpp index 4ff8be01..daecac01 100644 --- a/core/test/fraction_test.cpp +++ b/src/test/fraction_test.cpp @@ -2,13 +2,13 @@ //#ifdef UNITTEST // -//#include "core/pch.h" +//#include "pch.h" // -//#include +//#include //#include -//#include +//#include // -//#include +//#include // // //TEST(ObjTest, BigNum) { diff --git a/core/test/lexer_test.cpp b/src/test/lexer_test.cpp similarity index 98% rename from core/test/lexer_test.cpp rename to src/test/lexer_test.cpp index 17cd8e54..c0df6092 100644 --- a/core/test/lexer_test.cpp +++ b/src/test/lexer_test.cpp @@ -2,14 +2,14 @@ #ifdef UNITTEST -#include +#include #include -#include +#include -#include -#include -#include -#include +#include +#include +#include +#include using namespace newlang; diff --git a/core/test/nlc_test.cpp b/src/test/nlc_test.cpp similarity index 99% rename from core/test/nlc_test.cpp rename to src/test/nlc_test.cpp index 8e7616fc..ceef4801 100644 --- a/core/test/nlc_test.cpp +++ b/src/test/nlc_test.cpp @@ -2,12 +2,12 @@ #ifdef UNITTEST -#include +#include #include -#include +#include -#include -#include "core/builtin.h" +#include +#include "builtin.h" using namespace newlang; diff --git a/core/test/object_test.cpp b/src/test/object_test.cpp similarity index 99% rename from core/test/object_test.cpp rename to src/test/object_test.cpp index e3164610..7753d38e 100644 --- a/core/test/object_test.cpp +++ b/src/test/object_test.cpp @@ -2,17 +2,17 @@ #ifdef UNITTEST -#include "core/fraction.h" +#include "fraction.h" -#include +#include #include -#include +#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include using namespace std; @@ -510,7 +510,7 @@ TEST(Args, All) { // ASSERT_FALSE(proto1.m_is_ellipsis); - ObjPtr arg_999(Obj::CreateValue(999, ObjType::None)); + ObjPtr arg_999 = Obj::CreateDict(Obj::Arg(Obj::CreateValue(999, ObjType::None))); EXPECT_EQ(ObjType::Short, (*arg_999)[0]->getType()) << torch::toString(toTorchType((*arg_999)[0]->getType())); ObjPtr arg_empty_named = Obj::CreateDict(Obj::Arg()); diff --git a/core/test/parser_test.cpp b/src/test/parser_test.cpp similarity index 99% rename from core/test/parser_test.cpp rename to src/test/parser_test.cpp index 5737f7a7..ae6f8398 100644 --- a/core/test/parser_test.cpp +++ b/src/test/parser_test.cpp @@ -2,14 +2,14 @@ #ifdef UNITTEST -#include +#include #include -#include +#include -#include -#include -#include "core/newlang.h" -#include "core/nlc.h" +#include +#include +#include "newlang.h" +#include "nlc.h" using namespace newlang; @@ -24,7 +24,7 @@ class ParserTest : public ::testing::Test { int Count(TermID token_id) { int result = 0; for (int c = 0; c < ast->size(); c++) { - if ((*ast)[c]->m_id == token_id) { + if((*ast)[c]->m_id == token_id) { result++; } } @@ -665,7 +665,7 @@ TEST_F(ParserTest, Iterator) { ASSERT_EQ(1, arg->size()); ASSERT_STREQ("arg", (*arg)[0]->getText().c_str()); -// #pragma GCC warning "ITERATOR" + // #pragma GCC warning "ITERATOR" // ASSERT_TRUE(Parse("term(arg=value)??(100)")); // ASSERT_STREQ("??", ast->getText().c_str()); // ASSERT_EQ(1, ast->getItemCount()); @@ -1825,7 +1825,7 @@ TEST_F(ParserTest, MacroArgs) { args = Parser::ParseMacroArgs(body); ASSERT_EQ(1, args.size()); ASSERT_STREQ("...", args[0].c_str()); - + ASSERT_ANY_THROW( body = "\\macro(,)"; args = Parser::ParseMacroArgs(body); @@ -2034,7 +2034,7 @@ TEST_F(ParserTest, MacroDSL) { "\\\\return(...) --\\$*--\\\\\\" ""; - while (Parser::ExtractMacros(dsl, macros)) + while(Parser::ExtractMacros(dsl, macros)) ; ASSERT_EQ(7, macros.size()); diff --git a/core/types.h b/src/types.h similarity index 99% rename from core/types.h rename to src/types.h index 53d4888d..73b7e1f1 100644 --- a/core/types.h +++ b/src/types.h @@ -1,7 +1,7 @@ #ifndef INCLUDED_NEWLANG_TYPES_H_ #define INCLUDED_NEWLANG_TYPES_H_ -#include +#include "pch.h" namespace newlang { diff --git a/core/variable.cpp b/src/variable.cpp similarity index 99% rename from core/variable.cpp rename to src/variable.cpp index ada341f7..45024241 100644 --- a/core/variable.cpp +++ b/src/variable.cpp @@ -1,6 +1,6 @@ #include "pch.h" -#include +#include using namespace newlang; diff --git a/core/variable.h b/src/variable.h similarity index 71% rename from core/variable.h rename to src/variable.h index 14a9fa75..a2a57495 100644 --- a/core/variable.h +++ b/src/variable.h @@ -3,7 +3,7 @@ #include "pch.h" -#include +#include namespace newlang { @@ -82,7 +82,7 @@ namespace newlang { typedef T Type; typedef std::pair PairType; // typedef std::pair PairTypeConst; - typedef std::deque DataType; + typedef std::list DataType; class iterator; typedef iterator const_iterator; @@ -117,12 +117,14 @@ namespace newlang { } inline Type & push_front(PairType pair) { - m_data.push_front(pair); + m_data.insert(m_data.begin(), pair); + // m_data.push_front(pair); return at(0).second; } inline void pop_front() { - m_data.pop_front(); + m_data.erase(m_data.begin()); + // m_data.pop_front(); } inline Type top() const { @@ -137,43 +139,85 @@ namespace newlang { } inline Type & insert(int64_t index, Type value, const std::string &name = "") { - if (index < 0 || index >= static_cast(m_data.size())) { + if (index < 0 || index >= static_cast (m_data.size())) { LOG_RUNTIME("Index '%ld' not exists!", index); } - return m_data.insert(m_data.begin() + index, std::pair(name, value))->second; + return m_data.insert(at_index(index), std::pair(name, value))->second; } virtual PairType & at(const int64_t index) { - if (index >= 0) { - if (index < static_cast(m_data.size())) { - return m_data.at(index); - } - } else { - if (-index < static_cast(m_data.size())) { - return m_data.at(m_data.size() + index); - } - } - LOG_RUNTIME("Index '%ld' not exists!", index); + return *at_index(index); + // if (index >= 0) { + // if (index < static_cast (m_data.size())) { + // int64_t pos = 0; + // typename DataType::iterator iter = m_data.begin(); + // while (iter != m_data.end()) { + // if (pos == index) { + // return *iter; + // } + // pos++; + // iter++; + // } + // LOG_RUNTIME("Index %ld not exists!", index); + // // return m_data.at(index); + // } + // } else { + // if (-index < static_cast (m_data.size())) { + // int64_t pos = index + 1; + // typename DataType::reverse_iterator iter = m_data.rbegin(); + // while (iter != m_data.rend()) { + // if (pos == 0) { + // return *iter; + // } + // pos--; + // iter++; + // } + // LOG_RUNTIME("Index %ld not exists!", index); + // // return m_data.at(m_data.size() + index); + // } + // } + // LOG_RUNTIME("Index '%ld' not exists!", index); } virtual const PairType & at(const int64_t index) const { - if (index >= 0) { - if (index < static_cast(m_data.size())) { - return m_data.at(index); - } - } else { - if (-index < static_cast(m_data.size())) { - return m_data.at(m_data.size() + index); - } - } - LOG_RUNTIME("Index '%ld' not exists!", index); - } - -// template -// typename std::enable_if>::value, Type &>::type -// inline at(N * name) { -// return at(std::string(name)); -// } + return *at_index_const(index); + // if (index >= 0) { + // if (index < static_cast (m_data.size())) { + // int64_t pos = 0; + // typename DataType::const_iterator iter = m_data.begin(); + // while (iter != m_data.end()) { + // if (pos == index) { + // return *iter; + // } + // pos++; + // iter++; + // } + // LOG_RUNTIME("Index %ld not exists!", index); + // // return m_data.at(index); + // } + // } else { + // if (-index < static_cast (m_data.size())) { + // int64_t pos = index + 1; + // typename DataType::const_reverse_iterator iter = m_data.rbegin(); + // while (iter != m_data.rend()) { + // if (pos == 0) { + // return *iter; + // } + // pos--; + // iter++; + // } + // LOG_RUNTIME("Index %ld not exists!", index); + // // return m_data.at(m_data.size() + index); + // } + // } + // LOG_RUNTIME("Index '%ld' not exists!", index); + } + + // template + // typename std::enable_if>::value, Type &>::type + // inline at(N * name) { + // return at(std::string(name)); + // } virtual PairType & at(const std::string_view name) { iterator found = select(name); @@ -205,11 +249,8 @@ namespace newlang { // LOG_EXCEPT(std::out_of_range, "Property '%s' not found!", name.c_str()); // } - virtual const std::string & name(const size_t index) const { - if (index < m_data.size()) { - return m_data.at(index).first; - } - LOG_RUNTIME("Index '%lu' not exists!", static_cast (index)); + virtual const std::string & name(const int64_t index) const { + return at_index_const(index)->first; } virtual bool empty() const { @@ -231,9 +272,20 @@ namespace newlang { } else { // Если размер отрицательный - добавить или удалить вначале size = -size; - if (static_cast(m_data.size()) > size) { - m_data.erase(m_data.begin(), m_data.begin() + (m_data.size() - size)); - } else if (static_cast(m_data.size()) < size) { + if (static_cast (m_data.size()) > size) { + + m_data.erase(m_data.begin(), at_index(m_data.size() - size)); + + // int64_t pos = 0; + // typename DataType::iterator iter = m_data.begin(); + // while (iter != m_data.end()) { + // if (pos == size) { + // return m_data.size(); + // } + // pos++; + // iter++; + // } + } else if (static_cast (m_data.size()) < size) { m_data.insert(m_data.begin(), (m_data.size() - size), std::pair(name, fill)); } else { m_data.clear(); @@ -322,10 +374,10 @@ namespace newlang { return m_found == m_data.end(); } - inline size_t reset() { + inline int64_t reset() { m_found = m_data.begin(); search_loop(); - return m_find_key ? -1 : m_data.size(); + return m_find_key ? -1 : static_cast (m_data.size()); } @@ -401,21 +453,78 @@ namespace newlang { return m_data.end(); } - virtual typename DataType::iterator erase(size_t index) { - if (index < m_data.size()) { - return m_data.erase(m_data.begin() + index); + typename DataType::iterator at_index(const int64_t index) { + if (index < 0) { + if (-index < static_cast (m_data.size())) { + int64_t pos = index + 1; + typename DataType::iterator iter = m_data.end(); + while (iter != m_data.begin()) { + iter--; + if (pos == 0) { + return iter; + } + pos++; + } + } + } else { + int64_t pos = 0; + typename DataType::iterator iter = m_data.begin(); + while (iter != m_data.end()) { + if (pos == index) { + return iter; + } + pos++; + iter++; + } + } + LOG_RUNTIME("Index '%ld' not exists!", index); + } + + typename DataType::const_iterator at_index_const(const int64_t index) const { + if (index < 0) { + if (-index < static_cast (m_data.size())) { + int64_t pos = index + 1; + typename DataType::const_iterator iter = m_data.end(); + while (iter != m_data.begin()) { + iter--; + if (pos == 0) { + return iter; + } + pos++; + } + } + } else { + int64_t pos = 0; + typename DataType::const_iterator iter = m_data.begin(); + while (iter != m_data.end()) { + if (pos == index) { + return iter; + } + pos++; + iter++; + } } - LOG_RUNTIME("Index '%lu' not exists!", static_cast (index)); + LOG_RUNTIME("Index '%ld' not exists!", index); + } + + virtual void erase(const int64_t index) { + m_data.erase(at_index(index)); + } + + typename DataType::iterator erase(typename DataType::iterator iter) { + return m_data.erase(iter); } typename DataType::iterator erase(iterator iter) { if (!iter.complete()) { + return m_data.erase(iter.m_found); } LOG_RUNTIME("Try erase end of iter!"); } virtual iterator select() { + return iterator(m_data); } @@ -424,6 +533,7 @@ namespace newlang { // } virtual iterator select(const std::string_view key) { + return iterator(m_data, key); } @@ -433,10 +543,12 @@ namespace newlang { inline iterator select(CompareFuncType *func, void * extra = nullptr) { Variable args; + return select(func, args, extra); } virtual iterator select(CompareFuncType *func, Variable args, void * extra = nullptr) { + return iterator(m_data, func, args, extra); } @@ -446,6 +558,7 @@ namespace newlang { */ inline static PairType Arg(Type obj, const std::string name = "") { + return std::pair(name, obj); } @@ -459,6 +572,7 @@ namespace newlang { } Variable(PairType arg) { + push_front(arg.second, arg.first); } diff --git a/core/warning_pop.h b/src/warning_pop.h similarity index 100% rename from core/warning_pop.h rename to src/warning_pop.h diff --git a/core/warning_push.h b/src/warning_push.h similarity index 100% rename from core/warning_push.h rename to src/warning_push.h diff --git a/nlc-win/nlc.sln b/src/win/nlc.sln similarity index 100% rename from nlc-win/nlc.sln rename to src/win/nlc.sln diff --git a/nlc-win/nlc.vcxproj b/src/win/nlc.vcxproj similarity index 73% rename from nlc-win/nlc.vcxproj rename to src/win/nlc.vcxproj index 8aa89cc4..5eaa3756 100644 --- a/nlc-win/nlc.vcxproj +++ b/src/win/nlc.vcxproj @@ -22,9 +22,9 @@ 16.0 Win32Proj {ead3dacb-5c02-4bc6-98eb-79f6ad3198bf} - NewLang + nlc 10.0 - nlc-win + nlc @@ -72,8 +72,10 @@ - $(VC_IncludePath);$(WindowsSDK_IncludePath);..;../..;../contrib/;../contrib/googletest/googletest;../contrib/googletest/googletest/include;../contrib/Lyra/include;../contrib/libtorch-win/include;../contrib/libtorch-win/include/torch/csrc/api/include;../contrib/tensorboard_logger/include;../contrib/libffi/win64/include - ..\contrib\libffi\win64\lib;..\contrib\libtorch-win\lib;$(LibraryPath) + $(VC_IncludePath);$(WindowsSDK_IncludePath);..;../..;../../..;../../contrib/;../../contrib/googletest/googletest;../../contrib/googletest/googletest/include;../../contrib/Lyra/include;../../contrib/libtorch-win/include;../../contrib/libtorch-win/include/torch/csrc/api/include;../../contrib/tensorboard_logger/include;../../contrib/libffi/win64/include + ..\..\contrib\libffi\win64\lib;..\..\contrib\libtorch-win\lib;$(LibraryPath) + ..\..\output\ + nlc_unit_test @@ -120,13 +122,12 @@ Console true - $(OutDir)nlc$(TargetExt) + %(AdditionalLibraryDirectories) - - true - + - copy /y ..\contrib\libtorch-win\lib\*.dll $(TargetDir) + + @@ -146,72 +147,72 @@ - + NotUsing - + NotUsing - + NotUsing - - - + + + NotUsing - + NotUsing 4244;4005;%(DisableSpecificWarnings) - - - - - + + + + + NotUsing - + Create - + NotUsing - - - - - - - - - - - + + + + + + + + + + + NotUsing - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + From cc4c53938977e8350be3fc13d230783363b60313 Mon Sep 17 00:00:00 2001 From: Aleksandr Ryabikov Date: Thu, 30 Jun 2022 12:51:29 +0300 Subject: [PATCH 10/31] =?UTF-8?q?=D0=9C=D0=BD=D0=BE=D0=B3=D0=BE=D1=81?= =?UTF-8?q?=D1=82=D1=80=D0=BE=D1=87=D0=BD=D1=8B=D0=B5=20=D0=BA=D0=BE=D0=BC?= =?UTF-8?q?=D0=BC=D0=B5=D0=BD=D0=B0=D1=82=D1=80=D0=B8=D0=B8,=20=D1=81?= =?UTF-8?q?=D0=B1=D0=BE=D1=80=D0=BA=D0=B0=20=D0=B8=20=D0=B7=D0=B0=D0=BF?= =?UTF-8?q?=D1=83=D1=81=D0=BA=20=D0=BF=D0=BE=D0=B4=20windows.=20=D0=9E?= =?UTF-8?q?=D1=81=D1=82=D0=B0=D0=BB=D0=BE=D1=81=D1=82=D1=8C=20=D1=82=D0=BE?= =?UTF-8?q?=D0=BB=D1=8C=D0=BA=D0=BE=20=D1=81=D0=B4=D0=B5=D0=BB=D0=B0=D1=82?= =?UTF-8?q?=D1=8C=20=D0=B7=D0=B0=D0=BF=D1=83=D1=81=D0=BA=20=D1=81=20=D0=BF?= =?UTF-8?q?=D0=BE=D0=BC=D0=BE=D1=89=D1=8C=D1=8E=20libffi?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- contrib/build.cmd | 2 +- src/context.cpp | 27 +- src/lexer.cpp | 5 +- src/lexer.l | 34 +-- src/newlang.h | 530 ++++++++++++++++++++------------------- src/object.cpp | 84 ++++--- src/object.h | 6 +- src/parser.cpp | 1 - src/parser.h | 4 + src/pch.h | 2 + src/test/eval_test.cpp | 18 +- src/test/object_test.cpp | 61 ++++- src/test/parser_test.cpp | 16 ++ src/win/.gitignore | 3 + src/win/nlc.sln | 6 + src/win/nlc.vcxproj | 78 ++++++ 16 files changed, 544 insertions(+), 333 deletions(-) create mode 100644 src/win/.gitignore diff --git a/contrib/build.cmd b/contrib/build.cmd index f9c00d4a..5f10072a 100644 --- a/contrib/build.cmd +++ b/contrib/build.cmd @@ -1,3 +1,3 @@ -C:\msys64\usr\bin\bash -lc "cd /z/NewLang/newlang/contrib/libffi && ./configure --build=x86_64-w64-mingw32 --host=x86_64-w64-mingw32 --prefix=`pwd`/win64 --enable-static --disable-docs && make && make install" +C:\msys64\usr\bin\bash -lc "cd /z/NewLang/newlang/contrib/libffi && ./configure --build=x86_64-w64-mingw32 --host=x86_64-w64-mingw32 --prefix=`pwd`/win64 --disable-docs && make && make install" diff --git a/src/context.cpp b/src/context.cpp index ca1023c0..8bb1bbae 100644 --- a/src/context.cpp +++ b/src/context.cpp @@ -811,7 +811,7 @@ ObjPtr Context::eval_FOLLOW(Context *ctx, const TermPtr &term, Obj * args) { * */ - for (int i = 0; i < term->m_follow.size(); i++) { + for (int64_t i = 0; i < term->m_follow.size(); i++) { ASSERT(term->m_follow[i]->Left()); ObjPtr cond = ExecStr(ctx, term->m_follow[i]->Left(), args, false); @@ -1488,7 +1488,7 @@ ObjPtr Context::CreateNative(TermPtr proto, const char *module, bool lazzy, cons if(lazzy) { result->m_func_ptr = nullptr; } else { - result->m_func_ptr = m_runtime->GetProcAddress( + result->m_func_ptr = m_runtime->GetNativeAddr( result->m_func_mangle_name.empty() ? proto->m_text.c_str() : result->m_func_mangle_name.c_str(), module); if(result->is_function() || type == ObjType::Pointer) { NL_CHECK(result->m_func_ptr, "Error getting address '%s' from '%s'!", proto->toString().c_str(), module); @@ -1504,7 +1504,18 @@ ObjPtr Context::CreateNative(TermPtr proto, const char *module, bool lazzy, cons return result; } -void *RunTime::GetProcAddress(const char *name, const char *module) { +std::string RunTime::GetLastErrorMessage() { +#ifndef _MSC_VER + return std::string(strerror(errno)); +#else + wchar_t buffer[256]; + FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), buffer, sizeof(buffer), NULL); + return utf8_encode(buffer); +#endif +} + +void *RunTime::GetNativeAddr(const char *name, const char *module) { if(module && module[0]) { if(m_modules.find(module) == m_modules.end()) { LoadModule(module, false, nullptr); @@ -1517,13 +1528,17 @@ void *RunTime::GetProcAddress(const char *name, const char *module) { #ifndef _MSC_VER return dlsym(m_modules[module]->GetHandle(), name); #else - return nullptr; + return static_cast(::GetProcAddress(m_modules[module]->GetHandle(), name)); #endif } #ifndef _MSC_VER return dlsym(nullptr, name); #else - return nullptr; + HMODULE msys = GetModuleHandle(L"msys-2.0.dll"); + if(!msys){ + LOG_DEBUG("GetModuleHandle: %s", RunTime::GetLastErrorMessage().c_str()); + } + return static_cast(::GetProcAddress(msys, name)); #endif } @@ -2067,7 +2082,7 @@ ObjPtr Context::CreateRVal(Context *ctx, TermPtr term, Obj * local_vars, bool in } args = Obj::CreateDict(); - for (int i = 0; i < term->size(); i++) { + for (int64_t i = 0; i < term->size(); i++) { if((*term)[i]->GetTokenID() == TermID::FILLING) { diff --git a/src/lexer.cpp b/src/lexer.cpp index 11c90a32..6bf5977a 100644 --- a/src/lexer.cpp +++ b/src/lexer.cpp @@ -5,15 +5,12 @@ namespace newlang { Scanner::Scanner(std::istream* in, std::ostream* out, std::shared_ptr source) : NewLangFlexLexer(in, out), source_string(source) { +// yy_flex_debug = true; } Scanner::~Scanner() { } - void Scanner::set_debug(bool b) { - yy_flex_debug = b; - } - } #ifdef yylex diff --git a/src/lexer.l b/src/lexer.l index 4949b23d..d535ef2b 100644 --- a/src/lexer.l +++ b/src/lexer.l @@ -106,30 +106,36 @@ term [$@%]({ualpha}|[_])?({name})? yylloc->step(); %} - -"/*" { - BEGIN(state_COMMENT); - //buffer.clear(); -} +"/*" { + yy_push_state(state_COMMENT); + buffer.clear(); + buffer.append(yytext, yyleng); + } { +"/*" { + yy_push_state(state_COMMENT); + buffer.append(yytext, yyleng); + } + \n { - //buffer.append(yytext, yyleng); + buffer.append(yytext, yyleng); yylloc->lines(yyleng); yylloc->step(); } -[^*^\n]* //buffer.append(yytext, yyleng); - - -"*"[^*/]* //buffer.append(yytext, yyleng); - "*/" { - BEGIN(INITIAL); -// *yylval = Term::Create(TermID::COMMENT, buffer.c_str(), buffer.size(), yylloc, source_string); -// return token::COMMENT; + yy_pop_state(); + buffer.append(yytext, yyleng); +// *yylval = Term::Create(TermID::COMMENT, buffer.c_str(), buffer.size(), yylloc, source_string); +// return token::COMMENT; } + +. { + buffer.append(yytext, yyleng); + } + } /* End of state_COMMENT state */ "#"[^\n]* { diff --git a/src/newlang.h b/src/newlang.h index c3ace487..a9b50011 100644 --- a/src/newlang.h +++ b/src/newlang.h @@ -18,366 +18,376 @@ namespace newlang { #define NEWLANG_PREFIX "newlang" #define NEWLANG_NS "newlang" -template -T repeat(T str, const std::size_t n) { - if(n == 0) { - str.clear(); - str.shrink_to_fit(); - return str; - } else if(n == 1 || str.empty()) { - return str; - } - const auto period = str.size(); - if(period == 1) { - str.append(n - 1, str.front()); + template + T repeat(T str, const std::size_t n) { + if (n == 0) { + str.clear(); + str.shrink_to_fit(); + return str; + } else if (n == 1 || str.empty()) { + return str; + } + const auto period = str.size(); + if (period == 1) { + str.append(n - 1, str.front()); + return str; + } + str.reserve(period * n); + std::size_t m{2}; + for (; m < n; m *= 2) str += str; + str.append(str.c_str(), (n - (m / 2)) * period); return str; } - str.reserve(period * n); - std::size_t m{2}; - for (; m < n; m *= 2) str += str; - str.append(str.c_str(), (n - (m / 2)) * period); - return str; -} -class Context; -struct CompileInfo; + class Context; + struct CompileInfo; -class Module { -public: + class Module { + public: - typedef std::map FuncMap; + typedef std::map FuncMap; + typedef +#ifdef _MSC_VER + HMODULE +#else + void * +#endif + HandleType; - Module(const char * name = nullptr) { - m_handle = nullptr; - if (!Load(name)) { - LOG_RUNTIME("Can`t load %s", name); + Module(const char * name = nullptr) { + m_handle = nullptr; + if (!Load(name)) { + LOG_RUNTIME("Can`t load %s", name); + } } - } - bool Load(const char *name) { - m_name = name; + bool Load(const char *name) { + m_name = name; #ifdef _MSC_VER - m_handle = nullptr; + std::wstring win_name = utf8_decode(name); + m_handle = LoadLibrary(win_name.c_str()); #else - m_handle = dlopen(name, RTLD_LAZY | RTLD_LOCAL); // Для GCC нужно собирать с --no-gnu-unique для замены модулей в рантайме + m_handle = dlopen(name, RTLD_LAZY | RTLD_LOCAL); // Для GCC нужно собирать с --no-gnu-unique для замены модулей в рантайме #endif - return m_handle; - } + return m_handle; + } - virtual ~Module() { - //Если динамическая библиотека экпортировала функцию, названную _fini, то эта функция вызывается перед выгрузкой библиотеки. - if (m_handle) { + virtual ~Module() { + //Если динамическая библиотека экпортировала функцию, названную _fini, то эта функция вызывается перед выгрузкой библиотеки. + if (m_handle) { #ifdef _MSC_VER - m_handle = nullptr; + FreeLibrary(m_handle); #else - dlclose(m_handle); + dlclose(m_handle); #endif + } + m_handle = nullptr; } - m_handle = nullptr; - } - ObjPtr Main(Context *ctx, Obj &args) { - if (m_main) { - return (*m_main)(ctx, args); + ObjPtr Main(Context *ctx, Obj &args) { + if (m_main) { + return (*m_main)(ctx, args); + } + LOG_DEBUG("Main function in module '%s' not found!", m_name.c_str()); + return Obj::CreateNone(); } - LOG_DEBUG("Main function in module '%s' not found!", m_name.c_str()); - return Obj::CreateNone(); - } - inline FuncMap& Funcs() { - return m_funcs; - } + inline FuncMap& Funcs() { + return m_funcs; + } - const char **m_source; - FunctionType *m_main; + const char **m_source; + FunctionType *m_main; - inline void * GetHandle() { - return m_handle; - } + inline HandleType GetHandle() { + return m_handle; + } - SCOPE(private) : - void * m_handle; - std::string m_name; - FuncMap m_funcs; -}; + SCOPE(private) : + HandleType m_handle; + std::string m_name; + FuncMap m_funcs; + }; -//typedef std::map ProtoType; + //typedef std::map ProtoType; -class RunTime { -public: + class RunTime { + public: - static RuntimePtr Init(int argc = 0, const char** argv = nullptr) { - return std::make_shared(); - } + static RuntimePtr Init(int argc = 0, const char** argv = nullptr) { + return std::make_shared(); + } -// void ReadBuiltInProto(ProtoType &proto); + // void ReadBuiltInProto(ProtoType &proto); - bool LoadModule(const char *name, bool init = true, Context *ctx = nullptr, const char *module_name = nullptr); - bool UnLoadModule(Context *ctx, const char *name = nullptr, bool deinit = true); - ObjPtr ExecModule(const char *module, const char *output, bool cached, Context * ctx); + bool LoadModule(const char *name, bool init = true, Context *ctx = nullptr, const char *module_name = nullptr); + bool UnLoadModule(Context *ctx, const char *name = nullptr, bool deinit = true); + ObjPtr ExecModule(const char *module, const char *output, bool cached, Context * ctx); - void * GetProcAddress(const char * name, const char *module = nullptr); + void * GetNativeAddr(const char * name, const char *module = nullptr); - virtual ~RunTime() { - } + virtual ~RunTime() { + } - RunTime() { - } - -protected: + RunTime() { + } - SCOPE(private) : - RunTime(const RunTime&) = delete; - const RunTime& operator=(const RunTime&) = delete; + static std::string GetLastErrorMessage(); - std::map m_modules; -}; + protected: -struct CompileInfo { - BuiltInTorchDirect * m_builtin_direct; + SCOPE(private) : + RunTime(const RunTime&) = delete; + const RunTime& operator=(const RunTime&) = delete; - CompileInfo(RuntimePtr rt) { - indent = 0; - if (rt) { -// rt->ReadBuiltInProto(builtin); - } - m_builtin_direct = new BuiltInTorchDirect(); - } + std::map m_modules; + }; - virtual ~CompileInfo() { - delete m_builtin_direct; - } + struct CompileInfo { + BuiltInTorchDirect * m_builtin_direct; - ProtoType arguments; //< Аргументы функции - ProtoType functions; //< Локальные функции - ProtoType variables; //< Локальные переменные - ProtoType consts; //< Локальные константы - ProtoType builtin; - std::set iterators; //< Текущие итреаторы + CompileInfo(RuntimePtr rt) { + indent = 0; + if (rt) { + // rt->ReadBuiltInProto(builtin); + } + m_builtin_direct = new BuiltInTorchDirect(); + } - std::string last_type; //< Тип последней операции + virtual ~CompileInfo() { + delete m_builtin_direct; + } - TermPtr isFunction(TermPtr term); - TermPtr isArgument(TermPtr term); - TermPtr isVariable(TermPtr term); - TermPtr findObject(std::string name); + ProtoType arguments; //< Аргументы функции + ProtoType functions; //< Локальные функции + ProtoType variables; //< Локальные переменные + ProtoType consts; //< Локальные константы + ProtoType builtin; + std::set iterators; //< Текущие итреаторы - bool isLocalAccess(TermPtr term); + std::string last_type; //< Тип последней операции - size_t indent; + TermPtr isFunction(TermPtr term); + TermPtr isArgument(TermPtr term); + TermPtr isVariable(TermPtr term); + TermPtr findObject(std::string name); - std::string GetIndent(int64_t offset = 0) { - return repeat(std::string(NEWLANG_INDENT_OP), indent + offset); - } + bool isLocalAccess(TermPtr term); - class Indent { - public: + size_t indent; - Indent(CompileInfo &i) : info(i) { - info.indent++; + std::string GetIndent(int64_t offset = 0) { + return repeat(std::string(NEWLANG_INDENT_OP), indent + offset); } - ~Indent() { - info.indent--; - } - CompileInfo &info; - }; + class Indent { + public: - Indent NewIndent() { - return Indent(*this); - } + Indent(CompileInfo &i) : info(i) { + info.indent++; + } - // BuiltInInfo m_builtin_info; - //private: - // Context * m_ctx; -}; + ~Indent() { + info.indent--; + } + CompileInfo &info; + }; -class NewLang : public Variable { -public: + Indent NewIndent() { + return Indent(*this); + } - ObjPtr Run(const char *source, void *context); + // BuiltInInfo m_builtin_info; + //private: + // Context * m_ctx; + }; - ObjPtr RunFile(const char *filename) { - return Obj::CreateNone(); - } + class NewLang : public Variable { + public: - void Free(); + ObjPtr Run(const char *source, void *context); + ObjPtr RunFile(const char *filename) { + return Obj::CreateNone(); + } - /* - * - */ - static bool MakeFunctionCpp(CompileInfo &ci, std::string func_name, TermPtr &func_define, std::ostream &out); - static bool MakeCppFile(TermPtr list, std::ostream &out, const char *source = nullptr, Context *ctx = nullptr); + void Free(); - // Преобразуют последовательность команд в эквивалентный код на С++ и возвращают результат выполнения последенй команды (или nullptr если не применимо) - static std::string MakeFunctionBodyCpp(CompileInfo &ci, TermPtr ast); - static std::string MakeSequenceOpsCpp(CompileInfo &ci, TermPtr elem, bool top_level); - // Преобразуют один термин в эквивалентый код на C++ - static std::string GetImpl(CompileInfo &ci, TermPtr term, std::string &output); - static std::string BeginIterators(CompileInfo &ci, TermPtr args, std::string &output, std::vector &iters); - static void ReplaceSourceVariable(CompileInfo &ci, size_t count, std::string &body); + /* + * + */ + static bool MakeFunctionCpp(CompileInfo &ci, std::string func_name, TermPtr &func_define, std::ostream &out); + static bool MakeCppFile(TermPtr list, std::ostream &out, const char *source = nullptr, Context *ctx = nullptr); - static void MakeCppFileFunctions(CompileInfo &ci, TermPtr elem, std::ostream &out); - static void MakeCppFileConstants(CompileInfo &ci, TermPtr elem, std::ostream &out); - static void MakeCppFileCallTerm(CompileInfo &ci, TermPtr ast, std::ostream &out, size_t deep); - static std::string MakeCppFileCallArgs(CompileInfo &ci, TermPtr &args, TermPtr proto); - static std::string MakeIteratorCallArgs_(CompileInfo &ci, TermPtr args, std::vector &iters); - static std::string MakeCppFileVariable(CompileInfo &ci, TermPtr &args, std::ostream &out); + // Преобразуют последовательность команд в эквивалентный код на С++ и возвращают результат выполнения последенй команды (или nullptr если не применимо) + static std::string MakeFunctionBodyCpp(CompileInfo &ci, TermPtr ast); + static std::string MakeSequenceOpsCpp(CompileInfo &ci, TermPtr elem, bool top_level); + // Преобразуют один термин в эквивалентый код на C++ + static std::string GetImpl(CompileInfo &ci, TermPtr term, std::string &output); + static std::string BeginIterators(CompileInfo &ci, TermPtr args, std::string &output, std::vector &iters); + static void ReplaceSourceVariable(CompileInfo &ci, size_t count, std::string &body); - static bool Execute(const char *exec, std::string *out = nullptr, int *exit_code = nullptr); - static bool GccMakeModule(const char * file, const char * module, const char * opts = nullptr, std::string *out = nullptr, int *exit_code = nullptr); + static void MakeCppFileFunctions(CompileInfo &ci, TermPtr elem, std::ostream &out); + static void MakeCppFileConstants(CompileInfo &ci, TermPtr elem, std::ostream &out); + static void MakeCppFileCallTerm(CompileInfo &ci, TermPtr ast, std::ostream &out, size_t deep); + static std::string MakeCppFileCallArgs(CompileInfo &ci, TermPtr &args, TermPtr proto); + static std::string MakeIteratorCallArgs_(CompileInfo &ci, TermPtr args, std::vector &iters); + static std::string MakeCppFileVariable(CompileInfo &ci, TermPtr &args, std::ostream &out); - static std::string EncodeNonAsciiCharacters(const char * text); + static bool Execute(const char *exec, std::string *out = nullptr, int *exit_code = nullptr); + static bool GccMakeModule(const char * file, const char * module, const char * opts = nullptr, std::string *out = nullptr, int *exit_code = nullptr); - static bool CompileModule(const char *filename, const char *output); - // static ObjPtr ExecModule(const char *module, const char *output, bool cached, Context *ctx); + static std::string EncodeNonAsciiCharacters(const char * text); - // std::string MakeFunctionsSourceForJIT(TermPtr ast, Context *ctx); - // llvm::ExecutionEngine * JITCompileCPP(const char* source, const char* file_name = nullptr); - // bool LoadModule(const char *name, bool init = true, Context *ctx = nullptr, const char *module_name = nullptr); - // bool UnLoadModule(const char *name = nullptr, bool deinit = true); + static bool CompileModule(const char *filename, const char *output); + // static ObjPtr ExecModule(const char *module, const char *output, bool cached, Context *ctx); - // bool SaveContext(const char *name); - // static bool LoadContext(Context *ctx, const char *name); + // std::string MakeFunctionsSourceForJIT(TermPtr ast, Context *ctx); + // llvm::ExecutionEngine * JITCompileCPP(const char* source, const char* file_name = nullptr); + // bool LoadModule(const char *name, bool init = true, Context *ctx = nullptr, const char *module_name = nullptr); + // bool UnLoadModule(const char *name = nullptr, bool deinit = true); - // static ObjPtr Eval(Context *ctx, const char *text, bool make_function = false); - // static ObjPtr Eval(Context *ctx, TermPtr calc, bool make_function = false); - static ObjPtr GetIndexField(Context *ctx, ObjPtr obj, TermPtr term, bool create_field = false); + // bool SaveContext(const char *name); + // static bool LoadContext(Context *ctx, const char *name); - static bool ExecFunc(FunctionType * func, Obj *def_arg, Context *ctx, Obj &in, ObjPtr & out); - static bool StringTemplate(std::string &format, Context * ctx); + // static ObjPtr Eval(Context *ctx, const char *text, bool make_function = false); + // static ObjPtr Eval(Context *ctx, TermPtr calc, bool make_function = false); + static ObjPtr GetIndexField(Context *ctx, ObjPtr obj, TermPtr term, bool create_field = false); - NewLang(RuntimePtr rt); + static bool ExecFunc(FunctionType * func, Obj *def_arg, Context *ctx, Obj &in, ObjPtr & out); - virtual ~NewLang() { + static bool StringTemplate(std::string &format, Context * ctx); - } + NewLang(RuntimePtr rt); - static void WriteIncludeFiles_(std::ostream & out) { - out << "#include \"pch.h\"\n"; - out << "#include \"newlang.h\"\n"; - out << "#include \"builtin.h\"\n"; - out << "\n\n"; - out << "using namespace " NEWLANG_NS ";\n"; - out << "\n\n"; - } + virtual ~NewLang() { - static void WriteDeclarationFunctions_(CompileInfo &ci, TermPtr &func, std::ostream & out, std::vector &func_list); + } - enum FunctionStep { - PREPARE = 1, - OPERATION = 2, - COMPLETE = 3 - }; + static void WriteIncludeFiles_(std::ostream & out) { + out << "#include \"pch.h\"\n"; + out << "#include \"newlang.h\"\n"; + out << "#include \"builtin.h\"\n"; + out << "\n\n"; + out << "using namespace " NEWLANG_NS ";\n"; + out << "\n\n"; + } - typedef std::string WriteFunctionOp(CompileInfo &ci, TermPtr &op, FunctionStep step); + static void WriteDeclarationFunctions_(CompileInfo &ci, TermPtr &func, std::ostream & out, std::vector &func_list); - static std::string WriteFunctionCheckOp_(CompileInfo &ci, TermPtr &op, const char *check_true, const char *check_false); + enum FunctionStep { + PREPARE = 1, + OPERATION = 2, + COMPLETE = 3 + }; - static std::string WriteSimpleBodyAND_(CompileInfo &ci, TermPtr &op, FunctionStep step = FunctionStep::OPERATION) { - auto indent = ci.NewIndent(); - switch (step) { - case FunctionStep::PREPARE: - return ""; - case FunctionStep::COMPLETE: - return ci.GetIndent() + "return " NEWLANG_NS "::Obj::Yes();\n"; + typedef std::string WriteFunctionOp(CompileInfo &ci, TermPtr &op, FunctionStep step); - case FunctionStep::OPERATION: - return WriteFunctionCheckOp_(ci, op, "", "return " NEWLANG_NS "::Obj::No()"); - } - LOG_RUNTIME("Unknown function step %d", (int) step); - } + static std::string WriteFunctionCheckOp_(CompileInfo &ci, TermPtr &op, const char *check_true, const char *check_false); - static std::string WriteSimpleBodyOR_(CompileInfo &ci, TermPtr &op, FunctionStep step = FunctionStep::OPERATION) { - auto indent = ci.NewIndent(); - switch (step) { - case FunctionStep::PREPARE: - return ""; - case FunctionStep::COMPLETE: - return ci.GetIndent() + "return " NEWLANG_NS "::Obj::No();\n"; + static std::string WriteSimpleBodyAND_(CompileInfo &ci, TermPtr &op, FunctionStep step = FunctionStep::OPERATION) { + auto indent = ci.NewIndent(); + switch (step) { + case FunctionStep::PREPARE: + return ""; + case FunctionStep::COMPLETE: + return ci.GetIndent() + "return " NEWLANG_NS "::Obj::Yes();\n"; - case FunctionStep::OPERATION: - return WriteFunctionCheckOp_(ci, op, "return " NEWLANG_NS "::Obj::Yes()", ""); + case FunctionStep::OPERATION: + return WriteFunctionCheckOp_(ci, op, "", "return " NEWLANG_NS "::Obj::No()"); + } + LOG_RUNTIME("Unknown function step %d", (int) step); } - LOG_RUNTIME("Unknown function step %d", (int) step); - } - static std::string WriteSimpleBodyXOR_(CompileInfo &ci, TermPtr &op, FunctionStep step = FunctionStep::OPERATION) { - auto indent = ci.NewIndent(); - switch (step) { - case FunctionStep::PREPARE: - return ci.GetIndent() + "size_t xor_counter = 0;\n"; - case FunctionStep::COMPLETE: - // Результат равен 0, если нет операндов, равных 1, либо их чётное количество. - return ci.GetIndent() + "return (xor_counter & 1) ? " NEWLANG_NS "::Obj::Yes() : " NEWLANG_NS "::Obj::No();\n"; - - case FunctionStep::OPERATION: - return WriteFunctionCheckOp_(ci, op, "xor_counter++", ""); + static std::string WriteSimpleBodyOR_(CompileInfo &ci, TermPtr &op, FunctionStep step = FunctionStep::OPERATION) { + auto indent = ci.NewIndent(); + switch (step) { + case FunctionStep::PREPARE: + return ""; + case FunctionStep::COMPLETE: + return ci.GetIndent() + "return " NEWLANG_NS "::Obj::No();\n"; + + case FunctionStep::OPERATION: + return WriteFunctionCheckOp_(ci, op, "return " NEWLANG_NS "::Obj::Yes()", ""); + } + LOG_RUNTIME("Unknown function step %d", (int) step); } - LOG_RUNTIME("Unknown function step %d", (int) step); - } - static std::string WriteFunctionBodyCLEAN_(CompileInfo &ci, TermPtr &op, FunctionStep step = FunctionStep::OPERATION) { - auto indent = ci.NewIndent(); - switch (step) { - case FunctionStep::PREPARE: - return ""; - case FunctionStep::COMPLETE: - return ci.GetIndent(-1) + "return nullptr; // default return from function\n"; - default: // FunctionStep::OPERATION - break; + static std::string WriteSimpleBodyXOR_(CompileInfo &ci, TermPtr &op, FunctionStep step = FunctionStep::OPERATION) { + auto indent = ci.NewIndent(); + switch (step) { + case FunctionStep::PREPARE: + return ci.GetIndent() + "size_t xor_counter = 0;\n"; + case FunctionStep::COMPLETE: + // Результат равен 0, если нет операндов, равных 1, либо их чётное количество. + return ci.GetIndent() + "return (xor_counter & 1) ? " NEWLANG_NS "::Obj::Yes() : " NEWLANG_NS "::Obj::No();\n"; + + case FunctionStep::OPERATION: + return WriteFunctionCheckOp_(ci, op, "xor_counter++", ""); + } + LOG_RUNTIME("Unknown function step %d", (int) step); } - std::string str; - GetImpl(ci, op, str); - - return str + "\n"; - } - static std::string WriteFunctionBodyOTHER_(CompileInfo &ci, TermPtr &op, FunctionStep step = FunctionStep::OPERATION) { - auto indent = ci.NewIndent(); - switch (step) { - case FunctionStep::PREPARE: - return WriteArgsForCall_(ci, op); - case FunctionStep::COMPLETE: - return ci.GetIndent() + "return nullptr; // default return from function\n"; - default: // FunctionStep::OPERATION - break; + static std::string WriteFunctionBodyCLEAN_(CompileInfo &ci, TermPtr &op, FunctionStep step = FunctionStep::OPERATION) { + auto indent = ci.NewIndent(); + switch (step) { + case FunctionStep::PREPARE: + return ""; + case FunctionStep::COMPLETE: + return ci.GetIndent(-1) + "return nullptr; // default return from function\n"; + default: // FunctionStep::OPERATION + break; + } + std::string str; + GetImpl(ci, op, str); + + return str + "\n"; } - std::string str; - GetImpl(ci, op, str); - return str + ";\n"; - } + static std::string WriteFunctionBodyOTHER_(CompileInfo &ci, TermPtr &op, FunctionStep step = FunctionStep::OPERATION) { + auto indent = ci.NewIndent(); + switch (step) { + case FunctionStep::PREPARE: + return WriteArgsForCall_(ci, op); + case FunctionStep::COMPLETE: + return ci.GetIndent() + "return nullptr; // default return from function\n"; + default: // FunctionStep::OPERATION + break; + } + std::string str; + GetImpl(ci, op, str); + + return str + ";\n"; + } - static std::string WriteArgsForCall_(CompileInfo &ci, TermPtr & func); + static std::string WriteArgsForCall_(CompileInfo &ci, TermPtr & func); - static void SelectTerms_(TermPtr &obj, std::vector &terms); + static void SelectTerms_(TermPtr &obj, std::vector &terms); - static bool WriteFunctionName_(TermPtr &func, std::ostream & out, bool is_transparent = false); + static bool WriteFunctionName_(TermPtr &func, std::ostream & out, bool is_transparent = false); - static void ReplaceFuncArgs(TermPtr &func_define, std::string & str); + static void ReplaceFuncArgs(TermPtr &func_define, std::string & str); - static std::string MakeCommentLine(std::string comment); + static std::string MakeCommentLine(std::string comment); - static std::string WriteSimpleBody_(CompileInfo &ci, TermPtr &func); + static std::string WriteSimpleBody_(CompileInfo &ci, TermPtr &func); -public: - // cppjit::CppJIT *m_jit; + public: + // cppjit::CppJIT *m_jit; -protected: + protected: - RuntimePtr m_runtime; + RuntimePtr m_runtime; -}; + }; } diff --git a/src/object.cpp b/src/object.cpp index 19eacc55..fca56a1b 100644 --- a/src/object.cpp +++ b/src/object.cpp @@ -603,10 +603,7 @@ std::string Obj::toString(bool deep) const { if(is_scalar()) { result += GetValueAsString(); } else { - result += "["; - dump_tensor_(result); - result += ","; - result += "]"; + result += TensorToString(m_value); } return result; } else if(isSimpleType(m_var_type_current)) { @@ -1803,12 +1800,18 @@ torch::Tensor newlang::ConvertToTensor(Obj *data, at::ScalarType type, bool resh return torch::from_blob((void *) data->m_str.data(), data->m_str.size(), type).clone(); } else if(data->m_var_type_current == ObjType::StrWide) { if(type == at::ScalarType::Undefined) { - type = at::ScalarType::Int; + if(sizeof (wchar_t) == sizeof (int32_t)) { + type = at::ScalarType::Int; + } else if(sizeof (wchar_t) == sizeof (int16_t)) { + type = at::ScalarType::Short; + } else { + LOG_RUNTIME("Unsupport wchar_t size '%d'!!!", (int) sizeof (wchar_t)); + } } // В символьную строку конвертируется любой целочисленный скаляр или одномерный тензор return torch::from_blob((void *) data->m_wstr.data(), { (int) data->m_wstr.size() - }, type).clone(); + }, type).toType(at::ScalarType::Int).clone(); } else if(data->is_range()) { ASSERT(data->at("start").second); @@ -1917,7 +1920,7 @@ ObjPtr Obj::CallNative(Context *ctx, Obj args) { if(!m_func_ptr) { NL_CHECK(m_module_name.empty() || ctx, "You cannot load a module without access to the runtime context!"); - m_func_ptr = ctx->m_runtime->GetProcAddress(m_func_mangle_name.empty() ? m_func_proto->m_text.c_str() : m_func_mangle_name.c_str(), + m_func_ptr = ctx->m_runtime->GetNativeAddr(m_func_mangle_name.empty() ? m_func_proto->m_text.c_str() : m_func_mangle_name.c_str(), m_module_name.empty() ? nullptr : m_module_name.c_str()); } NL_CHECK(m_func_ptr, "Fail load func name '%s' (%s) or fail load module '%s'!", m_func_proto->m_text.c_str(), @@ -2043,8 +2046,10 @@ ObjPtr Obj::CallNative(Context *ctx, Obj args) { default: LOG_RUNTIME("Native arg '%s' not implemented!", args[i]->toString().c_str()); } - if(pind < check_count && (*m_func_proto)[pind]->GetType() && (*m_func_proto)[pind]->GetType()->m_text.compare("Format") == 0) { - NL_CHECK(ParsePrintfFormat(args, i), "Fail format string or type args!"); + if(pind < check_count && (*m_func_proto)[pind]->GetType()) { + if((*m_func_proto)[pind]->GetType()->m_text.compare(newlang::toString(ObjType::Format)) == 0) { + NL_CHECK(ParsePrintfFormat(&args, i), "Fail format string or type args!"); + } } } @@ -2141,18 +2146,22 @@ ObjPtr Obj::CallNative(Context *ctx, Obj args) { return Obj::CreateNone(); } -bool newlang::ParsePrintfFormat(Obj args, size_t start) { +bool newlang::ParsePrintfFormat(Obj *args, size_t start) { - //if(args.size() <= start || !args[start]) { - // LOG_WARNING("Missing format string!"); - // return false; - //} - //if(!args[start]->is_string_type()) { - // LOG_WARNING("Argument Format '%s' not string type!", args[start]->toString().c_str()); - // return false; - //} + if(!args) { + LOG_WARNING("Missing object!"); + return false; + } + if(args->size() <= start || !(*args)[start]) { + LOG_WARNING("Missing format string!"); + return false; + } + if(!(*args)[start]->is_string_type()) { + LOG_WARNING("Argument Format '%s' not string type!", (*args)[start]->toString().c_str()); + return false; + } - //std::string format = args[start]->GetValueAsString(); + //std::string format = (*args)[start]->GetValueAsString(); //size_t count = parse_printf_format(format.c_str(), 0, nullptr); //std::vector types(count); @@ -2163,7 +2172,7 @@ bool newlang::ParsePrintfFormat(Obj args, size_t start) { //ObjType cast; //while(i < types.size()) { - // if(aind < args.size()) { + // if(aind < args->size()) { // // if(types[i] & PA_FLAG_PTR == PA_FLAG_PTR) { // // LOG_WARNING("Pointer arg '%u' not suppotred!", i); // // result = false; @@ -2173,39 +2182,42 @@ bool newlang::ParsePrintfFormat(Obj args, size_t start) { // // } // switch(types[i] & ~PA_FLAG_MASK) { // case PA_INT: - // if(types[i] & PA_FLAG_MASK == 0) { + // if((types[i] & PA_FLAG_MASK) == 0) { // cast = ObjType::Int; - // } else if(types[i] & PA_FLAG_LONG == PA_FLAG_LONG) { + // } else if(((types[i] & PA_FLAG_LONG) == PA_FLAG_LONG) || ((types[i] & PA_FLAG_LONG) == PA_FLAG_LONG_LONG)) { // cast = ObjType::Long; - // } else if(types[i] & PA_FLAG_SHORT == PA_FLAG_SHORT) { + // } else if((types[i] & PA_FLAG_SHORT) == PA_FLAG_SHORT) { // cast = ObjType::Short; + // } else { + // LOG_WARNING("Format flag at pos %d unrecognized! %s", i, format.c_str()); + // result = false; // } - // if(!canCast(args[aind]->m_var_type_current, cast)) { - // LOG_WARNING("Cast '%s' to '%s' not supported!", newlang::toString(args[aind]->m_var_type_current), + // if(!canCast((*args)[aind]->m_var_type_current, cast)) { + // LOG_WARNING("Cast '%s' to '%s' not supported!", newlang::toString((*args)[aind]->m_var_type_current), // newlang::toString(cast)); // result = false; // } // break; // case PA_CHAR: // if(types[i] & PA_FLAG_MASK) { - // LOG_WARNING("format modifier arg '%s' %u not supported!", newlang::toString(args[aind]->m_var_type_current), i); + // LOG_WARNING("format modifier arg '%s' %u not supported!", newlang::toString((*args)[aind]->m_var_type_current), i); // result = false; // } // cast = ObjType::Char; - // if(!canCast(args[aind]->m_var_type_current, cast)) { - // LOG_WARNING("Cast '%s' to '%s' not supported!", newlang::toString(args[aind]->m_var_type_current), + // if(!canCast((*args)[aind]->m_var_type_current, cast)) { + // LOG_WARNING("Cast '%s' to '%s' not supported!", newlang::toString((*args)[aind]->m_var_type_current), // newlang::toString(cast)); // result = false; // } // break; // case PA_STRING: // if(types[i] & PA_FLAG_MASK) { - // LOG_WARNING("format modifier arg '%s' %u not supported!", newlang::toString(args[aind]->m_var_type_current), i); + // LOG_WARNING("format modifier arg '%s' %u not supported!", newlang::toString((*args)[aind]->m_var_type_current), i); // result = false; // } // cast = ObjType::StrChar; - // if(!canCast(args[aind]->m_var_type_current, cast)) { - // LOG_WARNING("Cast '%s' to '%s' not supported!", newlang::toString(args[aind]->m_var_type_current), + // if(!canCast((*args)[aind]->m_var_type_current, cast)) { + // LOG_WARNING("Cast '%s' to '%s' not supported!", newlang::toString((*args)[aind]->m_var_type_current), // newlang::toString(cast)); // result = false; // } @@ -2213,12 +2225,12 @@ bool newlang::ParsePrintfFormat(Obj args, size_t start) { // case PA_FLOAT: // case PA_DOUBLE: // if(types[i] & PA_FLAG_MASK) { - // LOG_WARNING("format modifier arg '%s' %u not supported!", newlang::toString(args[aind]->m_var_type_current), i); + // LOG_WARNING("format modifier arg '%s' %u not supported!", newlang::toString((*args)[aind]->m_var_type_current), i); // result = false; // } // cast = ObjType::Double; - // if(!canCast(args[aind]->m_var_type_current, cast)) { - // LOG_WARNING("Cast '%s' to '%s' not supported!", newlang::toString(args[aind]->m_var_type_current), + // if(!canCast((*args)[aind]->m_var_type_current, cast)) { + // LOG_WARNING("Cast '%s' to '%s' not supported!", newlang::toString((*args)[aind]->m_var_type_current), // newlang::toString(cast)); // result = false; // } @@ -2237,12 +2249,12 @@ bool newlang::ParsePrintfFormat(Obj args, size_t start) { // i++; // aind++; //} - //if(aind != args.size()) { + //if(aind != args->size()) { // LOG_WARNING("Extra arguments more %u", i); // return false; //} //return result; - return false; + return true; } void newlang::ConvertRangeToDict(Obj *from, Obj & to) { diff --git a/src/object.h b/src/object.h index c8dae921..fc24484b 100644 --- a/src/object.h +++ b/src/object.h @@ -34,7 +34,7 @@ namespace newlang { at::TensorOptions ConvertToTensorOptions(const Obj *obj); at::DimnameList ConvertToDimnameList(const Obj *obj); - bool ParsePrintfFormat(Obj args, size_t start = 1); + bool ParsePrintfFormat(Obj *args, size_t start = 1); enum class ConcatMode : uint8_t { Error = 0, @@ -949,10 +949,6 @@ namespace newlang { } } - void dump_tensor_(std::string & str) const { - str += m_value.toString(); - } - std::string toString(bool deep = true) const; std::string GetValueAsString() const; diff --git a/src/parser.cpp b/src/parser.cpp index 5f7ba8b9..54d6a899 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -15,7 +15,6 @@ bool Parser::parse_stream(std::istream& in, const std::string sname) { streamname = sname; Scanner scanner(&in); - scanner.set_debug(trace_scanning); this->lexer = &scanner; parser parser(*this); diff --git a/src/parser.h b/src/parser.h index 819d54c4..4de79771 100644 --- a/src/parser.h +++ b/src/parser.h @@ -197,6 +197,10 @@ namespace newlang { std::string body_base; std::string result(text); + if (name.empty() || result.empty()) { + return result; + } + if (name[name.size() - 1] != '(') { body_base = macro.substr(name.size()); if (!body_base.empty() && std::isspace(static_cast (body_base[0]))) { diff --git a/src/pch.h b/src/pch.h index 9a7c0275..a8a2a3ad 100644 --- a/src/pch.h +++ b/src/pch.h @@ -44,6 +44,8 @@ #include #include +#pragma execution_character_set("utf-8") + #else #include diff --git a/src/test/eval_test.cpp b/src/test/eval_test.cpp index bc0a3420..b13cde7f 100644 --- a/src/test/eval_test.cpp +++ b/src/test/eval_test.cpp @@ -569,17 +569,25 @@ TEST(ExecStr, Funcs) { Context::Reset(); Context ctx(RunTime::Init()); - ObjPtr printf = ctx.ExecStr("printf := @import('printf(format:Format, ...):Int');"); - ASSERT_TRUE(printf); - ASSERT_STREQ("printf=printf(format:Format, ...):Int{}", printf->toString().c_str()); + EXPECT_TRUE(ctx.m_runtime->GetNativeAddr("printf")); + + ObjPtr p = ctx.ExecStr("printf := @import('printf(format:Format, ...):Int');"); + ASSERT_TRUE(p); + ASSERT_STREQ("printf=printf(format:Format, ...):Int{}", p->toString().c_str()); + + ObjPtr res = p->Call(&ctx, Obj::Arg(Obj::CreateString("%s")), Obj::Arg(Obj::CreateString("call direct"))); + ASSERT_TRUE(res); + ASSERT_TRUE(res->is_integer()); + ASSERT_EQ(11, res->GetValueAsInteger()); + ObjPtr hello = ctx.ExecStr("hello(str='') := {printf('%s', $str); $str;}"); ASSERT_TRUE(hello); ASSERT_STREQ("hello=hello(str=''):={printf('%s', $str); $str;}", hello->toString().c_str()); - ObjPtr result = ctx.ExecStr("hello('Привет, мир!\\n');"); + ObjPtr result = ctx.ExecStr("hello('Привет, мир!');"); ASSERT_TRUE(result); - ASSERT_STREQ("Привет, мир!\n", result->GetValueAsString().c_str()); + ASSERT_STREQ("Привет, мир!", result->GetValueAsString().c_str()); } /* diff --git a/src/test/object_test.cpp b/src/test/object_test.cpp index 7753d38e..6211dea7 100644 --- a/src/test/object_test.cpp +++ b/src/test/object_test.cpp @@ -129,6 +129,58 @@ TEST(ObjTest, String) { } +TEST(ObjTest, PrintFormat) { + + ObjPtr format_none = Obj::CreateDict(Obj::Arg(Obj::CreateString(""))); + ASSERT_TRUE(ParsePrintfFormat(format_none.get(), 0)); + format_none->push_back(Obj::CreateString("")); + ASSERT_FALSE(ParsePrintfFormat(format_none.get(), 0)); + + ObjPtr format_string = Obj::CreateDict(Obj::Arg(Obj::CreateString("%s"))); + ASSERT_FALSE(ParsePrintfFormat(format_string.get(), 0)); + format_string->push_back(Obj::CreateString("")); + ASSERT_TRUE(ParsePrintfFormat(format_string.get(), 0)); + format_string->push_back(Obj::CreateString("")); + ASSERT_FALSE(ParsePrintfFormat(format_string.get(), 0)); + + ObjPtr format_int = Obj::CreateDict(Obj::Arg(Obj::CreateString("%d"))); + ASSERT_FALSE(ParsePrintfFormat(format_int.get(), 0)); + format_int->push_back(Obj::CreateValue(100)); + ASSERT_TRUE(ParsePrintfFormat(format_int.get(), 0)); + format_int->push_back(Obj::CreateString("")); + ASSERT_FALSE(ParsePrintfFormat(format_int.get(), 0)); + + format_int = Obj::CreateDict(Obj::Arg(Obj::CreateString("%d %d"))); + ASSERT_FALSE(ParsePrintfFormat(format_int.get(), 0)); + format_int->push_back(Obj::CreateValue(100)); + ASSERT_FALSE(ParsePrintfFormat(format_int.get(), 0)); + format_int->push_back(Obj::CreateValue(100)); + ASSERT_TRUE(ParsePrintfFormat(format_int.get(), 0)); + format_int->push_back(Obj::CreateString("")); + ASSERT_FALSE(ParsePrintfFormat(format_int.get(), 0)); + + ObjPtr format_number = Obj::CreateDict(Obj::Arg(Obj::CreateString("%f"))); + ASSERT_FALSE(ParsePrintfFormat(format_number.get(), 0)); + format_number->push_back(Obj::CreateValue(0.003)); + ASSERT_TRUE(ParsePrintfFormat(format_number.get(), 0)); + format_number->push_back(Obj::CreateString("")); + ASSERT_FALSE(ParsePrintfFormat(format_number.get(), 0)); + + ObjPtr format_full = Obj::CreateDict(Obj::Arg(Obj::CreateString("%s %d %f %s"))); + ASSERT_FALSE(ParsePrintfFormat(format_full.get(), 0)); + format_full->push_back(Obj::CreateString("")); + ASSERT_FALSE(ParsePrintfFormat(format_full.get(), 0)); + format_full->push_back(Obj::CreateValue(100)); + ASSERT_FALSE(ParsePrintfFormat(format_full.get(), 0)); + format_full->push_back(Obj::CreateValue(0.003)); + ASSERT_FALSE(ParsePrintfFormat(format_full.get(), 0)); + format_full->push_back(Obj::CreateString("")); + ASSERT_TRUE(ParsePrintfFormat(format_full.get(), 0)); + + format_full->push_back(Obj::CreateString("")); + ASSERT_FALSE(ParsePrintfFormat(format_full.get(), 0)); +} + TEST(ObjTest, Dict) { Context ctx(RunTime::Init()); @@ -696,6 +748,12 @@ TEST(ObjTest, Tensor) { ASSERT_EQ(2, t1->m_value.size(0)); ASSERT_EQ(3, t1->m_value.size(1)); + std::string from_str = "русские буквы для ПРОВЕРКИ КОНВЕРТАЦИИ символов"; + std::wstring to_str = utf8_decode(from_str); + std::string conv_str = utf8_encode(to_str); + + ASSERT_STREQ(from_str.c_str(), conv_str.c_str()); + // Байтовые строки ObjPtr str = Obj::CreateString("test"); ObjPtr t_str = Obj::CreateTensor(str->toTensor()); @@ -718,13 +776,14 @@ TEST(ObjTest, Tensor) { ObjPtr t_wstr = Obj::CreateTensor(wstr->toTensor()); ASSERT_EQ(t_wstr->m_var_type_current, ObjType::Int); ASSERT_EQ(4, t_wstr->size()); - EXPECT_STREQ(t_wstr->toType(ObjType::StrWide)->GetValueAsString().c_str(), "ТЕСТ"); ASSERT_EQ(t_wstr->index_get({0})->GetValueAsInteger(), L'Т'); ASSERT_EQ(t_wstr->index_get({1})->GetValueAsInteger(), L'Е'); ASSERT_EQ(t_wstr->index_get({2})->GetValueAsInteger(), L'С'); ASSERT_EQ(t_wstr->index_get({3})->GetValueAsInteger(), L'Т'); + EXPECT_STREQ(t_wstr->toType(ObjType::StrWide)->GetValueAsString().c_str(), "ТЕСТ"); + t_wstr->index_set_({1}, Obj::CreateString(L"е")); t_wstr->index_set_({2}, Obj::CreateString(L"с")); diff --git a/src/test/parser_test.cpp b/src/test/parser_test.cpp index ae6f8398..764bf8da 100644 --- a/src/test/parser_test.cpp +++ b/src/test/parser_test.cpp @@ -1396,6 +1396,22 @@ TEST_F(ParserTest, DISABLED_Comment6) { ASSERT_EQ(TermID::CREATE, ast->m_block[3]->getTermID()) << newlang::toString(ast->getTermID()); } + +TEST_F(ParserTest, CommentIncluded) { +// const char *str = "/* !!!!!!! \n" +// "@print(\"Привет, мир!\\n\");\n*/"; +// "# @print(\"Привет, мир!\\n\");\n"; +// ASSERT_TRUE(Parse(str)); + + const char *str2 = "/* /* /* /* term();\n" + "print1(str=\"\") ::= term();\n" + "print2(str=\"\") ::= term();\n\n */ " + "print3( */ str=\"\") ::= term();\n\n\n" + "ddd */ "; + "# @print(\"Привет, мир!\\n\");\n"; + ASSERT_TRUE(Parse(str2)); +} + TEST_F(ParserTest, Types) { EXPECT_TRUE(Parse(":type1 := :type;")); EXPECT_TRUE(Parse(":type2 := :type;")); diff --git a/src/win/.gitignore b/src/win/.gitignore new file mode 100644 index 00000000..f29b0e2f --- /dev/null +++ b/src/win/.gitignore @@ -0,0 +1,3 @@ +x64 +temp +.vs \ No newline at end of file diff --git a/src/win/nlc.sln b/src/win/nlc.sln index 1f158990..eb2e3a60 100644 --- a/src/win/nlc.sln +++ b/src/win/nlc.sln @@ -11,6 +11,8 @@ Global Debug|x86 = Debug|x86 Release|x64 = Release|x64 Release|x86 = Release|x86 + UnitTest|x64 = UnitTest|x64 + UnitTest|x86 = UnitTest|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {EAD3DACB-5C02-4BC6-98EB-79F6AD3198BF}.Debug|x64.ActiveCfg = Debug|x64 @@ -21,6 +23,10 @@ Global {EAD3DACB-5C02-4BC6-98EB-79F6AD3198BF}.Release|x64.Build.0 = Release|x64 {EAD3DACB-5C02-4BC6-98EB-79F6AD3198BF}.Release|x86.ActiveCfg = Release|Win32 {EAD3DACB-5C02-4BC6-98EB-79F6AD3198BF}.Release|x86.Build.0 = Release|Win32 + {EAD3DACB-5C02-4BC6-98EB-79F6AD3198BF}.UnitTest|x64.ActiveCfg = UnitTest|x64 + {EAD3DACB-5C02-4BC6-98EB-79F6AD3198BF}.UnitTest|x64.Build.0 = UnitTest|x64 + {EAD3DACB-5C02-4BC6-98EB-79F6AD3198BF}.UnitTest|x86.ActiveCfg = UnitTest|Win32 + {EAD3DACB-5C02-4BC6-98EB-79F6AD3198BF}.UnitTest|x86.Build.0 = UnitTest|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/src/win/nlc.vcxproj b/src/win/nlc.vcxproj index 5eaa3756..fd88bdea 100644 --- a/src/win/nlc.vcxproj +++ b/src/win/nlc.vcxproj @@ -17,6 +17,14 @@ Release x64 + + UnitTest + Win32 + + + UnitTest + x64 + 16.0 @@ -33,6 +41,12 @@ v143 Unicode + + Application + true + v143 + Unicode + Application false @@ -46,6 +60,12 @@ v143 Unicode + + Application + true + v143 + Unicode + Application false @@ -61,12 +81,18 @@ + + + + + + @@ -77,6 +103,12 @@ ..\..\output\ nlc_unit_test + + $(VC_IncludePath);$(WindowsSDK_IncludePath);..;../..;../../..;../../contrib/;../../contrib/googletest/googletest;../../contrib/googletest/googletest/include;../../contrib/Lyra/include;../../contrib/libtorch-win/include;../../contrib/libtorch-win/include/torch/csrc/api/include;../../contrib/tensorboard_logger/include;../../contrib/libffi/win64/include + ..\..\contrib\libffi\win64\lib;..\..\contrib\libtorch-win\lib;$(LibraryPath) + ..\..\output\ + nlc_unit_test + Level3 @@ -89,6 +121,18 @@ true + + + Level3 + true + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + Level3 @@ -130,6 +174,30 @@ + + + Level3 + true + _DEBUG;_CONSOLE;DEBUG;LOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG;PDC_WIDE;UNITTEST;_SILENCE_CXX17_ITERATOR_BASE_CLASS_DEPRECATION_WARNING;_SILENCE_CXX17_RESULT_OF_DEPRECATION_WARNING;_SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING;_SILENCE_CXX17_ADAPTOR_TYPEDEFS_DEPRECATION_WARNING;NOMINMAX;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + false + stdcpp17 + Use + pch.h + stdc17 + pch.h.pch + false + + + Console + true + %(AdditionalLibraryDirectories) + + + + + + + Level3 @@ -149,21 +217,27 @@ NotUsing + NotUsing NotUsing + NotUsing NotUsing + NotUsing NotUsing + NotUsing NotUsing + NotUsing 4244;4005;%(DisableSpecificWarnings) + 4244;4005;%(DisableSpecificWarnings) @@ -171,12 +245,15 @@ NotUsing + NotUsing Create + Create NotUsing + NotUsing @@ -190,6 +267,7 @@ NotUsing + NotUsing From 03089a0563af704c886f443831651d581ec76b02 Mon Sep 17 00:00:00 2001 From: Aleksandr Ryabikov Date: Sat, 2 Jul 2022 22:52:19 +0300 Subject: [PATCH 11/31] =?UTF-8?q?=D0=9F=D0=B5=D1=80=D0=B5=D0=B4=D0=B0?= =?UTF-8?q?=D0=BB=D0=B0=D0=BB=20libffi=20=D0=BD=D0=B0=20=D0=B4=D0=B8=D0=BD?= =?UTF-8?q?=D0=B0=D0=BC=D0=B8=D1=87=D0=B5=D1=81=D0=BA=D1=83=D1=8E=20=D0=B7?= =?UTF-8?q?=D0=B0=D0=B3=D1=80=D1=83=D0=B7=D0=BA=D1=83=20=D0=B4=D0=BB=D1=8F?= =?UTF-8?q?=20=D1=83=D0=BF=D1=80=D0=BE=D1=89=D0=B5=D0=BD=D0=B8=D1=8F=20?= =?UTF-8?q?=D0=B8=D1=81=D0=BF=D0=BE=D0=BB=D1=8C=D0=B7=D0=BE=D0=B2=D0=B0?= =?UTF-8?q?=D0=BD=D0=B8=D1=8F=20=D0=BF=D0=BE=D0=B4=20=D0=B2=D0=B8=D0=BD?= =?UTF-8?q?=D0=B4=D0=BE=D0=B9=20=D0=B8=20=D1=83=D0=B1=D1=80=D0=B0=D0=BB=20?= =?UTF-8?q?=D1=81=D1=83=D0=B1=D0=BC=D0=BE=D0=B4=D1=83=D0=BB=D1=8C=20libffi?= =?UTF-8?q?=20=D0=B4=D0=BB=D1=8F=20=D1=81=D1=82=D0=B0=D1=82=D0=B8=D1=87?= =?UTF-8?q?=D0=B5=D1=81=D0=BA=D0=BE=D0=B9=20=D0=BB=D0=B8=D0=BD=D0=BA=D0=BE?= =?UTF-8?q?=D0=B2=D0=BA=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitmodules | 3 - src/context.cpp | 12 ++-- src/nbproject/Makefile-UnitTest.mk | 4 +- src/nbproject/configurations.xml | 1 - src/newlang.h | 91 +++++++++++++++++++++++++++++- src/object.cpp | 58 ++++++++++--------- src/pch.h | 7 ++- src/test/eval_test.cpp | 30 +++++++--- src/win/nlc.vcxproj | 1 + 9 files changed, 154 insertions(+), 53 deletions(-) diff --git a/.gitmodules b/.gitmodules index 645748d5..8409ff49 100644 --- a/.gitmodules +++ b/.gitmodules @@ -7,9 +7,6 @@ [submodule "contrib/tensorboard_logger"] path = contrib/tensorboard_logger url = https://github.com/RustingSword/tensorboard_logger.git -[submodule "contrib/libffi"] - path = contrib/libffi - url = https://github.com/libffi/libffi.git [submodule "contrib/text2cpp"] path = contrib/text2cpp url = https://github.com/lostjared/text2cpp.git diff --git a/src/context.cpp b/src/context.cpp index 8bb1bbae..f4fabd15 100644 --- a/src/context.cpp +++ b/src/context.cpp @@ -1510,7 +1510,7 @@ std::string RunTime::GetLastErrorMessage() { #else wchar_t buffer[256]; FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), buffer, sizeof(buffer), NULL); + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), buffer, sizeof (buffer), NULL); return utf8_encode(buffer); #endif } @@ -1525,20 +1525,18 @@ void *RunTime::GetNativeAddr(const char *name, const char *module) { return nullptr; } + #ifndef _MSC_VER return dlsym(m_modules[module]->GetHandle(), name); #else - return static_cast(::GetProcAddress(m_modules[module]->GetHandle(), name)); + return static_cast (::GetProcAddress(m_modules[module]->GetHandle(), name)); #endif } + #ifndef _MSC_VER return dlsym(nullptr, name); #else - HMODULE msys = GetModuleHandle(L"msys-2.0.dll"); - if(!msys){ - LOG_DEBUG("GetModuleHandle: %s", RunTime::GetLastErrorMessage().c_str()); - } - return static_cast(::GetProcAddress(msys, name)); + return static_cast (::GetProcAddress(m_msys, name)); #endif } diff --git a/src/nbproject/Makefile-UnitTest.mk b/src/nbproject/Makefile-UnitTest.mk index 929bebe2..b0fb080c 100644 --- a/src/nbproject/Makefile-UnitTest.mk +++ b/src/nbproject/Makefile-UnitTest.mk @@ -75,14 +75,12 @@ FFLAGS= ASFLAGS= # Link Libraries and Options -LDLIBSOPTIONS=-L../contrib/libtorch/lib -Wl,-rpath,'../contrib/libtorch/lib' -lpthread -ldl ../contrib/libffi/output/lib/libffi.a -lcrypto -lLLVM-13 -ltorch -lc10 -ltorch_cpu +LDLIBSOPTIONS=-L../contrib/libtorch/lib -Wl,-rpath,'../contrib/libtorch/lib' -lpthread -ldl -lcrypto -lLLVM-13 -ltorch -lc10 -ltorch_cpu # Build Targets .build-conf: ${BUILD_SUBPROJECTS} "${MAKE}" -f nbproject/Makefile-${CND_CONF}.mk ../output/nlc_unit_test -../output/nlc_unit_test: ../contrib/libffi/output/lib/libffi.a - ../output/nlc_unit_test: ${OBJECTFILES} ${MKDIR} -p ../output ${LINK.cc} -o ../output/nlc_unit_test ${OBJECTFILES} ${LDLIBSOPTIONS} -Wl,--export-dynamic diff --git a/src/nbproject/configurations.xml b/src/nbproject/configurations.xml index 0149e624..3e530437 100644 --- a/src/nbproject/configurations.xml +++ b/src/nbproject/configurations.xml @@ -593,7 +593,6 @@ PosixThreads DynamicLinking - ../contrib/libffi/output/lib/libffi.a crypto LLVM-13 torch diff --git a/src/newlang.h b/src/newlang.h index a9b50011..989eeba2 100644 --- a/src/newlang.h +++ b/src/newlang.h @@ -115,8 +115,58 @@ namespace newlang { class RunTime { public: - static RuntimePtr Init(int argc = 0, const char** argv = nullptr) { - return std::make_shared(); + static RuntimePtr Init(int argc = 0, const char** argv = nullptr, bool ignore_error = true) { + RuntimePtr rt = std::make_shared(); + +#ifdef _MSC_VER + rt->m_msys = LoadLibrary(L"msys-2.0.dll"); + if (!rt->m_msys) { + if!(ignore_error) { + LOG_RUNTIME("Fail LoadLibrary msys-2.0.dll: %s", RunTime::GetLastErrorMessage().c_str()); + } + } + + typedef void init_type(); + + init_type *init = (init_type *) GetProcAddress(m_msys, "msys_dll_init"); + if (rt->m_msys && !init) { + if!(ignore_error) { + FreeLibrary(rt->m_msys); + LOG_RUNTIME("msys_dll_init not found! %s", RunTime::GetLastErrorMessage().c_str()); + } + (*init)(); + } +#else + rt->m_msys = dlopen("libffi.so", RTLD_NOW); +#endif + + rt->m_ffi_type_void = static_cast (GetDirectAddressFromLibrary(rt->m_msys, "ffi_type_void")); + rt->m_ffi_type_uint8 = static_cast (GetDirectAddressFromLibrary(rt->m_msys, "ffi_type_uint8")); + rt->m_ffi_type_sint8 = static_cast (GetDirectAddressFromLibrary(rt->m_msys, "ffi_type_sint8")); + rt->m_ffi_type_uint16 = static_cast (GetDirectAddressFromLibrary(rt->m_msys, "ffi_type_uint16")); + rt->m_ffi_type_sint16 = static_cast (GetDirectAddressFromLibrary(rt->m_msys, "ffi_type_sint16")); + rt->m_ffi_type_uint32 = static_cast (GetDirectAddressFromLibrary(rt->m_msys, "ffi_type_uint32")); + rt->m_ffi_type_sint32 = static_cast (GetDirectAddressFromLibrary(rt->m_msys, "ffi_type_sint32")); + rt->m_ffi_type_uint64 = static_cast (GetDirectAddressFromLibrary(rt->m_msys, "ffi_type_uint64")); + rt->m_ffi_type_sint64 = static_cast (GetDirectAddressFromLibrary(rt->m_msys, "ffi_type_sint64")); + rt->m_ffi_type_float = static_cast (GetDirectAddressFromLibrary(rt->m_msys, "ffi_type_float")); + rt->m_ffi_type_double = static_cast (GetDirectAddressFromLibrary(rt->m_msys, "ffi_type_double")); + rt->m_ffi_type_pointer = static_cast (GetDirectAddressFromLibrary(rt->m_msys, "ffi_type_pointer")); + + rt->m_ffi_prep_cif = reinterpret_cast (GetDirectAddressFromLibrary(rt->m_msys, "ffi_prep_cif")); + rt->m_ffi_prep_cif_var = reinterpret_cast (GetDirectAddressFromLibrary(rt->m_msys, "ffi_prep_cif_var")); + rt->m_ffi_call = reinterpret_cast (GetDirectAddressFromLibrary(rt->m_msys, "ffi_call")); + + return rt; + } + + inline static void * GetDirectAddressFromLibrary(void *handle, const char * name) { +#ifdef _MSC_VER + return static_cast (::GetProcAddress(handle, name)); +#else + + return dlsym(handle, name); +#endif } // void ReadBuiltInProto(ProtoType &proto); @@ -128,6 +178,12 @@ namespace newlang { void * GetNativeAddr(const char * name, const char *module = nullptr); virtual ~RunTime() { +#ifdef _MSC_VER + if (m_msys) { + FreeLibrary(m_msys); + m_msys = nullptr; + } +#endif } RunTime() { @@ -135,13 +191,36 @@ namespace newlang { static std::string GetLastErrorMessage(); + typedef ffi_status ffi_prep_cif_type(ffi_cif *cif, ffi_abi abi, unsigned int nargs, ffi_type *rtype, ffi_type **atypes); + typedef ffi_status ffi_prep_cif_var_type(ffi_cif *cif, ffi_abi abi, unsigned int nfixedargs, unsigned int ntotalargs, ffi_type *rtype, ffi_type **atypes); + typedef void ffi_call_type(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue); + protected: SCOPE(private) : RunTime(const RunTime&) = delete; const RunTime& operator=(const RunTime&) = delete; + void * m_msys; std::map m_modules; + + ffi_type * m_ffi_type_void; + ffi_type * m_ffi_type_uint8; + ffi_type * m_ffi_type_sint8; + ffi_type * m_ffi_type_uint16; + ffi_type * m_ffi_type_sint16; + ffi_type * m_ffi_type_uint32; + ffi_type * m_ffi_type_sint32; + ffi_type * m_ffi_type_uint64; + ffi_type * m_ffi_type_sint64; + ffi_type * m_ffi_type_float; + ffi_type * m_ffi_type_double; + ffi_type * m_ffi_type_pointer; + + ffi_prep_cif_type *m_ffi_prep_cif; + ffi_prep_cif_var_type * m_ffi_prep_cif_var; + ffi_call_type * m_ffi_call; + }; struct CompileInfo { @@ -152,10 +231,12 @@ namespace newlang { if (rt) { // rt->ReadBuiltInProto(builtin); } + m_builtin_direct = new BuiltInTorchDirect(); } virtual ~CompileInfo() { + delete m_builtin_direct; } @@ -178,6 +259,7 @@ namespace newlang { size_t indent; std::string GetIndent(int64_t offset = 0) { + return repeat(std::string(NEWLANG_INDENT_OP), indent + offset); } @@ -185,16 +267,19 @@ namespace newlang { public: Indent(CompileInfo &i) : info(i) { + info.indent++; } ~Indent() { + info.indent--; } CompileInfo &info; }; Indent NewIndent() { + return Indent(*this); } @@ -209,6 +294,7 @@ namespace newlang { ObjPtr Run(const char *source, void *context); ObjPtr RunFile(const char *filename) { + return Obj::CreateNone(); } @@ -272,6 +358,7 @@ namespace newlang { } static void WriteIncludeFiles_(std::ostream & out) { + out << "#include \"pch.h\"\n"; out << "#include \"newlang.h\"\n"; out << "#include \"builtin.h\"\n"; diff --git a/src/object.cpp b/src/object.cpp index fca56a1b..8f1f498e 100644 --- a/src/object.cpp +++ b/src/object.cpp @@ -1900,6 +1900,10 @@ at::DimnameList newlang::ConvertToDimnameList(const Obj * obj) { ObjPtr Obj::CallNative(Context *ctx, Obj args) { + if(!ctx || !ctx->m_runtime) { + LOG_RUNTIME("Fail context for call native!"); + } + ffi_cif m_cif; std::vector m_args_type; std::vector m_args_ptr; @@ -1948,7 +1952,7 @@ ObjPtr Obj::CallNative(Context *ctx, Obj args) { NL_CHECK(canCast(type, typeFromString((*m_func_proto)[pind]->m_type_name, ctx)), "Fail cast from '%s' to '%s'", (*m_func_proto)[pind]->m_type_name.c_str(), newlang::toString(type)); } - m_args_type.push_back(&ffi_type_uint8); + m_args_type.push_back(ctx->m_runtime->m_ffi_type_uint8); temp.boolean = args[i]->GetValueAsBoolean(); m_args_val.push_back(temp); break; @@ -1959,7 +1963,7 @@ ObjPtr Obj::CallNative(Context *ctx, Obj args) { NL_CHECK(canCast(type, typeFromString((*m_func_proto)[pind]->m_type_name, ctx)), "Fail cast from '%s' to '%s'", (*m_func_proto)[pind]->m_type_name.c_str(), newlang::toString(type)); } - m_args_type.push_back(&ffi_type_sint8); + m_args_type.push_back(ctx->m_runtime->m_ffi_type_sint8); temp.integer = args[i]->GetValueAsInteger(); m_args_val.push_back(temp); break; @@ -1970,7 +1974,7 @@ ObjPtr Obj::CallNative(Context *ctx, Obj args) { NL_CHECK(canCast(type, typeFromString((*m_func_proto)[pind]->m_type_name, ctx)), "Fail cast from '%s' to '%s'", (*m_func_proto)[pind]->m_type_name.c_str(), newlang::toString(type)); } - m_args_type.push_back(&ffi_type_sint16); + m_args_type.push_back(ctx->m_runtime->m_ffi_type_sint16); temp.integer = args[i]->GetValueAsInteger(); m_args_val.push_back(temp); break; @@ -1981,7 +1985,7 @@ ObjPtr Obj::CallNative(Context *ctx, Obj args) { NL_CHECK(canCast(type, typeFromString((*m_func_proto)[pind]->m_type_name, ctx)), "Fail cast from '%s' to '%s'", (*m_func_proto)[pind]->m_type_name.c_str(), newlang::toString(type)); } - m_args_type.push_back(&ffi_type_sint32); + m_args_type.push_back(ctx->m_runtime->m_ffi_type_sint32); temp.integer = args[i]->GetValueAsInteger(); m_args_val.push_back(temp); break; @@ -1992,7 +1996,7 @@ ObjPtr Obj::CallNative(Context *ctx, Obj args) { NL_CHECK(canCast(type, typeFromString((*m_func_proto)[pind]->m_type_name, ctx)), "Fail cast from '%s' to '%s'", (*m_func_proto)[pind]->m_type_name.c_str(), newlang::toString(type)); } - m_args_type.push_back(&ffi_type_sint64); + m_args_type.push_back(ctx->m_runtime->m_ffi_type_sint64); temp.integer = args[i]->GetValueAsInteger(); m_args_val.push_back(temp); break; @@ -2003,7 +2007,7 @@ ObjPtr Obj::CallNative(Context *ctx, Obj args) { NL_CHECK(canCast(type, typeFromString((*m_func_proto)[pind]->m_type_name, ctx)), "Fail cast from '%s' to '%s'", (*m_func_proto)[pind]->m_type_name.c_str(), newlang::toString(type)); } - m_args_type.push_back(&ffi_type_float); + m_args_type.push_back(ctx->m_runtime->m_ffi_type_float); temp.number = args[i]->GetValueAsNumber(); m_args_val.push_back(temp); break; @@ -2014,7 +2018,7 @@ ObjPtr Obj::CallNative(Context *ctx, Obj args) { NL_CHECK(canCast(type, typeFromString((*m_func_proto)[pind]->m_type_name, ctx)), "Fail cast from '%s' to '%s'", (*m_func_proto)[pind]->m_type_name.c_str(), newlang::toString(type)); } - m_args_type.push_back(&ffi_type_double); + m_args_type.push_back(ctx->m_runtime->m_ffi_type_double); temp.number = args[i]->GetValueAsNumber(); m_args_val.push_back(temp); break; @@ -2027,7 +2031,7 @@ ObjPtr Obj::CallNative(Context *ctx, Obj args) { NL_CHECK(canCast(type, typeFromString((*m_func_proto)[pind]->m_type_name, ctx)), "Fail cast from '%s' to '%s'", (*m_func_proto)[pind]->m_type_name.c_str(), newlang::toString(type)); } - m_args_type.push_back(&ffi_type_pointer); + m_args_type.push_back(ctx->m_runtime->m_ffi_type_pointer); temp.ptr = args[i]->m_str.c_str(); m_args_val.push_back(temp); break; @@ -2038,7 +2042,7 @@ ObjPtr Obj::CallNative(Context *ctx, Obj args) { NL_CHECK(canCast(type, typeFromString((*m_func_proto)[pind]->m_type_name, ctx)), "Fail cast from '%s' to '%s'", (*m_func_proto)[pind]->m_type_name.c_str(), newlang::toString(type)); } - m_args_type.push_back(&ffi_type_pointer); + m_args_type.push_back(ctx->m_runtime->m_ffi_type_pointer); temp.ptr = args[i]->m_func_ptr; m_args_val.push_back(temp); break; @@ -2066,37 +2070,37 @@ ObjPtr Obj::CallNative(Context *ctx, Obj args) { switch(type) { case ObjType::Bool: - result_ffi_type = &ffi_type_uint8; + result_ffi_type = ctx->m_runtime->m_ffi_type_uint8; break; case ObjType::Char: - result_ffi_type = &ffi_type_sint8; + result_ffi_type = ctx->m_runtime->m_ffi_type_sint8; break; case ObjType::Short: - result_ffi_type = &ffi_type_sint16; + result_ffi_type = ctx->m_runtime->m_ffi_type_sint16; break; case ObjType::Int: - result_ffi_type = &ffi_type_sint32; + result_ffi_type = ctx->m_runtime->m_ffi_type_sint32; break; case ObjType::Long: - result_ffi_type = &ffi_type_sint64; + result_ffi_type = ctx->m_runtime->m_ffi_type_sint64; break; case ObjType::Float: - result_ffi_type = &ffi_type_float; + result_ffi_type = ctx->m_runtime->m_ffi_type_float; break; case ObjType::Double: - result_ffi_type = &ffi_type_double; + result_ffi_type = ctx->m_runtime->m_ffi_type_double; break; case ObjType::Pointer: case ObjType::StrChar: case ObjType::StrWide: - result_ffi_type = &ffi_type_pointer; + result_ffi_type = ctx->m_runtime->m_ffi_type_pointer; break; default: @@ -2104,26 +2108,26 @@ ObjPtr Obj::CallNative(Context *ctx, Obj args) { } ASSERT(m_func_abi == FFI_DEFAULT_ABI); // Нужны другие типы вызовов ??? - if(ffi_prep_cif(&m_cif, m_func_abi, static_cast (m_args_type.size()), result_ffi_type, m_args_type.data()) == FFI_OK) { + if(ctx->m_runtime->m_ffi_prep_cif(&m_cif, m_func_abi, static_cast (m_args_type.size()), result_ffi_type, m_args_type.data()) == FFI_OK) { - ffi_call(&m_cif, FFI_FN(m_func_ptr), &res_value, m_args_ptr.data()); + ctx->m_runtime->m_ffi_call(&m_cif, FFI_FN(m_func_ptr), &res_value, m_args_ptr.data()); - if(result_ffi_type == &ffi_type_uint8) { + if(result_ffi_type == ctx->m_runtime->m_ffi_type_uint8) { // Возвращаемый тип может быть как Byte, так и Bool return Obj::CreateValue(static_cast (res_value.integer), typeFromString(m_func_proto->m_type_name)); - } else if(result_ffi_type == &ffi_type_sint8) { + } else if(result_ffi_type == ctx->m_runtime->m_ffi_type_sint8) { return Obj::CreateValue(static_cast (res_value.integer), ObjType::Char); - } else if(result_ffi_type == &ffi_type_sint16) { + } else if(result_ffi_type == ctx->m_runtime->m_ffi_type_sint16) { return Obj::CreateValue(static_cast (res_value.integer), ObjType::Short); - } else if(result_ffi_type == &ffi_type_sint32) { + } else if(result_ffi_type == ctx->m_runtime->m_ffi_type_sint32) { return Obj::CreateValue(static_cast (res_value.integer), ObjType::Int); - } else if(result_ffi_type == &ffi_type_sint64) { + } else if(result_ffi_type == ctx->m_runtime->m_ffi_type_sint64) { return Obj::CreateValue(res_value.integer, ObjType::Long); - } else if(result_ffi_type == &ffi_type_float) { + } else if(result_ffi_type == ctx->m_runtime->m_ffi_type_float) { return Obj::CreateValue(res_value.number, ObjType::Float); - } else if(result_ffi_type == &ffi_type_double) { + } else if(result_ffi_type == ctx->m_runtime->m_ffi_type_double) { return Obj::CreateValue(res_value.number, ObjType::Double); - } else if(result_ffi_type == &ffi_type_pointer) { + } else if(result_ffi_type == ctx->m_runtime->m_ffi_type_pointer) { if(type == ObjType::StrChar) { return Obj::CreateString(reinterpret_cast (res_value.ptr)); } else if(type == ObjType::StrWide) { diff --git a/src/pch.h b/src/pch.h index a8a2a3ad..951bc7cf 100644 --- a/src/pch.h +++ b/src/pch.h @@ -35,6 +35,7 @@ #include #include #include +#include #ifdef _MSC_VER @@ -48,12 +49,12 @@ #else -#include +#ifndef __WIN32__ #include #include -#include +#endif -#include +#include #endif diff --git a/src/test/eval_test.cpp b/src/test/eval_test.cpp index b13cde7f..bb2e885d 100644 --- a/src/test/eval_test.cpp +++ b/src/test/eval_test.cpp @@ -108,20 +108,20 @@ TEST(Eval, Assign) { ASSERT_EQ(func_export->getType(), ObjType::NativeFunc); ASSERT_STREQ("func_export=func_export(arg1:Long, arg2:Char=100):Long{}", func_export->toString().c_str()); - ObjPtr result = func_export->Call(nullptr, Obj::Arg(200), Obj::Arg(10)); + ObjPtr result = func_export->Call(&ctx, Obj::Arg(200), Obj::Arg(10)); ASSERT_TRUE(result); ASSERT_EQ(210, result->GetValueAsInteger()); - result = func_export->Call(nullptr, Obj::Arg(10), Obj::Arg(10)); + result = func_export->Call(&ctx, Obj::Arg(10), Obj::Arg(10)); ASSERT_TRUE(result); ASSERT_EQ(20, result->GetValueAsInteger()); - result = func_export->Call(nullptr, Obj::Arg(10)); + result = func_export->Call(&ctx, Obj::Arg(10)); ASSERT_TRUE(result); ASSERT_EQ(110, result->GetValueAsInteger()); // Переполнение второго аргумента - ASSERT_ANY_THROW(func_export->Call(nullptr, Obj::Arg(1000), Obj::Arg(1000))); + ASSERT_ANY_THROW(func_export->Call(&ctx, Obj::Arg(1000), Obj::Arg(1000))); list = ctx.ExecStr("$"); ASSERT_STREQ("$=('var_str', 'var_num', 'var_export', 'func_export',)", list->toString().c_str()); @@ -575,19 +575,35 @@ TEST(ExecStr, Funcs) { ASSERT_TRUE(p); ASSERT_STREQ("printf=printf(format:Format, ...):Int{}", p->toString().c_str()); - ObjPtr res = p->Call(&ctx, Obj::Arg(Obj::CreateString("%s")), Obj::Arg(Obj::CreateString("call direct"))); + + typedef int (* printf_type)(const char *, ...); + + printf_type ttt = (printf_type) p->m_func_ptr; + ASSERT_EQ(7, (*ttt)("Test 1 ")); + ASSERT_EQ(18,(*ttt)("%s", "Test Variadic call")); + + ObjPtr res = p->Call(&ctx, Obj::Arg(Obj::CreateString("Test"))); + ASSERT_TRUE(res); + ASSERT_TRUE(res->is_integer()); + ASSERT_EQ(4, res->GetValueAsInteger()); + + res = p->Call(&ctx, Obj::Arg(Obj::CreateString("%s")), Obj::Arg(Obj::CreateString("call direct"))); ASSERT_TRUE(res); ASSERT_TRUE(res->is_integer()); ASSERT_EQ(11, res->GetValueAsInteger()); + res = p->Call(&ctx, Obj::Arg(Obj::CreateString("%s")), Obj::Arg(Obj::CreateString("Русские символы"))); + ASSERT_TRUE(res); + ASSERT_TRUE(res->is_integer()); + ASSERT_TRUE(15 <= res->GetValueAsInteger()); ObjPtr hello = ctx.ExecStr("hello(str='') := {printf('%s', $str); $str;}"); ASSERT_TRUE(hello); ASSERT_STREQ("hello=hello(str=''):={printf('%s', $str); $str;}", hello->toString().c_str()); - ObjPtr result = ctx.ExecStr("hello('Привет, мир!');"); + ObjPtr result = ctx.ExecStr("hello('Привет, мир!\\n');"); ASSERT_TRUE(result); - ASSERT_STREQ("Привет, мир!", result->GetValueAsString().c_str()); + ASSERT_STREQ("Привет, мир!\n", result->GetValueAsString().c_str()); } /* diff --git a/src/win/nlc.vcxproj b/src/win/nlc.vcxproj index fd88bdea..9093925e 100644 --- a/src/win/nlc.vcxproj +++ b/src/win/nlc.vcxproj @@ -108,6 +108,7 @@ ..\..\contrib\libffi\win64\lib;..\..\contrib\libtorch-win\lib;$(LibraryPath) ..\..\output\ nlc_unit_test + false From bd30146e62f8fe97c92a72e63af4e4d3179156f8 Mon Sep 17 00:00:00 2001 From: Aleksandr Ryabikov Date: Sun, 3 Jul 2022 11:25:41 +0300 Subject: [PATCH 12/31] =?UTF-8?q?=D0=92=20=D1=81=D0=B1=D0=BE=D1=80=D0=BA?= =?UTF-8?q?=D1=83=20=D0=BF=D0=BE=D0=B4=20windows=20=D0=B4=D0=BE=D0=B0?= =?UTF-8?q?=D0=B2=D0=BB=D0=B5=D0=BD=20openssl=20=D0=B4=D0=BB=D1=8F=20?= =?UTF-8?q?=D0=BF=D0=BE=D0=B4=D0=B4=D0=B5=D1=80=D0=B6=D0=BA=D0=B8=20=D0=B4?= =?UTF-8?q?=D0=BB=D0=B8=D0=BD=D0=BD=D0=BE=D0=B9=20=D0=B0=D1=80=D0=B8=D1=84?= =?UTF-8?q?=D0=BC=D0=B5=D1=82=D0=B8=D0=BA=D0=B8=20+=20=D0=BF=D0=BE=D0=B4?= =?UTF-8?q?=D0=B4=D0=B5=D1=80=D0=B6=D0=BA=D0=B0=20cygwin1.dll=20=D0=B8?= =?UTF-8?q?=D0=BB=D0=B8=20msys2-2.0.dll?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- contrib/build.cmd | 13 +- contrib/build.sh | 7 - contrib/libffi | 1 - src/context.cpp | 4 +- src/fraction.h | 509 ++++++++++++++++++------------------- src/newlang.h | 97 ++++--- src/nlc.cpp | 12 - src/object.cpp | 2 +- src/pch.h | 12 +- src/test/fraction_test.cpp | 112 ++++---- src/win/nlc.vcxproj | 4 +- 11 files changed, 396 insertions(+), 377 deletions(-) delete mode 160000 contrib/libffi diff --git a/contrib/build.cmd b/contrib/build.cmd index 5f10072a..4d1675b3 100644 --- a/contrib/build.cmd +++ b/contrib/build.cmd @@ -1,3 +1,14 @@ +cd z:\NewLang\newlang\contrib\libffi +./configure CC="msvcc.sh -m64" CXX="msvcc.sh -m64" LD=link CPP="cl -nologo -EP" CPPFLAGS="-DFFI_BUILDING_DLL" + +rem PATH="C:\Program^ Files\Microsoft^ Visual^ Studio\2022\Community\VC\Tools\MSVC\14.32.31326\bin\Hostx64\x64;%PATH%" + +rem /z/NewLang/newlang/contrib/libffi/configure CC=/z/NewLang/newlang/contrib/libffi/msvcc.sh CXX=/z/NewLang/newlang/contrib/libffi/msvcc.sh LD=link CPP="cl -nologo -EP" CPPFLAGS="-DFFI_BUILDING_DLL" + +rem C:\msys64\usr\bin\bash -lc "cd /z/NewLang/newlang/contrib/libffi && ./configure CC='./msvcc.sh -m64' -- --prefix=`pwd`/vs --disable-docs" + + +rem C:\msys64\usr\bin\bash -lc "cd libffi && ./configure --build=x86_64-w64-mingw32 --host=x86_64-w64-mingw32 --prefix=`pwd`/win64 --disable-docs && make && make install && .." + -C:\msys64\usr\bin\bash -lc "cd /z/NewLang/newlang/contrib/libffi && ./configure --build=x86_64-w64-mingw32 --host=x86_64-w64-mingw32 --prefix=`pwd`/win64 --disable-docs && make && make install" diff --git a/contrib/build.sh b/contrib/build.sh index 199e6b04..d6e5b6e4 100755 --- a/contrib/build.sh +++ b/contrib/build.sh @@ -1,10 +1,3 @@ -cd libffi -./autogen.sh -./configure --prefix=`pwd`/output -make -make install -cd .. - cd text2cpp ./autogen.sh ./configure --prefix=`pwd`/output diff --git a/contrib/libffi b/contrib/libffi deleted file mode 160000 index 464b4b66..00000000 --- a/contrib/libffi +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 464b4b66e3cf3b5489e730c1466ee1bf825560e0 diff --git a/src/context.cpp b/src/context.cpp index f4fabd15..6b7d173c 100644 --- a/src/context.cpp +++ b/src/context.cpp @@ -811,7 +811,7 @@ ObjPtr Context::eval_FOLLOW(Context *ctx, const TermPtr &term, Obj * args) { * */ - for (int64_t i = 0; i < term->m_follow.size(); i++) { + for (int64_t i = 0; i < static_cast(term->m_follow.size()); i++) { ASSERT(term->m_follow[i]->Left()); ObjPtr cond = ExecStr(ctx, term->m_follow[i]->Left(), args, false); @@ -1536,7 +1536,7 @@ void *RunTime::GetNativeAddr(const char *name, const char *module) { #ifndef _MSC_VER return dlsym(nullptr, name); #else - return static_cast (::GetProcAddress(m_msys, name)); + return static_cast(::GetProcAddress((HMODULE)m_msys, name)); #endif } diff --git a/src/fraction.h b/src/fraction.h index e5384126..cb7cc379 100644 --- a/src/fraction.h +++ b/src/fraction.h @@ -1,261 +1,260 @@ #ifndef FRACTION_H #define FRACTION_H -//#include -//#include -// -//#include -//#include -// -//class BigNum { -// SCOPE(private) : -// BIGNUM *m_value; -// BN_CTX *m_ctx; -// bool m_is_init; -//public: -// -//#define CHECK_INIT(value) if (!(value)->m_is_init) { LOG_RUNTIME("Fail init!!!"); } -// -// BigNum() : m_value(nullptr), m_ctx(nullptr) { -// m_is_init = false; -// m_value = BN_new(); -// m_ctx = BN_CTX_new(); -// } -// -// BigNum(std::string str) { -// SetFromString(str); -// } -// -// virtual ~BigNum() { -// if (m_value) { -// BN_free(m_value); -// m_value = nullptr; -// } -// if (m_ctx) { -// BN_CTX_free(m_ctx); -// m_ctx = nullptr; -// } -// } -// -// int64_t GetAsInteger() { -// CHECK_INIT(this); -// -// int64_t result = BN_get_word(m_value); -// if (result == ~0) { -// LOG_RUNTIME("Bignum integer overflow!"); -// } -// -// if (BN_is_negative(m_value)) { -// result = -result; -// } -// return result; -// } -// -// double GetAsNumber() { -// CHECK_INIT(this); -// //@todo Refactor convert big integer to double! -// return GetAsInteger(); -// } -// -// inline bool SetFromString(const std::string str) { -// m_is_init = true; -// return BN_dec2bn(&m_value, str.c_str()); -// } -// -// std::string GetAsString() { -// CHECK_INIT(this); -// char * number_str = BN_bn2dec(m_value); -// std::string result(number_str); -// OPENSSL_free(number_str); -// return result; -// } -// -// BigNum &add(BigNum &val) { -// CHECK_INIT(this); -// CHECK_INIT(&val); -// -// BigNum temp; -// if (!BN_add(temp.m_value, m_value, val.m_value)) { -// LOG_RUNTIME("Bignum operation fail!"); -// } -// std::swap(temp.m_value, m_value); -// return *this; -// } -// -// BigNum &sub(BigNum &val) { -// CHECK_INIT(this); -// CHECK_INIT(&val); -// -// BigNum temp; -// if (!BN_sub(temp.m_value, m_value, val.m_value)) { -// LOG_RUNTIME("Bignum operation fail!"); -// } -// std::swap(temp.m_value, m_value); -// return *this; -// } -// -// BigNum &mul(BigNum &val) { -// CHECK_INIT(this); -// CHECK_INIT(&val); -// -// BigNum temp; -// if (!BN_mul(temp.m_value, m_value, val.m_value, m_ctx)) { -// LOG_RUNTIME("Bignum operation fail!"); -// } -// std::swap(temp.m_value, m_value); -// return *this; -// } -// -// BigNum &div(BigNum &val, BigNum &rem) { -// CHECK_INIT(this); -// CHECK_INIT(&val); -// -// BigNum dv; -// BigNum rm; -// if (!BN_div(dv.m_value, rm.m_value, m_value, val.m_value, m_ctx)) { -// LOG_RUNTIME("Bignum operation fail!"); -// } -// std::swap(dv.m_value, m_value); -// std::swap(rm.m_value, rem.m_value); -// rem.m_is_init = true; -// return *this; -// } -// -//}; -// -//class Fraction { -//private: -// // Числитель -// BigNum m_numerator; -// // Знаменатель -// BigNum m_denominator; -// -// // Функция нужна для сокращения дроби -// void reduce(); -//public: -// // Конструктор принимает значения числителя и знаменателя -// -// Fraction(BigNum & numerator, BigNum &denominator) { -// m_numerator = numerator; -// m_denominator = denominator; -// } -// -// Fraction(const std::string &numerator, const std::string &denominator) { -// // m_numerator = numerator; -// // m_denominator = denominator; -// } -// -// // Fraction(const std::string &string) { -// // // Выбрасываем исключение, если не задана строка -// // assert(string == ""); -// // // Ищем знак '/' -// // int pos = string.find("/"); -// // -// // // Если символ не найден - то вся строка является числом -// // if (pos == std::string::npos) { -// // m_numerator = stoi(string); -// // m_denominator = 1; -// // } else { -// // // Числитель - левая часть -// // m_numerator = std::stoi(string.substr(0, pos)); -// // // Знаменатель - правая часть -// // m_denominator = std::stoi(string.substr(pos, string.length())); -// // -// // // Знаменатель не должен быть равен нулю -// // assert(m_denominator == 0); -// // } -// // } -// // // Возвращаем дробь в виде строки -// // -// // std::string toString() { -// // std::string fraction = ""; -// // if (m_numerator == 0) { -// // fraction.append("0"); -// // return fraction; -// // } -// // -// // fraction.append(std::to_string(m_numerator)); -// // if (m_denominator != 1) { -// // fraction.append("/"); -// // fraction.append(std::to_string(m_denominator)); -// // } -// // return fraction; -// // } -// // // Геттеры -// // -// // int getNumerator() const { -// // return m_numerator; -// // } -// // -// // int getDenominator() const { -// // return m_denominator; -// // } -// -// -// // // Наибольший общий делитель -// // // (англ.) greatest common divisor -// // -// // static int gcd(int a, int b) { -// // while (b > 0) { -// // int c = a % b; -// // a = b; -// // b = c; -// // } -// // return a; -// // } -// // -// // // Наименьшее общее кратное -// // // (англ.) least common multiple -// // -// // static int lcm(int a, int b) { -// // return gcd(a, b) * a * b; -// // } -// //public void reduce () -// //{ -// // BigInteger num = BigInteger.valueOf(numerator); -// // int gcd = num.gcd(BigInteger.valueOf(denominator)).intValue(); -// // -// // this.denominator /= gcd; -// // this.numerator /= gcd; -// // -// //} -// -// Fraction& operator*(const Fraction &fraction) { -// LOG_RUNTIME("Not implemented!"); -// // m_numerator = m_numerator * fraction.getNumerator(); -// // m_denominator = m_denominator * fraction.getDenominator(); -// // reduce(); -// return *this; -// } -// -// Fraction& operator/(const Fraction &fraction) { -// LOG_RUNTIME("Not implemented!"); -// // m_numerator = m_numerator * fraction.getDenominator(); -// // m_denominator = m_denominator * fraction.getNumerator(); -// // reduce(); -// return *this; -// } -// -// Fraction& operator-(const Fraction &fraction) { -// LOG_RUNTIME("Not implemented!"); -// // int relNumerator = m_numerator * fraction.getDenominator(); -// // m_numerator = m_numerator * fraction.getDenominator() - m_denominator * fraction.getNumerator(); -// // m_denominator = gcd(m_denominator, fraction.getDenominator()); -// // reduce(); -// return *this; -// } -// -// Fraction& operator+(const Fraction &fraction) { -// LOG_RUNTIME("Not implemented!"); -// // int unionDenominator = lcm(m_denominator, fraction.getDenominator()); -// // int relNumerator = m_numerator * unionDenominator; -// // int mulNumerator = fraction.m_numerator * unionDenominator; -// // m_numerator = relNumerator * mulNumerator; -// // m_denominator = unionDenominator; -// // reduce(); -// return *this; -// } -//}; +#include +#include + +#include + +class BigNum { + SCOPE(private) : + BIGNUM *m_value; + BN_CTX *m_ctx; + bool m_is_init; +public: + +#define CHECK_INIT(value) if (!(value)->m_is_init) { LOG_RUNTIME("Fail init!!!"); } + + BigNum() : m_value(nullptr), m_ctx(nullptr) { + m_is_init = false; + m_value = BN_new(); + m_ctx = BN_CTX_new(); + } + + BigNum(std::string str) { + SetFromString(str); + } + + virtual ~BigNum() { + if (m_value) { + BN_free(m_value); + m_value = nullptr; + } + if (m_ctx) { + BN_CTX_free(m_ctx); + m_ctx = nullptr; + } + } + + int64_t GetAsInteger() { + CHECK_INIT(this); + + int64_t result = BN_get_word(m_value); + if (result == ~0) { + LOG_RUNTIME("Bignum integer overflow!"); + } + + if (BN_is_negative(m_value)) { + result = -result; + } + return result; + } + + double GetAsNumber() { + CHECK_INIT(this); + //@todo Refactor convert big integer to double! + return static_cast(GetAsInteger()); + } + + inline bool SetFromString(const std::string str) { + m_is_init = true; + return BN_dec2bn(&m_value, str.c_str()); + } + + std::string GetAsString() { + CHECK_INIT(this); + char * number_str = BN_bn2dec(m_value); + std::string result(number_str); + OPENSSL_free(number_str); + return result; + } + + BigNum &add(BigNum &val) { + CHECK_INIT(this); + CHECK_INIT(&val); + + BigNum temp; + if (!BN_add(temp.m_value, m_value, val.m_value)) { + LOG_RUNTIME("Bignum operation fail!"); + } + std::swap(temp.m_value, m_value); + return *this; + } + + BigNum &sub(BigNum &val) { + CHECK_INIT(this); + CHECK_INIT(&val); + + BigNum temp; + if (!BN_sub(temp.m_value, m_value, val.m_value)) { + LOG_RUNTIME("Bignum operation fail!"); + } + std::swap(temp.m_value, m_value); + return *this; + } + + BigNum &mul(BigNum &val) { + CHECK_INIT(this); + CHECK_INIT(&val); + + BigNum temp; + if (!BN_mul(temp.m_value, m_value, val.m_value, m_ctx)) { + LOG_RUNTIME("Bignum operation fail!"); + } + std::swap(temp.m_value, m_value); + return *this; + } + + BigNum &div(BigNum &val, BigNum &rem) { + CHECK_INIT(this); + CHECK_INIT(&val); + + BigNum dv; + BigNum rm; + if (!BN_div(dv.m_value, rm.m_value, m_value, val.m_value, m_ctx)) { + LOG_RUNTIME("Bignum operation fail!"); + } + std::swap(dv.m_value, m_value); + std::swap(rm.m_value, rem.m_value); + rem.m_is_init = true; + return *this; + } + +}; + +class Fraction { +private: + // Числитель + BigNum m_numerator; + // Знаменатель + BigNum m_denominator; + + // Функция нужна для сокращения дроби + void reduce(); +public: + // Конструктор принимает значения числителя и знаменателя + + Fraction(BigNum & numerator, BigNum &denominator) { + m_numerator = numerator; + m_denominator = denominator; + } + + Fraction(const std::string &numerator, const std::string &denominator) { + // m_numerator = numerator; + // m_denominator = denominator; + } + + // Fraction(const std::string &string) { + // // Выбрасываем исключение, если не задана строка + // assert(string == ""); + // // Ищем знак '/' + // int pos = string.find("/"); + // + // // Если символ не найден - то вся строка является числом + // if (pos == std::string::npos) { + // m_numerator = stoi(string); + // m_denominator = 1; + // } else { + // // Числитель - левая часть + // m_numerator = std::stoi(string.substr(0, pos)); + // // Знаменатель - правая часть + // m_denominator = std::stoi(string.substr(pos, string.length())); + // + // // Знаменатель не должен быть равен нулю + // assert(m_denominator == 0); + // } + // } + // // Возвращаем дробь в виде строки + // + // std::string toString() { + // std::string fraction = ""; + // if (m_numerator == 0) { + // fraction.append("0"); + // return fraction; + // } + // + // fraction.append(std::to_string(m_numerator)); + // if (m_denominator != 1) { + // fraction.append("/"); + // fraction.append(std::to_string(m_denominator)); + // } + // return fraction; + // } + // // Геттеры + // + // int getNumerator() const { + // return m_numerator; + // } + // + // int getDenominator() const { + // return m_denominator; + // } + + + // // Наибольший общий делитель + // // (англ.) greatest common divisor + // + // static int gcd(int a, int b) { + // while (b > 0) { + // int c = a % b; + // a = b; + // b = c; + // } + // return a; + // } + // + // // Наименьшее общее кратное + // // (англ.) least common multiple + // + // static int lcm(int a, int b) { + // return gcd(a, b) * a * b; + // } + //public void reduce () + //{ + // BigInteger num = BigInteger.valueOf(numerator); + // int gcd = num.gcd(BigInteger.valueOf(denominator)).intValue(); + // + // this.denominator /= gcd; + // this.numerator /= gcd; + // + //} + + Fraction& operator*(const Fraction &fraction) { + LOG_RUNTIME("Not implemented!"); + // m_numerator = m_numerator * fraction.getNumerator(); + // m_denominator = m_denominator * fraction.getDenominator(); + // reduce(); + return *this; + } + + Fraction& operator/(const Fraction &fraction) { + LOG_RUNTIME("Not implemented!"); + // m_numerator = m_numerator * fraction.getDenominator(); + // m_denominator = m_denominator * fraction.getNumerator(); + // reduce(); + return *this; + } + + Fraction& operator-(const Fraction &fraction) { + LOG_RUNTIME("Not implemented!"); + // int relNumerator = m_numerator * fraction.getDenominator(); + // m_numerator = m_numerator * fraction.getDenominator() - m_denominator * fraction.getNumerator(); + // m_denominator = gcd(m_denominator, fraction.getDenominator()); + // reduce(); + return *this; + } + + Fraction& operator+(const Fraction &fraction) { + LOG_RUNTIME("Not implemented!"); + // int unionDenominator = lcm(m_denominator, fraction.getDenominator()); + // int relNumerator = m_numerator * unionDenominator; + // int mulNumerator = fraction.m_numerator * unionDenominator; + // m_numerator = relNumerator * mulNumerator; + // m_denominator = unionDenominator; + // reduce(); + return *this; + } +}; #endif /* FRACTION_H */ diff --git a/src/newlang.h b/src/newlang.h index 989eeba2..4498652c 100644 --- a/src/newlang.h +++ b/src/newlang.h @@ -118,53 +118,78 @@ namespace newlang { static RuntimePtr Init(int argc = 0, const char** argv = nullptr, bool ignore_error = true) { RuntimePtr rt = std::make_shared(); + std::string ffi_file; + #ifdef _MSC_VER - rt->m_msys = LoadLibrary(L"msys-2.0.dll"); + + std::wstring sys_file; + std::string sys_init; + +//#define CYGWIN +#ifdef CYGWIN + sys_file = L"cygwin1.dll"; + sys_init = "cygwin_dll_init"; + ffi_file = "cygffi-6.dll"; +#else + sys_file = L"msys-2.0.dll"; + sys_init = "msys_dll_init"; + ffi_file = "libffi-7.dll"; +#endif + + rt->m_msys = LoadLibrary(sys_file.c_str()); if (!rt->m_msys) { - if!(ignore_error) { - LOG_RUNTIME("Fail LoadLibrary msys-2.0.dll: %s", RunTime::GetLastErrorMessage().c_str()); - } + LOG_RUNTIME("Fail LoadLibrary %s: %s", sys_file.c_str(), RunTime::GetLastErrorMessage().c_str()); } typedef void init_type(); - init_type *init = (init_type *) GetProcAddress(m_msys, "msys_dll_init"); + init_type *init = (init_type *) GetProcAddress((HMODULE) rt->m_msys, sys_init.c_str()); if (rt->m_msys && !init) { - if!(ignore_error) { - FreeLibrary(rt->m_msys); - LOG_RUNTIME("msys_dll_init not found! %s", RunTime::GetLastErrorMessage().c_str()); - } + FreeLibrary((HMODULE) rt->m_msys); + LOG_RUNTIME("Func %s not found! %s", sys_init.c_str(), RunTime::GetLastErrorMessage().c_str()); (*init)(); } + rt->m_ffi_handle = LoadLibrary(utf8_decode(ffi_file).c_str()); #else - rt->m_msys = dlopen("libffi.so", RTLD_NOW); + ffi_file = "libffi.so"; + rt->m_ffi_handle = dlopen(ffi_file.c_str(), RTLD_NOW); #endif - rt->m_ffi_type_void = static_cast (GetDirectAddressFromLibrary(rt->m_msys, "ffi_type_void")); - rt->m_ffi_type_uint8 = static_cast (GetDirectAddressFromLibrary(rt->m_msys, "ffi_type_uint8")); - rt->m_ffi_type_sint8 = static_cast (GetDirectAddressFromLibrary(rt->m_msys, "ffi_type_sint8")); - rt->m_ffi_type_uint16 = static_cast (GetDirectAddressFromLibrary(rt->m_msys, "ffi_type_uint16")); - rt->m_ffi_type_sint16 = static_cast (GetDirectAddressFromLibrary(rt->m_msys, "ffi_type_sint16")); - rt->m_ffi_type_uint32 = static_cast (GetDirectAddressFromLibrary(rt->m_msys, "ffi_type_uint32")); - rt->m_ffi_type_sint32 = static_cast (GetDirectAddressFromLibrary(rt->m_msys, "ffi_type_sint32")); - rt->m_ffi_type_uint64 = static_cast (GetDirectAddressFromLibrary(rt->m_msys, "ffi_type_uint64")); - rt->m_ffi_type_sint64 = static_cast (GetDirectAddressFromLibrary(rt->m_msys, "ffi_type_sint64")); - rt->m_ffi_type_float = static_cast (GetDirectAddressFromLibrary(rt->m_msys, "ffi_type_float")); - rt->m_ffi_type_double = static_cast (GetDirectAddressFromLibrary(rt->m_msys, "ffi_type_double")); - rt->m_ffi_type_pointer = static_cast (GetDirectAddressFromLibrary(rt->m_msys, "ffi_type_pointer")); - - rt->m_ffi_prep_cif = reinterpret_cast (GetDirectAddressFromLibrary(rt->m_msys, "ffi_prep_cif")); - rt->m_ffi_prep_cif_var = reinterpret_cast (GetDirectAddressFromLibrary(rt->m_msys, "ffi_prep_cif_var")); - rt->m_ffi_call = reinterpret_cast (GetDirectAddressFromLibrary(rt->m_msys, "ffi_call")); + if (!rt->m_ffi_handle) { + LOG_RUNTIME("Fail load %s!", ffi_file.c_str()); + } + + rt->m_ffi_type_void = static_cast (GetDirectAddressFromLibrary(rt->m_ffi_handle, "ffi_type_void")); + rt->m_ffi_type_uint8 = static_cast (GetDirectAddressFromLibrary(rt->m_ffi_handle, "ffi_type_uint8")); + rt->m_ffi_type_sint8 = static_cast (GetDirectAddressFromLibrary(rt->m_ffi_handle, "ffi_type_sint8")); + rt->m_ffi_type_uint16 = static_cast (GetDirectAddressFromLibrary(rt->m_ffi_handle, "ffi_type_uint16")); + rt->m_ffi_type_sint16 = static_cast (GetDirectAddressFromLibrary(rt->m_ffi_handle, "ffi_type_sint16")); + rt->m_ffi_type_uint32 = static_cast (GetDirectAddressFromLibrary(rt->m_ffi_handle, "ffi_type_uint32")); + rt->m_ffi_type_sint32 = static_cast (GetDirectAddressFromLibrary(rt->m_ffi_handle, "ffi_type_sint32")); + rt->m_ffi_type_uint64 = static_cast (GetDirectAddressFromLibrary(rt->m_ffi_handle, "ffi_type_uint64")); + rt->m_ffi_type_sint64 = static_cast (GetDirectAddressFromLibrary(rt->m_ffi_handle, "ffi_type_sint64")); + rt->m_ffi_type_float = static_cast (GetDirectAddressFromLibrary(rt->m_ffi_handle, "ffi_type_float")); + rt->m_ffi_type_double = static_cast (GetDirectAddressFromLibrary(rt->m_ffi_handle, "ffi_type_double")); + rt->m_ffi_type_pointer = static_cast (GetDirectAddressFromLibrary(rt->m_ffi_handle, "ffi_type_pointer")); + + rt->m_ffi_prep_cif = reinterpret_cast (GetDirectAddressFromLibrary(rt->m_ffi_handle, "ffi_prep_cif")); + rt->m_ffi_prep_cif_var = reinterpret_cast (GetDirectAddressFromLibrary(rt->m_ffi_handle, "ffi_prep_cif_var")); + rt->m_ffi_call = reinterpret_cast (GetDirectAddressFromLibrary(rt->m_ffi_handle, "ffi_call")); + + if (!(rt->m_ffi_type_uint8 && rt->m_ffi_type_sint8 && rt->m_ffi_type_uint16 && rt->m_ffi_type_sint16 && + rt->m_ffi_type_uint32 && rt->m_ffi_type_sint32 && rt->m_ffi_type_uint64 && rt->m_ffi_type_sint64 && + rt->m_ffi_type_float && rt->m_ffi_type_double && rt->m_ffi_type_pointer && rt->m_ffi_type_void && + rt->m_ffi_prep_cif && rt->m_ffi_prep_cif_var && rt->m_ffi_call)) { + LOG_RUNTIME("Fail init data from %s!", ffi_file.c_str()); + } return rt; } inline static void * GetDirectAddressFromLibrary(void *handle, const char * name) { #ifdef _MSC_VER - return static_cast (::GetProcAddress(handle, name)); + return static_cast (::GetProcAddress((HMODULE) handle, name)); #else - return dlsym(handle, name); #endif } @@ -178,11 +203,21 @@ namespace newlang { void * GetNativeAddr(const char * name, const char *module = nullptr); virtual ~RunTime() { + #ifdef _MSC_VER + if (m_ffi_handle) { + FreeLibrary((HMODULE) m_ffi_handle); + m_ffi_handle = nullptr; + } if (m_msys) { - FreeLibrary(m_msys); + FreeLibrary((HMODULE) m_msys); m_msys = nullptr; } +#else + if (m_ffi_handle) { + dlclose(m_ffi_handle); + m_ffi_handle = nullptr; + } #endif } @@ -201,9 +236,13 @@ namespace newlang { RunTime(const RunTime&) = delete; const RunTime& operator=(const RunTime&) = delete; +#ifdef _MSC_VER void * m_msys; +#endif + std::map m_modules; + void * m_ffi_handle; ffi_type * m_ffi_type_void; ffi_type * m_ffi_type_uint8; ffi_type * m_ffi_type_sint8; diff --git a/src/nlc.cpp b/src/nlc.cpp index ecd50995..8ed80ae4 100644 --- a/src/nlc.cpp +++ b/src/nlc.cpp @@ -10,18 +10,6 @@ using namespace newlang; #pragma comment(lib, "torch.lib") #pragma comment(lib, "torch_cpu.lib") #pragma comment(lib, "c10.lib") -#pragma comment(lib, "libffi.dll.a") - -//#pragma comment(lib, "pthreadpool.lib") -//#pragma comment(lib, "libprotoc.lib") -//#pragma comment(lib, "XNNPACK.lib") -//#pragma comment(lib, "dnnl.lib") -//#pragma comment(lib, "asmjit.lib") -//#pragma comment(lib, "cpuinfo.lib") -// -//#pragma comment(lib, "clog.lib") -//#pragma comment(lib, "fbgemm.lib") -//#pragma comment(lib, "kineto.lib") #endif diff --git a/src/object.cpp b/src/object.cpp index 8f1f498e..2bc3360d 100644 --- a/src/object.cpp +++ b/src/object.cpp @@ -2156,7 +2156,7 @@ bool newlang::ParsePrintfFormat(Obj *args, size_t start) { LOG_WARNING("Missing object!"); return false; } - if(args->size() <= start || !(*args)[start]) { + if(args->size() <= static_cast(start) || !(*args)[start]) { LOG_WARNING("Missing format string!"); return false; } diff --git a/src/pch.h b/src/pch.h index 951bc7cf..dab34ae5 100644 --- a/src/pch.h +++ b/src/pch.h @@ -28,36 +28,26 @@ #include #include #include -//#include #include - #include #include #include -#include #ifdef _MSC_VER #include -#include #include -#include -#include - -#pragma execution_character_set("utf-8") #else -#ifndef __WIN32__ #include #include -#endif - #include #endif +#include #include "warning_push.h" #include diff --git a/src/test/fraction_test.cpp b/src/test/fraction_test.cpp index daecac01..89b6b034 100644 --- a/src/test/fraction_test.cpp +++ b/src/test/fraction_test.cpp @@ -1,58 +1,58 @@ #include "pch.h" -//#ifdef UNITTEST -// -//#include "pch.h" -// -//#include -//#include -//#include -// -//#include -// -// -//TEST(ObjTest, BigNum) { -// -// BigNum dec; -// -// ASSERT_FALSE(dec.m_is_init); -// ASSERT_TRUE(dec.m_value); -// -// dec.SetFromString("123456789"); -// ASSERT_STREQ("123456789", dec.GetAsString().c_str()); -// ASSERT_EQ(123456789, dec.GetAsInteger()); -// ASSERT_EQ(123456789, dec.GetAsNumber()); -// -// BigNum dec2; -// dec2.SetFromString("-123456789"); -// ASSERT_STREQ("-123456789", dec2.GetAsString().c_str()); -// ASSERT_EQ(-123456789, dec2.GetAsInteger()); -// ASSERT_EQ(-123456789, dec2.GetAsNumber()); -// -// dec.add(dec2); -// ASSERT_STREQ("0", dec.GetAsString().c_str()); -// ASSERT_EQ(0, dec.GetAsInteger()); -// -// dec.sub(dec2); -// ASSERT_STREQ("123456789", dec.GetAsString().c_str()); -// ASSERT_EQ(123456789, dec.GetAsInteger()); -// -// -// BigNum dec3; -// dec3.SetFromString("123"); -// ASSERT_STREQ("123", dec3.GetAsString().c_str()); -// ASSERT_EQ(123, dec3.GetAsInteger()); -// -// dec.mul(dec3); -// ASSERT_STREQ("15185185047", dec.GetAsString().c_str()); -// ASSERT_EQ(15185185047, dec.GetAsInteger()); -// -// dec.div(dec2, dec3); -// ASSERT_STREQ("-123", dec.GetAsString().c_str()); -// ASSERT_EQ(-123, dec.GetAsInteger()); -// -// ASSERT_STREQ("0", dec3.GetAsString().c_str()); -// ASSERT_EQ(0, dec3.GetAsInteger()); -//} -// -//#endif \ No newline at end of file +#ifdef UNITTEST + +#include "pch.h" + +#include +#include +#include + +#include + + +TEST(ObjTest, BigNum) { + + BigNum dec; + + ASSERT_FALSE(dec.m_is_init); + ASSERT_TRUE(dec.m_value); + + dec.SetFromString("123456789"); + ASSERT_STREQ("123456789", dec.GetAsString().c_str()); + ASSERT_EQ(123456789, dec.GetAsInteger()); + ASSERT_EQ(123456789, dec.GetAsNumber()); + + BigNum dec2; + dec2.SetFromString("-123456789"); + ASSERT_STREQ("-123456789", dec2.GetAsString().c_str()); + ASSERT_EQ(-123456789, dec2.GetAsInteger()); + ASSERT_EQ(-123456789, dec2.GetAsNumber()); + + dec.add(dec2); + ASSERT_STREQ("0", dec.GetAsString().c_str()); + ASSERT_EQ(0, dec.GetAsInteger()); + + dec.sub(dec2); + ASSERT_STREQ("123456789", dec.GetAsString().c_str()); + ASSERT_EQ(123456789, dec.GetAsInteger()); + + + BigNum dec3; + dec3.SetFromString("123"); + ASSERT_STREQ("123", dec3.GetAsString().c_str()); + ASSERT_EQ(123, dec3.GetAsInteger()); + + dec.mul(dec3); + ASSERT_STREQ("15185185047", dec.GetAsString().c_str()); + ASSERT_EQ(15185185047, dec.GetAsInteger()); + + dec.div(dec2, dec3); + ASSERT_STREQ("-123", dec.GetAsString().c_str()); + ASSERT_EQ(-123, dec.GetAsInteger()); + + ASSERT_STREQ("0", dec3.GetAsString().c_str()); + ASSERT_EQ(0, dec3.GetAsInteger()); +} + +#endif \ No newline at end of file diff --git a/src/win/nlc.vcxproj b/src/win/nlc.vcxproj index 9093925e..e8222300 100644 --- a/src/win/nlc.vcxproj +++ b/src/win/nlc.vcxproj @@ -104,11 +104,10 @@ nlc_unit_test - $(VC_IncludePath);$(WindowsSDK_IncludePath);..;../..;../../..;../../contrib/;../../contrib/googletest/googletest;../../contrib/googletest/googletest/include;../../contrib/Lyra/include;../../contrib/libtorch-win/include;../../contrib/libtorch-win/include/torch/csrc/api/include;../../contrib/tensorboard_logger/include;../../contrib/libffi/win64/include + $(VC_IncludePath);$(WindowsSDK_IncludePath);..;../..;../../..;../../contrib/;../../contrib/googletest/googletest;../../contrib/googletest/googletest/include;../../contrib/Lyra/include;../../contrib/libtorch-win/include;../../contrib/libtorch-win/include/torch/csrc/api/include;../../contrib/tensorboard_logger/include;C:\msys64\usr\include;C:\Program Files\OpenSSL-Win64\include ..\..\contrib\libffi\win64\lib;..\..\contrib\libtorch-win\lib;$(LibraryPath) ..\..\output\ nlc_unit_test - false @@ -192,6 +191,7 @@ Console true %(AdditionalLibraryDirectories) + C:\Program Files\OpenSSL-Win64\lib\libcrypto_static.lib;Ws2_32.lib;%(AdditionalDependencies) From 96884352514651f44df784c9982bb88d0a939a9c Mon Sep 17 00:00:00 2001 From: Aleksandr Ryabikov Date: Mon, 4 Jul 2022 13:28:57 +0300 Subject: [PATCH 13/31] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D1=8B=20=D0=B4=D0=BB=D0=B8=D0=BD=D0=BD=D1=8B=D0=B5?= =?UTF-8?q?=20=D1=87=D0=B8=D1=81=D0=BB=D0=B0=20=D0=B2=20=D0=B2=D0=B8=D0=B4?= =?UTF-8?q?=D0=B5=20=D0=B4=D1=80=D0=BE=D0=B1=D0=B5=D0=B9=20(=D1=87=D0=B8?= =?UTF-8?q?=D1=81=D0=BB=D0=B8=D1=82=D0=B5=D0=BB=D1=8C\=D0=B7=D0=BD=D0=B0?= =?UTF-8?q?=D0=BC=D0=B5=D0=BD=D0=B0=D1=82=D0=B5=D0=BB=D1=8C)=20+=20=D0=BF?= =?UTF-8?q?=D1=80=D0=BE=D0=B2=D0=B5=D1=80=D0=BA=D0=B0=20=D1=81=D1=82=D1=80?= =?UTF-8?q?=D0=BE=D0=BA=D0=B8=20=D1=84=D0=BE=D1=80=D0=BC=D0=B0=D1=82=D0=B0?= =?UTF-8?q?=20=D0=B1=D0=B5=D0=B7=20=D0=B8=D1=81=D0=BF=D0=BE=D0=BB=D1=8C?= =?UTF-8?q?=D0=B7=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D1=8F=20parse=5Fprintf=5Ff?= =?UTF-8?q?ormat=20=D0=B8=D0=B7-=D0=B7=D0=B0=20=D0=B5=D1=91=20=D0=BE=D1=82?= =?UTF-8?q?=D1=81=D1=83=D1=82=D1=81=D1=82=D0=B2=D0=B8=D1=8F=20=D0=B2=20Win?= =?UTF-8?q?dows?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 1 + src/context.cpp | 23 +- src/fraction.h | 506 ++++++++++++++++++++----------------- src/lexer.l | 38 ++- src/object.cpp | 291 +++++++++++++-------- src/object.h | 88 ++++--- src/parser.y | 8 +- src/term.h | 14 +- src/test/eval_test.cpp | 35 ++- src/test/fraction_test.cpp | 19 +- src/test/object_test.cpp | 39 +++ src/test/parser_test.cpp | 26 +- src/types.h | 53 +++- 13 files changed, 724 insertions(+), 417 deletions(-) diff --git a/.gitignore b/.gitignore index 2839195e..a8a92d86 100644 --- a/.gitignore +++ b/.gitignore @@ -21,6 +21,7 @@ Makefile docs/syntax.txt output **/*temp* +**/.vs # Binaries diff --git a/src/context.cpp b/src/context.cpp index 6b7d173c..6b68e527 100644 --- a/src/context.cpp +++ b/src/context.cpp @@ -68,6 +68,7 @@ Context::Context(RuntimePtr global) { VERIFY(RegisterTypeHierarchy(ObjType::Any,{})); VERIFY(RegisterTypeHierarchy(ObjType::Arithmetic,{":Any"})); + VERIFY(RegisterTypeHierarchy(ObjType::Fraction,{":Arithmetic"})); VERIFY(RegisterTypeHierarchy(ObjType::Tensor,{":Arithmetic"})); VERIFY(RegisterTypeHierarchy(ObjType::Integer,{":Tensor"})); @@ -85,10 +86,6 @@ Context::Context(RuntimePtr global) { VERIFY(RegisterTypeHierarchy(ObjType::ComplexFloat,{":Complex"})); VERIFY(RegisterTypeHierarchy(ObjType::ComplexDouble,{":Complex"})); - VERIFY(RegisterTypeHierarchy(ObjType::BigNum,{":Arithmetic"})); - VERIFY(RegisterTypeHierarchy(ObjType::Fraction,{":Arithmetic"})); - VERIFY(RegisterTypeHierarchy(ObjType::Currency,{":Arithmetic"})); - VERIFY(RegisterTypeHierarchy(ObjType::String,{":Any"})); VERIFY(RegisterTypeHierarchy(ObjType::StrChar,{":String"})); VERIFY(RegisterTypeHierarchy(ObjType::StrWide,{":String"})); @@ -389,7 +386,7 @@ inline ObjPtr Context::eval_COMPLEX(Context *ctx, const TermPtr &term, Obj *args return CreateRVal(ctx, term, args); } -inline ObjPtr Context::eval_CURRENCY(Context *ctx, const TermPtr &term, Obj *args) { +inline ObjPtr Context::eval_EVAL(Context *ctx, const TermPtr &term, Obj *args) { return CreateRVal(ctx, term, args); } @@ -811,7 +808,7 @@ ObjPtr Context::eval_FOLLOW(Context *ctx, const TermPtr &term, Obj * args) { * */ - for (int64_t i = 0; i < static_cast(term->m_follow.size()); i++) { + for (int64_t i = 0; i < static_cast (term->m_follow.size()); i++) { ASSERT(term->m_follow[i]->Left()); ObjPtr cond = ExecStr(ctx, term->m_follow[i]->Left(), args, false); @@ -1536,7 +1533,11 @@ void *RunTime::GetNativeAddr(const char *name, const char *module) { #ifndef _MSC_VER return dlsym(nullptr, name); #else - return static_cast(::GetProcAddress((HMODULE)m_msys, name)); + void *result = static_cast (::GetProcAddress(GetModuleHandle(nullptr), name)); + if(result) { + return result; + } + return static_cast (::GetProcAddress((HMODULE) m_msys, name)); #endif } @@ -2059,6 +2060,10 @@ ObjPtr Context::CreateRVal(Context *ctx, TermPtr term, Obj * local_vars, bool in return result; + case TermID::EVAL: + return ctx->ExecStr(term->m_text.c_str(), local_vars, false); + + case TermID::TYPE: case TermID::TYPE_CALL: @@ -2265,6 +2270,10 @@ ObjPtr Context::CreateRVal(Context *ctx, TermPtr term, Obj * local_vars, bool in result->m_var_is_init = true; return result; + + case TermID::FRACTION: + return Obj::CreateFraction(term->m_text); + } LOG_RUNTIME("Fail create type %s from '%s'", newlang::toString(term->getTermID()), term->toString().c_str()); diff --git a/src/fraction.h b/src/fraction.h index cb7cc379..116c70e2 100644 --- a/src/fraction.h +++ b/src/fraction.h @@ -6,255 +6,297 @@ #include -class BigNum { - SCOPE(private) : - BIGNUM *m_value; - BN_CTX *m_ctx; - bool m_is_init; -public: - -#define CHECK_INIT(value) if (!(value)->m_is_init) { LOG_RUNTIME("Fail init!!!"); } - - BigNum() : m_value(nullptr), m_ctx(nullptr) { - m_is_init = false; - m_value = BN_new(); - m_ctx = BN_CTX_new(); - } - - BigNum(std::string str) { - SetFromString(str); - } - - virtual ~BigNum() { - if (m_value) { - BN_free(m_value); - m_value = nullptr; +#include "pch.h" + +namespace newlang { + + struct BigNum { + BIGNUM *value; + + BigNum() : value(BN_new()) { + ASSERT(value); } - if (m_ctx) { - BN_CTX_free(m_ctx); - m_ctx = nullptr; + + BigNum(const unsigned long var) : BigNum() { + BN_set_word(value, var); } - } - int64_t GetAsInteger() { - CHECK_INIT(this); + BigNum(const std::string str) : BigNum() { + SetFromString(str); + } + + BigNum(const BigNum ©) : BigNum() { + VERIFY(BN_copy(value, copy.value)); + } + BigNum& operator=(const BigNum&) = delete; // Disallow copying - int64_t result = BN_get_word(m_value); - if (result == ~0) { - LOG_RUNTIME("Bignum integer overflow!"); + virtual ~BigNum() { + if (value) { + BN_free(value); + value = nullptr; + } } - if (BN_is_negative(m_value)) { - result = -result; + struct CtxHelper { + BN_CTX *ctx; + + CtxHelper() : ctx(BN_CTX_new()) { + ASSERT(ctx); + } + + ~CtxHelper() { + if (ctx) { + BN_CTX_free(ctx); + ctx = nullptr; + } + } + }; + + int64_t GetAsInteger() const { + if (isOverflow()) { + LOG_RUNTIME("BigNum integer overflow!"); + } + + int64_t result = BN_get_word(value); + if (BN_is_negative(value)) { + result = -result; + } + return result; } - return result; - } - - double GetAsNumber() { - CHECK_INIT(this); - //@todo Refactor convert big integer to double! - return static_cast(GetAsInteger()); - } - - inline bool SetFromString(const std::string str) { - m_is_init = true; - return BN_dec2bn(&m_value, str.c_str()); - } - - std::string GetAsString() { - CHECK_INIT(this); - char * number_str = BN_bn2dec(m_value); - std::string result(number_str); - OPENSSL_free(number_str); - return result; - } - - BigNum &add(BigNum &val) { - CHECK_INIT(this); - CHECK_INIT(&val); - - BigNum temp; - if (!BN_add(temp.m_value, m_value, val.m_value)) { - LOG_RUNTIME("Bignum operation fail!"); + + /* + * Конвертировать длинное целое в число с плавающей точкой (с потерей точности) + */ + double GetAsNumber() const { + int num_bits = BN_num_bits(value); + + if (num_bits <= 52) { // Размер мантиссы double + ASSERT(!isOverflow()); + // Точности мантисы хватает для хранения всех значащих бит длинного числа + return static_cast (GetAsInteger()); + } else { + BigNum temp(*this); + + BigNum one; + one.SetOne(); + + BigNum divider; + BN_lshift(divider.value, one.value, num_bits - 52); + + BigNum remander; + temp.div(divider, remander); + + ASSERT(!temp.isOverflow()); + double result = static_cast (temp.GetAsInteger()); + + result *= std::pow(2, num_bits - 52); + return result; + } + /* + 1 \ / 2 3 + 123456789123465789123456789123465789 + 123456789123465786113767616146309120.000000 + */ } - std::swap(temp.m_value, m_value); - return *this; - } - BigNum &sub(BigNum &val) { - CHECK_INIT(this); - CHECK_INIT(&val); + inline bool SetFromString(const std::string str) { + if (!BN_dec2bn(&value, str.c_str())) { + LOG_RUNTIME("Fail create BinNum from string '%s'!", str.c_str()); + } + return value; + } - BigNum temp; - if (!BN_sub(temp.m_value, m_value, val.m_value)) { - LOG_RUNTIME("Bignum operation fail!"); + std::string GetAsString() const { + char * number_str = BN_bn2dec(value); + std::string result(number_str); + OPENSSL_free(number_str); + return result; } - std::swap(temp.m_value, m_value); - return *this; - } - BigNum &mul(BigNum &val) { - CHECK_INIT(this); - CHECK_INIT(&val); + BigNum &add(const BigNum &val) { + const BigNum temp(*this); + if (!BN_add(value, temp.value, val.value)) { + LOG_RUNTIME("BN_add operation fail!"); + } + return *this; + } - BigNum temp; - if (!BN_mul(temp.m_value, m_value, val.m_value, m_ctx)) { - LOG_RUNTIME("Bignum operation fail!"); + BigNum &sub(const BigNum &val) { + const BigNum temp(*this); + if (!BN_sub(value, temp.value, val.value)) { + LOG_RUNTIME("BN_sub operation fail!"); + } + return *this; } - std::swap(temp.m_value, m_value); - return *this; - } - - BigNum &div(BigNum &val, BigNum &rem) { - CHECK_INIT(this); - CHECK_INIT(&val); - - BigNum dv; - BigNum rm; - if (!BN_div(dv.m_value, rm.m_value, m_value, val.m_value, m_ctx)) { - LOG_RUNTIME("Bignum operation fail!"); + + BigNum &mul(const BigNum &val) { + CtxHelper ctx; + const BigNum temp(*this); + if (!BN_mul(value, temp.value, val.value, ctx.ctx)) { + LOG_RUNTIME("BN_mul operation fail!"); + } + return *this; } - std::swap(dv.m_value, m_value); - std::swap(rm.m_value, rem.m_value); - rem.m_is_init = true; - return *this; - } -}; + BigNum &div(const BigNum &val, BigNum &rem) { + CtxHelper ctx; + const BigNum temp(*this); + if (!BN_div(value, rem.value, temp.value, val.value, ctx.ctx)) { + LOG_RUNTIME("BN_div operation fail!"); + } + return *this; + } -class Fraction { -private: - // Числитель - BigNum m_numerator; - // Знаменатель - BigNum m_denominator; - - // Функция нужна для сокращения дроби - void reduce(); -public: - // Конструктор принимает значения числителя и знаменателя - - Fraction(BigNum & numerator, BigNum &denominator) { - m_numerator = numerator; - m_denominator = denominator; - } - - Fraction(const std::string &numerator, const std::string &denominator) { - // m_numerator = numerator; - // m_denominator = denominator; - } - - // Fraction(const std::string &string) { - // // Выбрасываем исключение, если не задана строка - // assert(string == ""); - // // Ищем знак '/' - // int pos = string.find("/"); - // - // // Если символ не найден - то вся строка является числом - // if (pos == std::string::npos) { - // m_numerator = stoi(string); - // m_denominator = 1; - // } else { - // // Числитель - левая часть - // m_numerator = std::stoi(string.substr(0, pos)); - // // Знаменатель - правая часть - // m_denominator = std::stoi(string.substr(pos, string.length())); - // - // // Знаменатель не должен быть равен нулю - // assert(m_denominator == 0); - // } - // } - // // Возвращаем дробь в виде строки - // - // std::string toString() { - // std::string fraction = ""; - // if (m_numerator == 0) { - // fraction.append("0"); - // return fraction; - // } - // - // fraction.append(std::to_string(m_numerator)); - // if (m_denominator != 1) { - // fraction.append("/"); - // fraction.append(std::to_string(m_denominator)); - // } - // return fraction; - // } - // // Геттеры - // - // int getNumerator() const { - // return m_numerator; - // } - // - // int getDenominator() const { - // return m_denominator; - // } - - - // // Наибольший общий делитель - // // (англ.) greatest common divisor - // - // static int gcd(int a, int b) { - // while (b > 0) { - // int c = a % b; - // a = b; - // b = c; - // } - // return a; - // } - // - // // Наименьшее общее кратное - // // (англ.) least common multiple - // - // static int lcm(int a, int b) { - // return gcd(a, b) * a * b; - // } - //public void reduce () - //{ - // BigInteger num = BigInteger.valueOf(numerator); - // int gcd = num.gcd(BigInteger.valueOf(denominator)).intValue(); - // - // this.denominator /= gcd; - // this.numerator /= gcd; - // - //} - - Fraction& operator*(const Fraction &fraction) { - LOG_RUNTIME("Not implemented!"); - // m_numerator = m_numerator * fraction.getNumerator(); - // m_denominator = m_denominator * fraction.getDenominator(); - // reduce(); - return *this; - } - - Fraction& operator/(const Fraction &fraction) { - LOG_RUNTIME("Not implemented!"); - // m_numerator = m_numerator * fraction.getDenominator(); - // m_denominator = m_denominator * fraction.getNumerator(); - // reduce(); - return *this; - } - - Fraction& operator-(const Fraction &fraction) { - LOG_RUNTIME("Not implemented!"); - // int relNumerator = m_numerator * fraction.getDenominator(); - // m_numerator = m_numerator * fraction.getDenominator() - m_denominator * fraction.getNumerator(); - // m_denominator = gcd(m_denominator, fraction.getDenominator()); - // reduce(); - return *this; - } - - Fraction& operator+(const Fraction &fraction) { - LOG_RUNTIME("Not implemented!"); - // int unionDenominator = lcm(m_denominator, fraction.getDenominator()); - // int relNumerator = m_numerator * unionDenominator; - // int mulNumerator = fraction.m_numerator * unionDenominator; - // m_numerator = relNumerator * mulNumerator; - // m_denominator = unionDenominator; - // reduce(); - return *this; - } -}; + inline void SetOne() { + BN_one(value); + } + + inline void SetZero() { + BN_zero(value); + } + + inline bool isOverflow() const { + return BN_get_word(value) == ~0; + } + + inline bool isZero() const { + return BN_is_zero(value); + } + + inline bool isOne() const { + return BN_is_one(value); + } + + inline bool isNegative() const { + return BN_is_negative(value); + } + + }; + + class Fraction { + public: + + BigNum m_numerator; // Числитель + BigNum m_denominator; // Знаменатель + // Функция нужна для сокращения дроби + void reduce(); + public: + // Конструктор принимает значения числителя и знаменателя + + Fraction() : Fraction("0", "1") { + } + + Fraction(const unsigned long value) : Fraction() { + BN_set_word(m_numerator.value, value); + } + + Fraction(const Fraction ©) : m_numerator(copy.m_numerator), m_denominator(copy.m_denominator) { + } + + Fraction(const std::string numerator, const std::string denominator) { + m_numerator.SetFromString(numerator); + m_denominator.SetFromString(denominator); + } + + std::string GetAsString() const { + std::string result = m_numerator.GetAsString(); + result += "\\"; + result += m_denominator.GetAsString(); + return result; + } + + int64_t GetAsInteger() const { + if (m_denominator.isZero()) { + LOG_RUNTIME("Denominator must be different from zero!"); + } + + if (m_denominator.isOne()) { + return m_numerator.GetAsInteger(); + } + + BigNum result = m_numerator; + + BigNum rem; + result.div(m_denominator, rem); + + return result.GetAsInteger(); + } + + double GetAsNumber() const { + if (m_denominator.isZero()) { + LOG_RUNTIME("Denominator must be different from zero!"); + } + if (m_denominator.isOne()) { + return m_numerator.GetAsNumber(); + } + return m_numerator.GetAsNumber() / m_denominator.GetAsNumber(); + } + + // // Наибольший общий делитель + // // (англ.) greatest common divisor + // + // static int gcd(int a, int b) { + // while (b > 0) { + // int c = a % b; + // a = b; + // b = c; + // } + // return a; + // } + // + // // Наименьшее общее кратное + // // (англ.) least common multiple + // + // static int lcm(int a, int b) { + // return gcd(a, b) * a * b; + // } + //public void reduce () + //{ + // BigInteger num = BigInteger.valueOf(numerator); + // int gcd = num.gcd(BigInteger.valueOf(denominator)).intValue(); + // + // this.denominator /= gcd; + // this.numerator /= gcd; + // + //} + + Fraction& operator*(const Fraction &fraction) { + LOG_RUNTIME("Not implemented!"); + // m_numerator = m_numerator * fraction.getNumerator(); + // m_denominator = m_denominator * fraction.getDenominator(); + // reduce(); + return *this; + } + + Fraction& operator/(const Fraction &fraction) { + LOG_RUNTIME("Not implemented!"); + // m_numerator = m_numerator * fraction.getDenominator(); + // m_denominator = m_denominator * fraction.getNumerator(); + // reduce(); + return *this; + } + + Fraction& operator-(const Fraction &fraction) { + LOG_RUNTIME("Not implemented!"); + // int relNumerator = m_numerator * fraction.getDenominator(); + // m_numerator = m_numerator * fraction.getDenominator() - m_denominator * fraction.getNumerator(); + // m_denominator = gcd(m_denominator, fraction.getDenominator()); + // reduce(); + return *this; + } + + Fraction& operator+(const Fraction &fraction) { + LOG_RUNTIME("Not implemented!"); + // int unionDenominator = lcm(m_denominator, fraction.getDenominator()); + // int relNumerator = m_numerator * unionDenominator; + // int mulNumerator = fraction.m_numerator * unionDenominator; + // m_numerator = relNumerator * mulNumerator; + // m_denominator = unionDenominator; + // reduce(); + return *this; + } + }; +}; #endif /* FRACTION_H */ diff --git a/src/lexer.l b/src/lexer.l index d535ef2b..0ddeca4a 100644 --- a/src/lexer.l +++ b/src/lexer.l @@ -67,7 +67,6 @@ ualpha {alpha}|{U2}{U1}|{U3}{U1}{U1}|{U4}{U1}{U1}{U1} digit [0-9] integer {digit}([_]?{digit}+)* -currency -?`{digit}(`?{digit}+)* name ({ualpha}|[_])({ualpha}|{digit}|[_])* macro \\({ualpha}|[_])?({name})? @@ -95,6 +94,7 @@ term [$@%]({ualpha}|[_])?({name})? %x state_COMMENT %x state_SOURCE %x state_MACRO +%x state_EVAL %% /*** Regular Expressions Part ***/ @@ -279,11 +279,6 @@ term [$@%]({ualpha}|[_])?({name})? } /* End of state_STRWIDE state*/ -' { /* Start state state_STRCHAR */ - BEGIN(state_STRCHAR); - buffer.clear(); -} - "r'" { BEGIN(state_STRCHAR_RAW); buffer.clear(); @@ -293,6 +288,12 @@ term [$@%]({ualpha}|[_])?({name})? . buffer.append(yytext, yyleng); } + +' { /* Start state state_STRCHAR */ + BEGIN(state_STRCHAR); + buffer.clear(); +} + { ' { /* saw closing quote - all done */ @@ -339,11 +340,34 @@ term [$@%]({ualpha}|[_])?({name})? } /* End of state_STRCHAR state*/ +"`" { /* Start state state_EVAL */ + BEGIN(state_EVAL); + buffer.clear(); +} + +{ + +"`" { + BEGIN(INITIAL); + *yylval = Term::Create(TermID::EVAL, buffer.c_str(), buffer.size(), yylloc, source_string); + return token::EVAL; + } + +\n { + /* generate error message */ + YY_FATAL_ERROR("Unterminated eval string"); + } + +. buffer.append(yytext, yyleng); + + +} /* End of state_EVAL state*/ + + -?{number}[-+]{number}j | {number}j YY_TOKEN(COMPLEX); -?{number}[-+]{number}i | {number}i YY_TOKEN(COMPLEX); -?{integer}\\-?{integer} YY_TOKEN(FRACTION); -?{integer} YY_TOKEN(INTEGER); -{currency} YY_TOKEN(CURRENCY); {number} YY_TOKEN(NUMBER); "::" YY_TOKEN(NAMESPACE); diff --git a/src/object.cpp b/src/object.cpp index 2bc3360d..bc30b8b6 100644 --- a/src/object.cpp +++ b/src/object.cpp @@ -521,6 +521,10 @@ void Obj::CloneDataTo(Obj & clone) const { clone.m_str = m_str; clone.m_wstr = m_wstr; + if(m_fraction) { + clone.m_fraction = std::make_shared(*m_fraction.get()); + } + clone.m_class_parents = m_class_parents; clone.m_class_name = m_class_name; // clone.m_ctx = m_ctx; @@ -767,6 +771,11 @@ std::string Obj::toString(bool deep) const { case ObjType::Ellipsis: result += "..."; return result; + + case ObjType::Fraction: + ASSERT(m_fraction); + result += m_fraction->GetAsString(); + return result; } } LOG_RUNTIME("Unknown type '%s' (%d)", newlang::toString(m_var_type_current), (int) m_var_type_current); @@ -913,6 +922,11 @@ std::string Obj::GetValueAsString() const { case ObjType::Range: result += toString(); return result; + + case ObjType::Fraction: + ASSERT(m_fraction); + result += m_fraction->GetAsString(); + return result; } LOG_RUNTIME("Data type '%s' %d incompatible to string!", newlang::toString(m_var_type_current), (int) m_var_type_current); } @@ -1605,14 +1619,23 @@ void Obj::toType_(ObjType target) { ConvertTensorToDict(m_value, *this); m_value.reset(); return; + } else if(target == ObjType::Fraction) { + if(!is_scalar()) { + LOG_RUNTIME("Fraction convert support for scalar only!"); + } + m_fraction = std::make_shared(GetValueAsInteger()); + m_value.reset(); + m_var_type_current = target; + return; } } else if(is_string_type()) { // Из строки в другой тип данных - if(isString(target)) { - // Строки хранятся в байтовом представлении и их ненужно конвертировать - m_var_type_current = target; - return; - } else if(isTensor(target)) { + // if(isString(target)) { + // // Строки хранятся в байтовом представлении и их ненужно конвертировать + // m_var_type_current = target; + // return; + // } else + if(isTensor(target)) { // Сконвертировать строку в тензор torch::Tensor std_data; std::wstring_convert < std::codecvt_utf8, wchar_t> converter; @@ -1652,6 +1675,12 @@ void Obj::toType_(ObjType target) { m_str.clear(); m_wstr.clear(); return; + } else if(target == ObjType::Fraction) { + m_fraction = std::make_shared(GetValueAsString(), "1"); + m_var_type_current = target; + m_str.clear(); + m_wstr.clear(); + return; } } else if(is_dictionary_type()) { @@ -2023,9 +2052,7 @@ ObjPtr Obj::CallNative(Context *ctx, Obj args) { m_args_val.push_back(temp); break; - case ObjType::StrWide: case ObjType::StrChar: - ASSERT(type == ObjType::StrChar); if(pind < check_count) { NL_CHECK(!(*m_func_proto)[pind]->m_type_name.empty(), "Undefined type arg '%s'", (*m_func_proto)[pind]->toString().c_str()); NL_CHECK(canCast(type, typeFromString((*m_func_proto)[pind]->m_type_name, ctx)), "Fail cast from '%s' to '%s'", @@ -2036,6 +2063,17 @@ ObjPtr Obj::CallNative(Context *ctx, Obj args) { m_args_val.push_back(temp); break; + case ObjType::StrWide: + if(pind < check_count) { + NL_CHECK(!(*m_func_proto)[pind]->m_type_name.empty(), "Undefined type arg '%s'", (*m_func_proto)[pind]->toString().c_str()); + NL_CHECK(canCast(type, typeFromString((*m_func_proto)[pind]->m_type_name, ctx)), "Fail cast from '%s' to '%s'", + (*m_func_proto)[pind]->m_type_name.c_str(), newlang::toString(type)); + } + m_args_type.push_back(ctx->m_runtime->m_ffi_type_pointer); + temp.ptr = args[i]->m_wstr.c_str(); + m_args_val.push_back(temp); + break; + case ObjType::Pointer: if(pind < check_count) { NL_CHECK(!(*m_func_proto)[pind]->m_type_name.empty(), "Undefined type arg '%s'", (*m_func_proto)[pind]->toString().c_str()); @@ -2156,7 +2194,7 @@ bool newlang::ParsePrintfFormat(Obj *args, size_t start) { LOG_WARNING("Missing object!"); return false; } - if(args->size() <= static_cast(start) || !(*args)[start]) { + if(args->size() <= static_cast (start) || !(*args)[start]) { LOG_WARNING("Missing format string!"); return false; } @@ -2165,100 +2203,127 @@ bool newlang::ParsePrintfFormat(Obj *args, size_t start) { return false; } - //std::string format = (*args)[start]->GetValueAsString(); - //size_t count = parse_printf_format(format.c_str(), 0, nullptr); - //std::vector types(count); - - //parse_printf_format(format.c_str(), types.size(), types.data()); - //bool result = true; - //unsigned i = 0; - //unsigned aind = start + 1; - //ObjType cast; - //while(i < types.size()) { - - // if(aind < args->size()) { - // // if(types[i] & PA_FLAG_PTR == PA_FLAG_PTR) { - // // LOG_WARNING("Pointer arg '%u' not suppotred!", i); - // // result = false; - // // i++; - // // aind++; - // // continue; - // // } - // switch(types[i] & ~PA_FLAG_MASK) { - // case PA_INT: - // if((types[i] & PA_FLAG_MASK) == 0) { - // cast = ObjType::Int; - // } else if(((types[i] & PA_FLAG_LONG) == PA_FLAG_LONG) || ((types[i] & PA_FLAG_LONG) == PA_FLAG_LONG_LONG)) { - // cast = ObjType::Long; - // } else if((types[i] & PA_FLAG_SHORT) == PA_FLAG_SHORT) { - // cast = ObjType::Short; - // } else { - // LOG_WARNING("Format flag at pos %d unrecognized! %s", i, format.c_str()); - // result = false; - // } - // if(!canCast((*args)[aind]->m_var_type_current, cast)) { - // LOG_WARNING("Cast '%s' to '%s' not supported!", newlang::toString((*args)[aind]->m_var_type_current), - // newlang::toString(cast)); - // result = false; - // } - // break; - // case PA_CHAR: - // if(types[i] & PA_FLAG_MASK) { - // LOG_WARNING("format modifier arg '%s' %u not supported!", newlang::toString((*args)[aind]->m_var_type_current), i); - // result = false; - // } - // cast = ObjType::Char; - // if(!canCast((*args)[aind]->m_var_type_current, cast)) { - // LOG_WARNING("Cast '%s' to '%s' not supported!", newlang::toString((*args)[aind]->m_var_type_current), - // newlang::toString(cast)); - // result = false; - // } - // break; - // case PA_STRING: - // if(types[i] & PA_FLAG_MASK) { - // LOG_WARNING("format modifier arg '%s' %u not supported!", newlang::toString((*args)[aind]->m_var_type_current), i); - // result = false; - // } - // cast = ObjType::StrChar; - // if(!canCast((*args)[aind]->m_var_type_current, cast)) { - // LOG_WARNING("Cast '%s' to '%s' not supported!", newlang::toString((*args)[aind]->m_var_type_current), - // newlang::toString(cast)); - // result = false; - // } - // break; - // case PA_FLOAT: - // case PA_DOUBLE: - // if(types[i] & PA_FLAG_MASK) { - // LOG_WARNING("format modifier arg '%s' %u not supported!", newlang::toString((*args)[aind]->m_var_type_current), i); - // result = false; - // } - // cast = ObjType::Double; - // if(!canCast((*args)[aind]->m_var_type_current, cast)) { - // LOG_WARNING("Cast '%s' to '%s' not supported!", newlang::toString((*args)[aind]->m_var_type_current), - // newlang::toString(cast)); - // result = false; - // } - // break; - // default: - // LOG_WARNING("Arg '%u' not supported!", i); - // // PA_WCHAR, /* wide char */ - // // PA_WSTRING, /* const wchar_t *, wide character string */ - // // PA_POINTER, /* void * */ - // result = false; - // } - // } else { - // LOG_WARNING("Missing argument %u", i); - // return false; - // } - // i++; - // aind++; - //} - //if(aind != args->size()) { - // LOG_WARNING("Extra arguments more %u", i); - // return false; - //} - //return result; - return true; + std::string format = (*args)[start]->GetValueAsString(); + + + static const std::string flags_list = "-+0123456789.lLh"; // '#', '*' + static const std::string types_list = "diufFeEgGxXaAoscp"; //, 'n' + + static std::string valid_chars; + if(valid_chars.empty()) { + valid_chars.append(flags_list); + valid_chars.append(types_list); + } + + bool result = true; + int aind = start + 1; + + size_t pos = 0; + while(pos < format.length()) { + pos = format.find_first_of('%', pos); + if(pos == format.npos) { + break; + } + pos++; + if(format[pos] == '%' || !format[pos]) { + continue; + } + + if(aind >= args->size()) { + + LOG_WARNING("Missing argument %u", (int) pos); + return false; + + } else { + + pos = format.find_first_not_of(valid_chars, pos); + if(pos == format.npos) { + pos = format.length(); + } + pos--; + + ObjType cast = ObjType::None; + switch(format[pos]) { + + case 'a': //%a Шестнадцатеричное в виде 0xh.hhhhp+d (только С99) + case 'A': //%A Шестнадцатеричное в виде 0Xh.hhhhP+d (только С99) + case 'd': //%d Десятичное целое со знаком + case 'i': //%i Десятичное целое со знаком + case 'o': //%o Восьмеричное без знака + case 'u': //%u Десятичное целое без знака + case 'x': //%x Шестнадцатеричное без знака (буквы на нижнем регистре) + case 'X': //%X Шестнадцатеричное без знака (буквы на верхнем регистре) + cast = ObjType::Int; + if(pos && (format[pos - 1] == 'l' || format[pos - 1] == 'L')) { + cast = ObjType::Long; + } else if(pos && format[pos - 1] == 'h') { + cast = ObjType::Short; + } + if(!canCast((*args)[aind]->m_var_type_current, cast)) { + LOG_WARNING("Cast '%s' to '%s' not supported!", newlang::toString((*args)[aind]->m_var_type_current), newlang::toString(cast)); + result = false; + } + break; + + + case 'e'://%e Экспоненциальное представление ('е' на нижнем регистре) + case 'E'://%E Экспоненциальное представление ('Е' на верхнем регистре) + case 'f'://%f Десятичное с плавающей точкой + case 'g'://%g В зависимости от того, какой вывод будет короче, используется %е или %f + case 'G'://%G В зависимости от того, какой вывод будет короче, используется %Е или %F + + cast = ObjType::Double; + if(!canCast((*args)[aind]->m_var_type_current, cast)) { + LOG_WARNING("Cast '%s' to '%s' not supported!", newlang::toString((*args)[aind]->m_var_type_current), newlang::toString(cast)); + result = false; + } + break; + + case 'c': + cast = ObjType::Char; + if(pos && (format[pos - 1] == 'l' || format[pos - 1] == 'L')) { + cast = ObjType::Int; + } + if(!canCast((*args)[aind]->m_var_type_current, cast)) { + LOG_WARNING("Cast '%s' to '%s' not supported!", newlang::toString((*args)[aind]->m_var_type_current), newlang::toString(cast)); + result = false; + } + break; + + case 's': + cast = ObjType::StrChar; + if(pos && (format[pos - 1] == 'l' || format[pos - 1] == 'L')) { + cast = ObjType::StrWide; + } + if(!canCast((*args)[aind]->m_var_type_current, cast)) { + LOG_WARNING("Cast '%s' to '%s' not supported!", newlang::toString((*args)[aind]->m_var_type_current), newlang::toString(cast)); + result = false; + } + break; + + + case 'p': + cast = ObjType::Pointer; + if(!canCast((*args)[aind]->m_var_type_current, cast)) { + LOG_WARNING("Cast '%s' to '%s' not supported!", newlang::toString((*args)[aind]->m_var_type_current), newlang::toString(cast)); + result = false; + } + break; + + default: + LOG_WARNING("Format modifier '%c' at pos %d in '%s' not supported!", format[pos], (int) pos, format.c_str()); + result = false; + } + } + pos++; + aind++; // Следующий аргумент + } + + if(aind != args->size()) { + LOG_WARNING("Extra arguments more %d", aind); + return false; + } + return result; } void newlang::ConvertRangeToDict(Obj *from, Obj & to) { @@ -2287,6 +2352,7 @@ void newlang::ConvertRangeToDict(Obj *from, Obj & to) { } else { ASSERT((*from)["step"]->GetValueAsNumber() < 0); while((*value) > (*from)["stop"]) { + to.push_back(value->Clone()); (*value) += (*from)["step"]; } @@ -2296,6 +2362,7 @@ void newlang::ConvertRangeToDict(Obj *from, Obj & to) { } void newlang::ConvertStringToTensor(const std::string &from, torch::Tensor &to, ObjType type) { + ASSERT(!from.empty()); ASSERT(type == ObjType::None || type == ObjType::Char || type == ObjType::Tensor); to = torch::from_blob((void *) from.data(),{(int64_t) from.size()}, at::ScalarType::Char).clone(); @@ -2309,6 +2376,7 @@ void newlang::ConvertStringToTensor(const std::wstring &from, torch::Tensor &to, } else if(sizeof (wchar_t) == sizeof (int16_t)) { to = torch::from_blob((void *) from.data(),{(int) from.size()}, torch::Dtype::Short); } else { + LOG_RUNTIME("Unsupport wchar_t size '%d'!!!", (int) sizeof (wchar_t)); } to = to.toType(torch::Dtype::Int).clone(); @@ -2339,17 +2407,21 @@ template void ConvertTensorToStringTemplate(const torch::Tensor &fr } else { index->push_back(0); for (int64_t i = 0; i < from.size(pos - 1); i++) { - (*index)[pos - 1] = i; + ( + + *index)[pos - 1] = i; ConvertTensorToString(from, to, index); } } } void newlang::ConvertTensorToString(const torch::Tensor &from, std::string &to, std::vector *index) { + ConvertTensorToStringTemplate(from, to, index); } void newlang::ConvertTensorToString(const torch::Tensor &from, std::wstring &to, std::vector *index) { + ConvertTensorToStringTemplate(from, to, index); } @@ -2382,7 +2454,9 @@ void newlang::ConvertTensorToDict(const torch::Tensor &from, Obj &to, std::vecto } else { index->push_back(0); for (int64_t i = 0; i < from.size(pos - 1); i++) { - (*index)[pos - 1] = i; + ( + + *index)[pos - 1] = i; ConvertTensorToDict(from, to, index); } } @@ -2403,6 +2477,7 @@ void newlang::ConvertDictToTensor(Obj &from, torch::Tensor &to, ObjType type) { if(to.dim() != 1 || to.size(0) == 0) { to = temp.clone(); } else { + to = torch::cat({to, temp}); } } @@ -2433,6 +2508,7 @@ void newlang::ConvertValueToTensor(Obj *from, torch::Tensor &to, ObjType type) { } else if(from->is_dictionary_type()) { ConvertDictToTensor(*from, to, type); } else { + LOG_RUNTIME("Fail convert object type %s to tensor (%s)!", newlang::toString(from->getType()), from->toString().c_str()); } } @@ -2473,6 +2549,7 @@ ObjPtr Obj::CreateBaseType(ObjType type) { result->m_func_ptr = (void *) BaseTypeConstructor; result->m_is_const = true; + return result; } @@ -2632,6 +2709,7 @@ ObjPtr Obj::ConstructorSimpleType_(const Context *ctx, Obj & args) { } result->m_value = result->m_value.reshape(dims); } else { + LOG_RUNTIME("Fail esing dimensions for type '%s'!", newlang::toString(result->getType())); } } @@ -2652,6 +2730,7 @@ ObjPtr Obj::ConstructorDictionary_(const Context *ctx, Obj & args) { result->push_back(args[i], args.name(i)); } result->m_var_is_init = true; + return result; } @@ -2663,6 +2742,7 @@ ObjPtr Obj::ConstructorClass_(const Context *ctx, Obj & args) { LOG_RUNTIME("Field pos %d has no name!", i); } if(!result->select(result->name(i)).complete()) { + LOG_RUNTIME("Field name '%s' at index %d already exists!", result->name(i).c_str(), i); } } @@ -2682,6 +2762,7 @@ ObjPtr Obj::ConstructorStruct_(const Context *ctx, Obj & args) { LOG_RUNTIME("Field '%s' at pos %d not defined!", result->name(i).c_str(), i); } if(!(*result)[i] || !isSimpleType((*result)[i]->getType()) || isGenericType((*result)[i]->getType())) { + LOG_RUNTIME("Field '%s' at pos %d not simple type! (%s)", result->name(i).c_str(), i, newlang::toString((*result)[i]->getType())); } } @@ -2739,6 +2820,7 @@ ObjPtr Obj::ConstructorError_(const Context *ctx, Obj & args) { result->m_var_type_current = ObjType::Error; result->m_var_type_fixed = ObjType::Error; if(!result->size()) { + LOG_RUNTIME("Argument for type ':Error' required!"); } return result; @@ -2752,6 +2834,7 @@ ObjPtr Obj::ConstructorReturn_(const Context *ctx, Obj & args) { result->push_back(Obj::Arg(Obj::CreateNone())); } if(result->size() != 1) { + LOG_RUNTIME("Multiple argument for type ':Return'!"); } return result; diff --git a/src/object.h b/src/object.h index fc24484b..1d7d9eb5 100644 --- a/src/object.h +++ b/src/object.h @@ -6,6 +6,7 @@ #include #include +#include namespace newlang { @@ -105,28 +106,8 @@ namespace newlang { m_var_type_fixed = fixed; } - // template < typename T > - // Obj(T data, typename std::enable_if::value>::type* = 0) { - // m_var_type_current = ObjType::Dictionary; - // m_var_type_fixed = ObjType::Dictionary; - // m_dimensions = nullptr; - // push_front(Arg(data, nullptr)); - // } - // - // template < typename T > - // Obj(T &data, typename std::enable_if::value>::type* = 0) { - // m_var_type_current = ObjType::Dictionary; - // m_var_type_fixed = ObjType::Dictionary; - // m_dimensions = nullptr; - // push_front(Arg(data, nullptr)); - // } - Obj(Context *ctx, const TermPtr term, bool as_value, Obj *local_vars); - // template - // inline Obj(A arg, T... rest) : Obj(rest...) { - // push_front(Arg(arg)); - // } [[nodiscard]] static inline PairType ArgNull(const std::string name = "") { @@ -143,12 +124,6 @@ namespace newlang { return Variable::pair(value, name); } - // template - // typename std::enable_if::value, PairType>::type - // static inline Arg(T value) { - // return value; - // } - template typename std::enable_if::value || std::is_same::value, PairType>::type static inline Arg(T value, const std::string name = "") { @@ -389,16 +364,6 @@ namespace newlang { return Variable::empty(); } - // virtual ObjPtr at(const std::string name) { - // return Variable::at(name.begin()).second; - // } - // - // virtual ObjPtr at(const std::string name) const { - // Obj * const obj = (Obj * const) this; - // return obj->Variable::at(name.begin()).second; - // // return Variable::at(name.begin()).second; - // } - Variable::PairType & at(const std::string_view name) const { Obj * const obj = (Obj * const) this; return obj->Variable::at(name); @@ -973,6 +938,10 @@ namespace newlang { case ObjType::Number: return static_cast (m_value.item()); + case ObjType::Fraction: + ASSERT(m_fraction); + return m_fraction->GetAsInteger(); + case ObjType::StrWide: return std::stoll(m_wstr); case ObjType::StrChar: @@ -993,6 +962,10 @@ namespace newlang { case ObjType::Double: return m_value.item(); + case ObjType::Fraction: + ASSERT(m_fraction); + return m_fraction->GetAsNumber(); + case ObjType::StrWide: return std::stod(m_wstr); case ObjType::StrChar: @@ -1024,6 +997,10 @@ namespace newlang { case ObjType::None: return false; + case ObjType::Fraction: + ASSERT(m_fraction); + return m_fraction->GetAsInteger(); + case ObjType::Dictionary: case ObjType::Class: if (size()) { @@ -1061,6 +1038,41 @@ namespace newlang { return std::make_shared(type, var_name, term, fixed); } + static ObjPtr CreateFraction(const std::string_view val) { + + std::string str; + std::remove_copy(val.begin(), val.end(), back_inserter(str), '_'); + + if (str.empty()) { + LOG_RUNTIME("Empty string!"); + } + + ObjPtr frac = Obj::CreateType(ObjType::Fraction); + + // Ищем разделитель дроби + size_t pos = str.find("\\"); + + // Если символ не найден - то вся строка является числом + if (pos == std::string::npos) { + frac->m_fraction = std::make_shared(str, "1"); + } else { + // Числитель - левая часть + // Знаменатель - правая часть + frac->m_fraction = std::make_shared(str.substr(0, pos), str.substr(pos + 1, str.length())); + // Знаменатель не должен быть равен нулю + if (frac->m_fraction->m_denominator.isZero()) { + LOG_RUNTIME("Denominator must be different from zero!"); + } + } + + frac->m_var_is_init = true; + if (str.compare(frac->m_fraction->GetAsString().c_str()) != 0) { + LOG_RUNTIME("Fraction value '%s' does not match source string '%s'!", frac->m_fraction->GetAsString().c_str(), str.c_str()); + } + + return frac; + } + // чистая функция static ObjPtr BaseTypeConstructor(const Context *ctx, Obj &in); @@ -1673,11 +1685,10 @@ namespace newlang { m_wstr.clear(); m_var_type_current = ObjType::None; - // m_var_name.clear(); - // m_string.clear(); m_class_parents.clear(); m_var_is_init = false; m_value.reset(); + m_fraction.reset(); // m_var = std::monostate(); // m_value.reset(); //???????????????? // m_items.clear(); @@ -1742,6 +1753,7 @@ namespace newlang { void *m_func_ptr; ffi_abi m_func_abi; torch::Tensor m_value; + std::shared_ptr m_fraction; TermPtr m_block_source; bool m_check_args; //< Проверять аргументы на корректность (для всех видов функций) @ref MakeArgs diff --git a/src/parser.y b/src/parser.y index 461cfd49..4f9a7e2d 100644 --- a/src/parser.y +++ b/src/parser.y @@ -75,7 +75,7 @@ * Fraction ::= Integer "\" Integer (Представление BigNum / BigNum) * Currency ::= "`" Integer | "`" Integer "." Integer (Представление Fraction == BigNum / 10000) * - * Ariphmetic ::= Integer | Number | Complex | Currency | Fraction + * Ariphmetic ::= Integer | Number | Complex | Fraction * * StrChar ::= "'" символы "'" * StrWide ::= "\"" символы "\"" @@ -334,10 +334,10 @@ star_arg = [STAR] STAR ID %token NUMBER "Number" %token COMPLEX "Complex" %token FRACTION "Fraction" -%token CURRENCY "Currency" %token STRCHAR "StrChar" %token STRWIDE "StrWide" %token TEMPLATE "Template" +%token EVAL "Eval" %token TERM "Term" %token SYMBOL "Symbol" @@ -792,6 +792,10 @@ rval_var: rval_name { $$ = $1; } + | EVAL + { + $$ = $1; + } diff --git a/src/term.h b/src/term.h index e7c9c342..0e98ccba 100644 --- a/src/term.h +++ b/src/term.h @@ -28,9 +28,9 @@ namespace newlang { _(STRWIDE) \ _(STRCHAR) \ _(TEMPLATE) \ + _(EVAL) \ _(COMMENT) \ \ - _(CURRENCY) \ _(FRACTION) \ \ _(NONE) \ @@ -228,6 +228,7 @@ namespace newlang { case TermID::TENSOR: case TermID::DICT: case TermID::OPERATOR: + case TermID::EVAL: return true; default: return IsLiteral() || IsVariable() || IsFunction(); @@ -360,6 +361,16 @@ namespace newlang { result += ")"; } return result; + + case TermID::EVAL: + if (!result.empty()) { + result += "="; + } + result += "`"; + result += m_text; + result += "`"; + return result; + case TermID::INTEGER:// name:=123 case TermID::NUMBER: // name:=123.0 test = result.empty(); @@ -637,7 +648,6 @@ namespace newlang { case TermID::SYMBOL: case TermID::FRACTION: case TermID::COMPLEX: - case TermID::CURRENCY: return m_text; case TermID::EMPTY: diff --git a/src/test/eval_test.cpp b/src/test/eval_test.cpp index bb2e885d..b4eb0c0a 100644 --- a/src/test/eval_test.cpp +++ b/src/test/eval_test.cpp @@ -344,7 +344,7 @@ TEST(Eval, FuncSimple) { // "arg2"))->GetValueAsBoolean()); } -TEST(Eval, Types) { +TEST(Eval, TypesNative) { Context::Reset(); Context ctx(RunTime::Init()); @@ -764,6 +764,39 @@ TEST(Eval, Convert) { ASSERT_TRUE(obj_float->m_var_is_init); ASSERT_STREQ("[\n [3, 4,], [1, 2,],\n]:Float", obj_float->GetValueAsString().c_str()); + + + + + ObjPtr frac_0 = ctx.ExecStr("0\\1"); + ASSERT_TRUE(frac_0); + ASSERT_EQ(ObjType::Fraction, frac_0->getType()); + ASSERT_EQ(ObjType::None, frac_0->m_var_type_fixed); + ASSERT_STREQ("0\\1", frac_0->GetValueAsString().c_str()); + + ObjPtr frac_1 = ctx.ExecStr("1\\1"); + ASSERT_TRUE(frac_1); + ASSERT_EQ(ObjType::Fraction, frac_1->getType()); + ASSERT_EQ(ObjType::None, frac_1->m_var_type_fixed); + ASSERT_STREQ("1\\1", frac_1->GetValueAsString().c_str()); + + ObjPtr frac_2 = ctx.ExecStr("222_222_222_222222_222_222_222\\1_1_1_1"); + ASSERT_TRUE(frac_2); + ASSERT_EQ(ObjType::Fraction, frac_2->getType()); + ASSERT_EQ(ObjType::None, frac_2->m_var_type_fixed); + ASSERT_STREQ("222222222222222222222222\\1111", frac_2->GetValueAsString().c_str()); + + ObjPtr obj_frac = ctx.ExecStr(":Fraction(0)"); + ASSERT_TRUE(obj_frac); + ASSERT_FALSE(obj_frac->is_tensor()); + ASSERT_FALSE(obj_frac->is_scalar()); + ASSERT_EQ(ObjType::Fraction, obj_frac->getType()) << toString(obj_frac->m_var_type_current); + + ASSERT_TRUE(obj_frac->m_var_is_init); + ASSERT_STREQ("0\\1", obj_frac->GetValueAsString().c_str()); + ASSERT_EQ(0, obj_frac->GetValueAsInteger()); + + // EXPECT_TRUE(dlsym(nullptr, "_ZN7newlang4CharEPKNS_7ContextERKNS_6ObjectE")); // EXPECT_TRUE(dlsym(nullptr, "_ZN7newlang6Short_EPNS_7ContextERNS_6ObjectE")); diff --git a/src/test/fraction_test.cpp b/src/test/fraction_test.cpp index 89b6b034..3894e087 100644 --- a/src/test/fraction_test.cpp +++ b/src/test/fraction_test.cpp @@ -10,15 +10,17 @@ #include +using namespace newlang; TEST(ObjTest, BigNum) { BigNum dec; - ASSERT_FALSE(dec.m_is_init); - ASSERT_TRUE(dec.m_value); + ASSERT_TRUE(dec.value); dec.SetFromString("123456789"); + ASSERT_TRUE(dec.value); + ASSERT_STREQ("123456789", dec.GetAsString().c_str()); ASSERT_EQ(123456789, dec.GetAsInteger()); ASSERT_EQ(123456789, dec.GetAsNumber()); @@ -28,11 +30,11 @@ TEST(ObjTest, BigNum) { ASSERT_STREQ("-123456789", dec2.GetAsString().c_str()); ASSERT_EQ(-123456789, dec2.GetAsInteger()); ASSERT_EQ(-123456789, dec2.GetAsNumber()); - + dec.add(dec2); ASSERT_STREQ("0", dec.GetAsString().c_str()); ASSERT_EQ(0, dec.GetAsInteger()); - + dec.sub(dec2); ASSERT_STREQ("123456789", dec.GetAsString().c_str()); ASSERT_EQ(123456789, dec.GetAsInteger()); @@ -46,13 +48,20 @@ TEST(ObjTest, BigNum) { dec.mul(dec3); ASSERT_STREQ("15185185047", dec.GetAsString().c_str()); ASSERT_EQ(15185185047, dec.GetAsInteger()); - + dec.div(dec2, dec3); ASSERT_STREQ("-123", dec.GetAsString().c_str()); ASSERT_EQ(-123, dec.GetAsInteger()); ASSERT_STREQ("0", dec3.GetAsString().c_str()); ASSERT_EQ(0, dec3.GetAsInteger()); + + + dec.SetFromString("123456789123456789123456789123456789"); + ASSERT_STREQ("123456789123456789123456789123456789", dec.GetAsString().c_str()); + ASSERT_ANY_THROW(dec.GetAsInteger()); + ASSERT_DOUBLE_EQ(1.23456789123456789e+35, dec.GetAsNumber()); + } #endif \ No newline at end of file diff --git a/src/test/object_test.cpp b/src/test/object_test.cpp index 6211dea7..4d90c694 100644 --- a/src/test/object_test.cpp +++ b/src/test/object_test.cpp @@ -550,6 +550,45 @@ TEST(ObjTest, CreateFromString) { ASSERT_STREQ("строка", var2->GetValueAsString().c_str()); } +TEST(ObjTest, CreateFromFraction) { + + Context ctx(RunTime::Init()); + + ObjPtr var = Context::CreateRVal(&ctx, Parser::ParseString("123\\1")); + ASSERT_TRUE(var); + ASSERT_EQ(ObjType::Fraction, var->getType()) << toString(var->getType()); + ASSERT_EQ(123, var->GetValueAsInteger()); + ASSERT_DOUBLE_EQ(123, var->GetValueAsInteger()); + + ObjPtr var2 = ctx.ExecStr("123\\1"); + ASSERT_TRUE(var2); + ASSERT_EQ(ObjType::Fraction, var2->getType()) << toString(var2->getType()); + ASSERT_EQ(123, var2->GetValueAsInteger()); + ASSERT_DOUBLE_EQ(123, var2->GetValueAsNumber()); + + var = Context::CreateRVal(&ctx, Parser::ParseString("-123\\1")); + ASSERT_TRUE(var); + ASSERT_EQ(ObjType::Fraction, var->getType()) << toString(var->getType()); + ASSERT_EQ(-123, var->GetValueAsInteger()); + ASSERT_DOUBLE_EQ(-123, var->GetValueAsInteger()); + + var2 = ctx.ExecStr("-123\\1"); + ASSERT_TRUE(var2); + ASSERT_EQ(ObjType::Fraction, var2->getType()) << toString(var2->getType()); + ASSERT_EQ(-123, var2->GetValueAsInteger()); + ASSERT_DOUBLE_EQ(-123, var2->GetValueAsNumber()); + + ASSERT_ANY_THROW(Context::CreateRVal(&ctx, Term::Create(TermID::FRACTION, "1\\0"))); + ASSERT_ANY_THROW(Context::CreateRVal(&ctx, Term::Create(TermID::FRACTION, "1\\"))); + ASSERT_ANY_THROW(Context::CreateRVal(&ctx, Term::Create(TermID::FRACTION, ""))); + ASSERT_ANY_THROW(Context::CreateRVal(&ctx, Term::Create(TermID::FRACTION, "asdsdff"))); + ASSERT_ANY_THROW(Context::CreateRVal(&ctx, Term::Create(TermID::FRACTION, "asdsdff\\dddddd"))); + ASSERT_ANY_THROW(Context::CreateRVal(&ctx, Term::Create(TermID::FRACTION, "123asdsdff\\dddddd"))); + ASSERT_ANY_THROW(Context::CreateRVal(&ctx, Term::Create(TermID::FRACTION, "123\\111dddddd"))); + ASSERT_ANY_THROW(Context::CreateRVal(&ctx, Term::Create(TermID::FRACTION, "123wwwww\\111"))); +} + + TEST(Args, All) { Context ctx(RunTime::Init()); TermPtr ast; diff --git a/src/test/parser_test.cpp b/src/test/parser_test.cpp index 764bf8da..d145c327 100644 --- a/src/test/parser_test.cpp +++ b/src/test/parser_test.cpp @@ -93,6 +93,18 @@ TEST_F(ParserTest, LiteralString4) { ASSERT_STREQ("'strbyte'(term(), 123)", ast->toString().c_str()); } +TEST_F(ParserTest, LiteralEval1) { + ASSERT_TRUE(Parse("``")); + ASSERT_EQ(TermID::EVAL, ast->getTermID()) << newlang::toString(ast->getTermID()); + ASSERT_STREQ("``", ast->toString().c_str()); +} + +TEST_F(ParserTest, LiteralEval2) { + ASSERT_TRUE(Parse("`strbyte(term(), 123);`")); + ASSERT_EQ(TermID::EVAL, ast->getTermID()) << newlang::toString(ast->getTermID()); + ASSERT_STREQ("`strbyte(term(), 123);`", ast->toString().c_str()); +} + TEST_F(ParserTest, LiteralFraction) { ASSERT_TRUE(Parse("1\\1;")); ASSERT_EQ(TermID::FRACTION, ast->getTermID()) << newlang::toString(ast->getTermID()); @@ -107,20 +119,6 @@ TEST_F(ParserTest, LiteralFraction) { ASSERT_STREQ("123456789123456789123456789\\123456789123456789123456789", ast->toString().c_str()); } -TEST_F(ParserTest, DISABLED_LiteralCurrency) { - ASSERT_TRUE(Parse("`1;")); - ASSERT_EQ(TermID::CURRENCY, ast->getTermID()) << newlang::toString(ast->getTermID()); - ASSERT_STREQ("`1", ast->toString().c_str()); - - ASSERT_TRUE(Parse("1`23;")); - ASSERT_EQ(TermID::CURRENCY, ast->getTermID()) << newlang::toString(ast->getTermID()); - ASSERT_STREQ("`123", ast->toString().c_str()); - - ASSERT_TRUE(Parse("1`2`3456.123;")); - ASSERT_EQ(TermID::CURRENCY, ast->getTermID()) << newlang::toString(ast->getTermID()); - ASSERT_STREQ("123`456.123", ast->toString().c_str()); -} - TEST_F(ParserTest, DISABLED_LiteralComplex) { ASSERT_TRUE(Parse("1+0j;")); ASSERT_EQ(TermID::COMPLEX, ast->getTermID()) << newlang::toString(ast->getTermID()); diff --git a/src/types.h b/src/types.h index 73b7e1f1..cbe9f152 100644 --- a/src/types.h +++ b/src/types.h @@ -20,7 +20,52 @@ namespace newlang { inline std::string & trim(std::string& s, const char* t = ws) { return ltrim(rtrim(s, t), t); } + + template + class SharedPtrWrapper { + public: + + explicit SharedPtrWrapper(T* p, void (*deleter)(T*)) : ptr_() { + if (!p) { + return; + } + + if (!deleter) { + deleter = NullDeleter; + } + + try { + ptr_ = std::shared_ptr(p, deleter); + } catch (...) { + } + } + + operator bool() const { + return !!ptr_; + } + + T* get() const { + return ptr_.get(); + } + + T& operator*() const { + return *ptr_; + } + + T* operator->() const { + return get(); + } + + private: + + static void NullDeleter(T*) { + } + + std::shared_ptr ptr_; + }; + + typedef at::indexing::TensorIndex Index; typedef at::IntArrayRef Dimension; @@ -133,9 +178,7 @@ void ParserException(const char *msg, std::string &buffer, int row, int col); \ _(Tensor, 32) \ \ - _(BigNum, 33) \ - _(Currency, 34) \ - _(Fraction, 35) \ + _(Fraction, 33) \ \ _(Arithmetic, 47) \ \ @@ -847,9 +890,9 @@ void ParserException(const char *msg, std::string &buffer, int row, int col); case ObjType::Number: // Любое число с ПЛАВАЮЩЕЙ ТОЧКОЙ return isFloatingType(type) || isIntegralType(type, true); case ObjType::Complex: // Любое КОМПЛЕКСНОЕ число - return isComplexType(type) || isFloatingType(type) || isIntegralType(type, true); + return isIntegralType(type, true) || isFloatingType(type) || isComplexType(type); case ObjType::Arithmetic: // Любое число - return isComplexType(type) || isFloatingType(type) || isIntegralType(type, true) || type == ObjType::BigNum || type == ObjType::Fraction || type == ObjType::Currency; + return isIntegralType(type, true) || isFloatingType(type) || isComplexType(type) || type == ObjType::Fraction; case ObjType::String: // Строка любого типа return isString(type); case ObjType::Object: // Любой объект (Class или Dictionary) From cdd370a962756097300cbef1024fef0b95c4c64b Mon Sep 17 00:00:00 2001 From: Aleksandr Ryabikov Date: Mon, 4 Jul 2022 14:48:19 +0300 Subject: [PATCH 14/31] =?UTF-8?q?=D0=97=D0=B0=D0=BC=D0=B5=D0=BD=D0=B8?= =?UTF-8?q?=D0=BB=20=D0=B2=D1=8B=D0=B7=D0=BE=D0=B2=20=D1=84=D1=83=D0=BD?= =?UTF-8?q?=D0=BA=D1=86=D0=B8=D0=B8=20import=20=D0=BD=D0=B0=20=D0=B8=D1=81?= =?UTF-8?q?=D0=BF=D0=BE=D0=BB=D1=8C=D0=B7=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8?= =?UTF-8?q?=D0=B5=20=D0=BE=D0=B1=D1=89=D0=B5=D0=B3=D0=BE=20=D1=82=D0=B8?= =?UTF-8?q?=D0=BF=D0=B0=20:Pointer?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- examples/fileio.nlp | 52 ++++++++++++++++++++-------------------- src/builtin.cpp | 42 ++++++++++++++++---------------- src/builtin.h | 8 +++---- src/context.cpp | 9 ++++--- src/object.cpp | 14 +++++++++++ src/object.h | 1 + src/test/eval_test.cpp | 30 +++++++++++------------ src/test/nlc_test.cpp | 2 +- src/test/parser_test.cpp | 2 +- src/variable.h | 2 -- 10 files changed, 86 insertions(+), 76 deletions(-) diff --git a/examples/fileio.nlp b/examples/fileio.nlp index 12b11dec..1c871fb2 100644 --- a/examples/fileio.nlp +++ b/examples/fileio.nlp @@ -1,49 +1,49 @@ :File ::= :Pointer; -@stdin:File ::= import("_IO_2_1_stdin_:File"); -@stdout:File ::= import("_IO_2_1_stdout_:File"); -@stderr:File ::= import("stderr:File"); +@stdin:File ::= :Pointer("_IO_2_1_stdin_:File"); +@stdout:File ::= :Pointer("_IO_2_1_stdout_:File"); +@stderr:File ::= :Pointer("stderr:File"); -@fopen(filename:String, modes:String):File ::= import("fopen(filename:StrChar, modes:StrChar):File");; -@fopen64(filename:String, modes:String):File ::= import("fopen(filename:StrChar, modes:StrChar):File");; +@fopen(filename:String, modes:String):File ::= :Pointer("fopen(filename:StrChar, modes:StrChar):File");; +@fopen64(filename:String, modes:String):File ::= :Pointer("fopen(filename:StrChar, modes:StrChar):File");; -@freopen(filename:String, modes:String):File ::= import("freopen(filename:StrChar, modes:StrChar, stream:File):File");; -@freopen64(filename:String, modes:String):File ::= import("freopen64(filename:StrChar, modes:StrChar, stream:File):File");; +@freopen(filename:String, modes:String):File ::= :Pointer("freopen(filename:StrChar, modes:StrChar, stream:File):File");; +@freopen64(filename:String, modes:String):File ::= :Pointer("freopen64(filename:StrChar, modes:StrChar, stream:File):File");; #extern FILE *fdopen (int __fd, const char *__modes) __THROW __wur; -@fclose(stream:File):Int ::= import("fclose(stream:File):Int");; -@fcloseall():Int ::= import("fcloseall():Int");; +@fclose(stream:File):Int ::= :Pointer("fclose(stream:File):Int");; +@fcloseall():Int ::= :Pointer("fcloseall():Int");; -@fflush(stream:File):Int ::= import("fflush(stream:File):Int");; -@fflush_unlocked(stream:File):Int ::= import("fflush_unlocked(stream:File):Int");; +@fflush(stream:File):Int ::= :Pointer("fflush(stream:File):Int");; +@fflush_unlocked(stream:File):Int ::= :Pointer("fflush_unlocked(stream:File):Int");; -@fremove(filename:String):Int ::= import("remove(filename:StrChar):Int");; +@fremove(filename:String):Int ::= :Pointer("remove(filename:StrChar):Int");; -@frename(old:String, new:String):Int ::= import("rename(old:StrChar, new:StrChar):Int");; +@frename(old:String, new:String):Int ::= :Pointer("rename(old:StrChar, new:StrChar):Int");; -@ftmpfile():File ::= import("tmpfile():File");; -@ftmpfile64():File ::= import("tmpfile64():File");; +@ftmpfile():File ::= :Pointer("tmpfile():File");; +@ftmpfile64():File ::= :Pointer("tmpfile64():File");; -@ftmpnam(template:String):StrChar ::= import("tmpnam(template:StrChar):StrChar");; -@ftmpnam_r(template:String):StrChar ::= import("tmpnam(template:StrChar):StrChar");; +@ftmpnam(template:String):StrChar ::= :Pointer("tmpnam(template:StrChar):StrChar");; +@ftmpnam_r(template:String):StrChar ::= :Pointer("tmpnam(template:StrChar):StrChar");; -@ftempnam(dir:String, prefix:String):StrChar ::= import("tempnam(dir:StrChar, prefix:StrChar):StrChar");; +@ftempnam(dir:String, prefix:String):StrChar ::= :Pointer("tempnam(dir:StrChar, prefix:StrChar):StrChar");; -@fprintf(stream:File, format:Format, ...):Int ::= import("fprintf(stream:File, format:Format, ...):Int");; -@fscanf(stream:File, format:Format, ...):Int ::= import("fscanf(stream:File, format:Format, ...):Int");; +@fprintf(stream:File, format:Format, ...):Int ::= :Pointer("fprintf(stream:File, format:Format, ...):Int");; +@fscanf(stream:File, format:Format, ...):Int ::= :Pointer("fscanf(stream:File, format:Format, ...):Int");; -@fgetc(stream:File):Int ::= import("fgetc(stream:File):Int");; +@fgetc(stream:File):Int ::= :Pointer("fgetc(stream:File):Int");; -@fgetc_unlocked(stream:File):Int ::= import("fgetc_unlocked(stream:File):Int");; +@fgetc_unlocked(stream:File):Int ::= :Pointer("fgetc_unlocked(stream:File):Int");; -@fungetc(c:Int, stream:File):Int ::= import("ungetc(c:Int, stream:File):Int");; +@fungetc(c:Int, stream:File):Int ::= :Pointer("ungetc(c:Int, stream:File):Int");; -@fputc(c:Int, stream:File):Int ::= import("fputc(c:Int, stream:File):Int");; -@fputs(string:String, stream:File):Int ::= import("fputs(c:StrChar, stream:File):Int");; +@fputc(c:Int, stream:File):Int ::= :Pointer("fputc(c:Int, stream:File):Int");; +@fputs(string:String, stream:File):Int ::= :Pointer("fputs(c:StrChar, stream:File):Int");; #extern size_t fread (void *__restrict __ptr, size_t __size, @@ -59,7 +59,7 @@ # size_t __n, FILE *__restrict __stream); # SEEK ::= :Enum(SET=0, CUR=1, END=2); -@fseek(stream:File, offset:Long, whence:Int):Int ::= import("fseek(stream:File, offset:Long, whence:Int):Int");; +@fseek(stream:File, offset:Long, whence:Int):Int ::= :Pointer("fseek(stream:File, offset:Long, whence:Int):Int");; #extern long int ftell (FILE *__stream) __wur; diff --git a/src/builtin.cpp b/src/builtin.cpp index af77b44d..3199b54d 100644 --- a/src/builtin.cpp +++ b/src/builtin.cpp @@ -59,27 +59,27 @@ namespace newlang { return in[1]->MakeMutable(); } - NEWLANG_FUNCTION(import) { - if(!ctx) { - LOG_RUNTIME("No access to context!"); - } - return ctx->CreateNative(in.at(1).second->GetValueAsString().c_str(), - in["module"]->GetValueAsString().c_str(), in["lazzy"]->GetValueAsBoolean()); - } - - NEWLANG_FUNCTION(eval) { - if(!ctx) { - LOG_RUNTIME("No access to context!"); - } - return ctx->ExecStr(in.at(1).second->GetValueAsString().c_str(), &in, true); - } - - NEWLANG_FUNCTION(exec) { - if(!ctx) { - LOG_RUNTIME("No access to context!"); - } - return ctx->ExecFile(in.at(1).second->GetValueAsString().c_str(), &in, true); - } +// NEWLANG_FUNCTION(import) { +// if(!ctx) { +// LOG_RUNTIME("No access to context!"); +// } +// return ctx->CreateNative(in.at(1).second->GetValueAsString().c_str(), +// in["module"]->GetValueAsString().c_str(), in["lazzy"]->GetValueAsBoolean()); +// } +// +// NEWLANG_FUNCTION(eval) { +// if(!ctx) { +// LOG_RUNTIME("No access to context!"); +// } +// return ctx->ExecStr(in.at(1).second->GetValueAsString().c_str(), &in, true); +// } +// +// NEWLANG_FUNCTION(exec) { +// if(!ctx) { +// LOG_RUNTIME("No access to context!"); +// } +// return ctx->ExecFile(in.at(1).second->GetValueAsString().c_str(), &in, true); +// } NEWLANG_TRANSPARENT(help) { diff --git a/src/builtin.h b/src/builtin.h index 3230fb9c..c800ea35 100644 --- a/src/builtin.h +++ b/src/builtin.h @@ -45,11 +45,9 @@ FUNC_TRANSPARENT(newlang_clone, clone); FUNC_TRANSPARENT(newlang_const_, const_); FUNC_TRANSPARENT(newlang_mutable_, mutable_); -FUNC_DIRECT(newlang_import, import); -FUNC_DIRECT(newlang_print, print_); - -FUNC_DIRECT(newlang_eval, eval); -FUNC_DIRECT(newlang_exec, exec); +//FUNC_DIRECT(newlang_import, import); +//FUNC_DIRECT(newlang_eval, eval); +//FUNC_DIRECT(newlang_exec, exec); FUNC_TRANSPARENT(newlang_help, help); /* diff --git a/src/context.cpp b/src/context.cpp index 6b68e527..b9b4b7ba 100644 --- a/src/context.cpp +++ b/src/context.cpp @@ -54,10 +54,10 @@ Context::Context(RuntimePtr global) { VERIFY(CreateBuiltin("max(arg, ...)", (void *) &max, ObjType::PureFunc)); VERIFY(CreateBuiltin("макс(arg, ...)", (void *) &max, ObjType::PureFunc)); - VERIFY(CreateBuiltin("import(arg, module='', lazzy=0)", (void *) &import, ObjType::Function)); + // VERIFY(CreateBuiltin("import(arg, module='', lazzy=0)", (void *) &import, ObjType::Function)); + // VERIFY(CreateBuiltin("eval(string:String)", (void *) &eval, ObjType::Function)); + // VERIFY(CreateBuiltin("exec(filename:String)", (void *) &exec, ObjType::Function)); - VERIFY(CreateBuiltin("eval(string:String)", (void *) &eval, ObjType::Function)); - VERIFY(CreateBuiltin("exec(filename:String)", (void *) &exec, ObjType::Function)); VERIFY(CreateBuiltin("help(...)", (void *) &help, ObjType::PureFunc)); } @@ -1454,7 +1454,6 @@ ObjPtr Context::CreateNative(TermPtr proto, const char *module, bool lazzy, cons type = typeFromString(proto->m_type_name, this); switch(type) { case ObjType::Bool: - // case ObjType::Byte: case ObjType::Char: case ObjType::Short: case ObjType::Int: @@ -2186,7 +2185,7 @@ ObjPtr Context::CreateRVal(Context *ctx, TermPtr term, Obj * local_vars, bool in temp = ctx->GetTerm(term->GetFullName().c_str(), term->isRef()); if(!temp) { - ASSERT(temp); + LOG_RUNTIME("Term '%s' not found!", term->GetFullName().c_str()); } args = Obj::CreateDict(); diff --git a/src/object.cpp b/src/object.cpp index bc30b8b6..7594f846 100644 --- a/src/object.cpp +++ b/src/object.cpp @@ -2565,6 +2565,8 @@ ObjPtr Obj::BaseTypeConstructor(const Context *ctx, Obj & args) { result = ConstructorSimpleType_(ctx, args); } else if(args[0]->m_var_type_fixed == ObjType::Dictionary) { result = ConstructorDictionary_(ctx, args); + } else if(args[0]->m_var_type_fixed == ObjType::Pointer && args.size() > 1) { + result = ConstructorNative_(ctx, args); } else if(args[0]->m_var_type_fixed == ObjType::Class) { result = ConstructorClass_(ctx, args); } else if(args[0]->m_var_type_fixed == ObjType::Struct || args[0]->m_var_type_fixed == ObjType::Union) { @@ -2734,6 +2736,18 @@ ObjPtr Obj::ConstructorDictionary_(const Context *ctx, Obj & args) { return result; } +ObjPtr Obj::ConstructorNative_(const Context *ctx_const, Obj & args) { + if(args.size() < 2) { + LOG_RUNTIME("Empty argument list!"); + } + if(!args.at(1).second->is_string_type()) { + LOG_RUNTIME("First argument not a string!"); + } + //@todo Передача дополнительных аргументов? args["module"]->GetValueAsString().c_str(), args["lazzy"]->GetValueAsBoolean() + Context *ctx = const_cast (ctx_const); + return ctx->CreateNative(args.at(1).second->GetValueAsString().c_str()); +} + ObjPtr Obj::ConstructorClass_(const Context *ctx, Obj & args) { ObjPtr result = ConstructorDictionary_(ctx, args); result->m_var_type_fixed = ObjType::Class; diff --git a/src/object.h b/src/object.h index 1d7d9eb5..10f2bc82 100644 --- a/src/object.h +++ b/src/object.h @@ -1078,6 +1078,7 @@ namespace newlang { static ObjPtr BaseTypeConstructor(const Context *ctx, Obj &in); static ObjPtr ConstructorSimpleType_(const Context *ctx, Obj & args); static ObjPtr ConstructorDictionary_(const Context *ctx, Obj & args); + static ObjPtr ConstructorNative_(const Context *ctx, Obj & args); static ObjPtr ConstructorClass_(const Context *ctx, Obj & args); static ObjPtr ConstructorStruct_(const Context *ctx, Obj & args); static ObjPtr ConstructorEnum_(const Context *ctx, Obj & args); diff --git a/src/test/eval_test.cpp b/src/test/eval_test.cpp index b4eb0c0a..6c633b0e 100644 --- a/src/test/eval_test.cpp +++ b/src/test/eval_test.cpp @@ -89,7 +89,7 @@ TEST(Eval, Assign) { ASSERT_STREQ("$=('var_str', 'var_num',)", list->toString().c_str()); var_long = 987654321; - ObjPtr var_export = ctx.ExecStr("var_export := @import(\"var_long:Long\")"); + ObjPtr var_export = ctx.ExecStr("var_export := :Pointer(\"var_long:Long\")"); ASSERT_TRUE(var_export); ASSERT_TRUE(var_export->is_tensor()) << var_export; ASSERT_EQ(var_export->getType(), ObjType::Long); @@ -102,7 +102,7 @@ TEST(Eval, Assign) { list = ctx.ExecStr("$"); ASSERT_STREQ("$=('var_str', 'var_num', 'var_export',)", list->toString().c_str()); - ObjPtr func_export = ctx.ExecStr("func_export := @import(\"func_export(arg1:Long, arg2:Char=100):Long\")"); + ObjPtr func_export = ctx.ExecStr("func_export := :Pointer(\"func_export(arg1:Long, arg2:Char=100):Long\")"); ASSERT_TRUE(func_export); ASSERT_TRUE(func_export->is_function()) << func_export; ASSERT_EQ(func_export->getType(), ObjType::NativeFunc); @@ -270,7 +270,7 @@ TEST(Eval, Tensor) { "0,], [0, 0,], [0, 0,], [0, 0,],\n]:Double", tt->GetValueAsString().c_str()); - ObjPtr rand = ctx.ExecStr("rand := @import('rand():Int')"); + ObjPtr rand = ctx.ExecStr("rand := :Pointer('rand():Int')"); // Может быть раскрытие словаря, который возвращает вызов функции // и может быть многократный вызов одной и той функции @@ -372,8 +372,8 @@ TEST(Eval, TypesNative) { // fputs("TEST STDOUT", stdout); // 0x7fff6ec7e760 // <_IO_2_1_stdout_> fputs("TEST STDOUT", (FILE *)f_stdout->m_func_ptr); - // //stdout:File ::= import("stdout:File"); - // ObjPtr f2_stdout = ctx.ExecStr("stdout:File ::= import('stdout:File')"); + // //stdout:File ::= :Pointer("stdout:File"); + // ObjPtr f2_stdout = ctx.ExecStr("stdout:File ::= :Pointer('stdout:File')"); // ASSERT_TRUE(f2_stdout); // ASSERT_TRUE(f2_stdout->m_func_ptr); // ASSERT_EQ(f_stdout->m_func_ptr, f2_stdout->m_func_ptr); @@ -383,7 +383,7 @@ TEST(Eval, TypesNative) { ASSERT_TRUE(fopen); ASSERT_TRUE(fopen->m_func_ptr); - ObjPtr fopen2 = ctx.ExecStr("@fopen2 ::= import('fopen(filename:StrChar, modes:StrChar):File')"); + ObjPtr fopen2 = ctx.ExecStr("@fopen2 ::= :Pointer('fopen(filename:StrChar, modes:StrChar):File')"); ASSERT_TRUE(fopen2); ASSERT_TRUE(fopen2->m_func_ptr); ASSERT_EQ(fopen->m_func_ptr, fopen2->m_func_ptr); @@ -392,33 +392,33 @@ TEST(Eval, TypesNative) { ASSERT_TRUE(!iter.complete()); ObjPtr fopen3 = ctx.ExecStr("@fopen3(filename:String, modes:String):File ::= " - "import('fopen(filename:StrChar, modes:StrChar):File')"); + ":Pointer('fopen(filename:StrChar, modes:StrChar):File')"); ASSERT_TRUE(fopen3); ASSERT_TRUE(fopen3->m_func_ptr); ASSERT_EQ(fopen->m_func_ptr, fopen3->m_func_ptr); - ObjPtr fclose = ctx.ExecStr("@fclose(stream:File):Int ::= import(\"fclose(stream:File):Int\")"); + ObjPtr fclose = ctx.ExecStr("@fclose(stream:File):Int ::= :Pointer(\"fclose(stream:File):Int\")"); ASSERT_TRUE(fclose); ASSERT_TRUE(fclose->m_func_ptr); ObjPtr fremove = ctx.ExecStr("@fremove(filename:String):Int ::= " - "import(\"remove(filename:StrChar):Int\")"); + ":Pointer(\"remove(filename:StrChar):Int\")"); ASSERT_TRUE(fremove); ASSERT_TRUE(fremove->m_func_ptr); ObjPtr frename = ctx.ExecStr("@rename(old:String, new:String):Int ::= " - "import('rename(old:StrChar, new:StrChar):Int')"); + ":Pointer('rename(old:StrChar, new:StrChar):Int')"); ASSERT_TRUE(frename); ASSERT_TRUE(frename->m_func_ptr); ObjPtr fprintf = ctx.ExecStr("@fprintf(stream:File, format:Format, ...):Int ::= " - "import('fprintf(stream:File, format:Format, ...):Int')"); + ":Pointer('fprintf(stream:File, format:Format, ...):Int')"); ASSERT_TRUE(fremove); ObjPtr fputc = ctx.ExecStr("@fputc(c:Int, stream:File):Int ::= " - "import('fputc(c:Int, stream:File):Int')"); + ":Pointer('fputc(c:Int, stream:File):Int')"); ASSERT_TRUE(fremove); ObjPtr fputs = ctx.ExecStr("@fputs(s:String, stream:File):Int ::= " - "import('fputs(s:StrChar, stream:File):Int')"); + ":Pointer('fputs(s:StrChar, stream:File):Int')"); ASSERT_TRUE(fputs); std::filesystem::create_directories("temp"); @@ -518,7 +518,7 @@ TEST(Eval, TypesNative) { ASSERT_EQ(2, F_res->GetValueAsInteger()); ObjPtr seek = ctx.ExecStr("@fseek(stream:File, offset:Long, whence:Int):Int ::= " - "import('fseek(stream:File, offset:Long, whence:Int):Int')"); + ":Pointer('fseek(stream:File, offset:Long, whence:Int):Int')"); ASSERT_TRUE(seek); F_res = ctx.ExecStr("fseek(F2, 10, @SEEK.SET)"); @@ -571,7 +571,7 @@ TEST(ExecStr, Funcs) { EXPECT_TRUE(ctx.m_runtime->GetNativeAddr("printf")); - ObjPtr p = ctx.ExecStr("printf := @import('printf(format:Format, ...):Int');"); + ObjPtr p = ctx.ExecStr("printf := :Pointer('printf(format:Format, ...):Int');"); ASSERT_TRUE(p); ASSERT_STREQ("printf=printf(format:Format, ...):Int{}", p->toString().c_str()); diff --git a/src/test/nlc_test.cpp b/src/test/nlc_test.cpp index ceef4801..9a7f6953 100644 --- a/src/test/nlc_test.cpp +++ b/src/test/nlc_test.cpp @@ -129,7 +129,7 @@ TEST(NLC, EvalHelloWorld) { std::string cmd; cmd += "#!./dist/Debug/GNU-Linux/nlc --eval\n"; - cmd += "hello(str='') := { printf := @import('printf(format:Format, ...):Int'); printf('%s', $str); $str;};\n"; + cmd += "hello(str='') := { printf := :Pointer('printf(format:Format, ...):Int'); printf('%s', $str); $str;};\n"; cmd += "hello('Привет, мир!\\n');"; std::filesystem::create_directories("temp"); diff --git a/src/test/parser_test.cpp b/src/test/parser_test.cpp index d145c327..30bec5ac 100644 --- a/src/test/parser_test.cpp +++ b/src/test/parser_test.cpp @@ -2056,7 +2056,7 @@ TEST_F(ParserTest, MacroDSL) { } TEST_F(ParserTest, HelloWorld) { - ASSERT_TRUE(Parse("hello(str=\"\") := { printf(format:Format, ...):Int := @import('printf'); printf('%s', $1); $str;};")); + ASSERT_TRUE(Parse("hello(str=\"\") := { printf(format:Format, ...):Int := :Pointer('printf'); printf('%s', $1); $str;};")); // ASSERT_STREQ("!!!!!!!!!!!!!!", ast->toString().c_str()); } diff --git a/src/variable.h b/src/variable.h index a2a57495..98f1ee21 100644 --- a/src/variable.h +++ b/src/variable.h @@ -118,13 +118,11 @@ namespace newlang { inline Type & push_front(PairType pair) { m_data.insert(m_data.begin(), pair); - // m_data.push_front(pair); return at(0).second; } inline void pop_front() { m_data.erase(m_data.begin()); - // m_data.pop_front(); } inline Type top() const { From 2d4be7837a925823b4261de5607427b6c74452ea Mon Sep 17 00:00:00 2001 From: Aleksandr Ryabikov Date: Mon, 4 Jul 2022 16:37:51 +0300 Subject: [PATCH 15/31] =?UTF-8?q?=D0=B1=D0=B0=D0=B7=D0=BE=D0=B2=D1=8B?= =?UTF-8?q?=D0=B5=20=D0=BE=D0=BF=D0=B5=D1=80=D0=B0=D1=86=D0=B8=D0=B8=20?= =?UTF-8?q?=D1=81=20=D0=B4=D1=80=D0=BE=D0=B1=D1=8F=D0=BC=D0=B8=20+=20?= =?UTF-8?q?=D1=82=D0=B5=D1=81=D1=82=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/fraction.h | 113 +++++++++++++++++++++-------------------- src/object.cpp | 82 ++++++++++++++++++++++++------ src/test/eval_test.cpp | 16 ++++++ 3 files changed, 140 insertions(+), 71 deletions(-) diff --git a/src/fraction.h b/src/fraction.h index 116c70e2..561fc684 100644 --- a/src/fraction.h +++ b/src/fraction.h @@ -179,16 +179,19 @@ namespace newlang { BigNum m_numerator; // Числитель BigNum m_denominator; // Знаменатель - // Функция нужна для сокращения дроби - void reduce(); public: // Конструктор принимает значения числителя и знаменателя Fraction() : Fraction("0", "1") { } - Fraction(const unsigned long value) : Fraction() { - BN_set_word(m_numerator.value, value); + Fraction(const int64_t value) : Fraction() { + if (value < 0) { + BN_set_word(m_numerator.value, -value); + BN_set_negative(m_numerator.value, -1); + } else { + BN_set_word(m_numerator.value, value); + } } Fraction(const Fraction ©) : m_numerator(copy.m_numerator), m_denominator(copy.m_denominator) { @@ -233,69 +236,69 @@ namespace newlang { return m_numerator.GetAsNumber() / m_denominator.GetAsNumber(); } - // // Наибольший общий делитель - // // (англ.) greatest common divisor - // - // static int gcd(int a, int b) { - // while (b > 0) { - // int c = a % b; - // a = b; - // b = c; - // } - // return a; - // } - // - // // Наименьшее общее кратное - // // (англ.) least common multiple - // - // static int lcm(int a, int b) { - // return gcd(a, b) * a * b; - // } - //public void reduce () - //{ - // BigInteger num = BigInteger.valueOf(numerator); - // int gcd = num.gcd(BigInteger.valueOf(denominator)).intValue(); - // - // this.denominator /= gcd; - // this.numerator /= gcd; - // - //} - - Fraction& operator*(const Fraction &fraction) { - LOG_RUNTIME("Not implemented!"); - // m_numerator = m_numerator * fraction.getNumerator(); - // m_denominator = m_denominator * fraction.getDenominator(); - // reduce(); + // Сокращения дроби + + void reduce() { + BigNum::CtxHelper ctx; + BigNum gcd; + + if (!BN_gcd(gcd.value, m_numerator.value, m_denominator.value, ctx.ctx)) { + LOG_RUNTIME("Fail call BN_gcd!"); + } + + BigNum rem; + m_numerator.div(gcd, rem); + ASSERT(rem.isZero()); + m_denominator.div(gcd, rem); + ASSERT(rem.isZero()); + } + + Fraction& operator*=(const Fraction &fraction) { + m_numerator.mul(fraction.m_numerator); + m_denominator.mul(fraction.m_denominator); + reduce(); return *this; } - Fraction& operator/(const Fraction &fraction) { - LOG_RUNTIME("Not implemented!"); - // m_numerator = m_numerator * fraction.getDenominator(); - // m_denominator = m_denominator * fraction.getNumerator(); - // reduce(); + Fraction& operator/=(const Fraction &fraction) { + m_numerator.mul(fraction.m_denominator); + m_denominator.mul(fraction.m_numerator); + reduce(); return *this; } - Fraction& operator-(const Fraction &fraction) { - LOG_RUNTIME("Not implemented!"); - // int relNumerator = m_numerator * fraction.getDenominator(); - // m_numerator = m_numerator * fraction.getDenominator() - m_denominator * fraction.getNumerator(); - // m_denominator = gcd(m_denominator, fraction.getDenominator()); - // reduce(); + Fraction& operator-=(const Fraction &fraction) { + + BigNum sub_num(fraction.m_numerator); + sub_num.mul(m_denominator); + + m_numerator.mul(fraction.m_denominator); + m_denominator.mul(fraction.m_denominator); + + m_numerator.sub(sub_num); + + reduce(); return *this; } - Fraction& operator+(const Fraction &fraction) { + Fraction& operator+=(const Fraction &fraction) { + BigNum add_num(fraction.m_numerator); + add_num.mul(m_denominator); + + m_numerator.mul(fraction.m_denominator); + m_denominator.mul(fraction.m_denominator); + + m_numerator.add(add_num); + + reduce(); + return *this; + } + + Fraction& op_pow_(const Fraction &fraction) { LOG_RUNTIME("Not implemented!"); - // int unionDenominator = lcm(m_denominator, fraction.getDenominator()); - // int relNumerator = m_numerator * unionDenominator; - // int mulNumerator = fraction.m_numerator * unionDenominator; - // m_numerator = relNumerator * mulNumerator; - // m_denominator = unionDenominator; - // reduce(); return *this; } + }; }; #endif /* FRACTION_H */ diff --git a/src/object.cpp b/src/object.cpp index 7594f846..c9a3cd44 100644 --- a/src/object.cpp +++ b/src/object.cpp @@ -382,6 +382,15 @@ ObjPtr Obj::operator+=(Obj value) { return shared(); } break; + + case ObjType::Fraction: + if(value.m_var_type_current == ObjType::Fraction) { + m_fraction->operator+=(*(value.m_fraction.get())); + } else { + m_fraction->operator+=(*(value.toType(ObjType::Fraction)->m_fraction.get())); + } + return shared(); + } LOG_RUNTIME("Operator '+' fail for '%s' and '%s'", toString().c_str(), value.toString().c_str()); } @@ -415,6 +424,13 @@ ObjPtr Obj::operator-=(Obj value) { return shared(); } break; + case ObjType::Fraction: + if(value.m_var_type_current == ObjType::Fraction) { + m_fraction->operator-=(*(value.m_fraction.get())); + } else { + m_fraction->operator-=(*(value.toType(ObjType::Fraction)->m_fraction.get())); + } + return shared(); } LOG_RUNTIME("Operator '-' fail for '%s' and '%s'", toString().c_str(), value.toString().c_str()); } @@ -458,6 +474,14 @@ ObjPtr Obj::operator*=(Obj value) { return shared(); } + case ObjType::Fraction: + if(value.m_var_type_current == ObjType::Fraction) { + m_fraction->operator*=(*(value.m_fraction.get())); + } else { + m_fraction->operator*=(*(value.toType(ObjType::Fraction)->m_fraction.get())); + } + return shared(); + } LOG_RUNTIME("Operator '*' fail for '%s' and '%s'", toString().c_str(), value.toString().c_str()); } @@ -467,6 +491,13 @@ ObjPtr Obj::operator/=(Obj value) { testResultIntegralType(ObjType::Double, false); m_value.div_(value.m_value); return shared(); + } else if(m_var_type_current == ObjType::Fraction) { + if(value.m_var_type_current == ObjType::Fraction) { + m_fraction->operator/=(*(value.m_fraction.get())); + } else { + m_fraction->operator/=(*(value.toType(ObjType::Fraction)->m_fraction.get())); + } + return shared(); } LOG_RUNTIME("Operator '/' fail for '%s' and '%s'", toString().c_str(), value.toString().c_str()); } @@ -478,6 +509,13 @@ ObjPtr Obj::op_div_ceil_(Obj & value) { m_value.div_(value.m_value, "floor"); m_value = m_value.toType(toTorchType(type)); return shared(); + } else if(m_var_type_current == ObjType::Fraction) { + // if(value.m_var_type_current == ObjType::Fraction) { + // m_fraction->operator/=(value.m_fraction); + // } else { + // m_fraction->operator/=(value.toType(ObjPtr::Fraction)->m_fraction); + // } + // return shared(); } LOG_RUNTIME("Operator '//' fail for '%s' and '%s'", toString().c_str(), value.toString().c_str()); } @@ -487,6 +525,13 @@ ObjPtr Obj::operator%=(Obj value) { testResultIntegralType(value.m_var_type_current, false); m_value.fmod_(value.m_value); return shared(); + } else if(m_var_type_current == ObjType::Fraction) { + // if(value.m_var_type_current == ObjType::Fraction) { + // m_fraction->operator*=(value.m_fraction); + // } else { + // m_fraction->operator*=(value.toType(ObjPtr::Fraction)->m_fraction); + // } + // return shared(); } LOG_RUNTIME("Operator '%%' fail for '%s' and '%s'", toString().c_str(), value.toString().c_str()); } @@ -1407,25 +1452,30 @@ bool Obj::op_duck_test_prop(Obj *base, Obj *value, bool strong) { } ObjPtr Obj::op_pow_(Obj & obj) { - if(obj.is_arithmetic_type()) { - if(is_tensor()) { - m_value.pow_(obj.toTensor()); - return shared(); - } else if(is_arithmetic_type()) { - if(is_integer()) { - SetValue_(static_cast (pow(GetValueAsInteger(), obj.GetValueAsInteger()) + 0.5)); - return shared(); - } else if(isFloatingType(m_var_type_current)) { - SetValue_(pow(GetValueAsNumber(), obj.GetValueAsNumber())); - return shared(); - } - } else if(m_var_type_current == ObjType::StrChar && obj.is_integer()) { - m_str = repeat(m_str, obj.GetValueAsInteger()); + if(is_tensor()) { + m_value.pow_(obj.toTensor()); + return shared(); + } else if(is_arithmetic_type()) { + if(is_integer()) { + SetValue_(static_cast (pow(GetValueAsInteger(), obj.GetValueAsInteger()) + 0.5)); return shared(); - } else if(m_var_type_current == ObjType::StrWide && obj.is_integer()) { - m_wstr = repeat(m_wstr, obj.GetValueAsInteger()); + } else if(isFloatingType(m_var_type_current)) { + SetValue_(pow(GetValueAsNumber(), obj.GetValueAsNumber())); return shared(); } + } else if(m_var_type_current == ObjType::StrChar && obj.is_integer()) { + m_str = repeat(m_str, obj.GetValueAsInteger()); + return shared(); + } else if(m_var_type_current == ObjType::StrWide && obj.is_integer()) { + m_wstr = repeat(m_wstr, obj.GetValueAsInteger()); + return shared(); + } else if(m_var_type_current == ObjType::Fraction) { + // if(value.m_var_type_current == ObjType::Fraction) { + // m_fraction->op_pow_(value.m_fraction); + // } else { + // m_fraction->op_pow_(value.toType(ObjPtr::Fraction)->m_fraction); + // } + // return shared(); } LOG_RUNTIME("Unsupported power operator for '%s' and '%s'!", toString().c_str(), obj.toString().c_str()); } diff --git a/src/test/eval_test.cpp b/src/test/eval_test.cpp index 6c633b0e..998e4a6f 100644 --- a/src/test/eval_test.cpp +++ b/src/test/eval_test.cpp @@ -966,19 +966,35 @@ TEST_F(OpEvalTest, Ops) { ASSERT_STREQ("5.1", Test("1.1+4")); ASSERT_STREQ("5.5", Test("1+4.5")); + ASSERT_STREQ("10\\1", Test("10\\1")); + ASSERT_STREQ("32\\1", Test("10\\1+22\\1")); + ASSERT_STREQ("5\\1", Test("4\\5 + 42\\10")); + ASSERT_STREQ("11\\1", Test("10\\1 + 1")); + ASSERT_STREQ("4\\3", Test("1\\3 + 1")); + ASSERT_STREQ("-12", Test("10 - 22")); ASSERT_STREQ("-2.9", Test("1.1 - 4")); ASSERT_STREQ("-3.5", Test("1 - 4.5")); + ASSERT_STREQ("-17\\5", Test("4\\5 - 42\\10")); + ASSERT_STREQ("-9\\10", Test("1\\10 - 1")); + ASSERT_STREQ("-2\\3", Test("1\\3 - 1")); ASSERT_STREQ("66", Test("2 * 33")); ASSERT_STREQ("-5.5", Test("1.1 * -5")); ASSERT_STREQ("180", Test("10 * 18")); + ASSERT_STREQ("66\\1", Test("2\\1 * 66\\2")); + ASSERT_STREQ("-15\\1", Test("3\\1 * -5")); + ASSERT_STREQ("9\\5", Test("18\\100 * 10")); ASSERT_STREQ("5", Test("10/2")); ASSERT_STREQ("5.05", Test("10.1 / 2")); ASSERT_STREQ("0.1", Test("1 / 10")); ASSERT_STREQ("0.1", Test("1.0 / 10")); + ASSERT_STREQ("4\\3", Test("12\\3 / 3")); + ASSERT_STREQ("1\\1", Test("5\\10 / 1\\2")); + ASSERT_STREQ("1\\100", Test("1\\10 / 10")); + ASSERT_STREQ("5", Test("10//2")); ASSERT_STREQ("5", Test("10.0 // 2")); ASSERT_STREQ("0", Test("1 // 10")); From 21cbaaaabda248b4021fe7ee805f7e1e70eb03e9 Mon Sep 17 00:00:00 2001 From: Aleksandr Ryabikov Date: Sat, 9 Jul 2022 18:02:46 +0300 Subject: [PATCH 16/31] =?UTF-8?q?=D0=9F=D0=B5=D1=80=D0=B5=D0=B4=D0=B5?= =?UTF-8?q?=D0=BB=D0=B0=D0=BD=20=D1=88=D0=B0=D0=B1=D0=BB=D0=BE=D0=BD=20?= =?UTF-8?q?=D0=BA=D0=BE=D0=BD=D1=82=D0=B5=D0=B9=D0=BD=D0=B5=D1=80=20=D0=B8?= =?UTF-8?q?=20=D0=B1=D0=B0=D0=B7=D0=BE=D0=B2=D1=8B=D0=B5=20=D0=B8=D1=82?= =?UTF-8?q?=D0=B5=D1=80=D0=B0=D1=82=D0=BE=D1=80=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- contrib/logger/logger.h | 159 +++++----- {src => examples}/dsl.nlp | 2 +- examples/fileio.nlp | 2 +- examples/foreach.nlp | 96 ++++++ src/builtin.cpp | 14 +- src/context.cpp | 187 +++++------ src/context.h | 29 +- src/nbproject/Makefile-Debug.mk | 55 ++-- src/nbproject/Makefile-variables.mk | 4 +- src/nbproject/Package-Debug.bash | 2 +- src/nbproject/configurations.xml | 8 +- src/newlang.cpp | 20 +- src/newlang.h | 7 +- src/nlc.h | 50 +-- src/object.cpp | 389 +++++++++++++---------- src/object.h | 263 ++++++++++++--- src/parser.h | 8 +- src/pch.h | 2 +- src/term.h | 2 +- src/test/alg_test.cpp | 64 ++-- src/test/compiler_test.cpp | 2 +- src/test/eval_test.cpp | 81 ++--- src/test/object_test.cpp | 302 +++++++++++++----- src/test/parser_test.cpp | 126 ++++---- src/types.h | 46 +-- src/variable.h | 476 ++++------------------------ src/win/nlc.vcxproj | 7 +- 27 files changed, 1258 insertions(+), 1145 deletions(-) rename {src => examples}/dsl.nlp (97%) create mode 100644 examples/foreach.nlp diff --git a/contrib/logger/logger.h b/contrib/logger/logger.h index d7163ab3..c1085dde 100644 --- a/contrib/logger/logger.h +++ b/contrib/logger/logger.h @@ -39,7 +39,13 @@ #define TO_STR(ARG) TO_STR2(ARG) #endif - +// Use: #pragma message WARNING("My message") +#if _MSC_VER +#define FILE_LINE_LINK __FILE__ "(" TO_STR(__LINE__) ") : " +#define WARNING(exp) (FILE_LINE_LINK "WARNING: " exp) +#else//__GNUC__ - may need other defines for different compilers +#define WARNING(exp) ("WARNING: " exp) +#endif #ifndef ASSERT @@ -205,96 +211,97 @@ EXTERN_C void log_print_callstack(); namespace utils { -class Logger { -public: - typedef uint8_t LogLevelType; - typedef void FuncCallback(void *param, LogLevelType level, const char * str, bool flush); + class Logger { + public: + typedef uint8_t LogLevelType; + typedef void FuncCallback(void *param, LogLevelType level, const char * str, bool flush); + + inline LogLevelType GetLogLevel() { + return m_level; + } - inline LogLevelType GetLogLevel() { - return m_level; - } + inline LogLevelType GetLogLevelNormal() { + return LOG_LEVEL_NORMAL; + } - inline LogLevelType GetLogLevelNormal() { - return LOG_LEVEL_NORMAL; - } + inline LogLevelType SetLogLevel(const LogLevelType level) { + LogLevelType prev_level = m_level; + if (level >= LOG_LEVEL_ABORT && level <= LOG_LEVEL_MAX) { + m_level = level; + } else { + m_level = LOG_LEVEL_NORMAL; + } + return prev_level; + } - inline LogLevelType SetLogLevel(const LogLevelType level) { - LogLevelType prev_level = m_level; - if (level >= LOG_LEVEL_ABORT && level <= LOG_LEVEL_MAX) { - m_level = level; - } else { - m_level = LOG_LEVEL_NORMAL; + inline bool SetPrintCallstack(bool enable) { + bool prev = m_print_callstack; + m_print_callstack = enable; + return prev; + } + + inline bool GetPrintCallstack() { + return m_print_callstack; } - return prev_level; - } - - inline bool SetPrintCallstack(bool enable) { - bool prev = m_print_callstack; - m_print_callstack = enable; - return prev; - } - inline bool GetPrintCallstack() { - return m_print_callstack; - } - - static void PrintfCallback(void *param, LogLevelType level, const char * str, bool flush) { - _UNUSED(param); - _UNUSED(level); - fprintf(stdout, "%s", str); - if (flush) { - fflush(stdout); + + static void PrintfCallback(void *param, LogLevelType level, const char * str, bool flush) { + _UNUSED(param); + _UNUSED(level); + fprintf(stdout, "%s", str); + if (flush) { + fflush(stdout); + } } - } - void SetCallback(FuncCallback * func, void * param) { - m_func = func; - m_func_param = param; - } + void SetCallback(FuncCallback * func, void * param) { + m_func = func; + m_func_param = param; + } - void SaveCallback(FuncCallback *&func, void * ¶m) { - func = m_func; - param = m_func_param; - } + void SaveCallback(FuncCallback *&func, void * ¶m) { + func = m_func; + param = m_func_param; + } - void Clear(); - const char * AddString(LogLevelType level, char const *string, bool flush); - static const char * GetLogLevelDesc(LogLevelType level); + void Clear(); + const char * AddString(LogLevelType level, char const *string, bool flush); + static const char * GetLogLevelDesc(LogLevelType level); - uint16_t GetDump(uint8_t *data, uint16_t max_size); - uint16_t GetDumpSize(); + uint16_t GetDump(uint8_t *data, uint16_t max_size); + uint16_t GetDumpSize(); - static inline Logger * Instance() { - // Шаблон с определением static Logger m_instance; собирается с warning в MinGW - if (m_instance == nullptr) { - m_instance = new Logger(); + static inline Logger * Instance() { + // Шаблон с определением static Logger m_instance; собирается с warning в MinGW + if (m_instance == nullptr) { + m_instance = new Logger(); + } + return m_instance; } - return m_instance; - } -private: + private: - Logger() { - m_level = LOG_LEVEL_NORMAL; + Logger() { + m_level = LOG_LEVEL_NORMAL; #ifdef USE_HAL_DRIVER - STATIC_ASSERT(LOG_LEVEL_MAX < LOG_LEVEL_DUMP); - STATIC_ASSERT(LOG_LEVEL_NORMAL <= LOG_LEVEL_DEBUG); - m_func = nullptr; + STATIC_ASSERT(LOG_LEVEL_MAX < LOG_LEVEL_DUMP); + STATIC_ASSERT(LOG_LEVEL_NORMAL <= LOG_LEVEL_DEBUG); + m_func = nullptr; #else - m_func = &PrintfCallback; + m_func = &PrintfCallback; #endif - m_func_param = nullptr; - m_print_callstack = false; - } - Logger(const Logger&) = delete; - const Logger& operator=(const Logger&) = delete; - - virtual ~Logger() { - } - static Logger * m_instance; - LogLevelType m_level; - FuncCallback *m_func; - void * m_func_param; - bool m_print_callstack; -}; + m_func_param = nullptr; + m_print_callstack = false; + } + Logger(const Logger&) = delete; + const Logger& operator=(const Logger&) = delete; + + virtual ~Logger() { + } + static Logger * m_instance; + LogLevelType m_level; + FuncCallback *m_func; + void * m_func_param; + bool m_print_callstack; + }; } #endif diff --git a/src/dsl.nlp b/examples/dsl.nlp similarity index 97% rename from src/dsl.nlp rename to examples/dsl.nlp index b3e87712..400cf2dc 100755 --- a/src/dsl.nlp +++ b/examples/dsl.nlp @@ -1,4 +1,4 @@ -#!./nlc --eval +#!../output/nlc --eval # Example implementation DSL — domain-specific language for english # Macros implementation name:"\name", body start: "\\", body end: "\\\", replace var_args \$* diff --git a/examples/fileio.nlp b/examples/fileio.nlp index 1c871fb2..4a013c19 100644 --- a/examples/fileio.nlp +++ b/examples/fileio.nlp @@ -93,4 +93,4 @@ SEEK ::= :Enum(SET=0, CUR=1, END=2); #extern int ftrylockfile (FILE *__stream) __THROW __wur; #extern void funlockfile (FILE *__stream) __THROW; -"Load fileio.nlp - OK"; \ No newline at end of file +"OK"; \ No newline at end of file diff --git a/examples/foreach.nlp b/examples/foreach.nlp new file mode 100644 index 00000000..4a013c19 --- /dev/null +++ b/examples/foreach.nlp @@ -0,0 +1,96 @@ + +:File ::= :Pointer; + +@stdin:File ::= :Pointer("_IO_2_1_stdin_:File"); +@stdout:File ::= :Pointer("_IO_2_1_stdout_:File"); +@stderr:File ::= :Pointer("stderr:File"); + +@fopen(filename:String, modes:String):File ::= :Pointer("fopen(filename:StrChar, modes:StrChar):File");; +@fopen64(filename:String, modes:String):File ::= :Pointer("fopen(filename:StrChar, modes:StrChar):File");; + +@freopen(filename:String, modes:String):File ::= :Pointer("freopen(filename:StrChar, modes:StrChar, stream:File):File");; +@freopen64(filename:String, modes:String):File ::= :Pointer("freopen64(filename:StrChar, modes:StrChar, stream:File):File");; + +#extern FILE *fdopen (int __fd, const char *__modes) __THROW __wur; + +@fclose(stream:File):Int ::= :Pointer("fclose(stream:File):Int");; +@fcloseall():Int ::= :Pointer("fcloseall():Int");; + +@fflush(stream:File):Int ::= :Pointer("fflush(stream:File):Int");; +@fflush_unlocked(stream:File):Int ::= :Pointer("fflush_unlocked(stream:File):Int");; + +@fremove(filename:String):Int ::= :Pointer("remove(filename:StrChar):Int");; + +@frename(old:String, new:String):Int ::= :Pointer("rename(old:StrChar, new:StrChar):Int");; + +@ftmpfile():File ::= :Pointer("tmpfile():File");; +@ftmpfile64():File ::= :Pointer("tmpfile64():File");; + +@ftmpnam(template:String):StrChar ::= :Pointer("tmpnam(template:StrChar):StrChar");; +@ftmpnam_r(template:String):StrChar ::= :Pointer("tmpnam(template:StrChar):StrChar");; + +@ftempnam(dir:String, prefix:String):StrChar ::= :Pointer("tempnam(dir:StrChar, prefix:StrChar):StrChar");; + + + +@fprintf(stream:File, format:Format, ...):Int ::= :Pointer("fprintf(stream:File, format:Format, ...):Int");; +@fscanf(stream:File, format:Format, ...):Int ::= :Pointer("fscanf(stream:File, format:Format, ...):Int");; + +@fgetc(stream:File):Int ::= :Pointer("fgetc(stream:File):Int");; + +@fgetc_unlocked(stream:File):Int ::= :Pointer("fgetc_unlocked(stream:File):Int");; + +@fungetc(c:Int, stream:File):Int ::= :Pointer("ungetc(c:Int, stream:File):Int");; + +@fputc(c:Int, stream:File):Int ::= :Pointer("fputc(c:Int, stream:File):Int");; +@fputs(string:String, stream:File):Int ::= :Pointer("fputs(c:StrChar, stream:File):Int");; + + +#extern size_t fread (void *__restrict __ptr, size_t __size, +# size_t __n, FILE *__restrict __stream) __wur; +# +#extern size_t fwrite (const void *__restrict __ptr, size_t __size, +# size_t __n, FILE *__restrict __s); + + +#extern size_t fread_unlocked (void *__restrict __ptr, size_t __size, +# size_t __n, FILE *__restrict __stream) __wur; +#extern size_t fwrite_unlocked (const void *__restrict __ptr, size_t __size, +# size_t __n, FILE *__restrict __stream); +# +SEEK ::= :Enum(SET=0, CUR=1, END=2); +@fseek(stream:File, offset:Long, whence:Int):Int ::= :Pointer("fseek(stream:File, offset:Long, whence:Int):Int");; + + +#extern long int ftell (FILE *__stream) __wur; +#extern void rewind (FILE *__stream); +#extern int fseeko (FILE *__stream, __off_t __off, int __whence); +#extern __off_t ftello (FILE *__stream) __wur; + + + +#extern int fgetpos (FILE *__restrict __stream, fpos_t *__restrict __pos); +#extern int fsetpos (FILE *__stream, const fpos_t *__pos); + +#extern int fseeko64 (FILE *__stream, __off64_t __off, int __whence); +#extern __off64_t ftello64 (FILE *__stream) __wur; +#extern int fgetpos64 (FILE *__restrict __stream, fpos64_t *__restrict __pos); +#extern int fsetpos64 (FILE *__stream, const fpos64_t *__pos); +#extern void clearerr (FILE *__stream) __THROW; +#extern int feof (FILE *__stream) __THROW __wur; +#extern int ferror (FILE *__stream) __THROW __wur; + +#extern void clearerr_unlocked (FILE *__stream) __THROW; +#extern int feof_unlocked (FILE *__stream) __THROW __wur; +#extern int ferror_unlocked (FILE *__stream) __THROW __wur; + +#extern void perror (const char *__s); + +#extern int fileno (FILE *__stream) __THROW __wur; +#extern int fileno_unlocked (FILE *__stream) __THROW __wur; + +#extern void flockfile (FILE *__stream) __THROW; +#extern int ftrylockfile (FILE *__stream) __THROW __wur; +#extern void funlockfile (FILE *__stream) __THROW; + +"OK"; \ No newline at end of file diff --git a/src/builtin.cpp b/src/builtin.cpp index 3199b54d..97754541 100644 --- a/src/builtin.cpp +++ b/src/builtin.cpp @@ -42,21 +42,21 @@ namespace newlang { if(in.size() != 2) { LOG_RUNTIME("Bad argument count parameter!"); } - return in[1]->Clone(nullptr); + return in[1].second->Clone(nullptr); } NEWLANG_FUNCTION(const_) { if(in.size() != 2) { LOG_RUNTIME("Bad argument count parameter!"); } - return in[1]->MakeConst(); + return in[1].second->MakeConst(); } NEWLANG_FUNCTION(mutable_) { if(in.size() != 2) { LOG_RUNTIME("Bad argument count parameter!"); } - return in[1]->MakeMutable(); + return in[1].second->MakeMutable(); } // NEWLANG_FUNCTION(import) { @@ -105,13 +105,13 @@ bool BuiltInTorchDirect::CheckDirect(CompileInfo &ci, TermPtr &term, std::string return true; } else if(term->size() == 1) { - if((*term)[0]->IsScalar() && m_tensor_scalar.find(term->getText()) != m_tensor_scalar.end()) { - output += "->asTensor_()." + term->getText() + "(" + (*term)[0]->getText() + "), " + output; + if((*term)[0].second->IsScalar() && m_tensor_scalar.find(term->getText()) != m_tensor_scalar.end()) { + output += "->asTensor_()." + term->getText() + "(" + (*term)[0].second->getText() + "), " + output; return true; - } else if((*term)[0]->getTermID() == TermID::TERM) { + } else if((*term)[0].second->getTermID() == TermID::TERM) { std::string temp; - NewLang::GetImpl(ci, (*term)[0], temp); + NewLang::GetImpl(ci, (*term)[0].second, temp); output += "->asTensor_()." + term->getText() + "(" + temp + "->asTensor_()), " + output; return true; } diff --git a/src/context.cpp b/src/context.cpp index b9b4b7ba..e91ba540 100644 --- a/src/context.cpp +++ b/src/context.cpp @@ -232,7 +232,7 @@ void newlang::NewLangSignalHandler(int signal) { //#include "StdCapture.h" -ObjPtr Context::ExecStr(Context *ctx, TermPtr term, Obj *args, bool int_catch) { +ObjPtr Context::Eval(Context *ctx, TermPtr term, Obj *args, bool int_catch) { // StdCapture Capture; // @@ -267,7 +267,7 @@ ObjPtr Context::ExecStr(Context *ctx, TermPtr term, Obj *args, bool int_catch) { if(int_catch && obj.m_obj->getType() == ObjType::Return) { ASSERT(obj.m_obj->size() == 1); - return (*obj.m_obj)[0]; // Возврат данных + return (*obj.m_obj)[0].second; // Возврат данных } else if(int_catch) { ASSERT(obj.m_obj); @@ -500,13 +500,13 @@ ObjPtr Context::CREATE_OR_ASSIGN(Context *ctx, const TermPtr &term, Obj *local_v } else if(elem->getTermID() == TermID::NONE) { result = Obj::CreateNone(); } else { - auto found = ctx->select(elem->m_text); - if(found.complete() && mode == CreateMode::ASSIGN_ONLY) { + auto found = ctx->find(elem->m_text); + if(found == ctx->end() && mode == CreateMode::ASSIGN_ONLY) { NL_PARSER(elem, "Variable '%s' not found!", elem->m_text.c_str()); } - if(!found.complete()) { - result = (*found).lock(); // Но она может быть возвращена как локальная + if(found != ctx->end()) { + result = (*found).second.lock(); // Но она может быть возвращена как локальная } if(result && mode == CreateMode::CREATE_ONLY) { @@ -514,7 +514,7 @@ ObjPtr Context::CREATE_OR_ASSIGN(Context *ctx, const TermPtr &term, Obj *local_v } if(!term->Right()) { // Удаление глобальной переменной - ctx->erase(found); + ctx->ListType::erase(found); } else { if(!result && (mode == CreateMode::ASSIGN_ONLY)) { NL_PARSER(term->Left(), "Object '%s' not found!", term->Left()->m_text.c_str()); @@ -545,9 +545,9 @@ ObjPtr Context::CREATE_OR_ASSIGN(Context *ctx, const TermPtr &term, Obj *local_v ObjPtr rval; if(term->Right()->getTermID() == TermID::ELLIPSIS) { ASSERT(term->Right()->Right()); - rval = ExecStr(ctx, term->Right()->Right(), local_vars, false); + rval = Eval(ctx, term->Right()->Right(), local_vars, false); } else { - rval = ExecStr(ctx, term->Right(), local_vars, false); + rval = Eval(ctx, term->Right(), local_vars, false); } if(!rval) { NL_PARSER(term->Right(), "Object is missing or expression is not evaluated!"); @@ -563,7 +563,7 @@ ObjPtr Context::CREATE_OR_ASSIGN(Context *ctx, const TermPtr &term, Obj *local_v for (int i = 0; i < list_obj.size() - 1; i++) { if(list_term[i]->getTermID() != TermID::NONE) { if(i < rval->size()) { - list_obj[i]->SetValue_((*rval)[i]); //->Clone() + list_obj[i]->SetValue_((*rval)[i].second); //->Clone() } else { list_obj[i]->SetValue_(Obj::CreateNone()); } @@ -642,10 +642,10 @@ ObjPtr Context::eval_FUNCTION(Context *ctx, const TermPtr &term, Obj * args) { ASSERT(term->Left()); ASSERT(ctx); - auto found = ctx->select(term->Left()->m_text); + auto found = ctx->find(term->Left()->m_text); if(!term->Right()) { - if(!found.complete()) { - ctx->erase(found); + if(found != ctx->end()) { + ctx->ListType::erase(found); return Obj::Yes(); } return Obj::No(); @@ -744,7 +744,7 @@ ObjPtr Context::eval_WHILE(Context *ctx, const TermPtr &term, Obj * args) { ASSERT(term->Right()); ObjPtr result = Obj::CreateNone(); - ObjPtr cond = ExecStr(ctx, term->Left(), args, false); + ObjPtr cond = Eval(ctx, term->Left(), args, false); while(cond->GetValueAsBoolean()) { try { @@ -752,7 +752,7 @@ ObjPtr Context::eval_WHILE(Context *ctx, const TermPtr &term, Obj * args) { LOG_DEBUG("result %s", result->toString().c_str()); result = CreateRVal(ctx, term->Right(), args, false); - cond = ExecStr(ctx, term->Left(), args, false); + cond = Eval(ctx, term->Left(), args, false); } catch (Interrupt &obj) { @@ -780,7 +780,7 @@ ObjPtr Context::eval_DOWHILE(Context *ctx, const TermPtr &term, Obj * args) { try { result = CreateRVal(ctx, term->Left(), args, false); - cond = ExecStr(ctx, term->Right(), args, false); + cond = Eval(ctx, term->Right(), args, false); } catch (Interrupt &obj) { @@ -811,7 +811,7 @@ ObjPtr Context::eval_FOLLOW(Context *ctx, const TermPtr &term, Obj * args) { for (int64_t i = 0; i < static_cast (term->m_follow.size()); i++) { ASSERT(term->m_follow[i]->Left()); - ObjPtr cond = ExecStr(ctx, term->m_follow[i]->Left(), args, false); + ObjPtr cond = Eval(ctx, term->m_follow[i]->Left(), args, false); if(cond->GetValueAsBoolean() || (i + 1 == term->m_follow.size() && cond->is_none_type())) { @@ -958,7 +958,7 @@ ObjPtr Context::op_EQUAL(Context *ctx, const TermPtr &term, Obj * args) { ASSERT(term->Left()); ASSERT(term->Right()); - return ExecStr(ctx, term->Left(), args)->op_equal(ExecStr(ctx, term->Right(), args)) ? Obj::Yes() : Obj::No(); + return Eval(ctx, term->Left(), args)->op_equal(Eval(ctx, term->Right(), args)) ? Obj::Yes() : Obj::No(); } ObjPtr Context::op_ACCURATE(Context *ctx, const TermPtr &term, Obj * args) { @@ -966,7 +966,7 @@ ObjPtr Context::op_ACCURATE(Context *ctx, const TermPtr &term, Obj * args) { ASSERT(term->Left()); ASSERT(term->Right()); - return ExecStr(ctx, term->Left(), args)->op_accurate(ExecStr(ctx, term->Right(), args)) ? Obj::Yes() : Obj::No(); + return Eval(ctx, term->Left(), args)->op_accurate(Eval(ctx, term->Right(), args)) ? Obj::Yes() : Obj::No(); } ObjPtr Context::op_NE(Context *ctx, const TermPtr &term, Obj * args) { @@ -974,7 +974,7 @@ ObjPtr Context::op_NE(Context *ctx, const TermPtr &term, Obj * args) { ASSERT(term->Left()); ASSERT(term->Right()); - return ExecStr(ctx, term->Left(), args)->operator!=(ExecStr(ctx, term->Right(), args)) ? Obj::Yes() : Obj::No(); + return Eval(ctx, term->Left(), args)->operator!=(Eval(ctx, term->Right(), args)) ? Obj::Yes() : Obj::No(); } ObjPtr Context::op_LT(Context *ctx, const TermPtr &term, Obj * args) { @@ -982,7 +982,7 @@ ObjPtr Context::op_LT(Context *ctx, const TermPtr &term, Obj * args) { ASSERT(term->Left()); ASSERT(term->Right()); - return ExecStr(ctx, term->Left(), args)->operator<(ExecStr(ctx, term->Right(), args)) ? Obj::Yes() : Obj::No(); + return Eval(ctx, term->Left(), args)->operator<(Eval(ctx, term->Right(), args)) ? Obj::Yes() : Obj::No(); } ObjPtr Context::op_GT(Context *ctx, const TermPtr &term, Obj * args) { @@ -990,7 +990,7 @@ ObjPtr Context::op_GT(Context *ctx, const TermPtr &term, Obj * args) { ASSERT(term->Left()); ASSERT(term->Right()); - return ExecStr(ctx, term->Left(), args)->operator>(ExecStr(ctx, term->Right(), args)) ? Obj::Yes() : Obj::No(); + return Eval(ctx, term->Left(), args)->operator>(Eval(ctx, term->Right(), args)) ? Obj::Yes() : Obj::No(); } ObjPtr Context::op_LE(Context *ctx, const TermPtr &term, Obj * args) { @@ -998,7 +998,7 @@ ObjPtr Context::op_LE(Context *ctx, const TermPtr &term, Obj * args) { ASSERT(term->Left()); ASSERT(term->Right()); - return ExecStr(ctx, term->Left(), args)->operator<=(ExecStr(ctx, term->Right(), args)) ? Obj::Yes() : Obj::No(); + return Eval(ctx, term->Left(), args)->operator<=(Eval(ctx, term->Right(), args)) ? Obj::Yes() : Obj::No(); } ObjPtr Context::op_GE(Context *ctx, const TermPtr &term, Obj * args) { @@ -1006,7 +1006,7 @@ ObjPtr Context::op_GE(Context *ctx, const TermPtr &term, Obj * args) { ASSERT(term->Left()); ASSERT(term->Right()); - return ExecStr(ctx, term->Left(), args)->operator>=(ExecStr(ctx, term->Right(), args)) ? Obj::Yes() : Obj::No(); + return Eval(ctx, term->Left(), args)->operator>=(Eval(ctx, term->Right(), args)) ? Obj::Yes() : Obj::No(); } /* @@ -1019,7 +1019,7 @@ ObjPtr Context::op_AND(Context *ctx, const TermPtr &term, Obj * args) { ASSERT(term->Left()); ASSERT(term->Right()); - return ExecStr(ctx, term->Left(), args)->op_bit_and(ExecStr(ctx, term->Right(), args), false); + return Eval(ctx, term->Left(), args)->op_bit_and(Eval(ctx, term->Right(), args), false); } ObjPtr Context::op_OR(Context *ctx, const TermPtr &term, Obj * args) { @@ -1079,9 +1079,9 @@ ObjPtr Context::op_PLUS(Context *ctx, const TermPtr &term, Obj * args) { ASSERT(term->Right()); if(term->Left()) { - return ExecStr(ctx, term->Left(), args)->operator+(ExecStr(ctx, term->Right(), args)); + return Eval(ctx, term->Left(), args)->operator+(Eval(ctx, term->Right(), args)); } - return ExecStr(ctx, term->Left(), args)->operator+(); + return Eval(ctx, term->Left(), args)->operator+(); } ObjPtr Context::op_MINUS(Context *ctx, const TermPtr &term, Obj * args) { @@ -1089,9 +1089,9 @@ ObjPtr Context::op_MINUS(Context *ctx, const TermPtr &term, Obj * args) { ASSERT(term->Right()); if(term->Left()) { - return ExecStr(ctx, term->Left(), args)->operator-(ExecStr(ctx, term->Right(), args)); + return Eval(ctx, term->Left(), args)->operator-(Eval(ctx, term->Right(), args)); } - return ExecStr(ctx, term->Left(), args)->operator-(); + return Eval(ctx, term->Left(), args)->operator-(); } ObjPtr Context::op_DIV(Context *ctx, const TermPtr &term, Obj * args) { @@ -1099,7 +1099,7 @@ ObjPtr Context::op_DIV(Context *ctx, const TermPtr &term, Obj * args) { ASSERT(term->Left()); ASSERT(term->Right()); - return ExecStr(ctx, term->Left(), args)->operator/(ExecStr(ctx, term->Right(), args)); + return Eval(ctx, term->Left(), args)->operator/(Eval(ctx, term->Right(), args)); } ObjPtr Context::op_DIV_CEIL(Context *ctx, const TermPtr &term, Obj * args) { @@ -1107,7 +1107,7 @@ ObjPtr Context::op_DIV_CEIL(Context *ctx, const TermPtr &term, Obj * args) { ASSERT(term->Left()); ASSERT(term->Right()); - return ExecStr(ctx, term->Left(), args)->op_div_ceil(ExecStr(ctx, term->Right(), args)); + return Eval(ctx, term->Left(), args)->op_div_ceil(Eval(ctx, term->Right(), args)); } ObjPtr Context::op_MUL(Context *ctx, const TermPtr &term, Obj * args) { @@ -1115,7 +1115,7 @@ ObjPtr Context::op_MUL(Context *ctx, const TermPtr &term, Obj * args) { ASSERT(term->Left()); ASSERT(term->Right()); - return ExecStr(ctx, term->Left(), args)->operator*(ExecStr(ctx, term->Right(), args)); + return Eval(ctx, term->Left(), args)->operator*(Eval(ctx, term->Right(), args)); } ObjPtr Context::op_REM(Context *ctx, const TermPtr &term, Obj * args) { @@ -1123,7 +1123,7 @@ ObjPtr Context::op_REM(Context *ctx, const TermPtr &term, Obj * args) { ASSERT(term->Left()); ASSERT(term->Right()); - return ExecStr(ctx, term->Left(), args)->operator%(ExecStr(ctx, term->Right(), args)); + return Eval(ctx, term->Left(), args)->operator%(Eval(ctx, term->Right(), args)); } ObjPtr Context::op_POW(Context *ctx, const TermPtr &term, Obj * args) { @@ -1131,7 +1131,7 @@ ObjPtr Context::op_POW(Context *ctx, const TermPtr &term, Obj * args) { ASSERT(term->Left()); ASSERT(term->Right()); - return ExecStr(ctx, term->Left(), args)->op_pow(ExecStr(ctx, term->Right(), args)); + return Eval(ctx, term->Left(), args)->op_pow(Eval(ctx, term->Right(), args)); } /* @@ -1143,7 +1143,7 @@ ObjPtr Context::op_PLUS_(Context *ctx, const TermPtr &term, Obj * args) { ASSERT(term->Left()); ASSERT(term->Right()); - return ExecStr(ctx, term->Left(), args)->operator+=(ExecStr(ctx, term->Right(), args)); + return Eval(ctx, term->Left(), args)->operator+=(Eval(ctx, term->Right(), args)); } ObjPtr Context::op_MINUS_(Context *ctx, const TermPtr &term, Obj * args) { @@ -1151,7 +1151,7 @@ ObjPtr Context::op_MINUS_(Context *ctx, const TermPtr &term, Obj * args) { ASSERT(term->Left()); ASSERT(term->Right()); - return ExecStr(ctx, term->Left(), args)->operator-=(ExecStr(ctx, term->Right(), args)); + return Eval(ctx, term->Left(), args)->operator-=(Eval(ctx, term->Right(), args)); } ObjPtr Context::op_DIV_(Context *ctx, const TermPtr &term, Obj * args) { @@ -1159,7 +1159,7 @@ ObjPtr Context::op_DIV_(Context *ctx, const TermPtr &term, Obj * args) { ASSERT(term->Left()); ASSERT(term->Right()); - return ExecStr(ctx, term->Left(), args)->operator/=(ExecStr(ctx, term->Right(), args)); + return Eval(ctx, term->Left(), args)->operator/=(Eval(ctx, term->Right(), args)); } ObjPtr Context::op_DIV_CEIL_(Context *ctx, const TermPtr &term, Obj * args) { @@ -1167,7 +1167,7 @@ ObjPtr Context::op_DIV_CEIL_(Context *ctx, const TermPtr &term, Obj * args) { ASSERT(term->Left()); ASSERT(term->Right()); - return ExecStr(ctx, term->Left(), args)->op_div_ceil_(ExecStr(ctx, term->Right(), args)); + return Eval(ctx, term->Left(), args)->op_div_ceil_(Eval(ctx, term->Right(), args)); } ObjPtr Context::op_MUL_(Context *ctx, const TermPtr &term, Obj * args) { @@ -1175,7 +1175,7 @@ ObjPtr Context::op_MUL_(Context *ctx, const TermPtr &term, Obj * args) { ASSERT(term->Left()); ASSERT(term->Right()); - return ExecStr(ctx, term->Left(), args)->operator*=(ExecStr(ctx, term->Right(), args)); + return Eval(ctx, term->Left(), args)->operator*=(Eval(ctx, term->Right(), args)); } ObjPtr Context::op_REM_(Context *ctx, const TermPtr &term, Obj * args) { @@ -1183,7 +1183,7 @@ ObjPtr Context::op_REM_(Context *ctx, const TermPtr &term, Obj * args) { ASSERT(term->Left()); ASSERT(term->Right()); - return ExecStr(ctx, term->Left(), args)->operator%=(ExecStr(ctx, term->Right(), args)); + return Eval(ctx, term->Left(), args)->operator%=(Eval(ctx, term->Right(), args)); } ObjPtr Context::op_POW_(Context *ctx, const TermPtr &term, Obj * args) { @@ -1191,7 +1191,7 @@ ObjPtr Context::op_POW_(Context *ctx, const TermPtr &term, Obj * args) { ASSERT(term->Left()); ASSERT(term->Right()); - return ExecStr(ctx, term->Left(), args)->op_pow_(ExecStr(ctx, term->Right(), args)); + return Eval(ctx, term->Left(), args)->op_pow_(Eval(ctx, term->Right(), args)); } ObjPtr Context::op_CONCAT(Context *ctx, const TermPtr &term, Obj * args) { @@ -1199,7 +1199,7 @@ ObjPtr Context::op_CONCAT(Context *ctx, const TermPtr &term, Obj * args) { ASSERT(term->Left()); ASSERT(term->Right()); - return ExecStr(ctx, term->Left(), args)->op_concat_(ExecStr(ctx, term->Right(), args), ConcatMode::Append); + return Eval(ctx, term->Left(), args)->op_concat_(Eval(ctx, term->Right(), args), ConcatMode::Append); } ObjPtr Context::op_TYPE_EQ(Context *ctx, const TermPtr &term, Obj * args) { @@ -1208,9 +1208,9 @@ ObjPtr Context::op_TYPE_EQ(Context *ctx, const TermPtr &term, Obj * args) { ASSERT(term->Right()); if(isType(term->Right()->GetFullName())) { - return Obj::CreateBool(ExecStr(ctx, term->Left(), args)->op_class_test(term->Right()->GetFullName().c_str(), ctx)); + return Obj::CreateBool(Eval(ctx, term->Left(), args)->op_class_test(term->Right()->GetFullName().c_str(), ctx)); } - return Obj::CreateBool(ExecStr(ctx, term->Left(), args)->op_class_test(ExecStr(ctx, term->Right(), args), ctx)); + return Obj::CreateBool(Eval(ctx, term->Left(), args)->op_class_test(Eval(ctx, term->Right(), args), ctx)); } ObjPtr Context::op_TYPE_EQ2(Context *ctx, const TermPtr &term, Obj * args) { @@ -1218,7 +1218,7 @@ ObjPtr Context::op_TYPE_EQ2(Context *ctx, const TermPtr &term, Obj * args) { ASSERT(term->Left()); ASSERT(term->Right()); - return Obj::CreateBool(ExecStr(ctx, term->Left(), args)->op_duck_test(ExecStr(ctx, term->Right(), args), false)); + return Obj::CreateBool(Eval(ctx, term->Left(), args)->op_duck_test(Eval(ctx, term->Right(), args), false)); } ObjPtr Context::op_TYPE_EQ3(Context *ctx, const TermPtr &term, Obj * args) { @@ -1226,7 +1226,7 @@ ObjPtr Context::op_TYPE_EQ3(Context *ctx, const TermPtr &term, Obj * args) { ASSERT(term->Left()); ASSERT(term->Right()); - return Obj::CreateBool(ExecStr(ctx, term->Left(), args)->op_duck_test(ExecStr(ctx, term->Right(), args), true)); + return Obj::CreateBool(Eval(ctx, term->Left(), args)->op_duck_test(Eval(ctx, term->Right(), args), true)); } ObjPtr Context::op_TYPE_NE(Context *ctx, const TermPtr &term, Obj * args) { @@ -1234,9 +1234,9 @@ ObjPtr Context::op_TYPE_NE(Context *ctx, const TermPtr &term, Obj * args) { ASSERT(term->Left()); ASSERT(term->Right()); if(isType(term->Right()->GetFullName())) { - return Obj::CreateBool(!ExecStr(ctx, term->Left(), args)->op_class_test(term->Right()->GetFullName().c_str(), ctx)); + return Obj::CreateBool(!Eval(ctx, term->Left(), args)->op_class_test(term->Right()->GetFullName().c_str(), ctx)); } - return Obj::CreateBool(!ExecStr(ctx, term->Left(), args)->op_class_test(ExecStr(ctx, term->Right(), args), ctx)); + return Obj::CreateBool(!Eval(ctx, term->Left(), args)->op_class_test(Eval(ctx, term->Right(), args), ctx)); } ObjPtr Context::op_TYPE_NE2(Context *ctx, const TermPtr &term, Obj * args) { @@ -1244,7 +1244,7 @@ ObjPtr Context::op_TYPE_NE2(Context *ctx, const TermPtr &term, Obj * args) { ASSERT(term->Left()); ASSERT(term->Right()); - return Obj::CreateBool(!ExecStr(ctx, term->Left(), args)->op_duck_test(ExecStr(ctx, term->Right(), args), false)); + return Obj::CreateBool(!Eval(ctx, term->Left(), args)->op_duck_test(Eval(ctx, term->Right(), args), false)); } ObjPtr Context::op_TYPE_NE3(Context *ctx, const TermPtr &term, Obj * args) { @@ -1252,7 +1252,7 @@ ObjPtr Context::op_TYPE_NE3(Context *ctx, const TermPtr &term, Obj * args) { ASSERT(term->Left()); ASSERT(term->Right()); - return Obj::CreateBool(!ExecStr(ctx, term->Left(), args)->op_duck_test(ExecStr(ctx, term->Right(), args), true)); + return Obj::CreateBool(!Eval(ctx, term->Left(), args)->op_duck_test(Eval(ctx, term->Right(), args), true)); } /* @@ -1331,10 +1331,10 @@ ObjPtr Context::CallBlock(Context *ctx, const TermPtr &block, Obj * local_vars, try { if(!block->m_block.empty()) { for (size_t i = 0; i < block->m_block.size(); i++) { - result = ExecStr(ctx, block->m_block[i], local_vars, false); + result = Eval(ctx, block->m_block[i], local_vars, false); } } else { - result = ExecStr(ctx, block, local_vars, false); + result = Eval(ctx, block, local_vars, false); } } catch (Interrupt &obj) { @@ -1351,7 +1351,7 @@ ObjPtr Context::CallBlock(Context *ctx, const TermPtr &block, Obj * local_vars, if(block->m_class_name.empty()) { // Только при возврате значения :Return ASSERT(obj.m_obj->size() == 1); - return (*obj.m_obj)[0]; + return (*obj.m_obj)[0].second; } } else if(!block->m_class_name.empty()) { throw; // Объект возврата не соответствует требуемому типу @@ -1365,13 +1365,13 @@ ObjPtr Context::EvalBlockAND(Context *ctx, const TermPtr &block, Obj * local_var ObjPtr result = nullptr; if(block->GetTokenID() == TermID::BLOCK) { for (size_t i = 0; i < block->m_block.size(); i++) { - result = ExecStr(ctx, block->m_block[i], local_vars, false); + result = Eval(ctx, block->m_block[i], local_vars, false); if(!result || !result->GetValueAsBoolean()) { return Obj::No(); } } } else { - result = ExecStr(ctx, block, local_vars, false); + result = Eval(ctx, block, local_vars, false); } if(!result || !result->GetValueAsBoolean()) { @@ -1384,13 +1384,13 @@ ObjPtr Context::EvalBlockOR(Context *ctx, const TermPtr &block, Obj * local_vars ObjPtr result = nullptr; if(block->GetTokenID() == TermID::BLOCK) { for (size_t i = 0; i < block->m_block.size(); i++) { - result = ExecStr(ctx, block->m_block[i], local_vars, false); + result = Eval(ctx, block->m_block[i], local_vars, false); if(result && result->GetValueAsBoolean()) { return Obj::Yes(); } } } else { - result = ExecStr(ctx, block, local_vars, false); + result = Eval(ctx, block, local_vars, false); } if(result && result->GetValueAsBoolean()) { @@ -1404,13 +1404,13 @@ ObjPtr Context::EvalBlockXOR(Context *ctx, const TermPtr &block, Obj * local_var size_t xor_counter = 0; if(block->GetTokenID() == TermID::BLOCK) { for (size_t i = 0; i < block->m_block.size(); i++) { - result = ExecStr(ctx, block->m_block[i], local_vars, false); + result = Eval(ctx, block->m_block[i], local_vars, false); if(result && result->GetValueAsBoolean()) { xor_counter++; } } } else { - result = ExecStr(ctx, block, local_vars, false); + result = Eval(ctx, block, local_vars, false); if(result && result->GetValueAsBoolean()) { xor_counter++; @@ -1444,6 +1444,11 @@ ObjPtr Context::CreateNative(TermPtr proto, const char *module, bool lazzy, cons NL_CHECK((module == nullptr || (module && *module == '\0')) || m_runtime, "You cannot load a module '%s' without access to the runtime context!", module); +#ifdef _MSC_VER +#pragma message WARNING("Fail native call from Windows!!!!") + return Obj::CreateNone(); +#endif + ObjPtr result; ObjType type; if(proto->GetTokenID() == TermID::TERM) { @@ -1544,7 +1549,7 @@ void Context::CleanUp() { auto iter = begin(); while(iter != end()) { if(iter->second.expired()) { - iter = erase(iter); + iter = ListType::erase(iter); } else { iter++; } @@ -1553,14 +1558,14 @@ void Context::CleanUp() { ObjPtr Context::FindSessionTerm(const char *name, bool current_only) { CleanUp(); - auto found = select(MakeName(name)); - while(!found.complete()) { - ObjPtr obj = found.data().second.lock(); + auto found = find(MakeName(name)); + while(found != end()) { + ObjPtr obj = found->second.lock(); if(obj) { return obj; } - erase(found); + ListType::erase(found); found++; } return nullptr; @@ -1654,10 +1659,10 @@ ObjPtr Context::CreateLVal(Context *ctx, TermPtr term, Obj * args) { ctx->CleanUp(); - auto iter = ctx->select(term->m_text); + auto iter = ctx->find(term->m_text); - if(!iter.complete()) { - ObjPtr obj = (*iter).lock(); + if(iter != ctx->end()) { + ObjPtr obj = (*iter).second.lock(); if(obj) { return obj; } @@ -2005,13 +2010,13 @@ ObjPtr Context::CreateRVal(Context *ctx, TermPtr term, Obj * local_vars, bool in ASSERT(ctx); - auto iter = ctx->m_data.begin(); - while(iter != ctx->m_data.end()) { + auto iter = ctx->begin(); + while(iter != ctx->end()) { if(!iter->second.expired()) { result->push_back(Obj::CreateString(iter->first)); iter++; } else { - iter = ctx->m_data.erase(iter); + iter = ctx->ListType::erase(iter); } } @@ -2078,7 +2083,7 @@ ObjPtr Context::CreateRVal(Context *ctx, TermPtr term, Obj * local_vars, bool in ASSERT(result->m_var_type_fixed == type); // Размерность, если указана - result->m_dimensions = Obj::CreateType(result->m_var_type_current, nullptr, result->m_var_type_current); + result->m_dimensions = Obj::CreateType(result->m_var_type_current, result->m_var_type_current, true); for (size_t i = 0; i < term->m_dims.size(); i++) { result->m_dimensions->push_back(CreateRVal(ctx, term->m_dims[i], local_vars)); } @@ -2087,19 +2092,19 @@ ObjPtr Context::CreateRVal(Context *ctx, TermPtr term, Obj * local_vars, bool in for (int64_t i = 0; i < term->size(); i++) { - if((*term)[i]->GetTokenID() == TermID::FILLING) { + if((*term)[i].second->GetTokenID() == TermID::FILLING) { // Заполнение значений вызовом функции // :Type(1, 2, 3, ... rand() ... ); - ASSERT(!(*term)[i]->Left()); - ASSERT((*term)[i]->Right()); + ASSERT(!(*term)[i].second->Left()); + ASSERT((*term)[i].second->Right()); - ObjPtr expr = ctx->FindTerm((*term)[i]->Right()->GetFullName()); + ObjPtr expr = ctx->FindTerm((*term)[i].second->Right()->GetFullName()); - if((*term)[i]->Right()->getTermID() != TermID::CALL) { + if((*term)[i].second->Right()->getTermID() != TermID::CALL) { LOG_RUNTIME("Operator filling supported function call only!"); } @@ -2114,11 +2119,11 @@ ObjPtr Context::CreateRVal(Context *ctx, TermPtr term, Obj * local_vars, bool in int64_t full_size = 1; for (int dim_index = 0; dim_index < result->m_dimensions->size(); dim_index++) { - if(!(*result->m_dimensions)[dim_index]->is_integer()) { + if(!(*result->m_dimensions)[dim_index].second->is_integer()) { LOG_RUNTIME("Dimension index for function filling support integer value only!"); } - full_size *= (*result->m_dimensions)[dim_index]->GetValueAsInteger(); + full_size *= (*result->m_dimensions)[dim_index].second->GetValueAsInteger(); } if(full_size <= 0) { @@ -2136,16 +2141,16 @@ ObjPtr Context::CreateRVal(Context *ctx, TermPtr term, Obj * local_vars, bool in break; - } else if((*term)[i]->GetTokenID() == TermID::ELLIPSIS) { + } else if((*term)[i].second->GetTokenID() == TermID::ELLIPSIS) { if(!term->name(i).empty()) { LOG_RUNTIME("Named ellipsys not implemented!"); } - if((*term)[i]->Right()) { + if((*term)[i].second->Right()) { - bool named = ((*term)[i]->Left() && (*term)[i]->Left()->getTermID() == TermID::ELLIPSIS); - ObjPtr exp = CreateRVal(ctx, (*term)[i]->Right()); + bool named = ((*term)[i].second->Left() && (*term)[i].second->Left()->getTermID() == TermID::ELLIPSIS); + ObjPtr exp = CreateRVal(ctx, (*term)[i].second->Right()); if(!exp->is_dictionary_type()) { LOG_RUNTIME("Expansion operator applies to dictionary only!"); @@ -2154,9 +2159,9 @@ ObjPtr Context::CreateRVal(Context *ctx, TermPtr term, Obj * local_vars, bool in for (int index = 0; index < exp->size(); index++) { if(named) { - args->push_back((*exp)[index], exp->name(index).empty() ? "" : exp->name(index)); + args->push_back((*exp)[index].second, exp->name(index).empty() ? "" : exp->name(index)); } else { - args->push_back((*exp)[index]); + args->push_back((*exp)[index].second); } } @@ -2165,9 +2170,9 @@ ObjPtr Context::CreateRVal(Context *ctx, TermPtr term, Obj * local_vars, bool in } if(term->name(i).empty()) { - args->push_back(CreateRVal(ctx, (*term)[i], local_vars)); + args->push_back(CreateRVal(ctx, (*term)[i].second, local_vars)); } else { - args->push_back(CreateRVal(ctx, (*term)[i], local_vars), term->name(i).c_str()); + args->push_back(CreateRVal(ctx, (*term)[i].second, local_vars), term->name(i).c_str()); } } @@ -2191,9 +2196,9 @@ ObjPtr Context::CreateRVal(Context *ctx, TermPtr term, Obj * local_vars, bool in args = Obj::CreateDict(); for (int i = 0; i < term->size(); i++) { if(term->name(i).empty()) { - args->push_back(CreateRVal(ctx, (*term)[i], local_vars)); + args->push_back(CreateRVal(ctx, (*term)[i].second, local_vars)); } else { - args->push_back(CreateRVal(ctx, (*term)[i], local_vars), term->name(i).c_str()); + args->push_back(CreateRVal(ctx, (*term)[i].second, local_vars), term->name(i).c_str()); } } @@ -2210,9 +2215,9 @@ ObjPtr Context::CreateRVal(Context *ctx, TermPtr term, Obj * local_vars, bool in result->m_var_type_current = ObjType::Dictionary; for (int i = 0; i < term->size(); i++) { if(term->name(i).empty()) { - result->push_back(CreateRVal(ctx, (*term)[i], local_vars)); + result->push_back(CreateRVal(ctx, (*term)[i].second, local_vars)); } else { - result->push_back(CreateRVal(ctx, (*term)[i], local_vars), term->name(i).c_str()); + result->push_back(CreateRVal(ctx, (*term)[i].second, local_vars), term->name(i).c_str()); } } result->m_var_is_init = true; @@ -2257,7 +2262,7 @@ ObjPtr Context::CreateRVal(Context *ctx, TermPtr term, Obj * local_vars, bool in for (int i = 0; i < term->size(); i++) { ASSERT(!term->name(i).empty()); - result->push_back(CreateRVal(ctx, (*term)[i], local_vars), term->name(i).c_str()); + result->push_back(CreateRVal(ctx, (*term)[i].second, local_vars), term->name(i).c_str()); } if(result->size() == 2) { diff --git a/src/context.h b/src/context.h index 6e6873ab..7188e17e 100644 --- a/src/context.h +++ b/src/context.h @@ -103,7 +103,7 @@ namespace newlang { _("export", NOT_SUPPORT)\ _("local", NOT_SUPPORT) - class Context : public Variable< std::weak_ptr > { + class Context : public Variable> { public: static ObjPtr eval_END(Context *ctx, const TermPtr & term, Obj *args); @@ -165,10 +165,10 @@ namespace newlang { temp = Obj::CreateNone(); args = temp.get(); } - return ExecStr(this, exec, args, int_catch); + return Eval(this, exec, args, int_catch); } - static ObjPtr ExecStr(Context *ctx, TermPtr term, Obj *args, bool int_catch = false); + static ObjPtr Eval(Context *ctx, TermPtr term, Obj *args, bool int_catch = false); static ObjPtr ExpandAssign(Context *ctx, TermPtr lvar, TermPtr rval, Obj *args, CreateMode mode); static ObjPtr ExpandCreate(Context *ctx, TermPtr lvar, TermPtr rval, Obj *args); @@ -214,9 +214,9 @@ namespace newlang { if (str.size() && (str[0] == '$' || str[0] == '@')) { str = str.substr(1); } - auto found = select(name); - if (!found.complete()) { - erase(found); + auto found = find(name); + if (found != end()) { + ListType::erase(found); return Obj::Yes(); } return Obj::No(); @@ -227,9 +227,9 @@ namespace newlang { if (str.size() && (str[0] == '$' || str[0] == '@')) { str = str.substr(1); } - auto found = select(str); - if (!found.complete()) { - return (*found).lock(); + auto found = find(str); + if (found != end()) { + return found->second.lock(); } auto func = m_funcs.find(str); if (func != m_funcs.end()) { @@ -243,7 +243,7 @@ namespace newlang { } RuntimePtr m_runtime; // Глобальный контекс, если к нему есть доступ - Variable m_global_terms; + Variable m_global_terms; virtual ~Context() { } @@ -260,10 +260,9 @@ namespace newlang { ObjPtr FindGlobalTerm(TermPtr term); ObjPtr FindGlobalTerm(const std::string name) { - auto found = m_global_terms.select(MakeName(name)); - if (!found.complete()) { - - return *found; + auto found = m_global_terms.find(MakeName(name)); + if (found != m_global_terms.end()) { + return found->second; } return GetObject(name); } @@ -274,7 +273,7 @@ namespace newlang { void RegisterInContext(Obj &args) { for (int i = static_cast (args.size()) - 1; args.size() && i >= 0; i--) { - push_front(args.at(i).second, args.at(i).first); + push_front(pair(args.at(i).second, args.at(i).first)); } } diff --git a/src/nbproject/Makefile-Debug.mk b/src/nbproject/Makefile-Debug.mk index 20216c34..d8528375 100644 --- a/src/nbproject/Makefile-Debug.mk +++ b/src/nbproject/Makefile-Debug.mk @@ -73,21 +73,20 @@ FFLAGS= ASFLAGS= # Link Libraries and Options -LDLIBSOPTIONS=-L../contrib/libtorch/lib -Wl,-rpath,'../contrib/libtorch/lib' -lpthread -ldl ../contrib/libffi/output/lib/libffi.a -lc10 -ltorch_cpu -ltorch +LDLIBSOPTIONS=-L../contrib/libtorch/lib -Wl,-rpath,'../contrib/libtorch/lib' -lpthread -ldl -lc10 -ltorch_cpu -ltorch -lcrypto # Build Targets .build-conf: ${BUILD_SUBPROJECTS} - "${MAKE}" -f nbproject/Makefile-${CND_CONF}.mk nlc + "${MAKE}" -f nbproject/Makefile-${CND_CONF}.mk ../output/nlc -nlc: ../contrib/libffi/output/lib/libffi.a - -nlc: ${OBJECTFILES} - ${LINK.cc} -o nlc ${OBJECTFILES} ${LDLIBSOPTIONS} -Wl,--export-dynamic +../output/nlc: ${OBJECTFILES} + ${MKDIR} -p ../output + ${LINK.cc} -o ../output/nlc ${OBJECTFILES} ${LDLIBSOPTIONS} -Wl,--export-dynamic ${OBJECTDIR}/_ext/e16507f5/logger.o: ../contrib/logger/logger.cpp ${MKDIR} -p ${OBJECTDIR}/_ext/e16507f5 ${RM} "$@.d" - $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -std=c++14 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/_ext/e16507f5/logger.o ../contrib/logger/logger.cpp + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I. -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -std=c++14 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/_ext/e16507f5/logger.o ../contrib/logger/logger.cpp temp/syntax.temp.txt: ../docs/syntax.md ../docs/syntax.md ${MKDIR} -p temp @@ -97,7 +96,7 @@ temp/syntax.temp.txt: ../docs/syntax.md ../docs/syntax.md ${OBJECTDIR}/builtin.o: builtin.cpp parser.h parser.yy.h pch.h.gch location.hh ${MKDIR} -p ${OBJECTDIR} ${RM} "$@.d" - $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/builtin.o builtin.cpp + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I. -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/builtin.o builtin.cpp : builtin.h pch.h.gch @echo Выполнение шага пользовательского сборки @@ -106,7 +105,7 @@ ${OBJECTDIR}/builtin.o: builtin.cpp parser.h parser.yy.h pch.h.gch location.hh ${OBJECTDIR}/context.o: context.cpp parser.h parser.yy.h pch.h.gch location.hh ${MKDIR} -p ${OBJECTDIR} ${RM} "$@.d" - $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/context.o context.cpp + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I. -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/context.o context.cpp : context.h pch.h.gch @echo Выполнение шага пользовательского сборки @@ -115,7 +114,7 @@ ${OBJECTDIR}/context.o: context.cpp parser.h parser.yy.h pch.h.gch location.hh ${OBJECTDIR}/lexer.o: lexer.cpp parser.h parser.yy.h pch.h.gch location.hh ${MKDIR} -p ${OBJECTDIR} ${RM} "$@.d" - $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/lexer.o lexer.cpp + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I. -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/lexer.o lexer.cpp : lexer.h parser.yy.h parser.yy.cpp location.hh pch.h.gch @echo Выполнение шага пользовательского сборки @@ -129,7 +128,7 @@ lexer.yy.cpp lexer.yy.h: lexer.l parser.y parser.yy.h parser.yy.cpp location.hh ${OBJECTDIR}/lexer.yy.o: lexer.yy.cpp parser.y parser.yy.h parser.yy.cpp location.hh ${MKDIR} -p ${OBJECTDIR} ${RM} "$@.d" - $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/lexer.yy.o lexer.yy.cpp + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I. -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/lexer.yy.o lexer.yy.cpp : lexer.yy.h pch.h.gch @echo Выполнение шага пользовательского сборки @@ -138,7 +137,7 @@ ${OBJECTDIR}/lexer.yy.o: lexer.yy.cpp parser.y parser.yy.h parser.yy.cpp locatio ${OBJECTDIR}/newlang.o: newlang.cpp parser.h parser.yy.h pch.h.gch location.hh ${MKDIR} -p ${OBJECTDIR} ${RM} "$@.d" - $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/newlang.o newlang.cpp + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I. -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/newlang.o newlang.cpp : newlang.h pch.h.gch @echo Выполнение шага пользовательского сборки @@ -147,12 +146,12 @@ ${OBJECTDIR}/newlang.o: newlang.cpp parser.h parser.yy.h pch.h.gch location.hh ${OBJECTDIR}/nlc.o: nlc.cpp parser.h parser.yy.h pch.h.gch location.hh ${MKDIR} -p ${OBJECTDIR} ${RM} "$@.d" - $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/nlc.o nlc.cpp + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I. -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/nlc.o nlc.cpp ${OBJECTDIR}/object.o: object.cpp parser.h parser.yy.h pch.h.gch location.hh ${MKDIR} -p ${OBJECTDIR} ${RM} "$@.d" - $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/object.o object.cpp + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I. -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/object.o object.cpp : object.h pch.h.gch @echo Выполнение шага пользовательского сборки @@ -161,7 +160,7 @@ ${OBJECTDIR}/object.o: object.cpp parser.h parser.yy.h pch.h.gch location.hh ${OBJECTDIR}/parser.o: parser.cpp pch.h.gch ${MKDIR} -p ${OBJECTDIR} ${RM} "$@.d" - $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/parser.o parser.cpp + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I. -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/parser.o parser.cpp : parser.h pch.h.gch @echo Выполнение шага пользовательского сборки @@ -175,7 +174,7 @@ parser.yy.h parser.yy.cpp location.hh: parser.y ${OBJECTDIR}/parser.yy.o: parser.yy.cpp parser.y ${MKDIR} -p ${OBJECTDIR} ${RM} "$@.d" - $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/parser.yy.o parser.yy.cpp + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I. -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/parser.yy.o parser.yy.cpp : parser.yy.h parser.y pch.h.gch @echo Выполнение шага пользовательского сборки @@ -188,12 +187,12 @@ pch.h.gch: pch.h ${OBJECTDIR}/syntax_help.o: syntax_help.cpp ${MKDIR} -p ${OBJECTDIR} ${RM} "$@.d" - $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/syntax_help.o syntax_help.cpp + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I. -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/syntax_help.o syntax_help.cpp ${OBJECTDIR}/term.o: term.cpp parser.h parser.yy.h pch.h.gch location.hh ${MKDIR} -p ${OBJECTDIR} ${RM} "$@.d" - $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/term.o term.cpp + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I. -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/term.o term.cpp : term.h parser.yy.cpp location.hh pch.h.gch @echo Выполнение шага пользовательского сборки @@ -202,42 +201,42 @@ ${OBJECTDIR}/term.o: term.cpp parser.h parser.yy.h pch.h.gch location.hh ${OBJECTDIR}/test/alg_test.o: test/alg_test.cpp pch.h.gch ${MKDIR} -p ${OBJECTDIR}/test ${RM} "$@.d" - $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/alg_test.o test/alg_test.cpp + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I. -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/alg_test.o test/alg_test.cpp ${OBJECTDIR}/test/compiler_test.o: test/compiler_test.cpp pch.h.gch ${MKDIR} -p ${OBJECTDIR}/test ${RM} "$@.d" - $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/compiler_test.o test/compiler_test.cpp + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I. -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/compiler_test.o test/compiler_test.cpp ${OBJECTDIR}/test/eval_test.o: test/eval_test.cpp pch.h.gch ${MKDIR} -p ${OBJECTDIR}/test ${RM} "$@.d" - $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/eval_test.o test/eval_test.cpp + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I. -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/eval_test.o test/eval_test.cpp ${OBJECTDIR}/test/fraction_test.o: test/fraction_test.cpp ${MKDIR} -p ${OBJECTDIR}/test ${RM} "$@.d" - $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/fraction_test.o test/fraction_test.cpp + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I. -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/fraction_test.o test/fraction_test.cpp ${OBJECTDIR}/test/lexer_test.o: test/lexer_test.cpp pch.h.gch ${MKDIR} -p ${OBJECTDIR}/test ${RM} "$@.d" - $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/lexer_test.o test/lexer_test.cpp + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I. -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/lexer_test.o test/lexer_test.cpp ${OBJECTDIR}/test/nlc_test.o: test/nlc_test.cpp pch.h.gch ${MKDIR} -p ${OBJECTDIR}/test ${RM} "$@.d" - $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/nlc_test.o test/nlc_test.cpp + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I. -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/nlc_test.o test/nlc_test.cpp ${OBJECTDIR}/test/object_test.o: test/object_test.cpp pch.h.gch ${MKDIR} -p ${OBJECTDIR}/test ${RM} "$@.d" - $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/object_test.o test/object_test.cpp + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I. -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/object_test.o test/object_test.cpp ${OBJECTDIR}/test/parser_test.o: test/parser_test.cpp pch.h.gch ${MKDIR} -p ${OBJECTDIR}/test ${RM} "$@.d" - $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/parser_test.o test/parser_test.cpp + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I. -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/parser_test.o test/parser_test.cpp : types.h pch.h.gch @echo Выполнение шага пользовательского сборки @@ -246,7 +245,7 @@ ${OBJECTDIR}/test/parser_test.o: test/parser_test.cpp pch.h.gch ${OBJECTDIR}/variable.o: variable.cpp pch.h.gch ${MKDIR} -p ${OBJECTDIR} ${RM} "$@.d" - $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/variable.o variable.cpp + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I. -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/variable.o variable.cpp : variable.h pch.h.gch @echo Выполнение шага пользовательского сборки @@ -255,7 +254,7 @@ ${OBJECTDIR}/variable.o: variable.cpp pch.h.gch ${OBJECTDIR}/version.o: version.c ${MKDIR} -p ${OBJECTDIR} ${RM} "$@.d" - $(COMPILE.c) -g -s -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DUMP -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I.. -std=c11 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/version.o version.c + $(COMPILE.c) -g -s -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DUMP -I. -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -std=c11 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/version.o version.c : warning_pop.h parser.yy.cpp location.hh @echo Выполнение шага пользовательского сборки diff --git a/src/nbproject/Makefile-variables.mk b/src/nbproject/Makefile-variables.mk index fa7ef8fa..53285db4 100644 --- a/src/nbproject/Makefile-variables.mk +++ b/src/nbproject/Makefile-variables.mk @@ -8,9 +8,9 @@ CND_BUILDDIR=build CND_DISTDIR=dist # Debug configuration CND_PLATFORM_Debug=GNU-Linux -CND_ARTIFACT_DIR_Debug= +CND_ARTIFACT_DIR_Debug=../output CND_ARTIFACT_NAME_Debug=nlc -CND_ARTIFACT_PATH_Debug=nlc +CND_ARTIFACT_PATH_Debug=../output/nlc CND_PACKAGE_DIR_Debug=dist/Debug/GNU-Linux/package CND_PACKAGE_NAME_Debug=src.tar CND_PACKAGE_PATH_Debug=dist/Debug/GNU-Linux/package/src.tar diff --git a/src/nbproject/Package-Debug.bash b/src/nbproject/Package-Debug.bash index 099748da..1eb18cd7 100644 --- a/src/nbproject/Package-Debug.bash +++ b/src/nbproject/Package-Debug.bash @@ -13,7 +13,7 @@ CND_BUILDDIR=build CND_DLIB_EXT=so NBTMPDIR=${CND_BUILDDIR}/${CND_CONF}/${CND_PLATFORM}/tmp-packaging TMPDIRNAME=tmp-packaging -OUTPUT_PATH=nlc +OUTPUT_PATH=../output/nlc OUTPUT_BASENAME=nlc PACKAGE_TOP_DIR=src/ diff --git a/src/nbproject/configurations.xml b/src/nbproject/configurations.xml index 3e530437..23bc23e6 100644 --- a/src/nbproject/configurations.xml +++ b/src/nbproject/configurations.xml @@ -102,9 +102,10 @@ true 10 + . + .. ../contrib/googletest/googletest ../contrib/googletest/googletest/include - .. DEBUG @@ -113,6 +114,7 @@ + . .. ../contrib/googletest/googletest ../contrib/googletest/googletest/include @@ -130,7 +132,7 @@ false - nlc + ../output/nlc ../contrib/libtorch/lib @@ -141,10 +143,10 @@ PosixThreads DynamicLinking - ../contrib/libffi/output/lib/libffi.a c10 torch_cpu torch + crypto -Wl,--export-dynamic diff --git a/src/newlang.cpp b/src/newlang.cpp index 7960754f..d1986b49 100644 --- a/src/newlang.cpp +++ b/src/newlang.cpp @@ -643,7 +643,7 @@ std::string NewLang::MakeCppFileCallArgs(CompileInfo &ci, TermPtr &args, TermPtr if(proto) { if(i < proto->size()) { - TermPtr term = (*proto)[i]; + TermPtr term = (*proto)[i].second; if(args->at(i).second) { NL_TYPECHECK(args->at(i).second, args->at(i).second->m_type_name, term->m_type_name); } @@ -1064,11 +1064,11 @@ ObjPtr NewLang::GetIndexField(Context *ctx, ObjPtr obj, TermPtr term, bool creat return obj; } else if(term->Right()->getTermID() == TermID::FIELD && !term->Right()->Right() && create_field) { // Если последнее в списке поле создается - return obj->push_back(Obj::CreateNone(), term->Right()->getText().c_str()); + return obj->push_back(Obj::CreateNone(), term->Right()->getText().c_str()).second; } ObjPtr result; if(term->Right()->getTermID() == TermID::FIELD) { - result = (*obj)[term->Right()->m_text.c_str()]; + result = (*obj)[term->Right()->m_text.c_str()].second; return GetIndexField(ctx, result, term->Right()); } else if(term->Right()->getTermID() == TermID::INDEX) { result = Obj::GetIndex(obj, term->Right()); @@ -1497,7 +1497,7 @@ std::string NewLang::GetImpl(CompileInfo &ci, TermPtr term, std::string &output) temp += ", "; } temp2.clear(); - GetImpl(ci, (*term)[i], temp2); + GetImpl(ci, (*term)[i].second, temp2); temp += "Obj::Arg(" + temp2; if(!term->name(i).empty()) { temp += ", \"" + term->name(i) + "\""; @@ -1818,18 +1818,18 @@ std::string NewLang::BeginIterators(CompileInfo &ci, TermPtr args, std::string & // Аргументы функции с локальным доступом по имени или ииндексу if(args->size()) { for (int i = 0; i < args->size(); i++) { - if((*args)[i]->GetTokenID() == TermID::ITERATOR) { + if((*args)[i].second->GetTokenID() == TermID::ITERATOR) { std::string name; - if((*args)[i]->getText().compare("!") == 0) { + if((*args)[i].second->getText().compare("!") == 0) { - ASSERT((*args)[i]->Left()); - ASSERT(!(*args)[i]->size()); // todo пока без обработки аргументов + ASSERT((*args)[i].second->Left()); + ASSERT(!(*args)[i].second->size()); // todo пока без обработки аргументов name = "iter_" + std::to_string(i + 1); iters.push_back(name); - output += ci.GetIndent() + "auto " + name + "= ctx->m_info.global->select(\"" + (*args)[i]->Left()->getText() + "\");\n"; + output += ci.GetIndent() + "auto " + name + "= ctx->m_info.global->select(\"" + (*args)[i].second->Left()->getText() + "\");\n"; } else { - LOG_RUNTIME("Iterator '%s' not implemented!", (*args)[i]->getText().c_str()); + LOG_RUNTIME("Iterator '%s' not implemented!", (*args)[i].second->getText().c_str()); } } } diff --git a/src/newlang.h b/src/newlang.h index 4498652c..0e7834c3 100644 --- a/src/newlang.h +++ b/src/newlang.h @@ -183,7 +183,7 @@ namespace newlang { LOG_RUNTIME("Fail init data from %s!", ffi_file.c_str()); } - return rt; + return std::move(rt); } inline static void * GetDirectAddressFromLibrary(void *handle, const char * name) { @@ -232,7 +232,8 @@ namespace newlang { protected: - SCOPE(private) : + //SCOPE(private) : + public: RunTime(const RunTime&) = delete; const RunTime& operator=(const RunTime&) = delete; @@ -327,7 +328,7 @@ namespace newlang { // Context * m_ctx; }; - class NewLang : public Variable { + class NewLang : public Variable { public: ObjPtr Run(const char *source, void *context); diff --git a/src/nlc.h b/src/nlc.h index d96b52c2..8d10189a 100644 --- a/src/nlc.h +++ b/src/nlc.h @@ -211,7 +211,7 @@ namespace newlang { ; - auto result = cli.parse({static_cast(argc), argv}); + auto result = cli.parse({static_cast (argc), argv}); if (!result) { m_mode = Mode::ModeError; m_output = result.message(); @@ -239,6 +239,14 @@ namespace newlang { m_modules = SplitString(load_list.c_str(), ","); m_load_only = SplitString(load_only.c_str(), ","); + int len; + char buffer[100]; + fcntl(STDIN_FILENO, F_SETFL, fcntl(STDIN_FILENO, F_GETFL, 0) | O_NONBLOCK); + while ((len = read(STDIN_FILENO, buffer, sizeof (buffer))) > 0) { + m_eval.append(buffer, len); + } + fcntl(STDIN_FILENO, F_SETFL, fcntl(STDIN_FILENO, F_GETFL, 0) & ~O_NONBLOCK); + int cnt = 0; cnt += !compile.empty(); cnt += !exec.empty(); @@ -317,36 +325,28 @@ namespace newlang { LOG_RUNTIME("Fail read or empty source file '%s'!", m_ifile.c_str()); } } - TermPtr term; - Parser p(term); - p.Parse(m_eval.c_str()); - if (!term || m_eval.empty()) { - LOG_RUNTIME("Eval expression empty!"); - } - ObjPtr result = Context::ExecStr(&m_ctx, term, m_args.get(), true); + ObjPtr result = m_ctx.ExecStr(m_eval, m_args.get(), true); if (result && m_local_vars.find(result.get()) == m_local_vars.end()) { m_local_vars[result.get()] = result; } m_output = result->GetValueAsString(); + m_output += "\n"; if (!m_ofile.empty()) { std::ofstream out(m_ofile); out << m_output; out.close(); } - if (!m_output.empty()) { - utils::Logger::LogLevelType save_level = utils::Logger::Instance()->GetLogLevel(); - utils::Logger::Instance()->SetLogLevel(LOG_LEVEL_INFO); - LOG_INFO("%s", m_output.c_str()); - utils::Logger::Instance()->SetLogLevel(save_level); - } + + fcntl(STDOUT_FILENO, F_SETFL, fcntl(STDOUT_FILENO, F_GETFL, 0) | O_NONBLOCK); + write(STDOUT_FILENO, m_output.c_str(), m_output.size()); + } else { ASSERT(m_mode == Mode::ModeInter); Interative(); - // LOG_INFO("%s", m_output.c_str()); } } catch (Interrupt &err) { @@ -491,14 +491,14 @@ namespace newlang { } break; }// Keyboard interrupt handler for Windows -//#if defined(OS_WINDOWS) -// else if (ch == CTRL_C) { -// predictions_free(pred); -// tree_free(rules); -// free(buff); -// exit(0); -// } -//#endif + //#if defined(OS_WINDOWS) + // else if (ch == CTRL_C) { + // predictions_free(pred); + // tree_free(rules); + // free(buff); + // exit(0); + // } + //#endif // Edit buffer like backspace if BACKSPACE was pressed else if (ch == KEY_BACKSPACE) { if (buff.size() && buff.size() - offset >= 1) { @@ -533,7 +533,7 @@ namespace newlang { switch (_getch()) { case KEY_LEFT: // Increase offset from the end of the buffer if left key pressed - offset = (offset < static_cast(buff.size())) ? (offset + 1) : buff.size(); + offset = (offset < static_cast (buff.size())) ? (offset + 1) : buff.size(); break; case KEY_RIGHT: // Decrease offset from the end of the buffer if left key pressed @@ -547,7 +547,7 @@ namespace newlang { } break; case KEY_DOWN: - if (!history.empty() && history_pos + 1 < static_cast(history.size())) { + if (!history.empty() && history_pos + 1 < static_cast (history.size())) { clear_line(); history_pos++; buff = utf8_decode(history[history_pos]); diff --git a/src/object.cpp b/src/object.cpp index c9a3cd44..600f66e7 100644 --- a/src/object.cpp +++ b/src/object.cpp @@ -47,7 +47,12 @@ Interrupt::Interrupt(const std::string error_message, const std::string type_nam } Interrupt::Interrupt(ObjPtr obj) : m_obj(obj) { - snprintf(m_buffer_message, sizeof (m_buffer_message), "Interrupt%s%s%s!", m_obj ? " data: '" : "", m_obj ? m_obj->toString().c_str() : "", m_obj ? "'" : ""); + std::string temp = m_obj->toString(); + size_t pos = temp.find("\n')"); + if(pos == temp.size() - 3) { + temp = temp.replace(pos, 1, ""); + } + snprintf(m_buffer_message, sizeof (m_buffer_message), "Interrupt%s%s%s!", temp.empty() ? "" : " data: \"", temp.empty() ? "" : temp.c_str(), temp.empty() ? "" : "\""); } const char* Interrupt::what() const noexcept { @@ -73,38 +78,38 @@ int64_t Obj::size(int64_t dim) const { return Variable::size(); } -int64_t Obj::resize_(int64_t size, ObjPtr fill, const std::string name) { +int64_t Obj::resize_(int64_t new_size, ObjPtr fill, const std::string name) { if(is_string_type()) { - if(size >= 0) { + if(new_size >= 0) { // Размер положительный, просто изменить число элементов добавив или удалив последние if(m_var_type_current == ObjType::StrChar) { - m_str.resize(size, ' '); + m_str.resize(new_size, ' '); return m_str.size(); } else if(m_var_type_current == ObjType::StrWide) { - m_wstr.resize(size, L' '); + m_wstr.resize(new_size, L' '); return m_wstr.size(); } } else { // Если размер отрицательный - добавить или удалить вначале - size = -size; - if(static_cast (m_data.size()) > size) { + new_size = -new_size; + if(static_cast (size()) > new_size) { if(m_var_type_current == ObjType::StrChar) { - m_str.erase(0, size); + m_str.erase(0, new_size); return m_str.size(); } else if(m_var_type_current == ObjType::StrWide) { - m_str.erase(0, size); + m_str.erase(0, new_size); return m_wstr.size(); } - } else if(static_cast (m_data.size()) < size) { + } else if(static_cast (size()) < new_size) { if(m_var_type_current == ObjType::StrChar) { - m_str.insert(0, size, ' '); + m_str.insert(0, new_size, ' '); return m_str.size(); } else if(m_var_type_current == ObjType::StrWide) { - m_wstr.insert(0, size, L' '); + m_wstr.insert(0, new_size, L' '); return m_wstr.size(); } @@ -112,7 +117,7 @@ int64_t Obj::resize_(int64_t size, ObjPtr fill, const std::string name) { } } else if(is_dictionary_type()) { - return Variable::resize(size, fill ? fill : Obj::CreateNone(), name); + return Variable::resize(new_size, fill ? fill : Obj::CreateNone(), name); } else if(is_tensor()) { std::vector sizes; for (int i = 0; i < m_value.dim(); i++) { @@ -123,27 +128,27 @@ int64_t Obj::resize_(int64_t size, ObjPtr fill, const std::string name) { LOG_RUNTIME("Method resize for SCALAR type '%s' not implemented!", newlang::toString(m_var_type_current)); - } else if(size == 0 || sizes[0] == size) { + } else if(new_size == 0 || sizes[0] == new_size) { // Tensor size OK - do nothing - } else if(size > 0) { // Increase tensor size + } else if(new_size > 0) { // Increase tensor size // The size is positive, just change the number of elements by adding or removing the last ASSERT(sizes.size() == 1); - sizes[0] = size; + sizes[0] = new_size; m_value.resize_(at::IntArrayRef(sizes)); } else { // Decrease tensor size // If the size is negative - add or remove elements first - size = -size; - if(sizes[0] == size) { + new_size = -new_size; + if(sizes[0] == new_size) { // Tensor size OK - do nothing - } else if(sizes[0] > size) { + } else if(sizes[0] > new_size) { ASSERT(sizes.size() == 1); - at::Tensor ind = torch::arange(sizes[0] - size - 1, sizes[0] - 1, at::ScalarType::Long); - at::Tensor any = torch::zeros(sizes[0] - size, at::ScalarType::Long); + at::Tensor ind = torch::arange(sizes[0] - new_size - 1, sizes[0] - 1, at::ScalarType::Long); + at::Tensor any = torch::zeros(sizes[0] - new_size, at::ScalarType::Long); // LOG_DEBUG("arange %s %s", TensorToString(ind).c_str(), TensorToString(any).c_str()); ind = at::cat({any, ind}); @@ -153,27 +158,27 @@ int64_t Obj::resize_(int64_t size, ObjPtr fill, const std::string name) { m_value.index_copy_(0, ind, m_value.clone()); // LOG_DEBUG("index_copy_ %s", TensorToString(m_value).c_str()); - sizes[0] = size; + sizes[0] = new_size; m_value.resize_(at::IntArrayRef(sizes)); // LOG_DEBUG("resize_ %s", TensorToString(m_value).c_str()); } else { // sizes[0] < size ASSERT(sizes.size() == 1); - m_value = at::cat({torch::zeros(size - sizes[0], m_value.scalar_type()), m_value}); + m_value = at::cat({torch::zeros(new_size - sizes[0], m_value.scalar_type()), m_value}); } } - if(size == 0) { + if(new_size == 0) { m_value.reset(); m_var_is_init = false; } - return size; + return new_size; } LOG_RUNTIME("Method resize for type '%s' not implemented!", newlang::toString(m_var_type_current)); } -const Variable::PairType & Obj::at(int64_t index) const { +const Variable::PairType & Obj::at(int64_t index) const { if(m_var_type_current == ObjType::StrChar) { if(index < static_cast (m_str.size())) { m_str_pair = pair(CreateString(std::string(1, m_str[index]))); @@ -195,7 +200,7 @@ const Variable::PairType & Obj::at(int64_t index) const { return Variable::at(index); } -Variable::PairType & Obj::at(int64_t index) { +Variable::PairType & Obj::at(int64_t index) { if(m_var_type_current == ObjType::StrChar) { if(index < static_cast (m_str.size())) { m_str_pair = pair(CreateString(std::string(1, m_str[index]))); @@ -307,7 +312,7 @@ ObjPtr Obj::op_set_index(int64_t index, std::string value) { } // at(index).second.set_(value); (*at(index).second) = value; - return Variable::operator[](index); + return Variable::operator[](index).second; } bool Obj::exist(ObjPtr &find, bool strong) { @@ -377,7 +382,7 @@ ObjPtr Obj::operator+=(Obj value) { return shared(); } else if(value.m_var_type_current == ObjType::Class || value.m_var_type_current == ObjType::Dictionary) { for (int i = 0; i < value.size(); i++) { - push_back(value.at(i)); + push_back(value.at(i).second); } return shared(); } @@ -416,9 +421,9 @@ ObjPtr Obj::operator-=(Obj value) { return shared(); } else if(value.m_var_type_current == ObjType::Class || value.m_var_type_current == ObjType::Dictionary) { for (int i = 0; i < value.size(); i++) { - auto found = select(value.name(i)); - if(!found.complete()) { - erase(found); + auto found = find(value.name(i)); + if(found != end()) { + ListType::erase(found); } } return shared(); @@ -588,12 +593,12 @@ void Obj::ClonePropTo(Obj & clone) const { NL_CHECK(!isLocalType(m_var_type_current), "Local object not clonable!"); - for (int i = 0; i < Variable::size(); i++) { - if(Variable::at(i).second) { - if(Variable::at(i).second->m_is_reference || Variable::at(i).second->m_is_reference) { - clone.push_back(Variable::at(i)); + for (int i = 0; i < Variable::size(); i++) { + if(Variable::at(i).second) { + if(Variable::at(i).second->m_is_reference || Variable::at(i).second->m_is_reference) { + clone.push_back(Variable::at(i)); } else { - clone.push_back(Variable::at(i).second->Clone(nullptr), name(i)); + clone.push_back(Variable::at(i).second->Clone(nullptr), name(i)); } } else { if(name(i).empty()) { @@ -728,7 +733,7 @@ std::string Obj::toString(bool deep) const { if(i) { result += ","; } - result += (*m_dimensions)[i]->toString(); + result += (*m_dimensions)[i].second->toString(); } result += "]"; } @@ -821,6 +826,10 @@ std::string Obj::toString(bool deep) const { ASSERT(m_fraction); result += m_fraction->GetAsString(); return result; + + case ObjType::Iterator: + case ObjType::IteratorEnd: + return newlang::toString(m_var_type_current); } } LOG_RUNTIME("Unknown type '%s' (%d)", newlang::toString(m_var_type_current), (int) m_var_type_current); @@ -984,7 +993,7 @@ ObjPtr Obj::CreateFunc(std::string prototype, FunctionType *func_addr, ObjType t TermPtr proto = Parser::ParseString(std::string(prototype + ":={}")); proto = proto->Left(); - ObjPtr result = Obj::CreateType(type, proto->m_text.c_str(), type); + ObjPtr result = Obj::CreateType(type, type); * const_cast (&result->m_func_proto) = proto; result->m_func_ptr = (void *) func_addr; @@ -1024,13 +1033,13 @@ Obj::Obj(Context *ctx, const TermPtr term, bool as_value, Obj * local_vars) { if(term->name(i).empty()) { if(as_value) { // Не именованный аргумент - push_back(Context::CreateRVal(ctx, (*term)[i], local_vars)); + push_back(Context::CreateRVal(ctx, (*term)[i].second, local_vars)); } else { // Обязательный аргумент без значения по умолчанию push_back(pair(nullptr, term->at(i).second->getText())); } } else { - push_back(Context::CreateRVal(ctx, (*term)[i], local_vars), term->name(i)); + push_back(Context::CreateRVal(ctx, (*term)[i].second, local_vars), term->name(i)); } } } @@ -1147,8 +1156,8 @@ void Obj::ConvertToArgs_(Obj *in, bool check_valid, Context * ctx) { // } if(i < size()) { if(check_valid && at(i).second && at(i).second->getType() != ObjType::None) { - if(!canCast((*in)[i]->getType(), at(i).second->getType())) { - LOG_RUNTIME("Fail cast value '%s' to type '%s'", newlang::toString((*in)[i]->getType()), + if(!canCast((*in)[i].second->getType(), at(i).second->getType())) { + LOG_RUNTIME("Fail cast value '%s' to type '%s'", newlang::toString((*in)[i].second->getType()), newlang::toString(at(i).second->getType())); } } @@ -1156,20 +1165,20 @@ void Obj::ConvertToArgs_(Obj *in, bool check_valid, Context * ctx) { at(i).second = Obj::CreateNone(); } if(m_func_proto && i < m_func_proto->size()) { - at(i).second->m_is_reference = (*m_func_proto)[i]->isRef(); + at(i).second->m_is_reference = (*m_func_proto)[i].second->isRef(); ObjType base_type = ObjType::None; if(ctx) { - base_type = typeFromString((*m_func_proto)[i]->m_type_name, ctx); + base_type = typeFromString((*m_func_proto)[i].second->m_type_name, ctx); } else { - base_type = ctx->BaseTypeFromString((*m_func_proto)[i]->m_type_name); + base_type = ctx->BaseTypeFromString((*m_func_proto)[i].second->m_type_name); } - ObjType limit_type = (*in)[i]->getTypeAsLimit(); + ObjType limit_type = (*in)[i].second->getTypeAsLimit(); if(!canCast(limit_type, base_type)) { LOG_RUNTIME("Fail cast value '%s' to type '%s'", - (*in)[i]->toString().c_str(), (*m_func_proto)[i]->m_type_name.c_str()); + (*in)[i].second->toString().c_str(), (*m_func_proto)[i].second->m_type_name.c_str()); } } - at(i).second->op_assign((*in)[i]); + at(i).second->op_assign((*in)[i].second); } else { if(check_valid && !is_ellipsis && m_func_proto && i >= m_func_proto->size()) { LOG_RUNTIME("Positional args overflow. Ptrototype '%s'!", @@ -1179,17 +1188,17 @@ void Obj::ConvertToArgs_(Obj *in, bool check_valid, Context * ctx) { } } else { named = true; - auto find = select(in->name(i)); - if(find != end()) { - if(check_valid && *find && (*find)->getType() != (*in)[i]->getType() && (*find)->getType() != ObjType::None) { - LOG_RUNTIME("Different type arg '%s' and '%s'", (*find)->toString().c_str(), - (*in)[i]->toString().c_str()); + auto found = find(in->name(i)); + if(found != end()) { + if(check_valid && (*found).second && (*found).second->getType() != (*in)[i].second->getType() && (*found).second->getType() != ObjType::None) { + LOG_RUNTIME("Different type arg '%s' and '%s'", (*found).second->toString().c_str(), + (*in)[i].second->toString().c_str()); } //@todo Проверка ограничений размер данных при указаном типе - if(!*find) { - *find = Obj::CreateNone(); + if(!(*found).second) { + (*found).second = Obj::CreateNone(); } - (*find)->op_assign((*in)[i]); + (*found).second->op_assign((*in)[i].second); } else { for (int pos = 0; pos < size(); pos++) { if(!at(pos).first.empty() && at(pos).first.compare(in->at(i).first) == 0) { @@ -1318,7 +1327,7 @@ bool Obj::op_equal(Obj & value) { if(name(i).compare(value.name(i)) != 0) { return false; } - if(!at(i).second->op_equal(value[i])) { + if(!at(i).second->op_equal(value[i].second)) { return false; } @@ -1432,14 +1441,14 @@ bool Obj::op_duck_test_prop(Obj *base, Obj *value, bool strong) { ObjPtr field; for (int i = 0; i < value->size(); i++) { if(value->name(i).empty()) { - field = (*base)[i]; + field = (*base)[i].second; } else { - field = (*base)[value->name(i)]; + field = (*base)[value->name(i)].second; } if(!field) { return false; } - if(strong || !((*value)[i]->getType() != ObjType::None)) { + if(strong || !((*value)[i].second->getType() != ObjType::None)) { for (auto &elem : *value) { if(!field->op_duck_test(elem.second, strong)) { @@ -1526,7 +1535,7 @@ std::string Obj::format(std::string format, Obj * args) { // Заменить номер аргумента name = "\\$" + std::to_string(i + 1); - place = (*args)[i]->GetValueAsString(); + place = (*args)[i].second->GetValueAsString(); format = std::regex_replace(format, std::regex(name), place); if(!args->name(i).empty()) { @@ -1574,7 +1583,7 @@ ObjPtr Obj::toShape_(ObjPtr dims) { } else if(is_dictionary_type()) { if(size() > array[0]) { - m_data.resize(array[0]); // Уменьшить размер + ListType::resize(array[0]); // Уменьшить размер } else { while(size() < array[0]) { push_back(Obj::CreateNone()); @@ -2010,136 +2019,136 @@ ObjPtr Obj::CallNative(Context *ctx, Obj args) { m_func_mangle_name.empty() ? m_func_proto->m_text.c_str() : m_func_mangle_name.c_str(), m_module_name.empty() ? "none" : m_module_name.c_str()); - bool is_ellipsis = (m_func_proto->size() && (*m_func_proto)[m_func_proto->size() - 1]->getTermID() == TermID::ELLIPSIS); + bool is_ellipsis = (m_func_proto->size() && (*m_func_proto)[m_func_proto->size() - 1].second->getTermID() == TermID::ELLIPSIS); size_t check_count = is_ellipsis ? m_func_proto->size() - 1 : m_func_proto->size(); // Пропустить нулевой аргумент для нативных функций for (int i = 1; i < args.size(); i++) { - ASSERT(args[i]); - if(args[i]->m_is_reference) { - LOG_RUNTIME("Argument REFERENCE! %s", args[i]->toString().c_str()); + ASSERT(args[i].second); + if(args[i].second->m_is_reference) { + LOG_RUNTIME("Argument REFERENCE! %s", args[i].second->toString().c_str()); } size_t pind = i - 1; // Индекс прототипа на единицу меньше из-за пустого нулевого аргумента - ObjType type = args[i]->getTypeAsLimit(); + ObjType type = args[i].second->getTypeAsLimit(); switch(type) { case ObjType::Bool: if(pind < check_count) { - NL_CHECK(!(*m_func_proto)[pind]->m_type_name.empty(), "Undefined type arg '%s'", (*m_func_proto)[pind]->toString().c_str()); - NL_CHECK(canCast(type, typeFromString((*m_func_proto)[pind]->m_type_name, ctx)), "Fail cast from '%s' to '%s'", - (*m_func_proto)[pind]->m_type_name.c_str(), newlang::toString(type)); + NL_CHECK(!(*m_func_proto)[pind].second->m_type_name.empty(), "Undefined type arg '%s'", (*m_func_proto)[pind].second->toString().c_str()); + NL_CHECK(canCast(type, typeFromString((*m_func_proto)[pind].second->m_type_name, ctx)), "Fail cast from '%s' to '%s'", + (*m_func_proto)[pind].second->m_type_name.c_str(), newlang::toString(type)); } m_args_type.push_back(ctx->m_runtime->m_ffi_type_uint8); - temp.boolean = args[i]->GetValueAsBoolean(); + temp.boolean = args[i].second->GetValueAsBoolean(); m_args_val.push_back(temp); break; case ObjType::Char: if(pind < check_count) { - NL_CHECK(!(*m_func_proto)[pind]->m_type_name.empty(), "Undefined type arg '%s'", (*m_func_proto)[pind]->toString().c_str()); - NL_CHECK(canCast(type, typeFromString((*m_func_proto)[pind]->m_type_name, ctx)), "Fail cast from '%s' to '%s'", - (*m_func_proto)[pind]->m_type_name.c_str(), newlang::toString(type)); + NL_CHECK(!(*m_func_proto)[pind].second->m_type_name.empty(), "Undefined type arg '%s'", (*m_func_proto)[pind].second->toString().c_str()); + NL_CHECK(canCast(type, typeFromString((*m_func_proto)[pind].second->m_type_name, ctx)), "Fail cast from '%s' to '%s'", + (*m_func_proto)[pind].second->m_type_name.c_str(), newlang::toString(type)); } m_args_type.push_back(ctx->m_runtime->m_ffi_type_sint8); - temp.integer = args[i]->GetValueAsInteger(); + temp.integer = args[i].second->GetValueAsInteger(); m_args_val.push_back(temp); break; case ObjType::Short: if(pind < check_count) { - NL_CHECK(!(*m_func_proto)[pind]->m_type_name.empty(), "Undefined type arg '%s'", (*m_func_proto)[pind]->toString().c_str()); - NL_CHECK(canCast(type, typeFromString((*m_func_proto)[pind]->m_type_name, ctx)), "Fail cast from '%s' to '%s'", - (*m_func_proto)[pind]->m_type_name.c_str(), newlang::toString(type)); + NL_CHECK(!(*m_func_proto)[pind].second->m_type_name.empty(), "Undefined type arg '%s'", (*m_func_proto)[pind].second->toString().c_str()); + NL_CHECK(canCast(type, typeFromString((*m_func_proto)[pind].second->m_type_name, ctx)), "Fail cast from '%s' to '%s'", + (*m_func_proto)[pind].second->m_type_name.c_str(), newlang::toString(type)); } m_args_type.push_back(ctx->m_runtime->m_ffi_type_sint16); - temp.integer = args[i]->GetValueAsInteger(); + temp.integer = args[i].second->GetValueAsInteger(); m_args_val.push_back(temp); break; case ObjType::Int: if(pind < check_count) { - NL_CHECK(!(*m_func_proto)[pind]->m_type_name.empty(), "Undefined type arg '%s'", (*m_func_proto)[pind]->toString().c_str()); - NL_CHECK(canCast(type, typeFromString((*m_func_proto)[pind]->m_type_name, ctx)), "Fail cast from '%s' to '%s'", - (*m_func_proto)[pind]->m_type_name.c_str(), newlang::toString(type)); + NL_CHECK(!(*m_func_proto)[pind].second->m_type_name.empty(), "Undefined type arg '%s'", (*m_func_proto)[pind].second->toString().c_str()); + NL_CHECK(canCast(type, typeFromString((*m_func_proto)[pind].second->m_type_name, ctx)), "Fail cast from '%s' to '%s'", + (*m_func_proto)[pind].second->m_type_name.c_str(), newlang::toString(type)); } m_args_type.push_back(ctx->m_runtime->m_ffi_type_sint32); - temp.integer = args[i]->GetValueAsInteger(); + temp.integer = args[i].second->GetValueAsInteger(); m_args_val.push_back(temp); break; case ObjType::Long: if(pind < check_count) { - NL_CHECK(!(*m_func_proto)[pind]->m_type_name.empty(), "Undefined type arg '%s'", (*m_func_proto)[pind]->toString().c_str()); - NL_CHECK(canCast(type, typeFromString((*m_func_proto)[pind]->m_type_name, ctx)), "Fail cast from '%s' to '%s'", - (*m_func_proto)[pind]->m_type_name.c_str(), newlang::toString(type)); + NL_CHECK(!(*m_func_proto)[pind].second->m_type_name.empty(), "Undefined type arg '%s'", (*m_func_proto)[pind].second->toString().c_str()); + NL_CHECK(canCast(type, typeFromString((*m_func_proto)[pind].second->m_type_name, ctx)), "Fail cast from '%s' to '%s'", + (*m_func_proto)[pind].second->m_type_name.c_str(), newlang::toString(type)); } m_args_type.push_back(ctx->m_runtime->m_ffi_type_sint64); - temp.integer = args[i]->GetValueAsInteger(); + temp.integer = args[i].second->GetValueAsInteger(); m_args_val.push_back(temp); break; case ObjType::Float: if(pind < check_count) { - NL_CHECK(!(*m_func_proto)[pind]->m_type_name.empty(), "Undefined type arg '%s'", (*m_func_proto)[pind]->toString().c_str()); - NL_CHECK(canCast(type, typeFromString((*m_func_proto)[pind]->m_type_name, ctx)), "Fail cast from '%s' to '%s'", - (*m_func_proto)[pind]->m_type_name.c_str(), newlang::toString(type)); + NL_CHECK(!(*m_func_proto)[pind].second->m_type_name.empty(), "Undefined type arg '%s'", (*m_func_proto)[pind].second->toString().c_str()); + NL_CHECK(canCast(type, typeFromString((*m_func_proto)[pind].second->m_type_name, ctx)), "Fail cast from '%s' to '%s'", + (*m_func_proto)[pind].second->m_type_name.c_str(), newlang::toString(type)); } m_args_type.push_back(ctx->m_runtime->m_ffi_type_float); - temp.number = args[i]->GetValueAsNumber(); + temp.number = args[i].second->GetValueAsNumber(); m_args_val.push_back(temp); break; case ObjType::Double: if(pind < check_count) { - NL_CHECK(!(*m_func_proto)[pind]->m_type_name.empty(), "Undefined type arg '%s'", (*m_func_proto)[pind]->toString().c_str()); - NL_CHECK(canCast(type, typeFromString((*m_func_proto)[pind]->m_type_name, ctx)), "Fail cast from '%s' to '%s'", - (*m_func_proto)[pind]->m_type_name.c_str(), newlang::toString(type)); + NL_CHECK(!(*m_func_proto)[pind].second->m_type_name.empty(), "Undefined type arg '%s'", (*m_func_proto)[pind].second->toString().c_str()); + NL_CHECK(canCast(type, typeFromString((*m_func_proto)[pind].second->m_type_name, ctx)), "Fail cast from '%s' to '%s'", + (*m_func_proto)[pind].second->m_type_name.c_str(), newlang::toString(type)); } m_args_type.push_back(ctx->m_runtime->m_ffi_type_double); - temp.number = args[i]->GetValueAsNumber(); + temp.number = args[i].second->GetValueAsNumber(); m_args_val.push_back(temp); break; case ObjType::StrChar: if(pind < check_count) { - NL_CHECK(!(*m_func_proto)[pind]->m_type_name.empty(), "Undefined type arg '%s'", (*m_func_proto)[pind]->toString().c_str()); - NL_CHECK(canCast(type, typeFromString((*m_func_proto)[pind]->m_type_name, ctx)), "Fail cast from '%s' to '%s'", - (*m_func_proto)[pind]->m_type_name.c_str(), newlang::toString(type)); + NL_CHECK(!(*m_func_proto)[pind].second->m_type_name.empty(), "Undefined type arg '%s'", (*m_func_proto)[pind].second->toString().c_str()); + NL_CHECK(canCast(type, typeFromString((*m_func_proto)[pind].second->m_type_name, ctx)), "Fail cast from '%s' to '%s'", + (*m_func_proto)[pind].second->m_type_name.c_str(), newlang::toString(type)); } m_args_type.push_back(ctx->m_runtime->m_ffi_type_pointer); - temp.ptr = args[i]->m_str.c_str(); + temp.ptr = args[i].second->m_str.c_str(); m_args_val.push_back(temp); break; case ObjType::StrWide: if(pind < check_count) { - NL_CHECK(!(*m_func_proto)[pind]->m_type_name.empty(), "Undefined type arg '%s'", (*m_func_proto)[pind]->toString().c_str()); - NL_CHECK(canCast(type, typeFromString((*m_func_proto)[pind]->m_type_name, ctx)), "Fail cast from '%s' to '%s'", - (*m_func_proto)[pind]->m_type_name.c_str(), newlang::toString(type)); + NL_CHECK(!(*m_func_proto)[pind].second->m_type_name.empty(), "Undefined type arg '%s'", (*m_func_proto)[pind].second->toString().c_str()); + NL_CHECK(canCast(type, typeFromString((*m_func_proto)[pind].second->m_type_name, ctx)), "Fail cast from '%s' to '%s'", + (*m_func_proto)[pind].second->m_type_name.c_str(), newlang::toString(type)); } m_args_type.push_back(ctx->m_runtime->m_ffi_type_pointer); - temp.ptr = args[i]->m_wstr.c_str(); + temp.ptr = args[i].second->m_wstr.c_str(); m_args_val.push_back(temp); break; case ObjType::Pointer: if(pind < check_count) { - NL_CHECK(!(*m_func_proto)[pind]->m_type_name.empty(), "Undefined type arg '%s'", (*m_func_proto)[pind]->toString().c_str()); - NL_CHECK(canCast(type, typeFromString((*m_func_proto)[pind]->m_type_name, ctx)), "Fail cast from '%s' to '%s'", - (*m_func_proto)[pind]->m_type_name.c_str(), newlang::toString(type)); + NL_CHECK(!(*m_func_proto)[pind].second->m_type_name.empty(), "Undefined type arg '%s'", (*m_func_proto)[pind].second->toString().c_str()); + NL_CHECK(canCast(type, typeFromString((*m_func_proto)[pind].second->m_type_name, ctx)), "Fail cast from '%s' to '%s'", + (*m_func_proto)[pind].second->m_type_name.c_str(), newlang::toString(type)); } m_args_type.push_back(ctx->m_runtime->m_ffi_type_pointer); - temp.ptr = args[i]->m_func_ptr; + temp.ptr = args[i].second->m_func_ptr; m_args_val.push_back(temp); break; default: - LOG_RUNTIME("Native arg '%s' not implemented!", args[i]->toString().c_str()); + LOG_RUNTIME("Native arg '%s' not implemented!", args[i].second->toString().c_str()); } - if(pind < check_count && (*m_func_proto)[pind]->GetType()) { - if((*m_func_proto)[pind]->GetType()->m_text.compare(newlang::toString(ObjType::Format)) == 0) { + if(pind < check_count && (*m_func_proto)[pind].second->GetType()) { + if((*m_func_proto)[pind].second->GetType()->m_text.compare(newlang::toString(ObjType::Format)) == 0) { NL_CHECK(ParsePrintfFormat(&args, i), "Fail format string or type args!"); } } @@ -2238,22 +2247,22 @@ ObjPtr Obj::CallNative(Context *ctx, Obj args) { return Obj::CreateNone(); } -bool newlang::ParsePrintfFormat(Obj *args, size_t start) { +bool newlang::ParsePrintfFormat(Obj *args, int start) { if(!args) { LOG_WARNING("Missing object!"); return false; } - if(args->size() <= static_cast (start) || !(*args)[start]) { + if(args->size() <= static_cast (start) || !(*args)[start].second) { LOG_WARNING("Missing format string!"); return false; } - if(!(*args)[start]->is_string_type()) { - LOG_WARNING("Argument Format '%s' not string type!", (*args)[start]->toString().c_str()); + if(!(*args)[start].second->is_string_type()) { + LOG_WARNING("Argument Format '%s' not string type!", (*args)[start].second->toString().c_str()); return false; } - std::string format = (*args)[start]->GetValueAsString(); + std::string format = (*args)[start].second->GetValueAsString(); static const std::string flags_list = "-+0123456789.lLh"; // '#', '*' @@ -2309,8 +2318,8 @@ bool newlang::ParsePrintfFormat(Obj *args, size_t start) { } else if(pos && format[pos - 1] == 'h') { cast = ObjType::Short; } - if(!canCast((*args)[aind]->m_var_type_current, cast)) { - LOG_WARNING("Cast '%s' to '%s' not supported!", newlang::toString((*args)[aind]->m_var_type_current), newlang::toString(cast)); + if(!canCast((*args)[aind].second->m_var_type_current, cast)) { + LOG_WARNING("Cast '%s' to '%s' not supported!", newlang::toString((*args)[aind].second->m_var_type_current), newlang::toString(cast)); result = false; } break; @@ -2323,8 +2332,8 @@ bool newlang::ParsePrintfFormat(Obj *args, size_t start) { case 'G'://%G В зависимости от того, какой вывод будет короче, используется %Е или %F cast = ObjType::Double; - if(!canCast((*args)[aind]->m_var_type_current, cast)) { - LOG_WARNING("Cast '%s' to '%s' not supported!", newlang::toString((*args)[aind]->m_var_type_current), newlang::toString(cast)); + if(!canCast((*args)[aind].second->m_var_type_current, cast)) { + LOG_WARNING("Cast '%s' to '%s' not supported!", newlang::toString((*args)[aind].second->m_var_type_current), newlang::toString(cast)); result = false; } break; @@ -2334,8 +2343,8 @@ bool newlang::ParsePrintfFormat(Obj *args, size_t start) { if(pos && (format[pos - 1] == 'l' || format[pos - 1] == 'L')) { cast = ObjType::Int; } - if(!canCast((*args)[aind]->m_var_type_current, cast)) { - LOG_WARNING("Cast '%s' to '%s' not supported!", newlang::toString((*args)[aind]->m_var_type_current), newlang::toString(cast)); + if(!canCast((*args)[aind].second->m_var_type_current, cast)) { + LOG_WARNING("Cast '%s' to '%s' not supported!", newlang::toString((*args)[aind].second->m_var_type_current), newlang::toString(cast)); result = false; } break; @@ -2345,8 +2354,8 @@ bool newlang::ParsePrintfFormat(Obj *args, size_t start) { if(pos && (format[pos - 1] == 'l' || format[pos - 1] == 'L')) { cast = ObjType::StrWide; } - if(!canCast((*args)[aind]->m_var_type_current, cast)) { - LOG_WARNING("Cast '%s' to '%s' not supported!", newlang::toString((*args)[aind]->m_var_type_current), newlang::toString(cast)); + if(!canCast((*args)[aind].second->m_var_type_current, cast)) { + LOG_WARNING("Cast '%s' to '%s' not supported!", newlang::toString((*args)[aind].second->m_var_type_current), newlang::toString(cast)); result = false; } break; @@ -2354,8 +2363,8 @@ bool newlang::ParsePrintfFormat(Obj *args, size_t start) { case 'p': cast = ObjType::Pointer; - if(!canCast((*args)[aind]->m_var_type_current, cast)) { - LOG_WARNING("Cast '%s' to '%s' not supported!", newlang::toString((*args)[aind]->m_var_type_current), newlang::toString(cast)); + if(!canCast((*args)[aind].second->m_var_type_current, cast)) { + LOG_WARNING("Cast '%s' to '%s' not supported!", newlang::toString((*args)[aind].second->m_var_type_current), newlang::toString(cast)); result = false; } break; @@ -2392,19 +2401,19 @@ void newlang::ConvertRangeToDict(Obj *from, Obj & to) { to.m_var_type_current = ObjType::Dictionary; } - ObjPtr value = (*from)["start"]->Clone(); - if((*value) < (*from)["stop"]) { - ASSERT((*from)["step"]->GetValueAsNumber() > 0); - while((*value) < (*from)["stop"]) { + ObjPtr value = (*from)["start"].second->Clone(); + if((*value) < (*from)["stop"].second) { + ASSERT((*from)["step"].second->GetValueAsNumber() > 0); + while((*value) < (*from)["stop"].second) { to.push_back(value->Clone()); - (*value) += (*from)["step"]; + (*value) += (*from)["step"].second; } } else { - ASSERT((*from)["step"]->GetValueAsNumber() < 0); - while((*value) > (*from)["stop"]) { + ASSERT((*from)["step"].second->GetValueAsNumber() < 0); + while((*value) > (*from)["stop"].second) { to.push_back(value->Clone()); - (*value) += (*from)["step"]; + (*value) += (*from)["step"].second; } } @@ -2605,56 +2614,56 @@ ObjPtr Obj::CreateBaseType(ObjType type) { ObjPtr Obj::BaseTypeConstructor(const Context *ctx, Obj & args) { - if(args.empty() || !args[0]) { + if(args.empty() || !args[0].second) { LOG_RUNTIME("Self simple type not defined!"); } - ASSERT(args[0]->getType() == ObjType::Type); + ASSERT(args[0].second->getType() == ObjType::Type); ObjPtr result = nullptr; - if(isArithmeticType(args[0]->m_var_type_fixed)) { + if(isArithmeticType(args[0].second->m_var_type_fixed)) { result = ConstructorSimpleType_(ctx, args); - } else if(args[0]->m_var_type_fixed == ObjType::Dictionary) { + } else if(args[0].second->m_var_type_fixed == ObjType::Dictionary) { result = ConstructorDictionary_(ctx, args); - } else if(args[0]->m_var_type_fixed == ObjType::Pointer && args.size() > 1) { + } else if(args[0].second->m_var_type_fixed == ObjType::Pointer && args.size() > 1) { result = ConstructorNative_(ctx, args); - } else if(args[0]->m_var_type_fixed == ObjType::Class) { + } else if(args[0].second->m_var_type_fixed == ObjType::Class) { result = ConstructorClass_(ctx, args); - } else if(args[0]->m_var_type_fixed == ObjType::Struct || args[0]->m_var_type_fixed == ObjType::Union) { + } else if(args[0].second->m_var_type_fixed == ObjType::Struct || args[0].second->m_var_type_fixed == ObjType::Union) { result = ConstructorStruct_(ctx, args); - } else if(args[0]->m_var_type_fixed == ObjType::Enum) { + } else if(args[0].second->m_var_type_fixed == ObjType::Enum) { result = ConstructorEnum_(ctx, args); - } else if(args[0]->m_var_type_fixed == ObjType::Return) { + } else if(args[0].second->m_var_type_fixed == ObjType::Return) { result = ConstructorReturn_(ctx, args); - } else if(args[0]->m_var_type_fixed == ObjType::Break || args[0]->m_var_type_fixed == ObjType::Continue) { - result = ConstructorInterraption_(ctx, args, args[0]->m_var_type_fixed); - } else if(args[0]->m_var_type_fixed == ObjType::Error || args[0]->m_var_type_fixed == ObjType::ErrorParser - || args[0]->m_var_type_fixed == ObjType::ErrorRunTime || args[0]->m_var_type_fixed == ObjType::ErrorSignal) { + } else if(args[0].second->m_var_type_fixed == ObjType::Break || args[0].second->m_var_type_fixed == ObjType::Continue) { + result = ConstructorInterraption_(ctx, args, args[0].second->m_var_type_fixed); + } else if(args[0].second->m_var_type_fixed == ObjType::Error || args[0].second->m_var_type_fixed == ObjType::ErrorParser + || args[0].second->m_var_type_fixed == ObjType::ErrorRunTime || args[0].second->m_var_type_fixed == ObjType::ErrorSignal) { result = ConstructorError_(ctx, args); } else { - result = args[0]->Clone(); + result = args[0].second->Clone(); if(result) { result->m_is_const = false; } } if(!result) { - LOG_RUNTIME("Create type '%s' error or not implemented!", newlang::toString(args[0]->m_var_type_fixed)); + LOG_RUNTIME("Create type '%s' error or not implemented!", newlang::toString(args[0].second->m_var_type_fixed)); } - result->m_class_name = args[0]->m_class_name; + result->m_class_name = args[0].second->m_class_name; return result; } ObjPtr Obj::ConstructorSimpleType_(const Context *ctx, Obj & args) { - ASSERT(!args.empty() && args[0]); - ASSERT(args[0]->getType() == ObjType::Type); + ASSERT(!args.empty() && args[0].second); + ASSERT(args[0].second->getType() == ObjType::Type); // Переданы значения для приведения типов // Но само значение пока не установлено - ObjPtr result = args[0]->Clone(); + ObjPtr result = args[0].second->Clone(); if(args.size() == 1) { // Копия существующего типа с возможностью редактирования result->m_is_const = false; @@ -2666,7 +2675,7 @@ ObjPtr Obj::ConstructorSimpleType_(const Context *ctx, Obj & args) { if(result->m_dimensions) { // Размерность указана for (int i = 0; i < result->m_dimensions->size(); i++) { - Index ind = (*result->m_dimensions)[i]->toIndex(); + Index ind = (*result->m_dimensions)[i].second->toIndex(); if(ind.is_integer()) { dims.push_back(ind.integer()); } else if(ind.is_boolean()) { @@ -2684,10 +2693,10 @@ ObjPtr Obj::ConstructorSimpleType_(const Context *ctx, Obj & args) { ObjPtr convert; // Если обобщенный тип данных, а сами данные принадлежат обощенному типу - if(isGenericType(result->m_var_type_fixed) && isContainsType(result->m_var_type_fixed, args[1]->getType())) { - convert = args[1]->Clone(); + if(isGenericType(result->m_var_type_fixed) && isContainsType(result->m_var_type_fixed, args[1].second->getType())) { + convert = args[1].second->Clone(); } else { - convert = args[1]->toType(result->m_var_type_fixed); + convert = args[1].second->toType(result->m_var_type_fixed); } convert->m_var_type_fixed = result->m_var_type_fixed; convert.swap(result); @@ -2701,7 +2710,7 @@ ObjPtr Obj::ConstructorSimpleType_(const Context *ctx, Obj & args) { ObjPtr prev = nullptr; for (int i = 1; i < args.size(); i++) { - if(args[i]->getType() == ObjType::Ellipsis) { + if(args[i].second->getType() == ObjType::Ellipsis) { if(!prev) { LOG_RUNTIME("There is no previous item to repeat!"); } @@ -2726,14 +2735,14 @@ ObjPtr Obj::ConstructorSimpleType_(const Context *ctx, Obj & args) { break; } else { - prev = args[i]; + prev = args[i].second; } result->op_concat_(prev, ConcatMode::Append); } - if(args[0]->m_var_type_fixed != ObjType::Dictionary) { - result = result->toType(args[0]->m_var_type_fixed); + if(args[0].second->m_var_type_fixed != ObjType::Dictionary) { + result = result->toType(args[0].second->m_var_type_fixed); result->m_var_type_fixed = result->m_var_type_current; } } @@ -2749,7 +2758,7 @@ ObjPtr Obj::ConstructorSimpleType_(const Context *ctx, Obj & args) { } else if(isTensor(result->getType())) { if(dims.size() == 1 && dims[0] == 0) { // Скаляр - if(args.size() == 2 && args[0]->m_var_type_fixed == ObjType::Bool) { + if(args.size() == 2 && args[0].second->m_var_type_fixed == ObjType::Bool) { result->m_value = torch::scalar_tensor(result->empty() ? 0 : 1, at::ScalarType::Bool); return result; @@ -2774,12 +2783,12 @@ ObjPtr Obj::ConstructorSimpleType_(const Context *ctx, Obj & args) { ObjPtr Obj::ConstructorDictionary_(const Context *ctx, Obj & args) { - ASSERT(!args.empty() && args[0]); - ASSERT(args[0]->getType() == ObjType::Type); + ASSERT(!args.empty() && args[0].second); + ASSERT(args[0].second->getType() == ObjType::Type); ObjPtr result = Obj::CreateDict(); for (int i = 1; i < args.size(); i++) { - result->push_back(args[i], args.name(i)); + result->push_back(args[i].second, args.name(i)); } result->m_var_is_init = true; @@ -2805,8 +2814,7 @@ ObjPtr Obj::ConstructorClass_(const Context *ctx, Obj & args) { if(result->name(i).empty()) { LOG_RUNTIME("Field pos %d has no name!", i); } - if(!result->select(result->name(i)).complete()) { - + if(result->find(result->name(i)) != result->end()) { LOG_RUNTIME("Field name '%s' at index %d already exists!", result->name(i).c_str(), i); } } @@ -2822,12 +2830,12 @@ ObjPtr Obj::ConstructorStruct_(const Context *ctx, Obj & args) { } for (int i = 0; i < result->size(); i++) { - if(!(*result)[i]) { + if(!(*result)[i].second) { LOG_RUNTIME("Field '%s' at pos %d not defined!", result->name(i).c_str(), i); } - if(!(*result)[i] || !isSimpleType((*result)[i]->getType()) || isGenericType((*result)[i]->getType())) { + if(!(*result)[i].second || !isSimpleType((*result)[i].second->getType()) || isGenericType((*result)[i].second->getType())) { - LOG_RUNTIME("Field '%s' at pos %d not simple type! (%s)", result->name(i).c_str(), i, newlang::toString((*result)[i]->getType())); + LOG_RUNTIME("Field '%s' at pos %d not simple type! (%s)", result->name(i).c_str(), i, newlang::toString((*result)[i].second->getType())); } } return result; @@ -2847,22 +2855,22 @@ ObjPtr Obj::ConstructorEnum_(const Context *ctx, Obj & args) { for (int i = 1; i < args.size(); i++) { if(args.name(i).empty()) { - if(args[i] && args[i]->is_string_type()) { - enum_name = args[i]->GetValueAsString(); + if(args[i].second && args[i].second->is_string_type()) { + enum_name = args[i].second->GetValueAsString(); } else { LOG_RUNTIME("Field pos %d has no name!", i); } } else { enum_name = args.name(i); - if(args[i] && (args[i]->is_integer() || args[i]->is_bool_type())) { - val_int = args[i]->GetValueAsInteger(); - } else if(!args[i] || !args[i]->is_none_type()) { + if(args[i].second && (args[i].second->is_integer() || args[i].second->is_bool_type())) { + val_int = args[i].second->GetValueAsInteger(); + } else if(!args[i].second || !args[i].second->is_none_type()) { LOG_RUNTIME("Field value '%s' %d must integer type!", args.name(i).c_str(), i); } } - if(!result->select(enum_name).complete()) { + if(result->find(enum_name) != result->end()) { LOG_RUNTIME("Field value '%s' at index %d already exists!", enum_name.c_str(), i); } @@ -2914,3 +2922,32 @@ ObjPtr Obj::ConstructorInterraption_(const Context* ctx, Obj& args, ObjType type return result; } +template<> +ObjPtr Iterator::read_and_next(int64_t count) { + ObjPtr result; + + if(count == 0) { + result = (*(*this)).second; + (*this)++; + } else if(count > 0) { + + result = Obj::CreateDict(); + for (int64_t i = 0; i < count; i++) { + if(*this != this->end()) { + result->push_back(*(*this)); + (*this)++; + } else { + result->push_back(Obj::CreateType(ObjType::IteratorEnd)); + } + } + + } else { + count = -count; + result = Obj::CreateDict(); + while(*this != this->end() && result->size() < count) { + result->push_back(*(*this)); + (*this)++; + } + } + return result; +} diff --git a/src/object.h b/src/object.h index 10f2bc82..d61fcb63 100644 --- a/src/object.h +++ b/src/object.h @@ -35,7 +35,7 @@ namespace newlang { at::TensorOptions ConvertToTensorOptions(const Obj *obj); at::DimnameList ConvertToDimnameList(const Obj *obj); - bool ParsePrintfFormat(Obj *args, size_t start = 1); + bool ParsePrintfFormat(Obj *args, int start = 1); enum class ConcatMode : uint8_t { Error = 0, @@ -76,14 +76,7 @@ namespace newlang { void calcTensorDims(ObjPtr & obj, std::vector &dims); void testTensorDims(ObjPtr & obj, at::IntArrayRef dims, int64_t pos); - template struct overloaded : Ts... { - using Ts::operator()...; - class Obj *obj; - }; - // explicit deduction guide (not needed as of C++20) - template overloaded(Ts...) -> overloaded; - - class Obj : public Variable, public std::enable_shared_from_this { + class Obj : public Variable, public std::enable_shared_from_this { public: // constexpr static const char * BUILDIN_TYPE = "__var_type__"; @@ -92,7 +85,7 @@ namespace newlang { // constexpr static const char * BUILDIN_CLASS = "__class_name__"; // constexpr static const char * BUILDIN_NAMESPACE = "__namespace__"; - Obj(ObjType type = ObjType::None, const char *var_name = nullptr, TermPtr func_proto = nullptr, ObjType fixed = ObjType::None) : + Obj(ObjType type = ObjType::None, const char *var_name = nullptr, TermPtr func_proto = nullptr, ObjType fixed = ObjType::None, bool init = false) : m_var_type_current(type), m_var_name(var_name ? var_name : ""), m_func_proto(func_proto) { // m_ctx = nullptr; m_is_const = false; @@ -104,6 +97,7 @@ namespace newlang { m_is_reference = false; m_func_abi = FFI_DEFAULT_ABI; m_var_type_fixed = fixed; + m_var_is_init = init; } Obj(Context *ctx, const TermPtr term, bool as_value, Obj *local_vars); @@ -111,7 +105,7 @@ namespace newlang { [[nodiscard]] static inline PairType ArgNull(const std::string name = "") { - return Variable::pair(nullptr, name); + return pair(nullptr, name); } [[nodiscard]] @@ -121,7 +115,7 @@ namespace newlang { [[nodiscard]] static inline PairType Arg(ObjPtr value, const std::string name = "") { - return Variable::pair(value, name); + return pair(value, name); } template @@ -133,7 +127,7 @@ namespace newlang { template typename std::enable_if::value && !std::is_pointer::value && !std::is_same::value, PairType>::type static inline Arg(T value, const std::string name = "") { - return Variable::pair(CreateValue(value, ObjType::None), name); + return pair(CreateValue(value, ObjType::None), name); } inline ObjPtr shared() { @@ -345,13 +339,13 @@ namespace newlang { inline void SetTermProp(Term &term); - int64_t size() const override { + virtual int64_t size() const { return size(0); } - int64_t size(int64_t ind) const; + virtual int64_t size(int64_t ind) const; int64_t resize_(int64_t size, ObjPtr fill, const std::string = ""); - bool empty() const override { + virtual bool empty() const { if (is_none_type()) { return true; } else if (m_var_type_current == ObjType::StrChar) { @@ -361,26 +355,26 @@ namespace newlang { } else if (is_tensor()) { return !m_var_is_init || at::_is_zerotensor(m_value); } - return Variable::empty(); + return Variable::empty(); } - Variable::PairType & at(const std::string_view name) const { + Variable::PairType & at(const std::string_view name) const { Obj * const obj = (Obj * const) this; - return obj->Variable::at(name); + return obj->Variable::at(name); } - Variable::PairType & at(const std::string_view name) override { - return Variable::at(name); + Variable::PairType & at(const std::string_view name) override { + return Variable::at(name); } - Variable::PairType & at(const int64_t index) override; - const Variable::PairType & at(const int64_t index) const override; + Variable::PairType & at(const int64_t index) override; + const Variable::PairType & at(const int64_t index) const override; - Variable::PairType & at(ObjPtr find) { + Variable::PairType & at(ObjPtr find) { if (!find->is_string_type()) { LOG_RUNTIME("Value must be a string type %d", (int) find->getType()); } - return Variable::at(find->GetValueAsString()); + return Variable::at(find->GetValueAsString()); } bool exist(ObjPtr &find, bool strong); @@ -874,7 +868,7 @@ namespace newlang { static ObjPtr GetIndex(ObjPtr obj, TermPtr index_arg); static ObjPtr GetIndex(ObjPtr obj, size_t index) { - return (*obj)[index]; + return (*obj)[index].second; } void dump_dict_(std::string &str, bool deep = true) const { @@ -1033,9 +1027,8 @@ namespace newlang { } - static ObjPtr CreateType(ObjType type, const char *var_name = nullptr, ObjType fixed = ObjType::None) { - TermPtr term = nullptr; - return std::make_shared(type, var_name, term, fixed); + static ObjPtr CreateType(ObjType type, ObjType fixed = ObjType::None, bool is_init = false) { + return std::make_shared(type, nullptr, nullptr, fixed, is_init); } static ObjPtr CreateFraction(const std::string_view val) { @@ -1090,7 +1083,7 @@ namespace newlang { static ObjPtr CreateBaseType(ObjType type); static ObjPtr CreateNone() { - return CreateType(ObjType::None); + return CreateType(ObjType::None, ObjType::None, true); } template @@ -1149,20 +1142,20 @@ namespace newlang { LOG_RUNTIME("Fail tensor type %s", val.toString().c_str()); } - static ObjPtr CreateBool(bool value, const char *var_name = nullptr) { - ObjPtr result = CreateType(ObjType::None, var_name); + static ObjPtr CreateBool(bool value) { + ObjPtr result = CreateType(ObjType::None); result->m_value = torch::scalar_tensor(value, torch::Dtype::Bool); result->m_var_type_current = ObjType::Bool; result->m_var_is_init = true; return result; } - static ObjPtr CreateTensor(torch::Tensor tensor, const char *var_name = nullptr) { + static ObjPtr CreateTensor(torch::Tensor tensor) { ObjType check_type = GetType(tensor); if (!isTensor(check_type)) { LOG_RUNTIME("Unsupport torch type %s (%d)!", at::toString(tensor.dtype().toScalarType()), (int) tensor.dtype().toScalarType()); } - ObjPtr result = CreateType(check_type, var_name); + ObjPtr result = CreateType(check_type); result->m_value = tensor; result->m_var_is_init = true; return result; @@ -1186,16 +1179,16 @@ namespace newlang { at::indexing::Slice toSlice() { NL_CHECK(is_range(), "Convert to slice supported for range only!"); - ASSERT(size() == 3 && Variable::at("start").second && Variable::at("stop").second && Variable::at("step").second); + ASSERT(size() == 3 && Variable::at("start").second && Variable::at("stop").second && Variable::at("step").second); - NL_CHECK(Variable::at("start").second->is_integer(), "Slice value start support integer type only!"); - NL_CHECK(Variable::at("stop").second->is_integer(), "Slice value stop support integer type only!"); - NL_CHECK(Variable::at("step").second->is_integer(), "Slice value step support integer type only!"); + NL_CHECK(Variable::at("start").second->is_integer(), "Slice value start support integer type only!"); + NL_CHECK(Variable::at("stop").second->is_integer(), "Slice value stop support integer type only!"); + NL_CHECK(Variable::at("step").second->is_integer(), "Slice value step support integer type only!"); return at::indexing::Slice( - Variable::at("start").second->GetValueAsInteger(), - Variable::at("stop").second->GetValueAsInteger(), - Variable::at("step").second->GetValueAsInteger()); + Variable::at("start").second->GetValueAsInteger(), + Variable::at("stop").second->GetValueAsInteger(), + Variable::at("step").second->GetValueAsInteger()); } /* @@ -1746,7 +1739,7 @@ namespace newlang { std::string m_namespace; std::string m_str; std::wstring m_wstr; - mutable std::pair::Type> m_str_pair; //< Для доступа к отдельным символам строк + mutable PairType m_str_pair; //< Для доступа к отдельным символам строк const TermPtr m_func_proto; std::string m_func_mangle_name; @@ -1770,6 +1763,192 @@ namespace newlang { }; + + /* + * Требуется разделять конейнеры с данными и итераторы по данным. + * В С++ контейнеры предоставялют итераторы непосредственно из самого контейнера. + * Это удобно для использования в рукописном коде, но сложно контроллировать в генерируемом исходнике, + * т.к. требуется использовать и итертор и сам контейнер с данными (для сравнения с end()). + * + * Логика работы с итераторами следующая. + * Итератор - отдельный объект, которому для создания требуется контейнер с данными. + * Итератор два интерфейса перебора данных: + * 1. - первый интерфейс итератора как в С++ + * 2. - второй интерфейс для использования в генерируемом коде с логикой NewLang + * + * Разделение контейнера и итератора на два объекта позволит выполнять проверку на использование + * + */ + + /* + * Итератор + */ + template + class Iterator : public std::iterator { + public: + + enum class IterCmp : int8_t { + No = static_cast (ObjType::None), /* skip data */ + Yes = static_cast (ObjType::Iterator), /* return data */ + End = static_cast (ObjType::IteratorEnd), /* iterator complete */ + }; + + STATIC_ASSERT(static_cast (IterCmp::Yes)); + STATIC_ASSERT(!static_cast (IterCmp::No)); + + typedef Iterator iterator; + typedef Iterator const_iterator; + + typedef Variable IterObj; + typedef typename Variable::Type IterObjPtr; + typedef typename Variable::PairType IterPairType; + typedef typename Variable::ListType IterListType; + + + typedef IterCmp CompareFuncType(const IterPairType &pair, const T *args, void *extra); + + /** + * Итератор для элементов списка с regex фильтром по имени элемента (по умолчанию для всех элементов списка) + * @param obj + * @param find_key + */ + Iterator(T &obj, const std::string find_key = "(.|\\n)*") : + Iterator(obj, &CompareFuncDefault, reinterpret_cast (const_cast (&find_key)), static_cast (this)) { + } + + /** + * Итератор для элементов списка с фильтром в виде функции обратного вызова + * @param obj + * @param func + * @param arg + * @param extra + */ + Iterator(T &obj, CompareFuncType *func, T *arg, void * extra = nullptr) : + m_iter_obj(obj), m_match(), m_func(func), m_func_args(arg), m_func_extra(extra), m_found(m_iter_obj.begin()) { + search_loop(); + } + + Iterator(const Iterator &iter) : m_iter_obj(iter.m_iter_obj), m_match(iter.m_match), m_func(iter.m_func), + m_func_args(iter.m_func_args), m_func_extra(iter.m_func_extra), m_found(iter.m_found) { + } + + SCOPE(private) : + T &m_iter_obj; + std::regex m_match; + std::string m_filter; + CompareFuncType *m_func; + T *m_func_args; + void *m_func_extra; + + mutable typename Variable::iterator m_found; + + inline static const IterPairType m_interator_end = IterObj::pair(Obj::CreateType(ObjType::IteratorEnd, ObjType::IteratorEnd, true)); + + static IterCmp CompareFuncDefault(const IterPairType &pair, const T *filter, void *extra) { + const std::string * str_filter = reinterpret_cast (filter); + Iterator * iter = static_cast (extra); + if (iter && str_filter) { + + iter->m_func_args = nullptr; // Передается однократно при создании объекта + iter->m_filter = *str_filter; + + if (!iter->m_filter.empty()) { + try { + iter->m_match = std::regex(iter->m_filter); + } catch (const std::regex_error &err) { + LOG_RUNTIME("Regular expression for '%s' error '%s'!", str_filter->c_str(), err.what()); + } + } + } + + if (iter) { + if (iter->m_filter.empty()) { + return pair.first.empty() ? IterCmp::Yes : IterCmp::No; + } else { + return std::regex_match(pair.first, iter->m_match) ? IterCmp::Yes : IterCmp::No; + } + } + return IterCmp::Yes; + } + + public: + + iterator begin() { + Iterator copy(*this); + copy.reset(); + return copy; + } + + iterator end() { + Iterator copy(*this); + copy.m_found = copy.m_iter_obj.end(); + return copy; + } + + inline const IterPairType &operator*() { + if (m_found == m_iter_obj.end()) { + return m_interator_end; + } + return *m_found; + } + + inline const IterPairType &operator*() const { + if (m_found == m_iter_obj.end()) { + return m_interator_end; + } + return *m_found; + } + + ObjPtr read_and_next(int64_t count); + + const iterator &operator++() const { + if (m_found != m_iter_obj.end()) { + m_found++; + search_loop(); + } + return *this; + } + + inline const iterator operator++(int) const { + return iterator::operator++(); + } + + + inline bool operator==(const iterator &other) const { + return m_found == other.m_found; + } + + inline bool operator!=(const iterator &other) const { + return m_found != other.m_found; + } + + inline void reset() { + m_found = m_iter_obj.begin(); + search_loop(); + } + + + protected: + + void search_loop() const { + while (m_found != m_iter_obj.end()) { + IterCmp result = IterCmp::Yes; + if (m_func) { + result = (*m_func)(*m_found, m_func_args, m_func_extra); + if (result == IterCmp::End) { + m_found = m_iter_obj.end(); + } + } + if (result != IterCmp::No) { + // IterCmp::Yes || IterCmp::End + return; + } + m_found++; + } + } + }; + + } // namespace newlang std::ostream & operator<<(std::ostream &out, newlang::Obj & var); diff --git a/src/parser.h b/src/parser.h index 4de79771..038abe4a 100644 --- a/src/parser.h +++ b/src/parser.h @@ -164,7 +164,13 @@ namespace newlang { LOG_RUNTIME("Fail parse name macro! '%s'", body.c_str()); // throw Interrupt(ParserMessage(buffer, row, col, "%s", msg), Interrupt::Parser); } - +////\__LINE__ +////\__FILE__ +////\__FUNC__ +////\__CLASS__ +////\__MACRO__ +// +//#\line 20 auto found = store.find(name); if (found != store.end()) { LOG_RUNTIME("Macro name %s are duplicated!", name.c_str()); diff --git a/src/pch.h b/src/pch.h index dab34ae5..294e1af2 100644 --- a/src/pch.h +++ b/src/pch.h @@ -59,7 +59,7 @@ #include "types.h" #undef LOG_RUNTIME -#define LOG_RUNTIME(...) LOG_EXCEPT(newlang::Interrupt, ##__VA_ARGS__) +#define LOG_RUNTIME(format, ...) LOG_EXCEPT(newlang::Interrupt, format, ##__VA_ARGS__) #endif // NEWLANG_PCH_H_ diff --git a/src/term.h b/src/term.h index 0e98ccba..cc938edf 100644 --- a/src/term.h +++ b/src/term.h @@ -102,7 +102,7 @@ namespace newlang { size_t IndexArg(TermPtr term); std::string ParserMessage(std::string &buffer, int row, int col, const char *format, ...); - class Term : public Variable, public std::enable_shared_from_this { + class Term : public Variable, public std::enable_shared_from_this { public: static TermPtr Create(Term * term) { diff --git a/src/test/alg_test.cpp b/src/test/alg_test.cpp index f6550232..ada94f5f 100644 --- a/src/test/alg_test.cpp +++ b/src/test/alg_test.cpp @@ -135,22 +135,22 @@ TEST(Alg, Foreach) { test->push_back(Obj::Arg(12)); test->push_back(Obj::Arg(13)); ASSERT_EQ(4, test->size()); - ASSERT_EQ(10, (*test)[0]->GetValueAsInteger()); - ASSERT_EQ(13, (*test)[3]->GetValueAsInteger()); + ASSERT_EQ(10, (*test)[0].second->GetValueAsInteger()); + ASSERT_EQ(13, (*test)[3].second->GetValueAsInteger()); ASSERT_EQ(test->resize_(4, nullptr), test->size()); ASSERT_EQ(4, test->size()); - ASSERT_EQ(10, (*test)[0]->GetValueAsInteger()); - ASSERT_EQ(13, (*test)[3]->GetValueAsInteger()); + ASSERT_EQ(10, (*test)[0].second->GetValueAsInteger()); + ASSERT_EQ(13, (*test)[3].second->GetValueAsInteger()); test->resize_(-3, nullptr); ASSERT_EQ(3, test->size()); - ASSERT_EQ(11, (*test)[0]->GetValueAsInteger()); - ASSERT_EQ(13, (*test)[2]->GetValueAsInteger()); + ASSERT_EQ(11, (*test)[0].second->GetValueAsInteger()); + ASSERT_EQ(13, (*test)[2].second->GetValueAsInteger()); test->resize_(-1, nullptr); ASSERT_EQ(1, test->size()); - ASSERT_EQ(13, (*test)[0]->GetValueAsInteger()); + ASSERT_EQ(13, (*test)[0].second->GetValueAsInteger()); test->resize_(0, nullptr); ASSERT_EQ(0, test->size()); @@ -163,8 +163,8 @@ TEST(Alg, Foreach) { ASSERT_TRUE(dict); ASSERT_TRUE(dict->is_dictionary_type()); ASSERT_EQ(3, dict->size()); - ASSERT_EQ(1, (*dict)[0]->GetValueAsInteger()); - ASSERT_EQ(3, (*dict)[2]->GetValueAsInteger()); + ASSERT_EQ(1, (*dict)[0].second->GetValueAsInteger()); + ASSERT_EQ(3, (*dict)[2].second->GetValueAsInteger()); ObjPtr temp = ctx.ExecStr("counter, dict := ... dict"); ASSERT_TRUE(temp); @@ -175,8 +175,8 @@ TEST(Alg, Foreach) { ASSERT_TRUE(dict->is_dictionary_type()); ASSERT_EQ(2, dict->size()); - ASSERT_EQ(2, (*dict)[0]->GetValueAsInteger()); - ASSERT_EQ(3, (*dict)[1]->GetValueAsInteger()); + ASSERT_EQ(2, (*dict)[0].second->GetValueAsInteger()); + ASSERT_EQ(3, (*dict)[1].second->GetValueAsInteger()); temp = ctx.ExecStr("counter, dict := ... dict"); ASSERT_TRUE(temp); @@ -187,7 +187,7 @@ TEST(Alg, Foreach) { ASSERT_TRUE(dict->is_dictionary_type()); ASSERT_EQ(1, dict->size()); - ASSERT_EQ(3, (*dict)[0]->GetValueAsInteger()); + ASSERT_EQ(3, (*dict)[0].second->GetValueAsInteger()); temp = ctx.ExecStr("counter, dict := ... dict"); ASSERT_TRUE(temp); @@ -271,9 +271,9 @@ TEST(Alg, Foreach) { ASSERT_TRUE(tensor->is_tensor()); ASSERT_TRUE(tensor->GetValueAsBoolean()); ASSERT_EQ(3, tensor->size()); - ASSERT_EQ(10, (*tensor)[0]->GetValueAsInteger()); - ASSERT_EQ(11, (*tensor)[1]->GetValueAsInteger()); - ASSERT_EQ(12, (*tensor)[2]->GetValueAsInteger()); + ASSERT_EQ(10, (*tensor)[0].second->GetValueAsInteger()); + ASSERT_EQ(11, (*tensor)[1].second->GetValueAsInteger()); + ASSERT_EQ(12, (*tensor)[2].second->GetValueAsInteger()); temp = ctx.ExecStr("counter, tensor := ... tensor "); ASSERT_TRUE(temp); @@ -285,8 +285,8 @@ TEST(Alg, Foreach) { ASSERT_TRUE(tensor->is_tensor()); ASSERT_TRUE(tensor->GetValueAsBoolean()); ASSERT_EQ(2, tensor ->size()); - ASSERT_EQ(11, (*tensor)[0]->GetValueAsInteger()); - ASSERT_EQ(12, (*tensor)[1]->GetValueAsInteger()); + ASSERT_EQ(11, (*tensor)[0].second->GetValueAsInteger()); + ASSERT_EQ(12, (*tensor)[1].second->GetValueAsInteger()); temp = ctx.ExecStr("counter, tensor := ... tensor "); ASSERT_TRUE(temp); @@ -298,7 +298,7 @@ TEST(Alg, Foreach) { ASSERT_TRUE(tensor->is_tensor()); ASSERT_TRUE(tensor->GetValueAsBoolean()); ASSERT_EQ(1, tensor ->size()); - ASSERT_EQ(12, (*tensor)[0]->GetValueAsInteger()); + ASSERT_EQ(12, (*tensor)[0].second->GetValueAsInteger()); temp = ctx.ExecStr("counter, tensor := ... tensor "); ASSERT_TRUE(temp); @@ -336,15 +336,15 @@ TEST(Alg, Foreach) { ObjPtr tensor_size = ctx.ExecStr("tensor_size := [10,20,30,40,]"); ASSERT_EQ(4, tensor_size->size()); - ASSERT_EQ(10, (*tensor_size)[0]->GetValueAsInteger()); - ASSERT_EQ(40, (*tensor_size)[3]->GetValueAsInteger()); + ASSERT_EQ(10, (*tensor_size)[0].second->GetValueAsInteger()); + ASSERT_EQ(40, (*tensor_size)[3].second->GetValueAsInteger()); tensor_size->resize_(-10, nullptr); ASSERT_EQ(10, tensor_size->size()); - ASSERT_EQ(0, (*tensor_size)[0]->GetValueAsInteger()); - ASSERT_EQ(0, (*tensor_size)[5]->GetValueAsInteger()); - ASSERT_EQ(10, (*tensor_size)[6]->GetValueAsInteger()); - ASSERT_EQ(40, (*tensor_size)[9]->GetValueAsInteger()); + ASSERT_EQ(0, (*tensor_size)[0].second->GetValueAsInteger()); + ASSERT_EQ(0, (*tensor_size)[5].second->GetValueAsInteger()); + ASSERT_EQ(10, (*tensor_size)[6].second->GetValueAsInteger()); + ASSERT_EQ(40, (*tensor_size)[9].second->GetValueAsInteger()); } @@ -461,7 +461,7 @@ TEST(Alg, Return) { } catch (Interrupt &except) { ASSERT_EQ(ObjType::Return, except.m_obj->getType()); ASSERT_EQ(1, except.m_obj->size()); - ASSERT_TRUE((*except.m_obj)[0]->is_none_type()); + ASSERT_TRUE((*except.m_obj)[0].second->is_none_type()); } ASSERT_FALSE(result); @@ -470,7 +470,7 @@ TEST(Alg, Return) { } catch (Interrupt &except) { ASSERT_EQ(ObjType::Return, except.m_obj->getType()); ASSERT_EQ(1, except.m_obj->size()); - ASSERT_STREQ("100", (*except.m_obj)[0]->toString().c_str()); + ASSERT_STREQ("100", (*except.m_obj)[0].second->toString().c_str()); } ASSERT_FALSE(result); @@ -479,7 +479,7 @@ TEST(Alg, Return) { } catch (Interrupt &except) { ASSERT_EQ(ObjType::Return, except.m_obj->getType()); ASSERT_EQ(1, except.m_obj->size()); - ASSERT_STREQ("'Тест'", (*except.m_obj)[0]->toString().c_str()); + ASSERT_STREQ("'Тест'", (*except.m_obj)[0].second->toString().c_str()); } ASSERT_FALSE(result); @@ -508,7 +508,7 @@ TEST(Alg, Return) { ASSERT_EQ(ObjType::Error, except.m_obj->getType()); ASSERT_EQ(1, except.m_obj->size()); ASSERT_STREQ(":Error('ТЕКСТ')", except.m_obj->toString().c_str()); - ASSERT_STREQ("'ТЕКСТ'", (*except.m_obj)[0]->toString().c_str()); + ASSERT_STREQ("'ТЕКСТ'", (*except.m_obj)[0].second->toString().c_str()); } ASSERT_FALSE(result); @@ -555,13 +555,13 @@ TEST(Alg, Return) { ASSERT_NO_THROW(result = ctx.ExecStr("(){ (){{count := 1; count += 1; count += 1; --:Error(99)--; count += 1; count += 1}}; }", nullptr, false);); ASSERT_TRUE(result); ASSERT_EQ(1, result->size()); - ASSERT_EQ(99, (*result)[0]->GetValueAsInteger()); + ASSERT_EQ(99, (*result)[0].second->GetValueAsInteger()); result.reset(); ASSERT_NO_THROW(result = ctx.ExecStr("(){ (){{count := 1; count += 1; count += 1; --:Error(33)--; count += 1; count += 1}}; }", nullptr, false);); ASSERT_TRUE(result); ASSERT_EQ(1, result->size()); - ASSERT_EQ(33, (*result)[0]->GetValueAsInteger()); + ASSERT_EQ(33, (*result)[0].second->GetValueAsInteger()); result.reset(); ASSERT_NO_THROW(result = ctx.ExecStr("(){ (){{count := 1; count += 1; count += 1; --:Error(44)--; count += 1; count += 1}}; 9999; }", nullptr, false);); @@ -595,7 +595,7 @@ TEST(Alg, Return) { ASSERT_NO_THROW(result = ctx.ExecStr("(){ (){{count := 1; count += 1; count += 1; --:ErrorRunTime(77)--; count += 1; count += 1}}:ErrorRunTime }", nullptr, false);); ASSERT_TRUE(result); ASSERT_EQ(1, result->size()); - ASSERT_EQ(77, (*result)[0]->GetValueAsInteger()); + ASSERT_EQ(77, (*result)[0].second->GetValueAsInteger()); result.reset(); ASSERT_NO_THROW(result = ctx.ExecStr("(){ (){{count := 1; count += 1; count += 1; --:ErrorRunTime(88)--; count += 1; count += 1}}:ErrorRunTime; 9999; }", nullptr, false);); @@ -606,7 +606,7 @@ TEST(Alg, Return) { ASSERT_NO_THROW(result = ctx.ExecStr("(){ (){{count := 1; count += 1; count += 1; --:ErrorRunTime(77)--; count += 1; count += 1}}:Error }", nullptr, false);); ASSERT_TRUE(result); ASSERT_EQ(1, result->size()); - ASSERT_EQ(77, (*result)[0]->GetValueAsInteger()); + ASSERT_EQ(77, (*result)[0].second->GetValueAsInteger()); result.reset(); ASSERT_NO_THROW(result = ctx.ExecStr("(){ (){{count := 1; count += 1; count += 1; --:ErrorRunTime(88)--; count += 1; count += 1}}:Error; 9999; }", nullptr, false);); diff --git a/src/test/compiler_test.cpp b/src/test/compiler_test.cpp index 3abc8041..51179558 100644 --- a/src/test/compiler_test.cpp +++ b/src/test/compiler_test.cpp @@ -27,7 +27,7 @@ TEST(Compiler, EvalExample) { ASSERT_EQ(TermID::CALL, op->GetTokenID()); ASSERT_STREQ("newlang", op->getText().c_str()); ASSERT_EQ(1, op->size()); - ASSERT_STREQ("cpp", (*op)[0]->getText().c_str()); + ASSERT_STREQ("cpp", (*op)[0].second->getText().c_str()); op = p->BlockCode()[1]; ASSERT_EQ(TermID::SOURCE, op->GetTokenID()); diff --git a/src/test/eval_test.cpp b/src/test/eval_test.cpp index 998e4a6f..d3a46767 100644 --- a/src/test/eval_test.cpp +++ b/src/test/eval_test.cpp @@ -35,7 +35,7 @@ TEST(Eval, Assign) { ASSERT_EQ(var1->m_var_type_current, ObjType::Char); ASSERT_EQ(var1->m_var_type_fixed, ObjType::None); ASSERT_STREQ("var1=123", var1->toString().c_str()); - ASSERT_FALSE(ctx.select("var1").complete()); + ASSERT_FALSE(ctx.find("var1") == ctx.end()); list = ctx.ExecStr("$"); ASSERT_STREQ("$=('var1',)", list->toString().c_str()); @@ -49,12 +49,12 @@ TEST(Eval, Assign) { ASSERT_TRUE(ctx.ExecStr("var1 = 999")); ASSERT_STREQ("var1=999", var1->toString().c_str()); - ASSERT_FALSE(ctx.select("var1").complete()); + ASSERT_FALSE(ctx.find("var1") == ctx.end()); ASSERT_TRUE(ctx.ExecStr("var1 = _")); ASSERT_EQ(var1->getType(), ObjType::None); ASSERT_STREQ("var1=_", var1->toString().c_str()); - ASSERT_FALSE(ctx.select("var1").complete()); + ASSERT_FALSE(ctx.find("var1") == ctx.end()); list = ctx.ExecStr("$"); ASSERT_STREQ("$=('var1',)", list->toString().c_str()); @@ -72,7 +72,7 @@ TEST(Eval, Assign) { ASSERT_EQ(var_str->m_var_type_current, ObjType::StrChar); // ASSERT_EQ(var_str->m_var_type_fixed, ObjType::String); ASSERT_STREQ("var_str='Строка'", var_str->toString().c_str()); - ASSERT_FALSE(ctx.select("var_str").complete()); + ASSERT_FALSE(ctx.find("var_str") == ctx.end()); list = ctx.ExecStr("$"); ASSERT_STREQ("$=('var_str',)", list->toString().c_str()); @@ -388,8 +388,8 @@ TEST(Eval, TypesNative) { ASSERT_TRUE(fopen2->m_func_ptr); ASSERT_EQ(fopen->m_func_ptr, fopen2->m_func_ptr); ASSERT_TRUE(ctx.FindTerm("fopen2")); - auto iter = ctx.m_global_terms.select("fopen2"); - ASSERT_TRUE(!iter.complete()); + auto iter = ctx.m_global_terms.find("fopen2"); + ASSERT_NE(iter, ctx.m_global_terms.end()); ObjPtr fopen3 = ctx.ExecStr("@fopen3(filename:String, modes:String):File ::= " ":Pointer('fopen(filename:StrChar, modes:StrChar):File')"); @@ -464,48 +464,48 @@ TEST(Eval, TypesNative) { ASSERT_TRUE(SEEK1); ASSERT_EQ(3, SEEK1->size()); - ASSERT_TRUE((*SEEK1)[0]); - ASSERT_EQ(ObjType::Char, (*SEEK1)[0]->getType()) << newlang::toString((*SEEK1)[0]->getType()); - ASSERT_EQ(ObjType::Char, (*SEEK1)[0]->m_var_type_fixed) << newlang::toString((*SEEK1)[0]->m_var_type_fixed); - ASSERT_EQ(10, (*SEEK1)[0]->GetValueAsInteger()); + ASSERT_TRUE((*SEEK1)[0].second); + ASSERT_EQ(ObjType::Char, (*SEEK1)[0].second->getType()) << newlang::toString((*SEEK1)[0].second->getType()); + ASSERT_EQ(ObjType::Char, (*SEEK1)[0].second->m_var_type_fixed) << newlang::toString((*SEEK1)[0].second->m_var_type_fixed); + ASSERT_EQ(10, (*SEEK1)[0].second->GetValueAsInteger()); - ASSERT_TRUE((*SEEK1)[1]); - ASSERT_EQ(ObjType::Char, (*SEEK1)[1]->getType()) << newlang::toString((*SEEK1)[1]->getType()); - ASSERT_EQ(ObjType::Char, (*SEEK1)[1]->m_var_type_fixed) << newlang::toString((*SEEK1)[1]->m_var_type_fixed); - ASSERT_EQ(11, (*SEEK1)[1]->GetValueAsInteger()); + ASSERT_TRUE((*SEEK1)[1].second); + ASSERT_EQ(ObjType::Char, (*SEEK1)[1].second->getType()) << newlang::toString((*SEEK1)[1].second->getType()); + ASSERT_EQ(ObjType::Char, (*SEEK1)[1].second->m_var_type_fixed) << newlang::toString((*SEEK1)[1].second->m_var_type_fixed); + ASSERT_EQ(11, (*SEEK1)[1].second->GetValueAsInteger()); - ASSERT_TRUE((*SEEK1)[2]); - ASSERT_EQ(ObjType::Char, (*SEEK1)[2]->getType()) << newlang::toString((*SEEK1)[2]->getType()); - ASSERT_EQ(ObjType::Char, (*SEEK1)[2]->m_var_type_fixed) << newlang::toString((*SEEK1)[2]->m_var_type_fixed); - ASSERT_EQ(20, (*SEEK1)[2]->GetValueAsInteger()); + ASSERT_TRUE((*SEEK1)[2].second); + ASSERT_EQ(ObjType::Char, (*SEEK1)[2].second->getType()) << newlang::toString((*SEEK1)[2].second->getType()); + ASSERT_EQ(ObjType::Char, (*SEEK1)[2].second->m_var_type_fixed) << newlang::toString((*SEEK1)[2].second->m_var_type_fixed); + ASSERT_EQ(20, (*SEEK1)[2].second->GetValueAsInteger()); - ASSERT_EQ(10, (*SEEK1)["SET"]->GetValueAsInteger()); - ASSERT_EQ(11, (*SEEK1)["CUR"]->GetValueAsInteger()); - ASSERT_EQ(20, (*SEEK1)["END"]->GetValueAsInteger()); + ASSERT_EQ(10, (*SEEK1)["SET"].second->GetValueAsInteger()); + ASSERT_EQ(11, (*SEEK1)["CUR"].second->GetValueAsInteger()); + ASSERT_EQ(20, (*SEEK1)["END"].second->GetValueAsInteger()); ObjPtr SEEK2 = ctx.ExecStr("@SEEK2 ::= :Enum(SET=, CUR=, END=300)"); ASSERT_TRUE(SEEK2); ASSERT_EQ(3, SEEK2->size()); - ASSERT_EQ(0, (*SEEK2)[0]->GetValueAsInteger()); - ASSERT_EQ(ObjType::Bool, (*SEEK2)[0]->getType()); - ASSERT_EQ(1, (*SEEK2)[1]->GetValueAsInteger()); - ASSERT_EQ(ObjType::Bool, (*SEEK2)[1]->getType()); - ASSERT_EQ(300, (*SEEK2)[2]->GetValueAsInteger()); - ASSERT_EQ(ObjType::Short, (*SEEK2)[2]->getType()); - ASSERT_EQ(0, (*SEEK2)["SET"]->GetValueAsInteger()); - ASSERT_EQ(1, (*SEEK2)["CUR"]->GetValueAsInteger()); - ASSERT_EQ(300, (*SEEK2)["END"]->GetValueAsInteger()); + ASSERT_EQ(0, (*SEEK2)[0].second->GetValueAsInteger()); + ASSERT_EQ(ObjType::Bool, (*SEEK2)[0].second->getType()); + ASSERT_EQ(1, (*SEEK2)[1].second->GetValueAsInteger()); + ASSERT_EQ(ObjType::Bool, (*SEEK2)[1].second->getType()); + ASSERT_EQ(300, (*SEEK2)[2].second->GetValueAsInteger()); + ASSERT_EQ(ObjType::Short, (*SEEK2)[2].second->getType()); + ASSERT_EQ(0, (*SEEK2)["SET"].second->GetValueAsInteger()); + ASSERT_EQ(1, (*SEEK2)["CUR"].second->GetValueAsInteger()); + ASSERT_EQ(300, (*SEEK2)["END"].second->GetValueAsInteger()); ObjPtr SEEK = ctx.ExecStr("@SEEK ::= :Enum(SET=0, CUR=1, END=2)"); ASSERT_TRUE(SEEK); ASSERT_EQ(3, SEEK->size()); - ASSERT_EQ(0, (*SEEK)[0]->GetValueAsInteger()); - ASSERT_EQ(1, (*SEEK)[1]->GetValueAsInteger()); - ASSERT_EQ(2, (*SEEK)[2]->GetValueAsInteger()); - ASSERT_EQ(0, (*SEEK)["SET"]->GetValueAsInteger()); - ASSERT_EQ(1, (*SEEK)["CUR"]->GetValueAsInteger()); - ASSERT_EQ(2, (*SEEK)["END"]->GetValueAsInteger()); + ASSERT_EQ(0, (*SEEK)[0].second->GetValueAsInteger()); + ASSERT_EQ(1, (*SEEK)[1].second->GetValueAsInteger()); + ASSERT_EQ(2, (*SEEK)[2].second->GetValueAsInteger()); + ASSERT_EQ(0, (*SEEK)["SET"].second->GetValueAsInteger()); + ASSERT_EQ(1, (*SEEK)["CUR"].second->GetValueAsInteger()); + ASSERT_EQ(2, (*SEEK)["END"].second->GetValueAsInteger()); F_res = ctx.ExecStr("@SEEK.SET"); ASSERT_TRUE(F_res); @@ -575,6 +575,8 @@ TEST(ExecStr, Funcs) { ASSERT_TRUE(p); ASSERT_STREQ("printf=printf(format:Format, ...):Int{}", p->toString().c_str()); +#ifndef _MSC_VER +#pragma message WARNING("Fail native call from Windows!!!!") typedef int (* printf_type)(const char *, ...); @@ -604,6 +606,7 @@ TEST(ExecStr, Funcs) { ObjPtr result = ctx.ExecStr("hello('Привет, мир!\\n');"); ASSERT_TRUE(result); ASSERT_STREQ("Привет, мир!\n", result->GetValueAsString().c_str()); +#endif } /* @@ -661,7 +664,7 @@ TEST(Eval, Convert) { ASSERT_TRUE(type_dim->m_dimensions); ASSERT_EQ(1, type_dim->m_dimensions->size()); - ASSERT_EQ(0, (*type_dim->m_dimensions)[0]->GetValueAsInteger()); + ASSERT_EQ(0, (*type_dim->m_dimensions)[0].second->GetValueAsInteger()); ObjPtr type_ell = ctx.ExecStr(":Int[10, ...]"); ASSERT_TRUE(type_ell); @@ -670,8 +673,8 @@ TEST(Eval, Convert) { ASSERT_TRUE(type_ell->m_dimensions); ASSERT_EQ(2, type_ell->m_dimensions->size()); - ASSERT_EQ(10, (*type_ell->m_dimensions)[0]->GetValueAsInteger()); - ASSERT_EQ(ObjType::Ellipsis, (*type_ell->m_dimensions)[1]->getType()); + ASSERT_EQ(10, (*type_ell->m_dimensions)[0].second->GetValueAsInteger()); + ASSERT_EQ(ObjType::Ellipsis, (*type_ell->m_dimensions)[1].second->getType()); diff --git a/src/test/object_test.cpp b/src/test/object_test.cpp index 4d90c694..cb5e6f58 100644 --- a/src/test/object_test.cpp +++ b/src/test/object_test.cpp @@ -79,10 +79,10 @@ TEST(ObjTest, String) { ASSERT_STREQ("byte", str_byte->GetValueAsString().c_str()); ASSERT_EQ(4, str_byte->size()); ASSERT_EQ(4, str_byte->m_str.size()); - ASSERT_STREQ("b", (*str_byte)[0]->GetValueAsString().c_str()); - ASSERT_STREQ("y", (*str_byte)[1]->GetValueAsString().c_str()); - ASSERT_STREQ("t", (*str_byte)[2]->GetValueAsString().c_str()); - ASSERT_STREQ("e", (*str_byte)[3]->GetValueAsString().c_str()); + ASSERT_STREQ("b", (*str_byte)[0].second->GetValueAsString().c_str()); + ASSERT_STREQ("y", (*str_byte)[1].second->GetValueAsString().c_str()); + ASSERT_STREQ("t", (*str_byte)[2].second->GetValueAsString().c_str()); + ASSERT_STREQ("e", (*str_byte)[3].second->GetValueAsString().c_str()); str_byte->op_set_index(0, "B"); str_byte->op_set_index(1, "Y"); @@ -95,12 +95,12 @@ TEST(ObjTest, String) { ASSERT_EQ(6, str_char->size()); ASSERT_EQ(6, str_char->m_wstr.size()); - ASSERT_STREQ("с", (*str_char)[0]->GetValueAsString().c_str()); - ASSERT_STREQ("т", (*str_char)[1]->GetValueAsString().c_str()); - ASSERT_STREQ("р", (*str_char)[2]->GetValueAsString().c_str()); - ASSERT_STREQ("о", (*str_char)[3]->GetValueAsString().c_str()); - ASSERT_STREQ("к", (*str_char)[4]->GetValueAsString().c_str()); - ASSERT_STREQ("а", (*str_char)[5]->GetValueAsString().c_str()); + ASSERT_STREQ("с", (*str_char)[0].second->GetValueAsString().c_str()); + ASSERT_STREQ("т", (*str_char)[1].second->GetValueAsString().c_str()); + ASSERT_STREQ("р", (*str_char)[2].second->GetValueAsString().c_str()); + ASSERT_STREQ("о", (*str_char)[3].second->GetValueAsString().c_str()); + ASSERT_STREQ("к", (*str_char)[4].second->GetValueAsString().c_str()); + ASSERT_STREQ("а", (*str_char)[5].second->GetValueAsString().c_str()); str_char->op_set_index(0, "С"); str_char->op_set_index(1, "Т"); @@ -196,28 +196,28 @@ TEST(ObjTest, Dict) { ASSERT_EQ(1, var.size()); var.push_back(Obj::CreateString("Test3")); ASSERT_EQ(2, var.size()); - var.insert(1, Obj::CreateValue(2, ObjType::None), "2"); - var.insert(0, Obj::CreateValue(0, ObjType::None), "0"); + var.insert(var.at_index_const(1), Obj::Arg(2, "2")); + var.insert(var.at_index_const(0), Obj::Arg(0, "0")); ASSERT_EQ(4, var.size()); - ASSERT_TRUE(var[0]->op_accurate(Obj::CreateValue(0, ObjType::None))); - ASSERT_TRUE(var[1]->op_accurate(Obj::CreateString("Test1"))); - ASSERT_TRUE(var[2]->op_accurate(Obj::CreateValue(2, ObjType::None))); - ASSERT_TRUE(var[3]->op_accurate(Obj::CreateString(L"Test3"))); + ASSERT_TRUE(var[0].second->op_accurate(Obj::CreateValue(0, ObjType::None))); + ASSERT_TRUE(var[1].second->op_accurate(Obj::CreateString("Test1"))); + ASSERT_TRUE(var[2].second->op_accurate(Obj::CreateValue(2, ObjType::None))); + ASSERT_TRUE(var[3].second->op_accurate(Obj::CreateString(L"Test3"))); var2 = ctx.ExecStr("(0, \"Test1\", 2, 'Test3',)"); - ASSERT_TRUE((*var2)[0]->op_accurate(Obj::CreateValue(0, ObjType::None))); - ASSERT_TRUE((*var2)[1]->op_accurate(Obj::CreateString("Test1"))); - ASSERT_TRUE((*var2)[2]->op_accurate(Obj::CreateValue(2, ObjType::None))); - ASSERT_TRUE((*var2)[3]->op_accurate(Obj::CreateString(L"Test3"))); + ASSERT_TRUE((*var2)[0].second->op_accurate(Obj::CreateValue(0, ObjType::None))); + ASSERT_TRUE((*var2)[1].second->op_accurate(Obj::CreateString("Test1"))); + ASSERT_TRUE((*var2)[2].second->op_accurate(Obj::CreateValue(2, ObjType::None))); + ASSERT_TRUE((*var2)[3].second->op_accurate(Obj::CreateString(L"Test3"))); ObjPtr var3 = ctx.ExecStr("(0, \"Test1\", 2, 'Test3',)"); - ASSERT_TRUE((*var3)[0]->op_accurate(Obj::CreateValue(0, ObjType::None))); - ASSERT_TRUE((*var3)[1]->op_accurate(Obj::CreateString("Test1"))); - ASSERT_TRUE((*var3)[2]->op_accurate(Obj::CreateValue(2, ObjType::None))); - ASSERT_TRUE((*var3)[3]->op_accurate(Obj::CreateString(L"Test3"))); + ASSERT_TRUE((*var3)[0].second->op_accurate(Obj::CreateValue(0, ObjType::None))); + ASSERT_TRUE((*var3)[1].second->op_accurate(Obj::CreateString("Test1"))); + ASSERT_TRUE((*var3)[2].second->op_accurate(Obj::CreateValue(2, ObjType::None))); + ASSERT_TRUE((*var3)[3].second->op_accurate(Obj::CreateString(L"Test3"))); } TEST(ObjTest, AsMap) { @@ -231,13 +231,13 @@ TEST(ObjTest, AsMap) { map->push_back(temp, "test1"); map->push_back(Obj::CreateValue(100, ObjType::None), "test2"); ASSERT_EQ(2, map->size()); - ASSERT_STREQ((*map)["test1"]->toString().c_str(), temp->toString().c_str()) << temp->toString().c_str(); + ASSERT_STREQ((*map)["test1"].second->toString().c_str(), temp->toString().c_str()) << temp->toString().c_str(); - ASSERT_TRUE((*map)["test2"]); + ASSERT_TRUE((*map)["test2"].second); ObjPtr temp100 = Obj::CreateValue(100, ObjType::None); ASSERT_TRUE(map->exist(temp100, true)); - ObjPtr test2 = (*map)["test2"]; + ObjPtr test2 = (*map)["test2"].second; ASSERT_TRUE(test2); ASSERT_TRUE(test2); ASSERT_STREQ("100", test2->toString().c_str()); @@ -327,9 +327,9 @@ TEST(ObjTest, Exist) { var_map.push_back(Obj::CreateString("MAP_VALUE1"), "map1"); var_map.push_back(Obj::CreateString("MAP_VALUE2"), "map2"); - ASSERT_TRUE(var_map[std::string("map1")]); - ASSERT_TRUE(var_map["map2"]); - ASSERT_EQ(var_map.select("map"), var_map.end()); + ASSERT_TRUE(var_map[std::string("map1")].second); + ASSERT_TRUE(var_map["map2"].second); + ASSERT_EQ(var_map.find("map"), var_map.end()); } @@ -438,17 +438,6 @@ TEST(ObjTest, Print) { var_array->push_back((*var_bool.get())(nullptr)); ASSERT_STREQ("array=('item1', 100, 1,)", var_array->toString().c_str()) << var_array; - - ObjPtr obj_empty = Obj::CreateType(ObjType::Class, "name"); - ASSERT_STREQ("name=()", obj_empty->toString().c_str()) << obj_empty; - - // ObjPtr var_obj = Obj::CreateFrom("obj", obj_empty); - // ASSERT_STREQ("obj=name()", var_obj->toString().c_str()) << var_obj; - // - // var_int->m_var_name = "int"; - // var_obj->push_back((*var_int.get())(nullptr)); - // ASSERT_STREQ("obj=name(int=100)", var_obj->toString().c_str()) << var_obj; - } TEST(ObjTest, CreateFromInteger) { @@ -558,7 +547,7 @@ TEST(ObjTest, CreateFromFraction) { ASSERT_TRUE(var); ASSERT_EQ(ObjType::Fraction, var->getType()) << toString(var->getType()); ASSERT_EQ(123, var->GetValueAsInteger()); - ASSERT_DOUBLE_EQ(123, var->GetValueAsInteger()); + ASSERT_DOUBLE_EQ(123.0, var->GetValueAsNumber()); ObjPtr var2 = ctx.ExecStr("123\\1"); ASSERT_TRUE(var2); @@ -570,7 +559,7 @@ TEST(ObjTest, CreateFromFraction) { ASSERT_TRUE(var); ASSERT_EQ(ObjType::Fraction, var->getType()) << toString(var->getType()); ASSERT_EQ(-123, var->GetValueAsInteger()); - ASSERT_DOUBLE_EQ(-123, var->GetValueAsInteger()); + ASSERT_DOUBLE_EQ(-123.0, var->GetValueAsNumber()); var2 = ctx.ExecStr("-123\\1"); ASSERT_TRUE(var2); @@ -588,7 +577,6 @@ TEST(ObjTest, CreateFromFraction) { ASSERT_ANY_THROW(Context::CreateRVal(&ctx, Term::Create(TermID::FRACTION, "123wwwww\\111"))); } - TEST(Args, All) { Context ctx(RunTime::Init()); TermPtr ast; @@ -602,13 +590,13 @@ TEST(Args, All) { ObjPtr arg_999 = Obj::CreateDict(Obj::Arg(Obj::CreateValue(999, ObjType::None))); - EXPECT_EQ(ObjType::Short, (*arg_999)[0]->getType()) << torch::toString(toTorchType((*arg_999)[0]->getType())); + EXPECT_EQ(ObjType::Short, (*arg_999)[0].second->getType()) << torch::toString(toTorchType((*arg_999)[0].second->getType())); ObjPtr arg_empty_named = Obj::CreateDict(Obj::Arg()); - ASSERT_EQ(ObjType::None, (*arg_empty_named)[0]->getType()); + ASSERT_EQ(ObjType::None, (*arg_empty_named)[0].second->getType()); ObjPtr arg_123_named = Obj::CreateDict(Obj::Arg(123, "named")); - EXPECT_EQ(ObjType::Char, (*arg_123_named)[0]->getType()) << torch::toString(toTorchType((*arg_123_named)[0]->getType())); + EXPECT_EQ(ObjType::Char, (*arg_123_named)[0].second->getType()) << torch::toString(toTorchType((*arg_123_named)[0].second->getType())); ObjPtr arg_999_123_named = Obj::CreateDict(); ASSERT_EQ(0, arg_999_123_named->size()); @@ -630,13 +618,13 @@ TEST(Args, All) { ASSERT_EQ(nullptr, proto2.at(0).second); ObjPtr o_arg_999 = proto2.ConvertToArgs(arg_999.get(), true, nullptr); - ASSERT_TRUE((*o_arg_999)[0]); - ASSERT_STREQ("999", (*o_arg_999)[0]->toString().c_str()); + ASSERT_TRUE((*o_arg_999)[0].second); + ASSERT_STREQ("999", (*o_arg_999)[0].second->toString().c_str()); // proto2[0].reset(); // Иначе типы гурментов буду отличаться ObjPtr o_arg_empty_named = proto2.ConvertToArgs(arg_empty_named.get(), false, nullptr); - ASSERT_TRUE((*o_arg_empty_named)[0]); - ASSERT_STREQ("_", (*o_arg_empty_named)[0]->toString().c_str()); + ASSERT_TRUE((*o_arg_empty_named)[0].second); + ASSERT_STREQ("_", (*o_arg_empty_named)[0].second->toString().c_str()); ASSERT_ANY_THROW(proto2.ConvertToArgs(arg_123_named.get(), true, nullptr)); // Имя аругмента отличается @@ -654,23 +642,23 @@ TEST(Args, All) { ObjPtr proto3_arg = proto3.ConvertToArgs(arg_999.get(), true, nullptr); ASSERT_EQ(1, proto3_arg->size()); - ASSERT_TRUE((*proto3_arg)[0]); - ASSERT_STREQ("999", (*proto3_arg)[0]->toString().c_str()); + ASSERT_TRUE((*proto3_arg)[0].second); + ASSERT_STREQ("999", (*proto3_arg)[0].second->toString().c_str()); ASSERT_STREQ("empty", proto3_arg->name(0).c_str()); // Дополнительный аргумент ObjPtr arg_extra = Obj::CreateDict(Obj::Arg(Obj::CreateValue(999, ObjType::None)), Obj::Arg(123, "named")); ASSERT_EQ(2, arg_extra->size()); - EXPECT_EQ(ObjType::Short, (*arg_extra)[0]->getType()) << torch::toString(toTorchType((*arg_extra)[0]->getType())); - EXPECT_EQ(ObjType::Char, (*arg_extra)[1]->getType()) << torch::toString(toTorchType((*arg_extra)[1]->getType())); + EXPECT_EQ(ObjType::Short, (*arg_extra)[0].second->getType()) << torch::toString(toTorchType((*arg_extra)[0].second->getType())); + EXPECT_EQ(ObjType::Char, (*arg_extra)[1].second->getType()) << torch::toString(toTorchType((*arg_extra)[1].second->getType())); ObjPtr proto3_extra = proto3.ConvertToArgs(arg_extra.get(), true, nullptr); ASSERT_EQ(2, proto3_extra->size()); - ASSERT_STREQ("999", (*proto3_extra)[0]->toString().c_str()); + ASSERT_STREQ("999", (*proto3_extra)[0].second->toString().c_str()); ASSERT_STREQ("empty", proto3_extra->name(0).c_str()); - ASSERT_STREQ("123", (*proto3_extra)[1]->toString().c_str()); + ASSERT_STREQ("123", (*proto3_extra)[1].second->toString().c_str()); ASSERT_STREQ("named", proto3_extra->name(1).c_str()); @@ -680,8 +668,8 @@ TEST(Args, All) { ASSERT_EQ(1, proto123.size()); // ASSERT_FALSE(proto123.m_is_ellipsis); ASSERT_STREQ("num", proto123.name(0).c_str()); - ASSERT_TRUE(proto123[0]); - ASSERT_STREQ("123", proto123[0]->toString().c_str()); + ASSERT_TRUE(proto123[0].second); + ASSERT_STREQ("123", proto123[0].second->toString().c_str()); // Изменен порядок @@ -690,17 +678,17 @@ TEST(Args, All) { ASSERT_EQ(2, proto_str.size()); // ASSERT_FALSE(proto_str.m_is_ellipsis); ASSERT_STREQ("arg1", proto_str.at(0).first.c_str()); - ASSERT_EQ(nullptr, proto_str[0]); + ASSERT_EQ(nullptr, proto_str[0].second); ObjPtr arg_str = Obj::CreateDict(Obj::Arg(L"СТРОКА", "str"), Obj::Arg(555, "arg1")); ObjPtr proto_str_arg = proto_str.ConvertToArgs(arg_str.get(), true, nullptr); ASSERT_STREQ("arg1", proto_str_arg->at(0).first.c_str()); ASSERT_TRUE(proto_str_arg->at(0).second); - ASSERT_STREQ("555", (*proto_str_arg)[0]->toString().c_str()); + ASSERT_STREQ("555", (*proto_str_arg)[0].second->toString().c_str()); ASSERT_STREQ("str", proto_str_arg->at(1).first.c_str()); - ASSERT_TRUE((*proto_str_arg)[1]); - ASSERT_STREQ("\"СТРОКА\"", (*proto_str_arg)[1]->toString().c_str()); + ASSERT_TRUE((*proto_str_arg)[1].second); + ASSERT_STREQ("\"СТРОКА\"", (*proto_str_arg)[1].second->toString().c_str()); ASSERT_TRUE(p.Parse("test(arg1, ...) := {}")); @@ -714,10 +702,10 @@ TEST(Args, All) { ASSERT_EQ(2, any->size()); ASSERT_STREQ("arg1", any->at(0).first.c_str()); ASSERT_TRUE(any->at(0).second); - ASSERT_STREQ("555", (*any)[0]->toString().c_str()); + ASSERT_STREQ("555", (*any)[0].second->toString().c_str()); ASSERT_STREQ("str", any->at(1).first.c_str()); ASSERT_TRUE(any->at(1).second); - ASSERT_STREQ("\"СТРОКА\"", (*any)[1]->toString().c_str()); + ASSERT_STREQ("\"СТРОКА\"", (*any)[1].second->toString().c_str()); // ASSERT_TRUE(p.Parse("min(arg, ...) := {}")); @@ -726,15 +714,15 @@ TEST(Args, All) { ObjPtr min_arg = min_proto.ConvertToArgs(min_args.get(), true, nullptr); ASSERT_EQ(3, min_arg->size()); - ASSERT_STREQ("200", (*min_arg)[0]->toString().c_str()); - ASSERT_STREQ("100", (*min_arg)[1]->toString().c_str()); - ASSERT_STREQ("300", (*min_arg)[2]->toString().c_str()); + ASSERT_STREQ("200", (*min_arg)[0].second->toString().c_str()); + ASSERT_STREQ("100", (*min_arg)[1].second->toString().c_str()); + ASSERT_STREQ("300", (*min_arg)[2].second->toString().c_str()); ASSERT_TRUE(p.Parse("min(200, 100, 300)")); Obj args_term(&ctx, ast, true, &local); - ASSERT_STREQ("200", args_term[0]->toString().c_str()); - ASSERT_STREQ("100", args_term[1]->toString().c_str()); - ASSERT_STREQ("300", args_term[2]->toString().c_str()); + ASSERT_STREQ("200", args_term[0].second->toString().c_str()); + ASSERT_STREQ("100", args_term[1].second->toString().c_str()); + ASSERT_STREQ("300", args_term[2].second->toString().c_str()); } TEST(Types, FromLimit) { @@ -830,4 +818,176 @@ TEST(ObjTest, Tensor) { } +TEST(ObjTest, Iterator) { + + ObjPtr dict = Obj::CreateDict(); + + dict->push_back(Obj::Arg(1, "1")); + dict->push_back(Obj::Arg(2, "22")); + dict->push_back(Obj::Arg(3, "333")); + dict->push_back(Obj::Arg(4)); + dict->push_back(Obj::Arg(5, "555")); + + ASSERT_EQ(5, dict->size()); + + auto all = std::regex("(.|\\n)*"); + ASSERT_TRUE(std::regex_match("1", all)); + ASSERT_TRUE(std::regex_match("22", all)); + ASSERT_TRUE(std::regex_match("333", all)); + ASSERT_TRUE(std::regex_match("", all)); + ASSERT_TRUE(std::regex_match("\n", all)); + ASSERT_TRUE(std::regex_match("\n\n\\n", all)); + + + Iterator iter(*dict); + + ASSERT_TRUE(iter == iter.begin()); + ASSERT_TRUE(iter != iter.end()); + + ObjPtr copy = Obj::CreateDict(); + for (auto &elem : iter) { + copy->push_back(elem.second, elem.first); + } + + ASSERT_TRUE(iter == iter.begin()); + ASSERT_TRUE(iter != iter.end()); + + ASSERT_EQ(dict->size(), copy->size()); + + /* + * Создание итератора + * ?, ?(), ?("Фильтр"), ?(func), ?(func, args...) + * + * Перебор элементов итератора + * !, !(), !(0), !(3), !(-3) + * + * dict! и dict!(0) эквивалентны + * dict! -> 1, dict! -> 2, dict! -> 3, dict! -> 4, dict! -> 5, dict! -> :IteratorEnd + * Различия отрицательного размера возвращаемого словаря + * dict!(1) -> (1,), dict!(1) -> (2,), dict!(1) -> (3,), dict!(1) -> (4,), dict!(1) -> (5,), dict!(1) -> (:IteratorEnd,), + * dict!(-1) -> (1,), dict!(-1) -> (2,), dict!(-1) -> (3,), dict!(-1) -> (4,), dict!(-1) -> (5,), dict!(-1) -> (,), + * dict!(3) -> (1, 2, 3,), dict!(3) -> (4, 5, :IteratorEnd,) + * dict!(-3) -> (1, 2, 3,), dict!(-3) -> (4, 5,) + * + */ + + ASSERT_TRUE(iter == iter.begin()); + + ObjPtr one = iter.read_and_next(0); + ASSERT_TRUE(one); + ASSERT_EQ(1, dict->at(0).second->GetValueAsInteger()); + + ASSERT_EQ(2, (*iter).second->GetValueAsInteger()); + one = iter.read_and_next(0); + ASSERT_TRUE(one); + ASSERT_EQ(2, dict->at(1).second->GetValueAsInteger()); + + ASSERT_EQ(3, (*iter).second->GetValueAsInteger()); + one = iter.read_and_next(0); + ASSERT_TRUE(one); + ASSERT_EQ(3, dict->at(2).second->GetValueAsInteger()); + + ASSERT_EQ(4, (*iter).second->GetValueAsInteger()); + one = iter.read_and_next(0); + ASSERT_TRUE(one); + ASSERT_EQ(4, dict->at(3).second->GetValueAsInteger()); + + ASSERT_EQ(5, (*iter).second->GetValueAsInteger()); + one = iter.read_and_next(0); + ASSERT_TRUE(one); + ASSERT_EQ(5, dict->at(4).second->GetValueAsInteger()); + + one = iter.read_and_next(0); + ASSERT_TRUE(one); + ASSERT_EQ(ObjType::IteratorEnd, one->getType()) << one << " " << toString(one->getType()); + + one = iter.read_and_next(0); + ASSERT_TRUE(one); + ASSERT_EQ(ObjType::IteratorEnd, one->getType()) << one << " " << toString(one->getType()); + + + + + ASSERT_TRUE(iter == iter.end()); + iter.reset(); + ASSERT_TRUE(iter == iter.begin()); + ASSERT_TRUE(iter != iter.end()); + + ObjPtr dict1 = iter.read_and_next(3); + ASSERT_TRUE(dict1); + ASSERT_EQ(3, dict1->size()); + ASSERT_EQ(1, dict1->at(0).second->GetValueAsInteger()); + ASSERT_EQ(2, dict1->at(1).second->GetValueAsInteger()); + ASSERT_EQ(3, dict1->at(2).second->GetValueAsInteger()); + + ObjPtr dict2 = iter.read_and_next(3); + ASSERT_TRUE(dict2); + ASSERT_EQ(3, dict2->size()); + ASSERT_EQ(4, dict2->at(0).second->GetValueAsInteger()); + ASSERT_EQ(5, dict2->at(1).second->GetValueAsInteger()); + ASSERT_EQ(ObjType::IteratorEnd, dict2->at(2).second->getType()); + + ObjPtr dict3 = iter.read_and_next(3); + ASSERT_TRUE(dict3); + ASSERT_EQ(3, dict1->size()); + ASSERT_EQ(ObjType::IteratorEnd, dict3->at(0).second->getType()); + ASSERT_EQ(ObjType::IteratorEnd, dict3->at(1).second->getType()); + ASSERT_EQ(ObjType::IteratorEnd, dict3->at(2).second->getType()); + + + + ASSERT_TRUE(iter == iter.end()); + iter.reset(); + ASSERT_TRUE(iter == iter.begin()); + ASSERT_TRUE(iter != iter.end()); + + dict1 = iter.read_and_next(-3); + ASSERT_TRUE(dict1); + ASSERT_EQ(3, dict1->size()); + ASSERT_EQ(1, dict1->at(0).second->GetValueAsInteger()); + ASSERT_EQ(2, dict1->at(1).second->GetValueAsInteger()); + ASSERT_EQ(3, dict1->at(2).second->GetValueAsInteger()); + + dict2 = iter.read_and_next(-3); + ASSERT_TRUE(dict2); + ASSERT_EQ(2, dict2->size()); + ASSERT_EQ(4, dict2->at(0).second->GetValueAsInteger()); + ASSERT_EQ(5, dict2->at(1).second->GetValueAsInteger()); + + dict3 = iter.read_and_next(-3); + ASSERT_TRUE(dict3); + ASSERT_EQ(0, dict3->size()); + + + + + Iterator flt(*dict, ""); + ObjPtr flt_res = flt.read_and_next(-100); + ASSERT_TRUE(flt_res); + ASSERT_EQ(1, flt_res->size()); + ASSERT_EQ(4, flt_res->at(0).second->GetValueAsInteger()); + + + Iterator flt1(*dict, "."); + ObjPtr flt1_res = flt1.read_and_next(-100); + ASSERT_TRUE(flt1_res); + ASSERT_EQ(1, flt1_res->size()); + ASSERT_EQ(1, flt1_res->at(0).second->GetValueAsInteger()); + + + Iterator flt2(*dict, ".."); + ObjPtr flt2_res = flt2.read_and_next(-100); + ASSERT_TRUE(flt2_res); + ASSERT_EQ(1, flt2_res->size()); + ASSERT_EQ(2, flt2_res->at(0).second->GetValueAsInteger()); + + Iterator flt3(*dict, "..."); + ObjPtr flt3_res = flt3.read_and_next(-100); + ASSERT_TRUE(flt3_res); + ASSERT_EQ(2, flt3_res->size()); + ASSERT_EQ(3, flt3_res->at(0).second->GetValueAsInteger()); + ASSERT_EQ(5, flt3_res->at(1).second->GetValueAsInteger()); + +} + #endif // UNITTEST \ No newline at end of file diff --git a/src/test/parser_test.cpp b/src/test/parser_test.cpp index 30bec5ac..d956a883 100644 --- a/src/test/parser_test.cpp +++ b/src/test/parser_test.cpp @@ -24,7 +24,7 @@ class ParserTest : public ::testing::Test { int Count(TermID token_id) { int result = 0; for (int c = 0; c < ast->size(); c++) { - if((*ast)[c]->m_id == token_id) { + if((*ast)[c].second->m_id == token_id) { result++; } } @@ -154,7 +154,7 @@ TEST_F(ParserTest, Tensor1) { ASSERT_EQ(TermID::INDEX, ast->Right()->getTermID()) << newlang::toString(ast->getTermID()); ASSERT_EQ(1, ast->Right()->size()); - ASSERT_STREQ("1", (*ast->Right())[0]->getText().c_str()); + ASSERT_STREQ("1", (*ast->Right())[0].second->getText().c_str()); ASSERT_TRUE(Parse("term[1..2];")); ASSERT_EQ(TermID::TERM, ast->getTermID()) << newlang::toString(ast->getTermID()); @@ -175,16 +175,16 @@ TEST_F(ParserTest, Tensor2) { ASSERT_EQ(TermID::INDEX, ast->Right()->getTermID()) << newlang::toString(ast->getTermID()); ASSERT_EQ(2, ast->Right()->size()); - ASSERT_STREQ("1", (*ast->Right())[0]->getText().c_str()); - ASSERT_STREQ("2", (*ast->Right())[1]->getText().c_str()); + ASSERT_STREQ("1", (*ast->Right())[0].second->getText().c_str()); + ASSERT_STREQ("2", (*ast->Right())[1].second->getText().c_str()); ASSERT_TRUE(Parse("term[1, 1..2, 3];")); ASSERT_EQ(TermID::INDEX, ast->Right()->getTermID()) << newlang::toString(ast->getTermID()); ASSERT_EQ(3, ast->Right()->size()); - ASSERT_STREQ("1", (*ast->Right())[0]->getText().c_str()); - ASSERT_STREQ("1..2", (*ast->Right())[1]->toString().c_str()); - ASSERT_STREQ("3", (*ast->Right())[2]->getText().c_str()); + ASSERT_STREQ("1", (*ast->Right())[0].second->getText().c_str()); + ASSERT_STREQ("1..2", (*ast->Right())[1].second->toString().c_str()); + ASSERT_STREQ("3", (*ast->Right())[2].second->getText().c_str()); } TEST_F(ParserTest, Tensor3) { @@ -507,8 +507,8 @@ TEST_F(ParserTest, TermArgTerm) { ASSERT_EQ(TermID::CALL, ast->getTermID()) << newlang::toString(ast->getTermID()); ASSERT_STREQ("term", ast->m_text.c_str()); ASSERT_EQ(1, ast->size()); - ASSERT_STREQ("arg", (*ast)[0]->m_text.c_str()); - ASSERT_FALSE((*ast)[0]->m_is_ref); + ASSERT_STREQ("arg", (*ast)[0].second->m_text.c_str()); + ASSERT_FALSE((*ast)[0].second->m_is_ref); ASSERT_TRUE(Parse("term(name=value);")); @@ -516,9 +516,9 @@ TEST_F(ParserTest, TermArgTerm) { ASSERT_STREQ("term", ast->m_text.c_str()); ASSERT_EQ(1, ast->size()); - ASSERT_STREQ("name", (*ast)[0]->getName().c_str()); - ASSERT_STREQ("value", (*ast)[0]->getText().c_str()); - ASSERT_FALSE((*ast)[0]->m_is_ref); + ASSERT_STREQ("name", (*ast)[0].second->getName().c_str()); + ASSERT_STREQ("value", (*ast)[0].second->getText().c_str()); + ASSERT_FALSE((*ast)[0].second->m_is_ref); } TEST_F(ParserTest, TermArgTermRef) { @@ -526,8 +526,8 @@ TEST_F(ParserTest, TermArgTermRef) { ASSERT_EQ(TermID::CALL, ast->getTermID()) << newlang::toString(ast->getTermID()); ASSERT_STREQ("term", ast->m_text.c_str()); ASSERT_EQ(1, ast->size()); - ASSERT_STREQ("arg", (*ast)[0]->m_text.c_str()); - ASSERT_TRUE((*ast)[0]->m_is_ref); + ASSERT_STREQ("arg", (*ast)[0].second->m_text.c_str()); + ASSERT_TRUE((*ast)[0].second->m_is_ref); ASSERT_TRUE(Parse("term(name=&value);")); @@ -535,9 +535,9 @@ TEST_F(ParserTest, TermArgTermRef) { ASSERT_STREQ("term", ast->m_text.c_str()); ASSERT_EQ(1, ast->size()); - ASSERT_STREQ("name", (*ast)[0]->getName().c_str()); - ASSERT_STREQ("value", (*ast)[0]->getText().c_str()); - ASSERT_TRUE((*ast)[0]->m_is_ref); + ASSERT_STREQ("name", (*ast)[0].second->getName().c_str()); + ASSERT_STREQ("value", (*ast)[0].second->getText().c_str()); + ASSERT_TRUE((*ast)[0].second->m_is_ref); } TEST_F(ParserTest, TermArgTermSpace) { @@ -545,7 +545,7 @@ TEST_F(ParserTest, TermArgTermSpace) { ASSERT_EQ(TermID::CALL, ast->getTermID()) << newlang::toString(ast->getTermID()); ASSERT_STREQ("term", ast->m_text.c_str()); ASSERT_EQ(1, ast->size()); - ASSERT_STREQ("arg", (*ast)[0]->m_text.c_str()); + ASSERT_STREQ("arg", (*ast)[0].second->m_text.c_str()); } TEST_F(ParserTest, TermArgs1) { @@ -553,7 +553,7 @@ TEST_F(ParserTest, TermArgs1) { ASSERT_EQ(TermID::CALL, ast->getTermID()) << newlang::toString(ast->getTermID()); ASSERT_STREQ("term", ast->m_text.c_str()); ASSERT_EQ(1, ast->size()); - ASSERT_STREQ("arg1", (*ast)[0]->m_text.c_str()); + ASSERT_STREQ("arg1", (*ast)[0].second->m_text.c_str()); } TEST_F(ParserTest, TermArgs2) { @@ -561,10 +561,10 @@ TEST_F(ParserTest, TermArgs2) { ASSERT_EQ(TermID::CALL, ast->getTermID()) << newlang::toString(ast->getTermID()); ASSERT_STREQ("term", ast->m_text.c_str()); ASSERT_EQ(2, ast->size()); - ASSERT_STREQ("arg1", (*ast)[0]->getText().c_str()); - ASSERT_STREQ("arg2", (*ast)[1]->getText().c_str()); - ASSERT_FALSE((*ast)[0]->m_is_ref); - ASSERT_FALSE((*ast)[1]->m_is_ref); + ASSERT_STREQ("arg1", (*ast)[0].second->getText().c_str()); + ASSERT_STREQ("arg2", (*ast)[1].second->getText().c_str()); + ASSERT_FALSE((*ast)[0].second->m_is_ref); + ASSERT_FALSE((*ast)[1].second->m_is_ref); } TEST_F(ParserTest, TermArgsRef) { @@ -572,10 +572,10 @@ TEST_F(ParserTest, TermArgsRef) { ASSERT_EQ(TermID::CALL, ast->getTermID()) << newlang::toString(ast->getTermID()); ASSERT_STREQ("term", ast->m_text.c_str()); ASSERT_EQ(2, ast->size()); - ASSERT_STREQ("arg1", (*ast)[0]->getText().c_str()); - ASSERT_STREQ("arg2", (*ast)[1]->getText().c_str()); - ASSERT_TRUE((*ast)[0]->m_is_ref); - ASSERT_TRUE((*ast)[1]->m_is_ref); + ASSERT_STREQ("arg1", (*ast)[0].second->getText().c_str()); + ASSERT_STREQ("arg2", (*ast)[1].second->getText().c_str()); + ASSERT_TRUE((*ast)[0].second->m_is_ref); + ASSERT_TRUE((*ast)[1].second->m_is_ref); } TEST_F(ParserTest, TermArgMixed) { @@ -584,9 +584,9 @@ TEST_F(ParserTest, TermArgMixed) { ASSERT_STREQ("term", ast->m_text.c_str()); ASSERT_EQ(2, ast->size()); - ASSERT_STREQ("arg1", (*ast)[0]->getText().c_str()); - ASSERT_STREQ("arg2", (*ast)[1]->getName().c_str()); - ASSERT_STREQ("arg3", (*ast)[1]->getText().c_str()); + ASSERT_STREQ("arg1", (*ast)[0].second->getText().c_str()); + ASSERT_STREQ("arg2", (*ast)[1].second->getName().c_str()); + ASSERT_STREQ("arg3", (*ast)[1].second->getText().c_str()); } TEST_F(ParserTest, ArgsType) { @@ -604,15 +604,15 @@ TEST_F(ParserTest, TermCall) { TermPtr right = ast->Right(); ASSERT_TRUE(right); ASSERT_EQ(3, right->size()); - ASSERT_STREQ("200", (*right)[0]->getText().c_str()); - ASSERT_FALSE((*right)[0]->m_left); - ASSERT_FALSE((*right)[0]->m_right); - ASSERT_STREQ("var", (*right)[1]->getText().c_str()); - ASSERT_FALSE((*right)[1]->m_left); - ASSERT_FALSE((*right)[1]->m_right); - ASSERT_STREQ("400", (*right)[2]->getText().c_str()); - ASSERT_FALSE((*right)[2]->m_left); - ASSERT_FALSE((*right)[2]->m_right); + ASSERT_STREQ("200", (*right)[0].second->getText().c_str()); + ASSERT_FALSE((*right)[0].second->m_left); + ASSERT_FALSE((*right)[0].second->m_right); + ASSERT_STREQ("var", (*right)[1].second->getText().c_str()); + ASSERT_FALSE((*right)[1].second->m_left); + ASSERT_FALSE((*right)[1].second->m_right); + ASSERT_STREQ("400", (*right)[2].second->getText().c_str()); + ASSERT_FALSE((*right)[2].second->m_left); + ASSERT_FALSE((*right)[2].second->m_right); } TEST_F(ParserTest, TermCollection) { @@ -620,8 +620,8 @@ TEST_F(ParserTest, TermCollection) { ASSERT_EQ(TermID::CALL, ast->getTermID()) << newlang::toString(ast->getTermID()); ASSERT_STREQ("term", ast->m_text.c_str()); ASSERT_EQ(2, ast->size()); - ASSERT_EQ(TermID::TENSOR, (*ast)[0]->getTermID()) << newlang::toString(ast->getTermID()); - ASSERT_EQ(TermID::TENSOR, (*ast)[1]->getTermID()) << newlang::toString(ast->getTermID()); + ASSERT_EQ(TermID::TENSOR, (*ast)[0].second->getTermID()) << newlang::toString(ast->getTermID()); + ASSERT_EQ(TermID::TENSOR, (*ast)[1].second->getTermID()) << newlang::toString(ast->getTermID()); } TEST_F(ParserTest, TermCollection2) { @@ -629,8 +629,8 @@ TEST_F(ParserTest, TermCollection2) { ASSERT_EQ(TermID::CALL, ast->getTermID()) << newlang::toString(ast->getTermID()); ASSERT_STREQ("term", ast->m_text.c_str()); ASSERT_EQ(2, ast->size()); - ASSERT_EQ(TermID::DICT, (*ast)[0]->getTermID()) << newlang::toString((*ast)[0]->getTermID()); - ASSERT_EQ(TermID::TENSOR, (*ast)[1]->getTermID()) << newlang::toString((*ast)[1]->getTermID()); + ASSERT_EQ(TermID::DICT, (*ast)[0].second->getTermID()) << newlang::toString((*ast)[0].second->getTermID()); + ASSERT_EQ(TermID::TENSOR, (*ast)[1].second->getTermID()) << newlang::toString((*ast)[1].second->getTermID()); } TEST_F(ParserTest, ArgMixedFail) { @@ -661,7 +661,7 @@ TEST_F(ParserTest, Iterator) { ASSERT_TRUE(arg); ASSERT_STREQ("term", arg->getText().c_str()); ASSERT_EQ(1, arg->size()); - ASSERT_STREQ("arg", (*arg)[0]->getText().c_str()); + ASSERT_STREQ("arg", (*arg)[0].second->getText().c_str()); // #pragma GCC warning "ITERATOR" // ASSERT_TRUE(Parse("term(arg=value)??(100)")); @@ -705,9 +705,9 @@ TEST_F(ParserTest, Iterator) { ASSERT_STREQ("term2", ast->getText().c_str()); ASSERT_EQ(1, ast->size()); ASSERT_STREQ("arg", ast->name(0).c_str()); - ASSERT_STREQ("?", (*ast)[0]->getText().c_str()); - ASSERT_TRUE((*ast)[0]->Left()); - ASSERT_STREQ("value", (*ast)[0]->Left()->getText().c_str()); + ASSERT_STREQ("?", (*ast)[0].second->getText().c_str()); + ASSERT_TRUE((*ast)[0].second->Left()); + ASSERT_STREQ("value", (*ast)[0].second->Left()->getText().c_str()); // @todo Проблемы с итератором у именованного аргумента !!!!!!!!!!!!!!!!!!!! @@ -927,7 +927,7 @@ TEST_F(ParserTest, ArrayAssign) { ASSERT_EQ(TermID::INDEX, ast->Left()->Right()->getTermID()); ASSERT_STREQ("[", ast->Left()->Right()->m_text.c_str()); ASSERT_EQ(1, ast->Left()->Right()->size()); - ASSERT_STREQ("0", (*ast->Left()->Right())[0]->m_text.c_str()); + ASSERT_STREQ("0", (*ast->Left()->Right())[0].second->m_text.c_str()); } @@ -1047,7 +1047,7 @@ TEST_F(ParserTest, ArgsArray1) { ASSERT_EQ(TermID::CALL, ast->getTermID()) << newlang::toString(ast->getTermID()); ASSERT_STREQ("term", ast->m_text.c_str()); ASSERT_EQ(1, ast->size()); - ASSERT_STREQ("[1,]", (*ast)[0]->toString().c_str()); + ASSERT_STREQ("[1,]", (*ast)[0].second->toString().c_str()); } TEST_F(ParserTest, LogicEq) { @@ -1377,21 +1377,19 @@ TEST_F(ParserTest, Comment5) { ASSERT_EQ(TermID::CREATE_OR_ASSIGN, ast->m_block[3]->getTermID()) << newlang::toString(ast->getTermID()); } -TEST_F(ParserTest, DISABLED_Comment6) { - const char *str = "term();\n" - "print1(str=\"\") ::= term();\n" - "print2(str=\"\") ::= term();\n\n" - "print3(str=\"\") ::= term();\n\n\n" - "# @print(\"Привет, мир!\\n\");\n"; - "# @print(\"Привет, мир!\\n\");\n"; - ASSERT_TRUE(Parse(str)); - ASSERT_EQ(TermID::BLOCK, ast->getTermID()) << newlang::toString(ast->getTermID()); - ASSERT_EQ(4, ast->m_block.size()); - ASSERT_EQ(TermID::CALL, ast->m_block[0]->getTermID()) << newlang::toString(ast->getTermID()); - - ASSERT_EQ(TermID::CREATE, ast->m_block[1]->getTermID()) << newlang::toString(ast->getTermID()); - ASSERT_EQ(TermID::CREATE, ast->m_block[2]->getTermID()) << newlang::toString(ast->getTermID()); - ASSERT_EQ(TermID::CREATE, ast->m_block[3]->getTermID()) << newlang::toString(ast->getTermID()); +TEST_F(ParserTest, Comment6) { + ASSERT_TRUE(Parse("# \\\\macro \\\\\\")); + ASSERT_FALSE(ast->size()); + ASSERT_TRUE(Parse("# \\\\macro \\\\\\\n")); + ASSERT_FALSE(ast->size()); + ASSERT_TRUE(Parse("/* \\\\macro \\\\\\ */")); + ASSERT_FALSE(ast->size()); + ASSERT_TRUE(Parse("/* \\\\macro \\\\\\\n*/")); + ASSERT_FALSE(ast->size()); + ASSERT_TRUE(Parse("/* \\\\macro \\\\\\\n\n*/")); + ASSERT_FALSE(ast->size()); + ASSERT_TRUE(Parse("/*/* \\\\macro \\\\\\\n\n*/*/")); + ASSERT_FALSE(ast->size()); } diff --git a/src/types.h b/src/types.h index cbe9f152..0f2a155c 100644 --- a/src/types.h +++ b/src/types.h @@ -22,49 +22,6 @@ namespace newlang { } - template - class SharedPtrWrapper { - public: - - explicit SharedPtrWrapper(T* p, void (*deleter)(T*)) : ptr_() { - if (!p) { - return; - } - - if (!deleter) { - deleter = NullDeleter; - } - - try { - ptr_ = std::shared_ptr(p, deleter); - } catch (...) { - } - } - - operator bool() const { - return !!ptr_; - } - - T* get() const { - return ptr_.get(); - } - - T& operator*() const { - return *ptr_; - } - - T* operator->() const { - return get(); - } - - private: - - static void NullDeleter(T*) { - } - - std::shared_ptr ptr_; - }; - typedef at::indexing::TensorIndex Index; typedef at::IntArrayRef Dimension; @@ -189,6 +146,9 @@ void ParserException(const char *msg, std::string &buffer, int row, int col); _(ViewWide, 52) \ _(String, 55) \ \ + _(Iterator, 62) \ + _(IteratorEnd, 63) \ + \ _(Pointer, 64) \ _(NativeFunc, 65) \ _(Function, 100) \ diff --git a/src/variable.h b/src/variable.h index 98f1ee21..9b9ee226 100644 --- a/src/variable.h +++ b/src/variable.h @@ -43,10 +43,6 @@ namespace newlang { || std::fabs(x - y) < std::numeric_limits::min(); } - /* - * - * - */ /* * Шаблон для объектов типа словарь (именованные и не именованный свойства с доступом по индексу и/или имени). @@ -57,6 +53,9 @@ namespace newlang { * */ + + template class Iter; + /* * Аргумент по умолчанию может быть литерал или выражение. * Если аргумент по умолчанию — это выражение, то оно вычисляется только один раз для всей программы при загрузке модуля. @@ -76,387 +75,111 @@ namespace newlang { * новые аргументы по мимо тех, которые уже определены в прототипе функции. */ - template - class Variable { - public: - typedef T Type; + template > + class Variable : public std::list> + { + public: + typedef PTR Type; typedef std::pair PairType; - // typedef std::pair PairTypeConst; - typedef std::list DataType; - - class iterator; - typedef iterator const_iterator; - //typedef typename _Rep_type::const_iterator iterator; - //typedef typename _Rep_type::const_iterator const_iterator; - - typedef bool CompareFuncType(const PairType &pair, Variable &args, const void *extra); + typedef std::list ListType; template - typename std::enable_if::value && !std::is_pointer::value, const Type &>::type - inline operator[](I index) { - return at(index).second; + typename std::enable_if < std::is_integral::value && !std::is_pointer::value, const PairType &>::type + inline operator[](I index) { + return at(index); } template - typename std::enable_if::value || std::is_pointer::value, const Type &>::type - inline operator[](N name) { - return at(name).second; - } - - inline Type & push_back(Type value, const std::string &name = "") { - return push_back(pair(value, name)); - } - - inline Type & push_back(PairType data) { - m_data.push_back(data); - return at(m_data.size() - 1).second; - } - - inline Type & push_front(Type value, const std::string &name = "") { - return push_front(pair(value, name)); + typename std::enable_if < std::is_same::value || std::is_pointer::value, const PairType &>::type + inline operator[](N name) { + return at(name); } - inline Type & push_front(PairType pair) { - m_data.insert(m_data.begin(), pair); - return at(0).second; + inline PairType & push_back(const PairType & p) { + ListType::push_back(p); + return *at_index(-1); } - inline void pop_front() { - m_data.erase(m_data.begin()); + inline PairType & push_back(const Type value, const std::string &name = "") { + return push_back(pair(value, name)); } - inline Type top() const { - if (m_data.empty()) { - return nullptr; + inline PairType top() const { + if (ListType::empty()) { + LOG_RUNTIME("Empty Index '%ld' not exists!", index); } - return m_data[m_data.size() - 1].second; + return *ListType::back(); } - static inline PairType pair(Type value, const std::string name = "") { + static inline PairType pair(const Type value, const std::string name = "") { return std::pair(name, value); } - inline Type & insert(int64_t index, Type value, const std::string &name = "") { - if (index < 0 || index >= static_cast (m_data.size())) { - LOG_RUNTIME("Index '%ld' not exists!", index); - } - return m_data.insert(at_index(index), std::pair(name, value))->second; - } - virtual PairType & at(const int64_t index) { return *at_index(index); - // if (index >= 0) { - // if (index < static_cast (m_data.size())) { - // int64_t pos = 0; - // typename DataType::iterator iter = m_data.begin(); - // while (iter != m_data.end()) { - // if (pos == index) { - // return *iter; - // } - // pos++; - // iter++; - // } - // LOG_RUNTIME("Index %ld not exists!", index); - // // return m_data.at(index); - // } - // } else { - // if (-index < static_cast (m_data.size())) { - // int64_t pos = index + 1; - // typename DataType::reverse_iterator iter = m_data.rbegin(); - // while (iter != m_data.rend()) { - // if (pos == 0) { - // return *iter; - // } - // pos--; - // iter++; - // } - // LOG_RUNTIME("Index %ld not exists!", index); - // // return m_data.at(m_data.size() + index); - // } - // } - // LOG_RUNTIME("Index '%ld' not exists!", index); } virtual const PairType & at(const int64_t index) const { return *at_index_const(index); - // if (index >= 0) { - // if (index < static_cast (m_data.size())) { - // int64_t pos = 0; - // typename DataType::const_iterator iter = m_data.begin(); - // while (iter != m_data.end()) { - // if (pos == index) { - // return *iter; - // } - // pos++; - // iter++; - // } - // LOG_RUNTIME("Index %ld not exists!", index); - // // return m_data.at(index); - // } - // } else { - // if (-index < static_cast (m_data.size())) { - // int64_t pos = index + 1; - // typename DataType::const_reverse_iterator iter = m_data.rbegin(); - // while (iter != m_data.rend()) { - // if (pos == 0) { - // return *iter; - // } - // pos--; - // iter++; - // } - // LOG_RUNTIME("Index %ld not exists!", index); - // // return m_data.at(m_data.size() + index); - // } - // } - // LOG_RUNTIME("Index '%ld' not exists!", index); } - // template - // typename std::enable_if>::value, Type &>::type - // inline at(N * name) { - // return at(std::string(name)); - // } + typename ListType::iterator find(const std::string_view name) { + auto iter = ListType::begin(); + while (iter != ListType::end()) { + if (iter->first.compare(name) == 0) { + return iter; + } + iter++; + } + return ListType::end(); + } + + typename ListType::const_iterator find(const std::string_view name) const { + return find(name); + } virtual PairType & at(const std::string_view name) { - iterator found = select(name); - if (found != m_data.end()) { - return found.data(); + auto iter = find(name); + if (iter != ListType::end()) { + return *iter; } LOG_RUNTIME("Property '%s' not found!", name.begin()); } - // template - // typename std::enable_if>::value, Type &>::type - // inline at(N * name) const { - // return at(std::string(name)); - // } - // - // virtual PairType & at(const std::string name) const { - // iterator found = select(name); - // if (found != m_data.end()) { - // return found.data(); - // } - // LOG_RUNTIME("Property '%s' not found!", name.c_str()); - // } - - // virtual const PairType & at(const std::string name) { - // iterator found = select(name); - // if (found != m_data.end()) { - // return found.data(); - // } - // LOG_EXCEPT(std::out_of_range, "Property '%s' not found!", name.c_str()); - // } - virtual const std::string & name(const int64_t index) const { return at_index_const(index)->first; } - virtual bool empty() const { - return m_data.empty(); - } - virtual void clear_() { - m_data.clear(); + ListType::clear(); } - virtual int64_t size() const { - return m_data.size(); - } - - virtual int64_t resize(int64_t size, const Type fill, const std::string &name = "") { - if (size >= 0) { + virtual int64_t resize(int64_t new_size, const Type fill, const std::string &name = "") { + if (new_size >= 0) { // Размер положительный, просто изменить число элементов добавив или удалив последние - m_data.resize(size, std::pair(name, fill)); + ListType::resize(new_size, std::pair(name, fill)); } else { // Если размер отрицательный - добавить или удалить вначале - size = -size; - if (static_cast (m_data.size()) > size) { - - m_data.erase(m_data.begin(), at_index(m_data.size() - size)); - - // int64_t pos = 0; - // typename DataType::iterator iter = m_data.begin(); - // while (iter != m_data.end()) { - // if (pos == size) { - // return m_data.size(); - // } - // pos++; - // iter++; - // } - } else if (static_cast (m_data.size()) < size) { - m_data.insert(m_data.begin(), (m_data.size() - size), std::pair(name, fill)); - } else { - m_data.clear(); - } - } - return m_data.size(); - } - - /* - * - */ - class iterator { - friend class Variable; - public: - - Type &operator*() { - if (m_found != m_data.end()) { - return m_found->second; - } - LOG_RUNTIME("Property '%s' not found or iterator completed!", m_key.c_str()); - } - - inline const Type &operator*() const { - return operator*(); - } - - PairType &data() { - if (m_found != m_data.end()) { - return *m_found; - } - LOG_RUNTIME("Property '%s' not found or iterator completed!", m_key.c_str()); - } - - inline const PairType &data() const { - return data(); - } - - const iterator &operator++() { - if (m_found == m_data.end()) { - LOG_RUNTIME("Property '%s' not found or iterator completed!", m_key.c_str()); - } - m_found++; - search_loop(); - return *this; - } + new_size = -new_size; + if (static_cast (ListType::size()) > new_size) { - inline const const_iterator &operator++() const { - return operator++(); - } - - iterator operator++(int) { - if (m_found == m_data.end()) { - LOG_RUNTIME("Property '%s' not found or iterator completed!", m_key.c_str()); - } - iterator copy(*this); - m_found++; - search_loop(); - return copy; - } - - // inline const_iterator operator++(int) const { - // return iterator::operator++(int); - // } - - inline bool operator==(const typename DataType::iterator &other) const { - return m_found == other; - } - - inline bool operator==(const typename DataType::const_iterator &other) const { - return m_found == other; - } - - inline bool operator!=(const typename DataType::iterator &other) const { - return m_found != other; - } + ListType::erase(ListType::begin(), at_index(ListType::size() - new_size)); - inline bool operator!=(const typename DataType::const_iterator &other) const { - return m_found != other; - } - - // inline bool complete() { - // return m_found == m_data.end(); - // } - - inline bool complete() const { - return m_found == m_data.end(); - } - - inline int64_t reset() { - m_found = m_data.begin(); - search_loop(); - return m_find_key ? -1 : static_cast (m_data.size()); - } - - - protected: - - iterator(DataType &data) : m_data(data), m_find_key(false), m_func(nullptr), m_found(data.begin()) { - search_loop(); - } - - iterator(DataType &data, const std::string_view find_key) : m_data(data), m_find_key(true), m_key(find_key), m_func(nullptr), m_found(data.begin()) { - search_loop(); - } - - // iterator(DataType &data, const std::string & find_key) : m_data(data), m_find_key(true), m_key(find_key), m_func(nullptr), m_found(data.begin()) { - // search_loop(); - // } - - iterator(DataType &data, CompareFuncType *func, Variable &arg, void * extra = nullptr) : - m_data(data), m_find_key(true), m_found(data.begin()), m_func(func), m_func_args(arg), m_func_extra(extra) { - // m_func_args.in - search_loop(); - } - - void search_loop() { - if (!m_find_key) { - return; - } - while (m_found != m_data.end()) { - if (m_func) { - if ((*m_func)(*m_found, m_func_args, m_func_extra)) { - return; - } - } else { - if (m_found->first.compare(m_key) == 0) { - return; - } - } - m_found++; + } else if (static_cast (ListType::size()) < new_size) { + ListType::insert(ListType::begin(), (ListType::size() - new_size), std::pair(name, fill)); + } else { + ListType::clear(); } } - - private: - DataType & m_data; - const bool m_find_key; - const std::string m_key; - typename DataType::iterator m_found; - - CompareFuncType *m_func; - Variable m_func_args; - const void *m_func_extra; - }; - - /* Базовый класс остается открытым, чтобы можно было использовать STL для обработки типовых итераторов в пермеенных. - * Но для использования в NewLang предназначены вирутальные методы iter, которые для простых объектов соответствуют - * типовым STL итераторам, а в производных класса (Context и т.д.) могу быть переопределены - * - * - */ - - virtual typename DataType::iterator begin() { - return m_data.begin(); - } - - inline typename DataType::const_iterator begin() const { - return m_data.begin(); - } - - virtual typename DataType::iterator end() { - return m_data.end(); - } - - inline typename DataType::const_iterator end() const { - return m_data.end(); + return ListType::size(); } - typename DataType::iterator at_index(const int64_t index) { + typename ListType::iterator at_index(const int64_t index) { if (index < 0) { - if (-index < static_cast (m_data.size())) { + if (-index <= static_cast (ListType::size())) { int64_t pos = index + 1; - typename DataType::iterator iter = m_data.end(); - while (iter != m_data.begin()) { + typename ListType::iterator iter = ListType::end(); + while (iter != ListType::begin()) { iter--; if (pos == 0) { return iter; @@ -466,8 +189,8 @@ namespace newlang { } } else { int64_t pos = 0; - typename DataType::iterator iter = m_data.begin(); - while (iter != m_data.end()) { + typename ListType::iterator iter = ListType::begin(); + while (iter != ListType::end()) { if (pos == index) { return iter; } @@ -478,12 +201,12 @@ namespace newlang { LOG_RUNTIME("Index '%ld' not exists!", index); } - typename DataType::const_iterator at_index_const(const int64_t index) const { + typename ListType::const_iterator at_index_const(const int64_t index) const { if (index < 0) { - if (-index < static_cast (m_data.size())) { + if (-index < static_cast (ListType::size())) { int64_t pos = index + 1; - typename DataType::const_iterator iter = m_data.end(); - while (iter != m_data.begin()) { + typename ListType::const_iterator iter = ListType::end(); + while (iter != ListType::begin()) { iter--; if (pos == 0) { return iter; @@ -493,8 +216,8 @@ namespace newlang { } } else { int64_t pos = 0; - typename DataType::const_iterator iter = m_data.begin(); - while (iter != m_data.end()) { + typename ListType::const_iterator iter = ListType::begin(); + while (iter != ListType::end()) { if (pos == index) { return iter; } @@ -506,58 +229,7 @@ namespace newlang { } virtual void erase(const int64_t index) { - m_data.erase(at_index(index)); - } - - typename DataType::iterator erase(typename DataType::iterator iter) { - return m_data.erase(iter); - } - - typename DataType::iterator erase(iterator iter) { - if (!iter.complete()) { - - return m_data.erase(iter.m_found); - } - LOG_RUNTIME("Try erase end of iter!"); - } - - virtual iterator select() { - - return iterator(m_data); - } - - // inline const_iterator select() const { - // return select(); - // } - - virtual iterator select(const std::string_view key) { - - return iterator(m_data, key); - } - - // virtual iterator select(const std::string & key) const { - // return iterator(m_data, key); - // } - - inline iterator select(CompareFuncType *func, void * extra = nullptr) { - Variable args; - - return select(func, args, extra); - } - - virtual iterator select(CompareFuncType *func, Variable args, void * extra = nullptr) { - - return iterator(m_data, func, args, extra); - } - - /* - * - * - */ - - inline static PairType Arg(Type obj, const std::string name = "") { - - return std::pair(name, obj); + ListType::erase(at_index_const(index)); } virtual ~Variable() { @@ -577,20 +249,6 @@ namespace newlang { template inline Variable(PairType arg, A... rest) : Variable(rest...) { push_front(arg.second, arg.first); } - - SCOPE(protected) : - DataType m_data; - - - /** - * Обновить аргументы по умолчанию реальными значениями по следующим правилам: - * 1. Изначально объект содержит аргументы по умолчанию. - * 2. Имена именованныех аргументов должны быть уникальны. - * 3. Имена передаваемые именованных аргументов должны присутствовать в аргументах по умолчанию. - * 4. Не именованные аргументы должны передаваться перед именованными. - * 5. Лимит количества аргументов определнных типов при создании объекта (описан в протитипе функции). - */ - }; } // namespace newlang diff --git a/src/win/nlc.vcxproj b/src/win/nlc.vcxproj index e8222300..fa14d89c 100644 --- a/src/win/nlc.vcxproj +++ b/src/win/nlc.vcxproj @@ -178,7 +178,7 @@ Level3 true - _DEBUG;_CONSOLE;DEBUG;LOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG;PDC_WIDE;UNITTEST;_SILENCE_CXX17_ITERATOR_BASE_CLASS_DEPRECATION_WARNING;_SILENCE_CXX17_RESULT_OF_DEPRECATION_WARNING;_SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING;_SILENCE_CXX17_ADAPTOR_TYPEDEFS_DEPRECATION_WARNING;NOMINMAX;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + _DEBUG;_CONSOLE;DEBUG;LOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG;PDC_WIDE;UNITTEST;_SILENCE_CXX17_ITERATOR_BASE_CLASS_DEPRECATION_WARNING;_SILENCE_CXX17_RESULT_OF_DEPRECATION_WARNING;_SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING;_SILENCE_CXX17_ADAPTOR_TYPEDEFS_DEPRECATION_WARNING;NOMINMAX;_CRT_SECURE_NO_WARNINGS;_NO_CRT_STDIO_INLINE;__CRT__NO_INLINE;%(PreprocessorDefinitions) false stdcpp17 Use @@ -186,12 +186,15 @@ stdc17 pch.h.pch false + MultiThreadedDebugDLL + false Console true %(AdditionalLibraryDirectories) - C:\Program Files\OpenSSL-Win64\lib\libcrypto_static.lib;Ws2_32.lib;%(AdditionalDependencies) + Ws2_32.lib;legacy_stdio_definitions.lib;legacy_stdio_wide_specifiers.lib;C:\Program Files\OpenSSL-Win64\lib\libcrypto_static.lib;%(AdditionalDependencies) + MSVCRT From ff3964270c7515dafb6706795c2f15375271ed9e Mon Sep 17 00:00:00 2001 From: Aleksandr Ryabikov Date: Sat, 9 Jul 2022 18:42:37 +0300 Subject: [PATCH 17/31] =?UTF-8?q?Fix=20=D1=81=D0=B8=D1=81=D1=82=D0=B5?= =?UTF-8?q?=D0=BC=D1=8B=20=D1=81=D0=B1=D0=BE=D1=80=D0=BA=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Makefile | 210 +++++++++++++++++++++++++++++ src/nbproject/Makefile-UnitTest.mk | 5 + src/nbproject/configurations.xml | 4 + src/variable.h | 11 -- 4 files changed, 219 insertions(+), 11 deletions(-) create mode 100644 src/Makefile diff --git a/src/Makefile b/src/Makefile new file mode 100644 index 00000000..f65a0605 --- /dev/null +++ b/src/Makefile @@ -0,0 +1,210 @@ +# +# There exist several targets which are by default empty and which can be +# used for execution of your targets. These targets are usually executed +# before and after some main targets. They are: +# +# .build-pre: called before 'build' target +# .build-post: called after 'build' target +# .clean-pre: called before 'clean' target +# .clean-post: called after 'clean' target +# .clobber-pre: called before 'clobber' target +# .clobber-post: called after 'clobber' target +# .all-pre: called before 'all' target +# .all-post: called after 'all' target +# .help-pre: called before 'help' target +# .help-post: called after 'help' target +# +# Targets beginning with '.' are not intended to be called on their own. +# +# Main targets can be executed directly, and they are: +# +# build build a specific configuration +# clean remove built files from a configuration +# clobber remove all built files +# all build all configurations +# help print help mesage +# +# Targets .build-impl, .clean-impl, .clobber-impl, .all-impl, and +# .help-impl are implemented in nbproject/makefile-impl.mk. +# +# Available make variables: +# +# CND_BASEDIR base directory for relative paths +# CND_DISTDIR default top distribution directory (build artifacts) +# CND_BUILDDIR default top build directory (object files, ...) +# CONF name of current configuration +# CND_PLATFORM_${CONF} platform name (current configuration) +# CND_ARTIFACT_DIR_${CONF} directory of build artifact (current configuration) +# CND_ARTIFACT_NAME_${CONF} name of build artifact (current configuration) +# CND_ARTIFACT_PATH_${CONF} path to build artifact (current configuration) +# CND_PACKAGE_DIR_${CONF} directory of package (current configuration) +# CND_PACKAGE_NAME_${CONF} name of package (current configuration) +# CND_PACKAGE_PATH_${CONF} path to package (current configuration) +# +# NOCDDL + + +# Environment +MKDIR=mkdir +CP=cp +CCADMIN=CCadmin + + +VERSION_MAJOR=0 +VERSION_MINOR=1 +VERSION_PATCH=0 +VERSION_HEADER="version.h" +VERSION_FILE="version.c" + + +GIT_TAG_VERSION=$(shell git describe --abbrev=0 --tags) +GIT_SHORT_HASH=$(shell git rev-parse --short HEAD) +GIT_SOURCE_ID=$(GIT_TAG_VERSION)-$(GIT_SHORT_HASH) +DATE_BUILD=$(shell date +'%y.%m.%d %H:%M:%S') + +# build +build: .build-post + +.build-pre: +# Add your pre 'build' code here... + +# @if [ ! -d "temp" ]; then \ +# @mkdir temp; \ +# fi +# pandoc -t plain ../docs/syntax.md > ../docs/syntax.txt +# ../contrib/text2cpp/output/bin/text2cpp ../docs/syntax.txt syntax_help.cpp newlang_syntax_help c +# +# +# @if [ "$(GIT_TAG_VERSION)" != "v$(VERSION_MAJOR).$(VERSION_MINOR).$(VERSION_PATCH)" ]; then \ +# echo "Git TAG $(GIT_TAG_VERSION) differ version v$(VERSION_MAJOR).$(VERSION_MINOR).$(VERSION_PATCH)"; \ +# exit 1; \ +# fi +# @if [ -z $(GIT_SHORT_HASH) ]; then \ +# echo Undefined version for build; \ +# exit 1; \ +# fi +# @if [ -f $(VERSION_HEADER) ]; then \ +# rm $(VERSION_HEADER); \ +# fi +# +# @echo "/** @file $(VERSION_HEADER)" > $(VERSION_HEADER) +# @echo "* Auto generate file for identification current build" >> $(VERSION_HEADER) +# @echo "* Date build $(DATE_BUILD)" >> $(VERSION_HEADER) +# @echo "*/" >> $(VERSION_HEADER) +# @echo "" >> $(VERSION_HEADER) +# +# @echo "#include " >> $(VERSION_HEADER) +# +# @echo "extern const uint8_t VERSION_MAJOR;" >> $(VERSION_HEADER) +# @echo "extern const uint8_t VERSION_MINOR;" >> $(VERSION_HEADER) +# @echo "extern const uint8_t VERSION_PATCH;" >> $(VERSION_HEADER) +# @echo "extern const uint16_t VERSION_BUILD;" >> $(VERSION_HEADER) +# @echo "" >> $(VERSION_HEADER) +# +# @echo "#define VERSION ($(VERSION_MAJOR) << 4 | $(VERSION_MINOR))" >> $(VERSION_HEADER) +# @echo "#define VERSION_GIT_SOURCE \"$(GIT_SOURCE_ID)\"" >> $(VERSION_HEADER) +# @echo "#define VERSION_DATE_BUILD_STR \"$(DATE_BUILD)\"" >> $(VERSION_HEADER) +# @echo "#define VERSION_SOURCE_FULL_ID \"$(GIT_SOURCE_ID) $(DATE_BUILD)\"" >> $(VERSION_HEADER) +# @echo "" >> $(VERSION_HEADER) +# +# @echo "extern const char * GIT_SOURCE;" >> $(VERSION_HEADER) +# @echo "extern const char * DATE_BUILD_STR;" >> $(VERSION_HEADER) +# @echo "extern const char * SOURCE_FULL_ID; " >> $(VERSION_HEADER) +# @echo "" >> $(VERSION_HEADER) +# +# @if [ -f $(VERSION_FILE) ]; then \ +# rm $(VERSION_FILE); \ +# fi +# +# @echo "/** @file $(VERSION_FILE)" > $(VERSION_FILE) +# @echo "* Auto generate file for identification current build" >> $(VERSION_FILE) +# @echo "* Date build $(DATE_BUILD)" >> $(VERSION_FILE) +# @echo "*/" >> $(VERSION_FILE) +# @echo "" >> $(VERSION_FILE) +# +# @echo "#include \"version.h\"" >> $(VERSION_FILE) +# @echo "" >> $(VERSION_FILE) +# +# @echo "const uint8_t VERSION_MAJOR=$(VERSION_MAJOR);" >> $(VERSION_FILE) +# @echo "const uint8_t VERSION_MINOR=$(VERSION_MINOR);" >> $(VERSION_FILE) +# @echo "const uint8_t VERSION_PATCH=$(VERSION_PATCH);" >> $(VERSION_FILE) +# @echo "" >> $(VERSION_FILE) +# +# @echo "const char * GIT_SOURCE = VERSION_GIT_SOURCE;" >> $(VERSION_FILE) +# @echo "const char * DATE_BUILD_STR = VERSION_DATE_BUILD_STR;" >> $(VERSION_FILE) +# @echo "const char * SOURCE_FULL_ID = VERSION_SOURCE_FULL_ID;" >> $(VERSION_FILE) +# @echo "" >> $(VERSION_FILE) +# +# @echo Mark version $(GIT_SOURCE_ID) $(DATE_BUILD) + + +.build-post: .build-impl +# Add your post 'build' code here... + + +# clean +clean: .clean-post + +.clean-pre: +# Add your pre 'clean' code here... + +.clean-post: .clean-impl +# Add your post 'clean' code here... + + +# clobber +clobber: .clobber-post + +.clobber-pre: +# Add your pre 'clobber' code here... + +.clobber-post: .clobber-impl +# Add your post 'clobber' code here... + + +# all +all: .all-post + +.all-pre: +# Add your pre 'all' code here... + +.all-post: .all-impl +# Add your post 'all' code here... + + +# build tests +build-tests: .build-tests-post + +.build-tests-pre: +# Add your pre 'build-tests' code here... + +.build-tests-post: .build-tests-impl +# Add your post 'build-tests' code here... + + +# run tests +test: .test-post + +.test-pre: build-tests +# Add your pre 'test' code here... + +.test-post: .test-impl +# Add your post 'test' code here... + + +# help +help: .help-post + +.help-pre: +# Add your pre 'help' code here... + +.help-post: .help-impl +# Add your post 'help' code here... + + + +# include project implementation makefile +include nbproject/Makefile-impl.mk + +# include project make variables +include nbproject/Makefile-variables.mk diff --git a/src/nbproject/Makefile-UnitTest.mk b/src/nbproject/Makefile-UnitTest.mk index b0fb080c..2bab3e9f 100644 --- a/src/nbproject/Makefile-UnitTest.mk +++ b/src/nbproject/Makefile-UnitTest.mk @@ -100,6 +100,10 @@ ${OBJECTDIR}/_ext/e16507f5/logger.o: ../contrib/logger/logger.cpp ${RM} "$@.d" $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I. -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -I/usr/lib/llvm-13/include -std=c++14 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/_ext/e16507f5/logger.o ../contrib/logger/logger.cpp +syntax_help.cpp: ../docs/syntax.txt + @echo Выполнение шага пользовательского сборки + ../contrib/text2cpp/output/bin/text2cpp ../docs/syntax.txt syntax_help.cpp syntax_help s + ${OBJECTDIR}/builtin.o: builtin.cpp parser.h parser.yy.h pch.h.gch location.hh ${MKDIR} -p ${OBJECTDIR} ${RM} "$@.d" @@ -277,6 +281,7 @@ ${OBJECTDIR}/version.o: version.c # Clean Targets .clean-conf: ${CLEAN_SUBPROJECTS} ${RM} -r ${CND_BUILDDIR}/${CND_CONF} + ${RM} syntax_help.cpp ${RM} ${RM} ${RM} diff --git a/src/nbproject/configurations.xml b/src/nbproject/configurations.xml index 23bc23e6..0dc3da93 100644 --- a/src/nbproject/configurations.xml +++ b/src/nbproject/configurations.xml @@ -635,6 +635,10 @@ + + ../contrib/text2cpp/output/bin/text2cpp ../docs/syntax.txt syntax_help.cpp syntax_help s + syntax_help.cpp + diff --git a/src/variable.h b/src/variable.h index 9b9ee226..ed38b757 100644 --- a/src/variable.h +++ b/src/variable.h @@ -44,18 +44,7 @@ namespace newlang { } - /* - * Шаблон для объектов типа словарь (именованные и не именованный свойства с доступом по индексу и/или имени). - * Имена свойств у объекта должны быть уникальными (одинаковыми быть не могут). - * Имена объектов могут быть одинаковыми, т.к. имя хранится внутри объекта. - * Глобальные объекты имет идентификатром объекта и имя локальной/сессионной переменной, которая хранит на него ссылку. - * Им объекта и имя переменной, содержащей объект - это разные имена. - * - */ - - template class Iter; - /* * Аргумент по умолчанию может быть литерал или выражение. * Если аргумент по умолчанию — это выражение, то оно вычисляется только один раз для всей программы при загрузке модуля. From 21c5ed063aee7f4c781c6c60aed4bfe4f23d67ee Mon Sep 17 00:00:00 2001 From: Aleksandr Ryabikov Date: Sat, 9 Jul 2022 21:33:55 +0300 Subject: [PATCH 18/31] =?UTF-8?q?=D0=97=D0=B0=D0=B3=D0=BE=D1=82=D0=BE?= =?UTF-8?q?=D0=B2=D0=BA=D0=B0=20=D0=B8=D1=82=D0=B5=D1=80=D1=82=D0=BE=D1=80?= =?UTF-8?q?=D0=B0=20=D0=B2=20ObjPtr?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/object.cpp | 10 + src/object.h | 3190 +++++++++++++++++++------------------- src/test/object_test.cpp | 14 +- 3 files changed, 1618 insertions(+), 1596 deletions(-) diff --git a/src/object.cpp b/src/object.cpp index 600f66e7..3c16e723 100644 --- a/src/object.cpp +++ b/src/object.cpp @@ -2922,6 +2922,9 @@ ObjPtr Obj::ConstructorInterraption_(const Context* ctx, Obj& args, ObjType type return result; } +template<> +const Iterator::IterPairType Iterator::m_interator_end = IterObj::pair(Obj::CreateType(ObjType::IteratorEnd, ObjType::IteratorEnd, true)); + template<> ObjPtr Iterator::read_and_next(int64_t count) { ObjPtr result; @@ -2951,3 +2954,10 @@ ObjPtr Iterator::read_and_next(int64_t count) { } return result; } + + +ObjPtr Obj::MakeIterator() { + ObjPtr result = CreateType(ObjType::Iterator, ObjType::Iterator, true); + result->m_iterator = std::make_shared> (shared()); + return result; +} \ No newline at end of file diff --git a/src/object.h b/src/object.h index d61fcb63..b1dc4416 100644 --- a/src/object.h +++ b/src/object.h @@ -10,1944 +10,1952 @@ namespace newlang { - /* - * Аргумент по умолчанию может быть литерал или выражение. - * Если аргумент по умолчанию — это выражение, то оно вычисляется только один раз для всей программы при загрузке модуля. - * Аргументы по умолчанию парсятся из токенов (создаются или вычисляются) при загрузке модуля, т.е. при создании - * аругментов по умолчанию, а сами значения хранятся уже как объекты. - * - * Аргументы в функции всегда имеют номер, который начинается с единицы в порядке определения в прототипе + некоторые могут иметь наименование. - * Даже обязательные аргументы (которые не имеют значения по умолчанию в прототипе финкции), могут быть переданы по имени, - * а сами именованные аргументы могут быть указаны в произвольном порядке. Поэтому в реализации Args для обязательных - * аргументов так же хранится имя аргумента, но его значение отсутствует. - * - * Так как позционные аргументы тоже могут передавать как именованные, то контроль и подстчет кол-ва - * не именованных аргументов при вызове фунции ничего не определяет. - * Следовательно, при вызове функции не именованные аргументы записываются по порядку, а именованные по имени. - * Контроль передаваемых аргументов производится на наличие значения у каждого аргумента. - * Если при определении функции после всех аргументов стоит многоточие, то разрешается добавлять - * новые аргументы по мимо тех, которые уже определены в прототипе функции. - */ - - ObjType DictionarySummaryType(const Obj *obj); - std::vector TensorShapeFromDict(const Obj *obj); - torch::Tensor ConvertToTensor(Obj *obj, at::ScalarType type = at::ScalarType::Undefined, bool reshape = true); - - at::TensorOptions ConvertToTensorOptions(const Obj *obj); - at::DimnameList ConvertToDimnameList(const Obj *obj); - bool ParsePrintfFormat(Obj *args, int start = 1); - - enum class ConcatMode : uint8_t { - Error = 0, - Append = 1, - Discard = 2, - }; - /* - * Для строк, словарей и классов (преобразование в одно измерение), тензоров (преобразование согласно ConcatMode) - */ - int64_t ConcatData(Obj *dest, Obj &src, ConcatMode mode = ConcatMode::Error); - - // Convert a wide Unicode string to an UTF8 string - - inline std::string utf8_encode(const std::wstring wstr) { - std::string utf8line; - - if (wstr.empty()) { - return utf8line; - } - utf8line = std::wstring_convert < std::codecvt_utf8>().to_bytes(wstr.c_str()); +/* + * Аргумент по умолчанию может быть литерал или выражение. + * Если аргумент по умолчанию — это выражение, то оно вычисляется только один раз для всей программы при загрузке модуля. + * Аргументы по умолчанию парсятся из токенов (создаются или вычисляются) при загрузке модуля, т.е. при создании + * аругментов по умолчанию, а сами значения хранятся уже как объекты. + * + * Аргументы в функции всегда имеют номер, который начинается с единицы в порядке определения в прототипе + некоторые могут иметь наименование. + * Даже обязательные аргументы (которые не имеют значения по умолчанию в прототипе финкции), могут быть переданы по имени, + * а сами именованные аргументы могут быть указаны в произвольном порядке. Поэтому в реализации Args для обязательных + * аргументов так же хранится имя аргумента, но его значение отсутствует. + * + * Так как позционные аргументы тоже могут передавать как именованные, то контроль и подстчет кол-ва + * не именованных аргументов при вызове фунции ничего не определяет. + * Следовательно, при вызове функции не именованные аргументы записываются по порядку, а именованные по имени. + * Контроль передаваемых аргументов производится на наличие значения у каждого аргумента. + * Если при определении функции после всех аргументов стоит многоточие, то разрешается добавлять + * новые аргументы по мимо тех, которые уже определены в прототипе функции. + */ + +ObjType DictionarySummaryType(const Obj *obj); +std::vector TensorShapeFromDict(const Obj *obj); +torch::Tensor ConvertToTensor(Obj *obj, at::ScalarType type = at::ScalarType::Undefined, bool reshape = true); + +at::TensorOptions ConvertToTensorOptions(const Obj *obj); +at::DimnameList ConvertToDimnameList(const Obj *obj); +bool ParsePrintfFormat(Obj *args, int start = 1); + +enum class ConcatMode : uint8_t { + Error = 0, + Append = 1, + Discard = 2, +}; +/* + * Для строк, словарей и классов (преобразование в одно измерение), тензоров (преобразование согласно ConcatMode) + */ +int64_t ConcatData(Obj *dest, Obj &src, ConcatMode mode = ConcatMode::Error); + +// Convert a wide Unicode string to an UTF8 string + +inline std::string utf8_encode(const std::wstring wstr) { + std::string utf8line; + + if (wstr.empty()) { return utf8line; } + utf8line = std::wstring_convert < std::codecvt_utf8>().to_bytes(wstr.c_str()); + return utf8line; +} - // Convert an UTF8 string to a wide Unicode String +// Convert an UTF8 string to a wide Unicode String - inline std::wstring utf8_decode(const std::string str) { - std::wstring wide_line; +inline std::wstring utf8_decode(const std::string str) { + std::wstring wide_line; - if (str.empty()) { - return wide_line; - } - wide_line = std::wstring_convert < std::codecvt_utf8>().from_bytes(str.c_str()); + if (str.empty()) { return wide_line; } + wide_line = std::wstring_convert < std::codecvt_utf8>().from_bytes(str.c_str()); + return wide_line; +} + +ObjType getSummaryTensorType(ObjPtr & obj, ObjType start); +std::vector getTensorSizes(Obj *obj); +void calcTensorDims(ObjPtr & obj, std::vector &dims); +void testTensorDims(ObjPtr & obj, at::IntArrayRef dims, int64_t pos); + + + + + +/* + * Требуется разделять конейнеры с данными и итераторы по данным. + * В С++ контейнеры предоставялют итераторы непосредственно из самого контейнера. + * Это удобно для использования в рукописном коде, но сложно контроллировать в генерируемом исходнике, + * т.к. требуется использовать и итертор и сам контейнер с данными (для сравнения с end()). + * + * Логика работы с итераторами следующая. + * Итератор - отдельный объект, которому для создания требуется контейнер с данными. + * Итератор два интерфейса перебора данных: + * 1. - первый интерфейс итератора как в С++ + * 2. - второй интерфейс для использования в генерируемом коде с логикой NewLang + * + * Разделение контейнера и итератора на два объекта позволит выполнять проверку на использование + * + */ + +/* + * Итератор + */ +template +class Iterator : public std::iterator { +public: + + enum class IterCmp : int8_t { + No = static_cast (ObjType::None), /* skip data */ + Yes = static_cast (ObjType::Iterator), /* return data */ + End = static_cast (ObjType::IteratorEnd), /* iterator complete */ + }; - ObjType getSummaryTensorType(ObjPtr & obj, ObjType start); - std::vector getTensorSizes(Obj *obj); - void calcTensorDims(ObjPtr & obj, std::vector &dims); - void testTensorDims(ObjPtr & obj, at::IntArrayRef dims, int64_t pos); - - class Obj : public Variable, public std::enable_shared_from_this { - public: - - // constexpr static const char * BUILDIN_TYPE = "__var_type__"; - // constexpr static const char * BUILDIN_NAME = "__var_name__"; - // constexpr static const char * BUILDIN_BASE = "__class_base__"; - // constexpr static const char * BUILDIN_CLASS = "__class_name__"; - // constexpr static const char * BUILDIN_NAMESPACE = "__namespace__"; - - Obj(ObjType type = ObjType::None, const char *var_name = nullptr, TermPtr func_proto = nullptr, ObjType fixed = ObjType::None, bool init = false) : - m_var_type_current(type), m_var_name(var_name ? var_name : ""), m_func_proto(func_proto) { - // m_ctx = nullptr; - m_is_const = false; - m_check_args = false; - m_ref_count = 0; - m_func_ptr = nullptr; - m_dimensions = nullptr; - m_value = torch::empty({0}, isSimpleType(type) ? toTorchType(type) : at::ScalarType::Undefined); - m_is_reference = false; - m_func_abi = FFI_DEFAULT_ABI; - m_var_type_fixed = fixed; - m_var_is_init = init; - } + STATIC_ASSERT(static_cast (IterCmp::Yes)); + STATIC_ASSERT(!static_cast (IterCmp::No)); - Obj(Context *ctx, const TermPtr term, bool as_value, Obj *local_vars); + typedef Iterator iterator; + typedef Iterator const_iterator; + typedef Variable IterObj; + typedef typename Variable::Type IterObjPtr; + typedef typename Variable::PairType IterPairType; + typedef typename Variable::ListType IterListType; - [[nodiscard]] - static inline PairType ArgNull(const std::string name = "") { - return pair(nullptr, name); - } - [[nodiscard]] - static inline PairType Arg() { - return pair(CreateNone()); - } + typedef IterCmp CompareFuncType(const IterPairType &pair, const T *args, void *extra); - [[nodiscard]] - static inline PairType Arg(ObjPtr value, const std::string name = "") { - return pair(value, name); - } + /** + * Итератор для элементов списка с regex фильтром по имени элемента (по умолчанию для всех элементов списка) + * @param obj + * @param find_key + */ + Iterator(std::shared_ptr obj, const std::string find_key = "(.|\\n)*") : + Iterator(obj, &CompareFuncDefault, reinterpret_cast (const_cast (&find_key)), static_cast (this)) { + } - template - typename std::enable_if::value || std::is_same::value, PairType>::type - static inline Arg(T value, const std::string name = "") { - return pair(CreateString(value), name); - } + /** + * Итератор для элементов списка с фильтром в виде функции обратного вызова + * @param obj + * @param func + * @param arg + * @param extra + */ + Iterator(std::shared_ptr obj, CompareFuncType *func, T *arg, void * extra = nullptr) : + m_iter_obj(obj), m_match(), m_func(func), m_func_args(arg), m_func_extra(extra), m_found(m_iter_obj->begin()) { + search_loop(); + } - template - typename std::enable_if::value && !std::is_pointer::value && !std::is_same::value, PairType>::type - static inline Arg(T value, const std::string name = "") { - return pair(CreateValue(value, ObjType::None), name); - } + Iterator(const Iterator &iter) : m_iter_obj(iter.m_iter_obj), m_match(iter.m_match), m_func(iter.m_func), + m_func_args(iter.m_func_args), m_func_extra(iter.m_func_extra), m_found(iter.m_found) { + } - inline ObjPtr shared() { - try { - return shared_from_this(); - } catch (std::bad_weak_ptr &err) { - LOG_RUNTIME("Exception thrown bad_weak_ptr! %s", err.what()); - } - } + SCOPE(private) : + std::shared_ptr m_iter_obj; + std::regex m_match; + std::string m_filter; + CompareFuncType *m_func; + T *m_func_args; + void *m_func_extra; - ObjPtr MakeConst() { - m_is_const = true; - return shared(); - } + mutable typename Variable::iterator m_found; - ObjPtr MakeMutable() { - m_is_const = false; - return shared(); - } + static const IterPairType m_interator_end; -#define TEST_CONST_() if (m_is_const) {LOG_RUNTIME("Can`t edit const value '%s'!", toString().c_str());} -#define TEST_INIT_() if (!m_var_is_init) {LOG_RUNTIME("Object not initialized '%s'!", toString().c_str());} + static IterCmp CompareFuncDefault(const IterPairType &pair, const T *filter, void *extra) { + const std::string * str_filter = reinterpret_cast (filter); + Iterator * iter = static_cast (extra); + if (iter && str_filter) { - [[nodiscard]] - inline ObjType getType() { - return m_var_type_current; - } + iter->m_func_args = nullptr; // Передается однократно при создании объекта + iter->m_filter = *str_filter; - [[nodiscard]] - inline ObjType getTypeAsLimit() { - if (is_arithmetic_type()) { - if (isIntegralType(m_var_type_current, true) && is_scalar()) { - return typeFromLimit(GetValueAsInteger()); - } else if (isFloatingType(m_var_type_current) && is_scalar()) { - return typeFromLimit(GetValueAsNumber()); + if (!iter->m_filter.empty()) { + try { + iter->m_match = std::regex(iter->m_filter); + } catch (const std::regex_error &err) { + LOG_RUNTIME("Regular expression for '%s' error '%s'!", str_filter->c_str(), err.what()); } - } else if (is_type_name()) { - return m_var_type_fixed; } - return m_var_type_current; - } - - [[nodiscard]] - inline std::string & getName() { - return m_var_name; } - [[nodiscard]] - inline const std::string & getName() const { - return m_var_name; + if (iter) { + if (iter->m_filter.empty()) { + return pair.first.empty() ? IterCmp::Yes : IterCmp::No; + } else { + return std::regex_match(pair.first, iter->m_match) ? IterCmp::Yes : IterCmp::No; + } } + return IterCmp::Yes; + } - /* - Встроенные атрибуты класса - - Объекты класса — дочерние элементы по отношению к атрибутам самого языка Python. Таким образом они заимствуют некоторые атрибуты: - Атрибут Описание - __dict__ Предоставляет данные о классе коротко и доступно, в виде словаря - __doc__ Возвращает строку с описанием класса, или None, если значение не определено - __class__ Возвращает объект, содержащий информацию о классе с массой полезных атрибутов, включая атрибут __name__ - __module__ Возвращает имя «модуля» класса или __main__, если класс определен в выполняемом модуле. - - class Customer: - 'Это класс Customer' - def __init__(self, name, phone, address): - self.name = name - self.phone = phone - self.address = address - - - john = Customer("John",1234567, "USA") - - print ("john.__dict__ = ", john.__dict__) - print ("john.__doc__ = ", john.__doc__) - print ("john.__class__ = ", john.__class__) - print ("john.__class__.__name__ = ", john.__class__.__name__) - print ("john.__module__ = ", john.__module__) - - Вывод: - - john.__dict__ = {'name': 'John', 'phone': 1234567, 'address': 'USA'} - john.__doc__ = Это класс Customer - john.__class__ = - john.__class__.__name__ = Customer - john.__module__ = __main__ - - */ - void SetClassName(std::string &name) { - m_class_name = name; - } +public: - inline bool isConst() const { - return m_is_const; - } + iterator begin() { + Iterator copy(*this); + copy.reset(); + return copy; + } - [[nodiscard]] - inline bool is_none_type() const { - return m_var_type_current == ObjType::None; - } + iterator end() { + Iterator copy(*this); + copy.m_found = copy.m_iter_obj->end(); + return copy; + } - [[nodiscard]] - inline bool is_bool_type() const { - return isBooleanType(m_var_type_current); + inline const IterPairType &operator*() { + if (m_found == m_iter_obj->end()) { + return m_interator_end; } + return *m_found; + } - [[nodiscard]] - inline bool is_arithmetic_type() const { - return isArithmeticType(m_var_type_current); + inline const IterPairType &operator*() const { + if (m_found == m_iter_obj->end()) { + return m_interator_end; } + return *m_found; + } - [[nodiscard]] - inline bool is_string_type() const { - return isString(m_var_type_current); - } + ObjPtr read_and_next(int64_t count); - [[nodiscard]] - inline bool is_dictionary_type() const { - return isDictionary(m_var_type_current); + const iterator &operator++() const { + if (m_found != m_iter_obj->end()) { + m_found++; + search_loop(); } + return *this; + } - //Plain data — это неизменяемые структуры без ссылок на другие объекты. - [[nodiscard]] - inline bool is_plain_type() const { - return isPlainDataType(m_var_type_current); - } + inline const iterator operator++(int) const { + return iterator::operator++(); + } - [[nodiscard]] - inline bool is_other_type() const { - return !(is_none_type() || is_bool_type() || is_arithmetic_type() || is_string_type() || is_dictionary_type()); - } + inline bool operator==(const iterator &other) const { + return m_found == other.m_found; + } - [[nodiscard]] - inline bool is_class() const { - return isClass(m_var_type_current); - } + inline bool operator!=(const iterator &other) const { + return m_found != other.m_found; + } - [[nodiscard]] - inline bool is_simple() const { - return isSimpleType(m_var_type_current); - } + inline void reset() { + m_found = m_iter_obj->begin(); + search_loop(); + } - [[nodiscard]] - inline bool is_scalar() const { - return is_tensor() && m_value.dim() == 0; - } - [[nodiscard]] - inline bool is_function() const { - return isFunction(m_var_type_current); - } +protected: - [[nodiscard]] - inline bool is_tensor() const { - return isTensor(m_var_type_current); + void search_loop() const { + while (m_found != m_iter_obj->end()) { + IterCmp result = IterCmp::Yes; + if (m_func) { + result = (*m_func)(*m_found, m_func_args, m_func_extra); + if (result == IterCmp::End) { + m_found = m_iter_obj->end(); + } + } + if (result != IterCmp::No) { + // IterCmp::Yes || IterCmp::End + return; + } + m_found++; } + } +}; + +/* + * + * + */ +class Obj : public Variable, public std::enable_shared_from_this { +public: + + // constexpr static const char * BUILDIN_TYPE = "__var_type__"; + // constexpr static const char * BUILDIN_NAME = "__var_name__"; + // constexpr static const char * BUILDIN_BASE = "__class_base__"; + // constexpr static const char * BUILDIN_CLASS = "__class_name__"; + // constexpr static const char * BUILDIN_NAMESPACE = "__namespace__"; + + Obj(ObjType type = ObjType::None, const char *var_name = nullptr, TermPtr func_proto = nullptr, ObjType fixed = ObjType::None, bool init = false) : + m_var_type_current(type), m_var_name(var_name ? var_name : ""), m_func_proto(func_proto) { + // m_ctx = nullptr; + m_is_const = false; + m_check_args = false; + m_ref_count = 0; + m_func_ptr = nullptr; + m_dimensions = nullptr; + m_value = torch::empty({0}, isSimpleType(type) ? toTorchType(type) : at::ScalarType::Undefined); + m_is_reference = false; + m_func_abi = FFI_DEFAULT_ABI; + m_var_type_fixed = fixed; + m_var_is_init = init; + } - [[nodiscard]] - inline bool is_integer() const { - return isIntegralType(m_var_type_current, false); - } + Obj(Context *ctx, const TermPtr term, bool as_value, Obj *local_vars); - [[nodiscard]] - inline bool is_complex() const { - return isComplexType(m_var_type_current); - } - [[nodiscard]] - inline bool is_floating() const { - return isFloatingType(m_var_type_current); - } + [[nodiscard]] + static inline PairType ArgNull(const std::string name = "") { + return pair(nullptr, name); + } - [[nodiscard]] - inline bool is_indexing() const { - return is_tensor() || is_string_type() || is_dictionary_type() || is_class(); - } + [[nodiscard]] + static inline PairType Arg() { + return pair(CreateNone()); + } - [[nodiscard]] - inline bool is_ellipsis() const { - return isEllipsis(m_var_type_current); - } + [[nodiscard]] + static inline PairType Arg(ObjPtr value, const std::string name = "") { + return pair(value, name); + } - [[nodiscard]] - inline bool is_range() const { - return isRange(m_var_type_current); - } + template + typename std::enable_if::value || std::is_same::value, PairType>::type + static inline Arg(T value, const std::string name = "") { + return pair(CreateString(value), name); + } - [[nodiscard]] - inline bool is_type_name() const { - return isTypeName(m_var_type_current); - } + template + typename std::enable_if::value && !std::is_pointer::value && !std::is_same::value, PairType>::type + static inline Arg(T value, const std::string name = "") { + return pair(CreateValue(value, ObjType::None), name); + } - [[nodiscard]] - inline bool is_error() const { - return m_var_type_current == ObjType::Error || m_var_type_fixed == ObjType::Error; + inline ObjPtr shared() { + try { + return shared_from_this(); + } catch (std::bad_weak_ptr &err) { + LOG_RUNTIME("Exception thrown bad_weak_ptr! %s", err.what()); } + } - [[nodiscard]] - inline bool is_return() const { - return m_var_type_current == ObjType::Return || m_var_type_fixed == ObjType::Return; - } + ObjPtr MakeConst() { + m_is_const = true; + return shared(); + } - [[nodiscard]] - ObjType SummaryArithmeticType(ObjType type); + ObjPtr MakeMutable() { + m_is_const = false; + return shared(); + } - [[nodiscard]] - inline bool is_defined_type() { - return m_var_type_fixed != ObjType::None; - } + ObjPtr MakeIterator(); - inline void SetTermProp(Term &term); +#define TEST_CONST_() if (m_is_const) {LOG_RUNTIME("Can`t edit const value '%s'!", toString().c_str());} +#define TEST_INIT_() if (!m_var_is_init) {LOG_RUNTIME("Object not initialized '%s'!", toString().c_str());} - virtual int64_t size() const { - return size(0); - } - virtual int64_t size(int64_t ind) const; - int64_t resize_(int64_t size, ObjPtr fill, const std::string = ""); + [[nodiscard]] + inline ObjType getType() { + return m_var_type_current; + } - virtual bool empty() const { - if (is_none_type()) { - return true; - } else if (m_var_type_current == ObjType::StrChar) { - return !m_var_is_init || m_str.empty(); - } else if (m_var_type_current == ObjType::StrWide) { - return !m_var_is_init || m_wstr.empty(); - } else if (is_tensor()) { - return !m_var_is_init || at::_is_zerotensor(m_value); + [[nodiscard]] + inline ObjType getTypeAsLimit() { + if (is_arithmetic_type()) { + if (isIntegralType(m_var_type_current, true) && is_scalar()) { + return typeFromLimit(GetValueAsInteger()); + } else if (isFloatingType(m_var_type_current) && is_scalar()) { + return typeFromLimit(GetValueAsNumber()); } - return Variable::empty(); + } else if (is_type_name()) { + return m_var_type_fixed; } + return m_var_type_current; + } - Variable::PairType & at(const std::string_view name) const { - Obj * const obj = (Obj * const) this; - return obj->Variable::at(name); - } + [[nodiscard]] + inline std::string & getName() { + return m_var_name; + } - Variable::PairType & at(const std::string_view name) override { - return Variable::at(name); - } + [[nodiscard]] + inline const std::string & getName() const { + return m_var_name; + } - Variable::PairType & at(const int64_t index) override; - const Variable::PairType & at(const int64_t index) const override; + /* + Встроенные атрибуты класса + +Объекты класса — дочерние элементы по отношению к атрибутам самого языка Python. Таким образом они заимствуют некоторые атрибуты: +Атрибут Описание +__dict__ Предоставляет данные о классе коротко и доступно, в виде словаря +__doc__ Возвращает строку с описанием класса, или None, если значение не определено +__class__ Возвращает объект, содержащий информацию о классе с массой полезных атрибутов, включая атрибут __name__ +__module__ Возвращает имя «модуля» класса или __main__, если класс определен в выполняемом модуле. + +class Customer: + 'Это класс Customer' + def __init__(self, name, phone, address): + self.name = name + self.phone = phone + self.address = address + + +john = Customer("John",1234567, "USA") + +print ("john.__dict__ = ", john.__dict__) +print ("john.__doc__ = ", john.__doc__) +print ("john.__class__ = ", john.__class__) +print ("john.__class__.__name__ = ", john.__class__.__name__) +print ("john.__module__ = ", john.__module__) - Variable::PairType & at(ObjPtr find) { - if (!find->is_string_type()) { - LOG_RUNTIME("Value must be a string type %d", (int) find->getType()); - } - return Variable::at(find->GetValueAsString()); - } +Вывод: - bool exist(ObjPtr &find, bool strong); - size_t ItemValueCount(ObjPtr &find, bool strong); +john.__dict__ = {'name': 'John', 'phone': 1234567, 'address': 'USA'} +john.__doc__ = Это класс Customer +john.__class__ = +john.__class__.__name__ = Customer +john.__module__ = __main__ - static bool is_true(const char *text) { - std::string temp(text); - std::transform(temp.begin(), temp.end(), temp.begin(), ::tolower); - return temp.compare("true") == 0; - } + */ + void SetClassName(std::string &name) { + m_class_name = name; + } - /** - * Создать копию объекта (клонировать) - * @return - */ - ObjPtr operator()(Context *ctx) { - Obj args; - return Call(ctx, &args); - } + inline bool isConst() const { + return m_is_const; + } - template - typename std::enable_if::value, ObjPtr>::type - inline operator()(Context *ctx, T ... args) { - auto list = {args...}; - ObjPtr arg = Obj::CreateDict(); - for (auto &elem : list) { - arg->push_back(elem); - } - return Call(ctx, arg.get()); - } + [[nodiscard]] + inline bool is_none_type() const { + return m_var_type_current == ObjType::None; + } - inline ObjPtr Call(Context *ctx) { - Obj args; - return Call(ctx, &args); - } + [[nodiscard]] + inline bool is_bool_type() const { + return isBooleanType(m_var_type_current); + } - template - typename std::enable_if::value, ObjPtr>::type - inline Call(Context *ctx, T ... args) { - auto list = {args...}; - Obj arg; - for (auto &elem : list) { - arg.push_back(elem); - } - return Call(ctx, &arg); - } + [[nodiscard]] + inline bool is_arithmetic_type() const { + return isArithmeticType(m_var_type_current); + } - ObjPtr Call(Context *ctx, Obj *args); + [[nodiscard]] + inline bool is_string_type() const { + return isString(m_var_type_current); + } + [[nodiscard]] + inline bool is_dictionary_type() const { + return isDictionary(m_var_type_current); + } + //Plain data — это неизменяемые структуры без ссылок на другие объекты. + [[nodiscard]] + inline bool is_plain_type() const { + return isPlainDataType(m_var_type_current); + } + [[nodiscard]] + inline bool is_other_type() const { + return !(is_none_type() || is_bool_type() || is_arithmetic_type() || is_string_type() || is_dictionary_type()); + } + [[nodiscard]] + inline bool is_class() const { + return isClass(m_var_type_current); + } - //унарный плюс ничего не делает. + [[nodiscard]] + inline bool is_simple() const { + return isSimpleType(m_var_type_current); + } - ObjPtr operator+() { - if (is_arithmetic_type()) { - return shared(); - } - LOG_RUNTIME("Unary plus for object '%s' not supported!", toString().c_str()); - } + [[nodiscard]] + inline bool is_scalar() const { + return is_tensor() && m_value.dim() == 0; + } - ObjPtr operator-() { - if (is_arithmetic_type()) { - if (is_tensor()) { - m_value = -m_value; - } else if (is_integer()) { - SetValue_(-GetValueAsInteger()); - } else if (isFloatingType(m_var_type_current)) { - SetValue_(-GetValueAsNumber()); - } else { - LOG_RUNTIME("Unary minus for object '%s' not supported!", toString().c_str()); - } - return shared(); - } - LOG_RUNTIME("Unary minus for object '%s' not supported!", toString().c_str()); - } + [[nodiscard]] + inline bool is_function() const { + return isFunction(m_var_type_current); + } - ObjPtr & operator+(ObjPtr & obj) { + [[nodiscard]] + inline bool is_tensor() const { + return isTensor(m_var_type_current); + } - if (is_tensor()) { - return obj; - } - LOG_RUNTIME("Object '%s' not numeric!", obj->toString().c_str()); - } + [[nodiscard]] + inline bool is_integer() const { + return isIntegralType(m_var_type_current, false); + } - ObjPtr &operator-(ObjPtr & obj) { - if (is_tensor()) { - obj->m_value = torch::zeros_like(obj->m_value) - obj->m_value; - return obj; - } - LOG_RUNTIME("Object '%s' not numeric!", obj->toString().c_str()); - } + [[nodiscard]] + inline bool is_complex() const { + return isComplexType(m_var_type_current); + } + [[nodiscard]] + inline bool is_floating() const { + return isFloatingType(m_var_type_current); + } - //префиксная версия возвращает значение после инкремента + [[nodiscard]] + inline bool is_indexing() const { + return is_tensor() || is_string_type() || is_dictionary_type() || is_class(); + } - ObjPtr operator++() { - if (is_tensor()) { - m_value.add_(torch::ones_like(m_value)); + [[nodiscard]] + inline bool is_ellipsis() const { + return isEllipsis(m_var_type_current); + } - return shared(); - } - LOG_RUNTIME("Object '%s' not numeric!", toString().c_str()); - } + [[nodiscard]] + inline bool is_range() const { + return isRange(m_var_type_current); + } - //постфиксная версия возвращает значение до инкремента + [[nodiscard]] + inline bool is_type_name() const { + return isTypeName(m_var_type_current); + } - ObjPtr operator++(int) { - ObjPtr old = Clone(); - Obj::operator++(); - return old; - } + [[nodiscard]] + inline bool is_error() const { + return m_var_type_current == ObjType::Error || m_var_type_fixed == ObjType::Error; + } - //префиксная версия возвращает значение после декремента + [[nodiscard]] + inline bool is_return() const { + return m_var_type_current == ObjType::Return || m_var_type_fixed == ObjType::Return; + } - ObjPtr operator--() { - if (is_tensor()) { - m_value.sub_(torch::ones_like(m_value)); - return shared(); - } - LOG_RUNTIME("Object '%s' not numeric!", toString().c_str()); - } + [[nodiscard]] + ObjType SummaryArithmeticType(ObjType type); - //постфиксная версия возвращает значение до декремента + [[nodiscard]] + inline bool is_defined_type() { + return m_var_type_fixed != ObjType::None; + } - ObjPtr operator--(int) { - ObjPtr old = Clone(); - Obj::operator--(); - return old; - } + inline void SetTermProp(Term &term); - inline ObjPtr operator*(ObjPtr obj) { - ASSERT(obj); - return operator*(*obj); - } + virtual int64_t size() const { + return size(0); + } + virtual int64_t size(int64_t ind) const; + int64_t resize_(int64_t size, ObjPtr fill, const std::string = ""); - inline ObjPtr operator*(Obj value) { - ObjPtr result = Clone(); - *result *= value; - return result; - } + virtual bool empty() const { + if (is_none_type()) { + return true; + } else if (m_var_type_current == ObjType::StrChar) { + return !m_var_is_init || m_str.empty(); + } else if (m_var_type_current == ObjType::StrWide) { + return !m_var_is_init || m_wstr.empty(); + } else if (is_tensor()) { + return !m_var_is_init || at::_is_zerotensor(m_value); + } + return Variable::empty(); + } - inline ObjPtr operator/(ObjPtr obj) { - ASSERT(obj); - return operator/(*obj); - } + Variable::PairType & at(const std::string_view name) const { + Obj * const obj = (Obj * const) this; + return obj->Variable::at(name); + } - inline ObjPtr operator/(Obj value) { - ObjPtr result = Clone(); - *result /= value; - return result; - } + Variable::PairType & at(const std::string_view name) override { + return Variable::at(name); + } - inline ObjPtr op_div_ceil(ObjPtr obj) { - ASSERT(obj); - return op_div_ceil(*obj); - } + Variable::PairType & at(const int64_t index) override; + const Variable::PairType & at(const int64_t index) const override; - inline ObjPtr op_div_ceil(Obj value) { - ObjPtr result = Clone(); - result->op_div_ceil_(value); - return result; + Variable::PairType & at(ObjPtr find) { + if (!find->is_string_type()) { + LOG_RUNTIME("Value must be a string type %d", (int) find->getType()); } + return Variable::at(find->GetValueAsString()); + } - inline ObjPtr op_concat(ObjPtr obj, ConcatMode mode = ConcatMode::Error) { - ASSERT(obj); - return op_concat(*obj, mode); - } + bool exist(ObjPtr &find, bool strong); + size_t ItemValueCount(ObjPtr &find, bool strong); - inline ObjPtr op_concat(Obj &value, ConcatMode mode = ConcatMode::Error) { - ObjPtr result = Clone(); - result->op_concat_(value, mode); - return result; - } + static bool is_true(const char *text) { + std::string temp(text); + std::transform(temp.begin(), temp.end(), temp.begin(), ::tolower); + return temp.compare("true") == 0; + } - inline ObjPtr op_concat_(Obj &obj, ConcatMode mode = ConcatMode::Error) { - ConcatData(this, obj, mode); - return shared(); - } + /** + * Создать копию объекта (клонировать) + * @return + */ + ObjPtr operator()(Context *ctx) { + Obj args; + return Call(ctx, &args); + } - inline ObjPtr op_concat_(ObjPtr obj, ConcatMode mode = ConcatMode::Error) { - return op_concat_(*obj, mode); + template + typename std::enable_if::value, ObjPtr>::type + inline operator()(Context *ctx, T ... args) { + auto list = {args...}; + ObjPtr arg = Obj::CreateDict(); + for (auto &elem : list) { + arg->push_back(elem); } + return Call(ctx, arg.get()); + } - inline ObjPtr operator%(ObjPtr obj) { - ASSERT(obj); - return operator%(*obj); - } + inline ObjPtr Call(Context *ctx) { + Obj args; + return Call(ctx, &args); + } - inline ObjPtr operator%(Obj value) { - ObjPtr result = Clone(); - *result %= value; - return result; + template + typename std::enable_if::value, ObjPtr>::type + inline Call(Context *ctx, T ... args) { + auto list = {args...}; + Obj arg; + for (auto &elem : list) { + arg.push_back(elem); } + return Call(ctx, &arg); + } - inline ObjPtr operator+(ObjPtr obj) { - ASSERT(obj); - return operator+(*obj); - } + ObjPtr Call(Context *ctx, Obj *args); - inline ObjPtr operator+(Obj value) { - ObjPtr result = Clone(); - *result += value; - return result; - } - inline ObjPtr operator-(ObjPtr obj) { - ASSERT(obj); - return operator-(*obj); - } - inline ObjPtr operator-(Obj value) { - ObjPtr result = Clone(); - *result -= value; - return result; - } - // ObjPtr op_lshift(ObjPtr obj) { - // LOG_RUNTIME("Operator '<<' not implementd!"); - // } - // - // ObjPtr op_rshift(ObjPtr obj) { - // LOG_RUNTIME("Operator '>>' not implementd!"); - // } - // - // ObjPtr op_rrshift(ObjPtr obj) { - // LOG_RUNTIME("Operator '>>>' not implementd!"); - // } - - inline bool operator<(ObjPtr obj) { - ASSERT(obj); - return operator<(*obj); - } - inline bool operator<(Obj obj) { - return op_compare(obj) < 0; - } + //унарный плюс ничего не делает. - inline bool operator<=(ObjPtr obj) { - ASSERT(obj); - return operator<=(*obj); + ObjPtr operator+() { + if (is_arithmetic_type()) { + return shared(); } + LOG_RUNTIME("Unary plus for object '%s' not supported!", toString().c_str()); + } - inline bool operator<=(Obj obj) { - return op_compare(obj) <= 0; + ObjPtr operator-() { + if (is_arithmetic_type()) { + if (is_tensor()) { + m_value = -m_value; + } else if (is_integer()) { + SetValue_(-GetValueAsInteger()); + } else if (isFloatingType(m_var_type_current)) { + SetValue_(-GetValueAsNumber()); + } else { + LOG_RUNTIME("Unary minus for object '%s' not supported!", toString().c_str()); + } + return shared(); } + LOG_RUNTIME("Unary minus for object '%s' not supported!", toString().c_str()); + } - inline bool operator>(ObjPtr obj) { - ASSERT(obj); - return operator>(*obj); - } + ObjPtr & operator+(ObjPtr & obj) { - inline bool operator>(Obj obj) { - return op_compare(obj) > 0; + if (is_tensor()) { + return obj; } + LOG_RUNTIME("Object '%s' not numeric!", obj->toString().c_str()); + } - inline bool operator>=(ObjPtr obj) { - ASSERT(obj); - return operator>=(*obj); + ObjPtr &operator-(ObjPtr & obj) { + if (is_tensor()) { + obj->m_value = torch::zeros_like(obj->m_value) - obj->m_value; + return obj; } + LOG_RUNTIME("Object '%s' not numeric!", obj->toString().c_str()); + } - inline bool operator>=(Obj obj) { - return op_compare(obj) >= 0; - } - int op_compare(Obj & value); - - /* - * instanceof (проверка класса объекта) test_obj ~~ obj объекты совместимы по свойствим и их типам (утиная типизация) - * in (проверка существования свойства) test_obj ~~ (prop=,) объект содержит указанные свойства (т.к. пустой тип совместим с любым типом) - * - * Реализация модели наследования: - * ~ - проверка по классу объекта, т.е. проверка имени объекта или имени базового типа (объект должен быть наследником образца) - * Реализация утиной типизации: - * ~~ - сравнение с образцом на совместимость типов (пустой тип совместим с любым) - * ~~~ - сравнение с образцом на равенство типов, т.е. типы объекта должны быть идентичны образцу, включая пустой - * Для двух последних случаев сравнение производится только для одного уровня (без раскрытия сложенных словарей, если они присутствуют в образце) - * или сравнение должно зависить от того, есть ли в образце вложенные словари (классы) ?????????????? - */ - - bool op_class_test(ObjPtr obj, Context *ctx) const; - bool op_class_test(const char * name, Context *ctx) const; - - inline bool op_duck_test(ObjPtr obj, bool strong) { - ASSERT(obj); - return op_duck_test(obj.get(), strong); - } - bool op_duck_test(Obj *value, bool strong); - static bool op_duck_test_prop(Obj *base, Obj *value, bool strong); - inline bool op_equal(ObjPtr value) { - ASSERT(value); - if (value) { - return op_equal(*value); - } - return false; - } + //префиксная версия возвращает значение после инкремента - inline ObjPtr operator==(ObjPtr obj) { - ASSERT(obj); - return operator==(*obj); - } + ObjPtr operator++() { + if (is_tensor()) { + m_value.add_(torch::ones_like(m_value)); - inline ObjPtr operator==(Obj obj) { - return op_equal(obj) ? Obj::Yes() : Obj::No(); + return shared(); } - bool op_equal(Obj & value); + LOG_RUNTIME("Object '%s' not numeric!", toString().c_str()); + } - inline bool op_accurate(ObjPtr obj) { - ASSERT(obj); - return op_accurate(*obj); - } - bool op_accurate(Obj & value); + //постфиксная версия возвращает значение до инкремента - inline ObjPtr operator!=(ObjPtr obj) { - ASSERT(obj); - return operator!=(*obj); - } + ObjPtr operator++(int) { + ObjPtr old = Clone(); + Obj::operator++(); + return old; + } - inline ObjPtr operator!=(Obj obj) { - return op_equal(obj) ? Obj::No() : Obj::Yes(); - } + //префиксная версия возвращает значение после декремента - inline ObjPtr op_bit_and(ObjPtr obj, bool strong) { - ASSERT(obj); - return op_bit_and(*obj, strong); + ObjPtr operator--() { + if (is_tensor()) { + m_value.sub_(torch::ones_like(m_value)); + return shared(); } + LOG_RUNTIME("Object '%s' not numeric!", toString().c_str()); + } - inline ObjPtr op_bit_and(Obj &obj, bool strong) { - ObjPtr result = Clone(); - result->op_bit_and_set(obj, strong); - return result; - } + //постфиксная версия возвращает значение до декремента - inline ObjPtr op_pow(ObjPtr obj) const { - ASSERT(obj); - return op_pow(*obj); - } + ObjPtr operator--(int) { + ObjPtr old = Clone(); + Obj::operator--(); + return old; + } - inline ObjPtr op_pow(Obj &obj) const { - ObjPtr result = Clone(); - result->op_pow_(obj); - return result; - } + inline ObjPtr operator*(ObjPtr obj) { + ASSERT(obj); + return operator*(*obj); + } - inline ObjPtr op_pow_(ObjPtr obj) { - ASSERT(obj); - return op_pow_(*obj); - } + inline ObjPtr operator*(Obj value) { + ObjPtr result = Clone(); + *result *= value; + return result; + } - ObjPtr op_pow_(Obj &obj); - - // ObjPtr operator^(ObjPtr obj) { - // LOG_RUNTIME("Operator '^' not implementd!"); - // } - // - // ObjPtr operator|(ObjPtr obj) { - // LOG_RUNTIME("Operator '|' not implementd!"); - // } - // - // ObjPtr operator&&(ObjPtr obj) { - // LOG_RUNTIME("Operator '&&' not implementd!"); - // } - // - // ObjPtr operator||(ObjPtr obj) { - // LOG_RUNTIME("Operator '||' not implementd!"); - // } - - ObjPtr op_assign(ObjPtr obj) { - if (obj) { - return op_assign(*obj); - } - clear_(); - return shared(); - } + inline ObjPtr operator/(ObjPtr obj) { + ASSERT(obj); + return operator/(*obj); + } - ObjPtr op_assign(Obj & obj) { - obj.CloneDataTo(*this); - obj.ClonePropTo(*this); - return shared(); - } + inline ObjPtr operator/(Obj value) { + ObjPtr result = Clone(); + *result /= value; + return result; + } - inline bool operator=(Obj & obj) { - obj.CloneDataTo(*this); - return true; - } + inline ObjPtr op_div_ceil(ObjPtr obj) { + ASSERT(obj); + return op_div_ceil(*obj); + } - /* - * ?: (выбор из двух операндов) - * = (присваивание) - * *=, /=, %=, +=, -=, &=, ^=, |=, <<=, >>=, >>>= (операции с присваиванием) - * , (отбрасывание первого и возврат второго операнда) - */ + inline ObjPtr op_div_ceil(Obj value) { + ObjPtr result = Clone(); + result->op_div_ceil_(value); + return result; + } + inline ObjPtr op_concat(ObjPtr obj, ConcatMode mode = ConcatMode::Error) { + ASSERT(obj); + return op_concat(*obj, mode); + } - inline ObjPtr operator*=(ObjPtr obj) { - ASSERT(obj); - return operator*=(*obj); - } + inline ObjPtr op_concat(Obj &value, ConcatMode mode = ConcatMode::Error) { + ObjPtr result = Clone(); + result->op_concat_(value, mode); + return result; + } - ObjPtr operator*=(Obj obj); + inline ObjPtr op_concat_(Obj &obj, ConcatMode mode = ConcatMode::Error) { + ConcatData(this, obj, mode); + return shared(); + } - inline ObjPtr operator/=(ObjPtr obj) { - ASSERT(obj); - return operator/=(*obj); - } + inline ObjPtr op_concat_(ObjPtr obj, ConcatMode mode = ConcatMode::Error) { + return op_concat_(*obj, mode); + } - ObjPtr operator/=(Obj obj); + inline ObjPtr operator%(ObjPtr obj) { + ASSERT(obj); + return operator%(*obj); + } - inline ObjPtr op_div_ceil_(ObjPtr obj) { - ASSERT(obj); - return op_div_ceil_(*obj); - } + inline ObjPtr operator%(Obj value) { + ObjPtr result = Clone(); + *result %= value; + return result; + } - ObjPtr op_div_ceil_(Obj &obj); + inline ObjPtr operator+(ObjPtr obj) { + ASSERT(obj); + return operator+(*obj); + } - inline ObjPtr operator%=(ObjPtr obj) { - ASSERT(obj); - return operator%=(*obj); - } + inline ObjPtr operator+(Obj value) { + ObjPtr result = Clone(); + *result += value; + return result; + } - ObjPtr operator%=(Obj obj); + inline ObjPtr operator-(ObjPtr obj) { + ASSERT(obj); + return operator-(*obj); + } - inline ObjPtr operator+=(ObjPtr obj) { - ASSERT(obj); - return operator+=(*obj); - } - ObjPtr operator+=(Obj obj); + inline ObjPtr operator-(Obj value) { + ObjPtr result = Clone(); + *result -= value; + return result; + } - inline ObjPtr operator-=(ObjPtr obj) { - ASSERT(obj); - return operator-=(*obj); - } - ObjPtr operator-=(Obj obj); + // ObjPtr op_lshift(ObjPtr obj) { + // LOG_RUNTIME("Operator '<<' not implementd!"); + // } + // + // ObjPtr op_rshift(ObjPtr obj) { + // LOG_RUNTIME("Operator '>>' not implementd!"); + // } + // + // ObjPtr op_rrshift(ObjPtr obj) { + // LOG_RUNTIME("Operator '>>>' not implementd!"); + // } + + inline bool operator<(ObjPtr obj) { + ASSERT(obj); + return operator<(*obj); + } + inline bool operator<(Obj obj) { + return op_compare(obj) < 0; + } - ObjPtr op_bit_and_set(Obj &obj, bool strong); + inline bool operator<=(ObjPtr obj) { + ASSERT(obj); + return operator<=(*obj); + } - inline ObjPtr operator^=(ObjPtr obj) { - ASSERT(obj); - return operator^=(*obj); - } + inline bool operator<=(Obj obj) { + return op_compare(obj) <= 0; + } - ObjPtr operator^=(Obj obj) { - LOG_RUNTIME("Operator '^=' not implementd!"); - } + inline bool operator>(ObjPtr obj) { + ASSERT(obj); + return operator>(*obj); + } - inline ObjPtr operator|=(ObjPtr obj) { - ASSERT(obj); - return operator|=(*obj); - } + inline bool operator>(Obj obj) { + return op_compare(obj) > 0; + } - ObjPtr operator|=(Obj obj) { - LOG_RUNTIME("Operator '|=' not implementd!"); - } + inline bool operator>=(ObjPtr obj) { + ASSERT(obj); + return operator>=(*obj); + } - inline ObjPtr op_lshift_set(ObjPtr obj) { - ASSERT(obj); - return op_lshift_set(*obj); - } + inline bool operator>=(Obj obj) { + return op_compare(obj) >= 0; + } + int op_compare(Obj & value); - ObjPtr op_lshift_set(Obj obj) { - LOG_RUNTIME("Operator '<<=' not implementd!"); - } - - inline ObjPtr op_rshift_set(ObjPtr obj) { - ASSERT(obj); - return op_rshift_set(*obj); - } - - ObjPtr op_rshift_set(Obj obj) { - LOG_RUNTIME("Operator '>>=' not implementd!"); - } - - inline ObjPtr op_rrshift_set(ObjPtr obj) { - ASSERT(obj); - return op_rrshift_set(*obj); - } - - ObjPtr op_rrshift_set(Obj obj) { - LOG_RUNTIME("Operator '>>>=' not implementd!"); - } - - template - bool operator=(T value) { - SetValue_(value); - return true; - } + /* + * instanceof (проверка класса объекта) test_obj ~~ obj объекты совместимы по свойствим и их типам (утиная типизация) + * in (проверка существования свойства) test_obj ~~ (prop=,) объект содержит указанные свойства (т.к. пустой тип совместим с любым типом) + * + * Реализация модели наследования: + * ~ - проверка по классу объекта, т.е. проверка имени объекта или имени базового типа (объект должен быть наследником образца) + * Реализация утиной типизации: + * ~~ - сравнение с образцом на совместимость типов (пустой тип совместим с любым) + * ~~~ - сравнение с образцом на равенство типов, т.е. типы объекта должны быть идентичны образцу, включая пустой + * Для двух последних случаев сравнение производится только для одного уровня (без раскрытия сложенных словарей, если они присутствуют в образце) + * или сравнение должно зависить от того, есть ли в образце вложенные словари (классы) ?????????????? + */ + bool op_class_test(ObjPtr obj, Context *ctx) const; + bool op_class_test(const char * name, Context *ctx) const; - static ObjPtr GetIndex(ObjPtr obj, TermPtr index_arg); + inline bool op_duck_test(ObjPtr obj, bool strong) { + ASSERT(obj); + return op_duck_test(obj.get(), strong); + } + bool op_duck_test(Obj *value, bool strong); + static bool op_duck_test_prop(Obj *base, Obj *value, bool strong); - static ObjPtr GetIndex(ObjPtr obj, size_t index) { - return (*obj)[index].second; - } - - void dump_dict_(std::string &str, bool deep = true) const { - bool first = true; - for (auto &elem : * this) { - if (first) { - first = false; - } else { - str.append(", "); - } - if (elem.first.empty()) { - if (elem.second) { - str.append(elem.second->toString(false)); - } else { - str.append("_"); - } - } else { - if (elem.second) { - - if (deep || !(elem.second->is_tensor() || elem.second->getType() == ObjType::Class)) { - str.append(elem.first); - str.append("="); - str.append(elem.second->toString(false)); - } else if (elem.second->getType() == ObjType::Class && elem.second->m_is_reference) { - str.append("&"); - str.append(elem.second->getName()); - } else { - - str.append(elem.second->getName()); - str.append("="); - str.append(elem.second->toString()); - } - } else { - str.append("_"); - } - } - } + inline bool op_equal(ObjPtr value) { + ASSERT(value); + if (value) { + return op_equal(*value); } + return false; + } - std::string toString(bool deep = true) const; + inline ObjPtr operator==(ObjPtr obj) { + ASSERT(obj); + return operator==(*obj); + } - std::string GetValueAsString() const; + inline ObjPtr operator==(Obj obj) { + return op_equal(obj) ? Obj::Yes() : Obj::No(); + } + bool op_equal(Obj & value); - inline std::wstring GetValueAsStringWide() const { - return utf8_decode(GetValueAsString()); - } + inline bool op_accurate(ObjPtr obj) { + ASSERT(obj); + return op_accurate(*obj); + } + bool op_accurate(Obj & value); - inline int64_t GetValueAsInteger() const { - TEST_INIT_(); - switch (m_var_type_current) { - case ObjType::Bool: - case ObjType::Char: - case ObjType::Short: - case ObjType::Int: - case ObjType::Long: - case ObjType::Integer: - return m_value.toType(at::ScalarType::Long).item(); + inline ObjPtr operator!=(ObjPtr obj) { + ASSERT(obj); + return operator!=(*obj); + } - case ObjType::Float: - case ObjType::Double: - case ObjType::Number: - return static_cast (m_value.item()); + inline ObjPtr operator!=(Obj obj) { + return op_equal(obj) ? Obj::No() : Obj::Yes(); + } - case ObjType::Fraction: - ASSERT(m_fraction); - return m_fraction->GetAsInteger(); + inline ObjPtr op_bit_and(ObjPtr obj, bool strong) { + ASSERT(obj); + return op_bit_and(*obj, strong); + } - case ObjType::StrWide: - return std::stoll(m_wstr); - case ObjType::StrChar: - return std::stoll(m_str); - default: - if (m_var_type_current == ObjType::Pointer || m_var_type_fixed == ObjType::Pointer) { - return reinterpret_cast (m_func_ptr); - } - LOG_RUNTIME("Data type incompatible %s", toString().c_str()); - } - return 0; - } + inline ObjPtr op_bit_and(Obj &obj, bool strong) { + ObjPtr result = Clone(); + result->op_bit_and_set(obj, strong); + return result; + } - inline double GetValueAsNumber() const { - TEST_INIT_(); - switch (m_var_type_current) { - case ObjType::Float: - case ObjType::Double: - return m_value.item(); + inline ObjPtr op_pow(ObjPtr obj) const { + ASSERT(obj); + return op_pow(*obj); + } - case ObjType::Fraction: - ASSERT(m_fraction); - return m_fraction->GetAsNumber(); + inline ObjPtr op_pow(Obj &obj) const { + ObjPtr result = Clone(); + result->op_pow_(obj); + return result; + } - case ObjType::StrWide: - return std::stod(m_wstr); - case ObjType::StrChar: - return std::stod(m_str); + inline ObjPtr op_pow_(ObjPtr obj) { + ASSERT(obj); + return op_pow_(*obj); + } - default: - if (is_simple()) { - return static_cast (GetValueAsInteger()); - } - } - LOG_RUNTIME("Data type incompatible %s", toString().c_str()); - } + ObjPtr op_pow_(Obj &obj); + + // ObjPtr operator^(ObjPtr obj) { + // LOG_RUNTIME("Operator '^' not implementd!"); + // } + // + // ObjPtr operator|(ObjPtr obj) { + // LOG_RUNTIME("Operator '|' not implementd!"); + // } + // + // ObjPtr operator&&(ObjPtr obj) { + // LOG_RUNTIME("Operator '&&' not implementd!"); + // } + // + // ObjPtr operator||(ObjPtr obj) { + // LOG_RUNTIME("Operator '||' not implementd!"); + // } + + ObjPtr op_assign(ObjPtr obj) { + if (obj) { + return op_assign(*obj); + } + clear_(); + return shared(); + } - inline bool GetValueAsBoolean() const { - if (!m_var_is_init) { - return false; - } - if (is_scalar()) { - return m_value.toType(at::ScalarType::Bool).item(); - } else if (isSimpleType(m_var_type_current)) { - // Error: Boolean value of Tensor with more than one value is ambiguous - return !at::_is_zerotensor(m_value); - } else { - switch (m_var_type_current) { - case ObjType::StrWide: - return !m_wstr.empty(); - case ObjType::StrChar: - return !m_str.empty(); - case ObjType::None: - return false; - - case ObjType::Fraction: - ASSERT(m_fraction); - return m_fraction->GetAsInteger(); - - case ObjType::Dictionary: - case ObjType::Class: - if (size()) { - return true; - } - for (auto &elem : m_class_parents) { - if (elem->GetValueAsBoolean()) { - return true; - } - } - return false; + ObjPtr op_assign(Obj & obj) { + obj.CloneDataTo(*this); + obj.ClonePropTo(*this); + return shared(); + } - default: - LOG_RUNTIME("Type cast to bool %s", toString().c_str()); - } - return true; - } - } + inline bool operator=(Obj & obj) { + obj.CloneDataTo(*this); + return true; + } - at::Scalar toTorchScalar() { - at::Scalar result; - if (is_integer() || is_bool_type()) { - result = at::Scalar(GetValueAsInteger()); - } else if (is_floating()) { - result = at::Scalar(GetValueAsNumber()); - } else { - LOG_RUNTIME("Not support Torch ScalarType '%s'", newlang::toString(m_var_type_current)); - } - return result; + /* + * ?: (выбор из двух операндов) + * = (присваивание) + * *=, /=, %=, +=, -=, &=, ^=, |=, <<=, >>=, >>>= (операции с присваиванием) + * , (отбрасывание первого и возврат второго операнда) + */ - } - static ObjPtr CreateType(ObjType type, ObjType fixed = ObjType::None, bool is_init = false) { - return std::make_shared(type, nullptr, nullptr, fixed, is_init); - } + inline ObjPtr operator*=(ObjPtr obj) { + ASSERT(obj); + return operator*=(*obj); + } - static ObjPtr CreateFraction(const std::string_view val) { + ObjPtr operator*=(Obj obj); - std::string str; - std::remove_copy(val.begin(), val.end(), back_inserter(str), '_'); + inline ObjPtr operator/=(ObjPtr obj) { + ASSERT(obj); + return operator/=(*obj); + } - if (str.empty()) { - LOG_RUNTIME("Empty string!"); - } + ObjPtr operator/=(Obj obj); - ObjPtr frac = Obj::CreateType(ObjType::Fraction); + inline ObjPtr op_div_ceil_(ObjPtr obj) { + ASSERT(obj); + return op_div_ceil_(*obj); + } - // Ищем разделитель дроби - size_t pos = str.find("\\"); + ObjPtr op_div_ceil_(Obj &obj); - // Если символ не найден - то вся строка является числом - if (pos == std::string::npos) { - frac->m_fraction = std::make_shared(str, "1"); - } else { - // Числитель - левая часть - // Знаменатель - правая часть - frac->m_fraction = std::make_shared(str.substr(0, pos), str.substr(pos + 1, str.length())); - // Знаменатель не должен быть равен нулю - if (frac->m_fraction->m_denominator.isZero()) { - LOG_RUNTIME("Denominator must be different from zero!"); - } - } + inline ObjPtr operator%=(ObjPtr obj) { + ASSERT(obj); + return operator%=(*obj); + } - frac->m_var_is_init = true; - if (str.compare(frac->m_fraction->GetAsString().c_str()) != 0) { - LOG_RUNTIME("Fraction value '%s' does not match source string '%s'!", frac->m_fraction->GetAsString().c_str(), str.c_str()); - } + ObjPtr operator%=(Obj obj); - return frac; - } + inline ObjPtr operator+=(ObjPtr obj) { + ASSERT(obj); + return operator+=(*obj); + } + ObjPtr operator+=(Obj obj); + inline ObjPtr operator-=(ObjPtr obj) { + ASSERT(obj); + return operator-=(*obj); + } + ObjPtr operator-=(Obj obj); - // чистая функция - static ObjPtr BaseTypeConstructor(const Context *ctx, Obj &in); - static ObjPtr ConstructorSimpleType_(const Context *ctx, Obj & args); - static ObjPtr ConstructorDictionary_(const Context *ctx, Obj & args); - static ObjPtr ConstructorNative_(const Context *ctx, Obj & args); - static ObjPtr ConstructorClass_(const Context *ctx, Obj & args); - static ObjPtr ConstructorStruct_(const Context *ctx, Obj & args); - static ObjPtr ConstructorEnum_(const Context *ctx, Obj & args); - static ObjPtr ConstructorError_(const Context *ctx, Obj & args); - static ObjPtr ConstructorReturn_(const Context *ctx, Obj & args); - static ObjPtr ConstructorInterraption_(const Context *ctx, Obj & args, ObjType type); + ObjPtr op_bit_and_set(Obj &obj, bool strong); - static ObjPtr CreateBaseType(ObjType type); + inline ObjPtr operator^=(ObjPtr obj) { + ASSERT(obj); + return operator^=(*obj); + } - static ObjPtr CreateNone() { - return CreateType(ObjType::None, ObjType::None, true); - } + ObjPtr operator^=(Obj obj) { + LOG_RUNTIME("Operator '^=' not implementd!"); + } - template - static ObjPtr CreateRange(T1 start, T2 stop, T3 step) { - ObjPtr obj = CreateType(ObjType::Range); - obj->push_back(CreateValue(start, ObjType::None), "start"); - obj->push_back(CreateValue(stop, ObjType::None), "stop"); - obj->push_back(CreateValue(step, ObjType::None), "step"); - obj->m_var_is_init = true; - return obj; - } + inline ObjPtr operator|=(ObjPtr obj) { + ASSERT(obj); + return operator|=(*obj); + } - template - static ObjPtr CreateRange(T1 start, T2 stop) { - ObjPtr obj = CreateType(ObjType::Range); - obj->push_back(CreateValue(start, ObjType::None), "start"); - obj->push_back(CreateValue(stop, ObjType::None), "stop"); - if (start < stop) { - obj->push_back(CreateValue(1, ObjType::None), "step"); - } else { - obj->push_back(CreateValue(-1, ObjType::None), "step"); - } - obj->m_var_is_init = true; - return obj; - } + ObjPtr operator|=(Obj obj) { + LOG_RUNTIME("Operator '|=' not implementd!"); + } - static ObjType GetType(torch::Tensor & val) { - switch (val.dtype().toScalarType()) { - case at::ScalarType::Bool: - return ObjType::Bool; - case at::ScalarType::Half: - case at::ScalarType::BFloat16: - case at::ScalarType::Float: - return ObjType::Float; - case at::ScalarType::Double: - return ObjType::Double; - case at::ScalarType::Byte: - case at::ScalarType::Char: - case at::ScalarType::QInt8: - case at::ScalarType::QUInt8: - case at::ScalarType::QUInt4x2: - return ObjType::Char; - case at::ScalarType::Short: - return ObjType::Short; - case at::ScalarType::Int: - case at::ScalarType::QInt32: - return ObjType::Int; - case at::ScalarType::Long: - return ObjType::Long; - case at::ScalarType::ComplexHalf: - case at::ScalarType::ComplexFloat: - return ObjType::ComplexFloat; - case at::ScalarType::ComplexDouble: - return ObjType::ComplexDouble; - } - LOG_RUNTIME("Fail tensor type %s", val.toString().c_str()); - } + inline ObjPtr op_lshift_set(ObjPtr obj) { + ASSERT(obj); + return op_lshift_set(*obj); + } - static ObjPtr CreateBool(bool value) { - ObjPtr result = CreateType(ObjType::None); - result->m_value = torch::scalar_tensor(value, torch::Dtype::Bool); - result->m_var_type_current = ObjType::Bool; - result->m_var_is_init = true; - return result; - } + ObjPtr op_lshift_set(Obj obj) { + LOG_RUNTIME("Operator '<<=' not implementd!"); + } - static ObjPtr CreateTensor(torch::Tensor tensor) { - ObjType check_type = GetType(tensor); - if (!isTensor(check_type)) { - LOG_RUNTIME("Unsupport torch type %s (%d)!", at::toString(tensor.dtype().toScalarType()), (int) tensor.dtype().toScalarType()); - } - ObjPtr result = CreateType(check_type); - result->m_value = tensor; - result->m_var_is_init = true; - return result; - } + inline ObjPtr op_rshift_set(ObjPtr obj) { + ASSERT(obj); + return op_rshift_set(*obj); + } - static ObjPtr CreateTensor(ObjPtr data, ObjType type) { - torch::Tensor var = ConvertToTensor(data.get(), toTorchType(type), false); - // ConvertToTensor(data->index_get({0}).get(), type, false); - return CreateTensor(var); - } + ObjPtr op_rshift_set(Obj obj) { + LOG_RUNTIME("Operator '>>=' not implementd!"); + } - inline torch::Tensor toTensor() { - return ConvertToTensor(this); - } + inline ObjPtr op_rrshift_set(ObjPtr obj) { + ASSERT(obj); + return op_rrshift_set(*obj); + } - inline torch::Tensor & asTensor_() { - NL_CHECK(is_tensor(), "Fail type as Tensor"); - return m_value; - } + ObjPtr op_rrshift_set(Obj obj) { + LOG_RUNTIME("Operator '>>>=' not implementd!"); + } - at::indexing::Slice toSlice() { - NL_CHECK(is_range(), "Convert to slice supported for range only!"); + template + bool operator=(T value) { + SetValue_(value); + return true; + } - ASSERT(size() == 3 && Variable::at("start").second && Variable::at("stop").second && Variable::at("step").second); - NL_CHECK(Variable::at("start").second->is_integer(), "Slice value start support integer type only!"); - NL_CHECK(Variable::at("stop").second->is_integer(), "Slice value stop support integer type only!"); - NL_CHECK(Variable::at("step").second->is_integer(), "Slice value step support integer type only!"); + static ObjPtr GetIndex(ObjPtr obj, TermPtr index_arg); - return at::indexing::Slice( - Variable::at("start").second->GetValueAsInteger(), - Variable::at("stop").second->GetValueAsInteger(), - Variable::at("step").second->GetValueAsInteger()); - } + static ObjPtr GetIndex(ObjPtr obj, size_t index) { + return (*obj)[index].second; + } - /* - * From TensorIndexing.h - // There is one-to-one correspondence between Python and C++ tensor index types: - // Python | C++ - // ----------------------------------------------------- - // `None` | `at::indexing::None` - // `Ellipsis` | `at::indexing::Ellipsis` - // `...` | `"..."` - // `123` | `123` - // `True` / `False` | `true` / `false` - // `:` | `Slice()` / `Slice(None, None)` - // `::` | `Slice()` / `Slice(None, None, None)` - // `1:` | `Slice(1, None)` - // `1::` | `Slice(1, None, None)` - // `:3` | `Slice(None, 3)` - // `:3:` | `Slice(None, 3, None)` - // `::2` | `Slice(None, None, 2)` - // `1:3` | `Slice(1, 3)` - // `1::2` | `Slice(1, None, 2)` - // `:3:2` | `Slice(None, 3, 2)` - // `1:3:2` | `Slice(1, 3, 2)` - // `torch.tensor([1, 2])`) | `torch::tensor({1, 2})` - */ - Index toIndex() { - if (is_none_type()) { - return Index(c10::nullopt); - } else if (is_dictionary_type()) { - std::vector temp = toIntVector(true); - if (temp.size()) { - torch::Tensor tensor = torch::from_blob(temp.data(), temp.size(), torch::Dtype::Long); - return Index(tensor.clone()); + void dump_dict_(std::string &str, bool deep = true) const { + bool first = true; + for (auto &elem : * this) { + if (first) { + first = false; + } else { + str.append(", "); + } + if (elem.first.empty()) { + if (elem.second) { + str.append(elem.second->toString(false)); } else { - return Index(c10::nullopt); + str.append("_"); } + } else { + if (elem.second) { + + if (deep || !(elem.second->is_tensor() || elem.second->getType() == ObjType::Class)) { + str.append(elem.first); + str.append("="); + str.append(elem.second->toString(false)); + } else if (elem.second->getType() == ObjType::Class && elem.second->m_is_reference) { + str.append("&"); + str.append(elem.second->getName()); + } else { - } else if (is_scalar()) { - switch (m_var_type_current) { - case ObjType::Bool: - return Index(GetValueAsBoolean()); - - case ObjType::Char: - case ObjType::Short: - case ObjType::Int: - case ObjType::Long: - return Index(GetValueAsInteger()); - default: - LOG_RUNTIME("Fail convert scalar type '%s' to Index!", newlang::toString(m_var_type_current)); + str.append(elem.second->getName()); + str.append("="); + str.append(elem.second->toString()); + } + } else { + str.append("_"); } - } else if (is_tensor()) { - return Index(m_value); - } else if (is_ellipsis()) { - return Index(at::indexing::Ellipsis); - } else if (is_range()) { - return Index(toSlice()); } - LOG_RUNTIME("Fail convert object '%s' to Index!", toString().c_str()); } + } - inline operator bool () const { - return GetValueAsBoolean(); - } + std::string toString(bool deep = true) const; - inline operator at::Tensor() { - return ConvertToTensor(this); - } + std::string GetValueAsString() const; - inline operator at::TensorOptions() const { - return ConvertToTensorOptions(this); - } + inline std::wstring GetValueAsStringWide() const { + return utf8_decode(GetValueAsString()); + } - inline operator at::DimnameList() const { - return ConvertToDimnameList(this); + inline int64_t GetValueAsInteger() const { + TEST_INIT_(); + switch (m_var_type_current) { + case ObjType::Bool: + case ObjType::Char: + case ObjType::Short: + case ObjType::Int: + case ObjType::Long: + case ObjType::Integer: + return m_value.toType(at::ScalarType::Long).item(); + + case ObjType::Float: + case ObjType::Double: + case ObjType::Number: + return static_cast (m_value.item()); + + case ObjType::Fraction: + ASSERT(m_fraction); + return m_fraction->GetAsInteger(); + + case ObjType::StrWide: + return std::stoll(m_wstr); + case ObjType::StrChar: + return std::stoll(m_str); + default: + if (m_var_type_current == ObjType::Pointer || m_var_type_fixed == ObjType::Pointer) { + return reinterpret_cast (m_func_ptr); + } + LOG_RUNTIME("Data type incompatible %s", toString().c_str()); } + return 0; + } - std::vector toIntVector(bool raise = true) const { - std::vector result; - for (int i = 0; i < size(); i++) { - if (raise && !at(i).second->is_integer()) { - LOG_RUNTIME("Item does not contain an integer value! '%s'", at(i).second->GetValueAsString().c_str()); + inline double GetValueAsNumber() const { + TEST_INIT_(); + switch (m_var_type_current) { + case ObjType::Float: + case ObjType::Double: + return m_value.item(); + + case ObjType::Fraction: + ASSERT(m_fraction); + return m_fraction->GetAsNumber(); + + case ObjType::StrWide: + return std::stod(m_wstr); + case ObjType::StrChar: + return std::stod(m_str); + + default: + if (is_simple()) { + return static_cast (GetValueAsInteger()); } - result.push_back(at(i).second->GetValueAsInteger()); - } - return result; } + LOG_RUNTIME("Data type incompatible %s", toString().c_str()); + } - - // ПЕРЕКРЫВАЕТ ДРУГИЕ МЕТОДЫ !!!!!!!!!!!!!! at::TensorOptions() - // inline operator std::string () const { - // return GetValueAsString(); - // } - - template - typename std::enable_if::value, ObjPtr>::type - static CreateValue(T value, ObjType fix_type = ObjType::None) { - ObjPtr result = CreateType(fix_type); - result->m_var_type_fixed = fix_type; - result->m_var_type_current = typeFromLimit((int64_t) value); - if (fix_type != ObjType::None) { - NL_CHECK(canCast(result->m_var_type_current, fix_type), - "Fail cast type from '%s' to '%s'!", newlang::toString(result->m_var_type_current), newlang::toString(fix_type)); - } - result->m_value = torch::scalar_tensor(value, toTorchType(result->m_var_type_current)); - result->m_var_is_init = true; - return result; + inline bool GetValueAsBoolean() const { + if (!m_var_is_init) { + return false; } + if (is_scalar()) { + return m_value.toType(at::ScalarType::Bool).item(); + } else if (isSimpleType(m_var_type_current)) { + // Error: Boolean value of Tensor with more than one value is ambiguous + return !at::_is_zerotensor(m_value); + } else { + switch (m_var_type_current) { + case ObjType::StrWide: + return !m_wstr.empty(); + case ObjType::StrChar: + return !m_str.empty(); + case ObjType::None: + return false; - template - typename std::enable_if::value, ObjPtr>::type - static CreateValue(T value, ObjType fix_type = ObjType::None) { - ObjPtr result = CreateType(fix_type); - result->m_var_type_fixed = fix_type; - result->m_var_type_current = typeFromLimit((double) value); - if (fix_type != ObjType::None) { - NL_CHECK(canCast(result->m_var_type_current, fix_type), - "Fail cast type from '%s' to '%s'!", newlang::toString(result->m_var_type_current), newlang::toString(fix_type)); - } - result->m_value = torch::scalar_tensor(value, toTorchType(result->m_var_type_current)); - result->m_var_is_init = true; - return result; - } + case ObjType::Fraction: + ASSERT(m_fraction); + return m_fraction->GetAsInteger(); - static ObjPtr CreateString(const std::string str) { - ObjPtr result = CreateType(ObjType::StrChar); - result->m_str = str; - result->m_var_type_fixed = ObjType::String; - result->m_var_is_init = true; - return result; - } + case ObjType::Dictionary: + case ObjType::Class: + if (size()) { + return true; + } + for (auto &elem : m_class_parents) { + if (elem->GetValueAsBoolean()) { + return true; + } + } + return false; - static ObjPtr CreateString(const std::wstring str) { - ObjPtr result = CreateType(ObjType::StrWide); - result->m_wstr = str; - result->m_var_type_fixed = ObjType::String; - result->m_var_is_init = true; - return result; + default: + LOG_RUNTIME("Type cast to bool %s", toString().c_str()); + } + return true; } + } - inline static ObjPtr Yes() { - ObjPtr result = std::make_shared(ObjType::Bool); - bool value = true; - result->m_value = torch::scalar_tensor(value); - result->m_var_is_init = true; - return result->MakeConst(); + at::Scalar toTorchScalar() { + at::Scalar result; + if (is_integer() || is_bool_type()) { + result = at::Scalar(GetValueAsInteger()); + } else if (is_floating()) { + result = at::Scalar(GetValueAsNumber()); + } else { + LOG_RUNTIME("Not support Torch ScalarType '%s'", newlang::toString(m_var_type_current)); } + return result; - inline static ObjPtr No() { - ObjPtr result = std::make_shared(ObjType::Bool); - bool value = false; - result->m_value = torch::scalar_tensor(value); - result->m_var_is_init = true; - return result->MakeConst(); - } + } - inline static ObjPtr CreateDict() { - return Obj::CreateType(ObjType::Dictionary); - } + static ObjPtr CreateType(ObjType type, ObjType fixed = ObjType::None, bool is_init = false) { + return std::make_shared(type, nullptr, nullptr, fixed, is_init); + } - template - typename std::enable_if::value, ObjPtr>::type - static CreateDict(T ... args) { - std::array < PairType, sizeof...(args) > list = {args...}; - ObjPtr result = Obj::CreateType(ObjType::Dictionary); - for (auto &elem : list) { - result->push_back(elem); - } - result->m_var_is_init = true; - return result; - } + static ObjPtr CreateFraction(const std::string_view val) { - inline static ObjPtr CreateClass(std::string name) { - ObjPtr result = Obj::CreateType(ObjType::Class); - result->m_class_name = name; - result->m_var_is_init = true; - return result; - } + std::string str; + std::remove_copy(val.begin(), val.end(), back_inserter(str), '_'); - template - typename std::enable_if::value, ObjPtr>::type - static CreateClass(std::string name, T ... args) { - std::array < PairType, sizeof...(args) > list = {args...}; - ObjPtr result = Obj::CreateType(ObjType::Class); - result->m_class_name = name; - for (auto &elem : list) { - result->push_back(elem); - } - result->m_var_is_init = true; - return result; + if (str.empty()) { + LOG_RUNTIME("Empty string!"); } + ObjPtr frac = Obj::CreateType(ObjType::Fraction); - ObjPtr CallNative(Context *ctx, Obj args); + // Ищем разделитель дроби + size_t pos = str.find("\\"); - ObjPtr Clone(const char *new_name = nullptr) const { - ObjPtr clone = Obj::CreateNone(); - CloneDataTo(*clone); - ClonePropTo(*clone); - if (new_name) { - clone->m_var_name = new_name; + // Если символ не найден - то вся строка является числом + if (pos == std::string::npos) { + frac->m_fraction = std::make_shared(str, "1"); + } else { + // Числитель - левая часть + // Знаменатель - правая часть + frac->m_fraction = std::make_shared(str.substr(0, pos), str.substr(pos + 1, str.length())); + // Знаменатель не должен быть равен нулю + if (frac->m_fraction->m_denominator.isZero()) { + LOG_RUNTIME("Denominator must be different from zero!"); } - clone->m_is_const = false; - clone->m_ref_count = 0; - return clone; } - inline void CloneTo(Obj & clone) { - if (&clone == this) { - // Не клонировать сам в себя - return; - } - CloneDataTo(clone); - ClonePropTo(clone); + frac->m_var_is_init = true; + if (str.compare(frac->m_fraction->GetAsString().c_str()) != 0) { + LOG_RUNTIME("Fraction value '%s' does not match source string '%s'!", frac->m_fraction->GetAsString().c_str(), str.c_str()); } - inline void CloneTo(ObjPtr & clone) { - if (clone.get() == this) { - // Не клонировать сам в себя - return; - } - clone.reset(); - clone = Obj::CreateNone(); - CloneDataTo(*clone); - ClonePropTo(*clone); - } + return frac; + } - void CloneDataTo(Obj & clone) const; - void ClonePropTo(Obj & clone) const; - virtual ~Obj() { - // Clear(); - } + // чистая функция + static ObjPtr BaseTypeConstructor(const Context *ctx, Obj &in); + static ObjPtr ConstructorSimpleType_(const Context *ctx, Obj & args); + static ObjPtr ConstructorDictionary_(const Context *ctx, Obj & args); + static ObjPtr ConstructorNative_(const Context *ctx, Obj & args); + static ObjPtr ConstructorClass_(const Context *ctx, Obj & args); + static ObjPtr ConstructorStruct_(const Context *ctx, Obj & args); + static ObjPtr ConstructorEnum_(const Context *ctx, Obj & args); - ObjPtr toType(ObjType target) const { - ObjPtr result = Clone(); - result->toType_(target); - return result; - } + static ObjPtr ConstructorError_(const Context *ctx, Obj & args); + static ObjPtr ConstructorReturn_(const Context *ctx, Obj & args); + static ObjPtr ConstructorInterraption_(const Context *ctx, Obj & args, ObjType type); - ObjPtr toType_(Obj *type); - void toType_(ObjType type); + static ObjPtr CreateBaseType(ObjType type); - ObjPtr toShape(ObjPtr dims) const { - ObjPtr result = Clone(); - result->toShape_(dims); - return result; - } - ObjPtr toShape_(ObjPtr shape); + static ObjPtr CreateNone() { + return CreateType(ObjType::None, ObjType::None, true); + } - ObjPtr Convert(ObjType type, ObjPtr shape = nullptr) const { - ObjPtr result = Clone(); - result->Convert_(type, shape); - return result; - } + template + static ObjPtr CreateRange(T1 start, T2 stop, T3 step) { + ObjPtr obj = CreateType(ObjType::Range); + obj->push_back(CreateValue(start, ObjType::None), "start"); + obj->push_back(CreateValue(stop, ObjType::None), "stop"); + obj->push_back(CreateValue(step, ObjType::None), "step"); + obj->m_var_is_init = true; + return obj; + } - ObjPtr Convert_(ObjType type, ObjPtr shape = nullptr) { - if (shape) { - toShape_(shape); - } - toType_(type); - return shared(); - } + template + static ObjPtr CreateRange(T1 start, T2 stop) { + ObjPtr obj = CreateType(ObjType::Range); + obj->push_back(CreateValue(start, ObjType::None), "start"); + obj->push_back(CreateValue(stop, ObjType::None), "stop"); + if (start < stop) { + obj->push_back(CreateValue(1, ObjType::None), "step"); + } else { + obj->push_back(CreateValue(-1, ObjType::None), "step"); + } + obj->m_var_is_init = true; + return obj; + } - const ObjPtr index_get(const std::vector & index) const; + static ObjType GetType(torch::Tensor & val) { + switch (val.dtype().toScalarType()) { + case at::ScalarType::Bool: + return ObjType::Bool; + case at::ScalarType::Half: + case at::ScalarType::BFloat16: + case at::ScalarType::Float: + return ObjType::Float; + case at::ScalarType::Double: + return ObjType::Double; + case at::ScalarType::Byte: + case at::ScalarType::Char: + case at::ScalarType::QInt8: + case at::ScalarType::QUInt8: + case at::ScalarType::QUInt4x2: + return ObjType::Char; + case at::ScalarType::Short: + return ObjType::Short; + case at::ScalarType::Int: + case at::ScalarType::QInt32: + return ObjType::Int; + case at::ScalarType::Long: + return ObjType::Long; + case at::ScalarType::ComplexHalf: + case at::ScalarType::ComplexFloat: + return ObjType::ComplexFloat; + case at::ScalarType::ComplexDouble: + return ObjType::ComplexDouble; + } + LOG_RUNTIME("Fail tensor type %s", val.toString().c_str()); + } - inline ObjPtr index_set(const std::vector & index, const ObjPtr value) const { - ObjPtr result = Clone(); - result->index_set_(index, value); - return result; - } - ObjPtr index_set_(const std::vector & index, const ObjPtr value); + static ObjPtr CreateBool(bool value) { + ObjPtr result = CreateType(ObjType::None); + result->m_value = torch::scalar_tensor(value, torch::Dtype::Bool); + result->m_var_type_current = ObjType::Bool; + result->m_var_is_init = true; + return result; + } - inline ObjPtr op_set_index(ObjPtr index, ObjPtr value) { - return op_set_index(index->GetValueAsInteger(), value->GetValueAsString()); + static ObjPtr CreateTensor(torch::Tensor tensor) { + ObjType check_type = GetType(tensor); + if (!isTensor(check_type)) { + LOG_RUNTIME("Unsupport torch type %s (%d)!", at::toString(tensor.dtype().toScalarType()), (int) tensor.dtype().toScalarType()); } - ObjPtr op_set_index(int64_t index, std::string value); - - template < typename T> - typename std::enable_if::value, void>::type - SetValue_(bool value) { + ObjPtr result = CreateType(check_type); + result->m_value = tensor; + result->m_var_is_init = true; + return result; + } - TEST_CONST_(); + static ObjPtr CreateTensor(ObjPtr data, ObjType type) { + torch::Tensor var = ConvertToTensor(data.get(), toTorchType(type), false); + // ConvertToTensor(data->index_get({0}).get(), type, false); + return CreateTensor(var); + } - ASSERT(m_var_type_current != ObjType::Class); - clear_(); - m_value = torch::scalar_tensor(value, torch::Dtype::Bool); - m_var_type_current = GetType(m_value); - m_var_is_init = true; - } + inline torch::Tensor toTensor() { + return ConvertToTensor(this); + } - template < typename T> - typename std::enable_if::value, void>::type - SetValue_(T value) { - TEST_CONST_(); - ASSERT(m_var_type_current != ObjType::Class); - clear_(); - m_value = torch::scalar_tensor(value, toTorchType(typeFromLimit((int64_t) value))); - m_var_type_current = GetType(m_value); - m_var_is_init = true; - } + inline torch::Tensor & asTensor_() { + NL_CHECK(is_tensor(), "Fail type as Tensor"); + return m_value; + } - template < typename T> - typename std::enable_if::value, void>::type - SetValue_(T value) { + at::indexing::Slice toSlice() { + NL_CHECK(is_range(), "Convert to slice supported for range only!"); - TEST_CONST_(); - ASSERT(m_var_type_current != ObjType::Class); - clear_(); - m_value = torch::scalar_tensor(value, toTorchType(typeFromLimit(value))); - m_var_type_current = GetType(m_value); - m_var_is_init = true; - } + ASSERT(size() == 3 && Variable::at("start").second && Variable::at("stop").second && Variable::at("step").second); - template < typename T> - typename std::enable_if::value, void>::type - SetValue_(T text) { - std::string str(text); - SetValue_(text); - } + NL_CHECK(Variable::at("start").second->is_integer(), "Slice value start support integer type only!"); + NL_CHECK(Variable::at("stop").second->is_integer(), "Slice value stop support integer type only!"); + NL_CHECK(Variable::at("step").second->is_integer(), "Slice value step support integer type only!"); - template < typename T> - typename std::enable_if::value, void>::type - SetValue_(T text) { - std::wstring str(text); - SetValue_(text); - } + return at::indexing::Slice( + Variable::at("start").second->GetValueAsInteger(), + Variable::at("stop").second->GetValueAsInteger(), + Variable::at("step").second->GetValueAsInteger()); + } - void SetValue_(std::string text) { - TEST_CONST_(); - if (m_var_type_current != ObjType::StrChar) { - testConvertType(ObjType::StrChar); - m_var_type_current = ObjType::StrChar; + /* + * From TensorIndexing.h +// There is one-to-one correspondence between Python and C++ tensor index types: +// Python | C++ +// ----------------------------------------------------- +// `None` | `at::indexing::None` +// `Ellipsis` | `at::indexing::Ellipsis` +// `...` | `"..."` +// `123` | `123` +// `True` / `False` | `true` / `false` +// `:` | `Slice()` / `Slice(None, None)` +// `::` | `Slice()` / `Slice(None, None, None)` +// `1:` | `Slice(1, None)` +// `1::` | `Slice(1, None, None)` +// `:3` | `Slice(None, 3)` +// `:3:` | `Slice(None, 3, None)` +// `::2` | `Slice(None, None, 2)` +// `1:3` | `Slice(1, 3)` +// `1::2` | `Slice(1, None, 2)` +// `:3:2` | `Slice(None, 3, 2)` +// `1:3:2` | `Slice(1, 3, 2)` +// `torch.tensor([1, 2])`) | `torch::tensor({1, 2})` + */ + Index toIndex() { + if (is_none_type()) { + return Index(c10::nullopt); + } else if (is_dictionary_type()) { + std::vector temp = toIntVector(true); + if (temp.size()) { + torch::Tensor tensor = torch::from_blob(temp.data(), temp.size(), torch::Dtype::Long); + return Index(tensor.clone()); + } else { + return Index(c10::nullopt); } - m_str.swap(text); - m_var_is_init = true; - } - void SetValue_(std::wstring text) { - TEST_CONST_(); - if (m_var_type_current != ObjType::StrWide) { - testConvertType(ObjType::StrWide); - m_var_type_current = ObjType::StrWide; - } - m_wstr.swap(text); - m_var_is_init = true; - } + } else if (is_scalar()) { + switch (m_var_type_current) { + case ObjType::Bool: + return Index(GetValueAsBoolean()); - inline void testConvertType(ObjType type) { - if (m_var_type_fixed == ObjType::None || canCast(type, m_var_type_fixed)) { - return; + case ObjType::Char: + case ObjType::Short: + case ObjType::Int: + case ObjType::Long: + return Index(GetValueAsInteger()); + default: + LOG_RUNTIME("Fail convert scalar type '%s' to Index!", newlang::toString(m_var_type_current)); } - LOG_RUNTIME("Cannot changed type from '%s' to '%s'!", newlang::toString(type), newlang::toString(m_var_type_fixed)); - } + } else if (is_tensor()) { + return Index(m_value); + } else if (is_ellipsis()) { + return Index(at::indexing::Ellipsis); + } else if (is_range()) { + return Index(toSlice()); + } + LOG_RUNTIME("Fail convert object '%s' to Index!", toString().c_str()); + } - inline void testResultIntegralType(ObjType type, bool upscalint) { - ObjType new_type = m_var_type_current; - if (!canCast(type, m_var_type_current)) { - testConvertType(type); - new_type = type; - } - bool check = false; - if (upscalint && isIntegralType(m_var_type_current, true) && isIntegralType(type, true)) { - if (type < ObjType::Long) { - new_type = static_cast (static_cast (type) + 1); - check = true; - } - if (check && m_var_type_fixed != ObjType::None && !canCast(new_type, m_var_type_fixed)) { - new_type = type; // Тип данных менять нельзя, но сама операция возможна - LOG_WARNING("Data type '%s' cannot be changed to '%s', loss of precision is possible!", newlang::toString(type), newlang::toString(m_var_type_fixed)); - } - } - if (new_type != m_var_type_current) { - m_value = m_value.toType(toTorchType(new_type)); - m_var_type_current = new_type; + inline operator bool () const { + return GetValueAsBoolean(); + } + + inline operator at::Tensor() { + return ConvertToTensor(this); + } + + inline operator at::TensorOptions() const { + return ConvertToTensorOptions(this); + } + + inline operator at::DimnameList() const { + return ConvertToDimnameList(this); + } + + std::vector toIntVector(bool raise = true) const { + std::vector result; + for (int i = 0; i < size(); i++) { + if (raise && !at(i).second->is_integer()) { + LOG_RUNTIME("Item does not contain an integer value! '%s'", at(i).second->GetValueAsString().c_str()); } + result.push_back(at(i).second->GetValueAsInteger()); } + return result; + } - void SetValue_(ObjPtr value) { - TEST_CONST_(); - if (value->is_none_type()) { - clear_(); - return; - } else if ((is_none_type() || is_tensor()) && value->is_tensor()) { - if (value->empty()) { - m_value.reset(); - m_var_is_init = false; - return; - } + // ПЕРЕКРЫВАЕТ ДРУГИЕ МЕТОДЫ !!!!!!!!!!!!!! at::TensorOptions() + // inline operator std::string () const { + // return GetValueAsString(); + // } - if (!canCast(value->m_var_type_current, m_var_type_current)) { - testConvertType(value->m_var_type_current); - toType_(value->getType()); - } - if (is_none_type()) { - m_value = value->m_value; - m_var_type_current = value->m_var_type_current; - } else { + template + typename std::enable_if::value, ObjPtr>::type + static CreateValue(T value, ObjType fix_type = ObjType::None) { + ObjPtr result = CreateType(fix_type); + result->m_var_type_fixed = fix_type; + result->m_var_type_current = typeFromLimit((int64_t) value); + if (fix_type != ObjType::None) { + NL_CHECK(canCast(result->m_var_type_current, fix_type), + "Fail cast type from '%s' to '%s'!", newlang::toString(result->m_var_type_current), newlang::toString(fix_type)); + } + result->m_value = torch::scalar_tensor(value, toTorchType(result->m_var_type_current)); + result->m_var_is_init = true; + return result; + } - if (m_value.dim() == 0 && value->m_value.dim() != 0) { - LOG_RUNTIME("Fail assign tensor to scalar!"); - } - if (!m_var_is_init) { - m_value = value->m_value.clone(); - } else { - if (!m_value.sizes().equals(value->m_value.sizes()) && value->m_value.dim() != 0) { - LOG_RUNTIME("Different sizes of tensors!"); - } else { - setTensorValue(m_value, value->m_value); - } - } - } - m_var_is_init = true; - return; - } else if ((is_none_type() || is_string_type()) && value->is_string_type()) { - - switch (m_var_type_current) { - case ObjType::None: - case ObjType::StrChar: - SetValue_(value->m_str); - return; - case ObjType::StrWide: - SetValue_(value->m_wstr); - return; - } + template + typename std::enable_if::value, ObjPtr>::type + static CreateValue(T value, ObjType fix_type = ObjType::None) { + ObjPtr result = CreateType(fix_type); + result->m_var_type_fixed = fix_type; + result->m_var_type_current = typeFromLimit((double) value); + if (fix_type != ObjType::None) { + NL_CHECK(canCast(result->m_var_type_current, fix_type), + "Fail cast type from '%s' to '%s'!", newlang::toString(result->m_var_type_current), newlang::toString(fix_type)); + } + result->m_value = torch::scalar_tensor(value, toTorchType(result->m_var_type_current)); + result->m_var_is_init = true; + return result; + } - } else if (is_none_type() || isObjectType(m_var_type_current)) { - std::string old_name = m_var_name; - clear_(); - value->CloneDataTo(*this); - value->ClonePropTo(*this); - m_var_name.swap(old_name); - m_var_is_init = true; + static ObjPtr CreateString(const std::string str) { + ObjPtr result = CreateType(ObjType::StrChar); + result->m_str = str; + result->m_var_type_fixed = ObjType::String; + result->m_var_is_init = true; + return result; + } - return; - } else if ((is_none_type() || m_var_type_current == ObjType::Pointer) && value->m_var_type_current == ObjType::Pointer) { - //@todo Check tree type !!! + static ObjPtr CreateString(const std::wstring str) { + ObjPtr result = CreateType(ObjType::StrWide); + result->m_wstr = str; + result->m_var_type_fixed = ObjType::String; + result->m_var_is_init = true; + return result; + } - std::string old_name = m_var_name; - value->CloneDataTo(*this); - value->ClonePropTo(*this); - m_var_name.swap(old_name); - m_var_is_init = true; + inline static ObjPtr Yes() { + ObjPtr result = std::make_shared(ObjType::Bool); + bool value = true; + result->m_value = torch::scalar_tensor(value); + result->m_var_is_init = true; + return result->MakeConst(); + } - return; - } else if ((is_none_type() || m_var_type_current == ObjType::Function) && value->is_function()) { - //@todo Check function type args !!! + inline static ObjPtr No() { + ObjPtr result = std::make_shared(ObjType::Bool); + bool value = false; + result->m_value = torch::scalar_tensor(value); + result->m_var_is_init = true; + return result->MakeConst(); + } - std::string old_name = m_var_name; - value->CloneDataTo(*this); - value->ClonePropTo(*this); - m_var_name.swap(old_name); - m_var_is_init = true; + inline static ObjPtr CreateDict() { + return Obj::CreateType(ObjType::Dictionary); + } - return; - } else if ((is_none_type() || m_var_type_current == ObjType::Function || m_var_type_current == ObjType::EVAL_FUNCTION) && (value->m_var_type_current == ObjType::BLOCK || value->m_var_type_current == ObjType::BLOCK_TRY)) { - //@todo Check function type args !!! - - // std::string old_name = m_var_name; - // TermPtr save_proto = m_func_proto; - // TermPtr save_block = m_block_source; - // ObjType save_type = m_var_type_current; - // value->CloneDataTo(*this); - // value->ClonePropTo(*this); - // m_var_name.swap(old_name); - // m_var_is_init = true; - // *const_cast (&m_func_proto) = save_proto; - m_block_source = value->m_block_source; - // m_var_type_current = save_type; + template + typename std::enable_if::value, ObjPtr>::type + static CreateDict(T ... args) { + std::array < PairType, sizeof...(args) > list = {args...}; + ObjPtr result = Obj::CreateType(ObjType::Dictionary); + for (auto &elem : list) { + result->push_back(elem); + } + result->m_var_is_init = true; + return result; + } - return; - } + inline static ObjPtr CreateClass(std::string name) { + ObjPtr result = Obj::CreateType(ObjType::Class); + result->m_class_name = name; + result->m_var_is_init = true; + return result; + } - LOG_RUNTIME("Set value type '%s' not implemented!", newlang::toString(m_var_type_current)); - } + template + typename std::enable_if::value, ObjPtr>::type + static CreateClass(std::string name, T ... args) { + std::array < PairType, sizeof...(args) > list = {args...}; + ObjPtr result = Obj::CreateType(ObjType::Class); + result->m_class_name = name; + for (auto &elem : list) { + result->push_back(elem); + } + result->m_var_is_init = true; + return result; + } - static std::string format(std::string format, Obj *args); - void clear_() override { + ObjPtr CallNative(Context *ctx, Obj args); - Variable::clear_(); - clear_(true); + ObjPtr Clone(const char *new_name = nullptr) const { + ObjPtr clone = Obj::CreateNone(); + CloneDataTo(*clone); + ClonePropTo(*clone); + if (new_name) { + clone->m_var_name = new_name; } + clone->m_is_const = false; + clone->m_ref_count = 0; + return clone; + } - void clear_(bool clear_iterator_name) { - - m_str.clear(); - m_wstr.clear(); - m_var_type_current = ObjType::None; + inline void CloneTo(Obj & clone) { + if (&clone == this) { + // Не клонировать сам в себя + return; + } + CloneDataTo(clone); + ClonePropTo(clone); + } - m_class_parents.clear(); - m_var_is_init = false; - m_value.reset(); - m_fraction.reset(); - // m_var = std::monostate(); - // m_value.reset(); //???????????????? - // m_items.clear(); + inline void CloneTo(ObjPtr & clone) { + if (clone.get() == this) { + // Не клонировать сам в себя + return; } + clone.reset(); + clone = Obj::CreateNone(); + CloneDataTo(*clone); + ClonePropTo(*clone); + } + void CloneDataTo(Obj & clone) const; + void ClonePropTo(Obj & clone) const; - bool CallAll(const char *func_name, ObjPtr &arg_in, ObjPtr &result, ObjPtr object = nullptr, size_t limit = 0); // ? - bool CallOnce(ObjPtr &arg_in, ObjPtr &result, ObjPtr object = nullptr); // ! + virtual ~Obj() { + // Clear(); + } + ObjPtr toType(ObjType target) const { + ObjPtr result = Clone(); + result->toType_(target); + return result; + } - static ObjPtr CreateFunc(Context *ctx, TermPtr proto, ObjType type, const std::string var_name = ""); - static ObjPtr CreateFunc(std::string proto, FunctionType *func_addr, ObjType type = ObjType::Function); + ObjPtr toType_(Obj *type); + void toType_(ObjType type); - ObjPtr ConvertToArgs(Obj *args, bool check_valid, Context *ctx) const { - ObjPtr result = Clone(); - result->ConvertToArgs_(args, check_valid, ctx); + ObjPtr toShape(ObjPtr dims) const { + ObjPtr result = Clone(); + result->toShape_(dims); + return result; + } + ObjPtr toShape_(ObjPtr shape); - return result; - } + ObjPtr Convert(ObjType type, ObjPtr shape = nullptr) const { + ObjPtr result = Clone(); + result->Convert_(type, shape); + return result; + } - void CheckArgsValid() const; - bool CheckArgs() const; + ObjPtr Convert_(ObjType type, ObjPtr shape = nullptr) { + if (shape) { + toShape_(shape); + } + toType_(type); + return shared(); + } - inline const TermPtr Proto() { + const ObjPtr index_get(const std::vector & index) const; - return m_func_proto; - } + inline ObjPtr index_set(const std::vector & index, const ObjPtr value) const { + ObjPtr result = Clone(); + result->index_set_(index, value); + return result; + } + ObjPtr index_set_(const std::vector & index, const ObjPtr value); - protected: + inline ObjPtr op_set_index(ObjPtr index, ObjPtr value) { + return op_set_index(index->GetValueAsInteger(), value->GetValueAsString()); + } + ObjPtr op_set_index(int64_t index, std::string value); - void ConvertToArgs_(Obj *args, bool check_valid, Context *ctx = nullptr); // Обновить параметры для вызова функции или элементы у словаря при создании копии + template < typename T> + typename std::enable_if::value, void>::type + SetValue_(bool value) { - public: + TEST_CONST_(); - ObjType m_var_type_current; ///< Текущий тип значения объекта - ObjType m_var_type_fixed; ///< Максимальный размер для арифметических типов, который задается разработчиком - bool m_var_is_init; ///< Содержит ли объект корректное значение ??? + ASSERT(m_var_type_current != ObjType::Class); + clear_(); + m_value = torch::scalar_tensor(value, torch::Dtype::Bool); + m_var_type_current = GetType(m_value); + m_var_is_init = true; + } - // struct FuncInfo { - // const TermPtr m_func_proto; - // std::string m_func_mangle_name; - // void *m_func_ptr; - // ffi_abi m_func_abi; - // }; - // std::variant m_var; + template < typename T> + typename std::enable_if::value, void>::type + SetValue_(T value) { + TEST_CONST_(); + ASSERT(m_var_type_current != ObjType::Class); + clear_(); + m_value = torch::scalar_tensor(value, toTorchType(typeFromLimit((int64_t) value))); + m_var_type_current = GetType(m_value); + m_var_is_init = true; + } + template < typename T> + typename std::enable_if::value, void>::type + SetValue_(T value) { - std::string m_var_name; ///< Имя переменной, в которой хранится объект + TEST_CONST_(); + ASSERT(m_var_type_current != ObjType::Class); + clear_(); + m_value = torch::scalar_tensor(value, toTorchType(typeFromLimit(value))); + m_var_type_current = GetType(m_value); + m_var_is_init = true; + } - ObjPtr m_dimensions; ///< Размерности для ObjType::Type - std::string m_class_name; ///< Имя класса объекта (у базовых типов отсуствует) - std::vector m_class_parents; ///< Родительские классы (типы) + template < typename T> + typename std::enable_if::value, void>::type + SetValue_(T text) { + std::string str(text); + SetValue_(text); + } - std::string m_namespace; - std::string m_str; - std::wstring m_wstr; - mutable PairType m_str_pair; //< Для доступа к отдельным символам строк + template < typename T> + typename std::enable_if::value, void>::type + SetValue_(T text) { + std::wstring str(text); + SetValue_(text); + } - const TermPtr m_func_proto; - std::string m_func_mangle_name; - std::string m_module_name; - void *m_func_ptr; - ffi_abi m_func_abi; - torch::Tensor m_value; - std::shared_ptr m_fraction; + void SetValue_(std::string text) { + TEST_CONST_(); + if (m_var_type_current != ObjType::StrChar) { + testConvertType(ObjType::StrChar); + m_var_type_current = ObjType::StrChar; + } + m_str.swap(text); + m_var_is_init = true; + } - TermPtr m_block_source; - bool m_check_args; //< Проверять аргументы на корректность (для всех видов функций) @ref MakeArgs + void SetValue_(std::wstring text) { + TEST_CONST_(); + if (m_var_type_current != ObjType::StrWide) { + testConvertType(ObjType::StrWide); + m_var_type_current = ObjType::StrWide; + } + m_wstr.swap(text); + m_var_is_init = true; + } - // Context *m_ctx; + inline void testConvertType(ObjType type) { + if (m_var_type_fixed == ObjType::None || canCast(type, m_var_type_fixed)) { + return; + } + LOG_RUNTIME("Cannot changed type from '%s' to '%s'!", newlang::toString(type), newlang::toString(m_var_type_fixed)); + } + inline void testResultIntegralType(ObjType type, bool upscalint) { + ObjType new_type = m_var_type_current; + if (!canCast(type, m_var_type_current)) { + testConvertType(type); + new_type = type; + } + bool check = false; + if (upscalint && isIntegralType(m_var_type_current, true) && isIntegralType(type, true)) { + if (type < ObjType::Long) { + new_type = static_cast (static_cast (type) + 1); + check = true; + } + if (check && m_var_type_fixed != ObjType::None && !canCast(new_type, m_var_type_fixed)) { + new_type = type; // Тип данных менять нельзя, но сама операция возможна + LOG_WARNING("Data type '%s' cannot be changed to '%s', loss of precision is possible!", newlang::toString(type), newlang::toString(m_var_type_fixed)); + } + } + if (new_type != m_var_type_current) { + m_value = m_value.toType(toTorchType(new_type)); + m_var_type_current = new_type; + } + } - // SCOPE(protected) : - bool m_is_const; //< Признак константы (по умолчанию изменения разрешено) - bool m_is_reference; //< Признак ссылки на объект (mutable) - size_t m_ref_count; + void SetValue_(ObjPtr value) { + TEST_CONST_(); + if (value->is_none_type()) { + clear_(); + return; + } else if ((is_none_type() || is_tensor()) && value->is_tensor()) { + if (value->empty()) { + m_value.reset(); + m_var_is_init = false; + return; + } - }; + if (!canCast(value->m_var_type_current, m_var_type_current)) { + testConvertType(value->m_var_type_current); + toType_(value->getType()); + } + if (is_none_type()) { + m_value = value->m_value; + m_var_type_current = value->m_var_type_current; + } else { + if (m_value.dim() == 0 && value->m_value.dim() != 0) { + LOG_RUNTIME("Fail assign tensor to scalar!"); + } + if (!m_var_is_init) { + m_value = value->m_value.clone(); + } else { + if (!m_value.sizes().equals(value->m_value.sizes()) && value->m_value.dim() != 0) { + LOG_RUNTIME("Different sizes of tensors!"); + } else { + setTensorValue(m_value, value->m_value); + } + } + } + m_var_is_init = true; + return; + } else if ((is_none_type() || is_string_type()) && value->is_string_type()) { - /* - * Требуется разделять конейнеры с данными и итераторы по данным. - * В С++ контейнеры предоставялют итераторы непосредственно из самого контейнера. - * Это удобно для использования в рукописном коде, но сложно контроллировать в генерируемом исходнике, - * т.к. требуется использовать и итертор и сам контейнер с данными (для сравнения с end()). - * - * Логика работы с итераторами следующая. - * Итератор - отдельный объект, которому для создания требуется контейнер с данными. - * Итератор два интерфейса перебора данных: - * 1. - первый интерфейс итератора как в С++ - * 2. - второй интерфейс для использования в генерируемом коде с логикой NewLang - * - * Разделение контейнера и итератора на два объекта позволит выполнять проверку на использование - * - */ + switch (m_var_type_current) { + case ObjType::None: + case ObjType::StrChar: + SetValue_(value->m_str); + return; + case ObjType::StrWide: + SetValue_(value->m_wstr); + return; + } - /* - * Итератор - */ - template - class Iterator : public std::iterator { - public: + } else if (is_none_type() || isObjectType(m_var_type_current)) { + std::string old_name = m_var_name; + clear_(); + value->CloneDataTo(*this); + value->ClonePropTo(*this); + m_var_name.swap(old_name); + m_var_is_init = true; - enum class IterCmp : int8_t { - No = static_cast (ObjType::None), /* skip data */ - Yes = static_cast (ObjType::Iterator), /* return data */ - End = static_cast (ObjType::IteratorEnd), /* iterator complete */ - }; + return; + } else if ((is_none_type() || m_var_type_current == ObjType::Pointer) && value->m_var_type_current == ObjType::Pointer) { + //@todo Check tree type !!! - STATIC_ASSERT(static_cast (IterCmp::Yes)); - STATIC_ASSERT(!static_cast (IterCmp::No)); + std::string old_name = m_var_name; + value->CloneDataTo(*this); + value->ClonePropTo(*this); + m_var_name.swap(old_name); + m_var_is_init = true; - typedef Iterator iterator; - typedef Iterator const_iterator; + return; + } else if ((is_none_type() || m_var_type_current == ObjType::Function) && value->is_function()) { + //@todo Check function type args !!! - typedef Variable IterObj; - typedef typename Variable::Type IterObjPtr; - typedef typename Variable::PairType IterPairType; - typedef typename Variable::ListType IterListType; + std::string old_name = m_var_name; + value->CloneDataTo(*this); + value->ClonePropTo(*this); + m_var_name.swap(old_name); + m_var_is_init = true; + return; + } else if ((is_none_type() || m_var_type_current == ObjType::Function || m_var_type_current == ObjType::EVAL_FUNCTION) && (value->m_var_type_current == ObjType::BLOCK || value->m_var_type_current == ObjType::BLOCK_TRY)) { + //@todo Check function type args !!! - typedef IterCmp CompareFuncType(const IterPairType &pair, const T *args, void *extra); + // std::string old_name = m_var_name; + // TermPtr save_proto = m_func_proto; + // TermPtr save_block = m_block_source; + // ObjType save_type = m_var_type_current; + // value->CloneDataTo(*this); + // value->ClonePropTo(*this); + // m_var_name.swap(old_name); + // m_var_is_init = true; + // *const_cast (&m_func_proto) = save_proto; + m_block_source = value->m_block_source; + // m_var_type_current = save_type; - /** - * Итератор для элементов списка с regex фильтром по имени элемента (по умолчанию для всех элементов списка) - * @param obj - * @param find_key - */ - Iterator(T &obj, const std::string find_key = "(.|\\n)*") : - Iterator(obj, &CompareFuncDefault, reinterpret_cast (const_cast (&find_key)), static_cast (this)) { + return; } - /** - * Итератор для элементов списка с фильтром в виде функции обратного вызова - * @param obj - * @param func - * @param arg - * @param extra - */ - Iterator(T &obj, CompareFuncType *func, T *arg, void * extra = nullptr) : - m_iter_obj(obj), m_match(), m_func(func), m_func_args(arg), m_func_extra(extra), m_found(m_iter_obj.begin()) { - search_loop(); - } + LOG_RUNTIME("Set value type '%s' not implemented!", newlang::toString(m_var_type_current)); + } - Iterator(const Iterator &iter) : m_iter_obj(iter.m_iter_obj), m_match(iter.m_match), m_func(iter.m_func), - m_func_args(iter.m_func_args), m_func_extra(iter.m_func_extra), m_found(iter.m_found) { - } + static std::string format(std::string format, Obj *args); - SCOPE(private) : - T &m_iter_obj; - std::regex m_match; - std::string m_filter; - CompareFuncType *m_func; - T *m_func_args; - void *m_func_extra; + void clear_() override { - mutable typename Variable::iterator m_found; + Variable::clear_(); + clear_(true); + } - inline static const IterPairType m_interator_end = IterObj::pair(Obj::CreateType(ObjType::IteratorEnd, ObjType::IteratorEnd, true)); + void clear_(bool clear_iterator_name) { - static IterCmp CompareFuncDefault(const IterPairType &pair, const T *filter, void *extra) { - const std::string * str_filter = reinterpret_cast (filter); - Iterator * iter = static_cast (extra); - if (iter && str_filter) { + m_str.clear(); + m_wstr.clear(); + m_var_type_current = ObjType::None; - iter->m_func_args = nullptr; // Передается однократно при создании объекта - iter->m_filter = *str_filter; + m_class_parents.clear(); + m_var_is_init = false; + m_value.reset(); + m_fraction.reset(); + // m_var = std::monostate(); + // m_value.reset(); //???????????????? + // m_items.clear(); + } - if (!iter->m_filter.empty()) { - try { - iter->m_match = std::regex(iter->m_filter); - } catch (const std::regex_error &err) { - LOG_RUNTIME("Regular expression for '%s' error '%s'!", str_filter->c_str(), err.what()); - } - } - } - if (iter) { - if (iter->m_filter.empty()) { - return pair.first.empty() ? IterCmp::Yes : IterCmp::No; - } else { - return std::regex_match(pair.first, iter->m_match) ? IterCmp::Yes : IterCmp::No; - } - } - return IterCmp::Yes; - } + bool CallAll(const char *func_name, ObjPtr &arg_in, ObjPtr &result, ObjPtr object = nullptr, size_t limit = 0); // ? + bool CallOnce(ObjPtr &arg_in, ObjPtr &result, ObjPtr object = nullptr); // ! - public: - iterator begin() { - Iterator copy(*this); - copy.reset(); - return copy; - } + static ObjPtr CreateFunc(Context *ctx, TermPtr proto, ObjType type, const std::string var_name = ""); + static ObjPtr CreateFunc(std::string proto, FunctionType *func_addr, ObjType type = ObjType::Function); - iterator end() { - Iterator copy(*this); - copy.m_found = copy.m_iter_obj.end(); - return copy; - } + ObjPtr ConvertToArgs(Obj *args, bool check_valid, Context *ctx) const { + ObjPtr result = Clone(); + result->ConvertToArgs_(args, check_valid, ctx); - inline const IterPairType &operator*() { - if (m_found == m_iter_obj.end()) { - return m_interator_end; - } - return *m_found; - } + return result; + } - inline const IterPairType &operator*() const { - if (m_found == m_iter_obj.end()) { - return m_interator_end; - } - return *m_found; - } + void CheckArgsValid() const; + bool CheckArgs() const; - ObjPtr read_and_next(int64_t count); + inline const TermPtr Proto() { - const iterator &operator++() const { - if (m_found != m_iter_obj.end()) { - m_found++; - search_loop(); - } - return *this; - } + return m_func_proto; + } - inline const iterator operator++(int) const { - return iterator::operator++(); - } +protected: + void ConvertToArgs_(Obj *args, bool check_valid, Context *ctx = nullptr); // Обновить параметры для вызова функции или элементы у словаря при создании копии - inline bool operator==(const iterator &other) const { - return m_found == other.m_found; - } +public: - inline bool operator!=(const iterator &other) const { - return m_found != other.m_found; - } + ObjType m_var_type_current; ///< Текущий тип значения объекта + ObjType m_var_type_fixed; ///< Максимальный размер для арифметических типов, который задается разработчиком + bool m_var_is_init; ///< Содержит ли объект корректное значение ??? - inline void reset() { - m_found = m_iter_obj.begin(); - search_loop(); - } + // struct FuncInfo { + // const TermPtr m_func_proto; + // std::string m_func_mangle_name; + // void *m_func_ptr; + // ffi_abi m_func_abi; + // }; + // std::variant m_var; - protected: + std::string m_var_name; ///< Имя переменной, в которой хранится объект + + ObjPtr m_dimensions; ///< Размерности для ObjType::Type + std::string m_class_name; ///< Имя класса объекта (у базовых типов отсуствует) + std::vector m_class_parents; ///< Родительские классы (типы) + + std::string m_namespace; + std::string m_str; + std::wstring m_wstr; + mutable PairType m_str_pair; //< Для доступа к отдельным символам строк + + const TermPtr m_func_proto; + std::string m_func_mangle_name; + std::string m_module_name; + void *m_func_ptr; + ffi_abi m_func_abi; + torch::Tensor m_value; + std::shared_ptr m_fraction; + std::shared_ptr< Iterator > m_iterator; + + TermPtr m_block_source; + bool m_check_args; //< Проверять аргументы на корректность (для всех видов функций) @ref MakeArgs + + // Context *m_ctx; + + + // SCOPE(protected) : + bool m_is_const; //< Признак константы (по умолчанию изменения разрешено) + bool m_is_reference; //< Признак ссылки на объект (mutable) + size_t m_ref_count; - void search_loop() const { - while (m_found != m_iter_obj.end()) { - IterCmp result = IterCmp::Yes; - if (m_func) { - result = (*m_func)(*m_found, m_func_args, m_func_extra); - if (result == IterCmp::End) { - m_found = m_iter_obj.end(); - } - } - if (result != IterCmp::No) { - // IterCmp::Yes || IterCmp::End - return; - } - m_found++; - } - } - }; +}; } // namespace newlang diff --git a/src/test/object_test.cpp b/src/test/object_test.cpp index cb5e6f58..3bfdb06d 100644 --- a/src/test/object_test.cpp +++ b/src/test/object_test.cpp @@ -839,7 +839,7 @@ TEST(ObjTest, Iterator) { ASSERT_TRUE(std::regex_match("\n\n\\n", all)); - Iterator iter(*dict); + Iterator iter(dict); ASSERT_TRUE(iter == iter.begin()); ASSERT_TRUE(iter != iter.end()); @@ -961,32 +961,36 @@ TEST(ObjTest, Iterator) { - Iterator flt(*dict, ""); + Iterator flt(dict, ""); ObjPtr flt_res = flt.read_and_next(-100); ASSERT_TRUE(flt_res); ASSERT_EQ(1, flt_res->size()); ASSERT_EQ(4, flt_res->at(0).second->GetValueAsInteger()); - Iterator flt1(*dict, "."); + Iterator flt1(dict, "."); ObjPtr flt1_res = flt1.read_and_next(-100); ASSERT_TRUE(flt1_res); ASSERT_EQ(1, flt1_res->size()); ASSERT_EQ(1, flt1_res->at(0).second->GetValueAsInteger()); - Iterator flt2(*dict, ".."); + Iterator flt2(dict, ".."); ObjPtr flt2_res = flt2.read_and_next(-100); ASSERT_TRUE(flt2_res); ASSERT_EQ(1, flt2_res->size()); ASSERT_EQ(2, flt2_res->at(0).second->GetValueAsInteger()); - Iterator flt3(*dict, "..."); + Iterator flt3(dict, "..."); ObjPtr flt3_res = flt3.read_and_next(-100); ASSERT_TRUE(flt3_res); ASSERT_EQ(2, flt3_res->size()); ASSERT_EQ(3, flt3_res->at(0).second->GetValueAsInteger()); ASSERT_EQ(5, flt3_res->at(1).second->GetValueAsInteger()); + + + + ObjPtr iter1 = dict->MakeIterator(); } From 969921a67658be040a9bb77d5082c22a614d9745 Mon Sep 17 00:00:00 2001 From: Aleksandr Ryabikov Date: Sun, 10 Jul 2022 21:57:28 +0300 Subject: [PATCH 19/31] =?UTF-8?q?=D0=9E=D0=BF=D1=80=D0=B5=D0=B4=D0=B5?= =?UTF-8?q?=D0=BB=D0=B8=D0=BB=D0=B8=D1=81=D1=8F=20=D1=81=20=D0=BD=D0=B0?= =?UTF-8?q?=D0=B7=D0=BD=D0=B0=D1=87=D0=B5=D0=BD=D0=B8=D0=B5=D0=BC=20=D0=BE?= =?UTF-8?q?=D0=BF=D0=B5=D1=80=D0=B0=D1=82=D0=BE=D1=80=D0=BE=D0=B2=20=D1=83?= =?UTF-8?q?=20=D0=B8=D1=82=D1=80=D0=B0=D1=82=D0=BE=D1=80=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/lexer.l | 5 ++- src/object.cpp | 6 ++-- src/parser.y | 11 ++----- src/test/eval_test.cpp | 71 +++++++++++++++++++++++++++++++++++----- src/test/object_test.cpp | 34 ++++++++++--------- 5 files changed, 89 insertions(+), 38 deletions(-) diff --git a/src/lexer.l b/src/lexer.l index 0ddeca4a..cc14ee99 100644 --- a/src/lexer.l +++ b/src/lexer.l @@ -446,8 +446,11 @@ term [$@%]({ualpha}|[_])?({name})? ">=" YY_TOKEN(OPERATOR); ">" YY_TOKEN(OPERATOR); -"??" YY_TOKEN(ITERATOR_QQ); + "!!" YY_TOKEN(ITERATOR); +"??" YY_TOKEN(ITERATOR); +"?!" YY_TOKEN(ITERATOR); +"!?" YY_TOKEN(ITERATOR); /* gobble up white-spaces */ diff --git a/src/object.cpp b/src/object.cpp index 3c16e723..66e3d615 100644 --- a/src/object.cpp +++ b/src/object.cpp @@ -2932,10 +2932,10 @@ ObjPtr Iterator::read_and_next(int64_t count) { if(count == 0) { result = (*(*this)).second; (*this)++; - } else if(count > 0) { + } else if(count < 0) { result = Obj::CreateDict(); - for (int64_t i = 0; i < count; i++) { + for (int64_t i = 0; i < -count; i++) { if(*this != this->end()) { result->push_back(*(*this)); (*this)++; @@ -2945,7 +2945,6 @@ ObjPtr Iterator::read_and_next(int64_t count) { } } else { - count = -count; result = Obj::CreateDict(); while(*this != this->end() && result->size() < count) { result->push_back(*(*this)); @@ -2955,7 +2954,6 @@ ObjPtr Iterator::read_and_next(int64_t count) { return result; } - ObjPtr Obj::MakeIterator() { ObjPtr result = CreateType(ObjType::Iterator, ObjType::Iterator, true); result->m_iterator = std::make_shared> (shared()); diff --git a/src/parser.y b/src/parser.y index 4f9a7e2d..7b7d875c 100644 --- a/src/parser.y +++ b/src/parser.y @@ -379,8 +379,7 @@ star_arg = [STAR] STAR ID %token COMMENT %token SOURCE -%token ITERATOR "!!" -%token ITERATOR_QQ "??" +%token ITERATOR %token PUREFUNC %token SIMPLE_AND @@ -766,13 +765,11 @@ rval_var: rval_name | rval_name iter_all { $$ = $2; - $$->SetTermID(TermID::ITERATOR); $$->Last()->Append($1, Term::LEFT); } | rval_name iter_all call { $$ = $2; - $$->SetTermID(TermID::ITERATOR); $$->Last()->Append($1, Term::LEFT); $$->SetArgs($call); } @@ -817,11 +814,7 @@ iter_all: '!' { $$=$1; } - | ITERATOR_QQ - { - $$=$1; - $$->SetTermID(TermID::ITERATOR); - } + /* diff --git a/src/test/eval_test.cpp b/src/test/eval_test.cpp index d3a46767..21ee5571 100644 --- a/src/test/eval_test.cpp +++ b/src/test/eval_test.cpp @@ -582,8 +582,8 @@ TEST(ExecStr, Funcs) { printf_type ttt = (printf_type) p->m_func_ptr; ASSERT_EQ(7, (*ttt)("Test 1 ")); - ASSERT_EQ(18,(*ttt)("%s", "Test Variadic call")); - + ASSERT_EQ(18, (*ttt)("%s", "Test Variadic call")); + ObjPtr res = p->Call(&ctx, Obj::Arg(Obj::CreateString("Test"))); ASSERT_TRUE(res); ASSERT_TRUE(res->is_integer()); @@ -767,10 +767,10 @@ TEST(Eval, Convert) { ASSERT_TRUE(obj_float->m_var_is_init); ASSERT_STREQ("[\n [3, 4,], [1, 2,],\n]:Float", obj_float->GetValueAsString().c_str()); - - - - + + + + ObjPtr frac_0 = ctx.ExecStr("0\\1"); ASSERT_TRUE(frac_0); ASSERT_EQ(ObjType::Fraction, frac_0->getType()); @@ -798,8 +798,8 @@ TEST(Eval, Convert) { ASSERT_TRUE(obj_frac->m_var_is_init); ASSERT_STREQ("0\\1", obj_frac->GetValueAsString().c_str()); ASSERT_EQ(0, obj_frac->GetValueAsInteger()); - - + + // EXPECT_TRUE(dlsym(nullptr, "_ZN7newlang4CharEPKNS_7ContextERKNS_6ObjectE")); // EXPECT_TRUE(dlsym(nullptr, "_ZN7newlang6Short_EPNS_7ContextERNS_6ObjectE")); @@ -934,6 +934,59 @@ TEST(Eval, MacroDSL) { ASSERT_EQ(42, result->GetValueAsInteger()); } +TEST(Eval, Iterator) { + + + +} + +TEST(Eval, Brother) { + /* + * + * :Human := :Class(пол:Пол=_, родители = (,)); + * #!./dist/Debug/GNU-Linux/nlc --exec + * :Sex := :Enum(male, female); + * :Human := :Class(sex:Sex=, parent=(,)); + * @Tom := :Human(Sex.male); + * @Janna := :Human(Sex.female); + * @Jake := :Human(Sex.male, (Tom, Janna,)); + * @Tim := :Human(Sex.male, parent=(Tom,)); + * + * Brother(h1, h2) := $h1 != $h2, $h1.sex==male, $h1.parent * $h2.parent; + * printf := :Native("printf(format:Format, ...):Int"); + * + * + * h1 := $?; + * [ h1 ] <<-->> { + * h2 := $?; + * [ h2 ] <<-->> { + * [ Brother(h1!, h2!) ] --> { + * printf("%s brother %s", ""(h1), `h2`); + * } + * } + * } + * + * h1 := \iterator($); + * \while( h1 ) { + * h2 := \iterator($); + * \while( h2 } { + * \if( Brother(h1!, h2!) ) { + * result []= "$1 brother $2"(h1, h2); + * } + * } + * } + * --result--; + * + * >>> ("Tim brother Jake", "Jake brother Tim",) + * + * + * + */ + + + +} + class OpEvalTest : public ::testing::Test { protected: Context m_ctx; @@ -974,7 +1027,7 @@ TEST_F(OpEvalTest, Ops) { ASSERT_STREQ("5\\1", Test("4\\5 + 42\\10")); ASSERT_STREQ("11\\1", Test("10\\1 + 1")); ASSERT_STREQ("4\\3", Test("1\\3 + 1")); - + ASSERT_STREQ("-12", Test("10 - 22")); ASSERT_STREQ("-2.9", Test("1.1 - 4")); ASSERT_STREQ("-3.5", Test("1 - 4.5")); diff --git a/src/test/object_test.cpp b/src/test/object_test.cpp index 3bfdb06d..b0f0ec93 100644 --- a/src/test/object_test.cpp +++ b/src/test/object_test.cpp @@ -863,12 +863,16 @@ TEST(ObjTest, Iterator) { * * dict! и dict!(0) эквивалентны * dict! -> 1, dict! -> 2, dict! -> 3, dict! -> 4, dict! -> 5, dict! -> :IteratorEnd - * Различия отрицательного размера возвращаемого словаря - * dict!(1) -> (1,), dict!(1) -> (2,), dict!(1) -> (3,), dict!(1) -> (4,), dict!(1) -> (5,), dict!(1) -> (:IteratorEnd,), - * dict!(-1) -> (1,), dict!(-1) -> (2,), dict!(-1) -> (3,), dict!(-1) -> (4,), dict!(-1) -> (5,), dict!(-1) -> (,), - * dict!(3) -> (1, 2, 3,), dict!(3) -> (4, 5, :IteratorEnd,) - * dict!(-3) -> (1, 2, 3,), dict!(-3) -> (4, 5,) + * Различия отрицательного размера возвращаемого словаря для итератора + * dict!(-1) -> (1,), ... dict!(-1) -> (5,), dict!(-1) -> (:IteratorEnd,), + * dict!(1) -> (1,), ... dict!(1) -> (5,), dict!(1) -> (,), + * dict!(-3) -> (1, 2, 3,), dict!(-3) -> (4, 5, :IteratorEnd,) + * dict!(3) -> (1, 2, 3,), dict!(3) -> (4, 5,) * + * !? или ?! эквиваленты и создают итератор и сразу его выполняет, + * вовзращая все значения в виде элементов словаря, т.е. ?(LINQ); !(:Long.__max__) + * А зачем может быть нужен итератор "??" - может сброс в начальное состояние??? + * Итератор !! эквиваленетен вызову !(1) */ ASSERT_TRUE(iter == iter.begin()); @@ -913,21 +917,21 @@ TEST(ObjTest, Iterator) { ASSERT_TRUE(iter == iter.begin()); ASSERT_TRUE(iter != iter.end()); - ObjPtr dict1 = iter.read_and_next(3); + ObjPtr dict1 = iter.read_and_next(-3); ASSERT_TRUE(dict1); ASSERT_EQ(3, dict1->size()); ASSERT_EQ(1, dict1->at(0).second->GetValueAsInteger()); ASSERT_EQ(2, dict1->at(1).second->GetValueAsInteger()); ASSERT_EQ(3, dict1->at(2).second->GetValueAsInteger()); - ObjPtr dict2 = iter.read_and_next(3); + ObjPtr dict2 = iter.read_and_next(-3); ASSERT_TRUE(dict2); ASSERT_EQ(3, dict2->size()); ASSERT_EQ(4, dict2->at(0).second->GetValueAsInteger()); ASSERT_EQ(5, dict2->at(1).second->GetValueAsInteger()); ASSERT_EQ(ObjType::IteratorEnd, dict2->at(2).second->getType()); - ObjPtr dict3 = iter.read_and_next(3); + ObjPtr dict3 = iter.read_and_next(-3); ASSERT_TRUE(dict3); ASSERT_EQ(3, dict1->size()); ASSERT_EQ(ObjType::IteratorEnd, dict3->at(0).second->getType()); @@ -941,20 +945,20 @@ TEST(ObjTest, Iterator) { ASSERT_TRUE(iter == iter.begin()); ASSERT_TRUE(iter != iter.end()); - dict1 = iter.read_and_next(-3); + dict1 = iter.read_and_next(3); ASSERT_TRUE(dict1); ASSERT_EQ(3, dict1->size()); ASSERT_EQ(1, dict1->at(0).second->GetValueAsInteger()); ASSERT_EQ(2, dict1->at(1).second->GetValueAsInteger()); ASSERT_EQ(3, dict1->at(2).second->GetValueAsInteger()); - dict2 = iter.read_and_next(-3); + dict2 = iter.read_and_next(3); ASSERT_TRUE(dict2); ASSERT_EQ(2, dict2->size()); ASSERT_EQ(4, dict2->at(0).second->GetValueAsInteger()); ASSERT_EQ(5, dict2->at(1).second->GetValueAsInteger()); - dict3 = iter.read_and_next(-3); + dict3 = iter.read_and_next(3); ASSERT_TRUE(dict3); ASSERT_EQ(0, dict3->size()); @@ -962,27 +966,27 @@ TEST(ObjTest, Iterator) { Iterator flt(dict, ""); - ObjPtr flt_res = flt.read_and_next(-100); + ObjPtr flt_res = flt.read_and_next(100); ASSERT_TRUE(flt_res); ASSERT_EQ(1, flt_res->size()); ASSERT_EQ(4, flt_res->at(0).second->GetValueAsInteger()); Iterator flt1(dict, "."); - ObjPtr flt1_res = flt1.read_and_next(-100); + ObjPtr flt1_res = flt1.read_and_next(100); ASSERT_TRUE(flt1_res); ASSERT_EQ(1, flt1_res->size()); ASSERT_EQ(1, flt1_res->at(0).second->GetValueAsInteger()); Iterator flt2(dict, ".."); - ObjPtr flt2_res = flt2.read_and_next(-100); + ObjPtr flt2_res = flt2.read_and_next(100); ASSERT_TRUE(flt2_res); ASSERT_EQ(1, flt2_res->size()); ASSERT_EQ(2, flt2_res->at(0).second->GetValueAsInteger()); Iterator flt3(dict, "..."); - ObjPtr flt3_res = flt3.read_and_next(-100); + ObjPtr flt3_res = flt3.read_and_next(100); ASSERT_TRUE(flt3_res); ASSERT_EQ(2, flt3_res->size()); ASSERT_EQ(3, flt3_res->at(0).second->GetValueAsInteger()); From 925507c8eb70b83dcf9a1393b33298ef4f9ba3e2 Mon Sep 17 00:00:00 2001 From: Aleksandr Ryabikov Date: Wed, 13 Jul 2022 00:35:33 +0300 Subject: [PATCH 20/31] =?UTF-8?q?=D0=92=20=D0=BF=D1=80=D0=BE=D1=86=D0=B5?= =?UTF-8?q?=D1=81=D1=81=D0=B5=20=D0=B2=D1=81=D1=82=D1=80=D0=B0=D0=B8=D0=B2?= =?UTF-8?q?=D0=B0=D0=BD=D0=B8=D1=8F=20=D0=B8=D1=82=D0=B5=D1=80=D0=B0=D1=82?= =?UTF-8?q?=D0=BE=D1=80=D0=BE=D0=B2=20=D0=B2=20=D0=BF=D0=B0=D1=80=D1=81?= =?UTF-8?q?=D0=B5=D1=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/context.cpp | 66 ++++++++----- src/context.h | 3 +- src/newlang.cpp | 34 +++---- src/object.cpp | 22 ++++- src/object.h | 10 +- src/parser.y | 15 ++- src/term.h | 1 - src/test/eval_test.cpp | 200 +++++++++++++++++++++++++++++++++++++++ src/test/object_test.cpp | 2 +- 9 files changed, 303 insertions(+), 50 deletions(-) diff --git a/src/context.cpp b/src/context.cpp index e91ba540..6de0a9d5 100644 --- a/src/context.cpp +++ b/src/context.cpp @@ -330,12 +330,6 @@ ObjPtr Context::eval_CALL_TRY(Context *ctx, const TermPtr &term, Obj *args) { return CallBlock(ctx, term, args, true); } -ObjPtr Context::eval_ITERATOR_QQ(Context *ctx, const TermPtr &term, Obj *args) { - LOG_RUNTIME("eval_ITERATOR_QQ: %s", term->toString().c_str()); - - return nullptr; -} - ObjPtr Context::eval_MACRO(Context *ctx, const TermPtr &term, Obj *args) { LOG_RUNTIME("eval_MACRO: %s", term->toString().c_str()); @@ -448,7 +442,7 @@ ObjPtr Context::eval_COMMENT(Context *ctx, const TermPtr &term, Obj *args) { } ObjPtr Context::eval_SYMBOL(Context *ctx, const TermPtr &term, Obj *args) { - LOG_RUNTIME("SYMBOL Not implemented!"); + LOG_RUNTIME("SYMBOL '%s' Not implemented!", term->m_text.c_str()); return nullptr; } @@ -706,9 +700,7 @@ ObjPtr Context::eval_PUREFUNC(Context *ctx, const TermPtr &term, Obj * args) { * */ ObjPtr Context::eval_ITERATOR(Context *ctx, const TermPtr &term, Obj * args) { - LOG_RUNTIME("ITERATOR Not implemented!"); - - return nullptr; + return CreateRVal(ctx, term, args); } ObjPtr Context::eval_RANGE(Context *ctx, const TermPtr &term, Obj * args) { @@ -2194,13 +2186,7 @@ ObjPtr Context::CreateRVal(Context *ctx, TermPtr term, Obj * local_vars, bool in } args = Obj::CreateDict(); - for (int i = 0; i < term->size(); i++) { - if(term->name(i).empty()) { - args->push_back(CreateRVal(ctx, (*term)[i].second, local_vars)); - } else { - args->push_back(CreateRVal(ctx, (*term)[i].second, local_vars), term->name(i).c_str()); - } - } + ctx->CreateArgs_(args, term, local_vars); if(term->getTermID() == TermID::EXIT) { return result; @@ -2213,13 +2199,8 @@ ObjPtr Context::CreateRVal(Context *ctx, TermPtr term, Obj * local_vars, bool in case TermID::TENSOR: case TermID::DICT: result->m_var_type_current = ObjType::Dictionary; - for (int i = 0; i < term->size(); i++) { - if(term->name(i).empty()) { - result->push_back(CreateRVal(ctx, (*term)[i].second, local_vars)); - } else { - result->push_back(CreateRVal(ctx, (*term)[i].second, local_vars), term->name(i).c_str()); - } - } + ctx->CreateArgs_(result, term, local_vars); + result->m_var_is_init = true; if(term->getTermID() == TermID::TENSOR) { @@ -2278,8 +2259,45 @@ ObjPtr Context::CreateRVal(Context *ctx, TermPtr term, Obj * local_vars, bool in case TermID::FRACTION: return Obj::CreateFraction(term->m_text); + case TermID::ITERATOR: + + ASSERT(term->Left()); + + temp = ctx->GetTerm(term->Left()->GetFullName().c_str(), true); + if(!temp) { + LOG_RUNTIME("Term '%s' not found!", term->GetFullName().c_str()); + } + + args = Obj::CreateDict(); + ctx->CreateArgs_(args, term, local_vars); + + if(term->m_text.compare("?") == 0) { + return temp->MakeIterator(args.get()); + } else if(term->m_text.compare("??") == 0) { + return temp->IteratorReset(); + } else if(term->m_text.compare("!") == 0) { + return temp->IteratorNext(0); + } else if(term->m_text.compare("!!") == 0) { + return temp->IteratorNext(1); + } else if(term->m_text.compare("!?") == 0 || term->m_text.compare("?!") == 0) { + result = temp->MakeIterator(args.get()); + return result->IteratorNext(std::numeric_limits::max()); + } else { + LOG_RUNTIME("Iterator '%s' not recognized in '%s'!", term->m_text.c_str(), term->toString().c_str()); + } + } LOG_RUNTIME("Fail create type %s from '%s'", newlang::toString(term->getTermID()), term->toString().c_str()); return nullptr; } + +void Context::CreateArgs_(ObjPtr &args, TermPtr &term, Obj *local_vars) { + for (int i = 0; i < term->size(); i++) { + if(term->name(i).empty()) { + args->push_back(CreateRVal(this, (*term)[i].second, local_vars)); + } else { + args->push_back(CreateRVal(this, (*term)[i].second, local_vars), term->name(i).c_str()); + } + } +} \ No newline at end of file diff --git a/src/context.h b/src/context.h index 7188e17e..6c435469 100644 --- a/src/context.h +++ b/src/context.h @@ -198,7 +198,8 @@ namespace newlang { static ObjPtr CreateLVal(Context *ctx, TermPtr type, Obj *args); static ObjPtr CreateRVal(Context *ctx, TermPtr term, Obj *args, bool int_catch = true); static ObjPtr CreateRVal(Context *ctx, const char *source, Obj *args, bool int_catch = true); - + void CreateArgs_(ObjPtr &args, TermPtr &term, Obj *local_vars); + static std::vector MakeIndex(Context *ctx, TermPtr term, Obj *local_vars); void ItemTensorEval_(torch::Tensor &tensor, c10::IntArrayRef shape, std::vector &ind, const int64_t pos, ObjPtr & obj, ObjPtr &args); diff --git a/src/newlang.cpp b/src/newlang.cpp index d1986b49..60b8e8c2 100644 --- a/src/newlang.cpp +++ b/src/newlang.cpp @@ -1059,23 +1059,23 @@ NewLang::NewLang(RuntimePtr rt) : m_runtime(rt) { // return ExecModule(filename, filename, true, ctx); //} -ObjPtr NewLang::GetIndexField(Context *ctx, ObjPtr obj, TermPtr term, bool create_field) { - if(!term->Right()) { - return obj; - } else if(term->Right()->getTermID() == TermID::FIELD && !term->Right()->Right() && create_field) { - // Если последнее в списке поле создается - return obj->push_back(Obj::CreateNone(), term->Right()->getText().c_str()).second; - } - ObjPtr result; - if(term->Right()->getTermID() == TermID::FIELD) { - result = (*obj)[term->Right()->m_text.c_str()].second; - return GetIndexField(ctx, result, term->Right()); - } else if(term->Right()->getTermID() == TermID::INDEX) { - result = Obj::GetIndex(obj, term->Right()); - return GetIndexField(ctx, result, term->Right()); - } - LOG_RUNTIME("Fail type %s of object '%s'!", newlang::toString(term->Right()->getTermID()), term->Right()->toString().c_str()); -} +//ObjPtr NewLang::GetIndexField(Context *ctx, ObjPtr obj, TermPtr term, bool create_field) { +// if(!term->Right()) { +// return obj; +// } else if(term->Right()->getTermID() == TermID::FIELD && !term->Right()->Right() && create_field) { +// // Если последнее в списке поле создается +// return obj->push_back(Obj::CreateNone(), term->Right()->getText().c_str()).second; +// } +// ObjPtr result; +// if(term->Right()->getTermID() == TermID::FIELD) { +// result = (*obj)[term->Right()->m_text.c_str()].second; +// return GetIndexField(ctx, result, term->Right()); +// } else if(term->Right()->getTermID() == TermID::INDEX) { +// result = Obj::GetIndex(obj, term->Right()); +// return GetIndexField(ctx, result, term->Right()); +// } +// LOG_RUNTIME("Fail type %s of object '%s'!", newlang::toString(term->Right()->getTermID()), term->Right()->toString().c_str()); +//} //ObjPtr NewLang::Eval(Context *ctx, TermPtr calc, bool make_function) { // try { diff --git a/src/object.cpp b/src/object.cpp index 66e3d615..35180d94 100644 --- a/src/object.cpp +++ b/src/object.cpp @@ -2954,8 +2954,26 @@ ObjPtr Iterator::read_and_next(int64_t count) { return result; } -ObjPtr Obj::MakeIterator() { +ObjPtr Obj::MakeIterator(Obj * args) { ObjPtr result = CreateType(ObjType::Iterator, ObjType::Iterator, true); result->m_iterator = std::make_shared> (shared()); return result; -} \ No newline at end of file +} + +ObjPtr Obj::IteratorReset() { + if(m_var_type_current != ObjType::Iterator) { + LOG_RUNTIME("Method available an iterator only!"); + } + ASSERT(m_iterator); + m_iterator->reset(); + return shared(); +} + +ObjPtr Obj::IteratorNext(int64_t count) { + if(m_var_type_current != ObjType::Iterator) { + LOG_RUNTIME("Method available an iterator only!"); + } + ASSERT(m_iterator); + return m_iterator->read_and_next(count); +} + diff --git a/src/object.h b/src/object.h index b1dc4416..1040a931 100644 --- a/src/object.h +++ b/src/object.h @@ -339,7 +339,15 @@ class Obj : public Variable, public std::enable_shared_from_this { return shared(); } - ObjPtr MakeIterator(); + ObjPtr MakeIterator(Obj * args); + ObjPtr IteratorReset(); + + inline ObjPtr IteratorNext(ObjPtr count) { + return IteratorNext(count->GetValueAsInteger()); + } + ObjPtr IteratorNext(int64_t count); + + #define TEST_CONST_() if (m_is_const) {LOG_RUNTIME("Can`t edit const value '%s'!", toString().c_str());} #define TEST_INIT_() if (!m_var_is_init) {LOG_RUNTIME("Object not initialized '%s'!", toString().c_str());} diff --git a/src/parser.y b/src/parser.y index 7b7d875c..0aa2860b 100644 --- a/src/parser.y +++ b/src/parser.y @@ -653,7 +653,14 @@ name: TERM $$->m_namespace.swap($1->m_namespace); } - +arg_name: name + { + $$ = $1; + } + | strtype + { + $$ = $1; + } /* Допустимые <имена> объеков */ assign_name: name @@ -805,10 +812,12 @@ rval: rval_var iter_all: '!' { $$=$1; + $$->SetTermID(TermID::ITERATOR); } | '?' { $$=$1; + $$->SetTermID(TermID::ITERATOR); } | ITERATOR { @@ -834,7 +843,7 @@ iter_all: '!' /* Аргументом может быть что угодно */ -arg: name '=' +arg: arg_name '=' { // Именованный аргумент $$ = $2; $$->m_name.swap($1->m_text); @@ -847,7 +856,7 @@ arg: name '=' $$->m_name.swap($1->m_text); $$->SetTermID(TermID::EMPTY); } - | name '=' rval + | arg_name '=' rval { // Именованный аргумент $$ = $rval; $$->SetName($1->getText()); diff --git a/src/term.h b/src/term.h index cc938edf..3ccc3871 100644 --- a/src/term.h +++ b/src/term.h @@ -54,7 +54,6 @@ namespace newlang { _(SIMPLE_XOR) \ _(PUREFUNC) \ _(ITERATOR) \ - _(ITERATOR_QQ)\ _(FOLLOW) \ _(MATCHING) \ _(WHILE) \ diff --git a/src/test/eval_test.cpp b/src/test/eval_test.cpp index 21ee5571..137bd49a 100644 --- a/src/test/eval_test.cpp +++ b/src/test/eval_test.cpp @@ -889,6 +889,13 @@ TEST(Eval, MacroDSL) { "\\\\no 0\\\\\\" "" "\\\\this $0\\\\\\" + "" + // "\\\\iquery(...) \\$var?(\\$*)\\\\\\" + // "\\\\inext(var) \\$var!\\\\\\" + // "\\\\inext(var, count) \\$var!(\\$count)\\\\\\" + // "\\ireset(var) \\$var??\\\\\\" + // "\\iselect(var) \\$var?!\\\\\\" + // "\\iselect(var, ...) \\$var?!(\\$*)\\\\\\" ""; ASSERT_EQ(0, Context::m_macros.size()); @@ -936,6 +943,199 @@ TEST(Eval, MacroDSL) { TEST(Eval, Iterator) { + Context::Reset(); + Context ctx(RunTime::Init()); + + ObjPtr dict = ctx.ExecStr("dict := ('1'=1, \"22\"=2, '333'=3, 4, \"555\"=5,)"); + ASSERT_TRUE(dict); + ASSERT_EQ(5, dict->size()); + ASSERT_EQ(1, dict->at(0).second->GetValueAsInteger()); + ASSERT_EQ(2, dict->at(1).second->GetValueAsInteger()); + ASSERT_EQ(3, dict->at(2).second->GetValueAsInteger()); + ASSERT_EQ(4, dict->at(3).second->GetValueAsInteger()); + ASSERT_EQ(5, dict->at(4).second->GetValueAsInteger()); + ASSERT_STREQ("1", dict->at(0).first.c_str()); + ASSERT_STREQ("22", dict->at(1).first.c_str()); + ASSERT_STREQ("333", dict->at(2).first.c_str()); + ASSERT_STREQ("", dict->at(3).first.c_str()); + ASSERT_STREQ("555", dict->at(4).first.c_str()); + + ObjPtr iter = ctx.ExecStr("iter := dict?"); + + ASSERT_TRUE(iter); + ASSERT_EQ(ObjType::Iterator, iter->getType()) << toString(iter->getType()); +// +// ASSERT_TRUE(*(iter->m_iterator) == iter->begin()); +// ASSERT_TRUE(*(iter->m_iterator) != iter->end()); +// +// ObjPtr copy = Obj::CreateDict(); +// for (auto &elem : iter) { +// copy->push_back(elem.second, elem.first); +// } +// +// ASSERT_TRUE(iter->m_iterator == iter->begin()); +// ASSERT_TRUE(iter->m_iterator != iter->end()); +// +// +// +// ASSERT_EQ(dict->size(), copy->size()); +// ObjPtr dict1 = ctx.ExecStr("iter?!"); +// ASSERT_TRUE(dict1); +// ASSERT_EQ(5, dict1->size()); +// ASSERT_EQ(1, dict1->at(0).second->GetValueAsInteger()); +// ASSERT_EQ(2, dict1->at(1).second->GetValueAsInteger()); +// ASSERT_EQ(3, dict1->at(2).second->GetValueAsInteger()); +// ASSERT_EQ(4, dict1->at(3).second->GetValueAsInteger()); +// ASSERT_EQ(5, dict1->at(4).second->GetValueAsInteger()); +// ASSERT_STREQ("1", dict1->at(0).first.c_str()); +// ASSERT_STREQ("22", dict1->at(1).first.c_str()); +// ASSERT_STREQ("333", dict1->at(2).first.c_str()); +// ASSERT_STREQ("", dict1->at(3).first.c_str()); +// ASSERT_STREQ("555", dict1->at(4).first.c_str()); + + + + /* + * Создание итератора + * ?, ?(), ?("Фильтр"), ?(func), ?(func, args...) + * + * Перебор элементов итератора + * !, !(), !(0), !(3), !(-3) + * + * dict! и dict!(0) эквивалентны + * dict! -> 1, dict! -> 2, dict! -> 3, dict! -> 4, dict! -> 5, dict! -> :IteratorEnd + * Различия отрицательного размера возвращаемого словаря для итератора + * dict!(-1) -> (1,), ... dict!(-1) -> (5,), dict!(-1) -> (:IteratorEnd,), + * dict!(1) -> (1,), ... dict!(1) -> (5,), dict!(1) -> (,), + * dict!(-3) -> (1, 2, 3,), dict!(-3) -> (4, 5, :IteratorEnd,) + * dict!(3) -> (1, 2, 3,), dict!(3) -> (4, 5,) + * + * !? или ?! эквиваленты и создают итератор и сразу его выполняет, + * вовзращая все значения в виде элементов словаря, т.е. ?(LINQ); !(:Long.__max__) + * А зачем может быть нужен итератор "??" - может сброс в начальное состояние??? + * Итератор !! эквиваленетен вызову !(1) + */ + + // ASSERT_TRUE(iter->m_iterator == iter->begin()); + // + // ObjPtr one = iter.read_and_next(0); + // ASSERT_TRUE(one); + // ASSERT_EQ(1, dict->at(0).second->GetValueAsInteger()); + // + // ASSERT_EQ(2, (*iter).second->GetValueAsInteger()); + // one = iter.read_and_next(0); + // ASSERT_TRUE(one); + // ASSERT_EQ(2, dict->at(1).second->GetValueAsInteger()); + // + // ASSERT_EQ(3, (*iter).second->GetValueAsInteger()); + // one = iter.read_and_next(0); + // ASSERT_TRUE(one); + // ASSERT_EQ(3, dict->at(2).second->GetValueAsInteger()); + // + // ASSERT_EQ(4, (*iter).second->GetValueAsInteger()); + // one = iter.read_and_next(0); + // ASSERT_TRUE(one); + // ASSERT_EQ(4, dict->at(3).second->GetValueAsInteger()); + // + // ASSERT_EQ(5, (*iter).second->GetValueAsInteger()); + // one = iter.read_and_next(0); + // ASSERT_TRUE(one); + // ASSERT_EQ(5, dict->at(4).second->GetValueAsInteger()); + // + // one = iter.read_and_next(0); + // ASSERT_TRUE(one); + // ASSERT_EQ(ObjType::IteratorEnd, one->getType()) << one << " " << toString(one->getType()); + // + // one = iter.read_and_next(0); + // ASSERT_TRUE(one); + // ASSERT_EQ(ObjType::IteratorEnd, one->getType()) << one << " " << toString(one->getType()); + // + // + // + // + // ASSERT_TRUE(iter == iter.end()); + // iter.reset(); + // ASSERT_TRUE(iter == iter.begin()); + // ASSERT_TRUE(iter != iter.end()); + // + // ObjPtr dict1 = iter.read_and_next(-3); + // ASSERT_TRUE(dict1); + // ASSERT_EQ(3, dict1->size()); + // ASSERT_EQ(1, dict1->at(0).second->GetValueAsInteger()); + // ASSERT_EQ(2, dict1->at(1).second->GetValueAsInteger()); + // ASSERT_EQ(3, dict1->at(2).second->GetValueAsInteger()); + // + // ObjPtr dict2 = iter.read_and_next(-3); + // ASSERT_TRUE(dict2); + // ASSERT_EQ(3, dict2->size()); + // ASSERT_EQ(4, dict2->at(0).second->GetValueAsInteger()); + // ASSERT_EQ(5, dict2->at(1).second->GetValueAsInteger()); + // ASSERT_EQ(ObjType::IteratorEnd, dict2->at(2).second->getType()); + // + // ObjPtr dict3 = iter.read_and_next(-3); + // ASSERT_TRUE(dict3); + // ASSERT_EQ(3, dict1->size()); + // ASSERT_EQ(ObjType::IteratorEnd, dict3->at(0).second->getType()); + // ASSERT_EQ(ObjType::IteratorEnd, dict3->at(1).second->getType()); + // ASSERT_EQ(ObjType::IteratorEnd, dict3->at(2).second->getType()); + // + // + // + // ASSERT_TRUE(iter == iter.end()); + // iter.reset(); + // ASSERT_TRUE(iter == iter.begin()); + // ASSERT_TRUE(iter != iter.end()); + // + // dict1 = iter.read_and_next(3); + // ASSERT_TRUE(dict1); + // ASSERT_EQ(3, dict1->size()); + // ASSERT_EQ(1, dict1->at(0).second->GetValueAsInteger()); + // ASSERT_EQ(2, dict1->at(1).second->GetValueAsInteger()); + // ASSERT_EQ(3, dict1->at(2).second->GetValueAsInteger()); + // + // dict2 = iter.read_and_next(3); + // ASSERT_TRUE(dict2); + // ASSERT_EQ(2, dict2->size()); + // ASSERT_EQ(4, dict2->at(0).second->GetValueAsInteger()); + // ASSERT_EQ(5, dict2->at(1).second->GetValueAsInteger()); + // + // dict3 = iter.read_and_next(3); + // ASSERT_TRUE(dict3); + // ASSERT_EQ(0, dict3->size()); + // + // + // + // + // Iterator flt(dict, ""); + // ObjPtr flt_res = flt.read_and_next(100); + // ASSERT_TRUE(flt_res); + // ASSERT_EQ(1, flt_res->size()); + // ASSERT_EQ(4, flt_res->at(0).second->GetValueAsInteger()); + // + // + // Iterator flt1(dict, "."); + // ObjPtr flt1_res = flt1.read_and_next(100); + // ASSERT_TRUE(flt1_res); + // ASSERT_EQ(1, flt1_res->size()); + // ASSERT_EQ(1, flt1_res->at(0).second->GetValueAsInteger()); + // + // + // Iterator flt2(dict, ".."); + // ObjPtr flt2_res = flt2.read_and_next(100); + // ASSERT_TRUE(flt2_res); + // ASSERT_EQ(1, flt2_res->size()); + // ASSERT_EQ(2, flt2_res->at(0).second->GetValueAsInteger()); + // + // Iterator flt3(dict, "..."); + // ObjPtr flt3_res = flt3.read_and_next(100); + // ASSERT_TRUE(flt3_res); + // ASSERT_EQ(2, flt3_res->size()); + // ASSERT_EQ(3, flt3_res->at(0).second->GetValueAsInteger()); + // ASSERT_EQ(5, flt3_res->at(1).second->GetValueAsInteger()); + // + // + // + // ObjPtr iter1 = dict->MakeIterator(); } diff --git a/src/test/object_test.cpp b/src/test/object_test.cpp index b0f0ec93..5d949780 100644 --- a/src/test/object_test.cpp +++ b/src/test/object_test.cpp @@ -994,7 +994,7 @@ TEST(ObjTest, Iterator) { - ObjPtr iter1 = dict->MakeIterator(); +// ObjPtr iter1 = dict->MakeIterator(); } From 21cf2cc0c665ead1bd6205fd9908cd787937a0cb Mon Sep 17 00:00:00 2001 From: Aleksandr Ryabikov Date: Wed, 13 Jul 2022 09:28:09 +0300 Subject: [PATCH 21/31] =?UTF-8?q?=D0=A1=D0=BA=D1=80=D1=8B=D0=BB=20=D0=B8?= =?UTF-8?q?=D0=BD=D1=82=D0=B5=D1=80=D1=84=D0=B5=D0=B9=D1=81=20std::list=20?= =?UTF-8?q?=D1=83=20=D1=88=D0=B0=D0=B1=D0=BB=D0=BE=D0=BD=D0=B0=20Variable,?= =?UTF-8?q?=20=D1=87=D1=82=D0=BE=D0=B1=D1=8B=20=D0=BC=D0=BE=D0=B6=D0=BD?= =?UTF-8?q?=D0=BE=20=D0=B1=D1=8B=D0=BB=D0=BE=20=D1=81=D0=B4=D0=B5=D0=BB?= =?UTF-8?q?=D0=B0=D1=82=D1=8C=20=D0=BA=D0=BE=D0=BD=D1=82=D1=80=D0=BE=D0=BB?= =?UTF-8?q?=D1=8C=20=D1=82=D0=B8=D0=BF=D0=BE=D0=B2.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/context.cpp | 2 +- src/context.h | 2 + src/nbproject/configurations.xml | 5 +- src/object.h | 3231 +++++++++++++++--------------- src/variable.h | 12 +- 5 files changed, 1669 insertions(+), 1583 deletions(-) mode change 100644 => 100755 src/object.h diff --git a/src/context.cpp b/src/context.cpp index 6de0a9d5..d0b1863d 100644 --- a/src/context.cpp +++ b/src/context.cpp @@ -2212,7 +2212,7 @@ ObjPtr Context::CreateRVal(Context *ctx, TermPtr term, Obj * local_vars, bool in } else { result->m_var_is_init = false; } - result->Variable::clear_(); + result->resize(0, nullptr, ""); result->m_var_type_current = type; } else { result->m_class_name = term->m_class_name; diff --git a/src/context.h b/src/context.h index 6c435469..eefaab90 100644 --- a/src/context.h +++ b/src/context.h @@ -105,6 +105,8 @@ namespace newlang { class Context : public Variable> { public: + + friend class Obj; static ObjPtr eval_END(Context *ctx, const TermPtr & term, Obj *args); static ObjPtr func_NOT_SUPPORT(Context *ctx, const TermPtr & term, Obj *args); diff --git a/src/nbproject/configurations.xml b/src/nbproject/configurations.xml index 0dc3da93..8f02d1fd 100644 --- a/src/nbproject/configurations.xml +++ b/src/nbproject/configurations.xml @@ -79,7 +79,10 @@ displayName="Важные файлы" projectFiles="false" kind="IMPORTANT_FILES_FOLDER"> - /home/rsashka/SOURCE/PUBLIC/NewLang/newlang/LICENSE + ../.clang-format + ../.gitignore + ../.gitmodules + ../LICENSE Makefile ../README.md diff --git a/src/object.h b/src/object.h old mode 100644 new mode 100755 index 1040a931..9e032dcd --- a/src/object.h +++ b/src/object.h @@ -10,1960 +10,2041 @@ namespace newlang { -/* - * Аргумент по умолчанию может быть литерал или выражение. - * Если аргумент по умолчанию — это выражение, то оно вычисляется только один раз для всей программы при загрузке модуля. - * Аргументы по умолчанию парсятся из токенов (создаются или вычисляются) при загрузке модуля, т.е. при создании - * аругментов по умолчанию, а сами значения хранятся уже как объекты. - * - * Аргументы в функции всегда имеют номер, который начинается с единицы в порядке определения в прототипе + некоторые могут иметь наименование. - * Даже обязательные аргументы (которые не имеют значения по умолчанию в прототипе финкции), могут быть переданы по имени, - * а сами именованные аргументы могут быть указаны в произвольном порядке. Поэтому в реализации Args для обязательных - * аргументов так же хранится имя аргумента, но его значение отсутствует. - * - * Так как позционные аргументы тоже могут передавать как именованные, то контроль и подстчет кол-ва - * не именованных аргументов при вызове фунции ничего не определяет. - * Следовательно, при вызове функции не именованные аргументы записываются по порядку, а именованные по имени. - * Контроль передаваемых аргументов производится на наличие значения у каждого аргумента. - * Если при определении функции после всех аргументов стоит многоточие, то разрешается добавлять - * новые аргументы по мимо тех, которые уже определены в прототипе функции. - */ - -ObjType DictionarySummaryType(const Obj *obj); -std::vector TensorShapeFromDict(const Obj *obj); -torch::Tensor ConvertToTensor(Obj *obj, at::ScalarType type = at::ScalarType::Undefined, bool reshape = true); - -at::TensorOptions ConvertToTensorOptions(const Obj *obj); -at::DimnameList ConvertToDimnameList(const Obj *obj); -bool ParsePrintfFormat(Obj *args, int start = 1); - -enum class ConcatMode : uint8_t { - Error = 0, - Append = 1, - Discard = 2, -}; -/* - * Для строк, словарей и классов (преобразование в одно измерение), тензоров (преобразование согласно ConcatMode) - */ -int64_t ConcatData(Obj *dest, Obj &src, ConcatMode mode = ConcatMode::Error); - -// Convert a wide Unicode string to an UTF8 string - -inline std::string utf8_encode(const std::wstring wstr) { - std::string utf8line; - - if (wstr.empty()) { + /* + * Аргумент по умолчанию может быть литерал или выражение. + * Если аргумент по умолчанию — это выражение, то оно вычисляется только один раз для всей программы при загрузке модуля. + * Аргументы по умолчанию парсятся из токенов (создаются или вычисляются) при загрузке модуля, т.е. при создании + * аругментов по умолчанию, а сами значения хранятся уже как объекты. + * + * Аргументы в функции всегда имеют номер, который начинается с единицы в порядке определения в прототипе + некоторые могут иметь наименование. + * Даже обязательные аргументы (которые не имеют значения по умолчанию в прототипе финкции), могут быть переданы по имени, + * а сами именованные аргументы могут быть указаны в произвольном порядке. Поэтому в реализации Args для обязательных + * аргументов так же хранится имя аргумента, но его значение отсутствует. + * + * Так как позционные аргументы тоже могут передавать как именованные, то контроль и подстчет кол-ва + * не именованных аргументов при вызове фунции ничего не определяет. + * Следовательно, при вызове функции не именованные аргументы записываются по порядку, а именованные по имени. + * Контроль передаваемых аргументов производится на наличие значения у каждого аргумента. + * Если при определении функции после всех аргументов стоит многоточие, то разрешается добавлять + * новые аргументы по мимо тех, которые уже определены в прототипе функции. + */ + + ObjType DictionarySummaryType(const Obj *obj); + std::vector TensorShapeFromDict(const Obj *obj); + torch::Tensor ConvertToTensor(Obj *obj, at::ScalarType type = at::ScalarType::Undefined, bool reshape = true); + + at::TensorOptions ConvertToTensorOptions(const Obj *obj); + at::DimnameList ConvertToDimnameList(const Obj *obj); + bool ParsePrintfFormat(Obj *args, int start = 1); + + enum class ConcatMode : uint8_t { + Error = 0, + Append = 1, + Discard = 2, + }; + /* + * Для строк, словарей и классов (преобразование в одно измерение), тензоров (преобразование согласно ConcatMode) + */ + int64_t ConcatData(Obj *dest, Obj &src, ConcatMode mode = ConcatMode::Error); + + // Convert a wide Unicode string to an UTF8 string + + inline std::string utf8_encode(const std::wstring wstr) { + std::string utf8line; + + if (wstr.empty()) { + return utf8line; + } + utf8line = std::wstring_convert < std::codecvt_utf8>().to_bytes(wstr.c_str()); return utf8line; } - utf8line = std::wstring_convert < std::codecvt_utf8>().to_bytes(wstr.c_str()); - return utf8line; -} -// Convert an UTF8 string to a wide Unicode String + // Convert an UTF8 string to a wide Unicode String -inline std::wstring utf8_decode(const std::string str) { - std::wstring wide_line; + inline std::wstring utf8_decode(const std::string str) { + std::wstring wide_line; - if (str.empty()) { + if (str.empty()) { + return wide_line; + } + wide_line = std::wstring_convert < std::codecvt_utf8>().from_bytes(str.c_str()); return wide_line; } - wide_line = std::wstring_convert < std::codecvt_utf8>().from_bytes(str.c_str()); - return wide_line; -} - -ObjType getSummaryTensorType(ObjPtr & obj, ObjType start); -std::vector getTensorSizes(Obj *obj); -void calcTensorDims(ObjPtr & obj, std::vector &dims); -void testTensorDims(ObjPtr & obj, at::IntArrayRef dims, int64_t pos); - - - - - -/* - * Требуется разделять конейнеры с данными и итераторы по данным. - * В С++ контейнеры предоставялют итераторы непосредственно из самого контейнера. - * Это удобно для использования в рукописном коде, но сложно контроллировать в генерируемом исходнике, - * т.к. требуется использовать и итертор и сам контейнер с данными (для сравнения с end()). - * - * Логика работы с итераторами следующая. - * Итератор - отдельный объект, которому для создания требуется контейнер с данными. - * Итератор два интерфейса перебора данных: - * 1. - первый интерфейс итератора как в С++ - * 2. - второй интерфейс для использования в генерируемом коде с логикой NewLang - * - * Разделение контейнера и итератора на два объекта позволит выполнять проверку на использование - * - */ - -/* - * Итератор - */ -template -class Iterator : public std::iterator { -public: - - enum class IterCmp : int8_t { - No = static_cast (ObjType::None), /* skip data */ - Yes = static_cast (ObjType::Iterator), /* return data */ - End = static_cast (ObjType::IteratorEnd), /* iterator complete */ - }; - STATIC_ASSERT(static_cast (IterCmp::Yes)); - STATIC_ASSERT(!static_cast (IterCmp::No)); + ObjType getSummaryTensorType(ObjPtr & obj, ObjType start); + std::vector getTensorSizes(Obj *obj); + void calcTensorDims(ObjPtr & obj, std::vector &dims); + void testTensorDims(ObjPtr & obj, at::IntArrayRef dims, int64_t pos); - typedef Iterator iterator; - typedef Iterator const_iterator; - typedef Variable IterObj; - typedef typename Variable::Type IterObjPtr; - typedef typename Variable::PairType IterPairType; - typedef typename Variable::ListType IterListType; - typedef IterCmp CompareFuncType(const IterPairType &pair, const T *args, void *extra); - /** - * Итератор для элементов списка с regex фильтром по имени элемента (по умолчанию для всех элементов списка) - * @param obj - * @param find_key + /* + * Требуется разделять конейнеры с данными и итераторы по данным. + * В С++ контейнеры предоставялют итераторы непосредственно из самого контейнера. + * Это удобно для использования в рукописном коде, но сложно контроллировать в генерируемом исходнике, + * т.к. требуется использовать и итертор и сам контейнер с данными (для сравнения с end()). + * + * Логика работы с итераторами следующая. + * Итератор - отдельный объект, которому для создания требуется контейнер с данными. + * Итератор два интерфейса перебора данных: + * 1. - первый интерфейс итератора как в С++ + * 2. - второй интерфейс для использования в генерируемом коде с логикой NewLang + * + * Разделение контейнера и итератора на два объекта позволит выполнять проверку на использование + * */ - Iterator(std::shared_ptr obj, const std::string find_key = "(.|\\n)*") : - Iterator(obj, &CompareFuncDefault, reinterpret_cast (const_cast (&find_key)), static_cast (this)) { - } - /** - * Итератор для элементов списка с фильтром в виде функции обратного вызова - * @param obj - * @param func - * @param arg - * @param extra + /* + * Итератор */ - Iterator(std::shared_ptr obj, CompareFuncType *func, T *arg, void * extra = nullptr) : - m_iter_obj(obj), m_match(), m_func(func), m_func_args(arg), m_func_extra(extra), m_found(m_iter_obj->begin()) { - search_loop(); - } + template + class Iterator : public std::iterator { + public: - Iterator(const Iterator &iter) : m_iter_obj(iter.m_iter_obj), m_match(iter.m_match), m_func(iter.m_func), - m_func_args(iter.m_func_args), m_func_extra(iter.m_func_extra), m_found(iter.m_found) { - } + friend class Obj; + friend class Variable; + friend class Context; + friend class Variable>; + + enum class IterCmp : int8_t { + No = static_cast (ObjType::None), /* skip data */ + Yes = static_cast (ObjType::Iterator), /* return data */ + End = static_cast (ObjType::IteratorEnd), /* iterator complete */ + }; + + STATIC_ASSERT(static_cast (IterCmp::Yes)); + STATIC_ASSERT(!static_cast (IterCmp::No)); - SCOPE(private) : - std::shared_ptr m_iter_obj; - std::regex m_match; - std::string m_filter; - CompareFuncType *m_func; - T *m_func_args; - void *m_func_extra; + typedef Iterator iterator; + typedef Iterator const_iterator; - mutable typename Variable::iterator m_found; + typedef Variable IterObj; + typedef typename Variable::Type IterObjPtr; + typedef typename Variable::PairType IterPairType; + typedef typename Variable::ListType IterListType; - static const IterPairType m_interator_end; - static IterCmp CompareFuncDefault(const IterPairType &pair, const T *filter, void *extra) { - const std::string * str_filter = reinterpret_cast (filter); - Iterator * iter = static_cast (extra); - if (iter && str_filter) { + typedef IterCmp CompareFuncType(const IterPairType &pair, const T *args, void *extra); - iter->m_func_args = nullptr; // Передается однократно при создании объекта - iter->m_filter = *str_filter; + /** + * Итератор для элементов списка с regex фильтром по имени элемента (по умолчанию для всех элементов списка) + * @param obj + * @param find_key + */ + Iterator(std::shared_ptr obj, const std::string find_key = "(.|\\n)*") : + Iterator(obj, &CompareFuncDefault, reinterpret_cast (const_cast (&find_key)), static_cast (this)) { + } + + /** + * Итератор для элементов списка с фильтром в виде функции обратного вызова + * @param obj + * @param func + * @param arg + * @param extra + */ + Iterator(std::shared_ptr obj, CompareFuncType *func, T *arg, void * extra = nullptr) : + m_iter_obj(obj), m_match(), m_func(func), m_func_args(arg), m_func_extra(extra), m_found(m_iter_obj->begin()) { + search_loop(); + } + + Iterator(const Iterator &iter) : m_iter_obj(iter.m_iter_obj), m_match(iter.m_match), m_func(iter.m_func), + m_func_args(iter.m_func_args), m_func_extra(iter.m_func_extra), m_found(iter.m_found) { + } + + SCOPE(private) : + std::shared_ptr m_iter_obj; + std::regex m_match; + std::string m_filter; + CompareFuncType *m_func; + T *m_func_args; + void *m_func_extra; + + mutable typename Variable::iterator m_found; + + static const IterPairType m_interator_end; + + static IterCmp CompareFuncDefault(const IterPairType &pair, const T *filter, void *extra) { + const std::string * str_filter = reinterpret_cast (filter); + Iterator * iter = static_cast (extra); + if (iter && str_filter) { + + iter->m_func_args = nullptr; // Передается однократно при создании объекта + iter->m_filter = *str_filter; - if (!iter->m_filter.empty()) { - try { - iter->m_match = std::regex(iter->m_filter); - } catch (const std::regex_error &err) { - LOG_RUNTIME("Regular expression for '%s' error '%s'!", str_filter->c_str(), err.what()); + if (!iter->m_filter.empty()) { + try { + iter->m_match = std::regex(iter->m_filter); + } catch (const std::regex_error &err) { + LOG_RUNTIME("Regular expression for '%s' error '%s'!", str_filter->c_str(), err.what()); + } } } - } - if (iter) { - if (iter->m_filter.empty()) { - return pair.first.empty() ? IterCmp::Yes : IterCmp::No; - } else { - return std::regex_match(pair.first, iter->m_match) ? IterCmp::Yes : IterCmp::No; + if (iter) { + if (iter->m_filter.empty()) { + return pair.first.empty() ? IterCmp::Yes : IterCmp::No; + } else { + return std::regex_match(pair.first, iter->m_match) ? IterCmp::Yes : IterCmp::No; + } } + return IterCmp::Yes; } - return IterCmp::Yes; - } -public: + public: - iterator begin() { - Iterator copy(*this); - copy.reset(); - return copy; - } + iterator begin() { + Iterator copy(*this); + copy.reset(); + return copy; + } - iterator end() { - Iterator copy(*this); - copy.m_found = copy.m_iter_obj->end(); - return copy; - } + iterator end() { + Iterator copy(*this); + copy.m_found = copy.m_iter_obj->end(); + return copy; + } - inline const IterPairType &operator*() { - if (m_found == m_iter_obj->end()) { - return m_interator_end; + inline const IterPairType &operator*() { + if (m_found == m_iter_obj->end()) { + return m_interator_end; + } + return *m_found; } - return *m_found; - } - inline const IterPairType &operator*() const { - if (m_found == m_iter_obj->end()) { - return m_interator_end; + inline const IterPairType &operator*() const { + if (m_found == m_iter_obj->end()) { + return m_interator_end; + } + return *m_found; } - return *m_found; - } - ObjPtr read_and_next(int64_t count); + ObjPtr read_and_next(int64_t count); - const iterator &operator++() const { - if (m_found != m_iter_obj->end()) { - m_found++; - search_loop(); + const iterator &operator++() const { + if (m_found != m_iter_obj->end()) { + m_found++; + search_loop(); + } + return *this; } - return *this; - } - inline const iterator operator++(int) const { - return iterator::operator++(); - } + inline const iterator operator++(int) const { + return iterator::operator++(); + } - inline bool operator==(const iterator &other) const { - return m_found == other.m_found; - } + inline bool operator==(const iterator &other) const { + return m_found == other.m_found; + } - inline bool operator!=(const iterator &other) const { - return m_found != other.m_found; - } + inline bool operator!=(const iterator &other) const { + return m_found != other.m_found; + } - inline void reset() { - m_found = m_iter_obj->begin(); - search_loop(); - } + inline void reset() { + m_found = m_iter_obj->begin(); + search_loop(); + } -protected: + protected: - void search_loop() const { - while (m_found != m_iter_obj->end()) { - IterCmp result = IterCmp::Yes; - if (m_func) { - result = (*m_func)(*m_found, m_func_args, m_func_extra); - if (result == IterCmp::End) { - m_found = m_iter_obj->end(); + void search_loop() const { + while (m_found != m_iter_obj->end()) { + IterCmp result = IterCmp::Yes; + if (m_func) { + result = (*m_func)(*m_found, m_func_args, m_func_extra); + if (result == IterCmp::End) { + m_found = m_iter_obj->end(); + } } + if (result != IterCmp::No) { + // IterCmp::Yes || IterCmp::End + return; + } + m_found++; } - if (result != IterCmp::No) { - // IterCmp::Yes || IterCmp::End - return; - } - m_found++; } - } -}; - -/* - * - * - */ -class Obj : public Variable, public std::enable_shared_from_this { -public: - - // constexpr static const char * BUILDIN_TYPE = "__var_type__"; - // constexpr static const char * BUILDIN_NAME = "__var_name__"; - // constexpr static const char * BUILDIN_BASE = "__class_base__"; - // constexpr static const char * BUILDIN_CLASS = "__class_name__"; - // constexpr static const char * BUILDIN_NAMESPACE = "__namespace__"; - - Obj(ObjType type = ObjType::None, const char *var_name = nullptr, TermPtr func_proto = nullptr, ObjType fixed = ObjType::None, bool init = false) : - m_var_type_current(type), m_var_name(var_name ? var_name : ""), m_func_proto(func_proto) { - // m_ctx = nullptr; - m_is_const = false; - m_check_args = false; - m_ref_count = 0; - m_func_ptr = nullptr; - m_dimensions = nullptr; - m_value = torch::empty({0}, isSimpleType(type) ? toTorchType(type) : at::ScalarType::Undefined); - m_is_reference = false; - m_func_abi = FFI_DEFAULT_ABI; - m_var_type_fixed = fixed; - m_var_is_init = init; - } + }; - Obj(Context *ctx, const TermPtr term, bool as_value, Obj *local_vars); + /* + * + * + */ + class Obj : protected Variable, public std::enable_shared_from_this { + public: + + // constexpr static const char * BUILDIN_TYPE = "__var_type__"; + // constexpr static const char * BUILDIN_NAME = "__var_name__"; + // constexpr static const char * BUILDIN_BASE = "__class_base__"; + // constexpr static const char * BUILDIN_CLASS = "__class_name__"; + // constexpr static const char * BUILDIN_NAMESPACE = "__namespace__"; + + Obj(ObjType type = ObjType::None, const char *var_name = nullptr, TermPtr func_proto = nullptr, ObjType fixed = ObjType::None, bool init = false) : + m_var_type_current(type), m_var_name(var_name ? var_name : ""), m_func_proto(func_proto) { + // m_ctx = nullptr; + m_is_const = false; + m_check_args = false; + m_ref_count = 0; + m_func_ptr = nullptr; + m_dimensions = nullptr; + m_value = torch::empty({0}, isSimpleType(type) ? toTorchType(type) : at::ScalarType::Undefined); + m_is_reference = false; + m_func_abi = FFI_DEFAULT_ABI; + m_var_type_fixed = fixed; + m_var_is_init = init; + } + Obj(Context *ctx, const TermPtr term, bool as_value, Obj *local_vars); - [[nodiscard]] - static inline PairType ArgNull(const std::string name = "") { - return pair(nullptr, name); - } - [[nodiscard]] - static inline PairType Arg() { - return pair(CreateNone()); - } + [[nodiscard]] + static inline PairType ArgNull(const std::string name = "") { + return pair(nullptr, name); + } - [[nodiscard]] - static inline PairType Arg(ObjPtr value, const std::string name = "") { - return pair(value, name); - } + [[nodiscard]] + static inline PairType Arg() { + return pair(CreateNone()); + } - template - typename std::enable_if::value || std::is_same::value, PairType>::type - static inline Arg(T value, const std::string name = "") { - return pair(CreateString(value), name); - } + [[nodiscard]] + static inline PairType Arg(ObjPtr value, const std::string name = "") { + return pair(value, name); + } - template - typename std::enable_if::value && !std::is_pointer::value && !std::is_same::value, PairType>::type - static inline Arg(T value, const std::string name = "") { - return pair(CreateValue(value, ObjType::None), name); - } + template + typename std::enable_if::value || std::is_same::value, PairType>::type + static inline Arg(T value, const std::string name = "") { + return pair(CreateString(value), name); + } - inline ObjPtr shared() { - try { - return shared_from_this(); - } catch (std::bad_weak_ptr &err) { - LOG_RUNTIME("Exception thrown bad_weak_ptr! %s", err.what()); + template + typename std::enable_if::value && !std::is_pointer::value && !std::is_same::value, PairType>::type + static inline Arg(T value, const std::string name = "") { + return pair(CreateValue(value, ObjType::None), name); } - } - ObjPtr MakeConst() { - m_is_const = true; - return shared(); - } + inline ObjPtr shared() { + try { + return shared_from_this(); + } catch (std::bad_weak_ptr &err) { + LOG_RUNTIME("Exception thrown bad_weak_ptr! %s", err.what()); + } + } - ObjPtr MakeMutable() { - m_is_const = false; - return shared(); - } + ObjPtr MakeConst() { + m_is_const = true; + return shared(); + } - ObjPtr MakeIterator(Obj * args); - ObjPtr IteratorReset(); + ObjPtr MakeMutable() { + m_is_const = false; + return shared(); + } - inline ObjPtr IteratorNext(ObjPtr count) { - return IteratorNext(count->GetValueAsInteger()); - } - ObjPtr IteratorNext(int64_t count); + ObjPtr MakeIterator(Obj * args); + ObjPtr IteratorReset(); + + inline ObjPtr IteratorNext(ObjPtr count) { + return IteratorNext(count->GetValueAsInteger()); + } + ObjPtr IteratorNext(int64_t count); #define TEST_CONST_() if (m_is_const) {LOG_RUNTIME("Can`t edit const value '%s'!", toString().c_str());} #define TEST_INIT_() if (!m_var_is_init) {LOG_RUNTIME("Object not initialized '%s'!", toString().c_str());} - [[nodiscard]] - inline ObjType getType() { - return m_var_type_current; - } + [[nodiscard]] + inline ObjType getType() { + return m_var_type_current; + } - [[nodiscard]] - inline ObjType getTypeAsLimit() { - if (is_arithmetic_type()) { - if (isIntegralType(m_var_type_current, true) && is_scalar()) { - return typeFromLimit(GetValueAsInteger()); - } else if (isFloatingType(m_var_type_current) && is_scalar()) { - return typeFromLimit(GetValueAsNumber()); + [[nodiscard]] + inline ObjType getTypeAsLimit() { + if (is_arithmetic_type()) { + if (isIntegralType(m_var_type_current, true) && is_scalar()) { + return typeFromLimit(GetValueAsInteger()); + } else if (isFloatingType(m_var_type_current) && is_scalar()) { + return typeFromLimit(GetValueAsNumber()); + } + } else if (is_type_name()) { + return m_var_type_fixed; } - } else if (is_type_name()) { - return m_var_type_fixed; + return m_var_type_current; } - return m_var_type_current; - } - [[nodiscard]] - inline std::string & getName() { - return m_var_name; - } + [[nodiscard]] + inline std::string & getName() { + return m_var_name; + } - [[nodiscard]] - inline const std::string & getName() const { - return m_var_name; - } + [[nodiscard]] + inline const std::string & getName() const { + return m_var_name; + } - /* - Встроенные атрибуты класса - -Объекты класса — дочерние элементы по отношению к атрибутам самого языка Python. Таким образом они заимствуют некоторые атрибуты: -Атрибут Описание -__dict__ Предоставляет данные о классе коротко и доступно, в виде словаря -__doc__ Возвращает строку с описанием класса, или None, если значение не определено -__class__ Возвращает объект, содержащий информацию о классе с массой полезных атрибутов, включая атрибут __name__ -__module__ Возвращает имя «модуля» класса или __main__, если класс определен в выполняемом модуле. - -class Customer: - 'Это класс Customer' - def __init__(self, name, phone, address): - self.name = name - self.phone = phone - self.address = address + /* + Встроенные атрибуты класса + + Объекты класса — дочерние элементы по отношению к атрибутам самого языка Python. Таким образом они заимствуют некоторые атрибуты: + Атрибут Описание + __dict__ Предоставляет данные о классе коротко и доступно, в виде словаря + __doc__ Возвращает строку с описанием класса, или None, если значение не определено + __class__ Возвращает объект, содержащий информацию о классе с массой полезных атрибутов, включая атрибут __name__ + __module__ Возвращает имя «модуля» класса или __main__, если класс определен в выполняемом модуле. + + class Customer: + 'Это класс Customer' + def __init__(self, name, phone, address): + self.name = name + self.phone = phone + self.address = address -john = Customer("John",1234567, "USA") + john = Customer("John",1234567, "USA") -print ("john.__dict__ = ", john.__dict__) -print ("john.__doc__ = ", john.__doc__) -print ("john.__class__ = ", john.__class__) -print ("john.__class__.__name__ = ", john.__class__.__name__) -print ("john.__module__ = ", john.__module__) + print ("john.__dict__ = ", john.__dict__) + print ("john.__doc__ = ", john.__doc__) + print ("john.__class__ = ", john.__class__) + print ("john.__class__.__name__ = ", john.__class__.__name__) + print ("john.__module__ = ", john.__module__) + + Вывод: + + john.__dict__ = {'name': 'John', 'phone': 1234567, 'address': 'USA'} + john.__doc__ = Это класс Customer + john.__class__ = + john.__class__.__name__ = Customer + john.__module__ = __main__ + + */ + void SetClassName(std::string &name) { + m_class_name = name; + } -Вывод: + inline bool isConst() const { + return m_is_const; + } -john.__dict__ = {'name': 'John', 'phone': 1234567, 'address': 'USA'} -john.__doc__ = Это класс Customer -john.__class__ = -john.__class__.__name__ = Customer -john.__module__ = __main__ + [[nodiscard]] + inline bool is_none_type() const { + return m_var_type_current == ObjType::None; + } - */ - void SetClassName(std::string &name) { - m_class_name = name; - } + [[nodiscard]] + inline bool is_bool_type() const { + return isBooleanType(m_var_type_current); + } - inline bool isConst() const { - return m_is_const; - } + [[nodiscard]] + inline bool is_arithmetic_type() const { + return isArithmeticType(m_var_type_current); + } - [[nodiscard]] - inline bool is_none_type() const { - return m_var_type_current == ObjType::None; - } + [[nodiscard]] + inline bool is_string_type() const { + return isString(m_var_type_current); + } - [[nodiscard]] - inline bool is_bool_type() const { - return isBooleanType(m_var_type_current); - } + [[nodiscard]] + inline bool is_dictionary_type() const { + return isDictionary(m_var_type_current); + } - [[nodiscard]] - inline bool is_arithmetic_type() const { - return isArithmeticType(m_var_type_current); - } + //Plain data — это неизменяемые структуры без ссылок на другие объекты. + [[nodiscard]] + inline bool is_plain_type() const { + return isPlainDataType(m_var_type_current); + } - [[nodiscard]] - inline bool is_string_type() const { - return isString(m_var_type_current); - } + [[nodiscard]] + inline bool is_other_type() const { + return !(is_none_type() || is_bool_type() || is_arithmetic_type() || is_string_type() || is_dictionary_type()); + } - [[nodiscard]] - inline bool is_dictionary_type() const { - return isDictionary(m_var_type_current); - } + [[nodiscard]] + inline bool is_class() const { + return isClass(m_var_type_current); + } - //Plain data — это неизменяемые структуры без ссылок на другие объекты. - [[nodiscard]] - inline bool is_plain_type() const { - return isPlainDataType(m_var_type_current); - } + [[nodiscard]] + inline bool is_simple() const { + return isSimpleType(m_var_type_current); + } - [[nodiscard]] - inline bool is_other_type() const { - return !(is_none_type() || is_bool_type() || is_arithmetic_type() || is_string_type() || is_dictionary_type()); - } + [[nodiscard]] + inline bool is_scalar() const { + return is_tensor() && m_value.dim() == 0; + } - [[nodiscard]] - inline bool is_class() const { - return isClass(m_var_type_current); - } + [[nodiscard]] + inline bool is_function() const { + return isFunction(m_var_type_current); + } - [[nodiscard]] - inline bool is_simple() const { - return isSimpleType(m_var_type_current); - } + [[nodiscard]] + inline bool is_tensor() const { + return isTensor(m_var_type_current); + } - [[nodiscard]] - inline bool is_scalar() const { - return is_tensor() && m_value.dim() == 0; - } + [[nodiscard]] + inline bool is_integer() const { + return isIntegralType(m_var_type_current, false); + } - [[nodiscard]] - inline bool is_function() const { - return isFunction(m_var_type_current); - } + [[nodiscard]] + inline bool is_complex() const { + return isComplexType(m_var_type_current); + } - [[nodiscard]] - inline bool is_tensor() const { - return isTensor(m_var_type_current); - } + [[nodiscard]] + inline bool is_floating() const { + return isFloatingType(m_var_type_current); + } - [[nodiscard]] - inline bool is_integer() const { - return isIntegralType(m_var_type_current, false); - } + [[nodiscard]] + inline bool is_indexing() const { + return is_tensor() || is_string_type() || is_dictionary_type() || is_class(); + } - [[nodiscard]] - inline bool is_complex() const { - return isComplexType(m_var_type_current); - } + [[nodiscard]] + inline bool is_ellipsis() const { + return isEllipsis(m_var_type_current); + } - [[nodiscard]] - inline bool is_floating() const { - return isFloatingType(m_var_type_current); - } + [[nodiscard]] + inline bool is_range() const { + return isRange(m_var_type_current); + } - [[nodiscard]] - inline bool is_indexing() const { - return is_tensor() || is_string_type() || is_dictionary_type() || is_class(); - } + [[nodiscard]] + inline bool is_type_name() const { + return isTypeName(m_var_type_current); + } - [[nodiscard]] - inline bool is_ellipsis() const { - return isEllipsis(m_var_type_current); - } + [[nodiscard]] + inline bool is_error() const { + return m_var_type_current == ObjType::Error || m_var_type_fixed == ObjType::Error; + } - [[nodiscard]] - inline bool is_range() const { - return isRange(m_var_type_current); - } + [[nodiscard]] + inline bool is_return() const { + return m_var_type_current == ObjType::Return || m_var_type_fixed == ObjType::Return; + } - [[nodiscard]] - inline bool is_type_name() const { - return isTypeName(m_var_type_current); - } + [[nodiscard]] + ObjType SummaryArithmeticType(ObjType type); - [[nodiscard]] - inline bool is_error() const { - return m_var_type_current == ObjType::Error || m_var_type_fixed == ObjType::Error; - } + [[nodiscard]] + inline bool is_defined_type() { + return m_var_type_fixed != ObjType::None; + } - [[nodiscard]] - inline bool is_return() const { - return m_var_type_current == ObjType::Return || m_var_type_fixed == ObjType::Return; - } + inline void SetTermProp(Term &term); - [[nodiscard]] - ObjType SummaryArithmeticType(ObjType type); + virtual int64_t size() const { + return size(0); + } + virtual int64_t size(int64_t ind) const; + int64_t resize_(int64_t size, ObjPtr fill, const std::string = ""); - [[nodiscard]] - inline bool is_defined_type() { - return m_var_type_fixed != ObjType::None; - } + virtual bool empty() const { + if (is_none_type()) { + return true; + } else if (m_var_type_current == ObjType::StrChar) { + return !m_var_is_init || m_str.empty(); + } else if (m_var_type_current == ObjType::StrWide) { + return !m_var_is_init || m_wstr.empty(); + } else if (is_tensor()) { + return !m_var_is_init || at::_is_zerotensor(m_value); + } + return Variable::empty(); + } - inline void SetTermProp(Term &term); + Variable::PairType & at(const std::string_view name) const { + Obj * const obj = (Obj * const) this; + return obj->Variable::at(name); + } - virtual int64_t size() const { - return size(0); - } - virtual int64_t size(int64_t ind) const; - int64_t resize_(int64_t size, ObjPtr fill, const std::string = ""); + Variable::PairType & at(const std::string_view name) override { + return Variable::at(name); + } - virtual bool empty() const { - if (is_none_type()) { - return true; - } else if (m_var_type_current == ObjType::StrChar) { - return !m_var_is_init || m_str.empty(); - } else if (m_var_type_current == ObjType::StrWide) { - return !m_var_is_init || m_wstr.empty(); - } else if (is_tensor()) { - return !m_var_is_init || at::_is_zerotensor(m_value); - } - return Variable::empty(); - } + Variable::PairType & at(const int64_t index) override; + const Variable::PairType & at(const int64_t index) const override; - Variable::PairType & at(const std::string_view name) const { - Obj * const obj = (Obj * const) this; - return obj->Variable::at(name); - } + Variable::PairType & at(ObjPtr find) { + if (!find->is_string_type()) { + LOG_RUNTIME("Value must be a string type %d", (int) find->getType()); + } + return Variable::at(find->GetValueAsString()); + } - Variable::PairType & at(const std::string_view name) override { - return Variable::at(name); - } + bool exist(ObjPtr &find, bool strong); + size_t ItemValueCount(ObjPtr &find, bool strong); - Variable::PairType & at(const int64_t index) override; - const Variable::PairType & at(const int64_t index) const override; + static bool is_true(const char *text) { + std::string temp(text); + std::transform(temp.begin(), temp.end(), temp.begin(), ::tolower); + return temp.compare("true") == 0; + } - Variable::PairType & at(ObjPtr find) { - if (!find->is_string_type()) { - LOG_RUNTIME("Value must be a string type %d", (int) find->getType()); + /** + * Создать копию объекта (клонировать) + * @return + */ + ObjPtr operator()(Context *ctx) { + Obj args; + return Call(ctx, &args); } - return Variable::at(find->GetValueAsString()); - } - bool exist(ObjPtr &find, bool strong); - size_t ItemValueCount(ObjPtr &find, bool strong); + template + typename std::enable_if::value, ObjPtr>::type + inline operator()(Context *ctx, T ... args) { + auto list = {args...}; + ObjPtr arg = Obj::CreateDict(); + for (auto &elem : list) { + arg->push_back(elem); + } + return Call(ctx, arg.get()); + } - static bool is_true(const char *text) { - std::string temp(text); - std::transform(temp.begin(), temp.end(), temp.begin(), ::tolower); - return temp.compare("true") == 0; - } + inline ObjPtr Call(Context *ctx) { + Obj args; + return Call(ctx, &args); + } - /** - * Создать копию объекта (клонировать) - * @return - */ - ObjPtr operator()(Context *ctx) { - Obj args; - return Call(ctx, &args); - } + template + typename std::enable_if::value, ObjPtr>::type + inline Call(Context *ctx, T ... args) { + auto list = {args...}; + Obj arg; + for (auto &elem : list) { + arg.push_back(elem); + } + return Call(ctx, &arg); + } + + ObjPtr Call(Context *ctx, Obj *args); - template - typename std::enable_if::value, ObjPtr>::type - inline operator()(Context *ctx, T ... args) { - auto list = {args...}; - ObjPtr arg = Obj::CreateDict(); - for (auto &elem : list) { - arg->push_back(elem); + /* + * + * Интерфейс Variable + * + */ + + template + typename std::enable_if < std::is_integral::value && !std::is_pointer::value, const PairType &>::type + inline operator[](const I index) { + return at(index); } - return Call(ctx, arg.get()); - } - inline ObjPtr Call(Context *ctx) { - Obj args; - return Call(ctx, &args); - } + template + typename std::enable_if < std::is_same::value || std::is_pointer::value, const PairType &>::type + inline operator[](const N name) { + return at(name); + } - template - typename std::enable_if::value, ObjPtr>::type - inline Call(Context *ctx, T ... args) { - auto list = {args...}; - Obj arg; - for (auto &elem : list) { - arg.push_back(elem); + Obj::iterator find(const std::string_view name) { + return Variable::find(name); } - return Call(ctx, &arg); - } - ObjPtr Call(Context *ctx, Obj *args); + Obj::const_iterator find(const std::string_view name) const { + return Variable::find(name); + } + Obj::iterator begin() { + return Variable::begin(); + } + Obj::iterator end() { + return Variable::end(); + } + Obj::const_iterator begin() const { + return Variable::begin(); + } + Obj::const_iterator end() const { + return Variable::end(); + } - //унарный плюс ничего не делает. + PairType & push_back(const PairType & p) { + return Variable::push_back(p); + } - ObjPtr operator+() { - if (is_arithmetic_type()) { - return shared(); + PairType & push_back(const Type value, const std::string &name = "") { + return Variable::push_back(value, name); } - LOG_RUNTIME("Unary plus for object '%s' not supported!", toString().c_str()); - } - ObjPtr operator-() { - if (is_arithmetic_type()) { - if (is_tensor()) { - m_value = -m_value; - } else if (is_integer()) { - SetValue_(-GetValueAsInteger()); - } else if (isFloatingType(m_var_type_current)) { - SetValue_(-GetValueAsNumber()); - } else { - LOG_RUNTIME("Unary minus for object '%s' not supported!", toString().c_str()); - } - return shared(); + Obj::iterator at_index(const int64_t index) { + return Variable::at_index(index); } - LOG_RUNTIME("Unary minus for object '%s' not supported!", toString().c_str()); - } - ObjPtr & operator+(ObjPtr & obj) { + Obj::const_iterator at_index_const(const int64_t index) const { + return Variable::at_index_const(index); + } - if (is_tensor()) { - return obj; + Obj::const_iterator insert(Obj::const_iterator pos, const PairType &data) { + return Variable::insert(pos, data); } - LOG_RUNTIME("Object '%s' not numeric!", obj->toString().c_str()); - } - ObjPtr &operator-(ObjPtr & obj) { - if (is_tensor()) { - obj->m_value = torch::zeros_like(obj->m_value) - obj->m_value; - return obj; + const std::string & name(const int64_t index) const override { + return Variable::name(index); + } + + int64_t resize(int64_t new_size, const Type fill, const std::string &name = "") override { + return Variable::resize(new_size, fill, name); + } + + void erase(const int64_t index) override { + Variable::erase(index); } - LOG_RUNTIME("Object '%s' not numeric!", obj->toString().c_str()); - } + void clear_() override { - //префиксная версия возвращает значение после инкремента + Variable::clear_(); + clear_(true); + } - ObjPtr operator++() { - if (is_tensor()) { - m_value.add_(torch::ones_like(m_value)); + void clear_(bool clear_iterator_name) { - return shared(); + m_str.clear(); + m_wstr.clear(); + m_var_type_current = ObjType::None; + + m_class_parents.clear(); + m_var_is_init = false; + m_value.reset(); + m_fraction.reset(); + // m_var = std::monostate(); + // m_value.reset(); //???????????????? + // m_items.clear(); } - LOG_RUNTIME("Object '%s' not numeric!", toString().c_str()); - } - //постфиксная версия возвращает значение до инкремента - ObjPtr operator++(int) { - ObjPtr old = Clone(); - Obj::operator++(); - return old; - } + /* + * + * + */ - //префиксная версия возвращает значение после декремента + //унарный плюс ничего не делает. - ObjPtr operator--() { - if (is_tensor()) { - m_value.sub_(torch::ones_like(m_value)); - return shared(); + ObjPtr operator+() { + if (is_arithmetic_type()) { + return shared(); + } + LOG_RUNTIME("Unary plus for object '%s' not supported!", toString().c_str()); } - LOG_RUNTIME("Object '%s' not numeric!", toString().c_str()); - } - //постфиксная версия возвращает значение до декремента + ObjPtr operator-() { + if (is_arithmetic_type()) { + if (is_tensor()) { + m_value = -m_value; + } else if (is_integer()) { + SetValue_(-GetValueAsInteger()); + } else if (isFloatingType(m_var_type_current)) { + SetValue_(-GetValueAsNumber()); + } else { + LOG_RUNTIME("Unary minus for object '%s' not supported!", toString().c_str()); + } + return shared(); + } + LOG_RUNTIME("Unary minus for object '%s' not supported!", toString().c_str()); + } - ObjPtr operator--(int) { - ObjPtr old = Clone(); - Obj::operator--(); - return old; - } + ObjPtr & operator+(ObjPtr & obj) { - inline ObjPtr operator*(ObjPtr obj) { - ASSERT(obj); - return operator*(*obj); - } + if (is_tensor()) { + return obj; + } + LOG_RUNTIME("Object '%s' not numeric!", obj->toString().c_str()); + } - inline ObjPtr operator*(Obj value) { - ObjPtr result = Clone(); - *result *= value; - return result; - } + ObjPtr &operator-(ObjPtr & obj) { + if (is_tensor()) { + obj->m_value = torch::zeros_like(obj->m_value) - obj->m_value; + return obj; + } + LOG_RUNTIME("Object '%s' not numeric!", obj->toString().c_str()); + } - inline ObjPtr operator/(ObjPtr obj) { - ASSERT(obj); - return operator/(*obj); - } - inline ObjPtr operator/(Obj value) { - ObjPtr result = Clone(); - *result /= value; - return result; - } + //префиксная версия возвращает значение после инкремента - inline ObjPtr op_div_ceil(ObjPtr obj) { - ASSERT(obj); - return op_div_ceil(*obj); - } + ObjPtr operator++() { + if (is_tensor()) { + m_value.add_(torch::ones_like(m_value)); - inline ObjPtr op_div_ceil(Obj value) { - ObjPtr result = Clone(); - result->op_div_ceil_(value); - return result; - } + return shared(); + } + LOG_RUNTIME("Object '%s' not numeric!", toString().c_str()); + } - inline ObjPtr op_concat(ObjPtr obj, ConcatMode mode = ConcatMode::Error) { - ASSERT(obj); - return op_concat(*obj, mode); - } + //постфиксная версия возвращает значение до инкремента - inline ObjPtr op_concat(Obj &value, ConcatMode mode = ConcatMode::Error) { - ObjPtr result = Clone(); - result->op_concat_(value, mode); - return result; - } + ObjPtr operator++(int) { + ObjPtr old = Clone(); + Obj::operator++(); + return old; + } - inline ObjPtr op_concat_(Obj &obj, ConcatMode mode = ConcatMode::Error) { - ConcatData(this, obj, mode); - return shared(); - } + //префиксная версия возвращает значение после декремента - inline ObjPtr op_concat_(ObjPtr obj, ConcatMode mode = ConcatMode::Error) { - return op_concat_(*obj, mode); - } + ObjPtr operator--() { + if (is_tensor()) { + m_value.sub_(torch::ones_like(m_value)); + return shared(); + } + LOG_RUNTIME("Object '%s' not numeric!", toString().c_str()); + } - inline ObjPtr operator%(ObjPtr obj) { - ASSERT(obj); - return operator%(*obj); - } + //постфиксная версия возвращает значение до декремента - inline ObjPtr operator%(Obj value) { - ObjPtr result = Clone(); - *result %= value; - return result; - } + ObjPtr operator--(int) { + ObjPtr old = Clone(); + Obj::operator--(); + return old; + } - inline ObjPtr operator+(ObjPtr obj) { - ASSERT(obj); - return operator+(*obj); - } + inline ObjPtr operator*(ObjPtr obj) { + ASSERT(obj); + return operator*(*obj); + } - inline ObjPtr operator+(Obj value) { - ObjPtr result = Clone(); - *result += value; - return result; - } + inline ObjPtr operator*(Obj value) { + ObjPtr result = Clone(); + *result *= value; + return result; + } - inline ObjPtr operator-(ObjPtr obj) { - ASSERT(obj); - return operator-(*obj); - } + inline ObjPtr operator/(ObjPtr obj) { + ASSERT(obj); + return operator/(*obj); + } - inline ObjPtr operator-(Obj value) { - ObjPtr result = Clone(); - *result -= value; - return result; - } + inline ObjPtr operator/(Obj value) { + ObjPtr result = Clone(); + *result /= value; + return result; + } - // ObjPtr op_lshift(ObjPtr obj) { - // LOG_RUNTIME("Operator '<<' not implementd!"); - // } - // - // ObjPtr op_rshift(ObjPtr obj) { - // LOG_RUNTIME("Operator '>>' not implementd!"); - // } - // - // ObjPtr op_rrshift(ObjPtr obj) { - // LOG_RUNTIME("Operator '>>>' not implementd!"); - // } - - inline bool operator<(ObjPtr obj) { - ASSERT(obj); - return operator<(*obj); - } + inline ObjPtr op_div_ceil(ObjPtr obj) { + ASSERT(obj); + return op_div_ceil(*obj); + } - inline bool operator<(Obj obj) { - return op_compare(obj) < 0; - } + inline ObjPtr op_div_ceil(Obj value) { + ObjPtr result = Clone(); + result->op_div_ceil_(value); + return result; + } - inline bool operator<=(ObjPtr obj) { - ASSERT(obj); - return operator<=(*obj); - } + inline ObjPtr op_concat(ObjPtr obj, ConcatMode mode = ConcatMode::Error) { + ASSERT(obj); + return op_concat(*obj, mode); + } - inline bool operator<=(Obj obj) { - return op_compare(obj) <= 0; - } + inline ObjPtr op_concat(Obj &value, ConcatMode mode = ConcatMode::Error) { + ObjPtr result = Clone(); + result->op_concat_(value, mode); + return result; + } - inline bool operator>(ObjPtr obj) { - ASSERT(obj); - return operator>(*obj); - } + inline ObjPtr op_concat_(Obj &obj, ConcatMode mode = ConcatMode::Error) { + ConcatData(this, obj, mode); + return shared(); + } - inline bool operator>(Obj obj) { - return op_compare(obj) > 0; - } + inline ObjPtr op_concat_(ObjPtr obj, ConcatMode mode = ConcatMode::Error) { + return op_concat_(*obj, mode); + } - inline bool operator>=(ObjPtr obj) { - ASSERT(obj); - return operator>=(*obj); - } + inline ObjPtr operator%(ObjPtr obj) { + ASSERT(obj); + return operator%(*obj); + } - inline bool operator>=(Obj obj) { - return op_compare(obj) >= 0; - } - int op_compare(Obj & value); + inline ObjPtr operator%(Obj value) { + ObjPtr result = Clone(); + *result %= value; + return result; + } - /* - * instanceof (проверка класса объекта) test_obj ~~ obj объекты совместимы по свойствим и их типам (утиная типизация) - * in (проверка существования свойства) test_obj ~~ (prop=,) объект содержит указанные свойства (т.к. пустой тип совместим с любым типом) - * - * Реализация модели наследования: - * ~ - проверка по классу объекта, т.е. проверка имени объекта или имени базового типа (объект должен быть наследником образца) - * Реализация утиной типизации: - * ~~ - сравнение с образцом на совместимость типов (пустой тип совместим с любым) - * ~~~ - сравнение с образцом на равенство типов, т.е. типы объекта должны быть идентичны образцу, включая пустой - * Для двух последних случаев сравнение производится только для одного уровня (без раскрытия сложенных словарей, если они присутствуют в образце) - * или сравнение должно зависить от того, есть ли в образце вложенные словари (классы) ?????????????? - */ + inline ObjPtr operator+(ObjPtr obj) { + ASSERT(obj); + return operator+(*obj); + } - bool op_class_test(ObjPtr obj, Context *ctx) const; - bool op_class_test(const char * name, Context *ctx) const; + inline ObjPtr operator+(Obj value) { + ObjPtr result = Clone(); + *result += value; + return result; + } - inline bool op_duck_test(ObjPtr obj, bool strong) { - ASSERT(obj); - return op_duck_test(obj.get(), strong); - } - bool op_duck_test(Obj *value, bool strong); - static bool op_duck_test_prop(Obj *base, Obj *value, bool strong); + inline ObjPtr operator-(ObjPtr obj) { + ASSERT(obj); + return operator-(*obj); + } - inline bool op_equal(ObjPtr value) { - ASSERT(value); - if (value) { - return op_equal(*value); + inline ObjPtr operator-(Obj value) { + ObjPtr result = Clone(); + *result -= value; + return result; } - return false; - } - inline ObjPtr operator==(ObjPtr obj) { - ASSERT(obj); - return operator==(*obj); - } + // ObjPtr op_lshift(ObjPtr obj) { + // LOG_RUNTIME("Operator '<<' not implementd!"); + // } + // + // ObjPtr op_rshift(ObjPtr obj) { + // LOG_RUNTIME("Operator '>>' not implementd!"); + // } + // + // ObjPtr op_rrshift(ObjPtr obj) { + // LOG_RUNTIME("Operator '>>>' not implementd!"); + // } + + inline bool operator<(ObjPtr obj) { + ASSERT(obj); + return operator<(*obj); + } - inline ObjPtr operator==(Obj obj) { - return op_equal(obj) ? Obj::Yes() : Obj::No(); - } - bool op_equal(Obj & value); + inline bool operator<(Obj obj) { + return op_compare(obj) < 0; + } - inline bool op_accurate(ObjPtr obj) { - ASSERT(obj); - return op_accurate(*obj); - } - bool op_accurate(Obj & value); + inline bool operator<=(ObjPtr obj) { + ASSERT(obj); + return operator<=(*obj); + } - inline ObjPtr operator!=(ObjPtr obj) { - ASSERT(obj); - return operator!=(*obj); - } + inline bool operator<=(Obj obj) { + return op_compare(obj) <= 0; + } - inline ObjPtr operator!=(Obj obj) { - return op_equal(obj) ? Obj::No() : Obj::Yes(); - } + inline bool operator>(ObjPtr obj) { + ASSERT(obj); + return operator>(*obj); + } - inline ObjPtr op_bit_and(ObjPtr obj, bool strong) { - ASSERT(obj); - return op_bit_and(*obj, strong); - } + inline bool operator>(Obj obj) { + return op_compare(obj) > 0; + } - inline ObjPtr op_bit_and(Obj &obj, bool strong) { - ObjPtr result = Clone(); - result->op_bit_and_set(obj, strong); - return result; - } + inline bool operator>=(ObjPtr obj) { + ASSERT(obj); + return operator>=(*obj); + } - inline ObjPtr op_pow(ObjPtr obj) const { - ASSERT(obj); - return op_pow(*obj); - } + inline bool operator>=(Obj obj) { + return op_compare(obj) >= 0; + } + int op_compare(Obj & value); + + /* + * instanceof (проверка класса объекта) test_obj ~~ obj объекты совместимы по свойствим и их типам (утиная типизация) + * in (проверка существования свойства) test_obj ~~ (prop=,) объект содержит указанные свойства (т.к. пустой тип совместим с любым типом) + * + * Реализация модели наследования: + * ~ - проверка по классу объекта, т.е. проверка имени объекта или имени базового типа (объект должен быть наследником образца) + * Реализация утиной типизации: + * ~~ - сравнение с образцом на совместимость типов (пустой тип совместим с любым) + * ~~~ - сравнение с образцом на равенство типов, т.е. типы объекта должны быть идентичны образцу, включая пустой + * Для двух последних случаев сравнение производится только для одного уровня (без раскрытия сложенных словарей, если они присутствуют в образце) + * или сравнение должно зависить от того, есть ли в образце вложенные словари (классы) ?????????????? + */ + + bool op_class_test(ObjPtr obj, Context *ctx) const; + bool op_class_test(const char * name, Context *ctx) const; + + inline bool op_duck_test(ObjPtr obj, bool strong) { + ASSERT(obj); + return op_duck_test(obj.get(), strong); + } + bool op_duck_test(Obj *value, bool strong); + static bool op_duck_test_prop(Obj *base, Obj *value, bool strong); - inline ObjPtr op_pow(Obj &obj) const { - ObjPtr result = Clone(); - result->op_pow_(obj); - return result; - } + inline bool op_equal(ObjPtr value) { + ASSERT(value); + if (value) { + return op_equal(*value); + } + return false; + } - inline ObjPtr op_pow_(ObjPtr obj) { - ASSERT(obj); - return op_pow_(*obj); - } + inline ObjPtr operator==(ObjPtr obj) { + ASSERT(obj); + return operator==(*obj); + } - ObjPtr op_pow_(Obj &obj); - - // ObjPtr operator^(ObjPtr obj) { - // LOG_RUNTIME("Operator '^' not implementd!"); - // } - // - // ObjPtr operator|(ObjPtr obj) { - // LOG_RUNTIME("Operator '|' not implementd!"); - // } - // - // ObjPtr operator&&(ObjPtr obj) { - // LOG_RUNTIME("Operator '&&' not implementd!"); - // } - // - // ObjPtr operator||(ObjPtr obj) { - // LOG_RUNTIME("Operator '||' not implementd!"); - // } - - ObjPtr op_assign(ObjPtr obj) { - if (obj) { - return op_assign(*obj); - } - clear_(); - return shared(); - } + inline ObjPtr operator==(Obj obj) { + return op_equal(obj) ? Obj::Yes() : Obj::No(); + } + bool op_equal(Obj & value); - ObjPtr op_assign(Obj & obj) { - obj.CloneDataTo(*this); - obj.ClonePropTo(*this); - return shared(); - } + inline bool op_accurate(ObjPtr obj) { + ASSERT(obj); + return op_accurate(*obj); + } + bool op_accurate(Obj & value); - inline bool operator=(Obj & obj) { - obj.CloneDataTo(*this); - return true; - } + inline ObjPtr operator!=(ObjPtr obj) { + ASSERT(obj); + return operator!=(*obj); + } - /* - * ?: (выбор из двух операндов) - * = (присваивание) - * *=, /=, %=, +=, -=, &=, ^=, |=, <<=, >>=, >>>= (операции с присваиванием) - * , (отбрасывание первого и возврат второго операнда) - */ + inline ObjPtr operator!=(Obj obj) { + return op_equal(obj) ? Obj::No() : Obj::Yes(); + } + inline ObjPtr op_bit_and(ObjPtr obj, bool strong) { + ASSERT(obj); + return op_bit_and(*obj, strong); + } - inline ObjPtr operator*=(ObjPtr obj) { - ASSERT(obj); - return operator*=(*obj); - } + inline ObjPtr op_bit_and(Obj &obj, bool strong) { + ObjPtr result = Clone(); + result->op_bit_and_set(obj, strong); + return result; + } - ObjPtr operator*=(Obj obj); + inline ObjPtr op_pow(ObjPtr obj) const { + ASSERT(obj); + return op_pow(*obj); + } - inline ObjPtr operator/=(ObjPtr obj) { - ASSERT(obj); - return operator/=(*obj); - } + inline ObjPtr op_pow(Obj &obj) const { + ObjPtr result = Clone(); + result->op_pow_(obj); + return result; + } - ObjPtr operator/=(Obj obj); + inline ObjPtr op_pow_(ObjPtr obj) { + ASSERT(obj); + return op_pow_(*obj); + } - inline ObjPtr op_div_ceil_(ObjPtr obj) { - ASSERT(obj); - return op_div_ceil_(*obj); - } + ObjPtr op_pow_(Obj &obj); + + // ObjPtr operator^(ObjPtr obj) { + // LOG_RUNTIME("Operator '^' not implementd!"); + // } + // + // ObjPtr operator|(ObjPtr obj) { + // LOG_RUNTIME("Operator '|' not implementd!"); + // } + // + // ObjPtr operator&&(ObjPtr obj) { + // LOG_RUNTIME("Operator '&&' not implementd!"); + // } + // + // ObjPtr operator||(ObjPtr obj) { + // LOG_RUNTIME("Operator '||' not implementd!"); + // } + + ObjPtr op_assign(ObjPtr obj) { + if (obj) { + return op_assign(*obj); + } + clear_(); + return shared(); + } - ObjPtr op_div_ceil_(Obj &obj); + ObjPtr op_assign(Obj & obj) { + obj.CloneDataTo(*this); + obj.ClonePropTo(*this); + return shared(); + } - inline ObjPtr operator%=(ObjPtr obj) { - ASSERT(obj); - return operator%=(*obj); - } + inline bool operator=(Obj & obj) { + obj.CloneDataTo(*this); + return true; + } - ObjPtr operator%=(Obj obj); + /* + * ?: (выбор из двух операндов) + * = (присваивание) + * *=, /=, %=, +=, -=, &=, ^=, |=, <<=, >>=, >>>= (операции с присваиванием) + * , (отбрасывание первого и возврат второго операнда) + */ - inline ObjPtr operator+=(ObjPtr obj) { - ASSERT(obj); - return operator+=(*obj); - } - ObjPtr operator+=(Obj obj); - inline ObjPtr operator-=(ObjPtr obj) { - ASSERT(obj); - return operator-=(*obj); - } - ObjPtr operator-=(Obj obj); + inline ObjPtr operator*=(ObjPtr obj) { + ASSERT(obj); + return operator*=(*obj); + } + ObjPtr operator*=(Obj obj); - ObjPtr op_bit_and_set(Obj &obj, bool strong); + inline ObjPtr operator/=(ObjPtr obj) { + ASSERT(obj); + return operator/=(*obj); + } - inline ObjPtr operator^=(ObjPtr obj) { - ASSERT(obj); - return operator^=(*obj); - } + ObjPtr operator/=(Obj obj); - ObjPtr operator^=(Obj obj) { - LOG_RUNTIME("Operator '^=' not implementd!"); - } + inline ObjPtr op_div_ceil_(ObjPtr obj) { + ASSERT(obj); + return op_div_ceil_(*obj); + } - inline ObjPtr operator|=(ObjPtr obj) { - ASSERT(obj); - return operator|=(*obj); - } + ObjPtr op_div_ceil_(Obj &obj); - ObjPtr operator|=(Obj obj) { - LOG_RUNTIME("Operator '|=' not implementd!"); - } + inline ObjPtr operator%=(ObjPtr obj) { + ASSERT(obj); + return operator%=(*obj); + } - inline ObjPtr op_lshift_set(ObjPtr obj) { - ASSERT(obj); - return op_lshift_set(*obj); - } + ObjPtr operator%=(Obj obj); - ObjPtr op_lshift_set(Obj obj) { - LOG_RUNTIME("Operator '<<=' not implementd!"); - } + inline ObjPtr operator+=(ObjPtr obj) { + ASSERT(obj); + return operator+=(*obj); + } + ObjPtr operator+=(Obj obj); - inline ObjPtr op_rshift_set(ObjPtr obj) { - ASSERT(obj); - return op_rshift_set(*obj); - } + inline ObjPtr operator-=(ObjPtr obj) { + ASSERT(obj); + return operator-=(*obj); + } + ObjPtr operator-=(Obj obj); + + + ObjPtr op_bit_and_set(Obj &obj, bool strong); + + inline ObjPtr operator^=(ObjPtr obj) { + ASSERT(obj); + return operator^=(*obj); + } + + ObjPtr operator^=(Obj obj) { + LOG_RUNTIME("Operator '^=' not implementd!"); + } + + inline ObjPtr operator|=(ObjPtr obj) { + ASSERT(obj); + return operator|=(*obj); + } + + ObjPtr operator|=(Obj obj) { + LOG_RUNTIME("Operator '|=' not implementd!"); + } + + inline ObjPtr op_lshift_set(ObjPtr obj) { + ASSERT(obj); + return op_lshift_set(*obj); + } + + ObjPtr op_lshift_set(Obj obj) { + LOG_RUNTIME("Operator '<<=' not implementd!"); + } + + inline ObjPtr op_rshift_set(ObjPtr obj) { + ASSERT(obj); + return op_rshift_set(*obj); + } - ObjPtr op_rshift_set(Obj obj) { - LOG_RUNTIME("Operator '>>=' not implementd!"); - } + ObjPtr op_rshift_set(Obj obj) { + LOG_RUNTIME("Operator '>>=' not implementd!"); + } - inline ObjPtr op_rrshift_set(ObjPtr obj) { - ASSERT(obj); - return op_rrshift_set(*obj); - } + inline ObjPtr op_rrshift_set(ObjPtr obj) { + ASSERT(obj); + return op_rrshift_set(*obj); + } - ObjPtr op_rrshift_set(Obj obj) { - LOG_RUNTIME("Operator '>>>=' not implementd!"); - } + ObjPtr op_rrshift_set(Obj obj) { + LOG_RUNTIME("Operator '>>>=' not implementd!"); + } - template - bool operator=(T value) { - SetValue_(value); - return true; - } + template + bool operator=(T value) { + SetValue_(value); + return true; + } - static ObjPtr GetIndex(ObjPtr obj, TermPtr index_arg); + static ObjPtr GetIndex(ObjPtr obj, TermPtr index_arg); - static ObjPtr GetIndex(ObjPtr obj, size_t index) { - return (*obj)[index].second; - } + static ObjPtr GetIndex(ObjPtr obj, size_t index) { + return (*obj)[index].second; + } - void dump_dict_(std::string &str, bool deep = true) const { - bool first = true; - for (auto &elem : * this) { - if (first) { - first = false; - } else { - str.append(", "); - } - if (elem.first.empty()) { - if (elem.second) { - str.append(elem.second->toString(false)); + void dump_dict_(std::string &str, bool deep = true) const { + bool first = true; + for (auto &elem : * this) { + if (first) { + first = false; } else { - str.append("_"); + str.append(", "); } - } else { - if (elem.second) { - - if (deep || !(elem.second->is_tensor() || elem.second->getType() == ObjType::Class)) { - str.append(elem.first); - str.append("="); + if (elem.first.empty()) { + if (elem.second) { str.append(elem.second->toString(false)); - } else if (elem.second->getType() == ObjType::Class && elem.second->m_is_reference) { - str.append("&"); - str.append(elem.second->getName()); } else { - - str.append(elem.second->getName()); - str.append("="); - str.append(elem.second->toString()); + str.append("_"); } } else { - str.append("_"); + if (elem.second) { + + if (deep || !(elem.second->is_tensor() || elem.second->getType() == ObjType::Class)) { + str.append(elem.first); + str.append("="); + str.append(elem.second->toString(false)); + } else if (elem.second->getType() == ObjType::Class && elem.second->m_is_reference) { + str.append("&"); + str.append(elem.second->getName()); + } else { + + str.append(elem.second->getName()); + str.append("="); + str.append(elem.second->toString()); + } + } else { + str.append("_"); + } } } } - } - - std::string toString(bool deep = true) const; - std::string GetValueAsString() const; - - inline std::wstring GetValueAsStringWide() const { - return utf8_decode(GetValueAsString()); - } + std::string toString(bool deep = true) const; - inline int64_t GetValueAsInteger() const { - TEST_INIT_(); - switch (m_var_type_current) { - case ObjType::Bool: - case ObjType::Char: - case ObjType::Short: - case ObjType::Int: - case ObjType::Long: - case ObjType::Integer: - return m_value.toType(at::ScalarType::Long).item(); - - case ObjType::Float: - case ObjType::Double: - case ObjType::Number: - return static_cast (m_value.item()); - - case ObjType::Fraction: - ASSERT(m_fraction); - return m_fraction->GetAsInteger(); - - case ObjType::StrWide: - return std::stoll(m_wstr); - case ObjType::StrChar: - return std::stoll(m_str); - default: - if (m_var_type_current == ObjType::Pointer || m_var_type_fixed == ObjType::Pointer) { - return reinterpret_cast (m_func_ptr); - } - LOG_RUNTIME("Data type incompatible %s", toString().c_str()); - } - return 0; - } + std::string GetValueAsString() const; - inline double GetValueAsNumber() const { - TEST_INIT_(); - switch (m_var_type_current) { - case ObjType::Float: - case ObjType::Double: - return m_value.item(); - - case ObjType::Fraction: - ASSERT(m_fraction); - return m_fraction->GetAsNumber(); - - case ObjType::StrWide: - return std::stod(m_wstr); - case ObjType::StrChar: - return std::stod(m_str); - - default: - if (is_simple()) { - return static_cast (GetValueAsInteger()); - } + inline std::wstring GetValueAsStringWide() const { + return utf8_decode(GetValueAsString()); } - LOG_RUNTIME("Data type incompatible %s", toString().c_str()); - } - inline bool GetValueAsBoolean() const { - if (!m_var_is_init) { - return false; - } - if (is_scalar()) { - return m_value.toType(at::ScalarType::Bool).item(); - } else if (isSimpleType(m_var_type_current)) { - // Error: Boolean value of Tensor with more than one value is ambiguous - return !at::_is_zerotensor(m_value); - } else { + inline int64_t GetValueAsInteger() const { + TEST_INIT_(); switch (m_var_type_current) { + case ObjType::Bool: + case ObjType::Char: + case ObjType::Short: + case ObjType::Int: + case ObjType::Long: + case ObjType::Integer: + return m_value.toType(at::ScalarType::Long).item(); + + case ObjType::Float: + case ObjType::Double: + case ObjType::Number: + return static_cast (m_value.item()); + + case ObjType::Fraction: + ASSERT(m_fraction); + return m_fraction->GetAsInteger(); + case ObjType::StrWide: - return !m_wstr.empty(); + return std::stoll(m_wstr); case ObjType::StrChar: - return !m_str.empty(); - case ObjType::None: - return false; + return std::stoll(m_str); + default: + if (m_var_type_current == ObjType::Pointer || m_var_type_fixed == ObjType::Pointer) { + return reinterpret_cast (m_func_ptr); + } + LOG_RUNTIME("Data type incompatible %s", toString().c_str()); + } + return 0; + } + + inline double GetValueAsNumber() const { + TEST_INIT_(); + switch (m_var_type_current) { + case ObjType::Float: + case ObjType::Double: + return m_value.item(); case ObjType::Fraction: ASSERT(m_fraction); - return m_fraction->GetAsInteger(); + return m_fraction->GetAsNumber(); + + case ObjType::StrWide: + return std::stod(m_wstr); + case ObjType::StrChar: + return std::stod(m_str); - case ObjType::Dictionary: - case ObjType::Class: - if (size()) { - return true; + default: + if (is_simple()) { + return static_cast (GetValueAsInteger()); } - for (auto &elem : m_class_parents) { - if (elem->GetValueAsBoolean()) { + } + LOG_RUNTIME("Data type incompatible %s", toString().c_str()); + } + + inline bool GetValueAsBoolean() const { + if (!m_var_is_init) { + return false; + } + if (is_scalar()) { + return m_value.toType(at::ScalarType::Bool).item(); + } else if (isSimpleType(m_var_type_current)) { + // Error: Boolean value of Tensor with more than one value is ambiguous + return !at::_is_zerotensor(m_value); + } else { + switch (m_var_type_current) { + case ObjType::StrWide: + return !m_wstr.empty(); + case ObjType::StrChar: + return !m_str.empty(); + case ObjType::None: + return false; + + case ObjType::Fraction: + ASSERT(m_fraction); + return m_fraction->GetAsInteger(); + + case ObjType::Dictionary: + case ObjType::Class: + if (size()) { return true; } - } - return false; + for (auto &elem : m_class_parents) { + if (elem->GetValueAsBoolean()) { + return true; + } + } + return false; - default: - LOG_RUNTIME("Type cast to bool %s", toString().c_str()); + default: + LOG_RUNTIME("Type cast to bool %s", toString().c_str()); + } + return true; } - return true; } - } - at::Scalar toTorchScalar() { - at::Scalar result; - if (is_integer() || is_bool_type()) { - result = at::Scalar(GetValueAsInteger()); - } else if (is_floating()) { - result = at::Scalar(GetValueAsNumber()); - } else { - LOG_RUNTIME("Not support Torch ScalarType '%s'", newlang::toString(m_var_type_current)); + at::Scalar toTorchScalar() { + at::Scalar result; + if (is_integer() || is_bool_type()) { + result = at::Scalar(GetValueAsInteger()); + } else if (is_floating()) { + result = at::Scalar(GetValueAsNumber()); + } else { + LOG_RUNTIME("Not support Torch ScalarType '%s'", newlang::toString(m_var_type_current)); + } + return result; + } - return result; - } + static ObjPtr CreateType(ObjType type, ObjType fixed = ObjType::None, bool is_init = false) { + return std::make_shared(type, nullptr, nullptr, fixed, is_init); + } - static ObjPtr CreateType(ObjType type, ObjType fixed = ObjType::None, bool is_init = false) { - return std::make_shared(type, nullptr, nullptr, fixed, is_init); - } + static ObjPtr CreateFraction(const std::string_view val) { - static ObjPtr CreateFraction(const std::string_view val) { + std::string str; + std::remove_copy(val.begin(), val.end(), back_inserter(str), '_'); - std::string str; - std::remove_copy(val.begin(), val.end(), back_inserter(str), '_'); + if (str.empty()) { + LOG_RUNTIME("Empty string!"); + } - if (str.empty()) { - LOG_RUNTIME("Empty string!"); - } + ObjPtr frac = Obj::CreateType(ObjType::Fraction); - ObjPtr frac = Obj::CreateType(ObjType::Fraction); + // Ищем разделитель дроби + size_t pos = str.find("\\"); - // Ищем разделитель дроби - size_t pos = str.find("\\"); + // Если символ не найден - то вся строка является числом + if (pos == std::string::npos) { + frac->m_fraction = std::make_shared(str, "1"); + } else { + // Числитель - левая часть + // Знаменатель - правая часть + frac->m_fraction = std::make_shared(str.substr(0, pos), str.substr(pos + 1, str.length())); + // Знаменатель не должен быть равен нулю + if (frac->m_fraction->m_denominator.isZero()) { + LOG_RUNTIME("Denominator must be different from zero!"); + } + } - // Если символ не найден - то вся строка является числом - if (pos == std::string::npos) { - frac->m_fraction = std::make_shared(str, "1"); - } else { - // Числитель - левая часть - // Знаменатель - правая часть - frac->m_fraction = std::make_shared(str.substr(0, pos), str.substr(pos + 1, str.length())); - // Знаменатель не должен быть равен нулю - if (frac->m_fraction->m_denominator.isZero()) { - LOG_RUNTIME("Denominator must be different from zero!"); + frac->m_var_is_init = true; + if (str.compare(frac->m_fraction->GetAsString().c_str()) != 0) { + LOG_RUNTIME("Fraction value '%s' does not match source string '%s'!", frac->m_fraction->GetAsString().c_str(), str.c_str()); } - } - frac->m_var_is_init = true; - if (str.compare(frac->m_fraction->GetAsString().c_str()) != 0) { - LOG_RUNTIME("Fraction value '%s' does not match source string '%s'!", frac->m_fraction->GetAsString().c_str(), str.c_str()); + return frac; } - return frac; - } - - // чистая функция - static ObjPtr BaseTypeConstructor(const Context *ctx, Obj &in); - static ObjPtr ConstructorSimpleType_(const Context *ctx, Obj & args); - static ObjPtr ConstructorDictionary_(const Context *ctx, Obj & args); - static ObjPtr ConstructorNative_(const Context *ctx, Obj & args); - static ObjPtr ConstructorClass_(const Context *ctx, Obj & args); - static ObjPtr ConstructorStruct_(const Context *ctx, Obj & args); - static ObjPtr ConstructorEnum_(const Context *ctx, Obj & args); + // чистая функция + static ObjPtr BaseTypeConstructor(const Context *ctx, Obj &in); + static ObjPtr ConstructorSimpleType_(const Context *ctx, Obj & args); + static ObjPtr ConstructorDictionary_(const Context *ctx, Obj & args); + static ObjPtr ConstructorNative_(const Context *ctx, Obj & args); + static ObjPtr ConstructorClass_(const Context *ctx, Obj & args); + static ObjPtr ConstructorStruct_(const Context *ctx, Obj & args); + static ObjPtr ConstructorEnum_(const Context *ctx, Obj & args); - static ObjPtr ConstructorError_(const Context *ctx, Obj & args); - static ObjPtr ConstructorReturn_(const Context *ctx, Obj & args); - static ObjPtr ConstructorInterraption_(const Context *ctx, Obj & args, ObjType type); + static ObjPtr ConstructorError_(const Context *ctx, Obj & args); + static ObjPtr ConstructorReturn_(const Context *ctx, Obj & args); + static ObjPtr ConstructorInterraption_(const Context *ctx, Obj & args, ObjType type); - static ObjPtr CreateBaseType(ObjType type); + static ObjPtr CreateBaseType(ObjType type); - static ObjPtr CreateNone() { - return CreateType(ObjType::None, ObjType::None, true); - } + static ObjPtr CreateNone() { + return CreateType(ObjType::None, ObjType::None, true); + } - template - static ObjPtr CreateRange(T1 start, T2 stop, T3 step) { - ObjPtr obj = CreateType(ObjType::Range); - obj->push_back(CreateValue(start, ObjType::None), "start"); - obj->push_back(CreateValue(stop, ObjType::None), "stop"); - obj->push_back(CreateValue(step, ObjType::None), "step"); - obj->m_var_is_init = true; - return obj; - } + template + static ObjPtr CreateRange(T1 start, T2 stop, T3 step) { + ObjPtr obj = CreateType(ObjType::Range); + obj->push_back(CreateValue(start, ObjType::None), "start"); + obj->push_back(CreateValue(stop, ObjType::None), "stop"); + obj->push_back(CreateValue(step, ObjType::None), "step"); + obj->m_var_is_init = true; + return obj; + } - template - static ObjPtr CreateRange(T1 start, T2 stop) { - ObjPtr obj = CreateType(ObjType::Range); - obj->push_back(CreateValue(start, ObjType::None), "start"); - obj->push_back(CreateValue(stop, ObjType::None), "stop"); - if (start < stop) { - obj->push_back(CreateValue(1, ObjType::None), "step"); - } else { - obj->push_back(CreateValue(-1, ObjType::None), "step"); - } - obj->m_var_is_init = true; - return obj; - } + template + static ObjPtr CreateRange(T1 start, T2 stop) { + ObjPtr obj = CreateType(ObjType::Range); + obj->push_back(CreateValue(start, ObjType::None), "start"); + obj->push_back(CreateValue(stop, ObjType::None), "stop"); + if (start < stop) { + obj->push_back(CreateValue(1, ObjType::None), "step"); + } else { + obj->push_back(CreateValue(-1, ObjType::None), "step"); + } + obj->m_var_is_init = true; + return obj; + } - static ObjType GetType(torch::Tensor & val) { - switch (val.dtype().toScalarType()) { - case at::ScalarType::Bool: - return ObjType::Bool; - case at::ScalarType::Half: - case at::ScalarType::BFloat16: - case at::ScalarType::Float: - return ObjType::Float; - case at::ScalarType::Double: - return ObjType::Double; - case at::ScalarType::Byte: - case at::ScalarType::Char: - case at::ScalarType::QInt8: - case at::ScalarType::QUInt8: - case at::ScalarType::QUInt4x2: - return ObjType::Char; - case at::ScalarType::Short: - return ObjType::Short; - case at::ScalarType::Int: - case at::ScalarType::QInt32: - return ObjType::Int; - case at::ScalarType::Long: - return ObjType::Long; - case at::ScalarType::ComplexHalf: - case at::ScalarType::ComplexFloat: - return ObjType::ComplexFloat; - case at::ScalarType::ComplexDouble: - return ObjType::ComplexDouble; - } - LOG_RUNTIME("Fail tensor type %s", val.toString().c_str()); - } + static ObjType GetType(torch::Tensor & val) { + switch (val.dtype().toScalarType()) { + case at::ScalarType::Bool: + return ObjType::Bool; + case at::ScalarType::Half: + case at::ScalarType::BFloat16: + case at::ScalarType::Float: + return ObjType::Float; + case at::ScalarType::Double: + return ObjType::Double; + case at::ScalarType::Byte: + case at::ScalarType::Char: + case at::ScalarType::QInt8: + case at::ScalarType::QUInt8: + case at::ScalarType::QUInt4x2: + return ObjType::Char; + case at::ScalarType::Short: + return ObjType::Short; + case at::ScalarType::Int: + case at::ScalarType::QInt32: + return ObjType::Int; + case at::ScalarType::Long: + return ObjType::Long; + case at::ScalarType::ComplexHalf: + case at::ScalarType::ComplexFloat: + return ObjType::ComplexFloat; + case at::ScalarType::ComplexDouble: + return ObjType::ComplexDouble; + } + LOG_RUNTIME("Fail tensor type %s", val.toString().c_str()); + } - static ObjPtr CreateBool(bool value) { - ObjPtr result = CreateType(ObjType::None); - result->m_value = torch::scalar_tensor(value, torch::Dtype::Bool); - result->m_var_type_current = ObjType::Bool; - result->m_var_is_init = true; - return result; - } + static ObjPtr CreateBool(bool value) { + ObjPtr result = CreateType(ObjType::None); + result->m_value = torch::scalar_tensor(value, torch::Dtype::Bool); + result->m_var_type_current = ObjType::Bool; + result->m_var_is_init = true; + return result; + } - static ObjPtr CreateTensor(torch::Tensor tensor) { - ObjType check_type = GetType(tensor); - if (!isTensor(check_type)) { - LOG_RUNTIME("Unsupport torch type %s (%d)!", at::toString(tensor.dtype().toScalarType()), (int) tensor.dtype().toScalarType()); + static ObjPtr CreateTensor(torch::Tensor tensor) { + ObjType check_type = GetType(tensor); + if (!isTensor(check_type)) { + LOG_RUNTIME("Unsupport torch type %s (%d)!", at::toString(tensor.dtype().toScalarType()), (int) tensor.dtype().toScalarType()); + } + ObjPtr result = CreateType(check_type); + result->m_value = tensor; + result->m_var_is_init = true; + return result; } - ObjPtr result = CreateType(check_type); - result->m_value = tensor; - result->m_var_is_init = true; - return result; - } - static ObjPtr CreateTensor(ObjPtr data, ObjType type) { - torch::Tensor var = ConvertToTensor(data.get(), toTorchType(type), false); - // ConvertToTensor(data->index_get({0}).get(), type, false); - return CreateTensor(var); - } + static ObjPtr CreateTensor(ObjPtr data, ObjType type) { + torch::Tensor var = ConvertToTensor(data.get(), toTorchType(type), false); + // ConvertToTensor(data->index_get({0}).get(), type, false); + return CreateTensor(var); + } - inline torch::Tensor toTensor() { - return ConvertToTensor(this); - } + inline torch::Tensor toTensor() { + return ConvertToTensor(this); + } - inline torch::Tensor & asTensor_() { - NL_CHECK(is_tensor(), "Fail type as Tensor"); - return m_value; - } + inline torch::Tensor & asTensor_() { + NL_CHECK(is_tensor(), "Fail type as Tensor"); + return m_value; + } - at::indexing::Slice toSlice() { - NL_CHECK(is_range(), "Convert to slice supported for range only!"); + at::indexing::Slice toSlice() { + NL_CHECK(is_range(), "Convert to slice supported for range only!"); - ASSERT(size() == 3 && Variable::at("start").second && Variable::at("stop").second && Variable::at("step").second); + ASSERT(size() == 3 && Variable::at("start").second && Variable::at("stop").second && Variable::at("step").second); - NL_CHECK(Variable::at("start").second->is_integer(), "Slice value start support integer type only!"); - NL_CHECK(Variable::at("stop").second->is_integer(), "Slice value stop support integer type only!"); - NL_CHECK(Variable::at("step").second->is_integer(), "Slice value step support integer type only!"); + NL_CHECK(Variable::at("start").second->is_integer(), "Slice value start support integer type only!"); + NL_CHECK(Variable::at("stop").second->is_integer(), "Slice value stop support integer type only!"); + NL_CHECK(Variable::at("step").second->is_integer(), "Slice value step support integer type only!"); - return at::indexing::Slice( - Variable::at("start").second->GetValueAsInteger(), - Variable::at("stop").second->GetValueAsInteger(), - Variable::at("step").second->GetValueAsInteger()); - } + return at::indexing::Slice( + Variable::at("start").second->GetValueAsInteger(), + Variable::at("stop").second->GetValueAsInteger(), + Variable::at("step").second->GetValueAsInteger()); + } - /* - * From TensorIndexing.h -// There is one-to-one correspondence between Python and C++ tensor index types: -// Python | C++ -// ----------------------------------------------------- -// `None` | `at::indexing::None` -// `Ellipsis` | `at::indexing::Ellipsis` -// `...` | `"..."` -// `123` | `123` -// `True` / `False` | `true` / `false` -// `:` | `Slice()` / `Slice(None, None)` -// `::` | `Slice()` / `Slice(None, None, None)` -// `1:` | `Slice(1, None)` -// `1::` | `Slice(1, None, None)` -// `:3` | `Slice(None, 3)` -// `:3:` | `Slice(None, 3, None)` -// `::2` | `Slice(None, None, 2)` -// `1:3` | `Slice(1, 3)` -// `1::2` | `Slice(1, None, 2)` -// `:3:2` | `Slice(None, 3, 2)` -// `1:3:2` | `Slice(1, 3, 2)` -// `torch.tensor([1, 2])`) | `torch::tensor({1, 2})` - */ - Index toIndex() { - if (is_none_type()) { - return Index(c10::nullopt); - } else if (is_dictionary_type()) { - std::vector temp = toIntVector(true); - if (temp.size()) { - torch::Tensor tensor = torch::from_blob(temp.data(), temp.size(), torch::Dtype::Long); - return Index(tensor.clone()); - } else { + /* + * From TensorIndexing.h + // There is one-to-one correspondence between Python and C++ tensor index types: + // Python | C++ + // ----------------------------------------------------- + // `None` | `at::indexing::None` + // `Ellipsis` | `at::indexing::Ellipsis` + // `...` | `"..."` + // `123` | `123` + // `True` / `False` | `true` / `false` + // `:` | `Slice()` / `Slice(None, None)` + // `::` | `Slice()` / `Slice(None, None, None)` + // `1:` | `Slice(1, None)` + // `1::` | `Slice(1, None, None)` + // `:3` | `Slice(None, 3)` + // `:3:` | `Slice(None, 3, None)` + // `::2` | `Slice(None, None, 2)` + // `1:3` | `Slice(1, 3)` + // `1::2` | `Slice(1, None, 2)` + // `:3:2` | `Slice(None, 3, 2)` + // `1:3:2` | `Slice(1, 3, 2)` + // `torch.tensor([1, 2])`) | `torch::tensor({1, 2})` + */ + Index toIndex() { + if (is_none_type()) { return Index(c10::nullopt); - } - - } else if (is_scalar()) { - switch (m_var_type_current) { - case ObjType::Bool: - return Index(GetValueAsBoolean()); + } else if (is_dictionary_type()) { + std::vector temp = toIntVector(true); + if (temp.size()) { + torch::Tensor tensor = torch::from_blob(temp.data(), temp.size(), torch::Dtype::Long); + return Index(tensor.clone()); + } else { + return Index(c10::nullopt); + } - case ObjType::Char: - case ObjType::Short: - case ObjType::Int: - case ObjType::Long: - return Index(GetValueAsInteger()); - default: - LOG_RUNTIME("Fail convert scalar type '%s' to Index!", newlang::toString(m_var_type_current)); + } else if (is_scalar()) { + switch (m_var_type_current) { + case ObjType::Bool: + return Index(GetValueAsBoolean()); + + case ObjType::Char: + case ObjType::Short: + case ObjType::Int: + case ObjType::Long: + return Index(GetValueAsInteger()); + default: + LOG_RUNTIME("Fail convert scalar type '%s' to Index!", newlang::toString(m_var_type_current)); + } + } else if (is_tensor()) { + return Index(m_value); + } else if (is_ellipsis()) { + return Index(at::indexing::Ellipsis); + } else if (is_range()) { + return Index(toSlice()); } - } else if (is_tensor()) { - return Index(m_value); - } else if (is_ellipsis()) { - return Index(at::indexing::Ellipsis); - } else if (is_range()) { - return Index(toSlice()); - } - LOG_RUNTIME("Fail convert object '%s' to Index!", toString().c_str()); - } + LOG_RUNTIME("Fail convert object '%s' to Index!", toString().c_str()); + } - inline operator bool () const { - return GetValueAsBoolean(); - } + inline operator bool () const { + return GetValueAsBoolean(); + } - inline operator at::Tensor() { - return ConvertToTensor(this); - } + inline operator at::Tensor() { + return ConvertToTensor(this); + } - inline operator at::TensorOptions() const { - return ConvertToTensorOptions(this); - } + inline operator at::TensorOptions() const { + return ConvertToTensorOptions(this); + } - inline operator at::DimnameList() const { - return ConvertToDimnameList(this); - } + inline operator at::DimnameList() const { + return ConvertToDimnameList(this); + } - std::vector toIntVector(bool raise = true) const { - std::vector result; - for (int i = 0; i < size(); i++) { - if (raise && !at(i).second->is_integer()) { - LOG_RUNTIME("Item does not contain an integer value! '%s'", at(i).second->GetValueAsString().c_str()); + std::vector toIntVector(bool raise = true) const { + std::vector result; + for (int i = 0; i < size(); i++) { + if (raise && !at(i).second->is_integer()) { + LOG_RUNTIME("Item does not contain an integer value! '%s'", at(i).second->GetValueAsString().c_str()); + } + result.push_back(at(i).second->GetValueAsInteger()); } - result.push_back(at(i).second->GetValueAsInteger()); + return result; } - return result; - } - // ПЕРЕКРЫВАЕТ ДРУГИЕ МЕТОДЫ !!!!!!!!!!!!!! at::TensorOptions() - // inline operator std::string () const { - // return GetValueAsString(); - // } - - template - typename std::enable_if::value, ObjPtr>::type - static CreateValue(T value, ObjType fix_type = ObjType::None) { - ObjPtr result = CreateType(fix_type); - result->m_var_type_fixed = fix_type; - result->m_var_type_current = typeFromLimit((int64_t) value); - if (fix_type != ObjType::None) { - NL_CHECK(canCast(result->m_var_type_current, fix_type), - "Fail cast type from '%s' to '%s'!", newlang::toString(result->m_var_type_current), newlang::toString(fix_type)); - } - result->m_value = torch::scalar_tensor(value, toTorchType(result->m_var_type_current)); - result->m_var_is_init = true; - return result; - } + // ПЕРЕКРЫВАЕТ ДРУГИЕ МЕТОДЫ !!!!!!!!!!!!!! at::TensorOptions() + // inline operator std::string () const { + // return GetValueAsString(); + // } + + template + typename std::enable_if::value, ObjPtr>::type + static CreateValue(T value, ObjType fix_type = ObjType::None) { + ObjPtr result = CreateType(fix_type); + result->m_var_type_fixed = fix_type; + result->m_var_type_current = typeFromLimit((int64_t) value); + if (fix_type != ObjType::None) { + NL_CHECK(canCast(result->m_var_type_current, fix_type), + "Fail cast type from '%s' to '%s'!", newlang::toString(result->m_var_type_current), newlang::toString(fix_type)); + } + result->m_value = torch::scalar_tensor(value, toTorchType(result->m_var_type_current)); + result->m_var_is_init = true; + return result; + } - template - typename std::enable_if::value, ObjPtr>::type - static CreateValue(T value, ObjType fix_type = ObjType::None) { - ObjPtr result = CreateType(fix_type); - result->m_var_type_fixed = fix_type; - result->m_var_type_current = typeFromLimit((double) value); - if (fix_type != ObjType::None) { - NL_CHECK(canCast(result->m_var_type_current, fix_type), - "Fail cast type from '%s' to '%s'!", newlang::toString(result->m_var_type_current), newlang::toString(fix_type)); - } - result->m_value = torch::scalar_tensor(value, toTorchType(result->m_var_type_current)); - result->m_var_is_init = true; - return result; - } + template + typename std::enable_if::value, ObjPtr>::type + static CreateValue(T value, ObjType fix_type = ObjType::None) { + ObjPtr result = CreateType(fix_type); + result->m_var_type_fixed = fix_type; + result->m_var_type_current = typeFromLimit((double) value); + if (fix_type != ObjType::None) { + NL_CHECK(canCast(result->m_var_type_current, fix_type), + "Fail cast type from '%s' to '%s'!", newlang::toString(result->m_var_type_current), newlang::toString(fix_type)); + } + result->m_value = torch::scalar_tensor(value, toTorchType(result->m_var_type_current)); + result->m_var_is_init = true; + return result; + } - static ObjPtr CreateString(const std::string str) { - ObjPtr result = CreateType(ObjType::StrChar); - result->m_str = str; - result->m_var_type_fixed = ObjType::String; - result->m_var_is_init = true; - return result; - } + static ObjPtr CreateString(const std::string str) { + ObjPtr result = CreateType(ObjType::StrChar); + result->m_str = str; + result->m_var_type_fixed = ObjType::String; + result->m_var_is_init = true; + return result; + } - static ObjPtr CreateString(const std::wstring str) { - ObjPtr result = CreateType(ObjType::StrWide); - result->m_wstr = str; - result->m_var_type_fixed = ObjType::String; - result->m_var_is_init = true; - return result; - } + static ObjPtr CreateString(const std::wstring str) { + ObjPtr result = CreateType(ObjType::StrWide); + result->m_wstr = str; + result->m_var_type_fixed = ObjType::String; + result->m_var_is_init = true; + return result; + } - inline static ObjPtr Yes() { - ObjPtr result = std::make_shared(ObjType::Bool); - bool value = true; - result->m_value = torch::scalar_tensor(value); - result->m_var_is_init = true; - return result->MakeConst(); - } + inline static ObjPtr Yes() { + ObjPtr result = std::make_shared(ObjType::Bool); + bool value = true; + result->m_value = torch::scalar_tensor(value); + result->m_var_is_init = true; + return result->MakeConst(); + } - inline static ObjPtr No() { - ObjPtr result = std::make_shared(ObjType::Bool); - bool value = false; - result->m_value = torch::scalar_tensor(value); - result->m_var_is_init = true; - return result->MakeConst(); - } + inline static ObjPtr No() { + ObjPtr result = std::make_shared(ObjType::Bool); + bool value = false; + result->m_value = torch::scalar_tensor(value); + result->m_var_is_init = true; + return result->MakeConst(); + } - inline static ObjPtr CreateDict() { - return Obj::CreateType(ObjType::Dictionary); - } + inline static ObjPtr CreateDict() { + return Obj::CreateType(ObjType::Dictionary); + } - template - typename std::enable_if::value, ObjPtr>::type - static CreateDict(T ... args) { - std::array < PairType, sizeof...(args) > list = {args...}; - ObjPtr result = Obj::CreateType(ObjType::Dictionary); - for (auto &elem : list) { - result->push_back(elem); + template + typename std::enable_if::value, ObjPtr>::type + static CreateDict(T ... args) { + std::array < PairType, sizeof...(args) > list = {args...}; + ObjPtr result = Obj::CreateType(ObjType::Dictionary); + for (auto &elem : list) { + result->push_back(elem); + } + result->m_var_is_init = true; + return result; } - result->m_var_is_init = true; - return result; - } - inline static ObjPtr CreateClass(std::string name) { - ObjPtr result = Obj::CreateType(ObjType::Class); - result->m_class_name = name; - result->m_var_is_init = true; - return result; - } + inline static ObjPtr CreateClass(std::string name) { + ObjPtr result = Obj::CreateType(ObjType::Class); + result->m_class_name = name; + result->m_var_is_init = true; + return result; + } - template - typename std::enable_if::value, ObjPtr>::type - static CreateClass(std::string name, T ... args) { - std::array < PairType, sizeof...(args) > list = {args...}; - ObjPtr result = Obj::CreateType(ObjType::Class); - result->m_class_name = name; - for (auto &elem : list) { - result->push_back(elem); - } - result->m_var_is_init = true; - return result; - } + template + typename std::enable_if::value, ObjPtr>::type + static CreateClass(std::string name, T ... args) { + std::array < PairType, sizeof...(args) > list = {args...}; + ObjPtr result = Obj::CreateType(ObjType::Class); + result->m_class_name = name; + for (auto &elem : list) { + result->push_back(elem); + } + result->m_var_is_init = true; + return result; + } - ObjPtr CallNative(Context *ctx, Obj args); + ObjPtr CallNative(Context *ctx, Obj args); - ObjPtr Clone(const char *new_name = nullptr) const { - ObjPtr clone = Obj::CreateNone(); - CloneDataTo(*clone); - ClonePropTo(*clone); - if (new_name) { - clone->m_var_name = new_name; + ObjPtr Clone(const char *new_name = nullptr) const { + ObjPtr clone = Obj::CreateNone(); + CloneDataTo(*clone); + ClonePropTo(*clone); + if (new_name) { + clone->m_var_name = new_name; + } + clone->m_is_const = false; + clone->m_ref_count = 0; + return clone; } - clone->m_is_const = false; - clone->m_ref_count = 0; - return clone; - } - inline void CloneTo(Obj & clone) { - if (&clone == this) { - // Не клонировать сам в себя - return; + inline void CloneTo(Obj & clone) { + if (&clone == this) { + // Не клонировать сам в себя + return; + } + CloneDataTo(clone); + ClonePropTo(clone); } - CloneDataTo(clone); - ClonePropTo(clone); - } - inline void CloneTo(ObjPtr & clone) { - if (clone.get() == this) { - // Не клонировать сам в себя - return; + inline void CloneTo(ObjPtr & clone) { + if (clone.get() == this) { + // Не клонировать сам в себя + return; + } + clone.reset(); + clone = Obj::CreateNone(); + CloneDataTo(*clone); + ClonePropTo(*clone); } - clone.reset(); - clone = Obj::CreateNone(); - CloneDataTo(*clone); - ClonePropTo(*clone); - } - - void CloneDataTo(Obj & clone) const; - void ClonePropTo(Obj & clone) const; - - virtual ~Obj() { - // Clear(); - } - ObjPtr toType(ObjType target) const { - ObjPtr result = Clone(); - result->toType_(target); - return result; - } + void CloneDataTo(Obj & clone) const; + void ClonePropTo(Obj & clone) const; - ObjPtr toType_(Obj *type); - void toType_(ObjType type); + virtual ~Obj() { + // Clear(); + } - ObjPtr toShape(ObjPtr dims) const { - ObjPtr result = Clone(); - result->toShape_(dims); - return result; - } - ObjPtr toShape_(ObjPtr shape); + ObjPtr toType(ObjType target) const { + ObjPtr result = Clone(); + result->toType_(target); + return result; + } - ObjPtr Convert(ObjType type, ObjPtr shape = nullptr) const { - ObjPtr result = Clone(); - result->Convert_(type, shape); - return result; - } + ObjPtr toType_(Obj *type); + void toType_(ObjType type); - ObjPtr Convert_(ObjType type, ObjPtr shape = nullptr) { - if (shape) { - toShape_(shape); + ObjPtr toShape(ObjPtr dims) const { + ObjPtr result = Clone(); + result->toShape_(dims); + return result; } - toType_(type); - return shared(); - } - - const ObjPtr index_get(const std::vector & index) const; + ObjPtr toShape_(ObjPtr shape); - inline ObjPtr index_set(const std::vector & index, const ObjPtr value) const { - ObjPtr result = Clone(); - result->index_set_(index, value); - return result; - } - ObjPtr index_set_(const std::vector & index, const ObjPtr value); + ObjPtr Convert(ObjType type, ObjPtr shape = nullptr) const { + ObjPtr result = Clone(); + result->Convert_(type, shape); + return result; + } - inline ObjPtr op_set_index(ObjPtr index, ObjPtr value) { - return op_set_index(index->GetValueAsInteger(), value->GetValueAsString()); - } - ObjPtr op_set_index(int64_t index, std::string value); + ObjPtr Convert_(ObjType type, ObjPtr shape = nullptr) { + if (shape) { + toShape_(shape); + } + toType_(type); + return shared(); + } - template < typename T> - typename std::enable_if::value, void>::type - SetValue_(bool value) { + const ObjPtr index_get(const std::vector & index) const; - TEST_CONST_(); + inline ObjPtr index_set(const std::vector & index, const ObjPtr value) const { + ObjPtr result = Clone(); + result->index_set_(index, value); + return result; + } + ObjPtr index_set_(const std::vector & index, const ObjPtr value); - ASSERT(m_var_type_current != ObjType::Class); - clear_(); - m_value = torch::scalar_tensor(value, torch::Dtype::Bool); - m_var_type_current = GetType(m_value); - m_var_is_init = true; - } + inline ObjPtr op_set_index(ObjPtr index, ObjPtr value) { + return op_set_index(index->GetValueAsInteger(), value->GetValueAsString()); + } + ObjPtr op_set_index(int64_t index, std::string value); - template < typename T> - typename std::enable_if::value, void>::type - SetValue_(T value) { - TEST_CONST_(); - ASSERT(m_var_type_current != ObjType::Class); - clear_(); - m_value = torch::scalar_tensor(value, toTorchType(typeFromLimit((int64_t) value))); - m_var_type_current = GetType(m_value); - m_var_is_init = true; - } + template < typename T> + typename std::enable_if::value, void>::type + SetValue_(bool value) { - template < typename T> - typename std::enable_if::value, void>::type - SetValue_(T value) { + TEST_CONST_(); - TEST_CONST_(); - ASSERT(m_var_type_current != ObjType::Class); - clear_(); - m_value = torch::scalar_tensor(value, toTorchType(typeFromLimit(value))); - m_var_type_current = GetType(m_value); - m_var_is_init = true; - } + ASSERT(m_var_type_current != ObjType::Class); + clear_(); + m_value = torch::scalar_tensor(value, torch::Dtype::Bool); + m_var_type_current = GetType(m_value); + m_var_is_init = true; + } - template < typename T> - typename std::enable_if::value, void>::type - SetValue_(T text) { - std::string str(text); - SetValue_(text); - } + template < typename T> + typename std::enable_if::value, void>::type + SetValue_(T value) { + TEST_CONST_(); + ASSERT(m_var_type_current != ObjType::Class); + clear_(); + m_value = torch::scalar_tensor(value, toTorchType(typeFromLimit((int64_t) value))); + m_var_type_current = GetType(m_value); + m_var_is_init = true; + } - template < typename T> - typename std::enable_if::value, void>::type - SetValue_(T text) { - std::wstring str(text); - SetValue_(text); - } + template < typename T> + typename std::enable_if::value, void>::type + SetValue_(T value) { - void SetValue_(std::string text) { - TEST_CONST_(); - if (m_var_type_current != ObjType::StrChar) { - testConvertType(ObjType::StrChar); - m_var_type_current = ObjType::StrChar; + TEST_CONST_(); + ASSERT(m_var_type_current != ObjType::Class); + clear_(); + m_value = torch::scalar_tensor(value, toTorchType(typeFromLimit(value))); + m_var_type_current = GetType(m_value); + m_var_is_init = true; } - m_str.swap(text); - m_var_is_init = true; - } - void SetValue_(std::wstring text) { - TEST_CONST_(); - if (m_var_type_current != ObjType::StrWide) { - testConvertType(ObjType::StrWide); - m_var_type_current = ObjType::StrWide; + template < typename T> + typename std::enable_if::value, void>::type + SetValue_(T text) { + std::string str(text); + SetValue_(text); } - m_wstr.swap(text); - m_var_is_init = true; - } - inline void testConvertType(ObjType type) { - if (m_var_type_fixed == ObjType::None || canCast(type, m_var_type_fixed)) { - return; + template < typename T> + typename std::enable_if::value, void>::type + SetValue_(T text) { + std::wstring str(text); + SetValue_(text); } - LOG_RUNTIME("Cannot changed type from '%s' to '%s'!", newlang::toString(type), newlang::toString(m_var_type_fixed)); - } - inline void testResultIntegralType(ObjType type, bool upscalint) { - ObjType new_type = m_var_type_current; - if (!canCast(type, m_var_type_current)) { - testConvertType(type); - new_type = type; - } - bool check = false; - if (upscalint && isIntegralType(m_var_type_current, true) && isIntegralType(type, true)) { - if (type < ObjType::Long) { - new_type = static_cast (static_cast (type) + 1); - check = true; + void SetValue_(std::string text) { + TEST_CONST_(); + if (m_var_type_current != ObjType::StrChar) { + testConvertType(ObjType::StrChar); + m_var_type_current = ObjType::StrChar; } - if (check && m_var_type_fixed != ObjType::None && !canCast(new_type, m_var_type_fixed)) { - new_type = type; // Тип данных менять нельзя, но сама операция возможна - LOG_WARNING("Data type '%s' cannot be changed to '%s', loss of precision is possible!", newlang::toString(type), newlang::toString(m_var_type_fixed)); - } - } - if (new_type != m_var_type_current) { - m_value = m_value.toType(toTorchType(new_type)); - m_var_type_current = new_type; + m_str.swap(text); + m_var_is_init = true; } - } - void SetValue_(ObjPtr value) { - TEST_CONST_(); - if (value->is_none_type()) { - clear_(); - return; - } else if ((is_none_type() || is_tensor()) && value->is_tensor()) { + void SetValue_(std::wstring text) { + TEST_CONST_(); + if (m_var_type_current != ObjType::StrWide) { + testConvertType(ObjType::StrWide); + m_var_type_current = ObjType::StrWide; + } + m_wstr.swap(text); + m_var_is_init = true; + } - if (value->empty()) { - m_value.reset(); - m_var_is_init = false; + inline void testConvertType(ObjType type) { + if (m_var_type_fixed == ObjType::None || canCast(type, m_var_type_fixed)) { return; } + LOG_RUNTIME("Cannot changed type from '%s' to '%s'!", newlang::toString(type), newlang::toString(m_var_type_fixed)); + } - if (!canCast(value->m_var_type_current, m_var_type_current)) { - testConvertType(value->m_var_type_current); - toType_(value->getType()); + inline void testResultIntegralType(ObjType type, bool upscalint) { + ObjType new_type = m_var_type_current; + if (!canCast(type, m_var_type_current)) { + testConvertType(type); + new_type = type; } - if (is_none_type()) { - m_value = value->m_value; - m_var_type_current = value->m_var_type_current; - } else { - - if (m_value.dim() == 0 && value->m_value.dim() != 0) { - LOG_RUNTIME("Fail assign tensor to scalar!"); + bool check = false; + if (upscalint && isIntegralType(m_var_type_current, true) && isIntegralType(type, true)) { + if (type < ObjType::Long) { + new_type = static_cast (static_cast (type) + 1); + check = true; } - if (!m_var_is_init) { - m_value = value->m_value.clone(); - } else { - if (!m_value.sizes().equals(value->m_value.sizes()) && value->m_value.dim() != 0) { - LOG_RUNTIME("Different sizes of tensors!"); - } else { - setTensorValue(m_value, value->m_value); - } + if (check && m_var_type_fixed != ObjType::None && !canCast(new_type, m_var_type_fixed)) { + new_type = type; // Тип данных менять нельзя, но сама операция возможна + LOG_WARNING("Data type '%s' cannot be changed to '%s', loss of precision is possible!", newlang::toString(type), newlang::toString(m_var_type_fixed)); } } - m_var_is_init = true; - return; - } else if ((is_none_type() || is_string_type()) && value->is_string_type()) { - - switch (m_var_type_current) { - case ObjType::None: - case ObjType::StrChar: - SetValue_(value->m_str); - return; - case ObjType::StrWide: - SetValue_(value->m_wstr); - return; + if (new_type != m_var_type_current) { + m_value = m_value.toType(toTorchType(new_type)); + m_var_type_current = new_type; } + } - } else if (is_none_type() || isObjectType(m_var_type_current)) { - std::string old_name = m_var_name; - clear_(); - value->CloneDataTo(*this); - value->ClonePropTo(*this); - m_var_name.swap(old_name); - m_var_is_init = true; - - return; - } else if ((is_none_type() || m_var_type_current == ObjType::Pointer) && value->m_var_type_current == ObjType::Pointer) { - //@todo Check tree type !!! - - std::string old_name = m_var_name; - value->CloneDataTo(*this); - value->ClonePropTo(*this); - m_var_name.swap(old_name); - m_var_is_init = true; + void SetValue_(ObjPtr value) { + TEST_CONST_(); + if (value->is_none_type()) { + clear_(); + return; + } else if ((is_none_type() || is_tensor()) && value->is_tensor()) { - return; - } else if ((is_none_type() || m_var_type_current == ObjType::Function) && value->is_function()) { - //@todo Check function type args !!! + if (value->empty()) { + m_value.reset(); + m_var_is_init = false; + return; + } - std::string old_name = m_var_name; - value->CloneDataTo(*this); - value->ClonePropTo(*this); - m_var_name.swap(old_name); - m_var_is_init = true; + if (!canCast(value->m_var_type_current, m_var_type_current)) { + testConvertType(value->m_var_type_current); + toType_(value->getType()); + } + if (is_none_type()) { + m_value = value->m_value; + m_var_type_current = value->m_var_type_current; + } else { - return; - } else if ((is_none_type() || m_var_type_current == ObjType::Function || m_var_type_current == ObjType::EVAL_FUNCTION) && (value->m_var_type_current == ObjType::BLOCK || value->m_var_type_current == ObjType::BLOCK_TRY)) { - //@todo Check function type args !!! + if (m_value.dim() == 0 && value->m_value.dim() != 0) { + LOG_RUNTIME("Fail assign tensor to scalar!"); + } + if (!m_var_is_init) { + m_value = value->m_value.clone(); + } else { + if (!m_value.sizes().equals(value->m_value.sizes()) && value->m_value.dim() != 0) { + LOG_RUNTIME("Different sizes of tensors!"); + } else { + setTensorValue(m_value, value->m_value); + } + } + } + m_var_is_init = true; + return; + } else if ((is_none_type() || is_string_type()) && value->is_string_type()) { + + switch (m_var_type_current) { + case ObjType::None: + case ObjType::StrChar: + SetValue_(value->m_str); + return; + case ObjType::StrWide: + SetValue_(value->m_wstr); + return; + } - // std::string old_name = m_var_name; - // TermPtr save_proto = m_func_proto; - // TermPtr save_block = m_block_source; - // ObjType save_type = m_var_type_current; - // value->CloneDataTo(*this); - // value->ClonePropTo(*this); - // m_var_name.swap(old_name); - // m_var_is_init = true; - // *const_cast (&m_func_proto) = save_proto; - m_block_source = value->m_block_source; - // m_var_type_current = save_type; + } else if (is_none_type() || isObjectType(m_var_type_current)) { + std::string old_name = m_var_name; + clear_(); + value->CloneDataTo(*this); + value->ClonePropTo(*this); + m_var_name.swap(old_name); + m_var_is_init = true; - return; - } + return; + } else if ((is_none_type() || m_var_type_current == ObjType::Pointer) && value->m_var_type_current == ObjType::Pointer) { + //@todo Check tree type !!! - LOG_RUNTIME("Set value type '%s' not implemented!", newlang::toString(m_var_type_current)); - } + std::string old_name = m_var_name; + value->CloneDataTo(*this); + value->ClonePropTo(*this); + m_var_name.swap(old_name); + m_var_is_init = true; - static std::string format(std::string format, Obj *args); + return; + } else if ((is_none_type() || m_var_type_current == ObjType::Function) && value->is_function()) { + //@todo Check function type args !!! - void clear_() override { + std::string old_name = m_var_name; + value->CloneDataTo(*this); + value->ClonePropTo(*this); + m_var_name.swap(old_name); + m_var_is_init = true; - Variable::clear_(); - clear_(true); - } + return; + } else if ((is_none_type() || m_var_type_current == ObjType::Function || m_var_type_current == ObjType::EVAL_FUNCTION) && (value->m_var_type_current == ObjType::BLOCK || value->m_var_type_current == ObjType::BLOCK_TRY)) { + //@todo Check function type args !!! + + // std::string old_name = m_var_name; + // TermPtr save_proto = m_func_proto; + // TermPtr save_block = m_block_source; + // ObjType save_type = m_var_type_current; + // value->CloneDataTo(*this); + // value->ClonePropTo(*this); + // m_var_name.swap(old_name); + // m_var_is_init = true; + // *const_cast (&m_func_proto) = save_proto; + m_block_source = value->m_block_source; + // m_var_type_current = save_type; - void clear_(bool clear_iterator_name) { + return; + } - m_str.clear(); - m_wstr.clear(); - m_var_type_current = ObjType::None; + LOG_RUNTIME("Set value type '%s' not implemented!", newlang::toString(m_var_type_current)); + } - m_class_parents.clear(); - m_var_is_init = false; - m_value.reset(); - m_fraction.reset(); - // m_var = std::monostate(); - // m_value.reset(); //???????????????? - // m_items.clear(); - } + static std::string format(std::string format, Obj *args); - bool CallAll(const char *func_name, ObjPtr &arg_in, ObjPtr &result, ObjPtr object = nullptr, size_t limit = 0); // ? - bool CallOnce(ObjPtr &arg_in, ObjPtr &result, ObjPtr object = nullptr); // ! + bool CallAll(const char *func_name, ObjPtr &arg_in, ObjPtr &result, ObjPtr object = nullptr, size_t limit = 0); // ? + bool CallOnce(ObjPtr &arg_in, ObjPtr &result, ObjPtr object = nullptr); // ! - static ObjPtr CreateFunc(Context *ctx, TermPtr proto, ObjType type, const std::string var_name = ""); - static ObjPtr CreateFunc(std::string proto, FunctionType *func_addr, ObjType type = ObjType::Function); + static ObjPtr CreateFunc(Context *ctx, TermPtr proto, ObjType type, const std::string var_name = ""); + static ObjPtr CreateFunc(std::string proto, FunctionType *func_addr, ObjType type = ObjType::Function); - ObjPtr ConvertToArgs(Obj *args, bool check_valid, Context *ctx) const { - ObjPtr result = Clone(); - result->ConvertToArgs_(args, check_valid, ctx); + ObjPtr ConvertToArgs(Obj *args, bool check_valid, Context *ctx) const { + ObjPtr result = Clone(); + result->ConvertToArgs_(args, check_valid, ctx); - return result; - } + return result; + } - void CheckArgsValid() const; - bool CheckArgs() const; + void CheckArgsValid() const; + bool CheckArgs() const; - inline const TermPtr Proto() { + inline const TermPtr Proto() { - return m_func_proto; - } + return m_func_proto; + } -protected: + protected: - void ConvertToArgs_(Obj *args, bool check_valid, Context *ctx = nullptr); // Обновить параметры для вызова функции или элементы у словаря при создании копии + void ConvertToArgs_(Obj *args, bool check_valid, Context *ctx = nullptr); // Обновить параметры для вызова функции или элементы у словаря при создании копии -public: + public: - ObjType m_var_type_current; ///< Текущий тип значения объекта - ObjType m_var_type_fixed; ///< Максимальный размер для арифметических типов, который задается разработчиком - bool m_var_is_init; ///< Содержит ли объект корректное значение ??? + ObjType m_var_type_current; ///< Текущий тип значения объекта + ObjType m_var_type_fixed; ///< Максимальный размер для арифметических типов, который задается разработчиком + bool m_var_is_init; ///< Содержит ли объект корректное значение ??? - // struct FuncInfo { - // const TermPtr m_func_proto; - // std::string m_func_mangle_name; - // void *m_func_ptr; - // ffi_abi m_func_abi; - // }; - // std::variant m_var; + // struct FuncInfo { + // const TermPtr m_func_proto; + // std::string m_func_mangle_name; + // void *m_func_ptr; + // ffi_abi m_func_abi; + // }; + // std::variant m_var; - std::string m_var_name; ///< Имя переменной, в которой хранится объект + std::string m_var_name; ///< Имя переменной, в которой хранится объект - ObjPtr m_dimensions; ///< Размерности для ObjType::Type - std::string m_class_name; ///< Имя класса объекта (у базовых типов отсуствует) - std::vector m_class_parents; ///< Родительские классы (типы) + ObjPtr m_dimensions; ///< Размерности для ObjType::Type + std::string m_class_name; ///< Имя класса объекта (у базовых типов отсуствует) + std::vector m_class_parents; ///< Родительские классы (типы) - std::string m_namespace; - std::string m_str; - std::wstring m_wstr; - mutable PairType m_str_pair; //< Для доступа к отдельным символам строк + std::string m_namespace; + std::string m_str; + std::wstring m_wstr; + mutable PairType m_str_pair; //< Для доступа к отдельным символам строк - const TermPtr m_func_proto; - std::string m_func_mangle_name; - std::string m_module_name; - void *m_func_ptr; - ffi_abi m_func_abi; - torch::Tensor m_value; - std::shared_ptr m_fraction; - std::shared_ptr< Iterator > m_iterator; + const TermPtr m_func_proto; + std::string m_func_mangle_name; + std::string m_module_name; + void *m_func_ptr; + ffi_abi m_func_abi; + torch::Tensor m_value; + std::shared_ptr m_fraction; + std::shared_ptr< Iterator > m_iterator; - TermPtr m_block_source; - bool m_check_args; //< Проверять аргументы на корректность (для всех видов функций) @ref MakeArgs + TermPtr m_block_source; + bool m_check_args; //< Проверять аргументы на корректность (для всех видов функций) @ref MakeArgs - // Context *m_ctx; + // Context *m_ctx; - // SCOPE(protected) : - bool m_is_const; //< Признак константы (по умолчанию изменения разрешено) - bool m_is_reference; //< Признак ссылки на объект (mutable) - size_t m_ref_count; + // SCOPE(protected) : + bool m_is_const; //< Признак константы (по умолчанию изменения разрешено) + bool m_is_reference; //< Признак ссылки на объект (mutable) + size_t m_ref_count; -}; + }; } // namespace newlang diff --git a/src/variable.h b/src/variable.h index ed38b757..61b0a5f2 100644 --- a/src/variable.h +++ b/src/variable.h @@ -93,12 +93,12 @@ namespace newlang { return push_back(pair(value, name)); } - inline PairType top() const { - if (ListType::empty()) { - LOG_RUNTIME("Empty Index '%ld' not exists!", index); - } - return *ListType::back(); - } + // inline PairType top() const { + // if (ListType::empty()) { + // LOG_RUNTIME("Empty Index '%ld' not exists!", index); + // } + // return *ListType::back(); + // } static inline PairType pair(const Type value, const std::string name = "") { return std::pair(name, value); From fa98286d1d9e2d329528498eb102cdf71d3b7176 Mon Sep 17 00:00:00 2001 From: Aleksandr Ryabikov Date: Wed, 13 Jul 2022 15:16:25 +0300 Subject: [PATCH 22/31] =?UTF-8?q?=D0=92=D1=81=D1=82=D1=80=D0=BE=D0=B8?= =?UTF-8?q?=D0=BB=20=D0=BF=D0=B5=D1=80=D0=B2=D1=8B=D0=B9=20=D0=B2=D0=B0?= =?UTF-8?q?=D1=80=D0=B8=D0=BD=D1=82=20=D0=B8=D1=82=D0=B5=D1=80=D0=B0=D1=82?= =?UTF-8?q?=D0=BE=D1=80=D0=BE=D0=B2=20=D0=B2=20=D1=81=D0=B8=D0=BD=D1=82?= =?UTF-8?q?=D0=B0=D0=BA=D1=81=D0=B8=D1=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/context.cpp | 20 ++- src/lexer.l | 4 +- src/object.cpp | 36 ++++- src/object.h | 7 +- src/parser.y | 27 ++-- src/test/eval_test.cpp | 288 ++++++++++++++++----------------------- src/test/object_test.cpp | 10 +- 7 files changed, 203 insertions(+), 189 deletions(-) diff --git a/src/context.cpp b/src/context.cpp index d0b1863d..8e4194ae 100644 --- a/src/context.cpp +++ b/src/context.cpp @@ -2280,12 +2280,28 @@ ObjPtr Context::CreateRVal(Context *ctx, TermPtr term, Obj * local_vars, bool in } else if(term->m_text.compare("!!") == 0) { return temp->IteratorNext(1); } else if(term->m_text.compare("!?") == 0 || term->m_text.compare("?!") == 0) { - result = temp->MakeIterator(args.get()); - return result->IteratorNext(std::numeric_limits::max()); + + val_int = std::numeric_limits::max(); + if(args->empty() || (args->size() == 1 && args->at(0).second->is_integer())) { + result = temp->MakeIterator(Iterator::FIND_KEY_DEFAULT, false); + if(args->size()) { + val_int = args->at(0).second->GetValueAsInteger(); + } + } else if(args->size() == 1 && args->at(0).second->is_string_type()) { + result = temp->MakeIterator(args->at(0).second->GetValueAsString(), false); + } else if(args->size() == 2 && args->at(0).second->is_string_type() && args->at(1).second->is_integer()) { + result = temp->MakeIterator(args->at(0).second->GetValueAsString(), false); + val_int = args->at(1).second->GetValueAsInteger(); + } else { + LOG_RUNTIME("Iterator`s args '%s' not allowed!", args->toString().c_str()); + } + return result->IteratorNext(val_int); + } else { LOG_RUNTIME("Iterator '%s' not recognized in '%s'!", term->m_text.c_str(), term->toString().c_str()); } + } LOG_RUNTIME("Fail create type %s from '%s'", newlang::toString(term->getTermID()), term->toString().c_str()); diff --git a/src/lexer.l b/src/lexer.l index cc14ee99..d4bcf9df 100644 --- a/src/lexer.l +++ b/src/lexer.l @@ -447,8 +447,8 @@ term [$@%]({ualpha}|[_])?({name})? ">" YY_TOKEN(OPERATOR); -"!!" YY_TOKEN(ITERATOR); -"??" YY_TOKEN(ITERATOR); +"!!" YY_TOKEN_ONLY(ITERATOR_QQ); +"??" YY_TOKEN_ONLY(ITERATOR_QQ); "?!" YY_TOKEN(ITERATOR); "!?" YY_TOKEN(ITERATOR); diff --git a/src/object.cpp b/src/object.cpp index 35180d94..ffa66639 100644 --- a/src/object.cpp +++ b/src/object.cpp @@ -574,6 +574,7 @@ void Obj::CloneDataTo(Obj & clone) const { if(m_fraction) { clone.m_fraction = std::make_shared(*m_fraction.get()); } + clone.m_iterator = m_iterator; clone.m_class_parents = m_class_parents; clone.m_class_name = m_class_name; @@ -2954,9 +2955,40 @@ ObjPtr Iterator::read_and_next(int64_t count) { return result; } -ObjPtr Obj::MakeIterator(Obj * args) { +ObjPtr Obj::MakeIterator(const std::string filter, bool check_create) { ObjPtr result = CreateType(ObjType::Iterator, ObjType::Iterator, true); - result->m_iterator = std::make_shared> (shared()); + if(!is_indexing()) { + if(getType() == ObjType::Iterator && !check_create) { + return shared(); + } + LOG_RUNTIME("Can't create iterator from '%s'!", toString().c_str()); + } + result->m_iterator = std::make_shared> (shared(), filter); + return result; +} + +ObjPtr Obj::MakeIterator(Obj *args) { + ObjPtr result = CreateType(ObjType::Iterator, ObjType::Iterator, true); + if(!is_indexing()) { + if(getType() == ObjType::Iterator) { + return shared(); + } + LOG_RUNTIME("Can't create iterator from '%s'!", toString().c_str()); + } + + if(!args || args->size() == 0) { + result->m_iterator = std::make_shared> (shared()); + } else if(args->size() == 1 && args->at(0).second && args->at(0).second->is_string_type()) { + result->m_iterator = std::make_shared> (shared(), args->GetValueAsString()); + } else if(args->size() >= 1 && args->at(0).second && args->at(0).second->is_function()) { + ASSERT(false); + // ObjPtr func = args->at(0).second; + // ObjPtr func_arg = args->Clone(); + // func_arg->resize_(-(func_arg->size() - 1)); // Удалить первый элемент + // result->m_iterator = std::make_shared> (shared(), func.get(), func_arg.get()); + } else { + LOG_RUNTIME("Invalid arguments for iterator create! '%s'", args->toString().c_str()); + } return result; } diff --git a/src/object.h b/src/object.h index 9e032dcd..e8a24bf9 100755 --- a/src/object.h +++ b/src/object.h @@ -128,12 +128,14 @@ namespace newlang { typedef IterCmp CompareFuncType(const IterPairType &pair, const T *args, void *extra); + inline static const std::string FIND_KEY_DEFAULT = "(.|\\n)*"; + /** * Итератор для элементов списка с regex фильтром по имени элемента (по умолчанию для всех элементов списка) * @param obj * @param find_key */ - Iterator(std::shared_ptr obj, const std::string find_key = "(.|\\n)*") : + Iterator(std::shared_ptr obj, const std::string find_key = FIND_KEY_DEFAULT) : Iterator(obj, &CompareFuncDefault, reinterpret_cast (const_cast (&find_key)), static_cast (this)) { } @@ -344,7 +346,8 @@ namespace newlang { return shared(); } - ObjPtr MakeIterator(Obj * args); + ObjPtr MakeIterator(const std::string, bool check_create = true); + ObjPtr MakeIterator(Obj *args); ObjPtr IteratorReset(); inline ObjPtr IteratorNext(ObjPtr count) { diff --git a/src/parser.y b/src/parser.y index 0aa2860b..2a36d574 100644 --- a/src/parser.y +++ b/src/parser.y @@ -380,6 +380,7 @@ star_arg = [STAR] STAR ID %token SOURCE %token ITERATOR +%token ITERATOR_QQ %token PUREFUNC %token SIMPLE_AND @@ -774,12 +775,6 @@ rval_var: rval_name $$ = $2; $$->Last()->Append($1, Term::LEFT); } - | rval_name iter_all call - { - $$ = $2; - $$->Last()->Append($1, Term::LEFT); - $$->SetArgs($call); - } | string { $$ = $1; @@ -809,20 +804,36 @@ rval: rval_var } +iter_call: '?' + { + $$=$1; + $$->SetTermID(TermID::ITERATOR); + } + | ITERATOR /* ?! ?! */ + { + $$=$1; + } + + iter_all: '!' { $$=$1; $$->SetTermID(TermID::ITERATOR); } - | '?' + | ITERATOR_QQ /* !! ?? */ { $$=$1; $$->SetTermID(TermID::ITERATOR); } - | ITERATOR + | iter_call { $$=$1; } + | iter_call call + { + $$=$1; + $$->SetArgs($call); + } diff --git a/src/test/eval_test.cpp b/src/test/eval_test.cpp index 137bd49a..80417c01 100644 --- a/src/test/eval_test.cpp +++ b/src/test/eval_test.cpp @@ -960,183 +960,135 @@ TEST(Eval, Iterator) { ASSERT_STREQ("", dict->at(3).first.c_str()); ASSERT_STREQ("555", dict->at(4).first.c_str()); + ObjPtr dict1 = ctx.ExecStr("dict?!"); + ASSERT_TRUE(dict1); + ASSERT_EQ(5, dict1->size()); + ASSERT_EQ(1, dict1->at(0).second->GetValueAsInteger()); + ASSERT_EQ(2, dict1->at(1).second->GetValueAsInteger()); + ASSERT_EQ(3, dict1->at(2).second->GetValueAsInteger()); + ASSERT_EQ(4, dict1->at(3).second->GetValueAsInteger()); + ASSERT_EQ(5, dict1->at(4).second->GetValueAsInteger()); + ASSERT_STREQ("1", dict1->at(0).first.c_str()); + ASSERT_STREQ("22", dict1->at(1).first.c_str()); + ASSERT_STREQ("333", dict1->at(2).first.c_str()); + ASSERT_STREQ("", dict1->at(3).first.c_str()); + ASSERT_STREQ("555", dict1->at(4).first.c_str()); + + ObjPtr iter = ctx.ExecStr("iter := dict?"); ASSERT_TRUE(iter); ASSERT_EQ(ObjType::Iterator, iter->getType()) << toString(iter->getType()); -// -// ASSERT_TRUE(*(iter->m_iterator) == iter->begin()); -// ASSERT_TRUE(*(iter->m_iterator) != iter->end()); -// -// ObjPtr copy = Obj::CreateDict(); -// for (auto &elem : iter) { -// copy->push_back(elem.second, elem.first); -// } -// -// ASSERT_TRUE(iter->m_iterator == iter->begin()); -// ASSERT_TRUE(iter->m_iterator != iter->end()); -// -// -// -// ASSERT_EQ(dict->size(), copy->size()); -// ObjPtr dict1 = ctx.ExecStr("iter?!"); -// ASSERT_TRUE(dict1); -// ASSERT_EQ(5, dict1->size()); -// ASSERT_EQ(1, dict1->at(0).second->GetValueAsInteger()); -// ASSERT_EQ(2, dict1->at(1).second->GetValueAsInteger()); -// ASSERT_EQ(3, dict1->at(2).second->GetValueAsInteger()); -// ASSERT_EQ(4, dict1->at(3).second->GetValueAsInteger()); -// ASSERT_EQ(5, dict1->at(4).second->GetValueAsInteger()); -// ASSERT_STREQ("1", dict1->at(0).first.c_str()); -// ASSERT_STREQ("22", dict1->at(1).first.c_str()); -// ASSERT_STREQ("333", dict1->at(2).first.c_str()); -// ASSERT_STREQ("", dict1->at(3).first.c_str()); -// ASSERT_STREQ("555", dict1->at(4).first.c_str()); + ASSERT_TRUE(iter->m_iterator); + ASSERT_TRUE(iter->m_iterator->begin() != iter->m_iterator->end()); + ASSERT_TRUE(*(iter->m_iterator) == iter->m_iterator->begin()); + ObjPtr one = ctx.ExecStr("iter!"); + ASSERT_TRUE(one); + ASSERT_EQ(1, dict->at(0).second->GetValueAsInteger()); - /* - * Создание итератора - * ?, ?(), ?("Фильтр"), ?(func), ?(func, args...) - * - * Перебор элементов итератора - * !, !(), !(0), !(3), !(-3) - * - * dict! и dict!(0) эквивалентны - * dict! -> 1, dict! -> 2, dict! -> 3, dict! -> 4, dict! -> 5, dict! -> :IteratorEnd - * Различия отрицательного размера возвращаемого словаря для итератора - * dict!(-1) -> (1,), ... dict!(-1) -> (5,), dict!(-1) -> (:IteratorEnd,), - * dict!(1) -> (1,), ... dict!(1) -> (5,), dict!(1) -> (,), - * dict!(-3) -> (1, 2, 3,), dict!(-3) -> (4, 5, :IteratorEnd,) - * dict!(3) -> (1, 2, 3,), dict!(3) -> (4, 5,) - * - * !? или ?! эквиваленты и создают итератор и сразу его выполняет, - * вовзращая все значения в виде элементов словаря, т.е. ?(LINQ); !(:Long.__max__) - * А зачем может быть нужен итератор "??" - может сброс в начальное состояние??? - * Итератор !! эквиваленетен вызову !(1) - */ + one = ctx.ExecStr("iter!"); + ASSERT_TRUE(one); + ASSERT_EQ(2, one->GetValueAsInteger()); - // ASSERT_TRUE(iter->m_iterator == iter->begin()); - // - // ObjPtr one = iter.read_and_next(0); - // ASSERT_TRUE(one); - // ASSERT_EQ(1, dict->at(0).second->GetValueAsInteger()); - // - // ASSERT_EQ(2, (*iter).second->GetValueAsInteger()); - // one = iter.read_and_next(0); - // ASSERT_TRUE(one); - // ASSERT_EQ(2, dict->at(1).second->GetValueAsInteger()); - // - // ASSERT_EQ(3, (*iter).second->GetValueAsInteger()); - // one = iter.read_and_next(0); - // ASSERT_TRUE(one); - // ASSERT_EQ(3, dict->at(2).second->GetValueAsInteger()); - // - // ASSERT_EQ(4, (*iter).second->GetValueAsInteger()); - // one = iter.read_and_next(0); - // ASSERT_TRUE(one); - // ASSERT_EQ(4, dict->at(3).second->GetValueAsInteger()); - // - // ASSERT_EQ(5, (*iter).second->GetValueAsInteger()); - // one = iter.read_and_next(0); - // ASSERT_TRUE(one); - // ASSERT_EQ(5, dict->at(4).second->GetValueAsInteger()); - // - // one = iter.read_and_next(0); - // ASSERT_TRUE(one); - // ASSERT_EQ(ObjType::IteratorEnd, one->getType()) << one << " " << toString(one->getType()); - // - // one = iter.read_and_next(0); - // ASSERT_TRUE(one); - // ASSERT_EQ(ObjType::IteratorEnd, one->getType()) << one << " " << toString(one->getType()); - // - // - // - // - // ASSERT_TRUE(iter == iter.end()); - // iter.reset(); - // ASSERT_TRUE(iter == iter.begin()); - // ASSERT_TRUE(iter != iter.end()); - // - // ObjPtr dict1 = iter.read_and_next(-3); - // ASSERT_TRUE(dict1); - // ASSERT_EQ(3, dict1->size()); - // ASSERT_EQ(1, dict1->at(0).second->GetValueAsInteger()); - // ASSERT_EQ(2, dict1->at(1).second->GetValueAsInteger()); - // ASSERT_EQ(3, dict1->at(2).second->GetValueAsInteger()); - // - // ObjPtr dict2 = iter.read_and_next(-3); - // ASSERT_TRUE(dict2); - // ASSERT_EQ(3, dict2->size()); - // ASSERT_EQ(4, dict2->at(0).second->GetValueAsInteger()); - // ASSERT_EQ(5, dict2->at(1).second->GetValueAsInteger()); - // ASSERT_EQ(ObjType::IteratorEnd, dict2->at(2).second->getType()); - // - // ObjPtr dict3 = iter.read_and_next(-3); - // ASSERT_TRUE(dict3); - // ASSERT_EQ(3, dict1->size()); - // ASSERT_EQ(ObjType::IteratorEnd, dict3->at(0).second->getType()); - // ASSERT_EQ(ObjType::IteratorEnd, dict3->at(1).second->getType()); - // ASSERT_EQ(ObjType::IteratorEnd, dict3->at(2).second->getType()); - // - // - // - // ASSERT_TRUE(iter == iter.end()); - // iter.reset(); - // ASSERT_TRUE(iter == iter.begin()); - // ASSERT_TRUE(iter != iter.end()); - // - // dict1 = iter.read_and_next(3); - // ASSERT_TRUE(dict1); - // ASSERT_EQ(3, dict1->size()); - // ASSERT_EQ(1, dict1->at(0).second->GetValueAsInteger()); - // ASSERT_EQ(2, dict1->at(1).second->GetValueAsInteger()); - // ASSERT_EQ(3, dict1->at(2).second->GetValueAsInteger()); - // - // dict2 = iter.read_and_next(3); - // ASSERT_TRUE(dict2); - // ASSERT_EQ(2, dict2->size()); - // ASSERT_EQ(4, dict2->at(0).second->GetValueAsInteger()); - // ASSERT_EQ(5, dict2->at(1).second->GetValueAsInteger()); - // - // dict3 = iter.read_and_next(3); - // ASSERT_TRUE(dict3); - // ASSERT_EQ(0, dict3->size()); - // - // - // - // - // Iterator flt(dict, ""); - // ObjPtr flt_res = flt.read_and_next(100); - // ASSERT_TRUE(flt_res); - // ASSERT_EQ(1, flt_res->size()); - // ASSERT_EQ(4, flt_res->at(0).second->GetValueAsInteger()); - // - // - // Iterator flt1(dict, "."); - // ObjPtr flt1_res = flt1.read_and_next(100); - // ASSERT_TRUE(flt1_res); - // ASSERT_EQ(1, flt1_res->size()); - // ASSERT_EQ(1, flt1_res->at(0).second->GetValueAsInteger()); - // - // - // Iterator flt2(dict, ".."); - // ObjPtr flt2_res = flt2.read_and_next(100); - // ASSERT_TRUE(flt2_res); - // ASSERT_EQ(1, flt2_res->size()); - // ASSERT_EQ(2, flt2_res->at(0).second->GetValueAsInteger()); - // - // Iterator flt3(dict, "..."); - // ObjPtr flt3_res = flt3.read_and_next(100); - // ASSERT_TRUE(flt3_res); - // ASSERT_EQ(2, flt3_res->size()); - // ASSERT_EQ(3, flt3_res->at(0).second->GetValueAsInteger()); - // ASSERT_EQ(5, flt3_res->at(1).second->GetValueAsInteger()); - // - // - // - // ObjPtr iter1 = dict->MakeIterator(); + one = ctx.ExecStr("iter!"); + ASSERT_TRUE(one); + ASSERT_EQ(3, one->GetValueAsInteger()); + + one = ctx.ExecStr("iter!"); + ASSERT_TRUE(one); + ASSERT_EQ(4, one->GetValueAsInteger()); + + one = ctx.ExecStr("iter!"); + ASSERT_TRUE(one); + ASSERT_EQ(5, one->GetValueAsInteger()); + + one = ctx.ExecStr("iter!"); + ASSERT_TRUE(one); + ASSERT_EQ(ObjType::IteratorEnd, one->getType()) << one << " " << toString(one->getType()); + + one = ctx.ExecStr("iter!"); + ASSERT_TRUE(one); + ASSERT_EQ(ObjType::IteratorEnd, one->getType()) << one << " " << toString(one->getType()); + + + ASSERT_TRUE(*(iter->m_iterator) == iter->m_iterator->end()); + ctx.ExecStr("iter??"); + ASSERT_TRUE(*(iter->m_iterator) == iter->m_iterator->begin()); + + dict1 = ctx.ExecStr("iter!?(-3)"); + ASSERT_TRUE(dict1); + ASSERT_EQ(3, dict1->size()); + ASSERT_EQ(1, dict1->at(0).second->GetValueAsInteger()); + ASSERT_EQ(2, dict1->at(1).second->GetValueAsInteger()); + ASSERT_EQ(3, dict1->at(2).second->GetValueAsInteger()); + + ObjPtr dict2 = ctx.ExecStr("iter!?(-3)"); + ASSERT_TRUE(dict2); + ASSERT_EQ(3, dict2->size()); + ASSERT_EQ(4, dict2->at(0).second->GetValueAsInteger()); + ASSERT_EQ(5, dict2->at(1).second->GetValueAsInteger()); + ASSERT_EQ(ObjType::IteratorEnd, dict2->at(2).second->getType()); + + ObjPtr dict3 = ctx.ExecStr("iter!?(-3)"); + ASSERT_TRUE(dict3); + ASSERT_EQ(3, dict1->size()); + ASSERT_EQ(ObjType::IteratorEnd, dict3->at(0).second->getType()); + ASSERT_EQ(ObjType::IteratorEnd, dict3->at(1).second->getType()); + ASSERT_EQ(ObjType::IteratorEnd, dict3->at(2).second->getType()); + + + + ASSERT_TRUE(*(iter->m_iterator) == iter->m_iterator->end()); + ctx.ExecStr("iter??"); + ASSERT_TRUE(*(iter->m_iterator) == iter->m_iterator->begin()); + + dict1 = ctx.ExecStr("iter!?(3)"); + ASSERT_TRUE(dict1); + ASSERT_EQ(3, dict1->size()); + ASSERT_EQ(1, dict1->at(0).second->GetValueAsInteger()); + ASSERT_EQ(2, dict1->at(1).second->GetValueAsInteger()); + ASSERT_EQ(3, dict1->at(2).second->GetValueAsInteger()); + + dict2 = ctx.ExecStr("iter!?(3)"); + ASSERT_TRUE(dict2); + ASSERT_EQ(2, dict2->size()); + ASSERT_EQ(4, dict2->at(0).second->GetValueAsInteger()); + ASSERT_EQ(5, dict2->at(1).second->GetValueAsInteger()); + + dict3 = ctx.ExecStr("iter!?(3)"); + ASSERT_TRUE(dict3); + ASSERT_EQ(0, dict3->size()); + + + + ASSERT_TRUE(*(iter->m_iterator) == iter->m_iterator->end()); + ctx.ExecStr("iter??"); + ASSERT_TRUE(*(iter->m_iterator) == iter->m_iterator->begin()); + + ObjPtr flt_res = ctx.ExecStr("dict!?('')"); + ASSERT_TRUE(flt_res); + ASSERT_EQ(1, flt_res->size()); + ASSERT_EQ(4, flt_res->at(0).second->GetValueAsInteger()); + + + ObjPtr flt1_res = ctx.ExecStr("dict!?('.',100)"); + ASSERT_TRUE(flt1_res); + ASSERT_EQ(1, flt1_res->size()); + ASSERT_EQ(1, flt1_res->at(0).second->GetValueAsInteger()); + + + ObjPtr flt2_res = ctx.ExecStr("dict!?('..',100)"); + ASSERT_TRUE(flt2_res); + ASSERT_EQ(1, flt2_res->size()); + ASSERT_EQ(2, flt2_res->at(0).second->GetValueAsInteger()); + ObjPtr flt3_res = ctx.ExecStr("dict!?('...',100)"); + ASSERT_TRUE(flt3_res); + ASSERT_EQ(2, flt3_res->size()); + ASSERT_EQ(3, flt3_res->at(0).second->GetValueAsInteger()); + ASSERT_EQ(5, flt3_res->at(1).second->GetValueAsInteger()); } diff --git a/src/test/object_test.cpp b/src/test/object_test.cpp index 5d949780..6c73c733 100644 --- a/src/test/object_test.cpp +++ b/src/test/object_test.cpp @@ -879,27 +879,27 @@ TEST(ObjTest, Iterator) { ObjPtr one = iter.read_and_next(0); ASSERT_TRUE(one); - ASSERT_EQ(1, dict->at(0).second->GetValueAsInteger()); + ASSERT_EQ(1, one->GetValueAsInteger()); ASSERT_EQ(2, (*iter).second->GetValueAsInteger()); one = iter.read_and_next(0); ASSERT_TRUE(one); - ASSERT_EQ(2, dict->at(1).second->GetValueAsInteger()); + ASSERT_EQ(2, one->GetValueAsInteger()); ASSERT_EQ(3, (*iter).second->GetValueAsInteger()); one = iter.read_and_next(0); ASSERT_TRUE(one); - ASSERT_EQ(3, dict->at(2).second->GetValueAsInteger()); + ASSERT_EQ(3, one->GetValueAsInteger()); ASSERT_EQ(4, (*iter).second->GetValueAsInteger()); one = iter.read_and_next(0); ASSERT_TRUE(one); - ASSERT_EQ(4, dict->at(3).second->GetValueAsInteger()); + ASSERT_EQ(4, one->GetValueAsInteger()); ASSERT_EQ(5, (*iter).second->GetValueAsInteger()); one = iter.read_and_next(0); ASSERT_TRUE(one); - ASSERT_EQ(5, dict->at(4).second->GetValueAsInteger()); + ASSERT_EQ(5, one->GetValueAsInteger()); one = iter.read_and_next(0); ASSERT_TRUE(one); From 0891bd5fca3fc78fced2668b01769e0f6ddafb7c Mon Sep 17 00:00:00 2001 From: Aleksandr Ryabikov Date: Thu, 14 Jul 2022 08:49:26 +0300 Subject: [PATCH 23/31] =?UTF-8?q?=D0=92=20=D0=BF=D1=80=D0=BE=D1=86=D0=B5?= =?UTF-8?q?=D1=81=D1=81=D0=B5=20=D0=BE=D1=84=D0=BE=D1=80=D0=BC=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D1=8F=20=D1=82=D0=B5=D1=81=D1=82=D0=BE=D0=B2=D1=8B?= =?UTF-8?q?=D1=85=20=D0=BF=D1=80=D0=B8=D0=BC=D0=B5=D1=80=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- examples/_run.sh | 19 +++++ examples/fileio.nlp | 1 + examples/foreach.nlp | 1 + examples/fraction.nlp | 10 +++ src/builtin.cpp | 42 +++++------ src/builtin.h | 2 +- src/context.cpp | 6 +- src/context.h | 56 +++++++++------ src/newlang.cpp | 20 +++--- src/object.cpp | 19 +++-- src/object.h | 5 +- src/term.h | 1 + src/test/eval_test.cpp | 154 +++++++++++++++++++++++++++++------------ src/types.h | 1 - 14 files changed, 222 insertions(+), 115 deletions(-) create mode 100755 examples/_run.sh mode change 100644 => 100755 examples/fileio.nlp mode change 100644 => 100755 examples/foreach.nlp create mode 100755 examples/fraction.nlp diff --git a/examples/_run.sh b/examples/_run.sh new file mode 100755 index 00000000..65a95b56 --- /dev/null +++ b/examples/_run.sh @@ -0,0 +1,19 @@ +#!/bin/bash + +CLR_BOLD='\033[1;33m' +CLR_NO='\033[0m' # No Color +CLR_FAIL='\033[0;31m' +CLR_OK='\033[0;32m' + +for filename in *.nlp; do +# for ((i=0; i<=3; i++)); do + echo -ne "Run file ${CLR_BOLD}${filename}${CLR_NO}" + OUT=`../output/nlc --eval=$filename` + if [[ "${OUT}" == "OK" ]]; then + echo -e " - ${CLR_OK}OK${CLR_NO}" + else + echo -e " - ${CLR_FAIL}FALSE${CLR_NO}" + fi; +# done +done + diff --git a/examples/fileio.nlp b/examples/fileio.nlp old mode 100644 new mode 100755 index 4a013c19..0e0d437c --- a/examples/fileio.nlp +++ b/examples/fileio.nlp @@ -1,3 +1,4 @@ +#!../output/nlc --eval :File ::= :Pointer; diff --git a/examples/foreach.nlp b/examples/foreach.nlp old mode 100644 new mode 100755 index 4a013c19..0e0d437c --- a/examples/foreach.nlp +++ b/examples/foreach.nlp @@ -1,3 +1,4 @@ +#!../output/nlc --eval :File ::= :Pointer; diff --git a/examples/fraction.nlp b/examples/fraction.nlp new file mode 100755 index 00000000..e5c5606e --- /dev/null +++ b/examples/fraction.nlp @@ -0,0 +1,10 @@ +#!../output/nlc --eval + +@var1 := 1234567890_1234567890\1; +@var2 := 100_000_000_000_000_001\1; +@var2 *= @var1; + + +--@var2--; + +"OK"; \ No newline at end of file diff --git a/src/builtin.cpp b/src/builtin.cpp index 97754541..a1b63bc1 100644 --- a/src/builtin.cpp +++ b/src/builtin.cpp @@ -97,27 +97,27 @@ namespace newlang { } -bool BuiltInTorchDirect::CheckDirect(CompileInfo &ci, TermPtr &term, std::string &output) { - - if(term->size() == 0 && m_tensor_noarg.find(term->getText()) != m_tensor_noarg.end()) { - output += "->asTensor_()." + term->getText() + "(), " + output; - - return true; - } else if(term->size() == 1) { - - if((*term)[0].second->IsScalar() && m_tensor_scalar.find(term->getText()) != m_tensor_scalar.end()) { - output += "->asTensor_()." + term->getText() + "(" + (*term)[0].second->getText() + "), " + output; - return true; - - } else if((*term)[0].second->getTermID() == TermID::TERM) { - std::string temp; - NewLang::GetImpl(ci, (*term)[0].second, temp); - output += "->asTensor_()." + term->getText() + "(" + temp + "->asTensor_()), " + output; - return true; - } - } - return false; -} +//bool BuiltInTorchDirect::CheckDirect(CompileInfo &ci, TermPtr &term, std::string &output) { +// +// if(term->size() == 0 && m_tensor_noarg.find(term->getText()) != m_tensor_noarg.end()) { +// output += "->asTensor_()." + term->getText() + "(), " + output; +// +// return true; +// } else if(term->size() == 1) { +// +// if((*term)[0].second->IsScalar() && m_tensor_scalar.find(term->getText()) != m_tensor_scalar.end()) { +// output += "->asTensor_()." + term->getText() + "(" + (*term)[0].second->getText() + "), " + output; +// return true; +// +// } else if((*term)[0].second->getTermID() == TermID::TERM) { +// std::string temp; +// NewLang::GetImpl(ci, (*term)[0].second, temp); +// output += "->asTensor_()." + term->getText() + "(" + temp + "->asTensor_()), " + output; +// return true; +// } +// } +// return false; +//} BuiltInTorchDirect::BuiltInTorchDirect() { diff --git a/src/builtin.h b/src/builtin.h index c800ea35..c4b0b701 100644 --- a/src/builtin.h +++ b/src/builtin.h @@ -60,7 +60,7 @@ class BuiltInTorchDirect { BuiltInTorchDirect(); - bool CheckDirect(CompileInfo &ci, TermPtr &term, std::string &output); +// bool CheckDirect(CompileInfo &ci, TermPtr &term, std::string &output); virtual ~BuiltInTorchDirect() { } diff --git a/src/context.cpp b/src/context.cpp index 8e4194ae..8e4c4019 100644 --- a/src/context.cpp +++ b/src/context.cpp @@ -331,9 +331,8 @@ ObjPtr Context::eval_CALL_TRY(Context *ctx, const TermPtr &term, Obj *args) { } ObjPtr Context::eval_MACRO(Context *ctx, const TermPtr &term, Obj *args) { - LOG_RUNTIME("eval_MACRO: %s", term->toString().c_str()); - - return nullptr; + LOG_ERROR("Macro %s not found!", term->toString().c_str()); + return Obj::CreateNone(); } ObjPtr Context::eval_MACRO_BODY(Context *ctx, const TermPtr &term, Obj *args) { @@ -588,7 +587,6 @@ ObjPtr Context::CREATE_OR_ASSIGN(Context *ctx, const TermPtr &term, Obj *local_v } result = rval->Clone(); - result->m_is_const = false; result->m_class_name = list_term[i]->m_text; result->m_class_parents.push_back(rval); diff --git a/src/context.h b/src/context.h index eefaab90..d9611605 100644 --- a/src/context.h +++ b/src/context.h @@ -40,7 +40,6 @@ namespace newlang { * * */ - class ContextCursor; typedef std::map ProtoType; @@ -103,13 +102,13 @@ namespace newlang { _("export", NOT_SUPPORT)\ _("local", NOT_SUPPORT) - class Context : public Variable> { + class Context : public Variable > { public: - + friend class Obj; - static ObjPtr eval_END(Context *ctx, const TermPtr & term, Obj *args); - static ObjPtr func_NOT_SUPPORT(Context *ctx, const TermPtr & term, Obj *args); + static ObjPtr eval_END(Context *ctx, const TermPtr & term, Obj * args); + static ObjPtr func_NOT_SUPPORT(Context *ctx, const TermPtr & term, Obj * args); enum class CreateMode { CREATE_ONLY, @@ -133,7 +132,7 @@ namespace newlang { #undef PROTO_OP - typedef ObjPtr(*EvalFunction)(Context *ctx, const TermPtr & term, Obj *args); + typedef ObjPtr(*EvalFunction)(Context *ctx, const TermPtr & term, Obj * args); static std::map m_ops; static std::map m_builtin_calls; @@ -173,13 +172,13 @@ namespace newlang { static ObjPtr Eval(Context *ctx, TermPtr term, Obj *args, bool int_catch = false); static ObjPtr ExpandAssign(Context *ctx, TermPtr lvar, TermPtr rval, Obj *args, CreateMode mode); - static ObjPtr ExpandCreate(Context *ctx, TermPtr lvar, TermPtr rval, Obj *args); + static ObjPtr ExpandCreate(Context *ctx, TermPtr lvar, TermPtr rval, Obj * args); Context(RuntimePtr global); static std::map m_types; - typedef std::variant> FuncItem; + typedef std::variant> FuncItem; static std::map m_funcs; // Системный и встроенные функции inline static ObjPtr CreateLVal(Context *ctx, TermPtr type) { @@ -197,14 +196,14 @@ namespace newlang { return CreateRVal(ctx, source, &args, int_catch); } - static ObjPtr CreateLVal(Context *ctx, TermPtr type, Obj *args); + static ObjPtr CreateLVal(Context *ctx, TermPtr type, Obj * args); static ObjPtr CreateRVal(Context *ctx, TermPtr term, Obj *args, bool int_catch = true); static ObjPtr CreateRVal(Context *ctx, const char *source, Obj *args, bool int_catch = true); - void CreateArgs_(ObjPtr &args, TermPtr &term, Obj *local_vars); - - static std::vector MakeIndex(Context *ctx, TermPtr term, Obj *local_vars); + void CreateArgs_(ObjPtr &args, TermPtr &term, Obj * local_vars); + + static std::vector MakeIndex(Context *ctx, TermPtr term, Obj * local_vars); - void ItemTensorEval_(torch::Tensor &tensor, c10::IntArrayRef shape, std::vector &ind, const int64_t pos, ObjPtr & obj, ObjPtr &args); + void ItemTensorEval_(torch::Tensor &tensor, c10::IntArrayRef shape, std::vector &ind, const int64_t pos, ObjPtr & obj, ObjPtr & args); void ItemTensorEval(torch::Tensor &tensor, ObjPtr obj, ObjPtr args); void ReadBuiltInProto(ProtoType & proto); @@ -270,17 +269,17 @@ namespace newlang { return GetObject(name); } - void RegisterInContext(ObjPtr &args) { + void RegisterInContext(ObjPtr & args) { RegisterInContext(*args); } - void RegisterInContext(Obj &args) { + void RegisterInContext(Obj & args) { for (int i = static_cast (args.size()) - 1; args.size() && i >= 0; i--) { push_front(pair(args.at(i).second, args.at(i).first)); } } - void UnRegisterInContext(Obj &args) { + void UnRegisterInContext(Obj & args) { for (int i = static_cast (args.size()) - 1; args.size() && i >= 0; i--) { pop_front(); } @@ -289,9 +288,9 @@ namespace newlang { static ObjPtr CallBlock(Context *ctx, const TermPtr &block, Obj *local_vars, bool int_catch); - static ObjPtr EvalBlockAND(Context *ctx, const TermPtr &block, Obj *local_vars); - static ObjPtr EvalBlockOR(Context *ctx, const TermPtr &block, Obj *local_vars); - static ObjPtr EvalBlockXOR(Context *ctx, const TermPtr &block, Obj *local_vars); + static ObjPtr EvalBlockAND(Context *ctx, const TermPtr &block, Obj * local_vars); + static ObjPtr EvalBlockOR(Context *ctx, const TermPtr &block, Obj * local_vars); + static ObjPtr EvalBlockXOR(Context *ctx, const TermPtr &block, Obj * local_vars); ObjPtr CreateNative(const char *proto, const char *module = nullptr, bool lazzy = false, const char *mangle_name = nullptr, ffi_abi abi = FFI_DEFAULT_ABI); ObjPtr CreateNative(TermPtr proto, const char *module = nullptr, bool lazzy = false, const char *mangle_name = nullptr, ffi_abi abi = FFI_DEFAULT_ABI); @@ -319,6 +318,7 @@ namespace newlang { bool find_local = false; bool find_global = false; bool find_types = false; + bool find_macro = false; std::string prefix; @@ -330,17 +330,29 @@ namespace newlang { prefix = start[0]; start = start.substr(1); find_local = true; + } else if (isMacro(start)) { + find_macro = true; } else if (isType(start)) { - // prefix = start[0]; - // start.remove_prefix(1); find_types = true; } else { find_local = true; find_global = true; find_types = true; + find_macro = true; } + if (find_macro) { + for (auto &elem : m_macros) { + if (pred_compare(start, elem.first)) { + result.push_back(utf8_decode(prefix + elem.first)); + if (result.size() > overage_count + 1) { + break; + } + } + } + } + if (find_local) { for (int i = 0; i < size(); i++) { if (pred_compare(start, at(i).first)) { @@ -497,7 +509,7 @@ namespace newlang { TYPE_EQUAL, TYPE_STRICT, }; - static bool MatchCompare(Obj &match, ObjPtr &value, MatchMode mode, Context *ctx); + static bool MatchCompare(Obj &match, ObjPtr &value, MatchMode mode, Context * ctx); static bool MatchEstimate(Obj &match, const TermPtr &match_item, MatchMode mode, Context *ctx, Obj * args); SCOPE(protected) : diff --git a/src/newlang.cpp b/src/newlang.cpp index 60b8e8c2..12dd122d 100644 --- a/src/newlang.cpp +++ b/src/newlang.cpp @@ -1537,16 +1537,16 @@ std::string NewLang::GetImpl(CompileInfo &ci, TermPtr term, std::string &output) output += result; return result; - case TermID::FIELD: - ASSERT(!term->getName().empty() || !term->getText().empty()); - ASSERT(!term->Right()); - - if(!ci.m_builtin_direct->CheckDirect(ci, term, output)) { - output.insert(0, "(*"); - output += ")[\"" + term->getText() + "\"]"; - } - result = output; - return result; +// case TermID::FIELD: +// ASSERT(!term->getName().empty() || !term->getText().empty()); +// ASSERT(!term->Right()); +// +// if(!ci.m_builtin_direct->CheckDirect(ci, term, output)) { +// output.insert(0, "(*"); +// output += ")[\"" + term->getText() + "\"]"; +// } +// result = output; +// return result; case TermID::SOURCE: temp = term->getText(); diff --git a/src/object.cpp b/src/object.cpp index ffa66639..59b36513 100644 --- a/src/object.cpp +++ b/src/object.cpp @@ -578,10 +578,8 @@ void Obj::CloneDataTo(Obj & clone) const { clone.m_class_parents = m_class_parents; clone.m_class_name = m_class_name; - // clone.m_ctx = m_ctx; - clone.m_is_const = false; + clone.m_is_const = m_is_const; - clone.m_ref_count = m_ref_count; clone.m_func_ptr = m_func_ptr; *const_cast (&clone.m_func_proto) = m_func_proto; if(is_tensor() && m_var_is_init) { @@ -2811,12 +2809,15 @@ ObjPtr Obj::ConstructorNative_(const Context *ctx_const, Obj & args) { ObjPtr Obj::ConstructorClass_(const Context *ctx, Obj & args) { ObjPtr result = ConstructorDictionary_(ctx, args); result->m_var_type_fixed = ObjType::Class; - for (int i = 0; i < result->size(); i++) { + result->m_var_is_init = true; + for (int i = 1; i < result->size(); i++) { if(result->name(i).empty()) { LOG_RUNTIME("Field pos %d has no name!", i); } - if(result->find(result->name(i)) != result->end()) { - LOG_RUNTIME("Field name '%s' at index %d already exists!", result->name(i).c_str(), i); + for (int pos = 0; pos < i; pos++) { + if(result->name(pos).compare(result->name(i)) == 0) { + LOG_RUNTIME("Field name '%s' at index %d already exists!", result->name(i).c_str(), i); + } } } return result; @@ -2884,6 +2885,7 @@ ObjPtr Obj::ConstructorEnum_(const Context *ctx, Obj & args) { } result->m_is_const = true; + result->m_var_is_init = true; return result; } @@ -3009,3 +3011,8 @@ ObjPtr Obj::IteratorNext(int64_t count) { return m_iterator->read_and_next(count); } +//void Obj::SetHelp(const std::string &help) { +// Context::HelpInfo help_info = Context::; +// std::shared_ptr m_help = help; +//} + diff --git a/src/object.h b/src/object.h index e8a24bf9..132edc90 100755 --- a/src/object.h +++ b/src/object.h @@ -288,7 +288,6 @@ namespace newlang { // m_ctx = nullptr; m_is_const = false; m_check_args = false; - m_ref_count = 0; m_func_ptr = nullptr; m_dimensions = nullptr; m_value = torch::empty({0}, isSimpleType(type) ? toTorchType(type) : at::ScalarType::Undefined); @@ -1696,8 +1695,6 @@ namespace newlang { if (new_name) { clone->m_var_name = new_name; } - clone->m_is_const = false; - clone->m_ref_count = 0; return clone; } @@ -2044,7 +2041,7 @@ namespace newlang { // SCOPE(protected) : bool m_is_const; //< Признак константы (по умолчанию изменения разрешено) bool m_is_reference; //< Признак ссылки на объект (mutable) - size_t m_ref_count; + std::shared_ptr m_help; }; diff --git a/src/term.h b/src/term.h index 3ccc3871..9824ee42 100644 --- a/src/term.h +++ b/src/term.h @@ -647,6 +647,7 @@ namespace newlang { case TermID::SYMBOL: case TermID::FRACTION: case TermID::COMPLEX: + case TermID::MACRO: return m_text; case TermID::EMPTY: diff --git a/src/test/eval_test.cpp b/src/test/eval_test.cpp index 80417c01..afa95f91 100644 --- a/src/test/eval_test.cpp +++ b/src/test/eval_test.cpp @@ -1092,52 +1092,114 @@ TEST(Eval, Iterator) { } -TEST(Eval, Brother) { - /* - * - * :Human := :Class(пол:Пол=_, родители = (,)); - * #!./dist/Debug/GNU-Linux/nlc --exec - * :Sex := :Enum(male, female); - * :Human := :Class(sex:Sex=, parent=(,)); - * @Tom := :Human(Sex.male); - * @Janna := :Human(Sex.female); - * @Jake := :Human(Sex.male, (Tom, Janna,)); - * @Tim := :Human(Sex.male, parent=(Tom,)); - * - * Brother(h1, h2) := $h1 != $h2, $h1.sex==male, $h1.parent * $h2.parent; - * printf := :Native("printf(format:Format, ...):Int"); - * - * - * h1 := $?; - * [ h1 ] <<-->> { - * h2 := $?; - * [ h2 ] <<-->> { - * [ Brother(h1!, h2!) ] --> { - * printf("%s brother %s", ""(h1), `h2`); - * } - * } - * } - * - * h1 := \iterator($); - * \while( h1 ) { - * h2 := \iterator($); - * \while( h2 } { - * \if( Brother(h1!, h2!) ) { - * result []= "$1 brother $2"(h1, h2); - * } - * } - * } - * --result--; - * - * >>> ("Tim brother Jake", "Jake brother Tim",) - * - * - * - */ - - - -} +//TEST(Eval, Brother) { +// /* +// * +// * :Human := :Class(пол:Пол=_, родители = (,)); +// * #!./dist/Debug/GNU-Linux/nlc --exec +// * :Sex := :Enum(male, female); +// * :Human := :Class(sex:Sex=, parent=(,)); +// * @Tom := :Human(Sex.male); +// * @Janna := :Human(Sex.female); +// * @Jake := :Human(Sex.male, (Tom, Janna,)); +// * @Tim := :Human(Sex.male, parent=(Tom,)); +// * +// * Brother(h1, h2) := $h1 != $h2, $h1.sex==male, $h1.parent * $h2.parent; +// * printf := :Native("printf(format:Format, ...):Int"); +// * +// * h1 := $?; +// * [ h1 ] <<-->> { +// * h2 := $?; +// * [ h2 ] <<-->> { +// * [ Brother(h1!, h2!) ] --> { +// * printf("%s brother %s", ""(h1), `h2`); +// * } +// * } +// * } +// * +// * h1 := \iterator($); +// * \while( h1 ) { +// * h2 := \iterator($); +// * \while( h2 } { +// * \if( Brother(h1!, h2!) ) { +// * result []= "$1 brother $2"(h1, h2); +// * } +// * } +// * } +// * --result--; +// * +// * >>> ("Tim brother Jake", "Jake brother Tim",) +// * +// */ +// +// Context::Reset(); +// Context ctx(RunTime::Init()); +// +// ObjPtr Sex = ctx.ExecStr(":Sex := :Enum(male=1, 'female')"); +// ASSERT_TRUE(Sex); +// ASSERT_TRUE(Sex->isConst()); +// ASSERT_EQ(2, Sex->size()); +// ASSERT_STREQ("male", Sex->at(0).first.c_str()); +// ASSERT_EQ(1, Sex->at(0).second->GetValueAsInteger()); +// ASSERT_STREQ("female", Sex->at(1).first.c_str()); +// ASSERT_EQ(2, Sex->at(1).second->GetValueAsInteger()); +// +// ObjPtr Human = ctx.ExecStr(":Human := :Class(sex:Sex=, parent=(,))"); +// +// ASSERT_TRUE(Human); +// ASSERT_EQ(2, Human->size()); +// ASSERT_STREQ("sex", Human->at(0).first.c_str()); +// ASSERT_TRUE(Human->at(0).second->is_none_type()); +// ASSERT_STREQ("parent", Human->at(1).first.c_str()); +// ASSERT_TRUE(Human->at(1).second->is_dictionary_type()); +// ASSERT_EQ(0, Human->at(1).second->size()); +// +// +// ObjPtr Tom = ctx.ExecStr("Tom := :Human(:Sex.male)"); +// ASSERT_TRUE(Tom); +// ASSERT_EQ(2, Tom->size()); +// ASSERT_STREQ("sex", Tom->at(0).first.c_str()); +//// ASSERT_TRUE(Tom->at(0).second->is_integer()); +// ASSERT_EQ(1, Tom->at(0).second->GetValueAsInteger()); +// ASSERT_STREQ("parent", Tom->at(1).first.c_str()); +// ASSERT_TRUE(Tom->at(1).second->is_dictionary_type()); +// ASSERT_EQ(0, Tom->at(1).second->size()); +// +// ObjPtr Janna = ctx.ExecStr("Janna := :Human(:Sex.female)"); +// ASSERT_TRUE(Janna); +// ASSERT_EQ(2, Janna->size()); +// ASSERT_STREQ("sex", Janna->at(0).first.c_str()); +// ASSERT_TRUE(Janna->at(0).second->is_integer()); +// ASSERT_EQ(2, Janna->at(0).second->GetValueAsInteger()); +// ASSERT_STREQ("parent", Janna->at(1).first.c_str()); +// ASSERT_TRUE(Janna->at(1).second->is_dictionary_type()); +// ASSERT_EQ(0, Janna->at(1).second->size()); +// +// +// ObjPtr Jake = ctx.ExecStr("Jake := :Human(:Sex.male, (Tom, Janna,))"); +// ASSERT_TRUE(Jake); +// ASSERT_EQ(2, Jake->size()); +// ASSERT_STREQ("sex", Jake->at(0).first.c_str()); +// ASSERT_TRUE(Jake->at(0).second->is_integer()); +// ASSERT_EQ(1, Jake->at(0).second->GetValueAsInteger()); +// ASSERT_STREQ("parent", Jake->at(1).first.c_str()); +// ASSERT_TRUE(Jake->at(1).second->is_dictionary_type()); +// ASSERT_EQ(2, Jake->at(1).second->size()); +// +// ObjPtr Tim = ctx.ExecStr("Tim := :Human(:Sex.male, (Tom,))"); +// ASSERT_TRUE(Tim); +// ASSERT_EQ(2, Tim->size()); +// ASSERT_STREQ("sex", Tim->at(0).first.c_str()); +// ASSERT_TRUE(Tim->at(0).second->is_integer()); +// ASSERT_EQ(1, Tim->at(0).second->GetValueAsInteger()); +// ASSERT_STREQ("parent", Tim->at(1).first.c_str()); +// ASSERT_TRUE(Tim->at(1).second->is_dictionary_type()); +// ASSERT_EQ(1, Tim->at(1).second->size()); +// +// +// +// +//} class OpEvalTest : public ::testing::Test { protected: diff --git a/src/types.h b/src/types.h index 0f2a155c..72c7e3df 100644 --- a/src/types.h +++ b/src/types.h @@ -31,7 +31,6 @@ class Obj; class Context; class NewLang; class RunTime; -struct CompileInfo; typedef std::shared_ptr TermPtr; typedef std::shared_ptr ObjPtr; From 2e9427870c4e91fc845d1700c5b4ffba4bb5ebca Mon Sep 17 00:00:00 2001 From: Aleksandr Ryabikov Date: Fri, 15 Jul 2022 18:50:04 +0300 Subject: [PATCH 24/31] =?UTF-8?q?=D0=9D=D0=B0=D1=87=D0=B0=D0=BB=20=D0=BF?= =?UTF-8?q?=D0=B5=D1=80=D0=B5=D0=B2=D0=BE=D0=B4=D0=B8=D1=82=D1=8C=20=D0=BD?= =?UTF-8?q?=D0=B0=20clang=20(=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=B0=D1=8E?= =?UTF-8?q?=D1=82=20=D0=BF=D0=BE=D1=87=D1=82=D0=B8=20=D0=B2=D1=81=D0=B5=20?= =?UTF-8?q?=D1=82=D0=B5=D1=81=D1=82=D1=8B=20=D0=BF=D0=BE=D0=B4=20Linux,=20?= =?UTF-8?q?=D0=BA=D1=80=D0=BE=D0=BC=D0=B5=20=D0=BB=D0=BE=D0=BA=D0=B0=D0=BB?= =?UTF-8?q?=D1=8C=D0=BD=D1=8B=D1=85=20=D0=BF=D0=B5=D1=80=D0=B5=D0=BC=D0=B5?= =?UTF-8?q?=D0=BD=D0=BD=D1=8B=D1=85=20=D0=B8=20=D1=84=D1=83=D0=BD=D0=BA?= =?UTF-8?q?=D1=86=D0=B8=D0=B9)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- contrib/logger/logger.cpp | 6 +- contrib/logger/logger.h | 2 +- src/Makefile | 2 +- src/context.cpp | 43 ++- src/context.h | 14 +- src/nbproject/Makefile-Debug.mk | 4 +- src/nbproject/Makefile-Debug_LLVM.mk | 246 +++++++++++++++ src/nbproject/Makefile-GCOV.mk | 4 +- src/nbproject/Makefile-LLVM.mk | 4 +- src/nbproject/Makefile-LLVM_GCC.mk | 4 +- src/nbproject/Makefile-Release.mk | 4 +- src/nbproject/Makefile-UnitTest-Win32.mk | 4 +- src/nbproject/Makefile-UnitTest-Win64.mk | 4 +- src/nbproject/Makefile-UnitTest.mk | 4 +- src/nbproject/Makefile-UnitTest_LLVM.mk | 66 ++-- src/nbproject/Makefile-impl.mk | 2 +- src/nbproject/Makefile-variables.mk | 14 +- src/nbproject/Package-Debug_LLVM.bash | 76 +++++ src/nbproject/Package-UnitTest_LLVM.bash | 4 +- src/nbproject/configurations.xml | 307 +++++++++++++++--- src/nbproject/project.xml | 6 +- src/newlang.cpp | 380 ++++++++++++----------- src/newlang.h | 183 +++++++++-- src/nlc.cpp | 28 +- src/nlc.h | 9 +- src/object.cpp | 47 +-- src/object.h | 22 +- src/parser.cpp | 25 +- src/parser.h | 20 +- src/pch.h | 51 +++ src/term.h | 1 - src/test/eval_test.cpp | 242 ++++++++------- src/test/object_test.cpp | 1 - src/test/parser_test.cpp | 13 +- src/types.h | 24 +- src/variable.h | 12 +- src/warning_push.h | 6 + src/win/nlc.vcxproj | 2 +- 38 files changed, 1351 insertions(+), 535 deletions(-) create mode 100644 src/nbproject/Makefile-Debug_LLVM.mk create mode 100644 src/nbproject/Package-Debug_LLVM.bash diff --git a/contrib/logger/logger.cpp b/contrib/logger/logger.cpp index 160cbdf4..84bfe1ba 100644 --- a/contrib/logger/logger.cpp +++ b/contrib/logger/logger.cpp @@ -307,7 +307,7 @@ EXTERN_C size_t BinToHexBuffer(const uint8_t * buf, const size_t size, char * st #include #include -inline char * basename(char * str) { +inline const char * get_basename(const char * str) { if(str) { size_t pos = strlen(str); while(pos) { @@ -362,10 +362,10 @@ EXTERN_C void log_print_callstack() { strncat(function, "()", sz); function[sz - 1] = '\0'; } - LOG_INFO(" %s:%s", basename(stack_strings[i]), basename(function)); + LOG_INFO(" %s:%s", get_basename(stack_strings[i]), get_basename(function)); } else { // didn't find the mangled name, just print the whole line - LOG_INFO(" %s", basename(stack_strings[i])); + LOG_INFO(" %s", get_basename(stack_strings[i])); } free(function); } diff --git a/contrib/logger/logger.h b/contrib/logger/logger.h index c1085dde..4391aca6 100644 --- a/contrib/logger/logger.h +++ b/contrib/logger/logger.h @@ -40,7 +40,7 @@ #endif // Use: #pragma message WARNING("My message") -#if _MSC_VER +#ifdef _MSC_VER #define FILE_LINE_LINK __FILE__ "(" TO_STR(__LINE__) ") : " #define WARNING(exp) (FILE_LINE_LINK "WARNING: " exp) #else//__GNUC__ - may need other defines for different compilers diff --git a/src/Makefile b/src/Makefile index f65a0605..cb80bbf4 100644 --- a/src/Makefile +++ b/src/Makefile @@ -54,7 +54,7 @@ VERSION_MAJOR=0 VERSION_MINOR=1 VERSION_PATCH=0 VERSION_HEADER="version.h" -VERSION_FILE="version.c" +VERSION_FILE="version.cpp" GIT_TAG_VERSION=$(shell git describe --abbrev=0 --tags) diff --git a/src/context.cpp b/src/context.cpp index 8e4c4019..195bc1fa 100644 --- a/src/context.cpp +++ b/src/context.cpp @@ -44,6 +44,13 @@ std::map Context::m_types; std::map Context::m_funcs; Parser::MacrosStore Context::m_macros; +const char * Interrupt::Return = ":Return"; +const char * Interrupt::Error = ":Error"; +const char * Interrupt::Parser = ":ErrorParser"; +const char * Interrupt::RunTime = ":ErrorRunTime"; +const char * Interrupt::Signal = ":ErrorSignal"; +const char * Interrupt::Abort = ":ErrorAbort"; + Context::Context(RuntimePtr global) { m_runtime = global; @@ -1440,7 +1447,7 @@ ObjPtr Context::CreateNative(TermPtr proto, const char *module, bool lazzy, cons #endif ObjPtr result; - ObjType type; + ObjType type = ObjType::None; if(proto->GetTokenID() == TermID::TERM) { if(proto->m_type_name.empty()) { LOG_RUNTIME("Cannot create native variable without specifying the type!"); @@ -1462,6 +1469,8 @@ ObjPtr Context::CreateNative(TermPtr proto, const char *module, bool lazzy, cons } } else if(proto->GetTokenID() == TermID::CALL) { type = ObjType::NativeFunc; + } else { + LOG_RUNTIME("Native type undefined! '%s'", proto->toString().c_str()); } result = Obj::CreateType(type); @@ -1489,7 +1498,7 @@ ObjPtr Context::CreateNative(TermPtr proto, const char *module, bool lazzy, cons result->m_var_is_init = true; } else { - LOG_RUNTIME("Fail CreateNative for object %s", result->toString().c_str()); + LOG_RUNTIME("Fail CreateNative for object %s", proto->toString().c_str()); } } return result; @@ -1518,14 +1527,40 @@ void *RunTime::GetNativeAddr(const char *name, const char *module) { } #ifndef _MSC_VER - return dlsym(m_modules[module]->GetHandle(), name); + + return GetDirectAddressFromLibrary(m_modules[module]->GetHandle(), name); #else return static_cast (::GetProcAddress(m_modules[module]->GetHandle(), name)); #endif } #ifndef _MSC_VER - return dlsym(nullptr, name); +// ASSERT(m_llvm_engine); + + // LOG_DEBUG("getAddressToGlobalIfAvailable( %s ) = %ld", "var_long", m_llvm_engine->getAddressToGlobalIfAvailable("var_long")); + // LOG_DEBUG("getGlobalValueAddress( %s ) = %ld", "var_long", m_llvm_engine->getGlobalValueAddress("var_long")); + // LOG_DEBUG("getPointerToNamedFunction( %s ) = %ld", "var_long", (long)m_llvm_engine->getPointerToNamedFunction("var_long", false)); + // + // LOG_DEBUG("getAddressToGlobalIfAvailable( %s ) = %ld", "_var_long", m_llvm_engine->getAddressToGlobalIfAvailable("_var_long")); + // LOG_DEBUG("getGlobalValueAddress( %s ) = %ld", "_var_long", m_llvm_engine->getGlobalValueAddress("_var_long")); + // LOG_DEBUG("getPointerToNamedFunction( %s ) = %ld", "_var_long", (long)m_llvm_engine->getPointerToNamedFunction("_var_long", false)); + // + // LOG_DEBUG("getAddressToGlobalIfAvailable( %s ) = %ld", "func_export", m_llvm_engine->getAddressToGlobalIfAvailable("func_export")); + // LOG_DEBUG("getGlobalValueAddress( %s ) = %ld", "func_export", m_llvm_engine->getGlobalValueAddress("func_export")); + // LOG_DEBUG("getPointerToNamedFunction( %s ) = %ld", "func_export", (long)m_llvm_engine->getPointerToNamedFunction("func_export", false)); + // + // LOG_DEBUG("getAddressToGlobalIfAvailable( %s ) = %ld", "_func_export", m_llvm_engine->getAddressToGlobalIfAvailable("_func_export")); + // LOG_DEBUG("getGlobalValueAddress( %s ) = %ld", "_func_export", m_llvm_engine->getGlobalValueAddress("_func_export")); + // LOG_DEBUG("getPointerToNamedFunction( %s ) = %ld", "_func_export", (long)m_llvm_engine->getPointerToNamedFunction("_func_export", false)); + // + // + // LOG_DEBUG("getAddressToGlobalIfAvailable( %s ) = %ld", name, m_llvm_engine->getAddressToGlobalIfAvailable(name)); + // LOG_DEBUG("getGlobalValueAddress( %s ) = %ld", name, m_llvm_engine->getGlobalValueAddress(name)); + // LOG_DEBUG("getPointerToNamedFunction( %s ) = %ld", name, (long)m_llvm_engine->getPointerToNamedFunction(name, false)); + + //m_llvm_engine->getPointerToNamedFunction(name, false); + return GetDirectAddressFromLibrary(nullptr, name); + // return ::dlsym(::dlopen(nullptr, RTLD_NOW | RTLD_GLOBAL), name); #else void *result = static_cast (::GetProcAddress(GetModuleHandle(nullptr), name)); if(result) { diff --git a/src/context.h b/src/context.h index d9611605..879a4c01 100644 --- a/src/context.h +++ b/src/context.h @@ -154,7 +154,7 @@ namespace newlang { return ExecStr(source, args, int_catch); } - inline ObjPtr ExecStr(const std::string_view str, Obj *args = nullptr, bool int_catch = false) { + inline ObjPtr ExecStr(const std::string str, Obj *args = nullptr, bool int_catch = false) { TermPtr exec = Parser::ParseString(str, &m_macros); if (exec->m_id == TermID::BLOCK) { exec->m_id = TermID::CALL_BLOCK; @@ -178,7 +178,7 @@ namespace newlang { static std::map m_types; - typedef std::variant> FuncItem; + typedef at::variant > FuncItem; static std::map m_funcs; // Системный и встроенные функции inline static ObjPtr CreateLVal(Context *ctx, TermPtr type) { @@ -235,11 +235,11 @@ namespace newlang { } auto func = m_funcs.find(str); if (func != m_funcs.end()) { - if (std::holds_alternative(func->second)) { - return std::get(func->second); + if (at::holds_alternative(func->second)) { + return at::get(func->second); } - ASSERT(std::holds_alternative> (func->second)); - return std::get> (func->second)[0]; + ASSERT(at::holds_alternative> (func->second)); + return at::get> (func->second)[0]; } return nullptr; } @@ -296,7 +296,7 @@ namespace newlang { ObjPtr CreateNative(TermPtr proto, const char *module = nullptr, bool lazzy = false, const char *mangle_name = nullptr, ffi_abi abi = FFI_DEFAULT_ABI); ObjPtr CreateNative(Obj args); - static bool pred_compare(const std::string_view find, const std::string_view str) { + static bool pred_compare(const std::string &find, const std::string &str) { size_t pos = 0; while (pos < find.size() && pos < str.size()) { if (find[pos] != str[pos]) { diff --git a/src/nbproject/Makefile-Debug.mk b/src/nbproject/Makefile-Debug.mk index d8528375..6ad02c2a 100644 --- a/src/nbproject/Makefile-Debug.mk +++ b/src/nbproject/Makefile-Debug.mk @@ -251,10 +251,10 @@ ${OBJECTDIR}/variable.o: variable.cpp pch.h.gch @echo Выполнение шага пользовательского сборки -${OBJECTDIR}/version.o: version.c +${OBJECTDIR}/version.o: version.cpp ${MKDIR} -p ${OBJECTDIR} ${RM} "$@.d" - $(COMPILE.c) -g -s -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DUMP -I. -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -std=c11 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/version.o version.c + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I. -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/version.o version.cpp : warning_pop.h parser.yy.cpp location.hh @echo Выполнение шага пользовательского сборки diff --git a/src/nbproject/Makefile-Debug_LLVM.mk b/src/nbproject/Makefile-Debug_LLVM.mk new file mode 100644 index 00000000..99fc3383 --- /dev/null +++ b/src/nbproject/Makefile-Debug_LLVM.mk @@ -0,0 +1,246 @@ +# +# Generated Makefile - do not edit! +# +# Edit the Makefile in the project folder instead (../Makefile). Each target +# has a -pre and a -post target defined where you can add customized code. +# +# This makefile implements configuration specific macros and targets. + + +# Environment +MKDIR=mkdir +CP=cp +GREP=grep +NM=nm +CCADMIN=CCadmin +RANLIB=ranlib +CC=clang +CCC=clang++ +CXX=clang++ +FC=gfortran +AS=as + +# Macros +CND_PLATFORM=CLang-Linux +CND_DLIB_EXT=so +CND_CONF=Debug_LLVM +CND_DISTDIR=dist +CND_BUILDDIR=build + +# Include project Makefile +include Makefile + +# Object Directory +OBJECTDIR=${CND_BUILDDIR}/${CND_CONF}/${CND_PLATFORM} + +# Object Files +OBJECTFILES= \ + ${OBJECTDIR}/_ext/e16507f5/logger.o \ + ${OBJECTDIR}/builtin.o \ + ${OBJECTDIR}/context.o \ + ${OBJECTDIR}/lexer.o \ + ${OBJECTDIR}/lexer.yy.o \ + ${OBJECTDIR}/newlang.o \ + ${OBJECTDIR}/nlc.o \ + ${OBJECTDIR}/object.o \ + ${OBJECTDIR}/parser.o \ + ${OBJECTDIR}/parser.yy.o \ + ${OBJECTDIR}/syntax_help.o \ + ${OBJECTDIR}/term.o \ + ${OBJECTDIR}/test/alg_test.o \ + ${OBJECTDIR}/test/compiler_test.o \ + ${OBJECTDIR}/test/eval_test.o \ + ${OBJECTDIR}/test/fraction_test.o \ + ${OBJECTDIR}/test/lexer_test.o \ + ${OBJECTDIR}/test/nlc_test.o \ + ${OBJECTDIR}/test/object_test.o \ + ${OBJECTDIR}/test/parser_test.o \ + ${OBJECTDIR}/variable.o \ + ${OBJECTDIR}/version.o + + +# C Compiler Flags +CFLAGS= + +# CC Compiler Flags +CCFLAGS=`llvm-config-13 --cxxflags` -std=c++17 -fexceptions -fcxx-exceptions -Wall -Wextra -Werror -Wfloat-equal -Wundef -Wcast-align -Wwrite-strings -Wmissing-declarations -Wredundant-decls -Wshadow -Woverloaded-virtual -Wno-trigraphs -Wno-invalid-source-encoding -stdlib=libstdc++ -Wno-error=unused-variable -Wno-error=unused-parameter -Wno-error=switch -fsanitize=undefined-trap -fsanitize-undefined-trap-on-error -Wno-undefined-var-template -Wno-switch +CXXFLAGS=`llvm-config-13 --cxxflags` -std=c++17 -fexceptions -fcxx-exceptions -Wall -Wextra -Werror -Wfloat-equal -Wundef -Wcast-align -Wwrite-strings -Wmissing-declarations -Wredundant-decls -Wshadow -Woverloaded-virtual -Wno-trigraphs -Wno-invalid-source-encoding -stdlib=libstdc++ -Wno-error=unused-variable -Wno-error=unused-parameter -Wno-error=switch -fsanitize=undefined-trap -fsanitize-undefined-trap-on-error -Wno-undefined-var-template -Wno-switch + +# Fortran Compiler Flags +FFLAGS= + +# Assembler Flags +ASFLAGS= + +# Link Libraries and Options +LDLIBSOPTIONS=-L../contrib/libtorch/lib -Wl,-rpath,'../contrib/libtorch/lib' -lc10 -ltorch_cpu -lcrypto + +# Build Targets +.build-conf: ${BUILD_SUBPROJECTS} + "${MAKE}" -f nbproject/Makefile-${CND_CONF}.mk ../output/nlc + +../output/nlc: ${OBJECTFILES} + ${MKDIR} -p ../output + ${LINK.cc} -o ../output/nlc ${OBJECTFILES} ${LDLIBSOPTIONS} `llvm-config-13 --libs --ldflags` -fuse-ld=lld-13 -g + +${OBJECTDIR}/_ext/e16507f5/logger.o: ../contrib/logger/logger.cpp + ${MKDIR} -p ${OBJECTDIR}/_ext/e16507f5 + ${RM} "$@.d" + $(COMPILE.cc) -g -O2 -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I. -I.. -I/usr/lib/llvm-13/lib/clang/13.0.1/include -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/_ext/e16507f5/logger.o ../contrib/logger/logger.cpp + +${OBJECTDIR}/builtin.o: builtin.cpp + ${MKDIR} -p ${OBJECTDIR} + ${RM} "$@.d" + $(COMPILE.cc) -g -O2 -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I. -I.. -I/usr/lib/llvm-13/lib/clang/13.0.1/include -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/builtin.o builtin.cpp + +${OBJECTDIR}/context.o: context.cpp parser.h parser.yy.h + ${MKDIR} -p ${OBJECTDIR} + ${RM} "$@.d" + $(COMPILE.cc) -g -O2 -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I. -I.. -I/usr/lib/llvm-13/lib/clang/13.0.1/include -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/context.o context.cpp + +${OBJECTDIR}/lexer.o: lexer.cpp parser.yy.h parser.yy.cpp location.hh + ${MKDIR} -p ${OBJECTDIR} + ${RM} "$@.d" + $(COMPILE.cc) -g -O2 -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I. -I.. -I/usr/lib/llvm-13/lib/clang/13.0.1/include -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/lexer.o lexer.cpp + +: lexer.h parser.yy.h parser.yy.cpp location.hh + @echo Выполнение шага пользовательского сборки + + +.NO_PARALLEL:lexer.yy.cpp lexer.yy.h +lexer.yy.cpp lexer.yy.h: lexer.l parser.y parser.yy.h parser.yy.cpp location.hh term.h + @echo + flex --outfile=lexer.yy.cpp --header-file=lexer.yy.h --noline lexer.l + +${OBJECTDIR}/lexer.yy.o: lexer.yy.cpp parser.y parser.yy.h parser.yy.cpp location.hh + ${MKDIR} -p ${OBJECTDIR} + ${RM} "$@.d" + $(COMPILE.cc) -g -O2 -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I. -I.. -I/usr/lib/llvm-13/lib/clang/13.0.1/include -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/lexer.yy.o lexer.yy.cpp + +${OBJECTDIR}/newlang.o: newlang.cpp + ${MKDIR} -p ${OBJECTDIR} + ${RM} "$@.d" + $(COMPILE.cc) -g -O2 -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I. -I.. -I/usr/lib/llvm-13/lib/clang/13.0.1/include -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/newlang.o newlang.cpp + +${OBJECTDIR}/nlc.o: nlc.cpp + ${MKDIR} -p ${OBJECTDIR} + ${RM} "$@.d" + $(COMPILE.cc) -g -O2 -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I. -I.. -I/usr/lib/llvm-13/lib/clang/13.0.1/include -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/nlc.o nlc.cpp + +${OBJECTDIR}/object.o: object.cpp + ${MKDIR} -p ${OBJECTDIR} + ${RM} "$@.d" + $(COMPILE.cc) -g -O2 -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I. -I.. -I/usr/lib/llvm-13/lib/clang/13.0.1/include -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/object.o object.cpp + +${OBJECTDIR}/parser.o: parser.cpp + ${MKDIR} -p ${OBJECTDIR} + ${RM} "$@.d" + $(COMPILE.cc) -g -O2 -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I. -I.. -I/usr/lib/llvm-13/lib/clang/13.0.1/include -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/parser.o parser.cpp + +.NO_PARALLEL:parser.yy.h parser.yy.cpp location.hh +parser.yy.h parser.yy.cpp location.hh: parser.y + @echo ************* Bison compile ************* + bison --output-file=parser.yy.cpp --defines=parser.yy.h --warnings=all parser.y + +${OBJECTDIR}/parser.yy.o: parser.yy.cpp parser.y + ${MKDIR} -p ${OBJECTDIR} + ${RM} "$@.d" + $(COMPILE.cc) -g -O2 -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I. -I.. -I/usr/lib/llvm-13/lib/clang/13.0.1/include -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/parser.yy.o parser.yy.cpp + +: parser.yy.h parser.y + @echo Выполнение шага пользовательского сборки + + +${OBJECTDIR}/syntax_help.o: syntax_help.cpp + ${MKDIR} -p ${OBJECTDIR} + ${RM} "$@.d" + $(COMPILE.cc) -g -O2 -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I. -I.. -I/usr/lib/llvm-13/lib/clang/13.0.1/include -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/syntax_help.o syntax_help.cpp + +${OBJECTDIR}/term.o: term.cpp + ${MKDIR} -p ${OBJECTDIR} + ${RM} "$@.d" + $(COMPILE.cc) -g -O2 -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I. -I.. -I/usr/lib/llvm-13/lib/clang/13.0.1/include -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/term.o term.cpp + +: term.h parser.yy.cpp location.hh + @echo Выполнение шага пользовательского сборки + + +${OBJECTDIR}/test/alg_test.o: test/alg_test.cpp + ${MKDIR} -p ${OBJECTDIR}/test + ${RM} "$@.d" + $(COMPILE.cc) -g -O2 -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I. -I.. -I/usr/lib/llvm-13/lib/clang/13.0.1/include -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/alg_test.o test/alg_test.cpp + +${OBJECTDIR}/test/compiler_test.o: test/compiler_test.cpp + ${MKDIR} -p ${OBJECTDIR}/test + ${RM} "$@.d" + $(COMPILE.cc) -g -O2 -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I. -I.. -I/usr/lib/llvm-13/lib/clang/13.0.1/include -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/compiler_test.o test/compiler_test.cpp + +${OBJECTDIR}/test/eval_test.o: test/eval_test.cpp + ${MKDIR} -p ${OBJECTDIR}/test + ${RM} "$@.d" + $(COMPILE.cc) -g -O2 -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I. -I.. -I/usr/lib/llvm-13/lib/clang/13.0.1/include -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/eval_test.o test/eval_test.cpp + +${OBJECTDIR}/test/fraction_test.o: test/fraction_test.cpp + ${MKDIR} -p ${OBJECTDIR}/test + ${RM} "$@.d" + $(COMPILE.cc) -g -O2 -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I. -I.. -I/usr/lib/llvm-13/lib/clang/13.0.1/include -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/fraction_test.o test/fraction_test.cpp + +${OBJECTDIR}/test/lexer_test.o: test/lexer_test.cpp + ${MKDIR} -p ${OBJECTDIR}/test + ${RM} "$@.d" + $(COMPILE.cc) -g -O2 -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I. -I.. -I/usr/lib/llvm-13/lib/clang/13.0.1/include -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/lexer_test.o test/lexer_test.cpp + +${OBJECTDIR}/test/nlc_test.o: test/nlc_test.cpp + ${MKDIR} -p ${OBJECTDIR}/test + ${RM} "$@.d" + $(COMPILE.cc) -g -O2 -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I. -I.. -I/usr/lib/llvm-13/lib/clang/13.0.1/include -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/nlc_test.o test/nlc_test.cpp + +${OBJECTDIR}/test/object_test.o: test/object_test.cpp + ${MKDIR} -p ${OBJECTDIR}/test + ${RM} "$@.d" + $(COMPILE.cc) -g -O2 -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I. -I.. -I/usr/lib/llvm-13/lib/clang/13.0.1/include -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -std=c++14 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/object_test.o test/object_test.cpp + +${OBJECTDIR}/test/parser_test.o: test/parser_test.cpp + ${MKDIR} -p ${OBJECTDIR}/test + ${RM} "$@.d" + $(COMPILE.cc) -g -O2 -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I. -I.. -I/usr/lib/llvm-13/lib/clang/13.0.1/include -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/parser_test.o test/parser_test.cpp + +${OBJECTDIR}/variable.o: variable.cpp + ${MKDIR} -p ${OBJECTDIR} + ${RM} "$@.d" + $(COMPILE.cc) -g -O2 -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I. -I.. -I/usr/lib/llvm-13/lib/clang/13.0.1/include -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/variable.o variable.cpp + +${OBJECTDIR}/version.o: version.cpp + ${MKDIR} -p ${OBJECTDIR} + ${RM} "$@.d" + $(COMPILE.cc) -g -O2 -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I. -I.. -I/usr/lib/llvm-13/lib/clang/13.0.1/include -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/version.o version.cpp + +: warning_pop.h parser.yy.cpp location.hh + @echo Выполнение шага пользовательского сборки + + +: warning_push.h parser.yy.cpp location.hh + @echo Выполнение шага пользовательского сборки + + +# Subprojects +.build-subprojects: + +# Clean Targets +.clean-conf: ${CLEAN_SUBPROJECTS} + ${RM} -r ${CND_BUILDDIR}/${CND_CONF} + ${RM} + ${RM} lexer.yy.cpp lexer.yy.h + ${RM} parser.yy.h parser.yy.cpp location.hh + ${RM} + ${RM} + ${RM} + ${RM} + +# Subprojects +.clean-subprojects: + +# Enable dependency checking +.dep.inc: .depcheck-impl + +include .dep.inc diff --git a/src/nbproject/Makefile-GCOV.mk b/src/nbproject/Makefile-GCOV.mk index 00a0fbff..c51c09c2 100644 --- a/src/nbproject/Makefile-GCOV.mk +++ b/src/nbproject/Makefile-GCOV.mk @@ -224,10 +224,10 @@ ${OBJECTDIR}/variable.o: variable.cpp ${RM} "$@.d" $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/variable.o variable.cpp -${OBJECTDIR}/version.o: version.c +${OBJECTDIR}/version.o: version.cpp ${MKDIR} -p ${OBJECTDIR} ${RM} "$@.d" - $(COMPILE.c) -g -s -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DUMP -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -std=c11 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/version.o version.c + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/version.o version.cpp : warning_pop.h parser.yy.cpp location.hh @echo Выполнение шага пользовательского сборки diff --git a/src/nbproject/Makefile-LLVM.mk b/src/nbproject/Makefile-LLVM.mk index 88ca82a9..d17db5ef 100644 --- a/src/nbproject/Makefile-LLVM.mk +++ b/src/nbproject/Makefile-LLVM.mk @@ -218,10 +218,10 @@ ${OBJECTDIR}/variable.o: variable.cpp ${RM} "$@.d" $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I/usr/lib/llvm-12/lib/clang/12.0.1/include -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I.. -std=c++14 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/variable.o variable.cpp -${OBJECTDIR}/version.o: version.c +${OBJECTDIR}/version.o: version.cpp ${MKDIR} -p ${OBJECTDIR} ${RM} "$@.d" - $(COMPILE.c) -g -s -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DUMP -DUNITTEST -I/usr/local/include -I/usr/include/x86_64-linux-gnu/c++/10 -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I.. -std=c11 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/version.o version.c + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I/usr/lib/llvm-12/lib/clang/12.0.1/include -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I.. -std=c++14 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/version.o version.cpp : warning_pop.h parser.yy.cpp location.hh @echo Выполнение шага пользовательского сборки diff --git a/src/nbproject/Makefile-LLVM_GCC.mk b/src/nbproject/Makefile-LLVM_GCC.mk index 96b8f9c7..f9c7b92e 100644 --- a/src/nbproject/Makefile-LLVM_GCC.mk +++ b/src/nbproject/Makefile-LLVM_GCC.mk @@ -218,10 +218,10 @@ ${OBJECTDIR}/variable.o: variable.cpp ${RM} "$@.d" $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I.. -std=c++14 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/variable.o variable.cpp -${OBJECTDIR}/version.o: version.c +${OBJECTDIR}/version.o: version.cpp ${MKDIR} -p ${OBJECTDIR} ${RM} "$@.d" - $(COMPILE.c) -g -s -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DUMP -DUNITTEST -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I.. -std=c11 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/version.o version.c + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I.. -std=c++14 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/version.o version.cpp : warning_pop.h parser.yy.cpp location.hh @echo Выполнение шага пользовательского сборки diff --git a/src/nbproject/Makefile-Release.mk b/src/nbproject/Makefile-Release.mk index b37eaf57..9985de75 100644 --- a/src/nbproject/Makefile-Release.mk +++ b/src/nbproject/Makefile-Release.mk @@ -204,10 +204,10 @@ ${OBJECTDIR}/variable.o: variable.cpp ${RM} "$@.d" $(COMPILE.cc) -O3 -Werror -I.. -std=c++14 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/variable.o variable.cpp -${OBJECTDIR}/version.o: version.c +${OBJECTDIR}/version.o: version.cpp ${MKDIR} -p ${OBJECTDIR} ${RM} "$@.d" - $(COMPILE.c) -O3 -Werror -s -I.. -std=c11 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/version.o version.c + $(COMPILE.cc) -O3 -Werror -I.. -std=c++14 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/version.o version.cpp # Subprojects .build-subprojects: diff --git a/src/nbproject/Makefile-UnitTest-Win32.mk b/src/nbproject/Makefile-UnitTest-Win32.mk index ecd27b30..30ba3aac 100644 --- a/src/nbproject/Makefile-UnitTest-Win32.mk +++ b/src/nbproject/Makefile-UnitTest-Win32.mk @@ -259,10 +259,10 @@ ${OBJECTDIR}/variable.o: variable.cpp pch.h.gch @echo Выполнение шага пользовательского сборки -${OBJECTDIR}/version.o: version.c +${OBJECTDIR}/version.o: version.cpp ${MKDIR} -p ${OBJECTDIR} ${RM} "$@.d" - $(COMPILE.c) -g -s -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DUMP -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -std=c11 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/version.o version.c + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -I/usr/lib/llvm-13/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/version.o version.cpp : warning_pop.h parser.yy.cpp location.hh @echo Выполнение шага пользовательского сборки diff --git a/src/nbproject/Makefile-UnitTest-Win64.mk b/src/nbproject/Makefile-UnitTest-Win64.mk index 93a61d9e..a553ded1 100644 --- a/src/nbproject/Makefile-UnitTest-Win64.mk +++ b/src/nbproject/Makefile-UnitTest-Win64.mk @@ -259,10 +259,10 @@ ${OBJECTDIR}/variable.o: variable.cpp pch.h.gch @echo Выполнение шага пользовательского сборки -${OBJECTDIR}/version.o: version.c +${OBJECTDIR}/version.o: version.cpp ${MKDIR} -p ${OBJECTDIR} ${RM} "$@.d" - $(COMPILE.c) -g -s -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DUMP -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I/usr/share/mingw-w64/include/ -std=c11 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/version.o version.c + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch-win/include/torch/csrc/api/include -I../contrib/libtorch-win/include -I../contrib/tensorboard_logger/include -I/usr/share/mingw-w64/include/ -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/version.o version.cpp : warning_pop.h parser.yy.cpp location.hh @echo Выполнение шага пользовательского сборки diff --git a/src/nbproject/Makefile-UnitTest.mk b/src/nbproject/Makefile-UnitTest.mk index 2bab3e9f..f4ae38d3 100644 --- a/src/nbproject/Makefile-UnitTest.mk +++ b/src/nbproject/Makefile-UnitTest.mk @@ -262,10 +262,10 @@ ${OBJECTDIR}/variable.o: variable.cpp pch.h.gch @echo Выполнение шага пользовательского сборки -${OBJECTDIR}/version.o: version.c +${OBJECTDIR}/version.o: version.cpp ${MKDIR} -p ${OBJECTDIR} ${RM} "$@.d" - $(COMPILE.c) -g -s -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DUMP -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -std=c11 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/version.o version.c + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I. -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -I/usr/lib/llvm-13/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/version.o version.cpp : warning_pop.h parser.yy.cpp location.hh @echo Выполнение шага пользовательского сборки diff --git a/src/nbproject/Makefile-UnitTest_LLVM.mk b/src/nbproject/Makefile-UnitTest_LLVM.mk index 26665fb4..68ca5ce0 100644 --- a/src/nbproject/Makefile-UnitTest_LLVM.mk +++ b/src/nbproject/Makefile-UnitTest_LLVM.mk @@ -65,8 +65,8 @@ OBJECTFILES= \ CFLAGS= # CC Compiler Flags -CCFLAGS=`llvm-config-12 --cxxflags` -fexceptions -fcxx-exceptions -Wall -Wextra -Werror -Wfloat-equal -Wundef -Wcast-align -Wwrite-strings -Wmissing-declarations -Wredundant-decls -Wshadow -Woverloaded-virtual -Wno-trigraphs -Wno-invalid-source-encoding -stdlib=libstdc++ -Wno-error=unused-variable -Wno-error=unused-parameter -Wno-error=switch -fsanitize=undefined-trap -fsanitize-undefined-trap-on-error -CXXFLAGS=`llvm-config-12 --cxxflags` -fexceptions -fcxx-exceptions -Wall -Wextra -Werror -Wfloat-equal -Wundef -Wcast-align -Wwrite-strings -Wmissing-declarations -Wredundant-decls -Wshadow -Woverloaded-virtual -Wno-trigraphs -Wno-invalid-source-encoding -stdlib=libstdc++ -Wno-error=unused-variable -Wno-error=unused-parameter -Wno-error=switch -fsanitize=undefined-trap -fsanitize-undefined-trap-on-error +CCFLAGS=`llvm-config-13 --cxxflags` -std=c++17 -fexceptions -fcxx-exceptions -Wall -Wextra -Werror -Wfloat-equal -Wundef -Wcast-align -Wwrite-strings -Wmissing-declarations -Wredundant-decls -Wshadow -Woverloaded-virtual -Wno-trigraphs -Wno-invalid-source-encoding -stdlib=libstdc++ -Wno-error=unused-variable -Wno-error=unused-parameter -Wno-error=switch -fsanitize=undefined-trap -fsanitize-undefined-trap-on-error -Wno-undefined-var-template -Wno-switch -fvisibility=default +CXXFLAGS=`llvm-config-13 --cxxflags` -std=c++17 -fexceptions -fcxx-exceptions -Wall -Wextra -Werror -Wfloat-equal -Wundef -Wcast-align -Wwrite-strings -Wmissing-declarations -Wredundant-decls -Wshadow -Woverloaded-virtual -Wno-trigraphs -Wno-invalid-source-encoding -stdlib=libstdc++ -Wno-error=unused-variable -Wno-error=unused-parameter -Wno-error=switch -fsanitize=undefined-trap -fsanitize-undefined-trap-on-error -Wno-undefined-var-template -Wno-switch -fvisibility=default # Fortran Compiler Flags FFLAGS= @@ -75,47 +75,45 @@ FFLAGS= ASFLAGS= # Link Libraries and Options -LDLIBSOPTIONS=-lpthread -ldl ../contrib/PDCurses/x11/libXCurses.a -lXaw -lXmu -lXt -lX11 -lXpm -lclangLex -lclangTooling -lclangFrontendTool -lclangFrontend -lclangSerialization -lclangCodeGen -lclangParse -lclangSema -lclangDriver -lclangStaticAnalyzerFrontend -lclangStaticAnalyzerCheckers -lclangStaticAnalyzerCore -lclangAnalysis -lclangARCMigrate -lclangRewrite -lclangRewriteFrontend -lclangEdit -lclangAST -lclangLex -lclangBasic -lclang -lLLVM-12 +LDLIBSOPTIONS=-L../contrib/libtorch/lib -L/usr/lib/x86_64-linux-gnu -Wl,-rpath,'../contrib/libtorch/lib' -Wl,-rpath,'/usr/lib/x86_64-linux-gnu' -lpthread -lc10 -ltorch -ltorch_cpu -lcrypto # Build Targets .build-conf: ${BUILD_SUBPROJECTS} - "${MAKE}" -f nbproject/Makefile-${CND_CONF}.mk ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/src + "${MAKE}" -f nbproject/Makefile-${CND_CONF}.mk ../output/nlc_unit_test -${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/src: ../contrib/PDCurses/x11/libXCurses.a - -${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/src: ${OBJECTFILES} - ${MKDIR} -p ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM} - ${LINK.cc} -o ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/src ${OBJECTFILES} ${LDLIBSOPTIONS} `llvm-config-12 --libs --ldflags` -stdlib=libstdc++ -fuse-ld=lld-12 -g +../output/nlc_unit_test: ${OBJECTFILES} + ${MKDIR} -p ../output + ${LINK.cc} -o ../output/nlc_unit_test ${OBJECTFILES} ${LDLIBSOPTIONS} `llvm-config-13 --libs --ldflags` -stdlib=libstdc++ -fuse-ld=lld-13 -g ${OBJECTDIR}/_ext/1e501df/gtest-all.o: ../contrib/googletest/googletest/src/gtest-all.cc ${MKDIR} -p ${OBJECTDIR}/_ext/1e501df ${RM} "$@.d" - $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I/usr/lib/llvm-12/lib/clang/12.0.1/include -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I.. -std=c++14 -Wno-undef -Wno-sign-compare -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/_ext/1e501df/gtest-all.o ../contrib/googletest/googletest/src/gtest-all.cc + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I. -I.. -I/usr/lib/llvm-13/lib/clang/13.0.1/include -I/usr/include/llvm-c-13 -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -std=c++14 -Wno-undef -Wno-sign-compare -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/_ext/1e501df/gtest-all.o ../contrib/googletest/googletest/src/gtest-all.cc ${OBJECTDIR}/_ext/1e501df/gtest_main.o: ../contrib/googletest/googletest/src/gtest_main.cc ${MKDIR} -p ${OBJECTDIR}/_ext/1e501df ${RM} "$@.d" - $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I/usr/lib/llvm-12/lib/clang/12.0.1/include -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I.. -std=c++14 -Wno-undef -Wno-sign-compare -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/_ext/1e501df/gtest_main.o ../contrib/googletest/googletest/src/gtest_main.cc + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I. -I.. -I/usr/lib/llvm-13/lib/clang/13.0.1/include -I/usr/include/llvm-c-13 -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -std=c++14 -Wno-undef -Wno-sign-compare -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/_ext/1e501df/gtest_main.o ../contrib/googletest/googletest/src/gtest_main.cc ${OBJECTDIR}/_ext/e16507f5/logger.o: ../contrib/logger/logger.cpp ${MKDIR} -p ${OBJECTDIR}/_ext/e16507f5 ${RM} "$@.d" - $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I/usr/lib/llvm-12/lib/clang/12.0.1/include -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I.. -std=c++14 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/_ext/e16507f5/logger.o ../contrib/logger/logger.cpp + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I. -I.. -I/usr/lib/llvm-13/lib/clang/13.0.1/include -I/usr/include/llvm-c-13 -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/_ext/e16507f5/logger.o ../contrib/logger/logger.cpp ${OBJECTDIR}/builtin.o: builtin.cpp ${MKDIR} -p ${OBJECTDIR} ${RM} "$@.d" - $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I/usr/lib/llvm-12/lib/clang/12.0.1/include -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I.. -std=c++14 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/builtin.o builtin.cpp + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I. -I.. -I/usr/lib/llvm-13/lib/clang/13.0.1/include -I/usr/include/llvm-c-13 -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/builtin.o builtin.cpp ${OBJECTDIR}/context.o: context.cpp parser.h parser.yy.h ${MKDIR} -p ${OBJECTDIR} ${RM} "$@.d" - $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I/usr/lib/llvm-12/lib/clang/12.0.1/include -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I.. -std=c++14 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/context.o context.cpp + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I. -I.. -I/usr/lib/llvm-13/lib/clang/13.0.1/include -I/usr/include/llvm-c-13 -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/context.o context.cpp ${OBJECTDIR}/lexer.o: lexer.cpp parser.yy.h parser.yy.cpp location.hh ${MKDIR} -p ${OBJECTDIR} ${RM} "$@.d" - $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I/usr/lib/llvm-12/lib/clang/12.0.1/include -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I.. -std=c++14 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/lexer.o lexer.cpp + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I. -I.. -I/usr/lib/llvm-13/lib/clang/13.0.1/include -I/usr/include/llvm-c-13 -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/lexer.o lexer.cpp : lexer.h parser.yy.h parser.yy.cpp location.hh @echo Выполнение шага пользовательского сборки @@ -129,27 +127,27 @@ lexer.yy.cpp lexer.yy.h: lexer.l parser.y parser.yy.h parser.yy.cpp location.hh ${OBJECTDIR}/lexer.yy.o: lexer.yy.cpp parser.y parser.yy.h parser.yy.cpp location.hh ${MKDIR} -p ${OBJECTDIR} ${RM} "$@.d" - $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I/usr/lib/llvm-12/lib/clang/12.0.1/include -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I.. -std=c++14 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/lexer.yy.o lexer.yy.cpp + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I. -I.. -I/usr/lib/llvm-13/lib/clang/13.0.1/include -I/usr/include/llvm-c-13 -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/lexer.yy.o lexer.yy.cpp ${OBJECTDIR}/newlang.o: newlang.cpp ${MKDIR} -p ${OBJECTDIR} ${RM} "$@.d" - $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I/usr/lib/llvm-12/lib/clang/12.0.1/include -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I.. -std=c++14 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/newlang.o newlang.cpp + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I. -I.. -I/usr/lib/llvm-13/lib/clang/13.0.1/include -I/usr/include/llvm-c-13 -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/newlang.o newlang.cpp ${OBJECTDIR}/nlc.o: nlc.cpp ${MKDIR} -p ${OBJECTDIR} ${RM} "$@.d" - $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I/usr/lib/llvm-12/lib/clang/12.0.1/include -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I.. -std=c++14 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/nlc.o nlc.cpp + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I. -I.. -I/usr/lib/llvm-13/lib/clang/13.0.1/include -I/usr/include/llvm-c-13 -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/nlc.o nlc.cpp ${OBJECTDIR}/object.o: object.cpp ${MKDIR} -p ${OBJECTDIR} ${RM} "$@.d" - $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I/usr/lib/llvm-12/lib/clang/12.0.1/include -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I.. -std=c++14 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/object.o object.cpp + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I. -I.. -I/usr/lib/llvm-13/lib/clang/13.0.1/include -I/usr/include/llvm-c-13 -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/object.o object.cpp ${OBJECTDIR}/parser.o: parser.cpp ${MKDIR} -p ${OBJECTDIR} ${RM} "$@.d" - $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I/usr/lib/llvm-12/lib/clang/12.0.1/include -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I.. -std=c++14 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/parser.o parser.cpp + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I. -I.. -I/usr/lib/llvm-13/lib/clang/13.0.1/include -I/usr/include/llvm-c-13 -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/parser.o parser.cpp .NO_PARALLEL:parser.yy.h parser.yy.cpp location.hh parser.yy.h parser.yy.cpp location.hh: parser.y @@ -159,7 +157,7 @@ parser.yy.h parser.yy.cpp location.hh: parser.y ${OBJECTDIR}/parser.yy.o: parser.yy.cpp parser.y ${MKDIR} -p ${OBJECTDIR} ${RM} "$@.d" - $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I/usr/lib/llvm-12/lib/clang/12.0.1/include -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I.. -std=c++14 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/parser.yy.o parser.yy.cpp + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I. -I.. -I/usr/lib/llvm-13/lib/clang/13.0.1/include -I/usr/include/llvm-c-13 -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/parser.yy.o parser.yy.cpp : parser.yy.h parser.y @echo Выполнение шага пользовательского сборки @@ -168,12 +166,12 @@ ${OBJECTDIR}/parser.yy.o: parser.yy.cpp parser.y ${OBJECTDIR}/syntax_help.o: syntax_help.cpp ${MKDIR} -p ${OBJECTDIR} ${RM} "$@.d" - $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I/usr/lib/llvm-12/lib/clang/12.0.1/include -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I.. -std=c++14 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/syntax_help.o syntax_help.cpp + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I. -I.. -I/usr/lib/llvm-13/lib/clang/13.0.1/include -I/usr/include/llvm-c-13 -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/syntax_help.o syntax_help.cpp ${OBJECTDIR}/term.o: term.cpp ${MKDIR} -p ${OBJECTDIR} ${RM} "$@.d" - $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I/usr/lib/llvm-12/lib/clang/12.0.1/include -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I.. -std=c++14 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/term.o term.cpp + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I. -I.. -I/usr/lib/llvm-13/lib/clang/13.0.1/include -I/usr/include/llvm-c-13 -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/term.o term.cpp : term.h parser.yy.cpp location.hh @echo Выполнение шага пользовательского сборки @@ -182,52 +180,52 @@ ${OBJECTDIR}/term.o: term.cpp ${OBJECTDIR}/test/alg_test.o: test/alg_test.cpp ${MKDIR} -p ${OBJECTDIR}/test ${RM} "$@.d" - $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I/usr/lib/llvm-12/lib/clang/12.0.1/include -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I.. -std=c++14 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/alg_test.o test/alg_test.cpp + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I. -I.. -I/usr/lib/llvm-13/lib/clang/13.0.1/include -I/usr/include/llvm-c-13 -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/alg_test.o test/alg_test.cpp ${OBJECTDIR}/test/compiler_test.o: test/compiler_test.cpp ${MKDIR} -p ${OBJECTDIR}/test ${RM} "$@.d" - $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I/usr/lib/llvm-12/lib/clang/12.0.1/include -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I.. -std=c++14 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/compiler_test.o test/compiler_test.cpp + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I. -I.. -I/usr/lib/llvm-13/lib/clang/13.0.1/include -I/usr/include/llvm-c-13 -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/compiler_test.o test/compiler_test.cpp ${OBJECTDIR}/test/eval_test.o: test/eval_test.cpp ${MKDIR} -p ${OBJECTDIR}/test ${RM} "$@.d" - $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I/usr/lib/llvm-12/lib/clang/12.0.1/include -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I.. -std=c++14 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/eval_test.o test/eval_test.cpp + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I. -I.. -I/usr/lib/llvm-13/lib/clang/13.0.1/include -I/usr/include/llvm-c-13 -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/eval_test.o test/eval_test.cpp ${OBJECTDIR}/test/fraction_test.o: test/fraction_test.cpp ${MKDIR} -p ${OBJECTDIR}/test ${RM} "$@.d" - $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I/usr/lib/llvm-12/lib/clang/12.0.1/include -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I.. -std=c++14 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/fraction_test.o test/fraction_test.cpp + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I. -I.. -I/usr/lib/llvm-13/lib/clang/13.0.1/include -I/usr/include/llvm-c-13 -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/fraction_test.o test/fraction_test.cpp ${OBJECTDIR}/test/lexer_test.o: test/lexer_test.cpp ${MKDIR} -p ${OBJECTDIR}/test ${RM} "$@.d" - $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I/usr/lib/llvm-12/lib/clang/12.0.1/include -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I.. -std=c++14 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/lexer_test.o test/lexer_test.cpp + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I. -I.. -I/usr/lib/llvm-13/lib/clang/13.0.1/include -I/usr/include/llvm-c-13 -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/lexer_test.o test/lexer_test.cpp ${OBJECTDIR}/test/nlc_test.o: test/nlc_test.cpp ${MKDIR} -p ${OBJECTDIR}/test ${RM} "$@.d" - $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I/usr/lib/llvm-12/lib/clang/12.0.1/include -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I.. -std=c++14 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/nlc_test.o test/nlc_test.cpp + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I. -I.. -I/usr/lib/llvm-13/lib/clang/13.0.1/include -I/usr/include/llvm-c-13 -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/nlc_test.o test/nlc_test.cpp ${OBJECTDIR}/test/object_test.o: test/object_test.cpp ${MKDIR} -p ${OBJECTDIR}/test ${RM} "$@.d" - $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I/usr/lib/llvm-12/lib/clang/12.0.1/include -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I.. -std=c++14 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/object_test.o test/object_test.cpp + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I. -I.. -I/usr/lib/llvm-13/lib/clang/13.0.1/include -I/usr/include/llvm-c-13 -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -std=c++14 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/object_test.o test/object_test.cpp ${OBJECTDIR}/test/parser_test.o: test/parser_test.cpp ${MKDIR} -p ${OBJECTDIR}/test ${RM} "$@.d" - $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I/usr/lib/llvm-12/lib/clang/12.0.1/include -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I.. -std=c++14 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/parser_test.o test/parser_test.cpp + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I. -I.. -I/usr/lib/llvm-13/lib/clang/13.0.1/include -I/usr/include/llvm-c-13 -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/parser_test.o test/parser_test.cpp ${OBJECTDIR}/variable.o: variable.cpp ${MKDIR} -p ${OBJECTDIR} ${RM} "$@.d" - $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I/usr/lib/llvm-12/lib/clang/12.0.1/include -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I.. -std=c++14 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/variable.o variable.cpp + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I. -I.. -I/usr/lib/llvm-13/lib/clang/13.0.1/include -I/usr/include/llvm-c-13 -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/variable.o variable.cpp -${OBJECTDIR}/version.o: version.c +${OBJECTDIR}/version.o: version.cpp ${MKDIR} -p ${OBJECTDIR} ${RM} "$@.d" - $(COMPILE.c) -g -s -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DUMP -DUNITTEST -I/usr/local/include -I/usr/include/x86_64-linux-gnu/c++/10 -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I.. -std=c11 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/version.o version.c + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I. -I.. -I/usr/lib/llvm-13/lib/clang/13.0.1/include -I/usr/include/llvm-c-13 -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/version.o version.cpp : warning_pop.h parser.yy.cpp location.hh @echo Выполнение шага пользовательского сборки diff --git a/src/nbproject/Makefile-impl.mk b/src/nbproject/Makefile-impl.mk index f394bd32..12246bf0 100644 --- a/src/nbproject/Makefile-impl.mk +++ b/src/nbproject/Makefile-impl.mk @@ -31,7 +31,7 @@ DEFAULTCONF=Debug CONF=${DEFAULTCONF} # All Configurations -ALLCONFS=Debug Release UnitTest UnitTest_LLVM GCOV LLVM LLVM_GCC UnitTest-Win64 UnitTest-Win32 +ALLCONFS=Debug Debug_LLVM Release UnitTest UnitTest_LLVM GCOV LLVM LLVM_GCC UnitTest-Win64 UnitTest-Win32 # build diff --git a/src/nbproject/Makefile-variables.mk b/src/nbproject/Makefile-variables.mk index 53285db4..2e98751d 100644 --- a/src/nbproject/Makefile-variables.mk +++ b/src/nbproject/Makefile-variables.mk @@ -14,6 +14,14 @@ CND_ARTIFACT_PATH_Debug=../output/nlc CND_PACKAGE_DIR_Debug=dist/Debug/GNU-Linux/package CND_PACKAGE_NAME_Debug=src.tar CND_PACKAGE_PATH_Debug=dist/Debug/GNU-Linux/package/src.tar +# Debug_LLVM configuration +CND_PLATFORM_Debug_LLVM=CLang-Linux +CND_ARTIFACT_DIR_Debug_LLVM=../output +CND_ARTIFACT_NAME_Debug_LLVM=nlc +CND_ARTIFACT_PATH_Debug_LLVM=../output/nlc +CND_PACKAGE_DIR_Debug_LLVM=dist/Debug_LLVM/CLang-Linux/package +CND_PACKAGE_NAME_Debug_LLVM=src.tar +CND_PACKAGE_PATH_Debug_LLVM=dist/Debug_LLVM/CLang-Linux/package/src.tar # Release configuration CND_PLATFORM_Release=GNU-Linux CND_ARTIFACT_DIR_Release=dist/Release/GNU-Linux @@ -32,9 +40,9 @@ CND_PACKAGE_NAME_UnitTest=src.tar CND_PACKAGE_PATH_UnitTest=dist/UnitTest/GNU-Linux/package/src.tar # UnitTest_LLVM configuration CND_PLATFORM_UnitTest_LLVM=CLang-Linux -CND_ARTIFACT_DIR_UnitTest_LLVM=dist/UnitTest_LLVM/CLang-Linux -CND_ARTIFACT_NAME_UnitTest_LLVM=src -CND_ARTIFACT_PATH_UnitTest_LLVM=dist/UnitTest_LLVM/CLang-Linux/src +CND_ARTIFACT_DIR_UnitTest_LLVM=../output +CND_ARTIFACT_NAME_UnitTest_LLVM=nlc_unit_test +CND_ARTIFACT_PATH_UnitTest_LLVM=../output/nlc_unit_test CND_PACKAGE_DIR_UnitTest_LLVM=dist/UnitTest_LLVM/CLang-Linux/package CND_PACKAGE_NAME_UnitTest_LLVM=src.tar CND_PACKAGE_PATH_UnitTest_LLVM=dist/UnitTest_LLVM/CLang-Linux/package/src.tar diff --git a/src/nbproject/Package-Debug_LLVM.bash b/src/nbproject/Package-Debug_LLVM.bash new file mode 100644 index 00000000..1f3df4ae --- /dev/null +++ b/src/nbproject/Package-Debug_LLVM.bash @@ -0,0 +1,76 @@ +#!/bin/bash -x + +# +# Generated - do not edit! +# + +# Macros +TOP=`pwd` +CND_PLATFORM=CLang-Linux +CND_CONF=Debug_LLVM +CND_DISTDIR=dist +CND_BUILDDIR=build +CND_DLIB_EXT=so +NBTMPDIR=${CND_BUILDDIR}/${CND_CONF}/${CND_PLATFORM}/tmp-packaging +TMPDIRNAME=tmp-packaging +OUTPUT_PATH=../output/nlc +OUTPUT_BASENAME=nlc +PACKAGE_TOP_DIR=src/ + +# Functions +function checkReturnCode +{ + rc=$? + if [ $rc != 0 ] + then + exit $rc + fi +} +function makeDirectory +# $1 directory path +# $2 permission (optional) +{ + mkdir -p "$1" + checkReturnCode + if [ "$2" != "" ] + then + chmod $2 "$1" + checkReturnCode + fi +} +function copyFileToTmpDir +# $1 from-file path +# $2 to-file path +# $3 permission +{ + cp "$1" "$2" + checkReturnCode + if [ "$3" != "" ] + then + chmod $3 "$2" + checkReturnCode + fi +} + +# Setup +cd "${TOP}" +mkdir -p ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package +rm -rf ${NBTMPDIR} +mkdir -p ${NBTMPDIR} + +# Copy files and create directories and links +cd "${TOP}" +makeDirectory "${NBTMPDIR}/src/bin" +copyFileToTmpDir "${OUTPUT_PATH}" "${NBTMPDIR}/${PACKAGE_TOP_DIR}bin/${OUTPUT_BASENAME}" 0755 + + +# Generate tar file +cd "${TOP}" +rm -f ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/src.tar +cd ${NBTMPDIR} +tar -vcf ../../../../${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/src.tar * +checkReturnCode + +# Cleanup +cd "${TOP}" +rm -rf ${NBTMPDIR} diff --git a/src/nbproject/Package-UnitTest_LLVM.bash b/src/nbproject/Package-UnitTest_LLVM.bash index ed605924..62718126 100644 --- a/src/nbproject/Package-UnitTest_LLVM.bash +++ b/src/nbproject/Package-UnitTest_LLVM.bash @@ -13,8 +13,8 @@ CND_BUILDDIR=build CND_DLIB_EXT=so NBTMPDIR=${CND_BUILDDIR}/${CND_CONF}/${CND_PLATFORM}/tmp-packaging TMPDIRNAME=tmp-packaging -OUTPUT_PATH=${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/src -OUTPUT_BASENAME=src +OUTPUT_PATH=../output/nlc_unit_test +OUTPUT_BASENAME=nlc_unit_test PACKAGE_TOP_DIR=src/ # Functions diff --git a/src/nbproject/configurations.xml b/src/nbproject/configurations.xml index 8f02d1fd..8c1ea276 100644 --- a/src/nbproject/configurations.xml +++ b/src/nbproject/configurations.xml @@ -67,7 +67,7 @@ pch.h.gch ../docs/syntax.txt syntax_help.cpp - version.c + version.cpp version.h pch.h.gch - + + + + + + + parser.yy.cpp location.hh + + + + + parser.yy.cpp location.hh + + + + + + CLang|CLang + true + false + + + + true + + /usr/local/include + /usr/include/x86_64-linux-gnu/c++/10 + ../contrib/googletest/googletest + ../contrib/googletest/googletest/include + .. + + + DEBUG + LOG_LEVEL_NORMAL=LOG_LEVEL_DUMP + UNITTEST + + + + 4 + + . + .. + /usr/lib/llvm-13/lib/clang/13.0.1/include + /usr/include/x86_64-linux-gnu/c++/10 + /usr/include/c++/10 + /usr/local/include + /usr/include + ../contrib/googletest/googletest + ../contrib/googletest/googletest/include + ../contrib/Tensorflow/bazel-bin/tensorflow/include + ../contrib/Lyra/include + ../contrib/libtorch/include/torch/csrc/api/include + ../contrib/libtorch/include + + `llvm-config-13 --cxxflags` -std=c++17 -fexceptions -fcxx-exceptions -Wall -Wextra -Werror -Wfloat-equal -Wundef -Wcast-align -Wwrite-strings -Wmissing-declarations -Wredundant-decls -Wshadow -Woverloaded-virtual -Wno-trigraphs -Wno-invalid-source-encoding -stdlib=libstdc++ -Wno-error=unused-variable -Wno-error=unused-parameter -Wno-error=switch -fsanitize=undefined-trap -fsanitize-undefined-trap-on-error -Wno-undefined-var-template -Wno-switch + + DEBUG + LOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG + PDC_WIDE + + false + + + ../output/nlc + + ../contrib/libtorch/lib + + + ../contrib/libtorch/lib + + + c10 + torch_cpu + crypto + + `llvm-config-13 --libs --ldflags` -fuse-ld=lld-13 -g + + + + + + + -Wno-undef -Wno-sign-compare + + + + + -Wno-undef -Wno-sign-compare + + + + + + + + + + + + + + + + + + + + + + + + + + + parser.h parser.yy.h + + + + + + + + + parser.yy.h parser.yy.cpp location.hh + + + + + parser.yy.h parser.yy.cpp location.hh + + + + + flex --outfile=lexer.yy.cpp --header-file=lexer.yy.h --noline lexer.l + + lexer.yy.cpp lexer.yy.h + parser.y parser.yy.h parser.yy.cpp location.hh term.h + + + + + parser.y parser.yy.h parser.yy.cpp location.hh + + + + + + + + + + + + + + + + + + + + + + + + + + + + bison --output-file=parser.yy.cpp --defines=parser.yy.h --warnings=all parser.y + ************* Bison compile ************* + parser.yy.h parser.yy.cpp location.hh + + + + + parser.y + + + + + parser.y + + + + + + + + + + + + + + + + parser.yy.cpp location.hh + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -536,7 +767,7 @@ - + @@ -826,7 +1057,7 @@ pch.h.gch - + @@ -850,7 +1081,6 @@ true - 10 /usr/local/include /usr/include/x86_64-linux-gnu/c++/10 @@ -865,9 +1095,11 @@ - 11 - /usr/lib/llvm-12/lib/clang/12.0.1/include + . + .. + /usr/lib/llvm-13/lib/clang/13.0.1/include + /usr/include/llvm-c-13 /usr/include/x86_64-linux-gnu/c++/10 /usr/include/c++/10 /usr/local/include @@ -876,9 +1108,10 @@ ../contrib/googletest/googletest/include ../contrib/Tensorflow/bazel-bin/tensorflow/include ../contrib/Lyra/include - .. + ../contrib/libtorch/include/torch/csrc/api/include + ../contrib/libtorch/include - `llvm-config-12 --cxxflags` -fexceptions -fcxx-exceptions -Wall -Wextra -Werror -Wfloat-equal -Wundef -Wcast-align -Wwrite-strings -Wmissing-declarations -Wredundant-decls -Wshadow -Woverloaded-virtual -Wno-trigraphs -Wno-invalid-source-encoding -stdlib=libstdc++ -Wno-error=unused-variable -Wno-error=unused-parameter -Wno-error=switch -fsanitize=undefined-trap -fsanitize-undefined-trap-on-error + `llvm-config-13 --cxxflags` -std=c++17 -fexceptions -fcxx-exceptions -Wall -Wextra -Werror -Wfloat-equal -Wundef -Wcast-align -Wwrite-strings -Wmissing-declarations -Wredundant-decls -Wshadow -Woverloaded-virtual -Wno-trigraphs -Wno-invalid-source-encoding -stdlib=libstdc++ -Wno-error=unused-variable -Wno-error=unused-parameter -Wno-error=switch -fsanitize=undefined-trap -fsanitize-undefined-trap-on-error -Wno-undefined-var-template -Wno-switch -fvisibility=default DEBUG LOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG @@ -888,39 +1121,23 @@ false + ../output/nlc_unit_test + + ../contrib/libtorch/lib + /usr/lib/x86_64-linux-gnu + + + ../contrib/libtorch/lib + /usr/lib/x86_64-linux-gnu + PosixThreads - DynamicLinking - ../contrib/PDCurses/x11/libXCurses.a - Xaw - Xmu - Xt - X11 - Xpm - clangLex - clangTooling - clangFrontendTool - clangFrontend - clangSerialization - clangCodeGen - clangParse - clangSema - clangDriver - clangStaticAnalyzerFrontend - clangStaticAnalyzerCheckers - clangStaticAnalyzerCore - clangAnalysis - clangARCMigrate - clangRewrite - clangRewriteFrontend - clangEdit - clangAST - clangLex - clangBasic - clang - LLVM-12 + c10 + torch + torch_cpu + crypto - `llvm-config-12 --libs --ldflags` -stdlib=libstdc++ -fuse-ld=lld-12 -g + `llvm-config-13 --libs --ldflags` -stdlib=libstdc++ -fuse-ld=lld-13 -g @@ -1076,7 +1293,7 @@ - + @@ -1291,7 +1508,7 @@ - + @@ -1534,7 +1751,7 @@ - + @@ -1773,7 +1990,7 @@ - + @@ -2066,7 +2283,7 @@ pch.h.gch - + @@ -2358,7 +2575,7 @@ pch.h.gch - + diff --git a/src/nbproject/project.xml b/src/nbproject/project.xml index bb662e83..cd9abda6 100644 --- a/src/nbproject/project.xml +++ b/src/nbproject/project.xml @@ -4,7 +4,7 @@ NewLang - c + cc,cpp h,hh,y UTF-8 @@ -17,6 +17,10 @@ Debug 1 + + Debug_LLVM + 1 + Release 1 diff --git a/src/newlang.cpp b/src/newlang.cpp index 12dd122d..a3c490ea 100644 --- a/src/newlang.cpp +++ b/src/newlang.cpp @@ -6,6 +6,10 @@ using namespace newlang; +//LLVMBuilderRef RunTime::m_llvm_builder = nullptr; +//LLVMModuleRef RunTime::m_llvm_module = nullptr; +//LLVMExecutionEngineRef RunTime::m_llvm_engine = nullptr; + TermPtr CompileInfo::isFunction(TermPtr term) { ASSERT(term); if(term) { @@ -401,82 +405,82 @@ std::string newlang::MangleName(const char * name) { bool NewLang::MakeFunctionCpp(CompileInfo &ci, std::string func_name, TermPtr &func_define, std::ostream &out) { LOG_RUNTIME("MakeFunctionCpp Not implemeneted!"); -// if(!func_define->IsFunction()) { -// LOG_RUNTIME("No function name"); -// } -// if(!func_define->Right()) { -// LOG_RUNTIME("No function body"); -// } -// -// std::string text = func_define->toString(); -// text = std::regex_replace(text, std::regex("\""), "\\\""); -// text = std::regex_replace(text, std::regex("\n"), "\\n"); -// text = std::regex_replace(text, std::regex("\t"), "\\t"); -// text = std::regex_replace(text, std::regex("\r"), "\\r"); -// text = std::regex_replace(text, std::regex("\b"), "\\b"); -// text = std::regex_replace(text, std::regex("\f"), "\\f"); -// out << "const char * " << MangleName(func_define->Left()->GetFullName().c_str()) << "_text"; -// out << "=\"" << text << "\";\n"; -// -// out << "const ObjPtr " << MangleName(func_define->Left()->GetFullName().c_str()) << "_arguments"; -// out << "=Obj::CreateDict(Obj::ArgNull(\"self\")"; -// if(func_define->Left()->size()) { -// for (size_t i = 0; i < func_define->Left()->size(); i++) { -// out << ", "; -// std::string var_name; -// if(func_define->Left()->name(i).empty()) { -// var_name = func_define->Left()->at(i).second->GetFullName(); -// out << "Obj::ArgNull("; -// -// } else { -// out << "Obj::Arg("; -// var_name = func_define->Left()->name(i); -// std::string impl; -// GetImpl(ci, func_define->Left()->at(i).second, impl); -// out << impl; -// out << ", "; -// } -// out << "\"" << var_name << "\")"; -// } -// } -// out << ");"; -// out << " // Default function args \n"; -// -// -// WriteFunctionName_(func_define, out); -// out << " {\n"; -// -// -// // Аргументы функции с локальным доступом по имени или индексу -// if(func_define->Left()->size()) { -// for (size_t i = 0; i < func_define->Left()->size(); i++) { -// std::string var_name; -// if(func_define->Left()->name(i).empty()) { -// var_name = func_define->Left()->at(i).second->GetFullName(); -// } else { -// var_name = func_define->Left()->name(i); -// } -// ci.arguments.insert(std::pair(var_name, func_define->Left())); -// } -// } -// -// std::string body; -// if(func_define->GetTokenID() == TermID::SIMPLE) { -// body = WriteSimpleBody_(ci, func_define); -// } else { -// body = MakeFunctionBodyCpp(ci, func_define->Right()); -// } -// -// out << body; -// -// // Проверка типа возвращаемого значения из функции -// NL_TYPECHECK(func_define->Left(), func_define->Left()->m_type_name, ci.last_type); -// -// out << "}\n"; -// -// ci.arguments.clear(); -// -// return true; + // if(!func_define->IsFunction()) { + // LOG_RUNTIME("No function name"); + // } + // if(!func_define->Right()) { + // LOG_RUNTIME("No function body"); + // } + // + // std::string text = func_define->toString(); + // text = std::regex_replace(text, std::regex("\""), "\\\""); + // text = std::regex_replace(text, std::regex("\n"), "\\n"); + // text = std::regex_replace(text, std::regex("\t"), "\\t"); + // text = std::regex_replace(text, std::regex("\r"), "\\r"); + // text = std::regex_replace(text, std::regex("\b"), "\\b"); + // text = std::regex_replace(text, std::regex("\f"), "\\f"); + // out << "const char * " << MangleName(func_define->Left()->GetFullName().c_str()) << "_text"; + // out << "=\"" << text << "\";\n"; + // + // out << "const ObjPtr " << MangleName(func_define->Left()->GetFullName().c_str()) << "_arguments"; + // out << "=Obj::CreateDict(Obj::ArgNull(\"self\")"; + // if(func_define->Left()->size()) { + // for (size_t i = 0; i < func_define->Left()->size(); i++) { + // out << ", "; + // std::string var_name; + // if(func_define->Left()->name(i).empty()) { + // var_name = func_define->Left()->at(i).second->GetFullName(); + // out << "Obj::ArgNull("; + // + // } else { + // out << "Obj::Arg("; + // var_name = func_define->Left()->name(i); + // std::string impl; + // GetImpl(ci, func_define->Left()->at(i).second, impl); + // out << impl; + // out << ", "; + // } + // out << "\"" << var_name << "\")"; + // } + // } + // out << ");"; + // out << " // Default function args \n"; + // + // + // WriteFunctionName_(func_define, out); + // out << " {\n"; + // + // + // // Аргументы функции с локальным доступом по имени или индексу + // if(func_define->Left()->size()) { + // for (size_t i = 0; i < func_define->Left()->size(); i++) { + // std::string var_name; + // if(func_define->Left()->name(i).empty()) { + // var_name = func_define->Left()->at(i).second->GetFullName(); + // } else { + // var_name = func_define->Left()->name(i); + // } + // ci.arguments.insert(std::pair(var_name, func_define->Left())); + // } + // } + // + // std::string body; + // if(func_define->GetTokenID() == TermID::SIMPLE) { + // body = WriteSimpleBody_(ci, func_define); + // } else { + // body = MakeFunctionBodyCpp(ci, func_define->Right()); + // } + // + // out << body; + // + // // Проверка типа возвращаемого значения из функции + // NL_TYPECHECK(func_define->Left(), func_define->Left()->m_type_name, ci.last_type); + // + // out << "}\n"; + // + // ci.arguments.clear(); + // + // return true; } @@ -729,48 +733,48 @@ bool NewLang::MakeCppFile(TermPtr ast, std::ostream &out, const char * source, C } bool NewLang::Execute(const char *exec, std::string *out, int *exit_code) { -// int status; -// pid_t pid; -// -// int mypipe[2]; -// pipe(mypipe); -// -// pid = fork(); -// if(pid < 0) { -// LOG_ERROR("Fork fail"); -// return false; -// } else if(!pid) { -// close(mypipe[0]); /* close unused in */ -// dup2(mypipe[1], 1); /* stdout to pipe out */ -// -// execl("/bin/bash", "bash", "-c", exec, NULL); -// -// close(mypipe[1]); -// _exit(EXIT_SUCCESS); -// } -// -// pid = wait(&status); -// -// /* parent process */ -// close(mypipe[1]); /* close unused out */ -// -// char buf[1024] = ""; -// ssize_t nbytes; -// /* read from pipe in */ -// while((nbytes = read(mypipe[0], buf, sizeof (buf))) > 0) { -// if(out) { -// out->append(buf, nbytes); -// } -// } -// close(mypipe[0]); -// -// if(WIFEXITED(status)) { -// if(exit_code) { -// -// *exit_code = WEXITSTATUS(status); -// } -// return true; -// } + // int status; + // pid_t pid; + // + // int mypipe[2]; + // pipe(mypipe); + // + // pid = fork(); + // if(pid < 0) { + // LOG_ERROR("Fork fail"); + // return false; + // } else if(!pid) { + // close(mypipe[0]); /* close unused in */ + // dup2(mypipe[1], 1); /* stdout to pipe out */ + // + // execl("/bin/bash", "bash", "-c", exec, NULL); + // + // close(mypipe[1]); + // _exit(EXIT_SUCCESS); + // } + // + // pid = wait(&status); + // + // /* parent process */ + // close(mypipe[1]); /* close unused out */ + // + // char buf[1024] = ""; + // ssize_t nbytes; + // /* read from pipe in */ + // while((nbytes = read(mypipe[0], buf, sizeof (buf))) > 0) { + // if(out) { + // out->append(buf, nbytes); + // } + // } + // close(mypipe[0]); + // + // if(WIFEXITED(status)) { + // if(exit_code) { + // + // *exit_code = WEXITSTATUS(status); + // } + // return true; + // } return false; } @@ -1251,63 +1255,63 @@ NewLang::NewLang(RuntimePtr rt) : m_runtime(rt) { bool RunTime::LoadModule(const char *name_str, bool init, Context *ctx, const char *module_name) { ASSERT(!"Not impelmented"); -// std::string name(module_name ? module_name : name_str); -// try { -// m_modules.insert(std::pair(name, new Module(name_str))); -// void * handle = m_modules[name]->GetHandle(); -// -// const size_t * func_list_count = static_cast (dlsym(handle, NEWLANG_PREFIX "_func_list_count")); -// const char ** func_list = static_cast (dlsym(handle, NEWLANG_PREFIX "_func_list")); -// m_modules[name]->m_source = static_cast (dlsym(handle, NEWLANG_PREFIX "_module_source")); -// m_modules[name]->m_main = reinterpret_cast (dlsym(handle, NEWLANG_PREFIX "_main_module_func")); -// -// //@todo INIT MODULE -// -// ObjPtr func; -// if(func_list_count && func_list) { -// TermPtr proto; -// Parser parser(proto); -// for (size_t i = 0; i < (*func_list_count); i++) { -// LOG_DEBUG("Load '%s' form module '%s'.", func_list[i], name_str); -// -// std::string arg_name = NEWLANG_PREFIX "_"; -// arg_name += func_list[i]; -// arg_name += "_text"; -// -// const char ** func_proto = static_cast (dlsym(handle, arg_name.c_str())); -// parser.Parse(*func_proto); -// ObjType type; -// switch(proto->getTermID()) { -// case TermID::SIMPLE: -// case TermID::PUREFUNC: -// type = ObjType::PUREFUNC; -// break; -// case TermID::FUNCTION: -// type = ObjType::FUNCTION; -// break; -// default: -// LOG_RUNTIME("Function type '%s' unknown '%s'", newlang::toString(proto->getTermID()), proto->toString().c_str()); -// } -// func = Obj::CreateFunc(ctx, proto->Left(), type, func_list[i]); -// func->m_func_ptr = reinterpret_cast (dlsym(handle, MangleName(func_list[i]).c_str())); -// func->m_func_source = proto; -// -// //@todo call init module -// if(!(func->m_func_ptr && ctx->RegisterObject(func))) { -// LOG_ERROR("Fail load '%s' form module '%s'.", func_list[i], name_str); -// } else { -// m_modules[name]->Funcs()[func_list[i]] = func; -// } -// } -// -// return true; -// } -// LOG_WARNING("In module '%s' functions not found!", name_str); -// return true; -// } catch (std::runtime_error &e) { -// -// LOG_ERROR("%s", e.what()); -// } + // std::string name(module_name ? module_name : name_str); + // try { + // m_modules.insert(std::pair(name, new Module(name_str))); + // void * handle = m_modules[name]->GetHandle(); + // + // const size_t * func_list_count = static_cast (dlsym(handle, NEWLANG_PREFIX "_func_list_count")); + // const char ** func_list = static_cast (dlsym(handle, NEWLANG_PREFIX "_func_list")); + // m_modules[name]->m_source = static_cast (dlsym(handle, NEWLANG_PREFIX "_module_source")); + // m_modules[name]->m_main = reinterpret_cast (dlsym(handle, NEWLANG_PREFIX "_main_module_func")); + // + // //@todo INIT MODULE + // + // ObjPtr func; + // if(func_list_count && func_list) { + // TermPtr proto; + // Parser parser(proto); + // for (size_t i = 0; i < (*func_list_count); i++) { + // LOG_DEBUG("Load '%s' form module '%s'.", func_list[i], name_str); + // + // std::string arg_name = NEWLANG_PREFIX "_"; + // arg_name += func_list[i]; + // arg_name += "_text"; + // + // const char ** func_proto = static_cast (dlsym(handle, arg_name.c_str())); + // parser.Parse(*func_proto); + // ObjType type; + // switch(proto->getTermID()) { + // case TermID::SIMPLE: + // case TermID::PUREFUNC: + // type = ObjType::PUREFUNC; + // break; + // case TermID::FUNCTION: + // type = ObjType::FUNCTION; + // break; + // default: + // LOG_RUNTIME("Function type '%s' unknown '%s'", newlang::toString(proto->getTermID()), proto->toString().c_str()); + // } + // func = Obj::CreateFunc(ctx, proto->Left(), type, func_list[i]); + // func->m_func_ptr = reinterpret_cast (dlsym(handle, MangleName(func_list[i]).c_str())); + // func->m_func_source = proto; + // + // //@todo call init module + // if(!(func->m_func_ptr && ctx->RegisterObject(func))) { + // LOG_ERROR("Fail load '%s' form module '%s'.", func_list[i], name_str); + // } else { + // m_modules[name]->Funcs()[func_list[i]] = func; + // } + // } + // + // return true; + // } + // LOG_WARNING("In module '%s' functions not found!", name_str); + // return true; + // } catch (std::runtime_error &e) { + // + // LOG_ERROR("%s", e.what()); + // } return false; } @@ -1421,7 +1425,7 @@ ObjPtr RunTime::ExecModule(const char *mod, const char *output, bool cached, Con return m_modules[output]->Main(ctx, args); }*/ LOG_RUNTIME("Fail compile module '%s' form file '%s'.", output, mod); - return nullptr; + return nullptr; } void NewLang::ReplaceSourceVariable(CompileInfo &ci, size_t count, std::string &body) { @@ -1537,16 +1541,16 @@ std::string NewLang::GetImpl(CompileInfo &ci, TermPtr term, std::string &output) output += result; return result; -// case TermID::FIELD: -// ASSERT(!term->getName().empty() || !term->getText().empty()); -// ASSERT(!term->Right()); -// -// if(!ci.m_builtin_direct->CheckDirect(ci, term, output)) { -// output.insert(0, "(*"); -// output += ")[\"" + term->getText() + "\"]"; -// } -// result = output; -// return result; + // case TermID::FIELD: + // ASSERT(!term->getName().empty() || !term->getText().empty()); + // ASSERT(!term->Right()); + // + // if(!ci.m_builtin_direct->CheckDirect(ci, term, output)) { + // output.insert(0, "(*"); + // output += ")[\"" + term->getText() + "\"]"; + // } + // result = output; + // return result; case TermID::SOURCE: temp = term->getText(); @@ -1555,7 +1559,7 @@ std::string NewLang::GetImpl(CompileInfo &ci, TermPtr term, std::string &output) return ""; case TermID::CALL: - if(proto = ci.isArgument(term)) { + if((proto = ci.isArgument(term))) { result = "in[\"" + MakeName(term->GetFullName()) + "\"]->Call("; result += MakeCppFileCallArgs(ci, term, proto); result += ")"; @@ -1567,7 +1571,7 @@ std::string NewLang::GetImpl(CompileInfo &ci, TermPtr term, std::string &output) result += ", " + temp; } result += ")"; - } else if(proto = ci.isFunction(term)) { + } else if((proto = ci.isFunction(term))) { //Непосредственный вызов - разрешение имени во время компиляции result = MakeLocalName(term->getText().c_str()) + "(ctx, "; result += "Obj::CreateDict(Obj::Arg()"; diff --git a/src/newlang.h b/src/newlang.h index 0e7834c3..aaf17d06 100644 --- a/src/newlang.h +++ b/src/newlang.h @@ -112,9 +112,136 @@ namespace newlang { //typedef std::map ProtoType; + /* + + LLVMBuilderRef builder = LLVMCreateBuilder(); + LLVMModuleRef mod = LLVMModuleCreateWithName("my_module"); + char *error = NULL; + + LLVMExecutionEngineRef engine; + + LLVMLinkInMCJIT(); + LLVMInitializeNativeTarget(); + LLVMInitializeNativeAsmPrinter(); + LLVMInitializeNativeAsmParser(); + + if(LLVMCreateExecutionEngineForModule(&engine, mod, &error) != 0) { + fprintf(stderr, "failed to create execution engine\n"); + abort(); + } + if(error) { + fprintf(stderr, "error: %s\n", error); + LLVMDisposeMessage(error); + exit(EXIT_FAILURE); + } + + + typedef int(*Printf)(const char *format, ...); + Printf prn = reinterpret_cast (LLVMGetPointerToNamedFunction(engine, "printf")); + + + LLVMDisposeBuilder(builder); + LLVMDisposeExecutionEngine(engine); + + */ class RunTime { public: + // static LLVMBuilderRef m_llvm_builder; + // static LLVMModuleRef m_llvm_module; + // static LLVMExecutionEngineRef m_llvm_engine; + +// static void * LLVMGetPointerToNamedFunction_(LLVMExecutionEngineRef EE, const char *Name) { +// return reinterpret_cast (reinterpret_cast (EE)->getPointerToNamedFunction(Name, false)); +// } + + void * m_ffi_handle; + + RunTime() : m_ffi_handle(nullptr) { + + // llvm::cl::PrintHelpMessage(); + // llvm::cl::ResetAllOptionOccurrences(); + + // llvm::cl::Option::~Option() + + // LLVMInitializeCore(LLVMGetGlobalPassRegistry()); + /* program init */ + // LLVMInitializeNativeTarget(); + // LLVMInitializeNativeAsmPrinter(); + // LLVMInitializeNativeAsmParser(); + // LLVMLinkInMCJIT(); + + // builder = CreateBuilder(); + + // if (!m_llvm_engine) { + + + // m_llvm_builder = LLVMCreateBuilder(); + // m_llvm_module = LLVMModuleCreateWithName("nlc"); + + // LLVMLinkInMCJIT(); + // LLVMInitializeNativeTarget(); + // LLVMInitializeNativeAsmPrinter(); + // LLVMInitializeNativeAsmParser(); + // + + // Загружает символы исполняемого файла для поиска с помощью SearchForAddressOfSymbol + llvm::sys::DynamicLibrary::LoadLibraryPermanently(nullptr, nullptr); + + // + // char *error = NULL; + // if (LLVMCreateExecutionEngineForModule(&m_llvm_engine, m_llvm_module, &error) != 0) { + // LOG_RUNTIME("Failed to create execution engine LLVM!"); + // } + // if (error) { + // std::string msg = error; + // LLVMDisposeMessage(error); + // LOG_RUNTIME("Failed to create execution engine LLVM '%s'!", msg.c_str()); + // } + +// typedef int(*Printf)(const char *format, ...); +// Printf prn = reinterpret_cast (GetDirectAddressFromLibrary(nullptr, "printf")); //LLVMGetPointerToNamedFunction_(m_llvm_engine, "printf")); +// if (!prn) { +// LOG_ERROR("Printf not found!!."); +// } else { +// int res = prn(" %s ", "\n\nУРА !!!!!!!!\n\n"); +// LOG_DEBUG("PRINTF !!!! %d !!!!!!!!!!!!!!!", res); +// } +// +// LOG_DEBUG("LLVM init complete!"); + // } + } + + virtual ~RunTime() { + +#ifdef _MSC_VER + if (m_ffi_handle) { + FreeLibrary((HMODULE) m_ffi_handle); + m_ffi_handle = nullptr; + } + if (m_msys) { + FreeLibrary((HMODULE) m_msys); + m_msys = nullptr; + } +#else + // if (m_ffi_handle) { + // dlclose(m_ffi_handle); + // m_ffi_handle = nullptr; + // } + + // LLVMDisposeBuilder(m_llvm_builder); + // LLVMDisposeExecutionEngine(m_llvm_engine); + // + // m_llvm_module = nullptr; + // m_llvm_engine = nullptr; + // m_llvm_builder = nullptr; + +#endif + // DisposeBuilder(builder); + // llvm::cl::ResetAllOptionOccurrences(); + LLVMShutdown(); + } + static RuntimePtr Init(int argc = 0, const char** argv = nullptr, bool ignore_error = true) { RuntimePtr rt = std::make_shared(); @@ -125,7 +252,7 @@ namespace newlang { std::wstring sys_file; std::string sys_init; -//#define CYGWIN + //#define CYGWIN #ifdef CYGWIN sys_file = L"cygwin1.dll"; sys_init = "cygwin_dll_init"; @@ -151,14 +278,20 @@ namespace newlang { } rt->m_ffi_handle = LoadLibrary(utf8_decode(ffi_file).c_str()); #else - ffi_file = "libffi.so"; - rt->m_ffi_handle = dlopen(ffi_file.c_str(), RTLD_NOW); -#endif - - if (!rt->m_ffi_handle) { - LOG_RUNTIME("Fail load %s!", ffi_file.c_str()); + std::string error; + if (!llvm::sys::DynamicLibrary::LoadLibraryPermanently("libffi", &error)) { + LOG_RUNTIME("Fail load library libffi.so '%s'", error.c_str()); } + + // ffi_file = "libffi.so"; + // rt->m_ffi_handle = dlopen(ffi_file.c_str(), RTLD_NOW); +#endif + // + // if (!rt->m_ffi_handle) { + // LOG_RUNTIME("Fail load %s!", ffi_file.c_str()); + // } + rt->m_ffi_type_void = static_cast (GetDirectAddressFromLibrary(rt->m_ffi_handle, "ffi_type_void")); rt->m_ffi_type_uint8 = static_cast (GetDirectAddressFromLibrary(rt->m_ffi_handle, "ffi_type_uint8")); rt->m_ffi_type_sint8 = static_cast (GetDirectAddressFromLibrary(rt->m_ffi_handle, "ffi_type_sint8")); @@ -183,14 +316,23 @@ namespace newlang { LOG_RUNTIME("Fail init data from %s!", ffi_file.c_str()); } - return std::move(rt); + return rt; } inline static void * GetDirectAddressFromLibrary(void *handle, const char * name) { #ifdef _MSC_VER return static_cast (::GetProcAddress((HMODULE) handle, name)); #else - return dlsym(handle, name); + void *res = llvm::sys::DynamicLibrary::SearchForAddressOfSymbol(name); + if (res) { + return res; + } + // if (m_llvm_engine) { + // // ASSERT(m_llvm_engine); + // return LLVMGetPointerToNamedFunction_(m_llvm_engine, name); + // } + return nullptr; + // return dlsym(handle, name); #endif } @@ -202,28 +344,6 @@ namespace newlang { void * GetNativeAddr(const char * name, const char *module = nullptr); - virtual ~RunTime() { - -#ifdef _MSC_VER - if (m_ffi_handle) { - FreeLibrary((HMODULE) m_ffi_handle); - m_ffi_handle = nullptr; - } - if (m_msys) { - FreeLibrary((HMODULE) m_msys); - m_msys = nullptr; - } -#else - if (m_ffi_handle) { - dlclose(m_ffi_handle); - m_ffi_handle = nullptr; - } -#endif - } - - RunTime() { - } - static std::string GetLastErrorMessage(); typedef ffi_status ffi_prep_cif_type(ffi_cif *cif, ffi_abi abi, unsigned int nargs, ffi_type *rtype, ffi_type **atypes); @@ -243,7 +363,6 @@ namespace newlang { std::map m_modules; - void * m_ffi_handle; ffi_type * m_ffi_type_void; ffi_type * m_ffi_type_uint8; ffi_type * m_ffi_type_sint8; diff --git a/src/nlc.cpp b/src/nlc.cpp index 8ed80ae4..8d7e22cc 100644 --- a/src/nlc.cpp +++ b/src/nlc.cpp @@ -2,9 +2,6 @@ #include -using namespace std; -using namespace newlang; - #ifdef _MSC_VER #pragma comment(lib, "torch.lib") @@ -16,8 +13,29 @@ using namespace newlang; #ifndef UNITTEST int main(int argc, char** argv) { - NLC nlc(argc, (const char **)argv); - return nlc.Run(); + + newlang::NLC nlc(argc, (const char **) argv); + + //#0 __GI___libc_free (mem=0x1) at malloc.c:3102 + //#1 0x00007fffe3d0c113 in llvm::cl::Option::~Option() () from ../contrib/libtorch/lib/libtorch_cpu.so + //#2 0x00007fffd93eafde in __cxa_finalize (d=0x7ffff6c74000) at cxa_finalize.c:83 + //#3 0x00007fffe0b80723 in __do_global_dtors_aux () from ../contrib/libtorch/lib/libtorch_cpu.so + //#4 0x00007fffffffdd80 in ?? () + //#5 0x00007ffff7fe0f6b in _dl_fini () at dl-fini.c:138 + + //#0 0x00000000c0200000 in ?? () + //#1 0x00007fffda7b844f in ?? () from /lib/x86_64-linux-gnu/libLLVM-13.so.1 + //#2 0x00007fffd95ecfde in __cxa_finalize (d=0x7fffdf9a0ba0) at cxa_finalize.c:83 + //#3 0x00007fffda743cd7 in ?? () from /lib/x86_64-linux-gnu/libLLVM-13.so.1 + //#4 0x00007fffffffdd80 in ?? () + //#5 0x00007ffff7fe0f6b in _dl_fini () at dl-fini.c:138 + + // При завершении приложения происходит Segmentation fault из-за двойного освобожнения памяти статической переменой + // llvm::cl::Option::~Option() во время выгрузки динамически библиотек libLLVM или libtorch_cpu + // Чтобы убрать этот coredump вместо нормального завершения main вызываю _exit, чтобы + // все остальные функции освобождения памяти не вызывались при завершении процесса. + + _exit(nlc.Run()); } #endif diff --git a/src/nlc.h b/src/nlc.h index 8d10189a..dd881b2c 100644 --- a/src/nlc.h +++ b/src/nlc.h @@ -239,6 +239,9 @@ namespace newlang { m_modules = SplitString(load_list.c_str(), ","); m_load_only = SplitString(load_only.c_str(), ","); +#ifdef _WIN32 + +#else int len; char buffer[100]; fcntl(STDIN_FILENO, F_SETFL, fcntl(STDIN_FILENO, F_GETFL, 0) | O_NONBLOCK); @@ -246,7 +249,7 @@ namespace newlang { m_eval.append(buffer, len); } fcntl(STDIN_FILENO, F_SETFL, fcntl(STDIN_FILENO, F_GETFL, 0) & ~O_NONBLOCK); - +#endif int cnt = 0; cnt += !compile.empty(); cnt += !exec.empty(); @@ -340,9 +343,13 @@ namespace newlang { out << m_output; out.close(); } +#ifdef _WIN32 +#else fcntl(STDOUT_FILENO, F_SETFL, fcntl(STDOUT_FILENO, F_GETFL, 0) | O_NONBLOCK); write(STDOUT_FILENO, m_output.c_str(), m_output.size()); +#endif // _WIN32 + } else { ASSERT(m_mode == Mode::ModeInter); diff --git a/src/object.cpp b/src/object.cpp index 59b36513..3b4d7735 100644 --- a/src/object.cpp +++ b/src/object.cpp @@ -11,6 +11,9 @@ using namespace newlang; +template <> +const std::string Iterator::FIND_KEY_DEFAULT = "(.|\\n)*"; + std::ostream &operator<<(std::ostream &out, newlang::Obj &var) { out << var.toString().c_str(); return out; @@ -565,6 +568,8 @@ void Obj::CloneDataTo(Obj & clone) const { if(m_dimensions) { clone.m_dimensions = m_dimensions->Clone(); + } else { + clone.m_dimensions = nullptr; } clone.m_var_name = m_var_name; @@ -573,6 +578,8 @@ void Obj::CloneDataTo(Obj & clone) const { if(m_fraction) { clone.m_fraction = std::make_shared(*m_fraction.get()); + } else { + clone.m_fraction = nullptr; } clone.m_iterator = m_iterator; @@ -581,7 +588,9 @@ void Obj::CloneDataTo(Obj & clone) const { clone.m_is_const = m_is_const; clone.m_func_ptr = m_func_ptr; - *const_cast (&clone.m_func_proto) = m_func_proto; + if(m_func_proto) { + *const_cast (&clone.m_func_proto) = m_func_proto; + } if(is_tensor() && m_var_is_init) { clone.m_value = m_value.clone(); } @@ -1025,6 +1034,8 @@ Obj::Obj(Context *ctx, const TermPtr term, bool as_value, Obj * local_vars) { m_var_type_current = ObjType::Dictionary; m_func_abi = FFI_DEFAULT_ABI; m_dimensions = nullptr; + m_var_is_init = false; + m_is_const = false; *const_cast (&m_func_proto) = term; @@ -1135,7 +1146,7 @@ void Obj::ConvertToArgs_(Obj *in, bool check_valid, Context * ctx) { ASSERT(in); - bool named = false; + // bool named = false; bool is_ellipsis = false; if(check_valid && size()) { if(at(size() - 1).first.compare("...") == 0) { @@ -1167,9 +1178,9 @@ void Obj::ConvertToArgs_(Obj *in, bool check_valid, Context * ctx) { at(i).second->m_is_reference = (*m_func_proto)[i].second->isRef(); ObjType base_type = ObjType::None; if(ctx) { - base_type = typeFromString((*m_func_proto)[i].second->m_type_name, ctx); - } else { base_type = ctx->BaseTypeFromString((*m_func_proto)[i].second->m_type_name); + } else { + base_type = typeFromString((*m_func_proto)[i].second->m_type_name, ctx); } ObjType limit_type = (*in)[i].second->getTypeAsLimit(); if(!canCast(limit_type, base_type)) { @@ -1186,7 +1197,7 @@ void Obj::ConvertToArgs_(Obj *in, bool check_valid, Context * ctx) { push_back(in->at(i)); } } else { - named = true; + // named = true; auto found = find(in->name(i)); if(found != end()) { if(check_valid && (*found).second && (*found).second->getType() != (*in)[i].second->getType() && (*found).second->getType() != ObjType::None) { @@ -1221,16 +1232,16 @@ void Obj::ConvertToArgs_(Obj *in, bool check_valid, Context * ctx) { } void Obj::CheckArgsValid() const { - bool named = false; - for (int i = 0; i < Variable::size(); i++) { - // if(!at(i).second) { - // - // LOG_RUNTIME("Argument %d '%s' missed!", (int) i + 1, at(i).first.c_str()); - // } - } - // if(!CheckArgs_()) { - // LOG_RUNTIME("Fail arguments!"); + // bool named = false; + // for (int i = 0; i < Variable::size(); i++) { + // // if(!at(i).second) { + // // + // // LOG_RUNTIME("Argument %d '%s' missed!", (int) i + 1, at(i).first.c_str()); + // // } // } + // // if(!CheckArgs_()) { + // // LOG_RUNTIME("Fail arguments!"); + // // } } /* @@ -1417,7 +1428,7 @@ bool Obj::op_class_test(const char *name, Context * ctx) const { } ObjType check_type = m_var_type_current; - if(m_var_type_current == ObjType::Type || !m_var_is_init && m_var_type_current == ObjType::None) { + if(m_var_type_current == ObjType::Type || (!m_var_is_init && m_var_type_current == ObjType::None)) { check_type = m_var_type_fixed; } @@ -2720,14 +2731,14 @@ ObjPtr Obj::ConstructorSimpleType_(const Context *ctx, Obj & args) { LOG_RUNTIME("Object has no dimensions!"); } int64_t full_size = 1; - for (int i = 0; i < dims.size(); i++) { - full_size *= dims[i]; + for (int j = 0; j < dims.size(); j++) { + full_size *= dims[j]; } if(full_size <= 0) { LOG_RUNTIME("Items count error for all dimensions!"); } - for (int64_t i = result->size(); i < full_size; i++) { + for (int64_t j = result->size(); j < full_size; j++) { result->op_concat_(prev, ConcatMode::Append); } diff --git a/src/object.h b/src/object.h index 132edc90..83e8d1df 100755 --- a/src/object.h +++ b/src/object.h @@ -128,14 +128,14 @@ namespace newlang { typedef IterCmp CompareFuncType(const IterPairType &pair, const T *args, void *extra); - inline static const std::string FIND_KEY_DEFAULT = "(.|\\n)*"; + static const std::string FIND_KEY_DEFAULT; /** * Итератор для элементов списка с regex фильтром по имени элемента (по умолчанию для всех элементов списка) * @param obj * @param find_key */ - Iterator(std::shared_ptr obj, const std::string find_key = FIND_KEY_DEFAULT) : + explicit Iterator(std::shared_ptr obj, const std::string find_key = Iterator::FIND_KEY_DEFAULT) : Iterator(obj, &CompareFuncDefault, reinterpret_cast (const_cast (&find_key)), static_cast (this)) { } @@ -282,6 +282,9 @@ namespace newlang { // constexpr static const char * BUILDIN_BASE = "__class_base__"; // constexpr static const char * BUILDIN_CLASS = "__class_name__"; // constexpr static const char * BUILDIN_NAMESPACE = "__namespace__"; + + typedef Variable::PairType PairType; + Obj(ObjType type = ObjType::None, const char *var_name = nullptr, TermPtr func_proto = nullptr, ObjType fixed = ObjType::None, bool init = false) : m_var_type_current(type), m_var_name(var_name ? var_name : ""), m_func_proto(func_proto) { @@ -295,6 +298,7 @@ namespace newlang { m_func_abi = FFI_DEFAULT_ABI; m_var_type_fixed = fixed; m_var_is_init = init; + m_is_const = false; } Obj(Context *ctx, const TermPtr term, bool as_value, Obj *local_vars); @@ -566,12 +570,12 @@ namespace newlang { return Variable::empty(); } - Variable::PairType & at(const std::string_view name) const { + Variable::PairType & at(const std::string name) const { Obj * const obj = (Obj * const) this; return obj->Variable::at(name); } - Variable::PairType & at(const std::string_view name) override { + Variable::PairType & at(const std::string name) override { return Variable::at(name); } @@ -650,13 +654,13 @@ namespace newlang { return at(name); } - Obj::iterator find(const std::string_view name) { + Obj::iterator find(const std::string name) { return Variable::find(name); } - Obj::const_iterator find(const std::string_view name) const { - return Variable::find(name); - } +// Obj::const_iterator find(const std::string_view name) const { +// return Variable::find(name); +// } Obj::iterator begin() { return Variable::begin(); @@ -1336,7 +1340,7 @@ namespace newlang { return std::make_shared(type, nullptr, nullptr, fixed, is_init); } - static ObjPtr CreateFraction(const std::string_view val) { + static ObjPtr CreateFraction(const std::string val) { std::string str; std::remove_copy(val.begin(), val.end(), back_inserter(str), '_'); diff --git a/src/parser.cpp b/src/parser.cpp index 54d6a899..74982932 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -7,6 +7,9 @@ using namespace newlang; +const std::string Parser::MACROS_START = "\\\\"; +const std::string Parser::MACROS_END = "\\\\\\"; + Parser::Parser(TermPtr &ast) : m_ast(ast) { m_ast = Term::Create(TermID::END, ""); } @@ -24,7 +27,7 @@ bool Parser::parse_stream(std::istream& in, const std::string sname) { bool Parser::parse_file(const std::string filename) { std::ifstream in(filename); - if (!in.good()) return false; + if(!in.good()) return false; return parse_stream(in, filename.c_str()); } @@ -33,7 +36,7 @@ bool Parser::parse_string(const std::string input, const std::string sname) { return parse_stream(iss, sname.c_str()); } -TermPtr Parser::Parse(const std::string_view input, MacrosStore *store) { +TermPtr Parser::Parse(const std::string input, MacrosStore *store) { std::string parse_string = ParseAllMacros(input, store); @@ -44,7 +47,7 @@ TermPtr Parser::Parse(const std::string_view input, MacrosStore *store) { lexer = &scanner; parser parser(*this); - if (parser.parse() != 0) { + if(parser.parse() != 0) { return m_ast; } @@ -54,7 +57,7 @@ TermPtr Parser::Parse(const std::string_view input, MacrosStore *store) { return m_ast; } -TermPtr Parser::ParseString(const std::string_view str, MacrosStore *store) { +TermPtr Parser::ParseString(const std::string str, MacrosStore *store) { TermPtr ast = Term::Create(TermID::END, ""); Parser p(ast); return p.Parse(str, store); @@ -64,7 +67,7 @@ void Parser::error(const class location& l, const std::string& m) { std::cerr << l << ": " << m << std::endl; } -void Parser::error(const std::string_view m) { +void Parser::error(const std::string &m) { std::cerr << m << std::endl; } @@ -77,10 +80,10 @@ void Parser::AstAddTerm(TermPtr &term) { ASSERT(m_ast); ASSERT(m_ast->m_source); term->m_source = m_ast->m_source; - if (m_ast->m_id == TermID::END) { + if(m_ast->m_id == TermID::END) { m_ast = term; m_ast->ConvertSequenceToBlock(TermID::BLOCK, false); - } else if (!m_ast->IsBlock()) { + } else if(!m_ast->IsBlock()) { m_ast->ConvertSequenceToBlock(TermID::BLOCK, true); } else { m_ast->m_block.push_back(term); @@ -98,7 +101,7 @@ std::string newlang::ParserMessage(std::string &buffer, int row, int col, const std::string message(va_buffer); - if (row) { // Если переданы координаты ошибки + if(row) { // Если переданы координаты ошибки message += " at line "; message += std::to_string(row); message += " col "; @@ -109,9 +112,9 @@ std::string newlang::ParserMessage(std::string &buffer, int row, int col, const // Ищем нужную строку size_t pos = 0; - if (buffer.find("\n") != std::string::npos) { + if(buffer.find("\n") != std::string::npos) { int count = 1; - while (count < row) { + while(count < row) { pos = buffer.find("\n", pos + 1); count++; } @@ -120,7 +123,7 @@ std::string newlang::ParserMessage(std::string &buffer, int row, int col, const std::string tmp = buffer.substr((pos ? pos + 1 : pos), buffer.find("\n", pos + 1)); tmp = tmp.substr(0, tmp.find("\n", col)); - if (row + 1) { // Если переданы координаты ошибки, показываем место + if(row + 1) { // Если переданы координаты ошибки, показываем место // Лексер обрабатывает строки в байтах, а вывод в UTF8 // поэтому позиция ошибки лексера може не совпадать для многобайтных символов diff --git a/src/parser.h b/src/parser.h index 038abe4a..490eca32 100644 --- a/src/parser.h +++ b/src/parser.h @@ -65,7 +65,7 @@ namespace newlang { /** General error handling. This can be modified to output the error * e.g. to a dialog box. */ - void error(const std::string_view m); + void error(const std::string &m); /** Pointer to the current lexer instance, this is used to connect the * parser to the scanner. It is used in the yylex macro. */ @@ -81,12 +81,12 @@ namespace newlang { typedef std::vector MacrosArgs; typedef std::map> MacrosStore; - inline static const std::string MACROS_START = "\\\\"; - inline static const std::string MACROS_END = "\\\\\\"; + static const std::string MACROS_START; + static const std::string MACROS_END; - TermPtr Parse(const std::string_view str, MacrosStore *store = nullptr); - static TermPtr ParseString(const std::string_view str, MacrosStore *store = nullptr); + TermPtr Parse(const std::string str, MacrosStore *store = nullptr); + static TermPtr ParseString(const std::string str, MacrosStore *store = nullptr); static inline std::string ParseMacroName(const std::string &body) { // имя макроса должно быть в самом начале строки без пробелов и начинаться на один слешь @@ -180,15 +180,15 @@ namespace newlang { if (fill) { // Заменить определение макроса пробелами, кроме переводов строк, чтобы не съезжала позиция парсинга - std::string fill(stop - start + MACROS_END.size(), ' '); + std::string fill_str(stop - start + MACROS_END.size(), ' '); - ASSERT(fill.size() > body.size()); + ASSERT(fill_str.size() > body.size()); for (size_t i = 0; i < body.size(); i++) { if (body[i] == '\n') { - fill[i + 1] = '\n'; + fill_str[i + 1] = '\n'; } } - text.replace(start, fill.size(), fill); + text.replace(start, fill_str.size(), fill_str); } return true; } @@ -303,7 +303,7 @@ namespace newlang { return result; } - static std::string ParseAllMacros(const std::string_view input, MacrosStore *store) { + static std::string ParseAllMacros(const std::string input, MacrosStore *store) { std::string result(input); if (store) { bool done; diff --git a/src/pch.h b/src/pch.h index 294e1af2..ceeeef24 100644 --- a/src/pch.h +++ b/src/pch.h @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -50,6 +51,56 @@ #include #include "warning_push.h" + +#include +#include +#include +#include +#include + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "llvm/ExecutionEngine/JITSymbol.h" +#include "llvm/ExecutionEngine/Orc/CompileUtils.h" +#include "llvm/ExecutionEngine/Orc/Core.h" +#include "llvm/ExecutionEngine/Orc/ExecutionUtils.h" +#include "llvm/ExecutionEngine/Orc/IRCompileLayer.h" +#include "llvm/ExecutionEngine/Orc/JITTargetMachineBuilder.h" +#include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + #include #include diff --git a/src/term.h b/src/term.h index 9824ee42..7e39ff77 100644 --- a/src/term.h +++ b/src/term.h @@ -530,7 +530,6 @@ namespace newlang { return result; case TermID::DOWHILE: - result = result; result += m_text + "["; ASSERT(m_right); result += m_right->toString(); diff --git a/src/test/eval_test.cpp b/src/test/eval_test.cpp index afa95f91..656bf595 100644 --- a/src/test/eval_test.cpp +++ b/src/test/eval_test.cpp @@ -14,10 +14,22 @@ using namespace newlang; -extern "C" int64_t var_long; +//To clarify a few things; it's not the compiler (Clang) itself that produces import libraries, but the linker, and the object file format plays a large role in the process. +//Adjusting which symbols are exported via __attribute__((visibility(default))) +//(when either marking other symbols as hidden with __attribute__((visibility(hidden))) +//, or setting the default with something like -fvisibility=hidden +//, works with both GCC and Clang when building ELF object files. COFF doesn't have a similar per-symbol visibility flag. +//When linking a DLL with MS link.exe, or LLVM's lld-link (which mimics link.exe's behaviour), only symbols either marked with __declspec(dllexport) +//, or listed in a def file that is passed to the linker, are exported. +//Within the MinGW ecosystem (which brings a bit more of unix-like behaviours), the default is to export all global symbols (with some amount of logic to avoid exporting things that belong to the mingw base libraries themselves) if no symbols are explicitly chosen to be exported. +//If linking with lld-link instead of MS link.exe (either by calling lld-link instead of link, if calling the linker directly, or by adding -fuse-ld=lld +//if invoking the linker via the clang-cl frontend), you can opt in to this behaviour by adding the lld specific option -lldmingw +//, which enables a number of MinGW-specific behaviours in lld. + +extern "C" __attribute__ ((visibility("default"))) int64_t var_long; //, export_name("var_long") int64_t var_long = 987654321; -extern "C" int64_t func_export(int64_t arg_long, uint8_t arg_byte) { +extern "C" __attribute__ ((visibility("default"))) int64_t func_export(int64_t arg_long, uint8_t arg_byte) { return arg_long + arg_byte; } @@ -88,119 +100,119 @@ TEST(Eval, Assign) { list = ctx.ExecStr("$"); ASSERT_STREQ("$=('var_str', 'var_num',)", list->toString().c_str()); - var_long = 987654321; - ObjPtr var_export = ctx.ExecStr("var_export := :Pointer(\"var_long:Long\")"); - ASSERT_TRUE(var_export); - ASSERT_TRUE(var_export->is_tensor()) << var_export; - ASSERT_EQ(var_export->getType(), ObjType::Long); - ASSERT_STREQ("var_export=987654321", var_export->toString().c_str()); - var_long = 123132132; - ASSERT_STREQ("var_export=123132132", var_export->toString().c_str()); - var_export->SetValue_(Obj::CreateValue(59875, ObjType::None)); - ASSERT_EQ(59875, var_long); - - list = ctx.ExecStr("$"); - ASSERT_STREQ("$=('var_str', 'var_num', 'var_export',)", list->toString().c_str()); - - ObjPtr func_export = ctx.ExecStr("func_export := :Pointer(\"func_export(arg1:Long, arg2:Char=100):Long\")"); - ASSERT_TRUE(func_export); - ASSERT_TRUE(func_export->is_function()) << func_export; - ASSERT_EQ(func_export->getType(), ObjType::NativeFunc); - ASSERT_STREQ("func_export=func_export(arg1:Long, arg2:Char=100):Long{}", func_export->toString().c_str()); - - ObjPtr result = func_export->Call(&ctx, Obj::Arg(200), Obj::Arg(10)); - ASSERT_TRUE(result); - ASSERT_EQ(210, result->GetValueAsInteger()); - - result = func_export->Call(&ctx, Obj::Arg(10), Obj::Arg(10)); - ASSERT_TRUE(result); - ASSERT_EQ(20, result->GetValueAsInteger()); - - result = func_export->Call(&ctx, Obj::Arg(10)); - ASSERT_TRUE(result); - ASSERT_EQ(110, result->GetValueAsInteger()); - - // Переполнение второго аргумента - ASSERT_ANY_THROW(func_export->Call(&ctx, Obj::Arg(1000), Obj::Arg(1000))); - - list = ctx.ExecStr("$"); - ASSERT_STREQ("$=('var_str', 'var_num', 'var_export', 'func_export',)", list->toString().c_str()); - - var_num.reset(); - func_export.reset(); - - list = ctx.ExecStr("$"); - ASSERT_STREQ("$=('var_str', 'var_export',)", list->toString().c_str()); - - // Функция возвращает словарь с именами объектов в текущем контексте - ObjPtr func_eval = ctx.ExecStr("func_eval(arg1, arg2) := {$;}"); - ASSERT_TRUE(func_eval); - ASSERT_TRUE(func_eval->is_function()) << func_eval; - ASSERT_EQ(func_eval->getType(), ObjType::EVAL_FUNCTION) << toString(func_eval->getType()); - ASSERT_STREQ("func_eval=func_eval(arg1, arg2):={$;}", func_eval->toString().c_str()); - - ObjPtr result_eval = func_eval->Call(&ctx, Obj::Arg(200), Obj::Arg(10)); - ASSERT_TRUE(result_eval); - ASSERT_STREQ("$=('$0', 'arg1', 'arg2', 'var_str', 'var_export', 'func_eval',)", result_eval->toString().c_str()); - - list = ctx.ExecStr("$"); - ASSERT_STREQ("$=('var_str', 'var_export', 'func_eval',)", list->toString().c_str()); - - - ObjPtr dict1 = ctx.ExecStr("(10, 2, 3, 4, )"); - ASSERT_TRUE(dict1); - ASSERT_EQ(ObjType::Dictionary, dict1->m_var_type_current) << toString(dict1->m_var_type_current); - ASSERT_EQ(ObjType::None, dict1->m_var_type_fixed) << toString(dict1->m_var_type_fixed); - ASSERT_EQ(4, dict1->size()); - ASSERT_STREQ("(10, 2, 3, 4,)", dict1->toString().c_str()); - - ObjPtr dict2 = ctx.ExecStr("( (10, 2, 3, 4, (1,2,), ), (10, 2, 3, 4, ),)"); - ASSERT_TRUE(dict2); - ASSERT_EQ(ObjType::Dictionary, dict2->m_var_type_current) << toString(dict2->m_var_type_current); - ASSERT_EQ(ObjType::None, dict2->m_var_type_fixed) << toString(dict2->m_var_type_fixed); - ASSERT_EQ(2, dict2->size()); - ASSERT_STREQ("((10, 2, 3, 4, (1, 2,),), (10, 2, 3, 4,),)", dict2->toString().c_str()); - - ObjPtr tensor = ctx.ExecStr("[1,1,0,0,]"); - ASSERT_TRUE(tensor); - ASSERT_EQ(ObjType::Bool, tensor->m_var_type_current) << toString(tensor->m_var_type_current); - ASSERT_EQ(ObjType::None, tensor->m_var_type_fixed) << toString(tensor->m_var_type_fixed); - ASSERT_EQ(1, tensor->m_value.dim()); - ASSERT_EQ(4, tensor->m_value.size(0)); - ASSERT_EQ(1, tensor->index_get({0})->GetValueAsInteger()); - ASSERT_EQ(1, tensor->index_get({1})->GetValueAsInteger()); - ASSERT_EQ(0, tensor->index_get({2})->GetValueAsInteger()); - ASSERT_EQ(0, tensor->index_get({3})->GetValueAsInteger()); - - ASSERT_STREQ("[1, 1, 0, 0,]:Bool", tensor->GetValueAsString().c_str()); - - ObjPtr tensor2 = ctx.ExecStr("[222,333,3333,]"); - ASSERT_TRUE(tensor2); - ASSERT_STREQ("[222, 333, 3333,]:Short", tensor2->GetValueAsString().c_str()); - - ObjPtr tensorf = ctx.ExecStr("[1.2, 0.22, 0.69,]"); - ASSERT_TRUE(tensorf); - ASSERT_STREQ("[1.2, 0.22, 0.69,]:Double", tensorf->GetValueAsString().c_str()); - - ObjPtr tensor_all = ctx.ExecStr("[ [1, 1, 0, 0,], [10, 10, 0.1, 0.2,], ]"); - ASSERT_TRUE(tensor_all); - ASSERT_EQ(ObjType::Double, tensor_all->m_var_type_current) << toString(tensor_all->m_var_type_current); - ASSERT_EQ(ObjType::None, tensor_all->m_var_type_fixed) << toString(tensor_all->m_var_type_fixed); - ASSERT_EQ(2, tensor_all->m_value.dim()); - ASSERT_EQ(2, tensor_all->m_value.size(0)); - ASSERT_EQ(4, tensor_all->m_value.size(1)); - - ASSERT_STREQ("1", tensor_all->index_get({0, 0})->GetValueAsString().c_str()); - ASSERT_STREQ("1", tensor_all->index_get({0, 1})->GetValueAsString().c_str()); - ASSERT_STREQ("0", tensor_all->index_get({0, 2})->GetValueAsString().c_str()); - ASSERT_STREQ("0", tensor_all->index_get({0, 3})->GetValueAsString().c_str()); - - ASSERT_STREQ("10", tensor_all->index_get({1, 0})->GetValueAsString().c_str()); - ASSERT_STREQ("10", tensor_all->index_get({1, 1})->GetValueAsString().c_str()); - ASSERT_STREQ("0.1", tensor_all->index_get({1, 2})->GetValueAsString().c_str()); - ASSERT_STREQ("0.2", tensor_all->index_get({1, 3})->GetValueAsString().c_str()); - - ASSERT_STREQ("[\n [1, 1, 0, 0,], [10, 10, 0.1, 0.2,],\n]:Double", tensor_all->GetValueAsString().c_str()); +// var_long = 987654321; +// ObjPtr var_export = ctx.ExecStr("var_export := :Pointer(\"var_long:Long\")"); +// ASSERT_TRUE(var_export); +// ASSERT_TRUE(var_export->is_tensor()) << var_export; +// ASSERT_EQ(var_export->getType(), ObjType::Long); +// ASSERT_STREQ("var_export=987654321", var_export->toString().c_str()); +// var_long = 123132132; +// ASSERT_STREQ("var_export=123132132", var_export->toString().c_str()); +// var_export->SetValue_(Obj::CreateValue(59875, ObjType::None)); +// ASSERT_EQ(59875, var_long); +// +// list = ctx.ExecStr("$"); +// ASSERT_STREQ("$=('var_str', 'var_num', 'var_export',)", list->toString().c_str()); +// +// ObjPtr func_export = ctx.ExecStr("func_export := :Pointer(\"func_export(arg1:Long, arg2:Char=100):Long\")"); +// ASSERT_TRUE(func_export); +// ASSERT_TRUE(func_export->is_function()) << func_export; +// ASSERT_EQ(func_export->getType(), ObjType::NativeFunc); +// ASSERT_STREQ("func_export=func_export(arg1:Long, arg2:Char=100):Long{}", func_export->toString().c_str()); +// +// ObjPtr result = func_export->Call(&ctx, Obj::Arg(200), Obj::Arg(10)); +// ASSERT_TRUE(result); +// ASSERT_EQ(210, result->GetValueAsInteger()); +// +// result = func_export->Call(&ctx, Obj::Arg(10), Obj::Arg(10)); +// ASSERT_TRUE(result); +// ASSERT_EQ(20, result->GetValueAsInteger()); +// +// result = func_export->Call(&ctx, Obj::Arg(10)); +// ASSERT_TRUE(result); +// ASSERT_EQ(110, result->GetValueAsInteger()); +// +// // Переполнение второго аргумента +// ASSERT_ANY_THROW(func_export->Call(&ctx, Obj::Arg(1000), Obj::Arg(1000))); +// +// list = ctx.ExecStr("$"); +// ASSERT_STREQ("$=('var_str', 'var_num', 'var_export', 'func_export',)", list->toString().c_str()); +// +// var_num.reset(); +// func_export.reset(); +// +// list = ctx.ExecStr("$"); +// ASSERT_STREQ("$=('var_str', 'var_export',)", list->toString().c_str()); +// +// // Функция возвращает словарь с именами объектов в текущем контексте +// ObjPtr func_eval = ctx.ExecStr("func_eval(arg1, arg2) := {$;}"); +// ASSERT_TRUE(func_eval); +// ASSERT_TRUE(func_eval->is_function()) << func_eval; +// ASSERT_EQ(func_eval->getType(), ObjType::EVAL_FUNCTION) << toString(func_eval->getType()); +// ASSERT_STREQ("func_eval=func_eval(arg1, arg2):={$;}", func_eval->toString().c_str()); +// +// ObjPtr result_eval = func_eval->Call(&ctx, Obj::Arg(200), Obj::Arg(10)); +// ASSERT_TRUE(result_eval); +// ASSERT_STREQ("$=('$0', 'arg1', 'arg2', 'var_str', 'var_export', 'func_eval',)", result_eval->toString().c_str()); +// +// list = ctx.ExecStr("$"); +// ASSERT_STREQ("$=('var_str', 'var_export', 'func_eval',)", list->toString().c_str()); +// +// +// ObjPtr dict1 = ctx.ExecStr("(10, 2, 3, 4, )"); +// ASSERT_TRUE(dict1); +// ASSERT_EQ(ObjType::Dictionary, dict1->m_var_type_current) << toString(dict1->m_var_type_current); +// ASSERT_EQ(ObjType::None, dict1->m_var_type_fixed) << toString(dict1->m_var_type_fixed); +// ASSERT_EQ(4, dict1->size()); +// ASSERT_STREQ("(10, 2, 3, 4,)", dict1->toString().c_str()); +// +// ObjPtr dict2 = ctx.ExecStr("( (10, 2, 3, 4, (1,2,), ), (10, 2, 3, 4, ),)"); +// ASSERT_TRUE(dict2); +// ASSERT_EQ(ObjType::Dictionary, dict2->m_var_type_current) << toString(dict2->m_var_type_current); +// ASSERT_EQ(ObjType::None, dict2->m_var_type_fixed) << toString(dict2->m_var_type_fixed); +// ASSERT_EQ(2, dict2->size()); +// ASSERT_STREQ("((10, 2, 3, 4, (1, 2,),), (10, 2, 3, 4,),)", dict2->toString().c_str()); +// +// ObjPtr tensor = ctx.ExecStr("[1,1,0,0,]"); +// ASSERT_TRUE(tensor); +// ASSERT_EQ(ObjType::Bool, tensor->m_var_type_current) << toString(tensor->m_var_type_current); +// ASSERT_EQ(ObjType::None, tensor->m_var_type_fixed) << toString(tensor->m_var_type_fixed); +// ASSERT_EQ(1, tensor->m_value.dim()); +// ASSERT_EQ(4, tensor->m_value.size(0)); +// ASSERT_EQ(1, tensor->index_get({0})->GetValueAsInteger()); +// ASSERT_EQ(1, tensor->index_get({1})->GetValueAsInteger()); +// ASSERT_EQ(0, tensor->index_get({2})->GetValueAsInteger()); +// ASSERT_EQ(0, tensor->index_get({3})->GetValueAsInteger()); +// +// ASSERT_STREQ("[1, 1, 0, 0,]:Bool", tensor->GetValueAsString().c_str()); +// +// ObjPtr tensor2 = ctx.ExecStr("[222,333,3333,]"); +// ASSERT_TRUE(tensor2); +// ASSERT_STREQ("[222, 333, 3333,]:Short", tensor2->GetValueAsString().c_str()); +// +// ObjPtr tensorf = ctx.ExecStr("[1.2, 0.22, 0.69,]"); +// ASSERT_TRUE(tensorf); +// ASSERT_STREQ("[1.2, 0.22, 0.69,]:Double", tensorf->GetValueAsString().c_str()); +// +// ObjPtr tensor_all = ctx.ExecStr("[ [1, 1, 0, 0,], [10, 10, 0.1, 0.2,], ]"); +// ASSERT_TRUE(tensor_all); +// ASSERT_EQ(ObjType::Double, tensor_all->m_var_type_current) << toString(tensor_all->m_var_type_current); +// ASSERT_EQ(ObjType::None, tensor_all->m_var_type_fixed) << toString(tensor_all->m_var_type_fixed); +// ASSERT_EQ(2, tensor_all->m_value.dim()); +// ASSERT_EQ(2, tensor_all->m_value.size(0)); +// ASSERT_EQ(4, tensor_all->m_value.size(1)); +// +// ASSERT_STREQ("1", tensor_all->index_get({0, 0})->GetValueAsString().c_str()); +// ASSERT_STREQ("1", tensor_all->index_get({0, 1})->GetValueAsString().c_str()); +// ASSERT_STREQ("0", tensor_all->index_get({0, 2})->GetValueAsString().c_str()); +// ASSERT_STREQ("0", tensor_all->index_get({0, 3})->GetValueAsString().c_str()); +// +// ASSERT_STREQ("10", tensor_all->index_get({1, 0})->GetValueAsString().c_str()); +// ASSERT_STREQ("10", tensor_all->index_get({1, 1})->GetValueAsString().c_str()); +// ASSERT_STREQ("0.1", tensor_all->index_get({1, 2})->GetValueAsString().c_str()); +// ASSERT_STREQ("0.2", tensor_all->index_get({1, 3})->GetValueAsString().c_str()); +// +// ASSERT_STREQ("[\n [1, 1, 0, 0,], [10, 10, 0.1, 0.2,],\n]:Double", tensor_all->GetValueAsString().c_str()); } TEST(Eval, Tensor) { diff --git a/src/test/object_test.cpp b/src/test/object_test.cpp index 6c73c733..b901b415 100644 --- a/src/test/object_test.cpp +++ b/src/test/object_test.cpp @@ -15,7 +15,6 @@ #include -using namespace std; using namespace newlang; TEST(ObjTest, Empty) { diff --git a/src/test/parser_test.cpp b/src/test/parser_test.cpp index d956a883..23cbc447 100644 --- a/src/test/parser_test.cpp +++ b/src/test/parser_test.cpp @@ -1392,19 +1392,18 @@ TEST_F(ParserTest, Comment6) { ASSERT_FALSE(ast->size()); } - TEST_F(ParserTest, CommentIncluded) { -// const char *str = "/* !!!!!!! \n" -// "@print(\"Привет, мир!\\n\");\n*/"; -// "# @print(\"Привет, мир!\\n\");\n"; -// ASSERT_TRUE(Parse(str)); + // const char *str = "/* !!!!!!! \n" + // "@print(\"Привет, мир!\\n\");\n*/"; + // "# @print(\"Привет, мир!\\n\");\n"; + // ASSERT_TRUE(Parse(str)); const char *str2 = "/* /* /* /* term();\n" "print1(str=\"\") ::= term();\n" "print2(str=\"\") ::= term();\n\n */ " "print3( */ str=\"\") ::= term();\n\n\n" - "ddd */ "; - "# @print(\"Привет, мир!\\n\");\n"; + "ddd */ " + "# @print(\"Привет, мир!\\n\");\n"; ASSERT_TRUE(Parse(str2)); } diff --git a/src/types.h b/src/types.h index 72c7e3df..839f20b3 100644 --- a/src/types.h +++ b/src/types.h @@ -43,12 +43,12 @@ typedef ObjPtr TransparentType(const Context *ctx, Obj &in); class Interrupt : public std::exception { public: - inline static const char * Return = ":Return"; - inline static const char * Error = ":Error"; - inline static const char * Parser = ":ErrorParser"; - inline static const char * RunTime = ":ErrorRunTime"; - inline static const char * Signal = ":ErrorSignal"; - inline static const char * Abort = ":ErrorAbort"; + static const char * Return; + static const char * Error; + static const char * Parser; + static const char * RunTime; + static const char * Signal; + static const char * Abort; Interrupt(const ObjPtr obj); Interrupt(const std::string message, const std::string error_name=Error); @@ -352,8 +352,8 @@ void ParserException(const char *msg, std::string &buffer, int row, int col); } inline bool isIntegralType(ObjType t, bool includeBool) { - return static_cast (t) >= static_cast (ObjType::Char) && - static_cast (t) <= static_cast (ObjType::Integer) || + return (static_cast (t) >= static_cast (ObjType::Char) && + static_cast (t) <= static_cast (ObjType::Integer)) || (includeBool && t == ObjType::Bool); } @@ -773,19 +773,19 @@ void ParserException(const char *msg, std::string &buffer, int row, int col); * * */ - inline bool isGlobal(const std::string_view name) { + inline bool isGlobal(const std::string name) { return !name.empty() && name[0] == '@'; } - inline bool isLocal(const std::string_view name) { + inline bool isLocal(const std::string name) { return !name.empty() && name[0] == '$'; } - inline bool isType(const std::string_view name) { + inline bool isType(const std::string name) { return !name.empty() && name[0] == ':'; } - inline bool isMacro(const std::string_view name) { + inline bool isMacro(const std::string name) { return !name.empty() && name[0] == '\\'; } diff --git a/src/variable.h b/src/variable.h index 61b0a5f2..139daefe 100644 --- a/src/variable.h +++ b/src/variable.h @@ -112,7 +112,7 @@ namespace newlang { return *at_index_const(index); } - typename ListType::iterator find(const std::string_view name) { + typename ListType::iterator find(const std::string name) { auto iter = ListType::begin(); while (iter != ListType::end()) { if (iter->first.compare(name) == 0) { @@ -123,16 +123,16 @@ namespace newlang { return ListType::end(); } - typename ListType::const_iterator find(const std::string_view name) const { - return find(name); - } +// typename ListType::const_iterator find(const std::string_view name) const { +// return find(name); +// } - virtual PairType & at(const std::string_view name) { + virtual PairType & at(const std::string name) { auto iter = find(name); if (iter != ListType::end()) { return *iter; } - LOG_RUNTIME("Property '%s' not found!", name.begin()); + LOG_RUNTIME("Property '%s' not found!", name.c_str()); } virtual const std::string & name(const int64_t index) const { diff --git a/src/warning_push.h b/src/warning_push.h index 124c11f0..72ead73c 100644 --- a/src/warning_push.h +++ b/src/warning_push.h @@ -5,6 +5,12 @@ #pragma clang attribute push #pragma clang diagnostic ignored "-Wundef" #pragma clang diagnostic ignored "-Wsign-compare" +#pragma clang diagnostic ignored "-Wunused-parameter" +#pragma clang diagnostic ignored "-Wfloat-equal" +#pragma clang diagnostic ignored "-Wdeprecated-copy" +#pragma clang diagnostic ignored "-Wshadow" +#pragma clang diagnostic ignored "-Wcast-align" +#pragma clang diagnostic ignored "-Wunused-variable" #elif __GNUC__ diff --git a/src/win/nlc.vcxproj b/src/win/nlc.vcxproj index fa14d89c..1b5d7535 100644 --- a/src/win/nlc.vcxproj +++ b/src/win/nlc.vcxproj @@ -63,7 +63,7 @@ Application true - v143 + ClangCL Unicode From 8d68b65704d61130fd27eff5cece018c21a4c725 Mon Sep 17 00:00:00 2001 From: Aleksandr Ryabikov Date: Sun, 17 Jul 2022 20:19:24 +0300 Subject: [PATCH 25/31] =?UTF-8?q?=D0=9F=D0=B5=D1=80=D0=B5=D0=B4=D0=B5?= =?UTF-8?q?=D0=BB=D0=B0=D0=BB=20=D0=B2=D1=8B=D0=B7=D0=BE=D0=B2=D1=8B=20?= =?UTF-8?q?=D0=BD=D0=B0=D1=82=D0=B8=D1=8B=D0=BD=D1=85=20=D1=84=D1=83=D0=BD?= =?UTF-8?q?=D0=BA=D1=86=D0=B8=D0=B9=20=D1=81=20libffi=20=D0=BD=D0=B0=20LLV?= =?UTF-8?q?M.=20=D0=9F=D0=BE=D0=B4=20Windows=D1=81=20=D0=9C=D0=A1JIT=20?= =?UTF-8?q?=D0=BD=D0=B5=D0=BA=D1=82=D0=BE=D1=80=D1=8B=D0=B5=20=D0=BF=D1=80?= =?UTF-8?q?=D0=BE=D0=B1=D0=BB=D0=B5=D0=BC=D1=8B=20=D0=B4=D0=BB=D1=8F=20?= =?UTF-8?q?=D0=BE=D1=82=D0=B4=D0=B5=D0=BB=D1=8C=D0=BD=D1=8B=D1=85=20=D1=82?= =?UTF-8?q?=D0=B8=D0=BF=D0=BE=D0=B2=20=D1=84=D1=83=D0=BD=D0=BA=D1=86=D0=B8?= =?UTF-8?q?=D0=B9,=20=D0=B0=20=20=D0=B2=D1=81=D0=B5=20=D0=BE=D1=81=D1=82?= =?UTF-8?q?=D0=B0=D0=BB=D1=8C=D0=BD=D0=BE=D0=B5=20=D1=80=D0=B0=D0=B1=D0=BE?= =?UTF-8?q?=D1=82=D0=B0=D0=B5=D1=82!!!?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- examples/fileio.nlp | 26 +- src/context.cpp | 80 ++-- src/context.h | 5 +- src/nbproject/Makefile-GCOV.mk | 6 - src/nbproject/Makefile-UnitTest-Win32.mk | 6 - src/nbproject/Makefile-UnitTest-Win64.mk | 6 - src/nbproject/Makefile-UnitTest.mk | 6 - src/nbproject/Makefile-UnitTest_LLVM.mk | 8 +- src/nbproject/configurations.xml | 71 +-- src/newlang.cpp | 42 +- src/newlang.h | 318 +------------ src/nlc.cpp | 24 +- src/object.cpp | 574 ++++++++++++++--------- src/object.h | 56 ++- src/parser.y | 2 +- src/pch.h | 48 +- src/test/compiler_test.cpp | 21 +- src/test/eval_test.cpp | 19 +- src/test/nlc_test.cpp | 2 +- src/test/parser_test.cpp | 2 +- src/types.h | 77 ++- src/win/nlc.vcxproj | 17 +- 22 files changed, 630 insertions(+), 786 deletions(-) diff --git a/examples/fileio.nlp b/examples/fileio.nlp index 0e0d437c..f3444f6a 100755 --- a/examples/fileio.nlp +++ b/examples/fileio.nlp @@ -2,44 +2,44 @@ :File ::= :Pointer; -@stdin:File ::= :Pointer("_IO_2_1_stdin_:File"); -@stdout:File ::= :Pointer("_IO_2_1_stdout_:File"); -@stderr:File ::= :Pointer("stderr:File"); +#@stdin:File ::= :Pointer("stdin:File"); +#@stdout:File ::= :Pointer("stdout:File"); +#@stderr:File ::= :Pointer("stderr:File"); @fopen(filename:String, modes:String):File ::= :Pointer("fopen(filename:StrChar, modes:StrChar):File");; @fopen64(filename:String, modes:String):File ::= :Pointer("fopen(filename:StrChar, modes:StrChar):File");; @freopen(filename:String, modes:String):File ::= :Pointer("freopen(filename:StrChar, modes:StrChar, stream:File):File");; -@freopen64(filename:String, modes:String):File ::= :Pointer("freopen64(filename:StrChar, modes:StrChar, stream:File):File");; +#@freopen64(filename:String, modes:String):File ::= :Pointer("freopen64(filename:StrChar, modes:StrChar, stream:File):File");; #extern FILE *fdopen (int __fd, const char *__modes) __THROW __wur; @fclose(stream:File):Int ::= :Pointer("fclose(stream:File):Int");; -@fcloseall():Int ::= :Pointer("fcloseall():Int");; +#@fcloseall():Int ::= :Pointer("fcloseall():Int");; @fflush(stream:File):Int ::= :Pointer("fflush(stream:File):Int");; -@fflush_unlocked(stream:File):Int ::= :Pointer("fflush_unlocked(stream:File):Int");; +#@fflush_unlocked(stream:File):Int ::= :Pointer("fflush_unlocked(stream:File):Int");; @fremove(filename:String):Int ::= :Pointer("remove(filename:StrChar):Int");; @frename(old:String, new:String):Int ::= :Pointer("rename(old:StrChar, new:StrChar):Int");; @ftmpfile():File ::= :Pointer("tmpfile():File");; -@ftmpfile64():File ::= :Pointer("tmpfile64():File");; +#@ftmpfile64():File ::= :Pointer("tmpfile64():File");; -@ftmpnam(template:String):StrChar ::= :Pointer("tmpnam(template:StrChar):StrChar");; -@ftmpnam_r(template:String):StrChar ::= :Pointer("tmpnam(template:StrChar):StrChar");; +#@ftmpnam(template:String):StrChar ::= :Pointer("tmpnam(template:StrChar):StrChar");; +#@ftmpnam_r(template:String):StrChar ::= :Pointer("tmpnam(template:StrChar):StrChar");; -@ftempnam(dir:String, prefix:String):StrChar ::= :Pointer("tempnam(dir:StrChar, prefix:StrChar):StrChar");; +#@ftempnam(dir:String, prefix:String):StrChar ::= :Pointer("tempnam(dir:StrChar, prefix:StrChar):StrChar");; -@fprintf(stream:File, format:Format, ...):Int ::= :Pointer("fprintf(stream:File, format:Format, ...):Int");; -@fscanf(stream:File, format:Format, ...):Int ::= :Pointer("fscanf(stream:File, format:Format, ...):Int");; +@fprintf(stream:File, format:FmtChar, ...):Int ::= :Pointer("fprintf(stream:File, format:FmtChar, ...):Int");; +@fscanf(stream:File, format:FmtChar, ...):Int ::= :Pointer("fscanf(stream:File, format:FmtChar, ...):Int");; @fgetc(stream:File):Int ::= :Pointer("fgetc(stream:File):Int");; -@fgetc_unlocked(stream:File):Int ::= :Pointer("fgetc_unlocked(stream:File):Int");; +#@fgetc_unlocked(stream:File):Int ::= :Pointer("fgetc_unlocked(stream:File):Int");; @fungetc(c:Int, stream:File):Int ::= :Pointer("ungetc(c:Int, stream:File):Int");; diff --git a/src/context.cpp b/src/context.cpp index 195bc1fa..73a2f0e7 100644 --- a/src/context.cpp +++ b/src/context.cpp @@ -43,6 +43,7 @@ std::map Context::m_builtin_calls; std::map Context::m_types; std::map Context::m_funcs; Parser::MacrosStore Context::m_macros; +std::multimap Docs::m_docs; const char * Interrupt::Return = ":Return"; const char * Interrupt::Error = ":Error"; @@ -96,7 +97,7 @@ Context::Context(RuntimePtr global) { VERIFY(RegisterTypeHierarchy(ObjType::String,{":Any"})); VERIFY(RegisterTypeHierarchy(ObjType::StrChar,{":String"})); VERIFY(RegisterTypeHierarchy(ObjType::StrWide,{":String"})); - VERIFY(RegisterTypeHierarchy(ObjType::Format,{":String"})); + VERIFY(RegisterTypeHierarchy(ObjType::FmtChar,{":String"})); VERIFY(RegisterTypeHierarchy(ObjType::Dictionary,{":Any"})); VERIFY(RegisterTypeHierarchy(ObjType::Class,{":Dictionary"})); @@ -313,6 +314,10 @@ ObjPtr Context::eval_BLOCK(Context *ctx, const TermPtr &term, Obj *args) { obj->m_block_source = term; obj->m_var_is_init = true; + if(term->size() && term->at(0).second->IsString()) { + obj->m_help = Docs::Append(term->at(0).second->m_text); + } + return obj; } @@ -322,6 +327,10 @@ ObjPtr Context::eval_BLOCK_TRY(Context *ctx, const TermPtr &term, Obj *args) { obj->m_block_source = term; obj->m_var_is_init = true; + if(term->size() && term->at(0).second->IsString()) { + obj->m_help = Docs::Append(term->at(0).second->m_text); + } + return obj; } @@ -1417,7 +1426,7 @@ ObjPtr Context::EvalBlockXOR(Context *ctx, const TermPtr &block, Obj * local_var return (xor_counter & 1) ? Obj::Yes() : Obj::No(); } -ObjPtr Context::CreateNative(const char *proto, const char *module, bool lazzy, const char *mangle_name, ffi_abi abi) { +ObjPtr Context::CreateNative(const char *proto, const char *module, bool lazzy, const char *mangle_name) { TermPtr term; try { // Термин или термин + тип парсятся без ошибок @@ -1432,20 +1441,15 @@ ObjPtr Context::CreateNative(const char *proto, const char *module, bool lazzy, LOG_RUNTIME("Fail parsing prototype '%s'!", e.what()); } } - return CreateNative(term, module, lazzy, mangle_name, abi); + return CreateNative(term, module, lazzy, mangle_name); } -ObjPtr Context::CreateNative(TermPtr proto, const char *module, bool lazzy, const char *mangle_name, ffi_abi abi) { +ObjPtr Context::CreateNative(TermPtr proto, const char *module, bool lazzy, const char *mangle_name) { NL_CHECK(proto, "Fail prototype native function!"); NL_CHECK((module == nullptr || (module && *module == '\0')) || m_runtime, "You cannot load a module '%s' without access to the runtime context!", module); -#ifdef _MSC_VER -#pragma message WARNING("Fail native call from Windows!!!!") - return Obj::CreateNone(); -#endif - ObjPtr result; ObjType type = ObjType::None; if(proto->GetTokenID() == TermID::TERM) { @@ -1477,7 +1481,7 @@ ObjPtr Context::CreateNative(TermPtr proto, const char *module, bool lazzy, cons result->m_var_type_fixed = type; // Тип определен и не может измениться в дальнейшем *const_cast (&result->m_func_proto) = proto; - result->m_func_abi = abi; +// result->m_func_abi = abi; if(mangle_name) { result->m_func_mangle_name = mangle_name; @@ -1516,26 +1520,26 @@ std::string RunTime::GetLastErrorMessage() { } void *RunTime::GetNativeAddr(const char *name, const char *module) { - if(module && module[0]) { - if(m_modules.find(module) == m_modules.end()) { - LoadModule(module, false, nullptr); - } - if(m_modules.find(module) == m_modules.end()) { - LOG_WARNING("Fail load module '%s'!", module); - - return nullptr; - } - -#ifndef _MSC_VER - - return GetDirectAddressFromLibrary(m_modules[module]->GetHandle(), name); -#else - return static_cast (::GetProcAddress(m_modules[module]->GetHandle(), name)); -#endif - } - -#ifndef _MSC_VER -// ASSERT(m_llvm_engine); +// if(module && module[0]) { +// if(m_modules.find(module) == m_modules.end()) { +// LoadModule(module, false, nullptr); +// } +// if(m_modules.find(module) == m_modules.end()) { +// LOG_WARNING("Fail load module '%s'!", module); +// +// return nullptr; +// } +// +////#ifndef _MSC_VER +// +// return GetDirectAddressFromLibrary(m_modules[module]->GetHandle(), name); +////#else +// //return static_cast (::GetProcAddress(m_modules[module]->GetHandle(), name)); +////#endif +// } + +//#ifndef _MSC_VER + // ASSERT(m_llvm_engine); // LOG_DEBUG("getAddressToGlobalIfAvailable( %s ) = %ld", "var_long", m_llvm_engine->getAddressToGlobalIfAvailable("var_long")); // LOG_DEBUG("getGlobalValueAddress( %s ) = %ld", "var_long", m_llvm_engine->getGlobalValueAddress("var_long")); @@ -1561,13 +1565,13 @@ void *RunTime::GetNativeAddr(const char *name, const char *module) { //m_llvm_engine->getPointerToNamedFunction(name, false); return GetDirectAddressFromLibrary(nullptr, name); // return ::dlsym(::dlopen(nullptr, RTLD_NOW | RTLD_GLOBAL), name); -#else - void *result = static_cast (::GetProcAddress(GetModuleHandle(nullptr), name)); - if(result) { - return result; - } - return static_cast (::GetProcAddress((HMODULE) m_msys, name)); -#endif +//#else +// void *result = static_cast (::GetProcAddress(GetModuleHandle(nullptr), name)); + //if(result) { + // return result; +// } + // return static_cast (::GetProcAddress((HMODULE) m_msys, name)); +//#endif } void Context::CleanUp() { @@ -2114,7 +2118,7 @@ ObjPtr Context::CreateRVal(Context *ctx, TermPtr term, Obj * local_vars, bool in } args = Obj::CreateDict(); - for (int64_t i = 0; i < term->size(); i++) { + for (int64_t i = 0; i < static_cast(term->size()); i++) { if((*term)[i].second->GetTokenID() == TermID::FILLING) { diff --git a/src/context.h b/src/context.h index 879a4c01..dcdaac53 100644 --- a/src/context.h +++ b/src/context.h @@ -144,6 +144,7 @@ namespace newlang { m_macros.clear(); m_ops.clear(); m_builtin_calls.clear(); + Docs::m_docs.clear(); } inline ObjPtr ExecFile(const std::string &filename, Obj *args = nullptr, bool int_catch = true) { @@ -292,8 +293,8 @@ namespace newlang { static ObjPtr EvalBlockOR(Context *ctx, const TermPtr &block, Obj * local_vars); static ObjPtr EvalBlockXOR(Context *ctx, const TermPtr &block, Obj * local_vars); - ObjPtr CreateNative(const char *proto, const char *module = nullptr, bool lazzy = false, const char *mangle_name = nullptr, ffi_abi abi = FFI_DEFAULT_ABI); - ObjPtr CreateNative(TermPtr proto, const char *module = nullptr, bool lazzy = false, const char *mangle_name = nullptr, ffi_abi abi = FFI_DEFAULT_ABI); + ObjPtr CreateNative(const char *proto, const char *module = nullptr, bool lazzy = false, const char *mangle_name = nullptr); + ObjPtr CreateNative(TermPtr proto, const char *module = nullptr, bool lazzy = false, const char *mangle_name = nullptr); ObjPtr CreateNative(Obj args); static bool pred_compare(const std::string &find, const std::string &str) { diff --git a/src/nbproject/Makefile-GCOV.mk b/src/nbproject/Makefile-GCOV.mk index c51c09c2..1db05382 100644 --- a/src/nbproject/Makefile-GCOV.mk +++ b/src/nbproject/Makefile-GCOV.mk @@ -36,7 +36,6 @@ OBJECTDIR=${CND_BUILDDIR}/${CND_CONF}/${CND_PLATFORM} # Object Files OBJECTFILES= \ ${OBJECTDIR}/_ext/1e501df/gtest-all.o \ - ${OBJECTDIR}/_ext/1e501df/gtest_main.o \ ${OBJECTDIR}/_ext/e16507f5/logger.o \ ${OBJECTDIR}/builtin.o \ ${OBJECTDIR}/context.o \ @@ -92,11 +91,6 @@ ${OBJECTDIR}/_ext/1e501df/gtest-all.o: ../contrib/googletest/googletest/src/gtes ${RM} "$@.d" $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -std=c++14 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/_ext/1e501df/gtest-all.o ../contrib/googletest/googletest/src/gtest-all.cc -${OBJECTDIR}/_ext/1e501df/gtest_main.o: ../contrib/googletest/googletest/src/gtest_main.cc - ${MKDIR} -p ${OBJECTDIR}/_ext/1e501df - ${RM} "$@.d" - $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -std=c++14 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/_ext/1e501df/gtest_main.o ../contrib/googletest/googletest/src/gtest_main.cc - ${OBJECTDIR}/_ext/e16507f5/logger.o: ../contrib/logger/logger.cpp ${MKDIR} -p ${OBJECTDIR}/_ext/e16507f5 ${RM} "$@.d" diff --git a/src/nbproject/Makefile-UnitTest-Win32.mk b/src/nbproject/Makefile-UnitTest-Win32.mk index 30ba3aac..52673741 100644 --- a/src/nbproject/Makefile-UnitTest-Win32.mk +++ b/src/nbproject/Makefile-UnitTest-Win32.mk @@ -36,7 +36,6 @@ OBJECTDIR=${CND_BUILDDIR}/${CND_CONF}/${CND_PLATFORM} # Object Files OBJECTFILES= \ ${OBJECTDIR}/_ext/1e501df/gtest-all.o \ - ${OBJECTDIR}/_ext/1e501df/gtest_main.o \ ${OBJECTDIR}/_ext/e16507f5/logger.o \ ${OBJECTDIR}/builtin.o \ ${OBJECTDIR}/context.o \ @@ -91,11 +90,6 @@ ${OBJECTDIR}/_ext/1e501df/gtest-all.o: ../contrib/googletest/googletest/src/gtes ${RM} "$@.d" $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -I/usr/lib/llvm-13/include -std=c++14 -Wno-error -Wno-all -Wno-extra -Wno-ctor-dtor-privacy -Wno-undef -Wno-sign-compare -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/_ext/1e501df/gtest-all.o ../contrib/googletest/googletest/src/gtest-all.cc -${OBJECTDIR}/_ext/1e501df/gtest_main.o: ../contrib/googletest/googletest/src/gtest_main.cc - ${MKDIR} -p ${OBJECTDIR}/_ext/1e501df - ${RM} "$@.d" - $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -I/usr/lib/llvm-13/include -std=c++14 -Wno-error -Wno-all -Wno-extra -Wno-ctor-dtor-privacy -Wno-undef -Wno-sign-compare -Wno-conversion -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/_ext/1e501df/gtest_main.o ../contrib/googletest/googletest/src/gtest_main.cc - ${OBJECTDIR}/_ext/e16507f5/logger.o: ../contrib/logger/logger.cpp ${MKDIR} -p ${OBJECTDIR}/_ext/e16507f5 ${RM} "$@.d" diff --git a/src/nbproject/Makefile-UnitTest-Win64.mk b/src/nbproject/Makefile-UnitTest-Win64.mk index a553ded1..4e17d1f0 100644 --- a/src/nbproject/Makefile-UnitTest-Win64.mk +++ b/src/nbproject/Makefile-UnitTest-Win64.mk @@ -36,7 +36,6 @@ OBJECTDIR=${CND_BUILDDIR}/${CND_CONF}/${CND_PLATFORM} # Object Files OBJECTFILES= \ ${OBJECTDIR}/_ext/1e501df/gtest-all.o \ - ${OBJECTDIR}/_ext/1e501df/gtest_main.o \ ${OBJECTDIR}/_ext/e16507f5/logger.o \ ${OBJECTDIR}/builtin.o \ ${OBJECTDIR}/context.o \ @@ -91,11 +90,6 @@ ${OBJECTDIR}/_ext/1e501df/gtest-all.o: ../contrib/googletest/googletest/src/gtes ${RM} "$@.d" $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch-win/include/torch/csrc/api/include -I../contrib/libtorch-win/include -I../contrib/tensorboard_logger/include -I/usr/share/mingw-w64/include/ -std=c++14 -Wno-error -Wno-all -Wno-extra -Wno-ctor-dtor-privacy -Wno-undef -Wno-sign-compare -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/_ext/1e501df/gtest-all.o ../contrib/googletest/googletest/src/gtest-all.cc -${OBJECTDIR}/_ext/1e501df/gtest_main.o: ../contrib/googletest/googletest/src/gtest_main.cc - ${MKDIR} -p ${OBJECTDIR}/_ext/1e501df - ${RM} "$@.d" - $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch-win/include/torch/csrc/api/include -I../contrib/libtorch-win/include -I../contrib/tensorboard_logger/include -I/usr/share/mingw-w64/include/ -std=c++14 -Wno-error -Wno-all -Wno-extra -Wno-ctor-dtor-privacy -Wno-undef -Wno-sign-compare -Wno-conversion -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/_ext/1e501df/gtest_main.o ../contrib/googletest/googletest/src/gtest_main.cc - ${OBJECTDIR}/_ext/e16507f5/logger.o: ../contrib/logger/logger.cpp ${MKDIR} -p ${OBJECTDIR}/_ext/e16507f5 ${RM} "$@.d" diff --git a/src/nbproject/Makefile-UnitTest.mk b/src/nbproject/Makefile-UnitTest.mk index f4ae38d3..e35cb0da 100644 --- a/src/nbproject/Makefile-UnitTest.mk +++ b/src/nbproject/Makefile-UnitTest.mk @@ -36,7 +36,6 @@ OBJECTDIR=${CND_BUILDDIR}/${CND_CONF}/${CND_PLATFORM} # Object Files OBJECTFILES= \ ${OBJECTDIR}/_ext/1e501df/gtest-all.o \ - ${OBJECTDIR}/_ext/1e501df/gtest_main.o \ ${OBJECTDIR}/_ext/e16507f5/logger.o \ ${OBJECTDIR}/builtin.o \ ${OBJECTDIR}/context.o \ @@ -90,11 +89,6 @@ ${OBJECTDIR}/_ext/1e501df/gtest-all.o: ../contrib/googletest/googletest/src/gtes ${RM} "$@.d" $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I. -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -I/usr/lib/llvm-13/include -std=c++14 -Wno-error -Wno-all -Wno-extra -Wno-ctor-dtor-privacy -Wno-undef -Wno-sign-compare -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/_ext/1e501df/gtest-all.o ../contrib/googletest/googletest/src/gtest-all.cc -${OBJECTDIR}/_ext/1e501df/gtest_main.o: ../contrib/googletest/googletest/src/gtest_main.cc - ${MKDIR} -p ${OBJECTDIR}/_ext/1e501df - ${RM} "$@.d" - $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I. -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -I/usr/lib/llvm-13/include -std=c++14 -Wno-error -Wno-all -Wno-extra -Wno-ctor-dtor-privacy -Wno-undef -Wno-sign-compare -Wno-conversion -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/_ext/1e501df/gtest_main.o ../contrib/googletest/googletest/src/gtest_main.cc - ${OBJECTDIR}/_ext/e16507f5/logger.o: ../contrib/logger/logger.cpp ${MKDIR} -p ${OBJECTDIR}/_ext/e16507f5 ${RM} "$@.d" diff --git a/src/nbproject/Makefile-UnitTest_LLVM.mk b/src/nbproject/Makefile-UnitTest_LLVM.mk index 68ca5ce0..a94fa374 100644 --- a/src/nbproject/Makefile-UnitTest_LLVM.mk +++ b/src/nbproject/Makefile-UnitTest_LLVM.mk @@ -36,7 +36,6 @@ OBJECTDIR=${CND_BUILDDIR}/${CND_CONF}/${CND_PLATFORM} # Object Files OBJECTFILES= \ ${OBJECTDIR}/_ext/1e501df/gtest-all.o \ - ${OBJECTDIR}/_ext/1e501df/gtest_main.o \ ${OBJECTDIR}/_ext/e16507f5/logger.o \ ${OBJECTDIR}/builtin.o \ ${OBJECTDIR}/context.o \ @@ -83,18 +82,13 @@ LDLIBSOPTIONS=-L../contrib/libtorch/lib -L/usr/lib/x86_64-linux-gnu -Wl,-rpath,' ../output/nlc_unit_test: ${OBJECTFILES} ${MKDIR} -p ../output - ${LINK.cc} -o ../output/nlc_unit_test ${OBJECTFILES} ${LDLIBSOPTIONS} `llvm-config-13 --libs --ldflags` -stdlib=libstdc++ -fuse-ld=lld-13 -g + ${LINK.cc} -o ../output/nlc_unit_test ${OBJECTFILES} ${LDLIBSOPTIONS} `llvm-config-13 --libs --ldflags` -fuse-ld=lld-13 -g ${OBJECTDIR}/_ext/1e501df/gtest-all.o: ../contrib/googletest/googletest/src/gtest-all.cc ${MKDIR} -p ${OBJECTDIR}/_ext/1e501df ${RM} "$@.d" $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I. -I.. -I/usr/lib/llvm-13/lib/clang/13.0.1/include -I/usr/include/llvm-c-13 -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -std=c++14 -Wno-undef -Wno-sign-compare -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/_ext/1e501df/gtest-all.o ../contrib/googletest/googletest/src/gtest-all.cc -${OBJECTDIR}/_ext/1e501df/gtest_main.o: ../contrib/googletest/googletest/src/gtest_main.cc - ${MKDIR} -p ${OBJECTDIR}/_ext/1e501df - ${RM} "$@.d" - $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I. -I.. -I/usr/lib/llvm-13/lib/clang/13.0.1/include -I/usr/include/llvm-c-13 -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -std=c++14 -Wno-undef -Wno-sign-compare -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/_ext/1e501df/gtest_main.o ../contrib/googletest/googletest/src/gtest_main.cc - ${OBJECTDIR}/_ext/e16507f5/logger.o: ../contrib/logger/logger.cpp ${MKDIR} -p ${OBJECTDIR}/_ext/e16507f5 ${RM} "$@.d" diff --git a/src/nbproject/configurations.xml b/src/nbproject/configurations.xml index 8c1ea276..4856d1c4 100644 --- a/src/nbproject/configurations.xml +++ b/src/nbproject/configurations.xml @@ -56,7 +56,6 @@ displayName="Файлы ресурсов" projectFiles="true"> ../contrib/googletest/googletest/src/gtest-all.cc - ../contrib/googletest/googletest/src/gtest_main.cc lexer.yy.cpp lexer.yy.h location.hh @@ -164,14 +163,6 @@ -Wno-error -Wno-all -Wno-extra -Wno-ctor-dtor-privacy -Wno-undef -Wno-sign-compare - - - -Wno-error -Wno-all -Wno-extra -Wno-ctor-dtor-privacy -Wno-undef -Wno-sign-compare -Wno-conversion - - @@ -462,14 +453,6 @@ -Wno-undef -Wno-sign-compare - - - -Wno-undef -Wno-sign-compare - - @@ -657,11 +640,6 @@ tool="1" flavor2="11"> - - @@ -848,14 +826,6 @@ -Wno-error -Wno-all -Wno-extra -Wno-ctor-dtor-privacy -Wno-undef -Wno-sign-compare - - - -Wno-error -Wno-all -Wno-extra -Wno-ctor-dtor-privacy -Wno-undef -Wno-sign-compare -Wno-conversion - - @@ -1137,7 +1107,7 @@ torch_cpu crypto - `llvm-config-13 --libs --ldflags` -stdlib=libstdc++ -fuse-ld=lld-13 -g + `llvm-config-13 --libs --ldflags` -fuse-ld=lld-13 -g @@ -1150,14 +1120,6 @@ -Wno-undef -Wno-sign-compare - - - -Wno-undef -Wno-sign-compare - - @@ -1368,11 +1330,6 @@ tool="1" flavor2="11"> - - @@ -1611,11 +1568,6 @@ tool="1" flavor2="11"> - - @@ -1850,11 +1802,6 @@ tool="1" flavor2="11"> - - @@ -2078,14 +2025,6 @@ -Wno-error -Wno-all -Wno-extra -Wno-ctor-dtor-privacy -Wno-undef -Wno-sign-compare - - - -Wno-error -Wno-all -Wno-extra -Wno-ctor-dtor-privacy -Wno-undef -Wno-sign-compare -Wno-conversion - - @@ -2370,14 +2309,6 @@ -Wno-error -Wno-all -Wno-extra -Wno-ctor-dtor-privacy -Wno-undef -Wno-sign-compare - - - -Wno-error -Wno-all -Wno-extra -Wno-ctor-dtor-privacy -Wno-undef -Wno-sign-compare -Wno-conversion - - diff --git a/src/newlang.cpp b/src/newlang.cpp index a3c490ea..d24e4d12 100644 --- a/src/newlang.cpp +++ b/src/newlang.cpp @@ -1318,27 +1318,27 @@ bool RunTime::LoadModule(const char *name_str, bool init, Context *ctx, const ch bool RunTime::UnLoadModule(Context *ctx, const char* name, bool deinit) { bool result = false; bool is_error = false; - auto it = m_modules.begin(); - while(it != m_modules.end()) { - if(name == nullptr || it->first.compare(name) == 0) { - - for (auto &elem : it->second->Funcs()) { - if(!ctx->RemoveObject(elem.first.c_str())) { - LOG_ERROR("Fail unregister func '%s' from module '%s'.", elem.first.c_str(), it->first.c_str()); - is_error = true; - } - } - LOG_DEBUG("UnLoad module '%s'.", it->first.c_str()); - - //@todo call deinit module - delete it->second; - it = m_modules.erase(it); - result = true; - } else { - - it++; - } - } +// auto it = m_modules.begin(); +// while(it != m_modules.end()) { +// if(name == nullptr || it->first.compare(name) == 0) { +// +// for (auto &elem : it->second->Funcs()) { +// if(!ctx->RemoveObject(elem.first.c_str())) { +// LOG_ERROR("Fail unregister func '%s' from module '%s'.", elem.first.c_str(), it->first.c_str()); +// is_error = true; +// } +// } +// LOG_DEBUG("UnLoad module '%s'.", it->first.c_str()); +// +// //@todo call deinit module +// delete it->second; +// it = m_modules.erase(it); +// result = true; +// } else { +// +// it++; +// } +// } return result && !is_error; } diff --git a/src/newlang.h b/src/newlang.h index aaf17d06..df2b0eee 100644 --- a/src/newlang.h +++ b/src/newlang.h @@ -10,7 +10,9 @@ #include #include #include -//#include + + + namespace newlang { @@ -39,304 +41,40 @@ namespace newlang { return str; } - class Context; +// class Context; struct CompileInfo; - class Module { - public: - - typedef std::map FuncMap; - typedef -#ifdef _MSC_VER - HMODULE -#else - void * -#endif - HandleType; - - Module(const char * name = nullptr) { - m_handle = nullptr; - if (!Load(name)) { - LOG_RUNTIME("Can`t load %s", name); - } - } - - bool Load(const char *name) { - m_name = name; -#ifdef _MSC_VER - std::wstring win_name = utf8_decode(name); - m_handle = LoadLibrary(win_name.c_str()); -#else - m_handle = dlopen(name, RTLD_LAZY | RTLD_LOCAL); // Для GCC нужно собирать с --no-gnu-unique для замены модулей в рантайме -#endif - return m_handle; - } - - virtual ~Module() { - //Если динамическая библиотека экпортировала функцию, названную _fini, то эта функция вызывается перед выгрузкой библиотеки. - if (m_handle) { -#ifdef _MSC_VER - FreeLibrary(m_handle); -#else - dlclose(m_handle); -#endif - } - m_handle = nullptr; - } - - ObjPtr Main(Context *ctx, Obj &args) { - if (m_main) { - return (*m_main)(ctx, args); - } - LOG_DEBUG("Main function in module '%s' not found!", m_name.c_str()); - return Obj::CreateNone(); - } - - inline FuncMap& Funcs() { - return m_funcs; - } - - const char **m_source; - FunctionType *m_main; - - inline HandleType GetHandle() { - return m_handle; - } - - SCOPE(private) : - HandleType m_handle; - std::string m_name; - FuncMap m_funcs; - }; - - - //typedef std::map ProtoType; - - /* - - LLVMBuilderRef builder = LLVMCreateBuilder(); - LLVMModuleRef mod = LLVMModuleCreateWithName("my_module"); - char *error = NULL; - - LLVMExecutionEngineRef engine; - - LLVMLinkInMCJIT(); - LLVMInitializeNativeTarget(); - LLVMInitializeNativeAsmPrinter(); - LLVMInitializeNativeAsmParser(); - - if(LLVMCreateExecutionEngineForModule(&engine, mod, &error) != 0) { - fprintf(stderr, "failed to create execution engine\n"); - abort(); - } - if(error) { - fprintf(stderr, "error: %s\n", error); - LLVMDisposeMessage(error); - exit(EXIT_FAILURE); - } - - - typedef int(*Printf)(const char *format, ...); - Printf prn = reinterpret_cast (LLVMGetPointerToNamedFunction(engine, "printf")); - - - LLVMDisposeBuilder(builder); - LLVMDisposeExecutionEngine(engine); - - */ class RunTime { public: - // static LLVMBuilderRef m_llvm_builder; - // static LLVMModuleRef m_llvm_module; - // static LLVMExecutionEngineRef m_llvm_engine; - -// static void * LLVMGetPointerToNamedFunction_(LLVMExecutionEngineRef EE, const char *Name) { -// return reinterpret_cast (reinterpret_cast (EE)->getPointerToNamedFunction(Name, false)); -// } + RunTime() { - void * m_ffi_handle; + LLVMInitializeCore(LLVMGetGlobalPassRegistry()); - RunTime() : m_ffi_handle(nullptr) { - - // llvm::cl::PrintHelpMessage(); - // llvm::cl::ResetAllOptionOccurrences(); - - // llvm::cl::Option::~Option() - - // LLVMInitializeCore(LLVMGetGlobalPassRegistry()); /* program init */ - // LLVMInitializeNativeTarget(); - // LLVMInitializeNativeAsmPrinter(); - // LLVMInitializeNativeAsmParser(); - // LLVMLinkInMCJIT(); - - // builder = CreateBuilder(); - - // if (!m_llvm_engine) { - - - // m_llvm_builder = LLVMCreateBuilder(); - // m_llvm_module = LLVMModuleCreateWithName("nlc"); - - // LLVMLinkInMCJIT(); - // LLVMInitializeNativeTarget(); - // LLVMInitializeNativeAsmPrinter(); - // LLVMInitializeNativeAsmParser(); - // + LLVMInitializeNativeTarget(); + LLVMInitializeNativeAsmPrinter(); + LLVMInitializeNativeAsmParser(); + LLVMLinkInMCJIT(); // Загружает символы исполняемого файла для поиска с помощью SearchForAddressOfSymbol - llvm::sys::DynamicLibrary::LoadLibraryPermanently(nullptr, nullptr); - - // - // char *error = NULL; - // if (LLVMCreateExecutionEngineForModule(&m_llvm_engine, m_llvm_module, &error) != 0) { - // LOG_RUNTIME("Failed to create execution engine LLVM!"); - // } - // if (error) { - // std::string msg = error; - // LLVMDisposeMessage(error); - // LOG_RUNTIME("Failed to create execution engine LLVM '%s'!", msg.c_str()); - // } - -// typedef int(*Printf)(const char *format, ...); -// Printf prn = reinterpret_cast (GetDirectAddressFromLibrary(nullptr, "printf")); //LLVMGetPointerToNamedFunction_(m_llvm_engine, "printf")); -// if (!prn) { -// LOG_ERROR("Printf not found!!."); -// } else { -// int res = prn(" %s ", "\n\nУРА !!!!!!!!\n\n"); -// LOG_DEBUG("PRINTF !!!! %d !!!!!!!!!!!!!!!", res); -// } -// -// LOG_DEBUG("LLVM init complete!"); - // } + LLVMLoadLibraryPermanently(nullptr); } virtual ~RunTime() { - -#ifdef _MSC_VER - if (m_ffi_handle) { - FreeLibrary((HMODULE) m_ffi_handle); - m_ffi_handle = nullptr; - } - if (m_msys) { - FreeLibrary((HMODULE) m_msys); - m_msys = nullptr; - } -#else - // if (m_ffi_handle) { - // dlclose(m_ffi_handle); - // m_ffi_handle = nullptr; - // } - - // LLVMDisposeBuilder(m_llvm_builder); - // LLVMDisposeExecutionEngine(m_llvm_engine); - // - // m_llvm_module = nullptr; - // m_llvm_engine = nullptr; - // m_llvm_builder = nullptr; - -#endif - // DisposeBuilder(builder); - // llvm::cl::ResetAllOptionOccurrences(); - LLVMShutdown(); + //LLVMShutdown(); } static RuntimePtr Init(int argc = 0, const char** argv = nullptr, bool ignore_error = true) { RuntimePtr rt = std::make_shared(); - std::string ffi_file; - -#ifdef _MSC_VER - - std::wstring sys_file; - std::string sys_init; - - //#define CYGWIN -#ifdef CYGWIN - sys_file = L"cygwin1.dll"; - sys_init = "cygwin_dll_init"; - ffi_file = "cygffi-6.dll"; -#else - sys_file = L"msys-2.0.dll"; - sys_init = "msys_dll_init"; - ffi_file = "libffi-7.dll"; -#endif - - rt->m_msys = LoadLibrary(sys_file.c_str()); - if (!rt->m_msys) { - LOG_RUNTIME("Fail LoadLibrary %s: %s", sys_file.c_str(), RunTime::GetLastErrorMessage().c_str()); - } - - typedef void init_type(); - - init_type *init = (init_type *) GetProcAddress((HMODULE) rt->m_msys, sys_init.c_str()); - if (rt->m_msys && !init) { - FreeLibrary((HMODULE) rt->m_msys); - LOG_RUNTIME("Func %s not found! %s", sys_init.c_str(), RunTime::GetLastErrorMessage().c_str()); - (*init)(); - } - rt->m_ffi_handle = LoadLibrary(utf8_decode(ffi_file).c_str()); -#else - std::string error; - if (!llvm::sys::DynamicLibrary::LoadLibraryPermanently("libffi", &error)) { - LOG_RUNTIME("Fail load library libffi.so '%s'", error.c_str()); - } - - - // ffi_file = "libffi.so"; - // rt->m_ffi_handle = dlopen(ffi_file.c_str(), RTLD_NOW); -#endif - // - // if (!rt->m_ffi_handle) { - // LOG_RUNTIME("Fail load %s!", ffi_file.c_str()); - // } - - rt->m_ffi_type_void = static_cast (GetDirectAddressFromLibrary(rt->m_ffi_handle, "ffi_type_void")); - rt->m_ffi_type_uint8 = static_cast (GetDirectAddressFromLibrary(rt->m_ffi_handle, "ffi_type_uint8")); - rt->m_ffi_type_sint8 = static_cast (GetDirectAddressFromLibrary(rt->m_ffi_handle, "ffi_type_sint8")); - rt->m_ffi_type_uint16 = static_cast (GetDirectAddressFromLibrary(rt->m_ffi_handle, "ffi_type_uint16")); - rt->m_ffi_type_sint16 = static_cast (GetDirectAddressFromLibrary(rt->m_ffi_handle, "ffi_type_sint16")); - rt->m_ffi_type_uint32 = static_cast (GetDirectAddressFromLibrary(rt->m_ffi_handle, "ffi_type_uint32")); - rt->m_ffi_type_sint32 = static_cast (GetDirectAddressFromLibrary(rt->m_ffi_handle, "ffi_type_sint32")); - rt->m_ffi_type_uint64 = static_cast (GetDirectAddressFromLibrary(rt->m_ffi_handle, "ffi_type_uint64")); - rt->m_ffi_type_sint64 = static_cast (GetDirectAddressFromLibrary(rt->m_ffi_handle, "ffi_type_sint64")); - rt->m_ffi_type_float = static_cast (GetDirectAddressFromLibrary(rt->m_ffi_handle, "ffi_type_float")); - rt->m_ffi_type_double = static_cast (GetDirectAddressFromLibrary(rt->m_ffi_handle, "ffi_type_double")); - rt->m_ffi_type_pointer = static_cast (GetDirectAddressFromLibrary(rt->m_ffi_handle, "ffi_type_pointer")); - - rt->m_ffi_prep_cif = reinterpret_cast (GetDirectAddressFromLibrary(rt->m_ffi_handle, "ffi_prep_cif")); - rt->m_ffi_prep_cif_var = reinterpret_cast (GetDirectAddressFromLibrary(rt->m_ffi_handle, "ffi_prep_cif_var")); - rt->m_ffi_call = reinterpret_cast (GetDirectAddressFromLibrary(rt->m_ffi_handle, "ffi_call")); - - if (!(rt->m_ffi_type_uint8 && rt->m_ffi_type_sint8 && rt->m_ffi_type_uint16 && rt->m_ffi_type_sint16 && - rt->m_ffi_type_uint32 && rt->m_ffi_type_sint32 && rt->m_ffi_type_uint64 && rt->m_ffi_type_sint64 && - rt->m_ffi_type_float && rt->m_ffi_type_double && rt->m_ffi_type_pointer && rt->m_ffi_type_void && - rt->m_ffi_prep_cif && rt->m_ffi_prep_cif_var && rt->m_ffi_call)) { - LOG_RUNTIME("Fail init data from %s!", ffi_file.c_str()); - } - return rt; } inline static void * GetDirectAddressFromLibrary(void *handle, const char * name) { -#ifdef _MSC_VER - return static_cast (::GetProcAddress((HMODULE) handle, name)); -#else - void *res = llvm::sys::DynamicLibrary::SearchForAddressOfSymbol(name); - if (res) { - return res; - } - // if (m_llvm_engine) { - // // ASSERT(m_llvm_engine); - // return LLVMGetPointerToNamedFunction_(m_llvm_engine, name); - // } - return nullptr; - // return dlsym(handle, name); -#endif + return LLVMSearchForAddressOfSymbol(name); } - // void ReadBuiltInProto(ProtoType &proto); bool LoadModule(const char *name, bool init = true, Context *ctx = nullptr, const char *module_name = nullptr); bool UnLoadModule(Context *ctx, const char *name = nullptr, bool deinit = true); @@ -346,41 +84,15 @@ namespace newlang { static std::string GetLastErrorMessage(); - typedef ffi_status ffi_prep_cif_type(ffi_cif *cif, ffi_abi abi, unsigned int nargs, ffi_type *rtype, ffi_type **atypes); - typedef ffi_status ffi_prep_cif_var_type(ffi_cif *cif, ffi_abi abi, unsigned int nfixedargs, unsigned int ntotalargs, ffi_type *rtype, ffi_type **atypes); - typedef void ffi_call_type(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue); - protected: //SCOPE(private) : public: RunTime(const RunTime&) = delete; const RunTime& operator=(const RunTime&) = delete; - -#ifdef _MSC_VER - void * m_msys; -#endif - - std::map m_modules; - - ffi_type * m_ffi_type_void; - ffi_type * m_ffi_type_uint8; - ffi_type * m_ffi_type_sint8; - ffi_type * m_ffi_type_uint16; - ffi_type * m_ffi_type_sint16; - ffi_type * m_ffi_type_uint32; - ffi_type * m_ffi_type_sint32; - ffi_type * m_ffi_type_uint64; - ffi_type * m_ffi_type_sint64; - ffi_type * m_ffi_type_float; - ffi_type * m_ffi_type_double; - ffi_type * m_ffi_type_pointer; - - ffi_prep_cif_type *m_ffi_prep_cif; - ffi_prep_cif_var_type * m_ffi_prep_cif_var; - ffi_call_type * m_ffi_call; - + }; + struct CompileInfo { BuiltInTorchDirect * m_builtin_direct; diff --git a/src/nlc.cpp b/src/nlc.cpp index 8d7e22cc..10007105 100644 --- a/src/nlc.cpp +++ b/src/nlc.cpp @@ -8,13 +8,20 @@ #pragma comment(lib, "torch_cpu.lib") #pragma comment(lib, "c10.lib") +#pragma comment(lib, "LLVMSupport.lib") +#pragma comment(lib, "LLVM-C.lib") + + #endif -#ifndef UNITTEST +#ifdef UNITTEST -int main(int argc, char** argv) { +#include +#include "gtest/gtest.h" - newlang::NLC nlc(argc, (const char **) argv); +int main(int argc, char **argv) { + printf("Running main() from %s\n", __FILE__); + testing::InitGoogleTest(&argc, argv); //#0 __GI___libc_free (mem=0x1) at malloc.c:3102 //#1 0x00007fffe3d0c113 in llvm::cl::Option::~Option() () from ../contrib/libtorch/lib/libtorch_cpu.so @@ -29,12 +36,19 @@ int main(int argc, char** argv) { //#3 0x00007fffda743cd7 in ?? () from /lib/x86_64-linux-gnu/libLLVM-13.so.1 //#4 0x00007fffffffdd80 in ?? () //#5 0x00007ffff7fe0f6b in _dl_fini () at dl-fini.c:138 - + // При завершении приложения происходит Segmentation fault из-за двойного освобожнения памяти статической переменой // llvm::cl::Option::~Option() во время выгрузки динамически библиотек libLLVM или libtorch_cpu // Чтобы убрать этот coredump вместо нормального завершения main вызываю _exit, чтобы // все остальные функции освобождения памяти не вызывались при завершении процесса. - + + _exit(RUN_ALL_TESTS()); +} + +#else + +int main(int argc, char** argv) { + newlang::NLC nlc(argc, (const char **) argv); _exit(nlc.Run()); } diff --git a/src/object.cpp b/src/object.cpp index 3b4d7735..368814fd 100644 --- a/src/object.cpp +++ b/src/object.cpp @@ -1032,7 +1032,7 @@ Obj::Obj(Context *ctx, const TermPtr term, bool as_value, Obj * local_vars) { m_is_reference = term->m_is_ref; m_var_name = term->m_name.empty() ? term->m_text : term->m_name; m_var_type_current = ObjType::Dictionary; - m_func_abi = FFI_DEFAULT_ABI; + // m_func_abi = FFI_DEFAULT_ABI; m_dimensions = nullptr; m_var_is_init = false; m_is_const = false; @@ -2002,36 +2002,17 @@ ObjPtr Obj::CallNative(Context *ctx, Obj args) { LOG_RUNTIME("Fail context for call native!"); } - ffi_cif m_cif; - std::vector m_args_type; - std::vector m_args_ptr; - union VALUE { - const void *ptr; - // ObjPtr obj; - size_t size; - int64_t integer; - double number; - bool boolean; - }; - std::vector m_args_val; - VALUE temp; + std::vector arg_types; + std::vector arg_generic; - ASSERT(m_var_type_current == ObjType::NativeFunc); - ASSERT(m_func_proto); - - if(!m_func_ptr) { - NL_CHECK(m_module_name.empty() || ctx, "You cannot load a module without access to the runtime context!"); - m_func_ptr = ctx->m_runtime->GetNativeAddr(m_func_mangle_name.empty() ? m_func_proto->m_text.c_str() : m_func_mangle_name.c_str(), - m_module_name.empty() ? nullptr : m_module_name.c_str()); - } - NL_CHECK(m_func_ptr, "Fail load func name '%s' (%s) or fail load module '%s'!", m_func_proto->m_text.c_str(), - m_func_mangle_name.empty() ? m_func_proto->m_text.c_str() : m_func_mangle_name.c_str(), - m_module_name.empty() ? "none" : m_module_name.c_str()); + ObjType type_result = ctx->BaseTypeFromString(m_func_proto->m_type_name); + LLVMTypeRef return_llvm_type = toLLVMType(type_result); bool is_ellipsis = (m_func_proto->size() && (*m_func_proto)[m_func_proto->size() - 1].second->getTermID() == TermID::ELLIPSIS); size_t check_count = is_ellipsis ? m_func_proto->size() - 1 : m_func_proto->size(); + bool pointer_exist = false; // Пропустить нулевой аргумент для нативных функций for (int i = 1; i < args.size(); i++) { @@ -2043,220 +2024,391 @@ ObjPtr Obj::CallNative(Context *ctx, Obj args) { size_t pind = i - 1; // Индекс прототипа на единицу меньше из-за пустого нулевого аргумента ObjType type = args[i].second->getTypeAsLimit(); - switch(type) { - case ObjType::Bool: - if(pind < check_count) { - NL_CHECK(!(*m_func_proto)[pind].second->m_type_name.empty(), "Undefined type arg '%s'", (*m_func_proto)[pind].second->toString().c_str()); - NL_CHECK(canCast(type, typeFromString((*m_func_proto)[pind].second->m_type_name, ctx)), "Fail cast from '%s' to '%s'", - (*m_func_proto)[pind].second->m_type_name.c_str(), newlang::toString(type)); - } - m_args_type.push_back(ctx->m_runtime->m_ffi_type_uint8); - temp.boolean = args[i].second->GetValueAsBoolean(); - m_args_val.push_back(temp); - break; + if(pind < check_count) { + NL_CHECK(!(*m_func_proto)[pind].second->m_type_name.empty(), "Undefined type arg '%s'", (*m_func_proto)[pind].second->toString().c_str()); + NL_CHECK(canCast(type, typeFromString((*m_func_proto)[pind].second->m_type_name, ctx)), "Fail cast from '%s' to '%s'", + (*m_func_proto)[pind].second->m_type_name.c_str(), newlang::toString(type)); + } - case ObjType::Char: - if(pind < check_count) { - NL_CHECK(!(*m_func_proto)[pind].second->m_type_name.empty(), "Undefined type arg '%s'", (*m_func_proto)[pind].second->toString().c_str()); - NL_CHECK(canCast(type, typeFromString((*m_func_proto)[pind].second->m_type_name, ctx)), "Fail cast from '%s' to '%s'", - (*m_func_proto)[pind].second->m_type_name.c_str(), newlang::toString(type)); - } - m_args_type.push_back(ctx->m_runtime->m_ffi_type_sint8); - temp.integer = args[i].second->GetValueAsInteger(); - m_args_val.push_back(temp); - break; + ObjType check_type; + if(pind < check_count) { + std::string temp_str = (*m_func_proto)[pind].second->m_type_name; + check_type = typeFromString((*m_func_proto)[pind].second->m_type_name, ctx); + } else { + check_type = args[i].second->getType(); + } - case ObjType::Short: - if(pind < check_count) { - NL_CHECK(!(*m_func_proto)[pind].second->m_type_name.empty(), "Undefined type arg '%s'", (*m_func_proto)[pind].second->toString().c_str()); - NL_CHECK(canCast(type, typeFromString((*m_func_proto)[pind].second->m_type_name, ctx)), "Fail cast from '%s' to '%s'", - (*m_func_proto)[pind].second->m_type_name.c_str(), newlang::toString(type)); - } - m_args_type.push_back(ctx->m_runtime->m_ffi_type_sint16); - temp.integer = args[i].second->GetValueAsInteger(); - m_args_val.push_back(temp); - break; + if(args[i].second->is_string_type()) { + pointer_exist = true; + } - case ObjType::Int: - if(pind < check_count) { - NL_CHECK(!(*m_func_proto)[pind].second->m_type_name.empty(), "Undefined type arg '%s'", (*m_func_proto)[pind].second->toString().c_str()); - NL_CHECK(canCast(type, typeFromString((*m_func_proto)[pind].second->m_type_name, ctx)), "Fail cast from '%s' to '%s'", - (*m_func_proto)[pind].second->m_type_name.c_str(), newlang::toString(type)); - } - m_args_type.push_back(ctx->m_runtime->m_ffi_type_sint32); - temp.integer = args[i].second->GetValueAsInteger(); - m_args_val.push_back(temp); - break; + LLVMTypeRef temp = toLLVMType(check_type); + arg_types.push_back(temp); + arg_generic.push_back(args[i].second->GetGenericValueRef(temp)); - case ObjType::Long: - if(pind < check_count) { - NL_CHECK(!(*m_func_proto)[pind].second->m_type_name.empty(), "Undefined type arg '%s'", (*m_func_proto)[pind].second->toString().c_str()); - NL_CHECK(canCast(type, typeFromString((*m_func_proto)[pind].second->m_type_name, ctx)), "Fail cast from '%s' to '%s'", - (*m_func_proto)[pind].second->m_type_name.c_str(), newlang::toString(type)); - } - m_args_type.push_back(ctx->m_runtime->m_ffi_type_sint64); - temp.integer = args[i].second->GetValueAsInteger(); - m_args_val.push_back(temp); - break; + if(pind < check_count && (*m_func_proto)[pind].second->GetType()) { + if((*m_func_proto)[pind].second->GetType()->m_text.compare(newlang::toString(ObjType::FmtChar)) == 0) { + NL_CHECK(ParsePrintfFormat(&args, i), "Fail format string or type args!"); + } + } + } - case ObjType::Float: - if(pind < check_count) { - NL_CHECK(!(*m_func_proto)[pind].second->m_type_name.empty(), "Undefined type arg '%s'", (*m_func_proto)[pind].second->toString().c_str()); - NL_CHECK(canCast(type, typeFromString((*m_func_proto)[pind].second->m_type_name, ctx)), "Fail cast from '%s' to '%s'", - (*m_func_proto)[pind].second->m_type_name.c_str(), newlang::toString(type)); - } - m_args_type.push_back(ctx->m_runtime->m_ffi_type_float); - temp.number = args[i].second->GetValueAsNumber(); - m_args_val.push_back(temp); - break; - case ObjType::Double: - if(pind < check_count) { - NL_CHECK(!(*m_func_proto)[pind].second->m_type_name.empty(), "Undefined type arg '%s'", (*m_func_proto)[pind].second->toString().c_str()); - NL_CHECK(canCast(type, typeFromString((*m_func_proto)[pind].second->m_type_name, ctx)), "Fail cast from '%s' to '%s'", - (*m_func_proto)[pind].second->m_type_name.c_str(), newlang::toString(type)); - } - m_args_type.push_back(ctx->m_runtime->m_ffi_type_double); - temp.number = args[i].second->GetValueAsNumber(); - m_args_val.push_back(temp); - break; + LLVMInitializeNativeTarget(); + LLVMInitializeNativeAsmPrinter(); + LLVMInitializeNativeAsmParser(); - case ObjType::StrChar: - if(pind < check_count) { - NL_CHECK(!(*m_func_proto)[pind].second->m_type_name.empty(), "Undefined type arg '%s'", (*m_func_proto)[pind].second->toString().c_str()); - NL_CHECK(canCast(type, typeFromString((*m_func_proto)[pind].second->m_type_name, ctx)), "Fail cast from '%s' to '%s'", - (*m_func_proto)[pind].second->m_type_name.c_str(), newlang::toString(type)); - } - m_args_type.push_back(ctx->m_runtime->m_ffi_type_pointer); - temp.ptr = args[i].second->m_str.c_str(); - m_args_val.push_back(temp); - break; + auto module = LLVMModuleCreateWithName("call_native"); + LLVMExecutionEngineRef interpreter; + LLVMCreateExecutionEngineForModule(&interpreter, module, nullptr); - case ObjType::StrWide: - if(pind < check_count) { - NL_CHECK(!(*m_func_proto)[pind].second->m_type_name.empty(), "Undefined type arg '%s'", (*m_func_proto)[pind].second->toString().c_str()); - NL_CHECK(canCast(type, typeFromString((*m_func_proto)[pind].second->m_type_name, ctx)), "Fail cast from '%s' to '%s'", - (*m_func_proto)[pind].second->m_type_name.c_str(), newlang::toString(type)); - } - m_args_type.push_back(ctx->m_runtime->m_ffi_type_pointer); - temp.ptr = args[i].second->m_wstr.c_str(); - m_args_val.push_back(temp); - break; + // std::vector arg_types{LLVMPointerType(LLVMInt8Type(), 0)}; + LLVMTypeRef func_res_type = LLVMFunctionType(return_llvm_type, arg_types.data(), static_cast (arg_types.size()), is_ellipsis); - case ObjType::Pointer: - if(pind < check_count) { - NL_CHECK(!(*m_func_proto)[pind].second->m_type_name.empty(), "Undefined type arg '%s'", (*m_func_proto)[pind].second->toString().c_str()); - NL_CHECK(canCast(type, typeFromString((*m_func_proto)[pind].second->m_type_name, ctx)), "Fail cast from '%s' to '%s'", - (*m_func_proto)[pind].second->m_type_name.c_str(), newlang::toString(type)); - } - m_args_type.push_back(ctx->m_runtime->m_ffi_type_pointer); - temp.ptr = args[i].second->m_func_ptr; - m_args_val.push_back(temp); - break; + // Declare a function bar in IR, we will define this function with IR + LLVMValueRef wrap = LLVMAddFunction(module, "call_wrap", func_res_type); + + // Create the code block of the function bar + auto entry = LLVMAppendBasicBlock(wrap, "entry"); + auto builder = LLVMCreateBuilder(); + LLVMPositionBuilderAtEnd(builder, entry); - default: - LOG_RUNTIME("Native arg '%s' not implemented!", args[i].second->toString().c_str()); - } - if(pind < check_count && (*m_func_proto)[pind].second->GetType()) { - if((*m_func_proto)[pind].second->GetType()->m_text.compare(newlang::toString(ObjType::Format)) == 0) { - NL_CHECK(ParsePrintfFormat(&args, i), "Fail format string or type args!"); - } - } - } - for (size_t i = 0; i < m_args_val.size(); i++) { - m_args_ptr.push_back((void *) &m_args_val[i]); + + std::vector args_param; + // Пропустить нулевой аргумент для нативных функций + for (int i = 1; i < args.size(); i++) { + // Индекс прототипа на единицу меньше из-за пустого нулевого аргумента + args_param.push_back(LLVMGetParam(wrap, i - 1)); } - NL_CHECK(!m_func_proto->m_type_name.empty(), "Undefined return type '%s'", m_func_proto->toString().c_str()); + // LLVMValueRef param_call[] = {LLVMGetParam(wrap, 0)}; + LLVMValueRef func_call = LLVMAddFunction(module, "m_func_ptr", func_res_type); // Имя функции может пересечся с сужествующими при связывании????? + LLVMValueRef func_ret = LLVMBuildCall2(builder, func_res_type, func_call, args_param.data(), static_cast (args_param.size()), m_func_proto->m_text.c_str()); - VALUE res_value; - ffi_type *result_ffi_type = nullptr; + //return value + LLVMBuildRet(builder, func_ret); - ObjType type = ctx->BaseTypeFromString(m_func_proto->m_type_name); - switch(type) { - case ObjType::Bool: - result_ffi_type = ctx->m_runtime->m_ffi_type_uint8; - break; + char *error = nullptr; + if(LLVMVerifyModule(module, LLVMReturnStatusAction, &error)) { + LOG_RUNTIME("LLVMVerifyModule %s", error ? error : ""); + } + if(error) { + LLVMDisposeMessage(error); + error = nullptr; + } - case ObjType::Char: - result_ffi_type = ctx->m_runtime->m_ffi_type_sint8; - break; - case ObjType::Short: - result_ffi_type = ctx->m_runtime->m_ffi_type_sint16; - break; - case ObjType::Int: - result_ffi_type = ctx->m_runtime->m_ffi_type_sint32; - break; +#ifdef UNITTEST + char *dump = LLVMPrintValueToString(wrap); + LOG_INFO("LLVM DUMP %s:\n%s\r\r", toString().c_str(), dump); + LLVMDisposeMessage(dump); +#endif - case ObjType::Long: - result_ffi_type = ctx->m_runtime->m_ffi_type_sint64; - break; + LLVMExecutionEngineRef engine; + if(LLVMCreateExecutionEngineForModule(&engine, module, &error)) { + LOG_RUNTIME("Failed to create execution engine '%s'!", error ? error : ""); + } + if(error) { + LLVMDisposeMessage(error); + error = nullptr; + } - case ObjType::Float: - result_ffi_type = ctx->m_runtime->m_ffi_type_float; - break; - case ObjType::Double: - result_ffi_type = ctx->m_runtime->m_ffi_type_double; - break; + // Map the global function in the external C++ code to the IR code, only the declaration in the IR code + LLVMAddGlobalMapping(engine, func_call, m_func_ptr); - case ObjType::Pointer: - case ObjType::StrChar: - case ObjType::StrWide: - result_ffi_type = ctx->m_runtime->m_ffi_type_pointer; - break; - default: - LOG_RUNTIME("Native return type '%s' not implemented!", m_func_proto->m_type_name.c_str()); - } - - ASSERT(m_func_abi == FFI_DEFAULT_ABI); // Нужны другие типы вызовов ??? - if(ctx->m_runtime->m_ffi_prep_cif(&m_cif, m_func_abi, static_cast (m_args_type.size()), result_ffi_type, m_args_type.data()) == FFI_OK) { - - ctx->m_runtime->m_ffi_call(&m_cif, FFI_FN(m_func_ptr), &res_value, m_args_ptr.data()); - - if(result_ffi_type == ctx->m_runtime->m_ffi_type_uint8) { - // Возвращаемый тип может быть как Byte, так и Bool - return Obj::CreateValue(static_cast (res_value.integer), typeFromString(m_func_proto->m_type_name)); - } else if(result_ffi_type == ctx->m_runtime->m_ffi_type_sint8) { - return Obj::CreateValue(static_cast (res_value.integer), ObjType::Char); - } else if(result_ffi_type == ctx->m_runtime->m_ffi_type_sint16) { - return Obj::CreateValue(static_cast (res_value.integer), ObjType::Short); - } else if(result_ffi_type == ctx->m_runtime->m_ffi_type_sint32) { - return Obj::CreateValue(static_cast (res_value.integer), ObjType::Int); - } else if(result_ffi_type == ctx->m_runtime->m_ffi_type_sint64) { - return Obj::CreateValue(res_value.integer, ObjType::Long); - } else if(result_ffi_type == ctx->m_runtime->m_ffi_type_float) { - return Obj::CreateValue(res_value.number, ObjType::Float); - } else if(result_ffi_type == ctx->m_runtime->m_ffi_type_double) { - return Obj::CreateValue(res_value.number, ObjType::Double); - } else if(result_ffi_type == ctx->m_runtime->m_ffi_type_pointer) { - if(type == ObjType::StrChar) { - return Obj::CreateString(reinterpret_cast (res_value.ptr)); - } else if(type == ObjType::StrWide) { - return Obj::CreateString(reinterpret_cast (res_value.ptr)); - } else if(type == ObjType::Pointer) { - ObjPtr result = ctx->GetTypeFromString(m_func_proto->m_type_name); - result->m_func_ptr = (void *) res_value.ptr; - result->m_var_is_init = true; - return result; - } else { - LOG_RUNTIME("Error result type '%s' or not implemented!", m_func_proto->m_type_name.c_str()); - } - } else { - LOG_RUNTIME("Native return type '%s' not implemented!", m_func_proto->m_type_name.c_str()); - } + ObjPtr result = nullptr; +#ifdef _MSC_VER + bool skip_call = true; +#else + bool skip_call = false; +#endif + if(pointer_exist && skip_call) { + LOG_WARNING("LLVM reported error on Windows: \"MCJIT::runFunction does not support full-featured argument passing!!!!\""); + result = Obj::CreateNone(); + } else { + // std::vector exec_args{LLVMCreateGenericValueOfPointer((void *) "РАБОТАЕТ!!!!")}; + LLVMGenericValueRef exec_res = LLVMRunFunction(engine, wrap, static_cast (arg_generic.size()), arg_generic.data()); + result = Obj::CreateFromGenericValue(type_result, exec_res, return_llvm_type); + LLVMDisposeGenericValue(exec_res); } - LOG_RUNTIME("Fail native call '%s'!", toString().c_str()); + for (auto &elem : arg_generic) { + LLVMDisposeGenericValue(elem); + } + + LLVMDisposeBuilder(builder); + // LLVMDisposeExecutionEngine(engine); + // LLVMDisposeModule(module); - return Obj::CreateNone(); + return result; } +//ObjPtr Obj::CallNative(Context *ctx, Obj args) { +// +// if(!ctx || !ctx->m_runtime) { +// LOG_RUNTIME("Fail context for call native!"); +// } +// +// ffi_cif m_cif; +// std::vector m_args_type; +// std::vector m_args_ptr; +// +// union VALUE { +// const void *ptr; +// // ObjPtr obj; +// size_t size; +// int64_t integer; +// double number; +// bool boolean; +// }; +// std::vector m_args_val; +// VALUE temp; +// +// ASSERT(m_var_type_current == ObjType::NativeFunc); +// ASSERT(m_func_proto); +// +// if(!m_func_ptr) { +// NL_CHECK(m_module_name.empty() || ctx, "You cannot load a module without access to the runtime context!"); +// m_func_ptr = ctx->m_runtime->GetNativeAddr(m_func_mangle_name.empty() ? m_func_proto->m_text.c_str() : m_func_mangle_name.c_str(), +// m_module_name.empty() ? nullptr : m_module_name.c_str()); +// } +// NL_CHECK(m_func_ptr, "Fail load func name '%s' (%s) or fail load module '%s'!", m_func_proto->m_text.c_str(), +// m_func_mangle_name.empty() ? m_func_proto->m_text.c_str() : m_func_mangle_name.c_str(), +// m_module_name.empty() ? "none" : m_module_name.c_str()); +// +// bool is_ellipsis = (m_func_proto->size() && (*m_func_proto)[m_func_proto->size() - 1].second->getTermID() == TermID::ELLIPSIS); +// size_t check_count = is_ellipsis ? m_func_proto->size() - 1 : m_func_proto->size(); +// +// // Пропустить нулевой аргумент для нативных функций +// for (int i = 1; i < args.size(); i++) { +// +// ASSERT(args[i].second); +// if(args[i].second->m_is_reference) { +// LOG_RUNTIME("Argument REFERENCE! %s", args[i].second->toString().c_str()); +// } +// +// size_t pind = i - 1; // Индекс прототипа на единицу меньше из-за пустого нулевого аргумента +// +// ObjType type = args[i].second->getTypeAsLimit(); +// switch(type) { +// case ObjType::Bool: +// if(pind < check_count) { +// NL_CHECK(!(*m_func_proto)[pind].second->m_type_name.empty(), "Undefined type arg '%s'", (*m_func_proto)[pind].second->toString().c_str()); +// NL_CHECK(canCast(type, typeFromString((*m_func_proto)[pind].second->m_type_name, ctx)), "Fail cast from '%s' to '%s'", +// (*m_func_proto)[pind].second->m_type_name.c_str(), newlang::toString(type)); +// } +// m_args_type.push_back(ctx->m_runtime->m_ffi_type_uint8); +// temp.boolean = args[i].second->GetValueAsBoolean(); +// m_args_val.push_back(temp); +// break; +// +// case ObjType::Char: +// if(pind < check_count) { +// NL_CHECK(!(*m_func_proto)[pind].second->m_type_name.empty(), "Undefined type arg '%s'", (*m_func_proto)[pind].second->toString().c_str()); +// NL_CHECK(canCast(type, typeFromString((*m_func_proto)[pind].second->m_type_name, ctx)), "Fail cast from '%s' to '%s'", +// (*m_func_proto)[pind].second->m_type_name.c_str(), newlang::toString(type)); +// } +// m_args_type.push_back(ctx->m_runtime->m_ffi_type_sint8); +// temp.integer = args[i].second->GetValueAsInteger(); +// m_args_val.push_back(temp); +// break; +// +// case ObjType::Short: +// if(pind < check_count) { +// NL_CHECK(!(*m_func_proto)[pind].second->m_type_name.empty(), "Undefined type arg '%s'", (*m_func_proto)[pind].second->toString().c_str()); +// NL_CHECK(canCast(type, typeFromString((*m_func_proto)[pind].second->m_type_name, ctx)), "Fail cast from '%s' to '%s'", +// (*m_func_proto)[pind].second->m_type_name.c_str(), newlang::toString(type)); +// } +// m_args_type.push_back(ctx->m_runtime->m_ffi_type_sint16); +// temp.integer = args[i].second->GetValueAsInteger(); +// m_args_val.push_back(temp); +// break; +// +// case ObjType::Int: +// if(pind < check_count) { +// NL_CHECK(!(*m_func_proto)[pind].second->m_type_name.empty(), "Undefined type arg '%s'", (*m_func_proto)[pind].second->toString().c_str()); +// NL_CHECK(canCast(type, typeFromString((*m_func_proto)[pind].second->m_type_name, ctx)), "Fail cast from '%s' to '%s'", +// (*m_func_proto)[pind].second->m_type_name.c_str(), newlang::toString(type)); +// } +// m_args_type.push_back(ctx->m_runtime->m_ffi_type_sint32); +// temp.integer = args[i].second->GetValueAsInteger(); +// m_args_val.push_back(temp); +// break; +// +// case ObjType::Long: +// if(pind < check_count) { +// NL_CHECK(!(*m_func_proto)[pind].second->m_type_name.empty(), "Undefined type arg '%s'", (*m_func_proto)[pind].second->toString().c_str()); +// NL_CHECK(canCast(type, typeFromString((*m_func_proto)[pind].second->m_type_name, ctx)), "Fail cast from '%s' to '%s'", +// (*m_func_proto)[pind].second->m_type_name.c_str(), newlang::toString(type)); +// } +// m_args_type.push_back(ctx->m_runtime->m_ffi_type_sint64); +// temp.integer = args[i].second->GetValueAsInteger(); +// m_args_val.push_back(temp); +// break; +// +// case ObjType::Float: +// if(pind < check_count) { +// NL_CHECK(!(*m_func_proto)[pind].second->m_type_name.empty(), "Undefined type arg '%s'", (*m_func_proto)[pind].second->toString().c_str()); +// NL_CHECK(canCast(type, typeFromString((*m_func_proto)[pind].second->m_type_name, ctx)), "Fail cast from '%s' to '%s'", +// (*m_func_proto)[pind].second->m_type_name.c_str(), newlang::toString(type)); +// } +// m_args_type.push_back(ctx->m_runtime->m_ffi_type_float); +// temp.number = args[i].second->GetValueAsNumber(); +// m_args_val.push_back(temp); +// break; +// +// case ObjType::Double: +// if(pind < check_count) { +// NL_CHECK(!(*m_func_proto)[pind].second->m_type_name.empty(), "Undefined type arg '%s'", (*m_func_proto)[pind].second->toString().c_str()); +// NL_CHECK(canCast(type, typeFromString((*m_func_proto)[pind].second->m_type_name, ctx)), "Fail cast from '%s' to '%s'", +// (*m_func_proto)[pind].second->m_type_name.c_str(), newlang::toString(type)); +// } +// m_args_type.push_back(ctx->m_runtime->m_ffi_type_double); +// temp.number = args[i].second->GetValueAsNumber(); +// m_args_val.push_back(temp); +// break; +// +// case ObjType::StrChar: +// if(pind < check_count) { +// NL_CHECK(!(*m_func_proto)[pind].second->m_type_name.empty(), "Undefined type arg '%s'", (*m_func_proto)[pind].second->toString().c_str()); +// NL_CHECK(canCast(type, typeFromString((*m_func_proto)[pind].second->m_type_name, ctx)), "Fail cast from '%s' to '%s'", +// (*m_func_proto)[pind].second->m_type_name.c_str(), newlang::toString(type)); +// } +// m_args_type.push_back(ctx->m_runtime->m_ffi_type_pointer); +// temp.ptr = args[i].second->m_str.c_str(); +// m_args_val.push_back(temp); +// break; +// +// case ObjType::StrWide: +// if(pind < check_count) { +// NL_CHECK(!(*m_func_proto)[pind].second->m_type_name.empty(), "Undefined type arg '%s'", (*m_func_proto)[pind].second->toString().c_str()); +// NL_CHECK(canCast(type, typeFromString((*m_func_proto)[pind].second->m_type_name, ctx)), "Fail cast from '%s' to '%s'", +// (*m_func_proto)[pind].second->m_type_name.c_str(), newlang::toString(type)); +// } +// m_args_type.push_back(ctx->m_runtime->m_ffi_type_pointer); +// temp.ptr = args[i].second->m_wstr.c_str(); +// m_args_val.push_back(temp); +// break; +// +// case ObjType::Pointer: +// if(pind < check_count) { +// NL_CHECK(!(*m_func_proto)[pind].second->m_type_name.empty(), "Undefined type arg '%s'", (*m_func_proto)[pind].second->toString().c_str()); +// NL_CHECK(canCast(type, typeFromString((*m_func_proto)[pind].second->m_type_name, ctx)), "Fail cast from '%s' to '%s'", +// (*m_func_proto)[pind].second->m_type_name.c_str(), newlang::toString(type)); +// } +// m_args_type.push_back(ctx->m_runtime->m_ffi_type_pointer); +// temp.ptr = args[i].second->m_func_ptr; +// m_args_val.push_back(temp); +// break; +// +// default: +// LOG_RUNTIME("Native arg '%s' not implemented!", args[i].second->toString().c_str()); +// } +// if(pind < check_count && (*m_func_proto)[pind].second->GetType()) { +// if((*m_func_proto)[pind].second->GetType()->m_text.compare(newlang::toString(ObjType::FmtChar)) == 0) { +// NL_CHECK(ParsePrintfFormat(&args, i), "Fail format string or type args!"); +// } +// } +// } +// +// for (size_t i = 0; i < m_args_val.size(); i++) { +// m_args_ptr.push_back((void *) &m_args_val[i]); +// } +// +// NL_CHECK(!m_func_proto->m_type_name.empty(), "Undefined return type '%s'", m_func_proto->toString().c_str()); +// +// VALUE res_value; +// ffi_type *result_ffi_type = nullptr; +// +// ObjType type = ctx->BaseTypeFromString(m_func_proto->m_type_name); +// +// switch(type) { +// case ObjType::Bool: +// result_ffi_type = ctx->m_runtime->m_ffi_type_uint8; +// break; +// +// case ObjType::Char: +// result_ffi_type = ctx->m_runtime->m_ffi_type_sint8; +// break; +// +// case ObjType::Short: +// result_ffi_type = ctx->m_runtime->m_ffi_type_sint16; +// break; +// +// case ObjType::Int: +// result_ffi_type = ctx->m_runtime->m_ffi_type_sint32; +// break; +// +// case ObjType::Long: +// result_ffi_type = ctx->m_runtime->m_ffi_type_sint64; +// break; +// +// case ObjType::Float: +// result_ffi_type = ctx->m_runtime->m_ffi_type_float; +// break; +// +// case ObjType::Double: +// result_ffi_type = ctx->m_runtime->m_ffi_type_double; +// break; +// +// case ObjType::Pointer: +// case ObjType::StrChar: +// case ObjType::StrWide: +// result_ffi_type = ctx->m_runtime->m_ffi_type_pointer; +// break; +// +// default: +// LOG_RUNTIME("Native return type '%s' not implemented!", m_func_proto->m_type_name.c_str()); +// } +// +// ASSERT(m_func_abi == FFI_DEFAULT_ABI); // Нужны другие типы вызовов ??? +// if(ctx->m_runtime->m_ffi_prep_cif(&m_cif, m_func_abi, static_cast (m_args_type.size()), result_ffi_type, m_args_type.data()) == FFI_OK) { +// +// ctx->m_runtime->m_ffi_call(&m_cif, FFI_FN(m_func_ptr), &res_value, m_args_ptr.data()); +// +// if(result_ffi_type == ctx->m_runtime->m_ffi_type_uint8) { +// // Возвращаемый тип может быть как Byte, так и Bool +// return Obj::CreateValue(static_cast (res_value.integer), typeFromString(m_func_proto->m_type_name)); +// } else if(result_ffi_type == ctx->m_runtime->m_ffi_type_sint8) { +// return Obj::CreateValue(static_cast (res_value.integer), ObjType::Char); +// } else if(result_ffi_type == ctx->m_runtime->m_ffi_type_sint16) { +// return Obj::CreateValue(static_cast (res_value.integer), ObjType::Short); +// } else if(result_ffi_type == ctx->m_runtime->m_ffi_type_sint32) { +// return Obj::CreateValue(static_cast (res_value.integer), ObjType::Int); +// } else if(result_ffi_type == ctx->m_runtime->m_ffi_type_sint64) { +// return Obj::CreateValue(res_value.integer, ObjType::Long); +// } else if(result_ffi_type == ctx->m_runtime->m_ffi_type_float) { +// return Obj::CreateValue(res_value.number, ObjType::Float); +// } else if(result_ffi_type == ctx->m_runtime->m_ffi_type_double) { +// return Obj::CreateValue(res_value.number, ObjType::Double); +// } else if(result_ffi_type == ctx->m_runtime->m_ffi_type_pointer) { +// if(type == ObjType::StrChar) { +// return Obj::CreateString(reinterpret_cast (res_value.ptr)); +// } else if(type == ObjType::StrWide) { +// return Obj::CreateString(reinterpret_cast (res_value.ptr)); +// } else if(type == ObjType::Pointer) { +// ObjPtr result = ctx->GetTypeFromString(m_func_proto->m_type_name); +// result->m_func_ptr = (void *) res_value.ptr; +// result->m_var_is_init = true; +// return result; +// } else { +// LOG_RUNTIME("Error result type '%s' or not implemented!", m_func_proto->m_type_name.c_str()); +// } +// } else { +// LOG_RUNTIME("Native return type '%s' not implemented!", m_func_proto->m_type_name.c_str()); +// } +// } +// +// LOG_RUNTIME("Fail native call '%s'!", toString().c_str()); +// +// return Obj::CreateNone(); +//} + bool newlang::ParsePrintfFormat(Obj *args, int start) { if(!args) { @@ -2980,7 +3132,7 @@ ObjPtr Obj::MakeIterator(const std::string filter, bool check_create) { return result; } -ObjPtr Obj::MakeIterator(Obj *args) { +ObjPtr Obj::MakeIterator(Obj * args) { ObjPtr result = CreateType(ObjType::Iterator, ObjType::Iterator, true); if(!is_indexing()) { if(getType() == ObjType::Iterator) { diff --git a/src/object.h b/src/object.h index 83e8d1df..ca8dcb50 100755 --- a/src/object.h +++ b/src/object.h @@ -282,9 +282,8 @@ namespace newlang { // constexpr static const char * BUILDIN_BASE = "__class_base__"; // constexpr static const char * BUILDIN_CLASS = "__class_name__"; // constexpr static const char * BUILDIN_NAMESPACE = "__namespace__"; - + typedef Variable::PairType PairType; - Obj(ObjType type = ObjType::None, const char *var_name = nullptr, TermPtr func_proto = nullptr, ObjType fixed = ObjType::None, bool init = false) : m_var_type_current(type), m_var_name(var_name ? var_name : ""), m_func_proto(func_proto) { @@ -295,7 +294,7 @@ namespace newlang { m_dimensions = nullptr; m_value = torch::empty({0}, isSimpleType(type) ? toTorchType(type) : at::ScalarType::Undefined); m_is_reference = false; - m_func_abi = FFI_DEFAULT_ABI; + // m_func_abi = FFI_DEFAULT_ABI; m_var_type_fixed = fixed; m_var_is_init = init; m_is_const = false; @@ -658,9 +657,9 @@ namespace newlang { return Variable::find(name); } -// Obj::const_iterator find(const std::string_view name) const { -// return Variable::find(name); -// } + // Obj::const_iterator find(const std::string_view name) const { + // return Variable::find(name); + // } Obj::iterator begin() { return Variable::begin(); @@ -1323,6 +1322,44 @@ namespace newlang { } } + LLVMGenericValueRef GetGenericValueRef(LLVMTypeRef type) { + if (is_integer() || is_bool_type()) { + return LLVMCreateGenericValueOfInt(type, GetValueAsInteger(), true); + } else if (is_floating()) { + return LLVMCreateGenericValueOfFloat(type, GetValueAsNumber()); + } else if (getType() == ObjType::StrChar || getType() == ObjType::FmtChar) { + return LLVMCreateGenericValueOfPointer((void *) m_str.c_str()); + } else if (getType() == ObjType::StrWide) { + return LLVMCreateGenericValueOfPointer((void *) m_wstr.c_str()); + } else if (getType() == ObjType::Pointer) { + return LLVMCreateGenericValueOfPointer(m_func_ptr); + } + LOG_RUNTIME("Not support LLVM type '%s'", newlang::toString(m_var_type_current)); + } + + static ObjPtr CreateFromGenericValue(ObjType type, LLVMGenericValueRef ref, LLVMTypeRef llvm_type) { + if (type == ObjType::None) { + return Obj::CreateNone(); + } else if (isIntegralType(type, true)) { + int64_t value = LLVMGenericValueToInt(ref, true); + unsigned width = LLVMGenericValueIntWidth(ref); + return Obj::CreateValue(value, type); + } else if (isFloatingType(type)) { + return Obj::CreateValue((double) LLVMGenericValueToFloat(llvm_type, ref), type); + } else if (type == ObjType::StrChar) { + return Obj::CreateString(std::string((const char *) LLVMGenericValueToPointer(ref))); + } else if (type == ObjType::StrWide) { + return Obj::CreateString(std::wstring((const wchar_t *)LLVMGenericValueToPointer(ref))); + } else if (type == ObjType::Pointer) { + + ObjPtr result = Obj::CreateType(type, ObjType::None, true); + result->m_func_ptr = LLVMGenericValueToPointer(ref); + + return result; + } + LOG_RUNTIME("Create to type '%s' form LLVM type not implemented!", newlang::toString(type)); + } + at::Scalar toTorchScalar() { at::Scalar result; if (is_integer() || is_bool_type()) { @@ -2031,7 +2068,7 @@ namespace newlang { std::string m_func_mangle_name; std::string m_module_name; void *m_func_ptr; - ffi_abi m_func_abi; + // ffi_abi m_func_abi; torch::Tensor m_value; std::shared_ptr m_fraction; std::shared_ptr< Iterator > m_iterator; @@ -2039,13 +2076,10 @@ namespace newlang { TermPtr m_block_source; bool m_check_args; //< Проверять аргументы на корректность (для всех видов функций) @ref MakeArgs - // Context *m_ctx; - - // SCOPE(protected) : bool m_is_const; //< Признак константы (по умолчанию изменения разрешено) bool m_is_reference; //< Признак ссылки на объект (mutable) - std::shared_ptr m_help; + DocPtr m_help; }; diff --git a/src/parser.y b/src/parser.y index 2a36d574..3615a243 100644 --- a/src/parser.y +++ b/src/parser.y @@ -144,7 +144,7 @@ * * # Инициализация для функции demo * @::var = _; - * @print := NewLang(import= «printf(format:Format, ...):Int» ); + * @print := NewLang(import= «printf(format:FmtChar, ...):Int» ); * --; * * %{ std::string demo(const char *arg) {; $var = arg; %} diff --git a/src/pch.h b/src/pch.h index ceeeef24..68aae7e7 100644 --- a/src/pch.h +++ b/src/pch.h @@ -48,58 +48,12 @@ #endif -#include - #include "warning_push.h" #include #include -#include #include -#include - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "llvm/ExecutionEngine/JITSymbol.h" -#include "llvm/ExecutionEngine/Orc/CompileUtils.h" -#include "llvm/ExecutionEngine/Orc/Core.h" -#include "llvm/ExecutionEngine/Orc/ExecutionUtils.h" -#include "llvm/ExecutionEngine/Orc/IRCompileLayer.h" -#include "llvm/ExecutionEngine/Orc/JITTargetMachineBuilder.h" -#include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include #include #include diff --git a/src/test/compiler_test.cpp b/src/test/compiler_test.cpp index 51179558..222bb507 100644 --- a/src/test/compiler_test.cpp +++ b/src/test/compiler_test.cpp @@ -41,6 +41,17 @@ TEST(Compiler, MangleName) { EXPECT_STREQ("newlang_maks", MangleName("макс").c_str()) << MangleName("макс"); } +TEST(LLVM, Symbols) { + + auto rt = RunTime::Init(); + + + EXPECT_TRUE(LLVMSearchForAddressOfSymbol("printf")); + EXPECT_TRUE(LLVMSearchForAddressOfSymbol("fopen")); + +} + + // TEST(NewLang, Simple) { // TermPtr context; // Parser parser(context); @@ -138,7 +149,7 @@ bool str_cmp_strart(const char *base_str, const char *cmp_str) { std::string base(base_str); std::string cmp(cmp_str); for (size_t i = 0; i < base.size() && i < cmp.size(); i++) { - if (base[i] != cmp[i]) { + if(base[i] != cmp[i]) { return false; } } @@ -576,10 +587,10 @@ TEST(Compiler, DISABLED_FuncsTypes) { ASSERT_TRUE(ctx.m_runtime->LoadModule("call_types.temp.nlm", false, &ctx)); // Переполнение байтовой переменной $res во время выполнения последнего оператора "+=" - Obj args; - ASSERT_TRUE(ctx.m_runtime->m_modules["temp/call_types.temp.nlm"]); - ASSERT_NO_THROW( - ctx.m_runtime->m_modules["temp/call_types.temp.nlm"]->Main(&ctx, args)); + // Obj args; + // ASSERT_TRUE(ctx.m_runtime->m_modules["temp/call_types.temp.nlm"]); + // ASSERT_NO_THROW( + // ctx.m_runtime->m_modules["temp/call_types.temp.nlm"]->Main(&ctx, args)); //@todo Контроль переполнения при операциях для типизированных переменных //???????????????? //@todo Такой же как и для остальных операций diff --git a/src/test/eval_test.cpp b/src/test/eval_test.cpp index 656bf595..10ea5ad8 100644 --- a/src/test/eval_test.cpp +++ b/src/test/eval_test.cpp @@ -26,10 +26,10 @@ using namespace newlang; //if invoking the linker via the clang-cl frontend), you can opt in to this behaviour by adding the lld specific option -lldmingw //, which enables a number of MinGW-specific behaviours in lld. -extern "C" __attribute__ ((visibility("default"))) int64_t var_long; //, export_name("var_long") +extern "C" int64_t var_long; //, export_name("var_long") __attribute__ ((visibility("default"))) int64_t var_long = 987654321; -extern "C" __attribute__ ((visibility("default"))) int64_t func_export(int64_t arg_long, uint8_t arg_byte) { +extern "C" int64_t func_export(int64_t arg_long, uint8_t arg_byte) { // __attribute__ ((visibility("default"))) return arg_long + arg_byte; } @@ -423,8 +423,8 @@ TEST(Eval, TypesNative) { ASSERT_TRUE(frename); ASSERT_TRUE(frename->m_func_ptr); - ObjPtr fprintf = ctx.ExecStr("@fprintf(stream:File, format:Format, ...):Int ::= " - ":Pointer('fprintf(stream:File, format:Format, ...):Int')"); + ObjPtr fprintf = ctx.ExecStr("@fprintf(stream:File, format:FmtChar, ...):Int ::= " + ":Pointer('fprintf(stream:File, format:FmtChar, ...):Int')"); ASSERT_TRUE(fremove); ObjPtr fputc = ctx.ExecStr("@fputc(c:Int, stream:File):Int ::= " ":Pointer('fputc(c:Int, stream:File):Int')"); @@ -583,12 +583,10 @@ TEST(ExecStr, Funcs) { EXPECT_TRUE(ctx.m_runtime->GetNativeAddr("printf")); - ObjPtr p = ctx.ExecStr("printf := :Pointer('printf(format:Format, ...):Int');"); + ObjPtr p = ctx.ExecStr("printf := :Pointer('printf(format:FmtChar, ...):Int');"); ASSERT_TRUE(p); - ASSERT_STREQ("printf=printf(format:Format, ...):Int{}", p->toString().c_str()); - -#ifndef _MSC_VER -#pragma message WARNING("Fail native call from Windows!!!!") + ASSERT_TRUE(p->m_func_ptr); + ASSERT_STREQ("printf=printf(format:FmtChar, ...):Int{}", p->toString().c_str()); typedef int (* printf_type)(const char *, ...); @@ -618,7 +616,6 @@ TEST(ExecStr, Funcs) { ObjPtr result = ctx.ExecStr("hello('Привет, мир!\\n');"); ASSERT_TRUE(result); ASSERT_STREQ("Привет, мир!\n", result->GetValueAsString().c_str()); -#endif } /* @@ -1117,7 +1114,7 @@ TEST(Eval, Iterator) { // * @Tim := :Human(Sex.male, parent=(Tom,)); // * // * Brother(h1, h2) := $h1 != $h2, $h1.sex==male, $h1.parent * $h2.parent; -// * printf := :Native("printf(format:Format, ...):Int"); +// * printf := :Native("printf(format:FmtChar, ...):Int"); // * // * h1 := $?; // * [ h1 ] <<-->> { diff --git a/src/test/nlc_test.cpp b/src/test/nlc_test.cpp index 9a7f6953..1df65e24 100644 --- a/src/test/nlc_test.cpp +++ b/src/test/nlc_test.cpp @@ -129,7 +129,7 @@ TEST(NLC, EvalHelloWorld) { std::string cmd; cmd += "#!./dist/Debug/GNU-Linux/nlc --eval\n"; - cmd += "hello(str='') := { printf := :Pointer('printf(format:Format, ...):Int'); printf('%s', $str); $str;};\n"; + cmd += "hello(str='') := { printf := :Pointer('printf(format:FmtChar, ...):Int'); printf('%s', $str); $str;};\n"; cmd += "hello('Привет, мир!\\n');"; std::filesystem::create_directories("temp"); diff --git a/src/test/parser_test.cpp b/src/test/parser_test.cpp index 23cbc447..f4d58027 100644 --- a/src/test/parser_test.cpp +++ b/src/test/parser_test.cpp @@ -2053,7 +2053,7 @@ TEST_F(ParserTest, MacroDSL) { } TEST_F(ParserTest, HelloWorld) { - ASSERT_TRUE(Parse("hello(str=\"\") := { printf(format:Format, ...):Int := :Pointer('printf'); printf('%s', $1); $str;};")); + ASSERT_TRUE(Parse("hello(str=\"\") := { printf(format:FmtChar, ...):Int := :Pointer('printf'); printf('%s', $1); $str;};")); // ASSERT_STREQ("!!!!!!!!!!!!!!", ast->toString().c_str()); } diff --git a/src/types.h b/src/types.h index 839f20b3..12ae34b0 100644 --- a/src/types.h +++ b/src/types.h @@ -64,6 +64,41 @@ class Interrupt : public std::exception { void NewLangSignalHandler(int signal); + +struct Docs; +typedef std::shared_ptr DocPtr; + +struct Docs { + + static std::multimap m_docs; + + std::string index; + std::string text; + + Docs(std::string body) { + size_t pos = body.find("\n"); + size_t pos2 = body.find("\n\n"); + if (pos != std::string::npos && pos == pos2) { + // Индексируемый заголовок должен быть первой строкой и отделаться пустой строкой от остального текста + index = body.substr(0, pos); + text = body.substr(pos + 2); + } else { + text = body; + } + } + + static DocPtr Build(std::string body) { + return std::make_shared(body); + } + + static DocPtr Append(std::string body, const std::string func=""){ + DocPtr result = Build(body); + m_docs.insert(std::pair(func,result)); + return result; + } +}; + + #ifdef __GNUC__ std::string ParserMessage(std::string &buffer, int row, int col, const char *format, ...) __attribute__((format(printf, 4, 5))); @@ -140,9 +175,10 @@ void ParserException(const char *msg, std::string &buffer, int row, int col); \ _(StrChar, 48) \ _(StrWide, 49) \ - _(Format, 50) \ - _(ViewChar, 51) \ - _(ViewWide, 52) \ + _(FmtChar, 50) \ + _(FmtWide, 51) \ + _(ViewChar, 52) \ + _(ViewWide, 53) \ _(String, 55) \ \ _(Iterator, 62) \ @@ -381,7 +417,7 @@ void ParserException(const char *msg, std::string &buffer, int row, int col); inline bool isString(ObjType t) { return t == ObjType::StrChar || t == ObjType::StrWide || t == ObjType::ViewWide || t == ObjType::ViewWide - || t == ObjType::String || t == ObjType::Format; + || t == ObjType::String || t == ObjType::FmtChar || t == ObjType::FmtWide; } inline bool isPlainDataType(ObjType t) { @@ -500,6 +536,39 @@ void ParserException(const char *msg, std::string &buffer, int row, int col); ObjType typeFromString(const std::string type, Context *ctx = nullptr, bool *has_error = nullptr); + inline LLVMTypeRef toLLVMType(ObjType t, bool none_if_error = false) { + switch (t) { + case ObjType::None: + return LLVMVoidType(); + case ObjType::Bool: + return LLVMInt1Type(); + case ObjType::Char: + return LLVMInt8Type(); + case ObjType::Short: + return LLVMInt16Type(); + case ObjType::Int: + return LLVMInt32Type(); + case ObjType::Long: + case ObjType::Integer: + return LLVMInt64Type(); + case ObjType::Float: + case ObjType::Tensor: + return LLVMFloatType(); + case ObjType::Double: + case ObjType::Number: + return LLVMDoubleType(); + + case ObjType::Pointer: + case ObjType::StrChar: + case ObjType::FmtChar: + return LLVMPointerType(LLVMInt8Type(), 0); + case ObjType::StrWide: + case ObjType::FmtWide: + return LLVMPointerType(LLVMInt32Type(), 0); + } + LOG_RUNTIME("Can`t convert type '%s' to LLVM type!", toString(t)); + } + /* * Можно ли привести один тип к другому типу с учетом размера данных * Используется в интепретаторе и при выполнении для выдачи предупреждений diff --git a/src/win/nlc.vcxproj b/src/win/nlc.vcxproj index 1b5d7535..bb7cbece 100644 --- a/src/win/nlc.vcxproj +++ b/src/win/nlc.vcxproj @@ -63,7 +63,7 @@ Application true - ClangCL + v143 Unicode @@ -104,10 +104,11 @@ nlc_unit_test - $(VC_IncludePath);$(WindowsSDK_IncludePath);..;../..;../../..;../../contrib/;../../contrib/googletest/googletest;../../contrib/googletest/googletest/include;../../contrib/Lyra/include;../../contrib/libtorch-win/include;../../contrib/libtorch-win/include/torch/csrc/api/include;../../contrib/tensorboard_logger/include;C:\msys64\usr\include;C:\Program Files\OpenSSL-Win64\include - ..\..\contrib\libffi\win64\lib;..\..\contrib\libtorch-win\lib;$(LibraryPath) + $(VC_IncludePath);$(WindowsSDK_IncludePath);..;../..;../../..;../../contrib/;../../contrib/googletest/googletest;../../contrib/googletest/googletest/include;../../contrib/Lyra/include;../../contrib/libtorch-win/include;../../contrib/libtorch-win/include/torch/csrc/api/include;../../contrib/tensorboard_logger/include;C:\msys64\usr\include;C:\Program Files\OpenSSL-Win64\include;C:\Program Files\LLVM\include\include + ..\..\contrib\libffi\win64\lib;..\..\contrib\libtorch-win\lib;C:\Program Files\LLVM\lib\lib;$(LibraryPath) ..\..\output\ nlc_unit_test + C:\Program Files\LLVM\include\include;C:\msys64\usr\include;$(ExternalIncludePath) @@ -192,7 +193,7 @@ Console true - %(AdditionalLibraryDirectories) + C:\Program Files\LLVM\lib;%(AdditionalLibraryDirectories) Ws2_32.lib;legacy_stdio_definitions.lib;legacy_stdio_wide_specifiers.lib;C:\Program Files\OpenSSL-Win64\lib\libcrypto_static.lib;%(AdditionalDependencies) MSVCRT @@ -220,11 +221,6 @@ - NotUsing - NotUsing - - - NotUsing NotUsing @@ -269,8 +265,7 @@ - - NotUsing + NotUsing From a24db98f8ab3e63ddabb9412bf4145d12f7e310f Mon Sep 17 00:00:00 2001 From: Aleksandr Ryabikov Date: Mon, 18 Jul 2022 17:49:13 +0300 Subject: [PATCH 26/31] =?UTF-8?q?=D0=9F=D0=B5=D1=80=D0=B2=D1=8B=D0=B5=20?= =?UTF-8?q?=D1=82=D0=B5=D1=81=D1=82=D1=8B=20=D0=B4=D0=BB=D1=8F=20=D1=81?= =?UTF-8?q?=D1=80=D0=B0=D0=B2=D0=BD=D0=B5=D0=BD=D0=B8=D1=8F=20=D1=81=D0=BA?= =?UTF-8?q?=D0=BE=D1=80=D0=BE=D1=81=D1=82=D0=B8=20=D0=B2=D1=8B=D0=BF=D0=BE?= =?UTF-8?q?=D0=BB=D0=BD=D0=B5=D0=BD=D0=B8=D1=8F=20=D0=B4=D0=BB=D1=8F=20?= =?UTF-8?q?=D0=BA=D0=BE=D0=B4=D0=B0=20=D0=A1++=20=D0=B8=20Python=20=D0=9C?= =?UTF-8?q?=D0=BD=D0=BE=D0=B3=D0=BE=20=D0=BF=D1=80=D0=B0=D0=B2=D0=BE=D0=BA?= =?UTF-8?q?=20=D0=B1=D0=B0=D0=B3=D0=BE=D0=B2=20=D0=B4=D0=BB=D1=8F=20=D1=80?= =?UTF-8?q?=D0=B0=D0=B1=D0=BE=D1=82=D1=8B=20=D1=82=D0=B5=D1=81=D1=82=D0=BE?= =?UTF-8?q?=D0=B2=20(=D0=BA=D0=BE=D0=BD=D0=B2=D0=B5=D1=80=D1=82=D0=B8?= =?UTF-8?q?=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D0=B5=20=D1=82=D0=B8=D0=BF?= =?UTF-8?q?=D0=BE=D0=B2,=20=D1=81=D0=B8=D0=BC=D0=B2=D0=BE=D0=BB=D1=8B=20?= =?UTF-8?q?=D0=B8=20=D1=81=D1=82=D1=80=D0=BE=D0=BA=D0=B8,=20=D1=81=D0=BE?= =?UTF-8?q?=D0=BE=D0=B1=D1=89=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=BE=D0=B1=20?= =?UTF-8?q?=D0=BE=D1=88=D0=B8=D0=B1=D0=BA=D0=B0=D1=85=20=D0=B2=20=D0=BB?= =?UTF-8?q?=D0=B5=D0=BA=D1=81=D0=B5=D1=80=D0=B5)=20=D0=9A=D0=BE=D0=BC?= =?UTF-8?q?=D0=BC=D0=B8=D1=82=20=D0=BF=D0=B5=D1=80=D0=B5=D0=B4=20=D1=80?= =?UTF-8?q?=D0=B5=D1=84=D0=B0=D0=BA=D1=82=D0=BE=D1=80=D0=B8=D0=BD=D0=B3?= =?UTF-8?q?=D0=BE=D0=BC=20=D1=85=D1=80=D0=B0=D0=BD=D0=B5=D0=BD=D0=B8=D1=8F?= =?UTF-8?q?=20=D1=81=D0=BA=D0=B0=D0=BB=D1=8F=D1=80=D0=BE=D0=B2=20=D0=B2=20?= =?UTF-8?q?=D0=BD=D0=B0=D1=82=D0=B8=D0=B2=D0=BD=D0=BE=D0=BC=20=D0=B2=D0=B8?= =?UTF-8?q?=D0=B4=D0=B5,=20=D0=B0=20=D0=BD=D0=B5=20=D0=B2=20=D1=82=D0=B5?= =?UTF-8?q?=D0=BD=D0=B7=D0=BE=D1=80=D0=B5.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/context.cpp | 84 ++++---- src/context.h | 5 + src/lexer.h | 66 ++++--- src/nbproject/Makefile-Debug.mk | 6 + src/nbproject/Makefile-Debug_LLVM.mk | 6 + src/nbproject/Makefile-GCOV.mk | 6 + src/nbproject/Makefile-LLVM.mk | 6 + src/nbproject/Makefile-LLVM_GCC.mk | 6 + src/nbproject/Makefile-Release.mk | 6 + src/nbproject/Makefile-UnitTest-Win32.mk | 6 + src/nbproject/Makefile-UnitTest-Win64.mk | 6 + src/nbproject/Makefile-UnitTest.mk | 6 + src/nbproject/Makefile-UnitTest_LLVM.mk | 6 + src/nbproject/configurations.xml | 159 +++++++++++++++ src/newlang.h | 16 +- src/object.cpp | 90 ++++++--- src/object.h | 104 ++++++---- src/parser.cpp | 3 +- src/pch.h | 4 +- src/test/compiler_test.cpp | 15 ++ src/test/eval_test.cpp | 242 ++++++++++++----------- src/test/object_test.cpp | 44 ++--- src/test/speed_test.cpp | 140 +++++++++++++ 23 files changed, 732 insertions(+), 300 deletions(-) create mode 100644 src/test/speed_test.cpp diff --git a/src/context.cpp b/src/context.cpp index 73a2f0e7..2a99588f 100644 --- a/src/context.cpp +++ b/src/context.cpp @@ -52,9 +52,19 @@ const char * Interrupt::RunTime = ":ErrorRunTime"; const char * Interrupt::Signal = ":ErrorSignal"; const char * Interrupt::Abort = ":ErrorAbort"; -Context::Context(RuntimePtr global) { +Context::Context(RuntimePtr global) : m_llvm_builder(LLVMCreateBuilder()) { m_runtime = global; + LLVMInitializeCore(LLVMGetGlobalPassRegistry()); + + /* program init */ + LLVMInitializeNativeTarget(); + LLVMInitializeNativeAsmPrinter(); + LLVMInitializeNativeAsmParser(); + LLVMLinkInMCJIT(); + // Загружает символы исполняемого файла для поиска с помощью SearchForAddressOfSymbol + LLVMLoadLibraryPermanently(nullptr); + if(Context::m_funcs.empty()) { VERIFY(CreateBuiltin("min(arg, ...)", (void *) &min, ObjType::PureFunc)); @@ -611,7 +621,12 @@ ObjPtr Context::CREATE_OR_ASSIGN(Context *ctx, const TermPtr &term, Obj *local_v } else if(list_term[i]->getTermID() == TermID::NONE) { // Skip } else { - list_obj[i]->SetValue_(rval); + if(list_term[i]->Right()) { + ASSERT(list_term[i]->Right()->GetTokenID() == TermID::INDEX); + list_obj[i]->index_set_(MakeIndex(ctx, list_term[i]->Right(), local_vars), rval); + } else { + list_obj[i]->SetValue_(rval); + } if(list_obj[i]->m_var_type_current == ObjType::Function && (rval->m_var_type_current == ObjType::BLOCK || rval->m_var_type_current == ObjType::BLOCK_TRY)) { list_obj[i]->m_var_type_current = ObjType::EVAL_FUNCTION; } @@ -755,7 +770,7 @@ ObjPtr Context::eval_WHILE(Context *ctx, const TermPtr &term, Obj * args) { try { - LOG_DEBUG("result %s", result->toString().c_str()); + // LOG_DEBUG("result %s", result->toString().c_str()); result = CreateRVal(ctx, term->Right(), args, false); cond = Eval(ctx, term->Left(), args, false); @@ -980,7 +995,7 @@ ObjPtr Context::op_NE(Context *ctx, const TermPtr &term, Obj * args) { ASSERT(term->Left()); ASSERT(term->Right()); - return Eval(ctx, term->Left(), args)->operator!=(Eval(ctx, term->Right(), args)) ? Obj::Yes() : Obj::No(); + return Eval(ctx, term->Left(), args)->op_equal(Eval(ctx, term->Right(), args)) ? Obj::No() : Obj::Yes(); } ObjPtr Context::op_LT(Context *ctx, const TermPtr &term, Obj * args) { @@ -1481,7 +1496,7 @@ ObjPtr Context::CreateNative(TermPtr proto, const char *module, bool lazzy, cons result->m_var_type_fixed = type; // Тип определен и не может измениться в дальнейшем *const_cast (&result->m_func_proto) = proto; -// result->m_func_abi = abi; + // result->m_func_abi = abi; if(mangle_name) { result->m_func_mangle_name = mangle_name; @@ -1520,25 +1535,25 @@ std::string RunTime::GetLastErrorMessage() { } void *RunTime::GetNativeAddr(const char *name, const char *module) { -// if(module && module[0]) { -// if(m_modules.find(module) == m_modules.end()) { -// LoadModule(module, false, nullptr); -// } -// if(m_modules.find(module) == m_modules.end()) { -// LOG_WARNING("Fail load module '%s'!", module); -// -// return nullptr; -// } -// -////#ifndef _MSC_VER -// -// return GetDirectAddressFromLibrary(m_modules[module]->GetHandle(), name); -////#else -// //return static_cast (::GetProcAddress(m_modules[module]->GetHandle(), name)); -////#endif -// } - -//#ifndef _MSC_VER + // if(module && module[0]) { + // if(m_modules.find(module) == m_modules.end()) { + // LoadModule(module, false, nullptr); + // } + // if(m_modules.find(module) == m_modules.end()) { + // LOG_WARNING("Fail load module '%s'!", module); + // + // return nullptr; + // } + // + ////#ifndef _MSC_VER + // + // return GetDirectAddressFromLibrary(m_modules[module]->GetHandle(), name); + ////#else + // //return static_cast (::GetProcAddress(m_modules[module]->GetHandle(), name)); + ////#endif + // } + + //#ifndef _MSC_VER // ASSERT(m_llvm_engine); // LOG_DEBUG("getAddressToGlobalIfAvailable( %s ) = %ld", "var_long", m_llvm_engine->getAddressToGlobalIfAvailable("var_long")); @@ -1565,13 +1580,13 @@ void *RunTime::GetNativeAddr(const char *name, const char *module) { //m_llvm_engine->getPointerToNamedFunction(name, false); return GetDirectAddressFromLibrary(nullptr, name); // return ::dlsym(::dlopen(nullptr, RTLD_NOW | RTLD_GLOBAL), name); -//#else -// void *result = static_cast (::GetProcAddress(GetModuleHandle(nullptr), name)); + //#else + // void *result = static_cast (::GetProcAddress(GetModuleHandle(nullptr), name)); //if(result) { - // return result; -// } - // return static_cast (::GetProcAddress((HMODULE) m_msys, name)); -//#endif + // return result; + // } + // return static_cast (::GetProcAddress((HMODULE) m_msys, name)); + //#endif } void Context::CleanUp() { @@ -1618,11 +1633,10 @@ ObjPtr Context::FindTerm(const std::string name) { } if(!result) { - return GetObject(name.c_str()); + result = GetObject(name.c_str()); } - if(result || isLocalAny(name.c_str()) || isLocal(name)) { - + if(result && (isLocalAny(name.c_str()) || isLocal(name))) { return result; } return FindGlobalTerm(name); @@ -2118,7 +2132,7 @@ ObjPtr Context::CreateRVal(Context *ctx, TermPtr term, Obj * local_vars, bool in } args = Obj::CreateDict(); - for (int64_t i = 0; i < static_cast(term->size()); i++) { + for (int64_t i = 0; i < static_cast (term->size()); i++) { if((*term)[i].second->GetTokenID() == TermID::FILLING) { @@ -2219,7 +2233,7 @@ ObjPtr Context::CreateRVal(Context *ctx, TermPtr term, Obj * local_vars, bool in temp = ctx->GetTerm(term->GetFullName().c_str(), term->isRef()); if(!temp) { - LOG_RUNTIME("Term '%s' not found!", term->GetFullName().c_str()); + NL_PARSER(term, "Term '%s' not found!", term->GetFullName().c_str()); } args = Obj::CreateDict(); diff --git a/src/context.h b/src/context.h index dcdaac53..db665ec3 100644 --- a/src/context.h +++ b/src/context.h @@ -138,6 +138,9 @@ namespace newlang { static std::map m_builtin_calls; static Parser::MacrosStore m_macros; ///< Хотя макросы и могут обработываться в рантайме, но доступны они только для парсера + + LLVMBuilderRef m_llvm_builder; + static void Reset() { m_types.clear(); m_funcs.clear(); @@ -249,6 +252,8 @@ namespace newlang { Variable m_global_terms; virtual ~Context() { + LLVMDisposeBuilder(m_llvm_builder); + m_llvm_builder = nullptr; } ObjPtr GetTerm(const std::string name, bool is_ref); diff --git a/src/lexer.h b/src/lexer.h index 08343cbe..1258e37f 100644 --- a/src/lexer.h +++ b/src/lexer.h @@ -4,10 +4,12 @@ -#define YY_FATAL_ERROR(msg) newlang::Scanner::FatalError(msg, yy_c_buf_p, lineno()) +//#define YY_FATAL_ERROR(msg) newlang::Scanner::FatalError(msg, lineno(), yyleng, *source_string) // Flex expects the signature of yylex to be defined in the macro YY_DECL, and // the C++ parser expects it to be declared. We can factor both as follows. +#define YY_USER_INIT m_loc = yylloc + #define YY_DECL \ newlang::parser::token_type \ newlang::Scanner::lex( \ @@ -26,40 +28,42 @@ namespace newlang { -/** Scanner is a derived class to add some extra function to the scanner - * class. Flex itself creates a class named yyFlexLexer, which is renamed using - * macros to ExampleFlexLexer. However we change the context of the generated - * yylex() function to be contained within the Scanner class. This is required - * because the yylex() defined in ExampleFlexLexer has no parameters. */ -class Scanner : public NewLangFlexLexer { -public: - /** Create a new scanner object. The streams arg_yyin and arg_yyout default - * to cin and cout, but that assignment is only made when initializing in - * yylex(). */ - Scanner(std::istream* arg_yyin = &std::cin, - std::ostream* arg_yyout = &std::cout, - std::shared_ptr source = nullptr); + /** Scanner is a derived class to add some extra function to the scanner + * class. Flex itself creates a class named yyFlexLexer, which is renamed using + * macros to ExampleFlexLexer. However we change the context of the generated + * yylex() function to be contained within the Scanner class. This is required + * because the yylex() defined in ExampleFlexLexer has no parameters. */ + class Scanner : public NewLangFlexLexer { + public: + /** Create a new scanner object. The streams arg_yyin and arg_yyout default + * to cin and cout, but that assignment is only made when initializing in + * yylex(). */ + Scanner(std::istream* arg_yyin = &std::cin, + std::ostream* arg_yyout = &std::cout, + std::shared_ptr source = nullptr); - /** Required for virtual functions */ - virtual ~Scanner(); + /** Required for virtual functions */ + virtual ~Scanner(); - std::shared_ptr source_string; - std::string buffer; - /** This is the main lexing function. It is generated by flex according to - * the macro declaration YY_DECL above. The generated bison parser then - * calls this virtual function to fetch new tokens. */ - virtual parser::token_type lex( - TermPtr * yylval, - parser::location_type* yylloc - ); + std::shared_ptr source_string; + parser::location_type* m_loc; + std::string buffer; + /** This is the main lexing function. It is generated by flex according to + * the macro declaration YY_DECL above. The generated bison parser then + * calls this virtual function to fetch new tokens. */ + virtual parser::token_type lex( + TermPtr * yylval, + parser::location_type* yylloc + ); - /** Enable debug output (via arg_yyout) if compiled into the scanner. */ - void set_debug(bool b); + /** Enable debug output (via arg_yyout) if compiled into the scanner. */ + void set_debug(bool b); - static void FatalError(const char* msg, const char *position, int line) { - LOG_RUNTIME("%s near \'%s\' at line %d", msg, position, line); - } -}; + void LexerError(const char* msg) override { + LOG_RUNTIME("%s", newlang::ParserMessage(buffer, m_loc->begin.line, m_loc->begin.column, "%s", msg).c_str()); + // LOG_RUNTIME("%s near \'%s\' at line %d", msg, position, line); + } + }; } diff --git a/src/nbproject/Makefile-Debug.mk b/src/nbproject/Makefile-Debug.mk index 6ad02c2a..14d5bab8 100644 --- a/src/nbproject/Makefile-Debug.mk +++ b/src/nbproject/Makefile-Debug.mk @@ -55,6 +55,7 @@ OBJECTFILES= \ ${OBJECTDIR}/test/nlc_test.o \ ${OBJECTDIR}/test/object_test.o \ ${OBJECTDIR}/test/parser_test.o \ + ${OBJECTDIR}/test/speed_test.o \ ${OBJECTDIR}/variable.o \ ${OBJECTDIR}/version.o @@ -238,6 +239,11 @@ ${OBJECTDIR}/test/parser_test.o: test/parser_test.cpp pch.h.gch ${RM} "$@.d" $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I. -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/parser_test.o test/parser_test.cpp +${OBJECTDIR}/test/speed_test.o: test/speed_test.cpp pch.h.gch + ${MKDIR} -p ${OBJECTDIR}/test + ${RM} "$@.d" + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I. -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/speed_test.o test/speed_test.cpp + : types.h pch.h.gch @echo Выполнение шага пользовательского сборки diff --git a/src/nbproject/Makefile-Debug_LLVM.mk b/src/nbproject/Makefile-Debug_LLVM.mk index 99fc3383..1c4b1f72 100644 --- a/src/nbproject/Makefile-Debug_LLVM.mk +++ b/src/nbproject/Makefile-Debug_LLVM.mk @@ -55,6 +55,7 @@ OBJECTFILES= \ ${OBJECTDIR}/test/nlc_test.o \ ${OBJECTDIR}/test/object_test.o \ ${OBJECTDIR}/test/parser_test.o \ + ${OBJECTDIR}/test/speed_test.o \ ${OBJECTDIR}/variable.o \ ${OBJECTDIR}/version.o @@ -205,6 +206,11 @@ ${OBJECTDIR}/test/parser_test.o: test/parser_test.cpp ${RM} "$@.d" $(COMPILE.cc) -g -O2 -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I. -I.. -I/usr/lib/llvm-13/lib/clang/13.0.1/include -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/parser_test.o test/parser_test.cpp +${OBJECTDIR}/test/speed_test.o: test/speed_test.cpp + ${MKDIR} -p ${OBJECTDIR}/test + ${RM} "$@.d" + $(COMPILE.cc) -g -O2 -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I. -I.. -I/usr/lib/llvm-13/lib/clang/13.0.1/include -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/speed_test.o test/speed_test.cpp + ${OBJECTDIR}/variable.o: variable.cpp ${MKDIR} -p ${OBJECTDIR} ${RM} "$@.d" diff --git a/src/nbproject/Makefile-GCOV.mk b/src/nbproject/Makefile-GCOV.mk index 1db05382..db994638 100644 --- a/src/nbproject/Makefile-GCOV.mk +++ b/src/nbproject/Makefile-GCOV.mk @@ -56,6 +56,7 @@ OBJECTFILES= \ ${OBJECTDIR}/test/nlc_test.o \ ${OBJECTDIR}/test/object_test.o \ ${OBJECTDIR}/test/parser_test.o \ + ${OBJECTDIR}/test/speed_test.o \ ${OBJECTDIR}/variable.o \ ${OBJECTDIR}/version.o @@ -213,6 +214,11 @@ ${OBJECTDIR}/test/parser_test.o: test/parser_test.cpp ${RM} "$@.d" $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/parser_test.o test/parser_test.cpp +${OBJECTDIR}/test/speed_test.o: test/speed_test.cpp + ${MKDIR} -p ${OBJECTDIR}/test + ${RM} "$@.d" + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/speed_test.o test/speed_test.cpp + ${OBJECTDIR}/variable.o: variable.cpp ${MKDIR} -p ${OBJECTDIR} ${RM} "$@.d" diff --git a/src/nbproject/Makefile-LLVM.mk b/src/nbproject/Makefile-LLVM.mk index d17db5ef..5021b3c2 100644 --- a/src/nbproject/Makefile-LLVM.mk +++ b/src/nbproject/Makefile-LLVM.mk @@ -56,6 +56,7 @@ OBJECTFILES= \ ${OBJECTDIR}/test/nlc_test.o \ ${OBJECTDIR}/test/object_test.o \ ${OBJECTDIR}/test/parser_test.o \ + ${OBJECTDIR}/test/speed_test.o \ ${OBJECTDIR}/variable.o \ ${OBJECTDIR}/version.o @@ -213,6 +214,11 @@ ${OBJECTDIR}/test/parser_test.o: test/parser_test.cpp ${RM} "$@.d" $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I/usr/lib/llvm-12/lib/clang/12.0.1/include -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I.. -std=c++14 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/parser_test.o test/parser_test.cpp +${OBJECTDIR}/test/speed_test.o: test/speed_test.cpp + ${MKDIR} -p ${OBJECTDIR}/test + ${RM} "$@.d" + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I/usr/lib/llvm-12/lib/clang/12.0.1/include -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I.. -std=c++14 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/speed_test.o test/speed_test.cpp + ${OBJECTDIR}/variable.o: variable.cpp ${MKDIR} -p ${OBJECTDIR} ${RM} "$@.d" diff --git a/src/nbproject/Makefile-LLVM_GCC.mk b/src/nbproject/Makefile-LLVM_GCC.mk index f9c7b92e..8e780e3d 100644 --- a/src/nbproject/Makefile-LLVM_GCC.mk +++ b/src/nbproject/Makefile-LLVM_GCC.mk @@ -56,6 +56,7 @@ OBJECTFILES= \ ${OBJECTDIR}/test/nlc_test.o \ ${OBJECTDIR}/test/object_test.o \ ${OBJECTDIR}/test/parser_test.o \ + ${OBJECTDIR}/test/speed_test.o \ ${OBJECTDIR}/variable.o \ ${OBJECTDIR}/version.o @@ -213,6 +214,11 @@ ${OBJECTDIR}/test/parser_test.o: test/parser_test.cpp ${RM} "$@.d" $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I.. -std=c++14 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/parser_test.o test/parser_test.cpp +${OBJECTDIR}/test/speed_test.o: test/speed_test.cpp + ${MKDIR} -p ${OBJECTDIR}/test + ${RM} "$@.d" + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I.. -std=c++14 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/speed_test.o test/speed_test.cpp + ${OBJECTDIR}/variable.o: variable.cpp ${MKDIR} -p ${OBJECTDIR} ${RM} "$@.d" diff --git a/src/nbproject/Makefile-Release.mk b/src/nbproject/Makefile-Release.mk index 9985de75..c16fa408 100644 --- a/src/nbproject/Makefile-Release.mk +++ b/src/nbproject/Makefile-Release.mk @@ -56,6 +56,7 @@ OBJECTFILES= \ ${OBJECTDIR}/test/nlc_test.o \ ${OBJECTDIR}/test/object_test.o \ ${OBJECTDIR}/test/parser_test.o \ + ${OBJECTDIR}/test/speed_test.o \ ${OBJECTDIR}/variable.o \ ${OBJECTDIR}/version.o @@ -199,6 +200,11 @@ ${OBJECTDIR}/test/parser_test.o: test/parser_test.cpp ${RM} "$@.d" $(COMPILE.cc) -O3 -Werror -I.. -std=c++14 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/parser_test.o test/parser_test.cpp +${OBJECTDIR}/test/speed_test.o: test/speed_test.cpp + ${MKDIR} -p ${OBJECTDIR}/test + ${RM} "$@.d" + $(COMPILE.cc) -O3 -Werror -I.. -std=c++14 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/speed_test.o test/speed_test.cpp + ${OBJECTDIR}/variable.o: variable.cpp ${MKDIR} -p ${OBJECTDIR} ${RM} "$@.d" diff --git a/src/nbproject/Makefile-UnitTest-Win32.mk b/src/nbproject/Makefile-UnitTest-Win32.mk index 52673741..67654f07 100644 --- a/src/nbproject/Makefile-UnitTest-Win32.mk +++ b/src/nbproject/Makefile-UnitTest-Win32.mk @@ -56,6 +56,7 @@ OBJECTFILES= \ ${OBJECTDIR}/test/nlc_test.o \ ${OBJECTDIR}/test/object_test.o \ ${OBJECTDIR}/test/parser_test.o \ + ${OBJECTDIR}/test/speed_test.o \ ${OBJECTDIR}/variable.o \ ${OBJECTDIR}/version.o @@ -240,6 +241,11 @@ ${OBJECTDIR}/test/parser_test.o: test/parser_test.cpp pch.h.gch ${RM} "$@.d" $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -I/usr/lib/llvm-13/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/parser_test.o test/parser_test.cpp +${OBJECTDIR}/test/speed_test.o: test/speed_test.cpp pch.h.gch + ${MKDIR} -p ${OBJECTDIR}/test + ${RM} "$@.d" + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -I/usr/lib/llvm-13/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/speed_test.o test/speed_test.cpp + : types.h pch.h.gch @echo Выполнение шага пользовательского сборки diff --git a/src/nbproject/Makefile-UnitTest-Win64.mk b/src/nbproject/Makefile-UnitTest-Win64.mk index 4e17d1f0..b22985b8 100644 --- a/src/nbproject/Makefile-UnitTest-Win64.mk +++ b/src/nbproject/Makefile-UnitTest-Win64.mk @@ -56,6 +56,7 @@ OBJECTFILES= \ ${OBJECTDIR}/test/nlc_test.o \ ${OBJECTDIR}/test/object_test.o \ ${OBJECTDIR}/test/parser_test.o \ + ${OBJECTDIR}/test/speed_test.o \ ${OBJECTDIR}/variable.o \ ${OBJECTDIR}/version.o @@ -240,6 +241,11 @@ ${OBJECTDIR}/test/parser_test.o: test/parser_test.cpp pch.h.gch ${RM} "$@.d" $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch-win/include/torch/csrc/api/include -I../contrib/libtorch-win/include -I../contrib/tensorboard_logger/include -I/usr/share/mingw-w64/include/ -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/parser_test.o test/parser_test.cpp +${OBJECTDIR}/test/speed_test.o: test/speed_test.cpp pch.h.gch + ${MKDIR} -p ${OBJECTDIR}/test + ${RM} "$@.d" + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch-win/include/torch/csrc/api/include -I../contrib/libtorch-win/include -I../contrib/tensorboard_logger/include -I/usr/share/mingw-w64/include/ -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/speed_test.o test/speed_test.cpp + : types.h pch.h.gch @echo Выполнение шага пользовательского сборки diff --git a/src/nbproject/Makefile-UnitTest.mk b/src/nbproject/Makefile-UnitTest.mk index e35cb0da..97f451d6 100644 --- a/src/nbproject/Makefile-UnitTest.mk +++ b/src/nbproject/Makefile-UnitTest.mk @@ -56,6 +56,7 @@ OBJECTFILES= \ ${OBJECTDIR}/test/nlc_test.o \ ${OBJECTDIR}/test/object_test.o \ ${OBJECTDIR}/test/parser_test.o \ + ${OBJECTDIR}/test/speed_test.o \ ${OBJECTDIR}/variable.o \ ${OBJECTDIR}/version.o @@ -243,6 +244,11 @@ ${OBJECTDIR}/test/parser_test.o: test/parser_test.cpp pch.h.gch ${RM} "$@.d" $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I. -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -I/usr/lib/llvm-13/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/parser_test.o test/parser_test.cpp +${OBJECTDIR}/test/speed_test.o: test/speed_test.cpp pch.h.gch + ${MKDIR} -p ${OBJECTDIR}/test + ${RM} "$@.d" + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I. -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -I/usr/lib/llvm-13/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/speed_test.o test/speed_test.cpp + : types.h pch.h.gch @echo Выполнение шага пользовательского сборки diff --git a/src/nbproject/Makefile-UnitTest_LLVM.mk b/src/nbproject/Makefile-UnitTest_LLVM.mk index a94fa374..ceb783cd 100644 --- a/src/nbproject/Makefile-UnitTest_LLVM.mk +++ b/src/nbproject/Makefile-UnitTest_LLVM.mk @@ -56,6 +56,7 @@ OBJECTFILES= \ ${OBJECTDIR}/test/nlc_test.o \ ${OBJECTDIR}/test/object_test.o \ ${OBJECTDIR}/test/parser_test.o \ + ${OBJECTDIR}/test/speed_test.o \ ${OBJECTDIR}/variable.o \ ${OBJECTDIR}/version.o @@ -211,6 +212,11 @@ ${OBJECTDIR}/test/parser_test.o: test/parser_test.cpp ${RM} "$@.d" $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I. -I.. -I/usr/lib/llvm-13/lib/clang/13.0.1/include -I/usr/include/llvm-c-13 -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/parser_test.o test/parser_test.cpp +${OBJECTDIR}/test/speed_test.o: test/speed_test.cpp + ${MKDIR} -p ${OBJECTDIR}/test + ${RM} "$@.d" + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I. -I.. -I/usr/lib/llvm-13/lib/clang/13.0.1/include -I/usr/include/llvm-c-13 -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/speed_test.o test/speed_test.cpp + ${OBJECTDIR}/variable.o: variable.cpp ${MKDIR} -p ${OBJECTDIR} ${RM} "$@.d" diff --git a/src/nbproject/configurations.xml b/src/nbproject/configurations.xml index 4856d1c4..2da62ba2 100644 --- a/src/nbproject/configurations.xml +++ b/src/nbproject/configurations.xml @@ -11,7 +11,13 @@ displayName="Исходные файлы" projectFiles="true"> + ../examples/_run.sh + ../examples/dsl.nlp ../examples/fileio.nlp + ../examples/foreach.nlp + ../examples/fraction.nlp + ../examples/speed_test.nlp + ../examples/speed_test.py test/alg_test.cpp @@ -22,6 +28,7 @@ test/nlc_test.cpp test/object_test.cpp test/parser_test.cpp + test/speed_test.cpp builtin.cpp context.cpp @@ -182,8 +189,20 @@ + + + + + + + + + + + + @@ -350,6 +369,11 @@ pch.h.gch + + + pch.h.gch + + pch.h.gch @@ -467,8 +491,20 @@ + + + + + + + + + + + + @@ -579,6 +615,8 @@ + + @@ -654,8 +692,20 @@ + + + + + + + + + + + + @@ -739,6 +789,8 @@ + + @@ -844,8 +896,20 @@ syntax_help.cpp + + + + + + + + + + + + @@ -1012,6 +1076,11 @@ pch.h.gch + + + pch.h.gch + + pch.h.gch @@ -1134,8 +1203,20 @@ + + + + + + + + + + + + @@ -1246,6 +1327,8 @@ + + @@ -1344,8 +1427,20 @@ + + + + + + + + + + + + @@ -1456,6 +1551,8 @@ + + @@ -1582,8 +1679,20 @@ + + + + + + + + + + + + @@ -1694,6 +1803,8 @@ + + @@ -1816,8 +1927,20 @@ + + + + + + + + + + + + @@ -1928,6 +2051,8 @@ + + @@ -2039,8 +2164,20 @@ + + + + + + + + + + + + @@ -2207,6 +2344,11 @@ pch.h.gch + + + pch.h.gch + + pch.h.gch @@ -2323,8 +2465,20 @@ + + + + + + + + + + + + @@ -2491,6 +2645,11 @@ pch.h.gch + + + pch.h.gch + + pch.h.gch diff --git a/src/newlang.h b/src/newlang.h index df2b0eee..d9dd63b8 100644 --- a/src/newlang.h +++ b/src/newlang.h @@ -41,24 +41,13 @@ namespace newlang { return str; } -// class Context; + // class Context; struct CompileInfo; class RunTime { public: RunTime() { - - LLVMInitializeCore(LLVMGetGlobalPassRegistry()); - - /* program init */ - LLVMInitializeNativeTarget(); - LLVMInitializeNativeAsmPrinter(); - LLVMInitializeNativeAsmParser(); - LLVMLinkInMCJIT(); - - // Загружает символы исполняемого файла для поиска с помощью SearchForAddressOfSymbol - LLVMLoadLibraryPermanently(nullptr); } virtual ~RunTime() { @@ -90,9 +79,8 @@ namespace newlang { public: RunTime(const RunTime&) = delete; const RunTime& operator=(const RunTime&) = delete; - + }; - struct CompileInfo { BuiltInTorchDirect * m_builtin_direct; diff --git a/src/object.cpp b/src/object.cpp index 368814fd..a6c6e7e3 100644 --- a/src/object.cpp +++ b/src/object.cpp @@ -226,22 +226,30 @@ Variable::PairType & Obj::at(int64_t index) { } const ObjPtr Obj::index_get(const std::vector &index) const { - if(m_var_type_current == ObjType::StrChar) { + if(m_var_type_current == ObjType::StrChar || m_var_type_current == ObjType::FmtChar) { if(index.size() != 1 || !index[0].is_integer()) { LOG_RUNTIME("The index must be an integer value '%s'!", IndexToString(index).c_str()); } - if(index[0].integer() < static_cast (m_str.size())) { - return CreateString(std::string(1, m_str[index[0].integer()])); + int64_t pos = index[0].integer(); + if(pos < 0) { + pos = m_str.size() + pos; // Позиция с конца строки + } + if(pos < static_cast (m_str.size())) { + return CreateString(std::string(1, m_str[pos])); } LOG_RUNTIME("Index '%s' not exists in byte string '%s'!", IndexToString(index).c_str(), m_str.c_str()); - } else if(m_var_type_current == ObjType::StrWide) { + } else if(m_var_type_current == ObjType::StrWide || m_var_type_current == ObjType::FmtWide) { if(index.size() != 1 || !index[0].is_integer()) { LOG_RUNTIME("The index must be an integer value '%s'!", IndexToString(index).c_str()); } - if(index[0].integer() < static_cast (m_wstr.size())) { - return CreateString(std::wstring(1, m_wstr[index[0].integer()])); + int64_t pos = index[0].integer(); + if(pos < 0) { + pos = m_wstr.size() + pos; // Позиция с конца строки } - LOG_RUNTIME("Index '%s' not exists in byte string '%s'!", IndexToString(index).c_str(), "WIDE"); + if(pos < static_cast (m_wstr.size())) { + return CreateString(std::wstring(1, m_wstr[pos])); + } + LOG_RUNTIME("Index '%s' not exists in WIDE string '%s'!", IndexToString(index).c_str(), utf8_encode(m_wstr).c_str()); } else if(is_tensor()) { torch::Tensor t = m_value.index(index); @@ -259,9 +267,13 @@ ObjPtr Obj::index_set_(const std::vector &index, const ObjPtr value) { if(index.size() != 1 || !index[0].is_integer()) { LOG_RUNTIME("The index must be an integer value '%s'!", IndexToString(index).c_str()); } - if(index[0].integer() < static_cast (m_str.size())) { - m_str.erase(index[0].integer(), 1); - m_str.insert(index[0].integer(), value->toType(ObjType::StrChar)->m_str); + int64_t pos = index[0].integer(); + if(pos < 0) { + pos = m_str.size() + pos; // Позиция с конца строки + } + if(pos < static_cast (m_str.size())) { + m_str.erase(pos, 1); + m_str.insert(pos, value->toType(ObjType::StrChar)->m_str); m_var_is_init = true; return shared(); } @@ -270,9 +282,13 @@ ObjPtr Obj::index_set_(const std::vector &index, const ObjPtr value) { if(index.size() != 1 || !index[0].is_integer()) { LOG_RUNTIME("The index must be an integer value '%s'!", IndexToString(index).c_str()); } - if(index[0].integer() < static_cast (m_wstr.size())) { - m_wstr.erase(index[0].integer(), 1); - m_wstr.insert(index[0].integer(), value->toType(ObjType::StrWide)->m_wstr); + int64_t pos = index[0].integer(); + if(pos < 0) { + pos = m_str.size() + pos; // Позиция с конца строки + } + if(pos < static_cast (m_wstr.size())) { + m_wstr.erase(pos, 1); + m_wstr.insert(pos, value->toType(ObjType::StrWide)->m_wstr); m_var_is_init = true; return shared(); } @@ -942,9 +958,11 @@ std::string Obj::GetValueAsString() const { return TensorToString(m_value); case ObjType::StrChar: + case ObjType::FmtChar: return m_str; case ObjType::StrWide: + case ObjType::FmtWide: return utf8_encode(m_wstr); case ObjType::NativeFunc: @@ -1184,8 +1202,11 @@ void Obj::ConvertToArgs_(Obj *in, bool check_valid, Context * ctx) { } ObjType limit_type = (*in)[i].second->getTypeAsLimit(); if(!canCast(limit_type, base_type)) { - LOG_RUNTIME("Fail cast value '%s' to type '%s'", - (*in)[i].second->toString().c_str(), (*m_func_proto)[i].second->m_type_name.c_str()); + // Строку с одним символом можно преобразовать в арифметичсекий тип + if(!(isArithmeticType(base_type) && (*in)[i].second->is_string_type() && (*in)[i].second->size() == 1)) { + LOG_RUNTIME("Fail cast value '%s' to type '%s'", + (*in)[i].second->toString().c_str(), (*m_func_proto)[i].second->m_type_name.c_str()); + } } } at(i).second->op_assign((*in)[i].second); @@ -2026,8 +2047,14 @@ ObjPtr Obj::CallNative(Context *ctx, Obj args) { ObjType type = args[i].second->getTypeAsLimit(); if(pind < check_count) { NL_CHECK(!(*m_func_proto)[pind].second->m_type_name.empty(), "Undefined type arg '%s'", (*m_func_proto)[pind].second->toString().c_str()); - NL_CHECK(canCast(type, typeFromString((*m_func_proto)[pind].second->m_type_name, ctx)), "Fail cast from '%s' to '%s'", - (*m_func_proto)[pind].second->m_type_name.c_str(), newlang::toString(type)); + + ObjType proto_type = typeFromString((*m_func_proto)[pind].second->m_type_name, ctx); + if(!canCast(type, proto_type)) { + if(!((type == ObjType::StrChar || type == ObjType::FmtChar) && proto_type == ObjType::Char) || + ((type == ObjType::StrWide || type == ObjType::FmtWide) && proto_type == ObjType::Int)) { + LOG_RUNTIME("Fail cast from '%s' to '%s'", (*m_func_proto)[pind].second->m_type_name.c_str(), newlang::toString(type)); + } + } } ObjType check_type; @@ -2042,6 +2069,16 @@ ObjPtr Obj::CallNative(Context *ctx, Obj args) { pointer_exist = true; } + if(check_type == ObjType::Bool && m_namespace.empty()) { + // В чистом С (для пустого m_namespace) для логического типа используется тип int + check_type = ObjType::Int; + } + if((check_type == ObjType::FmtWide || check_type == ObjType::StrWide) || + ((check_type == ObjType::FmtChar || check_type == ObjType::StrChar) && + (args[i].second->getType() == ObjType::StrWide || args[i].second->getType() == ObjType::FmtWide))) { + LOG_RUNTIME("Convert wide characters as native function arguments not supported!"); + } + LLVMTypeRef temp = toLLVMType(check_type); arg_types.push_back(temp); arg_generic.push_back(args[i].second->GetGenericValueRef(temp)); @@ -2053,11 +2090,6 @@ ObjPtr Obj::CallNative(Context *ctx, Obj args) { } } - - LLVMInitializeNativeTarget(); - LLVMInitializeNativeAsmPrinter(); - LLVMInitializeNativeAsmParser(); - auto module = LLVMModuleCreateWithName("call_native"); LLVMExecutionEngineRef interpreter; LLVMCreateExecutionEngineForModule(&interpreter, module, nullptr); @@ -2070,8 +2102,7 @@ ObjPtr Obj::CallNative(Context *ctx, Obj args) { // Create the code block of the function bar auto entry = LLVMAppendBasicBlock(wrap, "entry"); - auto builder = LLVMCreateBuilder(); - LLVMPositionBuilderAtEnd(builder, entry); + LLVMPositionBuilderAtEnd(ctx->m_llvm_builder, entry); @@ -2084,10 +2115,10 @@ ObjPtr Obj::CallNative(Context *ctx, Obj args) { // LLVMValueRef param_call[] = {LLVMGetParam(wrap, 0)}; LLVMValueRef func_call = LLVMAddFunction(module, "m_func_ptr", func_res_type); // Имя функции может пересечся с сужествующими при связывании????? - LLVMValueRef func_ret = LLVMBuildCall2(builder, func_res_type, func_call, args_param.data(), static_cast (args_param.size()), m_func_proto->m_text.c_str()); + LLVMValueRef func_ret = LLVMBuildCall2(ctx->m_llvm_builder, func_res_type, func_call, args_param.data(), static_cast (args_param.size()), m_func_proto->m_text.c_str()); //return value - LLVMBuildRet(builder, func_ret); + LLVMBuildRet(ctx->m_llvm_builder, func_ret); char *error = nullptr; @@ -2103,7 +2134,7 @@ ObjPtr Obj::CallNative(Context *ctx, Obj args) { #ifdef UNITTEST char *dump = LLVMPrintValueToString(wrap); - LOG_INFO("LLVM DUMP %s:\n%s\r\r", toString().c_str(), dump); + LOG_DEBUG("LLVM DUMP %s:\n%s\r\r", toString().c_str(), dump); LLVMDisposeMessage(dump); #endif @@ -2140,11 +2171,6 @@ ObjPtr Obj::CallNative(Context *ctx, Obj args) { for (auto &elem : arg_generic) { LLVMDisposeGenericValue(elem); } - - LLVMDisposeBuilder(builder); - // LLVMDisposeExecutionEngine(engine); - // LLVMDisposeModule(module); - return result; } diff --git a/src/object.h b/src/object.h index ca8dcb50..75e0aa90 100755 --- a/src/object.h +++ b/src/object.h @@ -981,14 +981,14 @@ namespace newlang { return false; } - inline ObjPtr operator==(ObjPtr obj) { - ASSERT(obj); - return operator==(*obj); - } - - inline ObjPtr operator==(Obj obj) { - return op_equal(obj) ? Obj::Yes() : Obj::No(); - } + // inline ObjPtr operator==(ObjPtr obj) { + // ASSERT(obj); + // return operator==(*obj); + // } + // + // inline ObjPtr operator==(Obj obj) { + // return op_equal(obj) ? Obj::Yes() : Obj::No(); + // } bool op_equal(Obj & value); inline bool op_accurate(ObjPtr obj) { @@ -997,14 +997,14 @@ namespace newlang { } bool op_accurate(Obj & value); - inline ObjPtr operator!=(ObjPtr obj) { - ASSERT(obj); - return operator!=(*obj); - } - - inline ObjPtr operator!=(Obj obj) { - return op_equal(obj) ? Obj::No() : Obj::Yes(); - } + // inline ObjPtr operator!=(ObjPtr obj) { + // ASSERT(obj); + // return operator!=(*obj); + // } + // + // inline ObjPtr operator!=(Obj obj) { + // return op_equal(obj) ? Obj::No() : Obj::Yes(); + // } inline ObjPtr op_bit_and(ObjPtr obj, bool strong) { ASSERT(obj); @@ -1245,9 +1245,15 @@ namespace newlang { return m_fraction->GetAsInteger(); case ObjType::StrWide: - return std::stoll(m_wstr); + case ObjType::FmtWide: + if (m_wstr.size() == 1) { + return m_wstr[0]; + } case ObjType::StrChar: - return std::stoll(m_str); + case ObjType::FmtChar: + if (m_str.size() == 1) { + return m_str[0]; + } default: if (m_var_type_current == ObjType::Pointer || m_var_type_fixed == ObjType::Pointer) { return reinterpret_cast (m_func_ptr); @@ -1268,13 +1274,8 @@ namespace newlang { ASSERT(m_fraction); return m_fraction->GetAsNumber(); - case ObjType::StrWide: - return std::stod(m_wstr); - case ObjType::StrChar: - return std::stod(m_str); - default: - if (is_simple()) { + if (is_simple() || is_string_type()) { return static_cast (GetValueAsInteger()); } } @@ -1323,17 +1324,32 @@ namespace newlang { } LLVMGenericValueRef GetGenericValueRef(LLVMTypeRef type) { - if (is_integer() || is_bool_type()) { + if (type == LLVMInt1Type() || type == LLVMInt8Type() || type == LLVMInt16Type() || type == LLVMInt32Type() || type == LLVMInt64Type()) { return LLVMCreateGenericValueOfInt(type, GetValueAsInteger(), true); - } else if (is_floating()) { + } else if (type == LLVMFloatType() || type == LLVMDoubleType()) { return LLVMCreateGenericValueOfFloat(type, GetValueAsNumber()); - } else if (getType() == ObjType::StrChar || getType() == ObjType::FmtChar) { - return LLVMCreateGenericValueOfPointer((void *) m_str.c_str()); - } else if (getType() == ObjType::StrWide) { - return LLVMCreateGenericValueOfPointer((void *) m_wstr.c_str()); - } else if (getType() == ObjType::Pointer) { - return LLVMCreateGenericValueOfPointer(m_func_ptr); + } else if (type == LLVMPointerType(LLVMInt8Type(), 0)) { + if (getType() == ObjType::StrChar || getType() == ObjType::FmtChar) { + return LLVMCreateGenericValueOfPointer((void *) m_str.c_str()); + } else if (getType() == ObjType::Pointer) { + return LLVMCreateGenericValueOfPointer(m_func_ptr); + } + } else if (type == LLVMPointerType(LLVMInt32Type(), 0)) { + if (getType() == ObjType::StrWide || getType() == ObjType::FmtWide) { + return LLVMCreateGenericValueOfPointer((void *) m_wstr.c_str()); + } } + // if (is_integer() || is_bool_type()) { + // return LLVMCreateGenericValueOfInt(type, GetValueAsInteger(), true); + // } else if (is_floating()) { + // return LLVMCreateGenericValueOfFloat(type, GetValueAsNumber()); + // } else if (getType() == ObjType::StrChar || getType() == ObjType::FmtChar) { + // return LLVMCreateGenericValueOfPointer((void *) m_str.c_str()); + // } else if (getType() == ObjType::StrWide) { + // return LLVMCreateGenericValueOfPointer((void *) m_wstr.c_str()); + // } else if (getType() == ObjType::Pointer) { + // return LLVMCreateGenericValueOfPointer(m_func_ptr); + // } LOG_RUNTIME("Not support LLVM type '%s'", newlang::toString(m_var_type_current)); } @@ -1346,10 +1362,20 @@ namespace newlang { return Obj::CreateValue(value, type); } else if (isFloatingType(type)) { return Obj::CreateValue((double) LLVMGenericValueToFloat(llvm_type, ref), type); - } else if (type == ObjType::StrChar) { - return Obj::CreateString(std::string((const char *) LLVMGenericValueToPointer(ref))); - } else if (type == ObjType::StrWide) { - return Obj::CreateString(std::wstring((const wchar_t *)LLVMGenericValueToPointer(ref))); + } else if (type == ObjType::StrChar || type == ObjType::FmtChar) { + if (llvm_type == LLVMInt8Type()) { + return Obj::CreateString(std::string(1, (char) LLVMGenericValueToInt(ref, false))); + } else { + //@todo Нужна проверка на тип LLVM данных? + return Obj::CreateString(std::string((const char *) LLVMGenericValueToPointer(ref))); + } + } else if (type == ObjType::StrWide || type == ObjType::FmtWide) { + if (llvm_type == LLVMInt32Type()) { + return Obj::CreateString(std::wstring(1, (wchar_t) LLVMGenericValueToInt(ref, false))); + } else { + //@todo Нужна проверка на тип LLVM данных? + return Obj::CreateString(std::wstring((const wchar_t *)LLVMGenericValueToPointer(ref))); + } } else if (type == ObjType::Pointer) { ObjPtr result = Obj::CreateType(type, ObjType::None, true); @@ -1952,10 +1978,12 @@ namespace newlang { switch (m_var_type_current) { case ObjType::None: case ObjType::StrChar: - SetValue_(value->m_str); + case ObjType::FmtChar: + SetValue_(value->GetValueAsString()); return; case ObjType::StrWide: - SetValue_(value->m_wstr); + case ObjType::FmtWide: + SetValue_(value->GetValueAsStringWide()); return; } diff --git a/src/parser.cpp b/src/parser.cpp index 74982932..e560c19c 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -107,7 +107,6 @@ std::string newlang::ParserMessage(std::string &buffer, int row, int col, const message += " col "; message += std::to_string(col); message += "\n"; - row--; } // Ищем нужную строку @@ -123,7 +122,7 @@ std::string newlang::ParserMessage(std::string &buffer, int row, int col, const std::string tmp = buffer.substr((pos ? pos + 1 : pos), buffer.find("\n", pos + 1)); tmp = tmp.substr(0, tmp.find("\n", col)); - if(row + 1) { // Если переданы координаты ошибки, показываем место + if(row) { // Если переданы координаты ошибки, показываем место // Лексер обрабатывает строки в байтах, а вывод в UTF8 // поэтому позиция ошибки лексера може не совпадать для многобайтных символов diff --git a/src/pch.h b/src/pch.h index 68aae7e7..dc2eba01 100644 --- a/src/pch.h +++ b/src/pch.h @@ -61,10 +61,12 @@ #include #include "warning_pop.h" -#include "types.h" #undef LOG_RUNTIME #define LOG_RUNTIME(format, ...) LOG_EXCEPT(newlang::Interrupt, format, ##__VA_ARGS__) +#include "types.h" + + #endif // NEWLANG_PCH_H_ diff --git a/src/test/compiler_test.cpp b/src/test/compiler_test.cpp index 222bb507..e1d394f8 100644 --- a/src/test/compiler_test.cpp +++ b/src/test/compiler_test.cpp @@ -41,6 +41,10 @@ TEST(Compiler, MangleName) { EXPECT_STREQ("newlang_maks", MangleName("макс").c_str()) << MangleName("макс"); } +void test_void_func() { +} +int test_void_val = 0; + TEST(LLVM, Symbols) { auto rt = RunTime::Init(); @@ -49,6 +53,17 @@ TEST(LLVM, Symbols) { EXPECT_TRUE(LLVMSearchForAddressOfSymbol("printf")); EXPECT_TRUE(LLVMSearchForAddressOfSymbol("fopen")); + EXPECT_FALSE(LLVMSearchForAddressOfSymbol("test_void_func")); + EXPECT_FALSE(LLVMSearchForAddressOfSymbol("test_void_val")); + + LLVMAddSymbol("test_void_func", (void *) &test_void_func); + LLVMAddSymbol("test_void_val", &test_void_val); + + EXPECT_TRUE(LLVMSearchForAddressOfSymbol("test_void_func")); + EXPECT_TRUE(LLVMSearchForAddressOfSymbol("test_void_val")); + + EXPECT_EQ(&test_void_func, LLVMSearchForAddressOfSymbol("test_void_func")); + EXPECT_EQ(&test_void_val, LLVMSearchForAddressOfSymbol("test_void_val")); } diff --git a/src/test/eval_test.cpp b/src/test/eval_test.cpp index 10ea5ad8..3dd42245 100644 --- a/src/test/eval_test.cpp +++ b/src/test/eval_test.cpp @@ -26,10 +26,9 @@ using namespace newlang; //if invoking the linker via the clang-cl frontend), you can opt in to this behaviour by adding the lld specific option -lldmingw //, which enables a number of MinGW-specific behaviours in lld. -extern "C" int64_t var_long; //, export_name("var_long") __attribute__ ((visibility("default"))) int64_t var_long = 987654321; -extern "C" int64_t func_export(int64_t arg_long, uint8_t arg_byte) { // __attribute__ ((visibility("default"))) +int64_t func_export(int64_t arg_long, uint8_t arg_byte) { return arg_long + arg_byte; } @@ -100,119 +99,124 @@ TEST(Eval, Assign) { list = ctx.ExecStr("$"); ASSERT_STREQ("$=('var_str', 'var_num',)", list->toString().c_str()); -// var_long = 987654321; -// ObjPtr var_export = ctx.ExecStr("var_export := :Pointer(\"var_long:Long\")"); -// ASSERT_TRUE(var_export); -// ASSERT_TRUE(var_export->is_tensor()) << var_export; -// ASSERT_EQ(var_export->getType(), ObjType::Long); -// ASSERT_STREQ("var_export=987654321", var_export->toString().c_str()); -// var_long = 123132132; -// ASSERT_STREQ("var_export=123132132", var_export->toString().c_str()); -// var_export->SetValue_(Obj::CreateValue(59875, ObjType::None)); -// ASSERT_EQ(59875, var_long); -// -// list = ctx.ExecStr("$"); -// ASSERT_STREQ("$=('var_str', 'var_num', 'var_export',)", list->toString().c_str()); -// -// ObjPtr func_export = ctx.ExecStr("func_export := :Pointer(\"func_export(arg1:Long, arg2:Char=100):Long\")"); -// ASSERT_TRUE(func_export); -// ASSERT_TRUE(func_export->is_function()) << func_export; -// ASSERT_EQ(func_export->getType(), ObjType::NativeFunc); -// ASSERT_STREQ("func_export=func_export(arg1:Long, arg2:Char=100):Long{}", func_export->toString().c_str()); -// -// ObjPtr result = func_export->Call(&ctx, Obj::Arg(200), Obj::Arg(10)); -// ASSERT_TRUE(result); -// ASSERT_EQ(210, result->GetValueAsInteger()); -// -// result = func_export->Call(&ctx, Obj::Arg(10), Obj::Arg(10)); -// ASSERT_TRUE(result); -// ASSERT_EQ(20, result->GetValueAsInteger()); -// -// result = func_export->Call(&ctx, Obj::Arg(10)); -// ASSERT_TRUE(result); -// ASSERT_EQ(110, result->GetValueAsInteger()); -// -// // Переполнение второго аргумента -// ASSERT_ANY_THROW(func_export->Call(&ctx, Obj::Arg(1000), Obj::Arg(1000))); -// -// list = ctx.ExecStr("$"); -// ASSERT_STREQ("$=('var_str', 'var_num', 'var_export', 'func_export',)", list->toString().c_str()); -// -// var_num.reset(); -// func_export.reset(); -// -// list = ctx.ExecStr("$"); -// ASSERT_STREQ("$=('var_str', 'var_export',)", list->toString().c_str()); -// -// // Функция возвращает словарь с именами объектов в текущем контексте -// ObjPtr func_eval = ctx.ExecStr("func_eval(arg1, arg2) := {$;}"); -// ASSERT_TRUE(func_eval); -// ASSERT_TRUE(func_eval->is_function()) << func_eval; -// ASSERT_EQ(func_eval->getType(), ObjType::EVAL_FUNCTION) << toString(func_eval->getType()); -// ASSERT_STREQ("func_eval=func_eval(arg1, arg2):={$;}", func_eval->toString().c_str()); -// -// ObjPtr result_eval = func_eval->Call(&ctx, Obj::Arg(200), Obj::Arg(10)); -// ASSERT_TRUE(result_eval); -// ASSERT_STREQ("$=('$0', 'arg1', 'arg2', 'var_str', 'var_export', 'func_eval',)", result_eval->toString().c_str()); -// -// list = ctx.ExecStr("$"); -// ASSERT_STREQ("$=('var_str', 'var_export', 'func_eval',)", list->toString().c_str()); -// -// -// ObjPtr dict1 = ctx.ExecStr("(10, 2, 3, 4, )"); -// ASSERT_TRUE(dict1); -// ASSERT_EQ(ObjType::Dictionary, dict1->m_var_type_current) << toString(dict1->m_var_type_current); -// ASSERT_EQ(ObjType::None, dict1->m_var_type_fixed) << toString(dict1->m_var_type_fixed); -// ASSERT_EQ(4, dict1->size()); -// ASSERT_STREQ("(10, 2, 3, 4,)", dict1->toString().c_str()); -// -// ObjPtr dict2 = ctx.ExecStr("( (10, 2, 3, 4, (1,2,), ), (10, 2, 3, 4, ),)"); -// ASSERT_TRUE(dict2); -// ASSERT_EQ(ObjType::Dictionary, dict2->m_var_type_current) << toString(dict2->m_var_type_current); -// ASSERT_EQ(ObjType::None, dict2->m_var_type_fixed) << toString(dict2->m_var_type_fixed); -// ASSERT_EQ(2, dict2->size()); -// ASSERT_STREQ("((10, 2, 3, 4, (1, 2,),), (10, 2, 3, 4,),)", dict2->toString().c_str()); -// -// ObjPtr tensor = ctx.ExecStr("[1,1,0,0,]"); -// ASSERT_TRUE(tensor); -// ASSERT_EQ(ObjType::Bool, tensor->m_var_type_current) << toString(tensor->m_var_type_current); -// ASSERT_EQ(ObjType::None, tensor->m_var_type_fixed) << toString(tensor->m_var_type_fixed); -// ASSERT_EQ(1, tensor->m_value.dim()); -// ASSERT_EQ(4, tensor->m_value.size(0)); -// ASSERT_EQ(1, tensor->index_get({0})->GetValueAsInteger()); -// ASSERT_EQ(1, tensor->index_get({1})->GetValueAsInteger()); -// ASSERT_EQ(0, tensor->index_get({2})->GetValueAsInteger()); -// ASSERT_EQ(0, tensor->index_get({3})->GetValueAsInteger()); -// -// ASSERT_STREQ("[1, 1, 0, 0,]:Bool", tensor->GetValueAsString().c_str()); -// -// ObjPtr tensor2 = ctx.ExecStr("[222,333,3333,]"); -// ASSERT_TRUE(tensor2); -// ASSERT_STREQ("[222, 333, 3333,]:Short", tensor2->GetValueAsString().c_str()); -// -// ObjPtr tensorf = ctx.ExecStr("[1.2, 0.22, 0.69,]"); -// ASSERT_TRUE(tensorf); -// ASSERT_STREQ("[1.2, 0.22, 0.69,]:Double", tensorf->GetValueAsString().c_str()); -// -// ObjPtr tensor_all = ctx.ExecStr("[ [1, 1, 0, 0,], [10, 10, 0.1, 0.2,], ]"); -// ASSERT_TRUE(tensor_all); -// ASSERT_EQ(ObjType::Double, tensor_all->m_var_type_current) << toString(tensor_all->m_var_type_current); -// ASSERT_EQ(ObjType::None, tensor_all->m_var_type_fixed) << toString(tensor_all->m_var_type_fixed); -// ASSERT_EQ(2, tensor_all->m_value.dim()); -// ASSERT_EQ(2, tensor_all->m_value.size(0)); -// ASSERT_EQ(4, tensor_all->m_value.size(1)); -// -// ASSERT_STREQ("1", tensor_all->index_get({0, 0})->GetValueAsString().c_str()); -// ASSERT_STREQ("1", tensor_all->index_get({0, 1})->GetValueAsString().c_str()); -// ASSERT_STREQ("0", tensor_all->index_get({0, 2})->GetValueAsString().c_str()); -// ASSERT_STREQ("0", tensor_all->index_get({0, 3})->GetValueAsString().c_str()); -// -// ASSERT_STREQ("10", tensor_all->index_get({1, 0})->GetValueAsString().c_str()); -// ASSERT_STREQ("10", tensor_all->index_get({1, 1})->GetValueAsString().c_str()); -// ASSERT_STREQ("0.1", tensor_all->index_get({1, 2})->GetValueAsString().c_str()); -// ASSERT_STREQ("0.2", tensor_all->index_get({1, 3})->GetValueAsString().c_str()); -// -// ASSERT_STREQ("[\n [1, 1, 0, 0,], [10, 10, 0.1, 0.2,],\n]:Double", tensor_all->GetValueAsString().c_str()); + + LLVMAddSymbol("var_long", &var_long); + LLVMAddSymbol("func_export", (void *) &func_export); + + + var_long = 987654321; + ObjPtr var_export = ctx.ExecStr("var_export := :Pointer(\"var_long:Long\")"); + ASSERT_TRUE(var_export); + ASSERT_TRUE(var_export->is_tensor()) << var_export; + ASSERT_EQ(var_export->getType(), ObjType::Long); + ASSERT_STREQ("var_export=987654321", var_export->toString().c_str()); + var_long = 123132132; + ASSERT_STREQ("var_export=123132132", var_export->toString().c_str()); + var_export->SetValue_(Obj::CreateValue(59875, ObjType::None)); + ASSERT_EQ(59875, var_long); + + list = ctx.ExecStr("$"); + ASSERT_STREQ("$=('var_str', 'var_num', 'var_export',)", list->toString().c_str()); + + ObjPtr func_export = ctx.ExecStr("func_export := :Pointer(\"func_export(arg1:Long, arg2:Char=100):Long\")"); + ASSERT_TRUE(func_export); + ASSERT_TRUE(func_export->is_function()) << func_export; + ASSERT_EQ(func_export->getType(), ObjType::NativeFunc); + ASSERT_STREQ("func_export=func_export(arg1:Long, arg2:Char=100):Long{}", func_export->toString().c_str()); + + ObjPtr result = func_export->Call(&ctx, Obj::Arg(200), Obj::Arg(10)); + ASSERT_TRUE(result); + ASSERT_EQ(210, result->GetValueAsInteger()); + + result = func_export->Call(&ctx, Obj::Arg(10), Obj::Arg(10)); + ASSERT_TRUE(result); + ASSERT_EQ(20, result->GetValueAsInteger()); + + result = func_export->Call(&ctx, Obj::Arg(10)); + ASSERT_TRUE(result); + ASSERT_EQ(110, result->GetValueAsInteger()); + + // Переполнение второго аргумента + ASSERT_ANY_THROW(func_export->Call(&ctx, Obj::Arg(1000), Obj::Arg(1000))); + + list = ctx.ExecStr("$"); + ASSERT_STREQ("$=('var_str', 'var_num', 'var_export', 'func_export',)", list->toString().c_str()); + + var_num.reset(); + func_export.reset(); + + list = ctx.ExecStr("$"); + ASSERT_STREQ("$=('var_str', 'var_export',)", list->toString().c_str()); + + // Функция возвращает словарь с именами объектов в текущем контексте + ObjPtr func_eval = ctx.ExecStr("func_eval(arg1, arg2) := {$;}"); + ASSERT_TRUE(func_eval); + ASSERT_TRUE(func_eval->is_function()) << func_eval; + ASSERT_EQ(func_eval->getType(), ObjType::EVAL_FUNCTION) << toString(func_eval->getType()); + ASSERT_STREQ("func_eval=func_eval(arg1, arg2):={$;}", func_eval->toString().c_str()); + + ObjPtr result_eval = func_eval->Call(&ctx, Obj::Arg(200), Obj::Arg(10)); + ASSERT_TRUE(result_eval); + ASSERT_STREQ("$=('$0', 'arg1', 'arg2', 'var_str', 'var_export', 'func_eval',)", result_eval->toString().c_str()); + + list = ctx.ExecStr("$"); + ASSERT_STREQ("$=('var_str', 'var_export', 'func_eval',)", list->toString().c_str()); + + + ObjPtr dict1 = ctx.ExecStr("(10, 2, 3, 4, )"); + ASSERT_TRUE(dict1); + ASSERT_EQ(ObjType::Dictionary, dict1->m_var_type_current) << toString(dict1->m_var_type_current); + ASSERT_EQ(ObjType::None, dict1->m_var_type_fixed) << toString(dict1->m_var_type_fixed); + ASSERT_EQ(4, dict1->size()); + ASSERT_STREQ("(10, 2, 3, 4,)", dict1->toString().c_str()); + + ObjPtr dict2 = ctx.ExecStr("( (10, 2, 3, 4, (1,2,), ), (10, 2, 3, 4, ),)"); + ASSERT_TRUE(dict2); + ASSERT_EQ(ObjType::Dictionary, dict2->m_var_type_current) << toString(dict2->m_var_type_current); + ASSERT_EQ(ObjType::None, dict2->m_var_type_fixed) << toString(dict2->m_var_type_fixed); + ASSERT_EQ(2, dict2->size()); + ASSERT_STREQ("((10, 2, 3, 4, (1, 2,),), (10, 2, 3, 4,),)", dict2->toString().c_str()); + + ObjPtr tensor = ctx.ExecStr("[1,1,0,0,]"); + ASSERT_TRUE(tensor); + ASSERT_EQ(ObjType::Bool, tensor->m_var_type_current) << toString(tensor->m_var_type_current); + ASSERT_EQ(ObjType::None, tensor->m_var_type_fixed) << toString(tensor->m_var_type_fixed); + ASSERT_EQ(1, tensor->m_value.dim()); + ASSERT_EQ(4, tensor->m_value.size(0)); + ASSERT_EQ(1, tensor->index_get({0})->GetValueAsInteger()); + ASSERT_EQ(1, tensor->index_get({1})->GetValueAsInteger()); + ASSERT_EQ(0, tensor->index_get({2})->GetValueAsInteger()); + ASSERT_EQ(0, tensor->index_get({3})->GetValueAsInteger()); + + ASSERT_STREQ("[1, 1, 0, 0,]:Bool", tensor->GetValueAsString().c_str()); + + ObjPtr tensor2 = ctx.ExecStr("[222,333,3333,]"); + ASSERT_TRUE(tensor2); + ASSERT_STREQ("[222, 333, 3333,]:Short", tensor2->GetValueAsString().c_str()); + + ObjPtr tensorf = ctx.ExecStr("[1.2, 0.22, 0.69,]"); + ASSERT_TRUE(tensorf); + ASSERT_STREQ("[1.2, 0.22, 0.69,]:Double", tensorf->GetValueAsString().c_str()); + + ObjPtr tensor_all = ctx.ExecStr("[ [1, 1, 0, 0,], [10, 10, 0.1, 0.2,], ]"); + ASSERT_TRUE(tensor_all); + ASSERT_EQ(ObjType::Double, tensor_all->m_var_type_current) << toString(tensor_all->m_var_type_current); + ASSERT_EQ(ObjType::None, tensor_all->m_var_type_fixed) << toString(tensor_all->m_var_type_fixed); + ASSERT_EQ(2, tensor_all->m_value.dim()); + ASSERT_EQ(2, tensor_all->m_value.size(0)); + ASSERT_EQ(4, tensor_all->m_value.size(1)); + + ASSERT_STREQ("1", tensor_all->index_get({0, 0})->GetValueAsString().c_str()); + ASSERT_STREQ("1", tensor_all->index_get({0, 1})->GetValueAsString().c_str()); + ASSERT_STREQ("0", tensor_all->index_get({0, 2})->GetValueAsString().c_str()); + ASSERT_STREQ("0", tensor_all->index_get({0, 3})->GetValueAsString().c_str()); + + ASSERT_STREQ("10", tensor_all->index_get({1, 0})->GetValueAsString().c_str()); + ASSERT_STREQ("10", tensor_all->index_get({1, 1})->GetValueAsString().c_str()); + ASSERT_STREQ("0.1", tensor_all->index_get({1, 2})->GetValueAsString().c_str()); + ASSERT_STREQ("0.2", tensor_all->index_get({1, 3})->GetValueAsString().c_str()); + + ASSERT_STREQ("[\n [1, 1, 0, 0,], [10, 10, 0.1, 0.2,],\n]:Double", tensor_all->GetValueAsString().c_str()); } TEST(Eval, Tensor) { @@ -613,9 +617,13 @@ TEST(ExecStr, Funcs) { ASSERT_TRUE(hello); ASSERT_STREQ("hello=hello(str=''):={printf('%s', $str); $str;}", hello->toString().c_str()); - ObjPtr result = ctx.ExecStr("hello('Привет, мир!\\n');"); + ObjPtr result = ctx.ExecStr("printf('%s%d\\n', 'Привет, мир!', 2);"); + ASSERT_TRUE(result); + ASSERT_TRUE(result->GetValueAsInteger() >= 23); + + result = ctx.ExecStr("hello('Привет, мир2!\\n');"); ASSERT_TRUE(result); - ASSERT_STREQ("Привет, мир!\n", result->GetValueAsString().c_str()); + ASSERT_STREQ("Привет, мир2!\n", result->GetValueAsString().c_str()); } /* diff --git a/src/test/object_test.cpp b/src/test/object_test.cpp index b901b415..6e6555d1 100644 --- a/src/test/object_test.cpp +++ b/src/test/object_test.cpp @@ -463,17 +463,9 @@ TEST(ObjTest, CreateFromInteger) { ASSERT_EQ(ObjType::Char, var2->getType()) << toString(var2->getType()); ASSERT_EQ(-123, var2->GetValueAsInteger()); - ASSERT_THROW( - var = Context::CreateRVal(&ctx, Term::Create(TermID::INTEGER, "")), - std::runtime_error); - - ASSERT_THROW( - var = Context::CreateRVal(&ctx, Term::Create(TermID::INTEGER, "lkdfjsha")), - std::runtime_error); - - ASSERT_THROW( - var = Context::CreateRVal(&ctx, Term::Create(TermID::INTEGER, "123lkdfjsha")), - std::runtime_error); + ASSERT_ANY_THROW(Context::CreateRVal(&ctx, Term::Create(TermID::INTEGER, ""))); + ASSERT_ANY_THROW(Context::CreateRVal(&ctx, Term::Create(TermID::INTEGER, "lkdfjsha"))); + ASSERT_ANY_THROW(Context::CreateRVal(&ctx, Term::Create(TermID::INTEGER, "123lkdfjsha"))); } TEST(ObjTest, CreateFromNumber) { @@ -500,17 +492,9 @@ TEST(ObjTest, CreateFromNumber) { ASSERT_EQ(ObjType::Double, var2->getType()); ASSERT_DOUBLE_EQ(-123.123, var2->GetValueAsNumber()); - ASSERT_THROW( - var = Context::CreateRVal(&ctx, Term::Create(TermID::NUMBER, "")), - std::runtime_error); - - ASSERT_THROW( - var = Context::CreateRVal(&ctx, Term::Create(TermID::NUMBER, "lkdfjsha")), - std::runtime_error); - - ASSERT_THROW( - var = Context::CreateRVal(&ctx, Term::Create(TermID::NUMBER, "123lkdfjsha")), - std::runtime_error); + ASSERT_ANY_THROW(Context::CreateRVal(&ctx, Term::Create(TermID::NUMBER, ""))); + ASSERT_ANY_THROW(Context::CreateRVal(&ctx, Term::Create(TermID::NUMBER, "lkdfjsha"))); + ASSERT_ANY_THROW(Context::CreateRVal(&ctx, Term::Create(TermID::NUMBER, "123lkdfjsha"))); } TEST(ObjTest, CreateFromString) { @@ -961,15 +945,15 @@ TEST(ObjTest, Iterator) { ASSERT_TRUE(dict3); ASSERT_EQ(0, dict3->size()); - - - + + + Iterator flt(dict, ""); ObjPtr flt_res = flt.read_and_next(100); ASSERT_TRUE(flt_res); ASSERT_EQ(1, flt_res->size()); ASSERT_EQ(4, flt_res->at(0).second->GetValueAsInteger()); - + Iterator flt1(dict, "."); ObjPtr flt1_res = flt1.read_and_next(100); @@ -990,10 +974,10 @@ TEST(ObjTest, Iterator) { ASSERT_EQ(2, flt3_res->size()); ASSERT_EQ(3, flt3_res->at(0).second->GetValueAsInteger()); ASSERT_EQ(5, flt3_res->at(1).second->GetValueAsInteger()); - - - -// ObjPtr iter1 = dict->MakeIterator(); + + + + // ObjPtr iter1 = dict->MakeIterator(); } diff --git a/src/test/speed_test.cpp b/src/test/speed_test.cpp new file mode 100644 index 00000000..1d58dbe4 --- /dev/null +++ b/src/test/speed_test.cpp @@ -0,0 +1,140 @@ +#include "pch.h" + +#ifdef UNITTEST + +#include +#include +#include + +#include +#include +#include + +using namespace newlang; + +char convert(char c) { + if(c == 'A') return 'C'; + if(c == 'C') return 'G'; + if(c == 'G') return 'T'; + if(c == 'T') return 'A'; + return ' '; +} + +TEST(Speed, CPP) { + + LOG_INFO("Start speed test C++"); + + std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now(); + + std::string opt = "ACGT"; + std::string s = ""; + std::string s_last = ""; + int len_str = 13; + bool change_next; + + for (int i = 0; i < len_str; i++) { + s += opt[0]; + } + + for (int i = 0; i < len_str; i++) { + s_last += opt.back(); + } + + int pos = 0; + int counter = 1; + while(s != s_last) { + counter++; + // You can uncomment the next line to see all k-mers. + //std::cout << s << std::endl; + change_next = true; + for (int i = 0; i < len_str; i++) { + if(change_next) { + if(s[i] == opt.back()) { + s[i] = convert(s[i]); + change_next = true; + } else { + s[i] = convert(s[i]); + i = len_str; // break; + } + } + } + } + + // You can uncomment the next line to see all k-mers. + // cout << s << endl; + std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now(); + int sec = std::chrono::duration_cast(end - begin).count(); + int ms = std::chrono::duration_cast(end - begin).count() % 1000000; + LOG_INFO("Number of generated k-mers: %d at %d.%d sec", counter, sec, ms); + +} + +TEST(Speed, NewLang) { + + Context::Reset(); + Context ctx(RunTime::Init()); + + std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now(); + + setvbuf(stdin, nullptr, _IONBF, 0); + setvbuf(stdout, nullptr, _IONBF, 0); + setvbuf(stderr, nullptr, _IONBF, 0); + + // std::string src; + // src = "@printf := :Pointer('printf(format:FmtChar, ...):Int'); @counter := 1; printf('%d',counter)"; + // ObjPtr test = ctx.ExecStr(src.c_str(), nullptr, true); + // ASSERT_TRUE(test); + // ASSERT_STREQ("0", test->GetValueAsString().c_str()); + + + LLVMAddSymbol("convert", (void *) &convert); + // src = "@test_convert := :Pointer('convert(sym:Char):Char'); test_convert('A')"; + // ObjPtr test = ctx.ExecStr(src.c_str(), nullptr, true); + // ASSERT_TRUE(test); + // ASSERT_STREQ("67", test->GetValueAsString().c_str()); + + utils::Logger::LogLevelType save = utils::Logger::Instance()->SetLogLevel(LOG_LEVEL_INFO); + ObjPtr result = ctx.ExecFile("../examples/speed_test.nlp"); + utils::Logger::Instance()->SetLogLevel(save); + + std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now(); + + + ASSERT_TRUE(result); + ASSERT_TRUE(result->is_string_type()) << result->toString(); + ASSERT_STREQ("OK", result->GetValueAsString().c_str()); + + + int sec = std::chrono::duration_cast(end - begin).count(); + int ms = std::chrono::duration_cast(end - begin).count() % 1000000; + LOG_INFO("Test complete at %d.%d sec", sec, ms); + + /* + * + * Start speed test C++ + * Number of generated k-mers: 67108864 at 2.502049 sec + * + * Start + * Number of generated k-mers: 67108864 + * real 0m33,794s + * + * Start speed test NewLang + * Number of generated k-mers: 67108864 + * Test complete at ???????????????????? + * + * Своя функция @convert + * 5 символов - 1.3 сек (с вывоводм строк) 0.491895 sec - без вывода строк + * 6 символов - 14.789793 sec (с вывоводм строк) 1.898168 sec - без вывода строк + * 7 символов без вывода строк - 7.671152 sec + * 8 символов без вывода строк - 30.412468 sec + * + * Импорт С++ функции convert + * 5 символов - 1.23 сек (с вывоводм строк) 0.53 sec - без вывода строк + * 6 символов - 13.538338 sec (с вывоводм строк) 2.30900 sec - без вывода строк + * 7 символов без вывода строк - 8.43029 sec + * 8 символов без вывода строк - 32.154832 sec + * + */ +} + +#endif // UNITTEST \ No newline at end of file From 21a2b166b92f07fcaa8ca07ece51b5f02bae0fa3 Mon Sep 17 00:00:00 2001 From: Aleksandr Ryabikov Date: Thu, 21 Jul 2022 09:42:56 +0300 Subject: [PATCH 27/31] =?UTF-8?q?=D0=97=D0=B0=D0=B2=D0=B5=D1=80=D1=88?= =?UTF-8?q?=D0=B8=D0=BB=20=D0=BF=D0=B5=D1=80=D0=B5=D0=B2=D0=BE=D0=B4=20?= =?UTF-8?q?=D1=85=D1=80=D0=B0=D0=BD=D0=B5=D0=BD=D0=B8=D1=8F=20=D1=81=D0=BA?= =?UTF-8?q?=D0=B0=D0=BB=D1=8F=D1=80=D0=BE=D0=B2=20=D0=B2=20=D0=BD=D0=B0?= =?UTF-8?q?=D1=82=D0=B8=D0=B2=D0=BD=D0=BE=D0=BC=20=D0=B2=D0=B8=D0=B4=D0=B5?= =?UTF-8?q?.=20=D0=9F=D0=BE=D1=84=D0=B8=D0=BA=D1=81=D0=B8=D0=BB=20=D0=B1?= =?UTF-8?q?=D0=B0=D0=B3=D0=B8=20=D1=81=20=D0=BA=D0=BE=D0=BD=D0=B2=D0=B5?= =?UTF-8?q?=D1=80=D1=82=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D0=B5?= =?UTF-8?q?=D0=BC=20=D1=82=D0=B8=D0=BF=D0=BE=D0=B2=20=D0=B8=20=D1=83=D0=BD?= =?UTF-8?q?=D0=B8=D1=84=D0=B8=D1=86=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BB=20?= =?UTF-8?q?=D1=84=D1=83=D0=BD=D0=BA=D1=86=D0=B8=D0=B8=20=D0=BA=D0=BE=D0=BD?= =?UTF-8?q?=D0=B2=D0=B5=D1=80=D1=82=D0=B0=D1=86=D0=B8=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- contrib/logger/logger.cpp | 2 +- examples/foreach.nlp | 6 +- examples/fraction.nlp | 2 +- examples/speed_test.nlp | 75 ++ examples/speed_test.py | 41 + src/context.cpp | 167 ++- src/context.h | 2 +- src/fraction.h | 58 +- src/nbproject/Makefile-Debug_LLVM.mk | 15 +- src/nbproject/Makefile-UnitTest_LLVM.mk | 81 +- src/nbproject/configurations.xml | 125 +- src/nlc.h | 2 +- src/object.cpp | 1649 ++++++++++------------- src/object.h | 550 +++++--- src/parser.y | 8 + src/pch.h | 1 - src/test/alg_test.cpp | 7 + src/test/eval_test.cpp | 104 +- src/test/object_test.cpp | 62 +- src/test/parser_test.cpp | 7 + src/test/speed_test.cpp | 65 +- src/types.h | 211 +-- 22 files changed, 1659 insertions(+), 1581 deletions(-) create mode 100755 examples/speed_test.nlp create mode 100755 examples/speed_test.py mode change 100755 => 100644 src/object.h diff --git a/contrib/logger/logger.cpp b/contrib/logger/logger.cpp index 84bfe1ba..ab9af44f 100644 --- a/contrib/logger/logger.cpp +++ b/contrib/logger/logger.cpp @@ -140,7 +140,7 @@ EXTERN_C const char * log_printf(uint8_t level, const char *prefix, const char * Logger::Instance()->AddString(level, buffer, false); - if(file && (level != LOG_LEVEL_INFO || Logger::Instance()->GetLogLevel() >= LOG_LEVEL_DEBUG)) { + if(file && (level != LOG_LEVEL_INFO || Logger::Instance()->GetLogLevel() >= LOG_LEVEL_DUMP)) { const char * file_name = strrchr(file, '/'); snprintf(buffer, LOG_MAX_BUFFER_SIZE, " (%s:%d)%s", ((file_name && *file_name == '/') ? file_name + 1 : file), line, nl ? "\n" : ""); diff --git a/examples/foreach.nlp b/examples/foreach.nlp index 0e0d437c..cda266cc 100755 --- a/examples/foreach.nlp +++ b/examples/foreach.nlp @@ -2,9 +2,9 @@ :File ::= :Pointer; -@stdin:File ::= :Pointer("_IO_2_1_stdin_:File"); -@stdout:File ::= :Pointer("_IO_2_1_stdout_:File"); -@stderr:File ::= :Pointer("stderr:File"); +#@stdin:File ::= :Pointer("stdin:File"); +#@stdout:File ::= :Pointer("stdout:File"); +#@stderr:File ::= :Pointer("stderr:File"); @fopen(filename:String, modes:String):File ::= :Pointer("fopen(filename:StrChar, modes:StrChar):File");; @fopen64(filename:String, modes:String):File ::= :Pointer("fopen(filename:StrChar, modes:StrChar):File");; diff --git a/examples/fraction.nlp b/examples/fraction.nlp index e5c5606e..7380ef8e 100755 --- a/examples/fraction.nlp +++ b/examples/fraction.nlp @@ -1,6 +1,6 @@ #!../output/nlc --eval -@var1 := 1234567890_1234567890\1; +@var1 := 12345678901234567865465491/1; @var2 := 100_000_000_000_000_001\1; @var2 *= @var1; diff --git a/examples/speed_test.nlp b/examples/speed_test.nlp new file mode 100755 index 00000000..78f7f927 --- /dev/null +++ b/examples/speed_test.nlp @@ -0,0 +1,75 @@ +#!../output/nlc + +@printf := :Pointer('printf(format:FmtChar, ...):Int'); + +printf('\nStart speed test NewLang\n'); + +@convert := :Pointer('convert(sym:Char):Char'); + +/* +@convert(c) := {{ + [c == 'A'] --> 'C', + [c == 'C'] --> 'G', + [c == 'G'] --> 'T', + [c == 'T'] --> 'A', + [_] --> ' '; +}}; +*/ + + + +@opt := 'ACGT'; + +@s := ''; +@s_last := ''; +@len_str := 5; +@change_next := 0; + +i := 0; +[i < len_str] <<->> { + s += @opt[0]; + i += 1; +}; + +i := 0; +[i < len_str] <<->> { + s_last += opt[-1]; + i += 1; +}; + +printf('From %s to %s\n', s, s_last ); + +@counter := 1; + +[s != s_last] <<->> { + + counter += 1; + #printf('%d\n', counter); + + # You can uncomment the next line to see all k-mers. + # cout << s << endl; + #printf('%s\n', s); + + change_next := 1; + + i := 0; + + [i < len_str] <<->> { + [change_next] --> { + [s[i] == opt[-1]] --> { + s[i] := convert(s[i]); + change_next := 1; + }, + [_] --> { + s[i] := convert(s[i]); + i = len_str; + }; + }; + i += 1; + }; +}; + +printf('Number of generated k-mers: %d\n', counter); +"OK"; + + diff --git a/examples/speed_test.py b/examples/speed_test.py new file mode 100755 index 00000000..5c760570 --- /dev/null +++ b/examples/speed_test.py @@ -0,0 +1,41 @@ +#!/bin/python3 + +def convert(c): + if (c == 'A'): return 'C' + if (c == 'C'): return 'G' + if (c == 'G'): return 'T' + if (c == 'T'): return 'A' + +print("Start") + +opt = "ACGT" +s = "" +s_last = "" +len_str = 13 + +for i in range(len_str): + s += opt[0] + +for i in range(len_str): + s_last += opt[-1] + +pos = 0 +counter = 1 +while (s != s_last): + counter += 1 + # You can uncomment the next line to see all k-mers. + # print(s) + change_next = True + for i in range(len_str): + if (change_next): + if (s[i] == opt[-1]): + s = s[:i] + convert(s[i]) + s[i+1:] + change_next = True + else: + s = s[:i] + convert(s[i]) + s[i+1:] + break + +# You can uncomment the next line to see all k-mers. +# print(s) +print("Number of generated k-mers: {}".format(counter)) + diff --git a/src/context.cpp b/src/context.cpp index 2a99588f..06ac6ed0 100644 --- a/src/context.cpp +++ b/src/context.cpp @@ -183,7 +183,7 @@ bool Context::CreateBuiltin(const char *prototype, void *func, ObjType type) { ASSERT(proto->Left() && !proto->Left()->getText().empty()); ObjPtr obj = Obj::CreateFunc(this, proto->Left(), type, proto->Left()->getText()); - obj->m_func_ptr = func; + obj->m_var = func; obj->m_var_is_init = true; auto found = m_funcs.find(proto->Left()->getText()); @@ -321,7 +321,7 @@ ObjPtr Context::eval_UNKNOWN(Context *ctx, const TermPtr &term, Obj *args) { ObjPtr Context::eval_BLOCK(Context *ctx, const TermPtr &term, Obj *args) { ASSERT(term && term->getTermID() == TermID::BLOCK); ObjPtr obj = Obj::CreateType(ObjType::BLOCK); - obj->m_block_source = term; + obj->m_sequence = term; obj->m_var_is_init = true; if(term->size() && term->at(0).second->IsString()) { @@ -334,7 +334,7 @@ ObjPtr Context::eval_BLOCK(Context *ctx, const TermPtr &term, Obj *args) { ObjPtr Context::eval_BLOCK_TRY(Context *ctx, const TermPtr &term, Obj *args) { ASSERT(term && term->getTermID() == TermID::BLOCK_TRY); ObjPtr obj = Obj::CreateType(ObjType::BLOCK_TRY); - obj->m_block_source = term; + obj->m_sequence = term; obj->m_var_is_init = true; if(term->size() && term->at(0).second->IsString()) { @@ -576,7 +576,7 @@ ObjPtr Context::CREATE_OR_ASSIGN(Context *ctx, const TermPtr &term, Obj *local_v if(term->Right()->getTermID() == TermID::ELLIPSIS) { if(rval->is_dictionary_type() || rval->is_tensor()) { - if(rval->is_scalar()) { + if(!rval->empty() && rval->is_scalar()) { LOG_RUNTIME("Fail expand scalar!"); } for (int i = 0; i < list_obj.size() - 1; i++) { @@ -698,7 +698,7 @@ ObjPtr Context::eval_FUNCTION(Context *ctx, const TermPtr &term, Obj * args) { } lval->m_var_type_fixed = lval->m_var_type_current; lval->m_var_is_init = true; - lval->m_block_source = term->Right(); + lval->m_sequence = term->Right(); } return ctx->RegisterObject(lval); @@ -1493,9 +1493,9 @@ ObjPtr Context::CreateNative(TermPtr proto, const char *module, bool lazzy, cons } result = Obj::CreateType(type); - result->m_var_type_fixed = type; // Тип определен и не может измениться в дальнейшем + result->m_var_type_fixed = ObjType::Pointer; // Тип определен и не может измениться в дальнейшем - *const_cast (&result->m_func_proto) = proto; + *const_cast (&result->m_prototype) = proto; // result->m_func_abi = abi; if(mangle_name) { @@ -1504,16 +1504,49 @@ ObjPtr Context::CreateNative(TermPtr proto, const char *module, bool lazzy, cons if(module) { result->m_module_name = module; } + void * ptr = nullptr; if(lazzy) { - result->m_func_ptr = nullptr; + result->m_var = static_cast (nullptr); } else { - result->m_func_ptr = m_runtime->GetNativeAddr( - result->m_func_mangle_name.empty() ? proto->m_text.c_str() : result->m_func_mangle_name.c_str(), module); + ASSERT(at::holds_alternative(result->m_var)); + + ptr = m_runtime->GetNativeAddr(result->m_func_mangle_name.empty() ? proto->m_text.c_str() : result->m_func_mangle_name.c_str(), module); + + switch(type) { + case ObjType::Bool: + result->m_var = static_cast (ptr); + break; + case ObjType::Char: + result->m_var = static_cast (ptr); + break; + case ObjType::Short: + result->m_var = static_cast (ptr); + break; + case ObjType::Int: + result->m_var = static_cast (ptr); + break; + case ObjType::Long: + result->m_var = static_cast (ptr); + break; + case ObjType::Float: + result->m_var = static_cast (ptr); + break; + case ObjType::Double: + result->m_var = static_cast (ptr); + break; + + case ObjType::NativeFunc: + default: + result->m_var = ptr; + } + // result->m_var = m_runtime->GetNativeAddr( + // result->m_func_mangle_name.empty() ? proto->m_text.c_str() : result->m_func_mangle_name.c_str(), module); + if(result->is_function() || type == ObjType::Pointer) { - NL_CHECK(result->m_func_ptr, "Error getting address '%s' from '%s'!", proto->toString().c_str(), module); - } else if(result->m_func_ptr && result->is_tensor()) { - result->m_value = torch::from_blob(result->m_func_ptr, { - }, toTorchType(type)); + NL_CHECK(at::get(result->m_var), "Error getting address '%s' from '%s'!", proto->toString().c_str(), module); + } else if(ptr && result->is_tensor()) { + // result->m_tensor = torch::from_blob(at::get(result->m_var),{ + // }, toTorchType(type)); result->m_var_is_init = true; } else { @@ -1535,58 +1568,7 @@ std::string RunTime::GetLastErrorMessage() { } void *RunTime::GetNativeAddr(const char *name, const char *module) { - // if(module && module[0]) { - // if(m_modules.find(module) == m_modules.end()) { - // LoadModule(module, false, nullptr); - // } - // if(m_modules.find(module) == m_modules.end()) { - // LOG_WARNING("Fail load module '%s'!", module); - // - // return nullptr; - // } - // - ////#ifndef _MSC_VER - // - // return GetDirectAddressFromLibrary(m_modules[module]->GetHandle(), name); - ////#else - // //return static_cast (::GetProcAddress(m_modules[module]->GetHandle(), name)); - ////#endif - // } - - //#ifndef _MSC_VER - // ASSERT(m_llvm_engine); - - // LOG_DEBUG("getAddressToGlobalIfAvailable( %s ) = %ld", "var_long", m_llvm_engine->getAddressToGlobalIfAvailable("var_long")); - // LOG_DEBUG("getGlobalValueAddress( %s ) = %ld", "var_long", m_llvm_engine->getGlobalValueAddress("var_long")); - // LOG_DEBUG("getPointerToNamedFunction( %s ) = %ld", "var_long", (long)m_llvm_engine->getPointerToNamedFunction("var_long", false)); - // - // LOG_DEBUG("getAddressToGlobalIfAvailable( %s ) = %ld", "_var_long", m_llvm_engine->getAddressToGlobalIfAvailable("_var_long")); - // LOG_DEBUG("getGlobalValueAddress( %s ) = %ld", "_var_long", m_llvm_engine->getGlobalValueAddress("_var_long")); - // LOG_DEBUG("getPointerToNamedFunction( %s ) = %ld", "_var_long", (long)m_llvm_engine->getPointerToNamedFunction("_var_long", false)); - // - // LOG_DEBUG("getAddressToGlobalIfAvailable( %s ) = %ld", "func_export", m_llvm_engine->getAddressToGlobalIfAvailable("func_export")); - // LOG_DEBUG("getGlobalValueAddress( %s ) = %ld", "func_export", m_llvm_engine->getGlobalValueAddress("func_export")); - // LOG_DEBUG("getPointerToNamedFunction( %s ) = %ld", "func_export", (long)m_llvm_engine->getPointerToNamedFunction("func_export", false)); - // - // LOG_DEBUG("getAddressToGlobalIfAvailable( %s ) = %ld", "_func_export", m_llvm_engine->getAddressToGlobalIfAvailable("_func_export")); - // LOG_DEBUG("getGlobalValueAddress( %s ) = %ld", "_func_export", m_llvm_engine->getGlobalValueAddress("_func_export")); - // LOG_DEBUG("getPointerToNamedFunction( %s ) = %ld", "_func_export", (long)m_llvm_engine->getPointerToNamedFunction("_func_export", false)); - // - // - // LOG_DEBUG("getAddressToGlobalIfAvailable( %s ) = %ld", name, m_llvm_engine->getAddressToGlobalIfAvailable(name)); - // LOG_DEBUG("getGlobalValueAddress( %s ) = %ld", name, m_llvm_engine->getGlobalValueAddress(name)); - // LOG_DEBUG("getPointerToNamedFunction( %s ) = %ld", name, (long)m_llvm_engine->getPointerToNamedFunction(name, false)); - - //m_llvm_engine->getPointerToNamedFunction(name, false); return GetDirectAddressFromLibrary(nullptr, name); - // return ::dlsym(::dlopen(nullptr, RTLD_NOW | RTLD_GLOBAL), name); - //#else - // void *result = static_cast (::GetProcAddress(GetModuleHandle(nullptr), name)); - //if(result) { - // return result; - // } - // return static_cast (::GetProcAddress((HMODULE) m_msys, name)); - //#endif } void Context::CleanUp() { @@ -1720,14 +1702,14 @@ ObjPtr Context::CreateLVal(Context *ctx, TermPtr term, Obj * args) { result->m_var_is_init = false; result->m_var_name = term->m_text; - *const_cast (&result->m_func_proto) = term; + *const_cast (&result->m_prototype) = term; TermPtr type = term->GetType(); if(term->IsFunction() || term->getTermID() == TermID::CALL) { result->m_var_type_current = ObjType::Function; result->m_var_type_fixed = result->m_var_type_current; - *const_cast (&result->m_func_proto) = term; + *const_cast (&result->m_prototype) = term; } else if(type) { result->m_var_type_current = typeFromString(type->getText().c_str(), ctx); result->m_var_type_fixed = result->m_var_type_current; @@ -1747,7 +1729,7 @@ ObjPtr Context::CreateLVal(Context *ctx, TermPtr term, Obj * args) { dims.push_back(temp->GetValueAsInteger()); } } - result->m_value = torch::empty(dims, toTorchType(result->m_var_type_current)); + result->m_tensor = torch::empty(dims, toTorchType(result->m_var_type_current)); } } if(!isType(term->m_text)) { @@ -1924,8 +1906,8 @@ std::vector Context::MakeIndex(Context *ctx, TermPtr term, Obj * local_va if(temp->is_scalar()) { result.push_back(Index(temp->GetValueAsInteger())); - } else if(temp->m_value.dim() == 1) { - result.push_back(Index(temp->m_value)); + } else if(temp->m_tensor.dim() == 1) { + result.push_back(Index(temp->m_tensor)); } else { NL_PARSER(term->at(i).second, "Extra dimensions index not support '%d'!", i); } @@ -1970,40 +1952,35 @@ ObjPtr Context::CreateRVal(Context *ctx, TermPtr term, Obj * local_vars, bool in at::Scalar torch_scalar; switch(term->getTermID()) { case TermID::INTEGER: + val_int = parseInteger(term->getText().c_str()); - NL_TYPECHECK(term, newlang::toString(typeFromLimit(val_int)), - term->m_type_name); // Соответстствует ли тип значению? + NL_TYPECHECK(term, newlang::toString(typeFromLimit(val_int)), term->m_type_name); // Соответстствует ли тип значению? + + result = Obj::CreateValue(val_int); result->m_var_type_current = typeFromLimit(val_int); if(term->GetType()) { result->m_var_type_fixed = typeFromString(term->m_type_name, ctx); result->m_var_type_current = result->m_var_type_fixed; } - result->m_value = torch::scalar_tensor(val_int, toTorchType(result->m_var_type_current)); - result->m_var_is_init = true; return result; + case TermID::NUMBER: val_dbl = parseDouble(term->getText().c_str()); - NL_TYPECHECK(term, newlang::toString(typeFromLimit(val_dbl)), - term->m_type_name); // Соответстствует ли тип значению? + NL_TYPECHECK(term, newlang::toString(typeFromLimit(val_dbl)), term->m_type_name); // Соответстствует ли тип значению? + + result = Obj::CreateValue(val_dbl); result->m_var_type_current = typeFromLimit(val_dbl); if(term->GetType()) { result->m_var_type_fixed = typeFromString(term->m_type_name, ctx); result->m_var_type_current = result->m_var_type_fixed; } - result->m_value = torch::scalar_tensor(val_dbl, toTorchType(result->m_var_type_current)); - result->m_var_is_init = true; return result; + case TermID::STRWIDE: - result->m_var_type_current = ObjType::StrWide; - result->m_wstr = utf8_decode(term->getText()); - result->m_var_is_init = true; - return result; + return Obj::CreateString(utf8_decode(term->getText())); case TermID::STRCHAR: - result->m_var_type_current = ObjType::StrChar; - result->m_str = term->getText(); - result->m_var_is_init = true; - return result; + return Obj::CreateString(term->getText()); /* case TermID::FIELD: if(module && module->HasFunc(term->GetFullName().c_str())) { @@ -2256,14 +2233,24 @@ ObjPtr Context::CreateRVal(Context *ctx, TermPtr term, Obj * local_vars, bool in if(term->getTermID() == TermID::TENSOR) { result->m_var_type_fixed = typeFromString(term->m_type_name, ctx); - type = getSummaryTensorType(result, result->m_var_type_fixed); + type = getSummaryTensorType(result.get(), result->m_var_type_fixed); if(type != ObjType::None) { - result->m_value = ConvertToTensor(result.get(), toTorchType(type)); + + + sizes = TensorShapeFromDict(result.get()); + result->toType_(type); + + if(!sizes.empty()) { + ASSERT(result->m_tensor.defined()); + result->m_tensor = result->m_tensor.reshape(sizes); + } + + } else { result->m_var_is_init = false; } - result->resize(0, nullptr, ""); + // result->resize(0, nullptr, ""); result->m_var_type_current = type; } else { result->m_class_name = term->m_class_name; @@ -2359,7 +2346,7 @@ ObjPtr Context::CreateRVal(Context *ctx, TermPtr term, Obj * local_vars, bool in return nullptr; } -void Context::CreateArgs_(ObjPtr &args, TermPtr &term, Obj *local_vars) { +void Context::CreateArgs_(ObjPtr &args, TermPtr &term, Obj * local_vars) { for (int i = 0; i < term->size(); i++) { if(term->name(i).empty()) { args->push_back(CreateRVal(this, (*term)[i].second, local_vars)); diff --git a/src/context.h b/src/context.h index db665ec3..43a2a39c 100644 --- a/src/context.h +++ b/src/context.h @@ -432,7 +432,7 @@ namespace newlang { ObjPtr obj = Obj::CreateFunc(this, proto->Left(), type, proto->Left()->getName().empty() ? proto->Left()->getText() : proto->Left()->getName()); - obj->m_func_ptr = func; + obj->m_var = func; return obj; } diff --git a/src/fraction.h b/src/fraction.h index 561fc684..06beb5e7 100644 --- a/src/fraction.h +++ b/src/fraction.h @@ -1,12 +1,9 @@ +#include "pch.h" + #ifndef FRACTION_H #define FRACTION_H #include -#include - -#include - -#include "pch.h" namespace newlang { @@ -28,7 +25,11 @@ namespace newlang { BigNum(const BigNum ©) : BigNum() { VERIFY(BN_copy(value, copy.value)); } - BigNum& operator=(const BigNum&) = delete; // Disallow copying + + BigNum& operator=(const BigNum & copy) { + VERIFY(BN_copy(value, copy.value)); + return *this; + } virtual ~BigNum() { if (value) { @@ -294,11 +295,56 @@ namespace newlang { return *this; } + Fraction& operator%=(const Fraction &fraction) { + LOG_RUNTIME("Not implemented!"); + return *this; + } + + Fraction &operator^=(const Fraction &) { + LOG_RUNTIME("Operator '^=' not implementd!"); + return *this; + } + + Fraction & operator|=(const Fraction &) { + LOG_RUNTIME("Operator '|=' not implementd!"); + return *this; + } + + Fraction &op_lshift_set(const Fraction &) { + LOG_RUNTIME("Operator '<<=' not implementd!"); + return *this; + } + + Fraction & op_rshift_set(const Fraction &) { + LOG_RUNTIME("Operator '>>=' not implementd!"); + return *this; + } + + const Fraction & op_rrshift_set(const Fraction &) { + LOG_RUNTIME("Operator '>>>=' not implementd!"); + return *this; + } + Fraction& op_pow_(const Fraction &fraction) { LOG_RUNTIME("Not implemented!"); return *this; } + bool op_equal(const Fraction &fraction) const { + LOG_RUNTIME("Not implemented!"); + return false; + } + + int op_compare(const Fraction &fraction) const { + LOG_RUNTIME("Not implemented!"); + return false; + } + + Fraction &op_div_ceil_(Fraction &fraction) { + LOG_RUNTIME("Not implemented!"); + return *this; + } + }; }; #endif /* FRACTION_H */ diff --git a/src/nbproject/Makefile-Debug_LLVM.mk b/src/nbproject/Makefile-Debug_LLVM.mk index 1c4b1f72..af14c3bf 100644 --- a/src/nbproject/Makefile-Debug_LLVM.mk +++ b/src/nbproject/Makefile-Debug_LLVM.mk @@ -64,8 +64,8 @@ OBJECTFILES= \ CFLAGS= # CC Compiler Flags -CCFLAGS=`llvm-config-13 --cxxflags` -std=c++17 -fexceptions -fcxx-exceptions -Wall -Wextra -Werror -Wfloat-equal -Wundef -Wcast-align -Wwrite-strings -Wmissing-declarations -Wredundant-decls -Wshadow -Woverloaded-virtual -Wno-trigraphs -Wno-invalid-source-encoding -stdlib=libstdc++ -Wno-error=unused-variable -Wno-error=unused-parameter -Wno-error=switch -fsanitize=undefined-trap -fsanitize-undefined-trap-on-error -Wno-undefined-var-template -Wno-switch -CXXFLAGS=`llvm-config-13 --cxxflags` -std=c++17 -fexceptions -fcxx-exceptions -Wall -Wextra -Werror -Wfloat-equal -Wundef -Wcast-align -Wwrite-strings -Wmissing-declarations -Wredundant-decls -Wshadow -Woverloaded-virtual -Wno-trigraphs -Wno-invalid-source-encoding -stdlib=libstdc++ -Wno-error=unused-variable -Wno-error=unused-parameter -Wno-error=switch -fsanitize=undefined-trap -fsanitize-undefined-trap-on-error -Wno-undefined-var-template -Wno-switch +CCFLAGS=`llvm-config-13 --cxxflags` -std=c++17 -fexceptions -fcxx-exceptions -Wall -Wextra -Werror -Wfloat-equal -Wundef -Wcast-align -Wwrite-strings -Wmissing-declarations -Wredundant-decls -Wshadow -Woverloaded-virtual -Wno-trigraphs -Wno-invalid-source-encoding -stdlib=libstdc++ -Wno-error=unused-variable -Wno-error=unused-parameter -Wno-error=switch -fsanitize=undefined-trap -fsanitize-undefined-trap-on-error -Wno-undefined-var-template -Wno-switch +CXXFLAGS=`llvm-config-13 --cxxflags` -std=c++17 -fexceptions -fcxx-exceptions -Wall -Wextra -Werror -Wfloat-equal -Wundef -Wcast-align -Wwrite-strings -Wmissing-declarations -Wredundant-decls -Wshadow -Woverloaded-virtual -Wno-trigraphs -Wno-invalid-source-encoding -stdlib=libstdc++ -Wno-error=unused-variable -Wno-error=unused-parameter -Wno-error=switch -fsanitize=undefined-trap -fsanitize-undefined-trap-on-error -Wno-undefined-var-template -Wno-switch # Fortran Compiler Flags FFLAGS= @@ -94,12 +94,12 @@ ${OBJECTDIR}/builtin.o: builtin.cpp ${RM} "$@.d" $(COMPILE.cc) -g -O2 -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I. -I.. -I/usr/lib/llvm-13/lib/clang/13.0.1/include -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/builtin.o builtin.cpp -${OBJECTDIR}/context.o: context.cpp parser.h parser.yy.h +${OBJECTDIR}/context.o: context.cpp ${MKDIR} -p ${OBJECTDIR} ${RM} "$@.d" $(COMPILE.cc) -g -O2 -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I. -I.. -I/usr/lib/llvm-13/lib/clang/13.0.1/include -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/context.o context.cpp -${OBJECTDIR}/lexer.o: lexer.cpp parser.yy.h parser.yy.cpp location.hh +${OBJECTDIR}/lexer.o: lexer.cpp ${MKDIR} -p ${OBJECTDIR} ${RM} "$@.d" $(COMPILE.cc) -g -O2 -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I. -I.. -I/usr/lib/llvm-13/lib/clang/13.0.1/include -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/lexer.o lexer.cpp @@ -152,6 +152,10 @@ ${OBJECTDIR}/parser.yy.o: parser.yy.cpp parser.y @echo Выполнение шага пользовательского сборки +pch.h.pch: pch.h + @echo Выполнение шага пользовательского сборки + + ${OBJECTDIR}/syntax_help.o: syntax_help.cpp ${MKDIR} -p ${OBJECTDIR} ${RM} "$@.d" @@ -199,7 +203,7 @@ ${OBJECTDIR}/test/nlc_test.o: test/nlc_test.cpp ${OBJECTDIR}/test/object_test.o: test/object_test.cpp ${MKDIR} -p ${OBJECTDIR}/test ${RM} "$@.d" - $(COMPILE.cc) -g -O2 -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I. -I.. -I/usr/lib/llvm-13/lib/clang/13.0.1/include -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -std=c++14 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/object_test.o test/object_test.cpp + $(COMPILE.cc) -g -O2 -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I. -I.. -I/usr/lib/llvm-13/lib/clang/13.0.1/include -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/object_test.o test/object_test.cpp ${OBJECTDIR}/test/parser_test.o: test/parser_test.cpp ${MKDIR} -p ${OBJECTDIR}/test @@ -239,6 +243,7 @@ ${OBJECTDIR}/version.o: version.cpp ${RM} lexer.yy.cpp lexer.yy.h ${RM} parser.yy.h parser.yy.cpp location.hh ${RM} + ${RM} pch.h.pch ${RM} ${RM} ${RM} diff --git a/src/nbproject/Makefile-UnitTest_LLVM.mk b/src/nbproject/Makefile-UnitTest_LLVM.mk index ceb783cd..e8e28655 100644 --- a/src/nbproject/Makefile-UnitTest_LLVM.mk +++ b/src/nbproject/Makefile-UnitTest_LLVM.mk @@ -65,8 +65,8 @@ OBJECTFILES= \ CFLAGS= # CC Compiler Flags -CCFLAGS=`llvm-config-13 --cxxflags` -std=c++17 -fexceptions -fcxx-exceptions -Wall -Wextra -Werror -Wfloat-equal -Wundef -Wcast-align -Wwrite-strings -Wmissing-declarations -Wredundant-decls -Wshadow -Woverloaded-virtual -Wno-trigraphs -Wno-invalid-source-encoding -stdlib=libstdc++ -Wno-error=unused-variable -Wno-error=unused-parameter -Wno-error=switch -fsanitize=undefined-trap -fsanitize-undefined-trap-on-error -Wno-undefined-var-template -Wno-switch -fvisibility=default -CXXFLAGS=`llvm-config-13 --cxxflags` -std=c++17 -fexceptions -fcxx-exceptions -Wall -Wextra -Werror -Wfloat-equal -Wundef -Wcast-align -Wwrite-strings -Wmissing-declarations -Wredundant-decls -Wshadow -Woverloaded-virtual -Wno-trigraphs -Wno-invalid-source-encoding -stdlib=libstdc++ -Wno-error=unused-variable -Wno-error=unused-parameter -Wno-error=switch -fsanitize=undefined-trap -fsanitize-undefined-trap-on-error -Wno-undefined-var-template -Wno-switch -fvisibility=default +CCFLAGS=`llvm-config-13 --cxxflags` -std=c++17 -fexceptions -fcxx-exceptions -Wall -Wextra -Werror -Wfloat-equal -Wundef -Wcast-align -Wwrite-strings -Wmissing-declarations -Wredundant-decls -Wshadow -Woverloaded-virtual -Wno-trigraphs -Wno-invalid-source-encoding -stdlib=libstdc++ -Wno-error=unused-variable -Wno-error=unused-parameter -Wno-error=switch -fsanitize=undefined-trap -fsanitize-undefined-trap-on-error -Wno-undefined-var-template -Wno-switch -fvisibility=default +CXXFLAGS=`llvm-config-13 --cxxflags` -std=c++17 -fexceptions -fcxx-exceptions -Wall -Wextra -Werror -Wfloat-equal -Wundef -Wcast-align -Wwrite-strings -Wmissing-declarations -Wredundant-decls -Wshadow -Woverloaded-virtual -Wno-trigraphs -Wno-invalid-source-encoding -stdlib=libstdc++ -Wno-error=unused-variable -Wno-error=unused-parameter -Wno-error=switch -fsanitize=undefined-trap -fsanitize-undefined-trap-on-error -Wno-undefined-var-template -Wno-switch -fvisibility=default # Fortran Compiler Flags FFLAGS= @@ -95,20 +95,20 @@ ${OBJECTDIR}/_ext/e16507f5/logger.o: ../contrib/logger/logger.cpp ${RM} "$@.d" $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I. -I.. -I/usr/lib/llvm-13/lib/clang/13.0.1/include -I/usr/include/llvm-c-13 -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/_ext/e16507f5/logger.o ../contrib/logger/logger.cpp -${OBJECTDIR}/builtin.o: builtin.cpp +${OBJECTDIR}/builtin.o: builtin.cpp pch.h.pch ${MKDIR} -p ${OBJECTDIR} ${RM} "$@.d" - $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I. -I.. -I/usr/lib/llvm-13/lib/clang/13.0.1/include -I/usr/include/llvm-c-13 -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/builtin.o builtin.cpp + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I. -I.. -I/usr/lib/llvm-13/lib/clang/13.0.1/include -I/usr/include/llvm-c-13 -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -include-pch pch.h.pch -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/builtin.o builtin.cpp -${OBJECTDIR}/context.o: context.cpp parser.h parser.yy.h +${OBJECTDIR}/context.o: context.cpp pch.h.pch ${MKDIR} -p ${OBJECTDIR} ${RM} "$@.d" - $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I. -I.. -I/usr/lib/llvm-13/lib/clang/13.0.1/include -I/usr/include/llvm-c-13 -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/context.o context.cpp + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I. -I.. -I/usr/lib/llvm-13/lib/clang/13.0.1/include -I/usr/include/llvm-c-13 -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -include-pch pch.h.pch -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/context.o context.cpp -${OBJECTDIR}/lexer.o: lexer.cpp parser.yy.h parser.yy.cpp location.hh +${OBJECTDIR}/lexer.o: lexer.cpp pch.h.pch ${MKDIR} -p ${OBJECTDIR} ${RM} "$@.d" - $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I. -I.. -I/usr/lib/llvm-13/lib/clang/13.0.1/include -I/usr/include/llvm-c-13 -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/lexer.o lexer.cpp + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I. -I.. -I/usr/lib/llvm-13/lib/clang/13.0.1/include -I/usr/include/llvm-c-13 -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -include-pch pch.h.pch -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/lexer.o lexer.cpp : lexer.h parser.yy.h parser.yy.cpp location.hh @echo Выполнение шага пользовательского сборки @@ -124,25 +124,25 @@ ${OBJECTDIR}/lexer.yy.o: lexer.yy.cpp parser.y parser.yy.h parser.yy.cpp locatio ${RM} "$@.d" $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I. -I.. -I/usr/lib/llvm-13/lib/clang/13.0.1/include -I/usr/include/llvm-c-13 -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/lexer.yy.o lexer.yy.cpp -${OBJECTDIR}/newlang.o: newlang.cpp +${OBJECTDIR}/newlang.o: newlang.cpp pch.h.pch ${MKDIR} -p ${OBJECTDIR} ${RM} "$@.d" - $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I. -I.. -I/usr/lib/llvm-13/lib/clang/13.0.1/include -I/usr/include/llvm-c-13 -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/newlang.o newlang.cpp + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I. -I.. -I/usr/lib/llvm-13/lib/clang/13.0.1/include -I/usr/include/llvm-c-13 -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -include-pch pch.h.pch -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/newlang.o newlang.cpp -${OBJECTDIR}/nlc.o: nlc.cpp +${OBJECTDIR}/nlc.o: nlc.cpp pch.h.pch ${MKDIR} -p ${OBJECTDIR} ${RM} "$@.d" - $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I. -I.. -I/usr/lib/llvm-13/lib/clang/13.0.1/include -I/usr/include/llvm-c-13 -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/nlc.o nlc.cpp + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I. -I.. -I/usr/lib/llvm-13/lib/clang/13.0.1/include -I/usr/include/llvm-c-13 -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -include-pch pch.h.pch -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/nlc.o nlc.cpp -${OBJECTDIR}/object.o: object.cpp +${OBJECTDIR}/object.o: object.cpp pch.h.pch ${MKDIR} -p ${OBJECTDIR} ${RM} "$@.d" - $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I. -I.. -I/usr/lib/llvm-13/lib/clang/13.0.1/include -I/usr/include/llvm-c-13 -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/object.o object.cpp + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I. -I.. -I/usr/lib/llvm-13/lib/clang/13.0.1/include -I/usr/include/llvm-c-13 -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -include-pch pch.h.pch -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/object.o object.cpp -${OBJECTDIR}/parser.o: parser.cpp +${OBJECTDIR}/parser.o: parser.cpp pch.h.pch ${MKDIR} -p ${OBJECTDIR} ${RM} "$@.d" - $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I. -I.. -I/usr/lib/llvm-13/lib/clang/13.0.1/include -I/usr/include/llvm-c-13 -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/parser.o parser.cpp + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I. -I.. -I/usr/lib/llvm-13/lib/clang/13.0.1/include -I/usr/include/llvm-c-13 -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -include-pch pch.h.pch -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/parser.o parser.cpp .NO_PARALLEL:parser.yy.h parser.yy.cpp location.hh parser.yy.h parser.yy.cpp location.hh: parser.y @@ -158,69 +158,73 @@ ${OBJECTDIR}/parser.yy.o: parser.yy.cpp parser.y @echo Выполнение шага пользовательского сборки +pch.h.pch: pch.h + @echo Выполнение шага пользовательского сборки + clang++ `llvm-config-13 --cxxflags` -std=c++17 -fexceptions -fcxx-exceptions -Wall -Wextra -Werror -Wfloat-equal -Wundef -Wcast-align -Wwrite-strings -Wmissing-declarations -Wredundant-decls -Wshadow -Woverloaded-virtual -Wno-trigraphs -Wno-invalid-source-encoding -stdlib=libstdc++ -Wno-error=unused-variable -Wno-error=unused-parameter -Wno-error=switch -fsanitize=undefined-trap -fsanitize-undefined-trap-on-error -Wno-undefined-var-template -Wno-switch -fvisibility=default -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I. -I.. -I/usr/lib/llvm-13/lib/clang/13.0.1/include -I/usr/include/llvm-c-13 -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -x c++-header -o pch.h.pch pch.h -verify-pch -fpch-validate-input-files-content + ${OBJECTDIR}/syntax_help.o: syntax_help.cpp ${MKDIR} -p ${OBJECTDIR} ${RM} "$@.d" $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I. -I.. -I/usr/lib/llvm-13/lib/clang/13.0.1/include -I/usr/include/llvm-c-13 -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/syntax_help.o syntax_help.cpp -${OBJECTDIR}/term.o: term.cpp +${OBJECTDIR}/term.o: term.cpp pch.h.pch ${MKDIR} -p ${OBJECTDIR} ${RM} "$@.d" - $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I. -I.. -I/usr/lib/llvm-13/lib/clang/13.0.1/include -I/usr/include/llvm-c-13 -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/term.o term.cpp + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I. -I.. -I/usr/lib/llvm-13/lib/clang/13.0.1/include -I/usr/include/llvm-c-13 -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -include-pch pch.h.pch -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/term.o term.cpp : term.h parser.yy.cpp location.hh @echo Выполнение шага пользовательского сборки -${OBJECTDIR}/test/alg_test.o: test/alg_test.cpp +${OBJECTDIR}/test/alg_test.o: test/alg_test.cpp pch.h.pch ${MKDIR} -p ${OBJECTDIR}/test ${RM} "$@.d" - $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I. -I.. -I/usr/lib/llvm-13/lib/clang/13.0.1/include -I/usr/include/llvm-c-13 -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/alg_test.o test/alg_test.cpp + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I. -I.. -I/usr/lib/llvm-13/lib/clang/13.0.1/include -I/usr/include/llvm-c-13 -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -include-pch pch.h.pch -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/alg_test.o test/alg_test.cpp -${OBJECTDIR}/test/compiler_test.o: test/compiler_test.cpp +${OBJECTDIR}/test/compiler_test.o: test/compiler_test.cpp pch.h.pch ${MKDIR} -p ${OBJECTDIR}/test ${RM} "$@.d" - $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I. -I.. -I/usr/lib/llvm-13/lib/clang/13.0.1/include -I/usr/include/llvm-c-13 -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/compiler_test.o test/compiler_test.cpp + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I. -I.. -I/usr/lib/llvm-13/lib/clang/13.0.1/include -I/usr/include/llvm-c-13 -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -include-pch pch.h.pch -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/compiler_test.o test/compiler_test.cpp -${OBJECTDIR}/test/eval_test.o: test/eval_test.cpp +${OBJECTDIR}/test/eval_test.o: test/eval_test.cpp pch.h.pch ${MKDIR} -p ${OBJECTDIR}/test ${RM} "$@.d" - $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I. -I.. -I/usr/lib/llvm-13/lib/clang/13.0.1/include -I/usr/include/llvm-c-13 -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/eval_test.o test/eval_test.cpp + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I. -I.. -I/usr/lib/llvm-13/lib/clang/13.0.1/include -I/usr/include/llvm-c-13 -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -include-pch pch.h.pch -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/eval_test.o test/eval_test.cpp -${OBJECTDIR}/test/fraction_test.o: test/fraction_test.cpp +${OBJECTDIR}/test/fraction_test.o: test/fraction_test.cpp pch.h.pch ${MKDIR} -p ${OBJECTDIR}/test ${RM} "$@.d" - $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I. -I.. -I/usr/lib/llvm-13/lib/clang/13.0.1/include -I/usr/include/llvm-c-13 -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/fraction_test.o test/fraction_test.cpp + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I. -I.. -I/usr/lib/llvm-13/lib/clang/13.0.1/include -I/usr/include/llvm-c-13 -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -include-pch pch.h.pch -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/fraction_test.o test/fraction_test.cpp -${OBJECTDIR}/test/lexer_test.o: test/lexer_test.cpp +${OBJECTDIR}/test/lexer_test.o: test/lexer_test.cpp pch.h.pch ${MKDIR} -p ${OBJECTDIR}/test ${RM} "$@.d" - $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I. -I.. -I/usr/lib/llvm-13/lib/clang/13.0.1/include -I/usr/include/llvm-c-13 -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/lexer_test.o test/lexer_test.cpp + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I. -I.. -I/usr/lib/llvm-13/lib/clang/13.0.1/include -I/usr/include/llvm-c-13 -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -include-pch pch.h.pch -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/lexer_test.o test/lexer_test.cpp -${OBJECTDIR}/test/nlc_test.o: test/nlc_test.cpp +${OBJECTDIR}/test/nlc_test.o: test/nlc_test.cpp pch.h.pch ${MKDIR} -p ${OBJECTDIR}/test ${RM} "$@.d" - $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I. -I.. -I/usr/lib/llvm-13/lib/clang/13.0.1/include -I/usr/include/llvm-c-13 -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/nlc_test.o test/nlc_test.cpp + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I. -I.. -I/usr/lib/llvm-13/lib/clang/13.0.1/include -I/usr/include/llvm-c-13 -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -include-pch pch.h.pch -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/nlc_test.o test/nlc_test.cpp -${OBJECTDIR}/test/object_test.o: test/object_test.cpp +${OBJECTDIR}/test/object_test.o: test/object_test.cpp pch.h.pch ${MKDIR} -p ${OBJECTDIR}/test ${RM} "$@.d" - $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I. -I.. -I/usr/lib/llvm-13/lib/clang/13.0.1/include -I/usr/include/llvm-c-13 -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -std=c++14 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/object_test.o test/object_test.cpp + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I. -I.. -I/usr/lib/llvm-13/lib/clang/13.0.1/include -I/usr/include/llvm-c-13 -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -include-pch pch.h.pch -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/object_test.o test/object_test.cpp -${OBJECTDIR}/test/parser_test.o: test/parser_test.cpp +${OBJECTDIR}/test/parser_test.o: test/parser_test.cpp pch.h.pch ${MKDIR} -p ${OBJECTDIR}/test ${RM} "$@.d" - $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I. -I.. -I/usr/lib/llvm-13/lib/clang/13.0.1/include -I/usr/include/llvm-c-13 -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/parser_test.o test/parser_test.cpp + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I. -I.. -I/usr/lib/llvm-13/lib/clang/13.0.1/include -I/usr/include/llvm-c-13 -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -include-pch pch.h.pch -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/parser_test.o test/parser_test.cpp -${OBJECTDIR}/test/speed_test.o: test/speed_test.cpp +${OBJECTDIR}/test/speed_test.o: test/speed_test.cpp pch.h.pch ${MKDIR} -p ${OBJECTDIR}/test ${RM} "$@.d" - $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I. -I.. -I/usr/lib/llvm-13/lib/clang/13.0.1/include -I/usr/include/llvm-c-13 -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/speed_test.o test/speed_test.cpp + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I. -I.. -I/usr/lib/llvm-13/lib/clang/13.0.1/include -I/usr/include/llvm-c-13 -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -include-pch pch.h.pch -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/speed_test.o test/speed_test.cpp -${OBJECTDIR}/variable.o: variable.cpp +${OBJECTDIR}/variable.o: variable.cpp pch.h.pch ${MKDIR} -p ${OBJECTDIR} ${RM} "$@.d" - $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I. -I.. -I/usr/lib/llvm-13/lib/clang/13.0.1/include -I/usr/include/llvm-c-13 -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/variable.o variable.cpp + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I. -I.. -I/usr/lib/llvm-13/lib/clang/13.0.1/include -I/usr/include/llvm-c-13 -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -include-pch pch.h.pch -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/variable.o variable.cpp ${OBJECTDIR}/version.o: version.cpp ${MKDIR} -p ${OBJECTDIR} @@ -245,6 +249,7 @@ ${OBJECTDIR}/version.o: version.cpp ${RM} lexer.yy.cpp lexer.yy.h ${RM} parser.yy.h parser.yy.cpp location.hh ${RM} + ${RM} pch.h.pch ${RM} ${RM} ${RM} diff --git a/src/nbproject/configurations.xml b/src/nbproject/configurations.xml index 2da62ba2..83240958 100644 --- a/src/nbproject/configurations.xml +++ b/src/nbproject/configurations.xml @@ -443,7 +443,7 @@ ../contrib/libtorch/include/torch/csrc/api/include ../contrib/libtorch/include - `llvm-config-13 --cxxflags` -std=c++17 -fexceptions -fcxx-exceptions -Wall -Wextra -Werror -Wfloat-equal -Wundef -Wcast-align -Wwrite-strings -Wmissing-declarations -Wredundant-decls -Wshadow -Woverloaded-virtual -Wno-trigraphs -Wno-invalid-source-encoding -stdlib=libstdc++ -Wno-error=unused-variable -Wno-error=unused-parameter -Wno-error=switch -fsanitize=undefined-trap -fsanitize-undefined-trap-on-error -Wno-undefined-var-template -Wno-switch + `llvm-config-13 --cxxflags` -std=c++17 -fexceptions -fcxx-exceptions -Wall -Wextra -Werror -Wfloat-equal -Wundef -Wcast-align -Wwrite-strings -Wmissing-declarations -Wredundant-decls -Wshadow -Woverloaded-virtual -Wno-trigraphs -Wno-invalid-source-encoding -stdlib=libstdc++ -Wno-error=unused-variable -Wno-error=unused-parameter -Wno-error=switch -fsanitize=undefined-trap -fsanitize-undefined-trap-on-error -Wno-undefined-var-template -Wno-switch DEBUG LOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG @@ -508,12 +508,15 @@ + + + - parser.h parser.yy.h + @@ -522,7 +525,7 @@ - parser.yy.h parser.yy.cpp location.hh + @@ -548,10 +551,16 @@ + + + + + + @@ -563,6 +572,9 @@ + + + @@ -584,6 +596,9 @@ + + pch.h.pch + @@ -600,22 +615,49 @@ + + + + + + + + + + + + + + + + + + - + + + + + + + + + + @@ -1150,7 +1192,7 @@ ../contrib/libtorch/include/torch/csrc/api/include ../contrib/libtorch/include - `llvm-config-13 --cxxflags` -std=c++17 -fexceptions -fcxx-exceptions -Wall -Wextra -Werror -Wfloat-equal -Wundef -Wcast-align -Wwrite-strings -Wmissing-declarations -Wredundant-decls -Wshadow -Woverloaded-virtual -Wno-trigraphs -Wno-invalid-source-encoding -stdlib=libstdc++ -Wno-error=unused-variable -Wno-error=unused-parameter -Wno-error=switch -fsanitize=undefined-trap -fsanitize-undefined-trap-on-error -Wno-undefined-var-template -Wno-switch -fvisibility=default + `llvm-config-13 --cxxflags` -std=c++17 -fexceptions -fcxx-exceptions -Wall -Wextra -Werror -Wfloat-equal -Wundef -Wcast-align -Wwrite-strings -Wmissing-declarations -Wredundant-decls -Wshadow -Woverloaded-virtual -Wno-trigraphs -Wno-invalid-source-encoding -stdlib=libstdc++ -Wno-error=unused-variable -Wno-error=unused-parameter -Wno-error=switch -fsanitize=undefined-trap -fsanitize-undefined-trap-on-error -Wno-undefined-var-template -Wno-switch -fvisibility=default DEBUG LOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG @@ -1220,12 +1262,17 @@ + + -include-pch pch.h.pch + pch.h.pch + - parser.h parser.yy.h + -include-pch pch.h.pch + pch.h.pch @@ -1234,7 +1281,8 @@ - parser.yy.h parser.yy.cpp location.hh + -include-pch pch.h.pch + pch.h.pch @@ -1260,21 +1308,34 @@ + + -include-pch pch.h.pch + pch.h.pch + + + -include-pch pch.h.pch + pch.h.pch + - + -include-pch pch.h.pch + pch.h.pch + + -include-pch pch.h.pch + pch.h.pch + @@ -1296,6 +1357,10 @@ + + clang++ `llvm-config-13 --cxxflags` -std=c++17 -fexceptions -fcxx-exceptions -Wall -Wextra -Werror -Wfloat-equal -Wundef -Wcast-align -Wwrite-strings -Wmissing-declarations -Wredundant-decls -Wshadow -Woverloaded-virtual -Wno-trigraphs -Wno-invalid-source-encoding -stdlib=libstdc++ -Wno-error=unused-variable -Wno-error=unused-parameter -Wno-error=switch -fsanitize=undefined-trap -fsanitize-undefined-trap-on-error -Wno-undefined-var-template -Wno-switch -fvisibility=default -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I. -I.. -I/usr/lib/llvm-13/lib/clang/13.0.1/include -I/usr/include/llvm-c-13 -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -x c++-header -o pch.h.pch pch.h -verify-pch -fpch-validate-input-files-content + pch.h.pch + @@ -1303,7 +1368,8 @@ - + -include-pch pch.h.pch + pch.h.pch @@ -1312,28 +1378,65 @@ + + -include-pch pch.h.pch + pch.h.pch + + + -include-pch pch.h.pch + pch.h.pch + + + -include-pch pch.h.pch + pch.h.pch + + + -include-pch pch.h.pch + pch.h.pch + + + -include-pch pch.h.pch + pch.h.pch + + + -include-pch pch.h.pch + pch.h.pch + - + + + -include-pch pch.h.pch + pch.h.pch + + + -include-pch pch.h.pch + pch.h.pch + + + -include-pch pch.h.pch + pch.h.pch + - + -include-pch pch.h.pch + pch.h.pch diff --git a/src/nlc.h b/src/nlc.h index dd881b2c..5843f61f 100644 --- a/src/nlc.h +++ b/src/nlc.h @@ -329,7 +329,7 @@ namespace newlang { } } - ObjPtr result = m_ctx.ExecStr(m_eval, m_args.get(), true); + ObjPtr result = m_ctx.ExecStr(m_eval, m_args.get(), false); if (result && m_local_vars.find(result.get()) == m_local_vars.end()) { m_local_vars[result.get()] = result; diff --git a/src/object.cpp b/src/object.cpp index a6c6e7e3..452df616 100644 --- a/src/object.cpp +++ b/src/object.cpp @@ -70,13 +70,13 @@ int64_t Obj::size(int64_t dim) const { } return 0; } - return m_value.size(dim); + return m_tensor.size(dim); } ASSERT(dim == 0); if(m_var_type_current == ObjType::StrChar) { - return m_str.size(); + return m_value.size(); } else if(m_var_type_current == ObjType::StrWide) { - return m_wstr.size(); + return m_string.size(); } return Variable::size(); } @@ -88,32 +88,32 @@ int64_t Obj::resize_(int64_t new_size, ObjPtr fill, const std::string name) { if(new_size >= 0) { // Размер положительный, просто изменить число элементов добавив или удалив последние if(m_var_type_current == ObjType::StrChar) { - m_str.resize(new_size, ' '); - return m_str.size(); + m_value.resize(new_size, ' '); + return m_value.size(); } else if(m_var_type_current == ObjType::StrWide) { - m_wstr.resize(new_size, L' '); - return m_wstr.size(); + m_string.resize(new_size, L' '); + return m_string.size(); } } else { // Если размер отрицательный - добавить или удалить вначале new_size = -new_size; if(static_cast (size()) > new_size) { if(m_var_type_current == ObjType::StrChar) { - m_str.erase(0, new_size); - return m_str.size(); + m_value.erase(0, new_size); + return m_value.size(); } else if(m_var_type_current == ObjType::StrWide) { - m_str.erase(0, new_size); - return m_wstr.size(); + m_value.erase(0, new_size); + return m_string.size(); } } else if(static_cast (size()) < new_size) { if(m_var_type_current == ObjType::StrChar) { - m_str.insert(0, new_size, ' '); - return m_str.size(); + m_value.insert(0, new_size, ' '); + return m_value.size(); } else if(m_var_type_current == ObjType::StrWide) { - m_wstr.insert(0, new_size, L' '); - return m_wstr.size(); + m_string.insert(0, new_size, L' '); + return m_string.size(); } } @@ -123,8 +123,8 @@ int64_t Obj::resize_(int64_t new_size, ObjPtr fill, const std::string name) { return Variable::resize(new_size, fill ? fill : Obj::CreateNone(), name); } else if(is_tensor()) { std::vector sizes; - for (int i = 0; i < m_value.dim(); i++) { - sizes.push_back(m_value.size(i)); + for (int i = 0; i < m_tensor.dim(); i++) { + sizes.push_back(m_tensor.size(i)); } if(sizes.empty()) { // Scalar @@ -139,7 +139,7 @@ int64_t Obj::resize_(int64_t new_size, ObjPtr fill, const std::string name) { ASSERT(sizes.size() == 1); sizes[0] = new_size; - m_value.resize_(at::IntArrayRef(sizes)); + m_tensor.resize_(at::IntArrayRef(sizes)); } else { // Decrease tensor size // If the size is negative - add or remove elements first @@ -158,22 +158,22 @@ int64_t Obj::resize_(int64_t new_size, ObjPtr fill, const std::string name) { // LOG_DEBUG("cat %s", TensorToString(ind).c_str()); // LOG_DEBUG("m_value %s", TensorToString(m_value).c_str()); - m_value.index_copy_(0, ind, m_value.clone()); + m_tensor.index_copy_(0, ind, m_tensor.clone()); // LOG_DEBUG("index_copy_ %s", TensorToString(m_value).c_str()); sizes[0] = new_size; - m_value.resize_(at::IntArrayRef(sizes)); + m_tensor.resize_(at::IntArrayRef(sizes)); // LOG_DEBUG("resize_ %s", TensorToString(m_value).c_str()); } else { // sizes[0] < size ASSERT(sizes.size() == 1); - m_value = at::cat({torch::zeros(new_size - sizes[0], m_value.scalar_type()), m_value}); + m_tensor = at::cat({torch::zeros(new_size - sizes[0], m_tensor.scalar_type()), m_tensor}); } } if(new_size == 0) { - m_value.reset(); + m_tensor.reset(); m_var_is_init = false; } return new_size; @@ -183,20 +183,21 @@ int64_t Obj::resize_(int64_t new_size, ObjPtr fill, const std::string name) { const Variable::PairType & Obj::at(int64_t index) const { if(m_var_type_current == ObjType::StrChar) { - if(index < static_cast (m_str.size())) { - m_str_pair = pair(CreateString(std::string(1, m_str[index]))); + if(index < static_cast (m_value.size())) { + m_str_pair = pair(CreateString(std::string(1, m_value[index]))); return m_str_pair; } - LOG_RUNTIME("Index '%ld' not exists in byte string '%s'!", index, m_str.c_str()); + LOG_RUNTIME("Index '%ld' not exists in byte string '%s'!", index, m_value.c_str()); } else if(m_var_type_current == ObjType::StrWide) { - if(index < static_cast (m_wstr.size())) { - m_str_pair = pair(CreateString(std::wstring(1, m_wstr[index]))); + if(index < static_cast (m_string.size())) { + m_str_pair = pair(CreateString(std::wstring(1, m_string[index]))); return m_str_pair; } LOG_RUNTIME("Index '%ld' not exists in byte string '%s'!", index, "WIDE"); } else if(is_tensor()) { - torch::Tensor t = m_value.index({index}); + ASSERT(!is_scalar()); + torch::Tensor t = m_tensor.index({index}); m_str_pair = pair(Obj::CreateTensor(t)); return m_str_pair; } @@ -205,22 +206,25 @@ const Variable::PairType & Obj::at(int64_t index) const { Variable::PairType & Obj::at(int64_t index) { if(m_var_type_current == ObjType::StrChar) { - if(index < static_cast (m_str.size())) { - m_str_pair = pair(CreateString(std::string(1, m_str[index]))); + if(index < static_cast (m_value.size())) { + m_str_pair = pair(CreateString(std::string(1, m_value[index]))); return m_str_pair; } - LOG_RUNTIME("Index '%ld' not exists in byte string '%s'!", index, m_str.c_str()); + LOG_RUNTIME("Index '%ld' not exists in byte string '%s'!", index, m_value.c_str()); } else if(m_var_type_current == ObjType::StrWide) { - if(index < static_cast (m_wstr.size())) { - m_str_pair = pair(CreateString(std::wstring(1, m_wstr[index]))); + if(index < static_cast (m_string.size())) { + m_str_pair = pair(CreateString(std::wstring(1, m_string[index]))); return m_str_pair; } LOG_RUNTIME("Index '%ld' not exists in byte string '%s'!", index, "WIDE"); } else if(is_tensor()) { - torch::Tensor t = m_value.index({(int) index}); + ASSERT(!is_scalar()); + ASSERT(m_tensor.defined()); + torch::Tensor t = m_tensor.index({(int) index}); m_str_pair = pair(Obj::CreateTensor(t)); return m_str_pair; + // } } return Variable::at(index); } @@ -232,27 +236,29 @@ const ObjPtr Obj::index_get(const std::vector &index) const { } int64_t pos = index[0].integer(); if(pos < 0) { - pos = m_str.size() + pos; // Позиция с конца строки + pos = m_value.size() + pos; // Позиция с конца строки } - if(pos < static_cast (m_str.size())) { - return CreateString(std::string(1, m_str[pos])); + if(pos < static_cast (m_value.size())) { + return CreateString(std::string(1, m_value[pos])); } - LOG_RUNTIME("Index '%s' not exists in byte string '%s'!", IndexToString(index).c_str(), m_str.c_str()); + LOG_RUNTIME("Index '%s' not exists in byte string '%s'!", IndexToString(index).c_str(), m_value.c_str()); } else if(m_var_type_current == ObjType::StrWide || m_var_type_current == ObjType::FmtWide) { if(index.size() != 1 || !index[0].is_integer()) { LOG_RUNTIME("The index must be an integer value '%s'!", IndexToString(index).c_str()); } int64_t pos = index[0].integer(); if(pos < 0) { - pos = m_wstr.size() + pos; // Позиция с конца строки + pos = m_string.size() + pos; // Позиция с конца строки } - if(pos < static_cast (m_wstr.size())) { - return CreateString(std::wstring(1, m_wstr[pos])); + if(pos < static_cast (m_string.size())) { + return CreateString(std::wstring(1, m_string[pos])); } - LOG_RUNTIME("Index '%s' not exists in WIDE string '%s'!", IndexToString(index).c_str(), utf8_encode(m_wstr).c_str()); + LOG_RUNTIME("Index '%s' not exists in WIDE string '%s'!", IndexToString(index).c_str(), utf8_encode(m_string).c_str()); } else if(is_tensor()) { - torch::Tensor t = m_value.index(index); + ASSERT(!is_scalar()); + ASSERT(m_tensor.defined()); + torch::Tensor t = m_tensor.index(index); return Obj::CreateTensor(t); } @@ -269,34 +275,47 @@ ObjPtr Obj::index_set_(const std::vector &index, const ObjPtr value) { } int64_t pos = index[0].integer(); if(pos < 0) { - pos = m_str.size() + pos; // Позиция с конца строки + pos = m_value.size() + pos; // Позиция с конца строки } - if(pos < static_cast (m_str.size())) { - m_str.erase(pos, 1); - m_str.insert(pos, value->toType(ObjType::StrChar)->m_str); + if(pos < static_cast (m_value.size())) { + m_value.erase(pos, 1); + m_value.insert(pos, value->toType(ObjType::StrChar)->m_value); m_var_is_init = true; return shared(); } - LOG_RUNTIME("Index '%s' not exists in byte string '%s'!", IndexToString(index).c_str(), m_str.c_str()); + LOG_RUNTIME("Index '%s' not exists in byte string '%s'!", IndexToString(index).c_str(), m_value.c_str()); } else if(m_var_type_current == ObjType::StrWide) { if(index.size() != 1 || !index[0].is_integer()) { LOG_RUNTIME("The index must be an integer value '%s'!", IndexToString(index).c_str()); } int64_t pos = index[0].integer(); if(pos < 0) { - pos = m_str.size() + pos; // Позиция с конца строки + pos = m_value.size() + pos; // Позиция с конца строки } - if(pos < static_cast (m_wstr.size())) { - m_wstr.erase(pos, 1); - m_wstr.insert(pos, value->toType(ObjType::StrWide)->m_wstr); + if(pos < static_cast (m_string.size())) { + m_string.erase(pos, 1); + m_string.insert(pos, value->toType(ObjType::StrWide)->m_string); m_var_is_init = true; return shared(); } LOG_RUNTIME("Index '%s' not exists in byte string '%s'!", IndexToString(index).c_str(), "WIDE"); } else if(is_tensor()) { + ASSERT(!is_scalar()); + ASSERT(m_tensor.defined()); - m_value.index_put_(index, value->toTensor()); + ObjPtr temp = value->toType(fromTorchType(m_tensor.scalar_type())); + if(temp->is_scalar()) { + if(temp->is_integral()) { + m_tensor.index_put_(index, temp->GetValueAsInteger()); + } else { + ASSERT(temp->is_floating()); + m_tensor.index_put_(index, temp->GetValueAsNumber()); + } + } else { + ASSERT(temp->m_tensor.defined()); + m_tensor.index_put_(index, temp->m_tensor); + } m_var_is_init = true; return shared(); @@ -313,17 +332,17 @@ ObjPtr Obj::index_set_(const std::vector &index, const ObjPtr value) { ObjPtr Obj::op_set_index(int64_t index, std::string value) { if(m_var_type_current == ObjType::StrChar) { - if(index < static_cast (m_str.size())) { - m_str.erase(index, 1); - m_str.insert(index, value); + if(index < static_cast (m_value.size())) { + m_value.erase(index, 1); + m_value.insert(index, value); m_var_is_init = true; return shared(); } - LOG_RUNTIME("Index '%ld' not exists in byte string '%s'!", index, m_str.c_str()); + LOG_RUNTIME("Index '%ld' not exists in byte string '%s'!", index, m_value.c_str()); } else if(m_var_type_current == ObjType::StrWide) { - if(index < static_cast (m_wstr.size())) { - m_wstr.erase(index, 1); - m_wstr.insert(index, utf8_decode(value)); + if(index < static_cast (m_string.size())) { + m_string.erase(index, 1); + m_string.insert(index, utf8_decode(value)); m_var_is_init = true; return shared(); } @@ -345,28 +364,26 @@ bool Obj::exist(ObjPtr &find, bool strong) { return false; } -/* - * Вычисление итогового типа объетка для арифметических типов. - * Арифметические данные могут быть тензор или ссылка на рельный тип. - * Тензор может сменить тип, если он не указан для конкретной переменной. - * Реальный тип данных изменить тип не может. - */ +ObjType newlang::getSummaryTensorType(Obj *obj, ObjType start) { -ObjType newlang::getSummaryTensorType(ObjPtr &obj, ObjType start) { ObjType result = ObjType::None; - if(!obj->getName().empty()) { - LOG_RUNTIME("Tensor does not support named data or dimensions '%s'!", obj->getName().c_str()); + if(!obj) { + return result; } if(obj->is_dictionary_type()) { for (int i = 0; i < obj->size(); i++) { - result = getSummaryTensorType(obj->at(i).second, result); + result = getSummaryTensorType(obj->at(i).second.get(), result); } return result; - } else if(obj->is_arithmetic_type() || obj->is_bool_type()) { - if(start >= std::max(obj->m_var_type_current, obj->m_var_type_fixed)) { - return start; + } else if(obj->is_arithmetic_type()) { + if(isGenericType(obj->m_var_type_fixed)) { + return std::max(obj->m_var_type_current, start); } else { - return std::max(obj->m_var_type_current, obj->m_var_type_fixed); + if(start >= std::max(obj->m_var_type_current, obj->m_var_type_fixed)) { + return start; + } else { + return std::max(obj->m_var_type_current, obj->m_var_type_fixed); + } } } LOG_RUNTIME("Tensor support arithmetic data type only '%s'!", obj->toString().c_str()); @@ -376,7 +393,30 @@ ObjPtr Obj::operator+=(Obj value) { if(is_tensor()) { if(value.is_tensor()) { testResultIntegralType(value.m_var_type_current, true); - m_value.add_(value.m_value); + if(is_scalar() && value.is_scalar()) { + if(is_floating()) { + ASSERT(at::holds_alternative(m_var)); + m_var = GetValueAsNumber() + value.GetValueAsNumber(); + m_var_type_current = ObjType::Double; + } else if(is_integral() && value.is_integral()) { + ASSERT(at::holds_alternative(m_var)); + m_var = GetValueAsInteger() + value.GetValueAsInteger(); + m_var_type_current = typeFromLimit(GetValueAsInteger()); + } else { + LOG_RUNTIME("Fail convert '%s' to type %s!", value.toString().c_str(), newlang::toString(m_var_type_current)); + } + } else if(value.is_scalar()) { + if(value.is_floating()) { + m_tensor.add_(value.GetValueAsNumber()); + } else if(value.is_integral()) { + m_tensor.add_(value.GetValueAsInteger()); + } else { + LOG_RUNTIME("Fail convert '%s' to type %s!", value.toString().c_str(), newlang::toString(m_var_type_current)); + } + } else { + ASSERT(!is_scalar() && !value.is_scalar()); + m_tensor.add_(value.m_tensor); + } return shared(); } } @@ -387,10 +427,10 @@ ObjPtr Obj::operator+=(Obj value) { case ObjType::None: return shared(); case ObjType::StrChar: - m_str += value.m_str; + m_value += value.m_value; return shared(); case ObjType::StrWide: - m_wstr += value.m_wstr; + m_string += value.m_string; return shared(); } break; @@ -424,13 +464,30 @@ ObjPtr Obj::operator-=(Obj value) { m_var_type_current = value.m_var_type_current; } else if(is_tensor() && value.is_tensor()) { testResultIntegralType(value.m_var_type_current, true); - if(is_bool_type()) { - toType_(ObjType::Char); - } - if(value.is_bool_type()) { - value.toType_(ObjType::Char); + if(is_scalar() && value.is_scalar()) { + if(is_floating()) { + ASSERT(at::holds_alternative(m_var)); + m_var = GetValueAsNumber() - value.GetValueAsNumber(); + m_var_type_current = ObjType::Double; + } else if(is_integral() && value.is_integral()) { + ASSERT(at::holds_alternative(m_var)); + m_var = GetValueAsInteger() - value.GetValueAsInteger(); + m_var_type_current = typeFromLimit(GetValueAsInteger()); + } else { + LOG_RUNTIME("Fail convert '%s' to type %s!", value.toString().c_str(), newlang::toString(m_var_type_current)); + } + } else if(value.is_scalar()) { + if(value.is_floating()) { + m_tensor.sub_(value.GetValueAsNumber()); + } else if(value.is_integral()) { + m_tensor.sub_(value.GetValueAsInteger()); + } else { + LOG_RUNTIME("Fail convert '%s' to type %s!", value.toString().c_str(), newlang::toString(m_var_type_current)); + } + } else { + ASSERT(!is_scalar() && !value.is_scalar()); + m_tensor.sub_(value.m_tensor); } - m_value.sub_(value.m_value); return shared(); } switch(m_var_type_current) { @@ -464,7 +521,30 @@ ObjPtr Obj::operator*=(Obj value) { m_var_type_current = value.m_var_type_current; } else if(is_tensor() && value.is_tensor()) { testResultIntegralType(value.m_var_type_current, true); - m_value.mul_(value.m_value); + if(is_scalar() && value.is_scalar()) { + if(is_floating()) { + ASSERT(at::holds_alternative(m_var)); + m_var = GetValueAsNumber() * value.GetValueAsNumber(); + m_var_type_current = ObjType::Double; + } else if(is_integral() && value.is_integral()) { + ASSERT(at::holds_alternative(m_var)); + m_var = GetValueAsInteger() * value.GetValueAsInteger(); + m_var_type_current = typeFromLimit(GetValueAsInteger()); + } else { + LOG_RUNTIME("Fail convert '%s' to type %s!", value.toString().c_str(), newlang::toString(m_var_type_current)); + } + } else if(value.is_scalar()) { + if(value.is_floating()) { + m_tensor.mul_(value.GetValueAsNumber()); + } else if(value.is_integral()) { + m_tensor.mul_(value.GetValueAsInteger()); + } else { + LOG_RUNTIME("Fail convert '%s' to type %s!", value.toString().c_str(), newlang::toString(m_var_type_current)); + } + } else { + ASSERT(!is_scalar() && !value.is_scalar()); + m_tensor.mul_(value.m_tensor); + } return shared(); } @@ -482,19 +562,19 @@ ObjPtr Obj::operator*=(Obj value) { break; case ObjType::StrChar: - if(value.is_integer()) { - m_str = repeat(m_str, value.GetValueAsInteger()); + if(value.is_integral()) { + m_value = repeat(m_value, value.GetValueAsInteger()); return shared(); } else if(value.is_string_type()) { - m_str += value.GetValueAsString(); + m_value += value.GetValueAsString(); return shared(); } case ObjType::StrWide: - if(value.is_integer()) { - m_wstr = repeat(m_wstr, value.GetValueAsInteger()); + if(value.is_integral()) { + m_string = repeat(m_string, value.GetValueAsInteger()); return shared(); } else if(value.is_string_type()) { - m_wstr += utf8_decode(value.GetValueAsString()); + m_string += utf8_decode(value.GetValueAsString()); return shared(); } @@ -512,8 +592,31 @@ ObjPtr Obj::operator*=(Obj value) { ObjPtr Obj::operator/=(Obj value) { if(is_tensor() && value.is_tensor()) { - testResultIntegralType(ObjType::Double, false); - m_value.div_(value.m_value); + testResultIntegralType(ObjType::Double, true); + if(is_scalar() && value.is_scalar()) { + if(is_floating()) { + ASSERT(at::holds_alternative(m_var)); + m_var = GetValueAsNumber() / value.GetValueAsNumber(); + m_var_type_current = ObjType::Double; + } else if(is_integral() && value.is_integral()) { + ASSERT(at::holds_alternative(m_var)); + m_var = GetValueAsInteger() / value.GetValueAsInteger(); + m_var_type_current = typeFromLimit(GetValueAsInteger()); + } else { + LOG_RUNTIME("Fail convert '%s' to type %s!", value.toString().c_str(), newlang::toString(m_var_type_current)); + } + } else if(value.is_scalar()) { + if(value.is_floating()) { + m_tensor.div_(value.GetValueAsNumber()); + } else if(value.is_integral()) { + m_tensor.div_(value.GetValueAsInteger()); + } else { + LOG_RUNTIME("Fail convert '%s' to type %s!", value.toString().c_str(), newlang::toString(m_var_type_current)); + } + } else { + ASSERT(!is_scalar() && !value.is_scalar()); + m_tensor.div_(value.m_tensor); + } return shared(); } else if(m_var_type_current == ObjType::Fraction) { if(value.m_var_type_current == ObjType::Fraction) { @@ -530,9 +633,37 @@ ObjPtr Obj::op_div_ceil_(Obj & value) { if(is_tensor() && value.is_tensor()) { ObjType type = m_var_type_current; testResultIntegralType(ObjType::Float, false); - m_value.div_(value.m_value, "floor"); - m_value = m_value.toType(toTorchType(type)); + if(is_scalar() && value.is_scalar()) { + if(is_floating()) { + ASSERT(at::holds_alternative(m_var)); + m_var = floor(GetValueAsNumber() / value.GetValueAsNumber()); + m_var_type_current = ObjType::Double; + } else if(is_integral() && value.is_integral()) { + ASSERT(at::holds_alternative(m_var)); + m_var = static_cast (GetValueAsInteger() / value.GetValueAsInteger()); + m_var_type_current = typeFromLimit(GetValueAsInteger()); + } else { + LOG_RUNTIME("Fail convert '%s' to type %s!", value.toString().c_str(), newlang::toString(m_var_type_current)); + } + } else if(value.is_scalar()) { + if(value.is_floating()) { + m_tensor.div_(value.GetValueAsNumber(), "floor"); + } else if(value.is_integral()) { + m_tensor.div_(value.GetValueAsInteger(), "floor"); + } else { + LOG_RUNTIME("Fail convert '%s' to type %s!", value.toString().c_str(), newlang::toString(m_var_type_current)); + } + } else { + ASSERT(!is_scalar() && !value.is_scalar()); + m_tensor.div_(value.m_tensor, "floor"); + m_tensor = m_tensor.toType(toTorchType(type)); + } + // ObjType type = m_var_type_current; + // testResultIntegralType(ObjType::Float, false); + // m_tensor.div_(value.m_tensor, "floor"); + // m_tensor = m_tensor.toType(toTorchType(type)); return shared(); + } else if(m_var_type_current == ObjType::Fraction) { // if(value.m_var_type_current == ObjType::Fraction) { // m_fraction->operator/=(value.m_fraction); @@ -546,8 +677,29 @@ ObjPtr Obj::op_div_ceil_(Obj & value) { ObjPtr Obj::operator%=(Obj value) { if(is_tensor() && value.is_tensor()) { - testResultIntegralType(value.m_var_type_current, false); - m_value.fmod_(value.m_value); + testResultIntegralType(value.m_var_type_current, true); + if(is_scalar() && value.is_scalar()) { + if(is_floating()) { + ASSERT(at::holds_alternative(m_var)); + m_var = fmod(GetValueAsNumber(), value.GetValueAsNumber()); + } else if(is_integral() && value.is_integral()) { + ASSERT(at::holds_alternative(m_var)); + m_var = GetValueAsInteger() % value.GetValueAsInteger(); + } else { + LOG_RUNTIME("Fail convert '%s' to type %s!", value.toString().c_str(), newlang::toString(m_var_type_current)); + } + } else if(value.is_scalar()) { + if(value.is_floating()) { + m_tensor.fmod_(value.GetValueAsNumber()); + } else if(value.is_integral()) { + m_tensor.fmod_(value.GetValueAsInteger()); + } else { + LOG_RUNTIME("Fail convert '%s' to type %s!", value.toString().c_str(), newlang::toString(m_var_type_current)); + } + } else { + ASSERT(!is_scalar() && !value.is_scalar()); + m_tensor.fmod_(value.m_tensor); + } return shared(); } else if(m_var_type_current == ObjType::Fraction) { // if(value.m_var_type_current == ObjType::Fraction) { @@ -589,8 +741,8 @@ void Obj::CloneDataTo(Obj & clone) const { } clone.m_var_name = m_var_name; - clone.m_str = m_str; - clone.m_wstr = m_wstr; + clone.m_value = m_value; + clone.m_string = m_string; if(m_fraction) { clone.m_fraction = std::make_shared(*m_fraction.get()); @@ -603,12 +755,12 @@ void Obj::CloneDataTo(Obj & clone) const { clone.m_class_name = m_class_name; clone.m_is_const = m_is_const; - clone.m_func_ptr = m_func_ptr; - if(m_func_proto) { - *const_cast (&clone.m_func_proto) = m_func_proto; + clone.m_var = m_var; + if(m_prototype) { + *const_cast (&clone.m_prototype) = m_prototype; } - if(is_tensor() && m_var_is_init) { - clone.m_value = m_value.clone(); + if(m_tensor.defined()) { + clone.m_tensor = m_tensor.clone(); } } } @@ -638,14 +790,14 @@ void Obj::SetTermProp(Term & term) { m_namespace = term.m_namespace; } -void newlang::calcTensorDims(ObjPtr &obj, std::vector &dims) { - if(obj->is_dictionary_type()) { - dims.push_back(obj->size()); - if(obj->size()) { - calcTensorDims(obj->at(0).second, dims); - } - } -} +//void newlang::calcTensorDims(ObjPtr &obj, std::vector &dims) { +// if(obj->is_dictionary_type()) { +// dims.push_back(obj->size()); +// if(obj->size()) { +// calcTensorDims(obj->at(0).second, dims); +// } +// } +//} ObjPtr Obj::GetIndex(ObjPtr obj, TermPtr index_arg) { ASSERT(index_arg->size() == 1); @@ -670,8 +822,8 @@ std::string Obj::toString(bool deep) const { std::stringstream ss; if(m_var_type_current == ObjType::None) { - if(m_func_proto && m_func_proto->GetType()) { - result += m_func_proto->GetType()->toString(); + if(m_prototype && m_prototype->GetType()) { + result += m_prototype->GetType()->toString(); } else if(m_var_type_fixed != ObjType::None) { result += newlang::toString(m_var_type_fixed); } @@ -681,7 +833,8 @@ std::string Obj::toString(bool deep) const { if(is_scalar()) { result += GetValueAsString(); } else { - result += TensorToString(m_value); + ASSERT(m_tensor.defined()); + result += TensorToString(m_tensor); } return result; } else if(isSimpleType(m_var_type_current)) { @@ -696,13 +849,13 @@ std::string Obj::toString(bool deep) const { case ObjType::StrChar: result += "'"; - result += m_str; + result += m_value; result.append("'"); return result; case ObjType::StrWide: // name:='string' or name:="string" result += "\""; - result += utf8_encode(m_wstr); + result += utf8_encode(m_string); result.append("\""); return result; @@ -743,7 +896,8 @@ std::string Obj::toString(bool deep) const { return result; case ObjType::Pointer: - ss << m_func_ptr; + ASSERT(at::holds_alternative(m_var)); + ss << at::get(m_var); result += ss.str(); result += ":Pointer"; return result; @@ -773,13 +927,13 @@ std::string Obj::toString(bool deep) const { case ObjType::NativeFunc: case ObjType::Function: // name:={function code} case ObjType::PureFunc: // name=>{function code} - ASSERT(m_func_proto); - result += m_func_proto->m_text; + ASSERT(m_prototype); + result += m_prototype->m_text; result += "("; - m_func_proto->dump_items_(result); + m_prototype->dump_items_(result); result += ")"; - if(!m_func_proto->m_type_name.empty()) { - result += m_func_proto->m_type_name; + if(!m_prototype->m_type_name.empty()) { + result += m_prototype->m_type_name; } case ObjType::BLOCK: @@ -795,13 +949,13 @@ std::string Obj::toString(bool deep) const { case ObjType::SimplePureAND: case ObjType::SimplePureOR: case ObjType::SimplePureXOR: - ASSERT(m_func_proto); - result += m_func_proto->m_text; + ASSERT(m_prototype); + result += m_prototype->m_text; result += "("; - m_func_proto->dump_items_(result); + m_prototype->dump_items_(result); result += ")"; - if(!m_func_proto->m_type_name.empty()) { - result += m_func_proto->m_type_name; + if(!m_prototype->m_type_name.empty()) { + result += m_prototype->m_type_name; } if(m_var_type_current == ObjType::EVAL_FUNCTION) { @@ -818,16 +972,16 @@ std::string Obj::toString(bool deep) const { LOG_RUNTIME("Fail function type"); } - if(m_block_source->getTermID() != TermID::BLOCK) { + if(m_sequence->getTermID() != TermID::BLOCK) { result += "{"; } - if(m_block_source) { - result += m_block_source->toString(); - if(m_block_source->getTermID() != TermID::BLOCK) { + if(m_sequence) { + result += m_sequence->toString(); + if(m_sequence->getTermID() != TermID::BLOCK) { result += ";"; } } - if(m_block_source->getTermID() != TermID::BLOCK) { + if(m_sequence->getTermID() != TermID::BLOCK) { result.append("}"); } return result; @@ -907,17 +1061,8 @@ std::string newlang::TensorToString(const torch::Tensor & tensor) { std::string result; std::stringstream ss; - if(tensor.dim() == 0) { - if(tensor.is_floating_point()) { - ss << tensor.item(); - ss >> result; - } else if(tensor.is_complex()) { - ASSERT(!"Not implemented!"); - // return std::to_string(tensor.item>()); - } else { - result = std::to_string(tensor.item()); - } - return result; + if(!tensor.dim()) { + ASSERT(tensor.dim()); } c10::IntArrayRef shape = tensor.sizes(); // Кол-во эментов в каждом измерении @@ -955,15 +1100,26 @@ std::string Obj::GetValueAsString() const { case ObjType::Complex: case ObjType::ComplexFloat: case ObjType::ComplexDouble: - return TensorToString(m_value); + if(is_scalar()) { + if(is_integral()) { + return std::to_string(GetValueAsInteger()); + } else if(is_floating()) { + ss << GetValueAsNumber(); + return ss.str(); + } else { + ASSERT(!"Not implemented!"); + } + } else { + return TensorToString(m_tensor); + } case ObjType::StrChar: case ObjType::FmtChar: - return m_str; + return m_value; case ObjType::StrWide: case ObjType::FmtWide: - return utf8_encode(m_wstr); + return utf8_encode(m_string); case ObjType::NativeFunc: case ObjType::Function: @@ -984,13 +1140,14 @@ std::string Obj::GetValueAsString() const { if(!m_var_name.empty()) { result += ": "; } - temp = m_str; + temp = m_value; trim(temp, "\n"); result += temp; return result; case ObjType::Pointer: - ss << m_func_ptr; + ASSERT(at::holds_alternative(m_var)); + ss << at::get(m_var); result += ss.str(); if(m_class_name.empty()) { result += ":Pointer"; @@ -1021,8 +1178,8 @@ ObjPtr Obj::CreateFunc(std::string prototype, FunctionType *func_addr, ObjType t ObjPtr result = Obj::CreateType(type, type); - * const_cast (&result->m_func_proto) = proto; - result->m_func_ptr = (void *) func_addr; + * const_cast (&result->m_prototype) = proto; + result->m_var = (void *) func_addr; return result; } @@ -1033,7 +1190,7 @@ ObjPtr Obj::CreateFunc(Context *ctx, TermPtr proto, ObjType type, const std::str Obj local; Obj args(ctx, proto, false, &local); args.ClonePropTo(*result); - *const_cast (&result->m_func_proto) = proto; + *const_cast (&result->m_prototype) = proto; if(!result->CheckArgs()) { LOG_RUNTIME("Fail create function '%s'!", proto->toString().c_str()); } @@ -1050,12 +1207,13 @@ Obj::Obj(Context *ctx, const TermPtr term, bool as_value, Obj * local_vars) { m_is_reference = term->m_is_ref; m_var_name = term->m_name.empty() ? term->m_text : term->m_name; m_var_type_current = ObjType::Dictionary; - // m_func_abi = FFI_DEFAULT_ABI; m_dimensions = nullptr; m_var_is_init = false; m_is_const = false; + m_var = at::monostate(); + ASSERT(!m_tensor.defined()); - *const_cast (&m_func_proto) = term; + *const_cast (&m_prototype) = term; for (int i = 0; i < term->size(); i++) { if(term->name(i).empty()) { @@ -1103,13 +1261,13 @@ bool Obj::CheckArgs() const { ObjPtr Obj::Call(Context *ctx, Obj * args) { if(is_string_type()) { ObjPtr result = Clone(); - result->m_str = format(result->m_str, args); + result->m_value = format(result->m_value, args); return result; } else if(is_function() || m_var_type_current == ObjType::Type) { Obj local; ObjPtr param; - if(m_func_proto) { - param = std::make_shared(ctx, m_func_proto, false, &local); + if(m_prototype) { + param = std::make_shared(ctx, m_prototype, false, &local); } else { param = Obj::CreateDict(); } @@ -1122,19 +1280,21 @@ ObjPtr Obj::Call(Context *ctx, Obj * args) { ObjPtr result; if(m_var_type_current == ObjType::Function) { - result = (*reinterpret_cast (m_func_ptr))(ctx, *param.get()); // Непосредственно вызов функции - } else if(m_var_type_current == ObjType::PureFunc || (m_var_type_current == ObjType::Type && m_func_ptr)) { - result = (*reinterpret_cast (m_func_ptr))(ctx, *param.get()); // Непосредственно вызов функции + ASSERT(at::holds_alternative(m_var)); + result = (*reinterpret_cast (at::get(m_var)))(ctx, *param.get()); // Непосредственно вызов функции + } else if(m_var_type_current == ObjType::PureFunc || (m_var_type_current == ObjType::Type)) { + ASSERT(at::holds_alternative(m_var)); + result = (*reinterpret_cast (at::get(m_var)))(ctx, *param.get()); // Непосредственно вызов функции } else if(m_var_type_current == ObjType::NativeFunc) { result = CallNative(ctx, *param.get()); } else if(m_var_type_current == ObjType::EVAL_FUNCTION || m_var_type_current == ObjType::SimplePureFunc) { - result = Context::CallBlock(ctx, m_block_source, param.get(), false); + result = Context::CallBlock(ctx, m_sequence, param.get(), false); } else if(m_var_type_current == ObjType::SimplePureAND) { - result = Context::EvalBlockAND(ctx, m_block_source, param.get()); + result = Context::EvalBlockAND(ctx, m_sequence, param.get()); } else if(m_var_type_current == ObjType::SimplePureOR) { - result = Context::EvalBlockOR(ctx, m_block_source, param.get()); + result = Context::EvalBlockOR(ctx, m_sequence, param.get()); } else if(m_var_type_current == ObjType::SimplePureXOR) { - result = Context::EvalBlockXOR(ctx, m_block_source, param.get()); + result = Context::EvalBlockXOR(ctx, m_sequence, param.get()); } else { LOG_RUNTIME("Call by name not implemted '%s'!", toString().c_str()); } @@ -1192,28 +1352,28 @@ void Obj::ConvertToArgs_(Obj *in, bool check_valid, Context * ctx) { if(!at(i).second) { at(i).second = Obj::CreateNone(); } - if(m_func_proto && i < m_func_proto->size()) { - at(i).second->m_is_reference = (*m_func_proto)[i].second->isRef(); + if(m_prototype && i < m_prototype->size()) { + at(i).second->m_is_reference = (*m_prototype)[i].second->isRef(); ObjType base_type = ObjType::None; if(ctx) { - base_type = ctx->BaseTypeFromString((*m_func_proto)[i].second->m_type_name); + base_type = ctx->BaseTypeFromString((*m_prototype)[i].second->m_type_name); } else { - base_type = typeFromString((*m_func_proto)[i].second->m_type_name, ctx); + base_type = typeFromString((*m_prototype)[i].second->m_type_name, ctx); } ObjType limit_type = (*in)[i].second->getTypeAsLimit(); if(!canCast(limit_type, base_type)) { // Строку с одним символом можно преобразовать в арифметичсекий тип if(!(isArithmeticType(base_type) && (*in)[i].second->is_string_type() && (*in)[i].second->size() == 1)) { LOG_RUNTIME("Fail cast value '%s' to type '%s'", - (*in)[i].second->toString().c_str(), (*m_func_proto)[i].second->m_type_name.c_str()); + (*in)[i].second->toString().c_str(), (*m_prototype)[i].second->m_type_name.c_str()); } } } at(i).second->op_assign((*in)[i].second); } else { - if(check_valid && !is_ellipsis && m_func_proto && i >= m_func_proto->size()) { + if(check_valid && !is_ellipsis && m_prototype && i >= m_prototype->size()) { LOG_RUNTIME("Positional args overflow. Ptrototype '%s'!", - m_func_proto ? m_func_proto->toString().c_str() : "Prototype not exists!"); + m_prototype ? m_prototype->toString().c_str() : "Prototype not exists!"); } push_back(in->at(i)); } @@ -1297,10 +1457,10 @@ int Obj::op_compare(Obj & value) { } else if((is_string_type() && value.is_string_type())) { switch(m_var_type_current) { case ObjType::StrChar: - return m_str.compare(value.GetValueAsString()); + return m_value.compare(value.GetValueAsString()); case ObjType::StrWide: - return m_wstr.compare(value.GetValueAsStringWide()); + return m_string.compare(value.GetValueAsStringWide()); } } LOG_RUNTIME("Fail compare type %s and %s", newlang::toString(m_var_type_current), newlang::toString(value.m_var_type_current)); @@ -1322,27 +1482,25 @@ bool Obj::op_equal(Obj & value) { if(this == &value) { return true; } else if(is_tensor()) { - // Арифметические типы данных сравниваются как тензоры - torch::Dtype summary_type = toTorchType( - static_cast (std::max(static_cast (m_var_type_current), static_cast (value.m_var_type_current)))); + ObjType summary_type = static_cast (std::max( + static_cast (m_var_type_current), + static_cast (value.m_var_type_current))); try { - if(m_value.dim() == 0 || value.m_value.dim() == 0) { - if(m_value.dim() == 0 && value.m_value.dim() == 0) { - - ObjType type = fromTorchType(summary_type); - - if(isIntegralType(type, true)) { + if(is_scalar() || value.is_scalar()) { + if(is_scalar() && value.is_scalar()) { + if(isIntegralType(summary_type, true)) { return GetValueAsInteger() == value.GetValueAsInteger(); - } else if(isFloatingType(type)) { + } else if(isFloatingType(summary_type)) { return GetValueAsNumber() == value.GetValueAsNumber(); } else { - LOG_RUNTIME("Fail compare type '%s'!", newlang::toString(type)); + LOG_RUNTIME("Fail compare type '%s'!", newlang::toString(summary_type)); } } return false; } + torch::Dtype summary_torch_type = toTorchType(static_cast (summary_type)); + return m_tensor.toType(summary_torch_type).equal(value.toType(summary_type)->m_tensor); - return m_value.toType(summary_type).equal(value.toTensor().toType(summary_type)); } catch (std::exception e) { LOG_RUNTIME("Fail compare"); //, e.what()); } @@ -1382,7 +1540,7 @@ bool Obj::op_accurate(Obj & value) { ObjPtr Obj::op_bit_and_set(Obj &obj, bool strong) { if(m_var_type_current == ObjType::Long) { if(m_var_type_current == obj.m_var_type_current) { - m_value.bitwise_and_(obj.m_value); + m_tensor.bitwise_and_(obj.m_tensor); // m_values.integer &= obj.m_values.integer; return shared(); } @@ -1493,21 +1651,37 @@ bool Obj::op_duck_test_prop(Obj *base, Obj *value, bool strong) { ObjPtr Obj::op_pow_(Obj & obj) { if(is_tensor()) { - m_value.pow_(obj.toTensor()); - return shared(); - } else if(is_arithmetic_type()) { - if(is_integer()) { - SetValue_(static_cast (pow(GetValueAsInteger(), obj.GetValueAsInteger()) + 0.5)); - return shared(); - } else if(isFloatingType(m_var_type_current)) { - SetValue_(pow(GetValueAsNumber(), obj.GetValueAsNumber())); - return shared(); + ASSERT(obj.is_arithmetic_type()); + if(is_scalar()) { + double temp = pow(GetValueAsNumber(), obj.GetValueAsNumber()); + if(is_integral()) { + if(temp > static_cast (std::numeric_limits::max())) { + LOG_ERROR("Integer overflow!"); + } + m_var = static_cast (llround(temp)); + } else { + m_var = temp; + } + } else { + ASSERT(m_tensor.defined()); + m_tensor.pow_(obj.GetValueAsNumber()); } - } else if(m_var_type_current == ObjType::StrChar && obj.is_integer()) { - m_str = repeat(m_str, obj.GetValueAsInteger()); return shared(); - } else if(m_var_type_current == ObjType::StrWide && obj.is_integer()) { - m_wstr = repeat(m_wstr, obj.GetValueAsInteger()); + } else if(is_fraction()) { + + ASSERT(m_fraction); + ObjPtr temp = obj.toType(ObjType::Fraction); + ASSERT(temp); + ASSERT(temp->m_fraction); + + m_fraction->op_pow_(*temp->m_fraction.get()); + return shared(); + + } else if(m_var_type_current == ObjType::StrChar && obj.is_integral()) { + m_value = repeat(m_value, obj.GetValueAsInteger()); + return shared(); + } else if(m_var_type_current == ObjType::StrWide && obj.is_integral()) { + m_string = repeat(m_string, obj.GetValueAsInteger()); return shared(); } else if(m_var_type_current == ObjType::Fraction) { // if(value.m_var_type_current == ObjType::Fraction) { @@ -1588,236 +1762,6 @@ std::string Obj::format(std::string format, Obj * args) { return format; } -ObjPtr Obj::toShape_(ObjPtr dims) { - std::vector array = dims->toIntVector(true); - if(is_tensor()) { - m_value.resize_(array); - return shared(); - } - - if(array.size() > 1) { - LOG_RUNTIME("More than one dimension is not supported!"); - } else if(array.size() == 0) { - // Ноль измерений не у тензора только у None - toType_(ObjType::None); - return shared(); - - } else if(size() == array[0]) { - // Требуемый размер - return shared(); - } - - if(m_var_type_current == ObjType::StrChar) { - m_str.resize(array[0]); - } else if(m_var_type_current == ObjType::StrWide) { - m_wstr.resize(array[0]); - } else if(is_dictionary_type()) { - - if(size() > array[0]) { - ListType::resize(array[0]); // Уменьшить размер - } else { - while(size() < array[0]) { - push_back(Obj::CreateNone()); - } - } - } else { - - LOG_RUNTIME("Reshaping is not supported!"); - } - return shared(); -} - -ObjPtr Obj::toType_(Obj * type) { - ASSERT(type); - if(type->m_var_type_current != ObjType::Type) { - LOG_RUNTIME("Fail type object '%s'!", type->toString().c_str()); - } - - toType_(type->m_var_type_fixed); //, &ref - return shared(); -} - -void Obj::toType_(ObjType target) { - if(m_var_type_current == target) { - // Конвертировать не нужно - return; - - } else if(is_none_type() || target == ObjType::None) { - // Любой тип при конвертации в пустой, просто очистить данные - clear_(); - m_var_type_current = target; - return; - - } else if(is_tensor()) { - // Из тензора конвертировать в другой тип - if(isTensor(target)) { - m_value = m_value.toType(toTorchType(target)); - m_var_type_current = target; - Variable::clear_(); - return; - - } else if(isString(target)) { - if(target == ObjType::StrChar) { - // В байтовую строку конвертируются только байтовый скаляр или одномерный байтовый тензор - if(!(m_value.dtype().toScalarType() == at::ScalarType::Byte || m_value.dtype().toScalarType() == at::ScalarType::Char)) { - LOG_RUNTIME("Convert to byte string can 1-byte tensor only!"); - } - - if(m_value.dim() == 0) { - m_str.resize(1); - m_str[0] = m_value.item().toInt(); - } else if(m_value.dim() == 1) { - m_str.clear(); - for (int i = 0; i < m_value.size(0); i++) { - m_str += m_value.index({i}).item().toChar(); - } - } else { - LOG_RUNTIME("Convert to string single dimension tensor only!"); - } - m_var_type_current = target; - return; - - - } else { // ObjType::StrWide - ASSERT(target == ObjType::StrWide); - - // В символьную строку конвертируется любой целочисленный скаляр или одномерный тензор - if(!(m_value.dtype().toScalarType() == at::ScalarType::Byte || m_value.dtype().toScalarType() == at::ScalarType::Char || - m_value.dtype().toScalarType() == at::ScalarType::Short || m_value.dtype().toScalarType() == at::ScalarType::Int)) { - LOG_RUNTIME("Convert to wide string can 1..4 byte tensor only!"); - } - - STATIC_ASSERT(sizeof (wchar_t) <= sizeof (int32_t)); - - if(m_value.dim() == 0) { - m_wstr.resize(1); - m_wstr[0] = m_value.item().toInt(); - } else if(m_value.dim() == 1) { - m_wstr.clear(); - for (int i = 0; i < m_value.size(0); i++) { - m_wstr += m_value.index({i}).item().toInt(); - } - } else { - LOG_RUNTIME("Convert to string single dimension tensor only!"); - } - - m_var_type_current = target; - return; - } - } else if(isDictionary(target)) { - m_var_type_current = target; - ConvertTensorToDict(m_value, *this); - m_value.reset(); - return; - } else if(target == ObjType::Fraction) { - if(!is_scalar()) { - LOG_RUNTIME("Fraction convert support for scalar only!"); - } - m_fraction = std::make_shared(GetValueAsInteger()); - m_value.reset(); - m_var_type_current = target; - return; - } - } else if(is_string_type()) { - // Из строки в другой тип данных - // if(isString(target)) { - // // Строки хранятся в байтовом представлении и их ненужно конвертировать - // m_var_type_current = target; - // return; - // } else - if(isTensor(target)) { - // Сконвертировать строку в тензор - torch::Tensor std_data; - std::wstring_convert < std::codecvt_utf8, wchar_t> converter; - std::wstring temp; - if(m_var_type_current == ObjType::StrChar) { - // Байтовая строка конвертируются в одномерный байтовый тензор - std_data = torch::from_blob((void *) m_str.data(),{(int) m_str.size()}, torch::Dtype::Char); - } else { // ObjType::StrWide - ASSERT(m_var_type_current == ObjType::StrWide); - if(sizeof (wchar_t) == sizeof (int32_t)) { - std_data = torch::from_blob((void *) m_wstr.data(),{(int) m_wstr.size()}, torch::Dtype::Int); - } else if(sizeof (wchar_t) == sizeof (int16_t)) { - std_data = torch::from_blob((void *) m_wstr.data(),{(int) m_wstr.size()}, torch::Dtype::Short); - } else { - LOG_RUNTIME("Unsupport wchar_t size '%d'!!!", (int) sizeof (wchar_t)); - } - std_data = std_data.toType(torch::Dtype::Int); - } - if(isGenericType(target) && !isContainsType(target, fromTorchType(std_data.scalar_type()))) { - m_value = std_data.toType(toTorchType(target)); - } else { - m_value = std_data.clone(); - } - - m_str.clear(); - m_wstr.clear(); - m_var_type_current = target; - return; - - } else if(isDictionary(target)) { - - torch::Tensor temp; - ConvertValueToTensor(this, temp); - - m_var_type_current = target; - ConvertTensorToDict(temp, *this); - m_str.clear(); - m_wstr.clear(); - return; - } else if(target == ObjType::Fraction) { - m_fraction = std::make_shared(GetValueAsString(), "1"); - m_var_type_current = target; - m_str.clear(); - m_wstr.clear(); - return; - } - - } else if(is_dictionary_type()) { - // Из словаря в другой тип данных - if(isString(target)) { - // Допустимо (обратная реализация чуть выше) - LOG_RUNTIME("Not implemented!!!"); - } else if(isDictionary(target)) { - // Словрь в словарь - ничего не делаем - m_var_type_current = target; - return; - } else if(isTensor(target)) { - - ConvertDictToTensor(*this, m_value, target); - - m_var_type_current = fromTorchType(m_value.scalar_type()); - return; - - } - } else if(m_var_type_current == ObjType::Range) { - // Из диапазона в другой тип данных - if(isDictionary(target) || isTensor(target)) { - // В словарь - - ObjPtr temp = Obj::CreateDict(); - - ConvertRangeToDict(this, *temp.get()); - - Variable::clear_(); - - if(isTensor(target)) { - // В тензор - ConvertDictToTensor(*temp.get(), m_value, target); - m_var_type_current = target; - - } else { - m_var_type_current = ObjType::Dictionary; - temp->ClonePropTo(*this); - } - return; - } - } - // Остальные варианты предобразований выполнить нельзя - LOG_RUNTIME("Can`t convert type '%s'(%d) to type '%s'(%d)!", - newlang::toString(m_var_type_current), (int) m_var_type_current, newlang::toString(target), (int) target); -} - int64_t newlang::ConcatData(Obj *dest, Obj &src, ConcatMode mode) { int64_t size = 0; ASSERT(dest); @@ -1836,11 +1780,11 @@ int64_t newlang::ConcatData(Obj *dest, Obj &src, ConcatMode mode) { if(dest->m_var_type_current == ObjType::StrChar) { std::string add = src.GetValueAsString(); - dest->m_str.append(add); + dest->m_value.append(add); size = add.size(); } else if(dest->m_var_type_current == ObjType::StrWide) { std::wstring add = src.GetValueAsStringWide(); - dest->m_wstr.append(add); + dest->m_string.append(add); size = add.size(); } else { LOG_RUNTIME("Unknown string type %s!", dest->toString().c_str()); @@ -1857,13 +1801,13 @@ int64_t newlang::ConcatData(Obj *dest, Obj &src, ConcatMode mode) { } else if(dest->is_tensor()) { if(dest->m_var_type_current == src.m_var_type_current) { - if(dest->m_value.dim() == 0) { - dest->m_value.resize_(1); + if(dest->m_tensor.dim() == 0) { + dest->m_tensor.resize_(1); } - if(src.m_value.dim() == 0) { - src.m_value.resize_(1); + if(src.m_tensor.dim() == 0) { + src.m_tensor.resize_(1); } - dest->m_value = torch::cat({dest->m_value, src.m_value}); + dest->m_tensor = torch::cat({dest->m_tensor, src.m_tensor}); // size += src.m_value.si } else { ObjPtr temp = src.toType(dest->m_var_type_current); @@ -1895,128 +1839,6 @@ std::vector newlang::TensorShapeFromDict(const Obj * obj) { return shape; } -torch::Tensor newlang::ConvertToTensor(Obj *data, at::ScalarType type, bool reshape) { - ASSERT(data); - - if(data->is_tensor()) { - // Прообразование один в один - if(type == at::ScalarType::Undefined) { - if(data->is_scalar()) { - return data->m_value.reshape({1}); - } - return data->m_value.clone(); - } else { - if(data->is_scalar()) { - return data->m_value.reshape({1}).toType(type); - } - return data->m_value.clone().toType(type); - } - } else if(data->m_var_type_current == ObjType::StrChar) { - if(type == at::ScalarType::Undefined) { - type = at::ScalarType::Char; - } - // В байтовую строку конвертируются только байтовый скаляр или одномерный байтовый тензор - return torch::from_blob((void *) data->m_str.data(), data->m_str.size(), type).clone(); - } else if(data->m_var_type_current == ObjType::StrWide) { - if(type == at::ScalarType::Undefined) { - if(sizeof (wchar_t) == sizeof (int32_t)) { - type = at::ScalarType::Int; - } else if(sizeof (wchar_t) == sizeof (int16_t)) { - type = at::ScalarType::Short; - } else { - LOG_RUNTIME("Unsupport wchar_t size '%d'!!!", (int) sizeof (wchar_t)); - } - } - // В символьную строку конвертируется любой целочисленный скаляр или одномерный тензор - return torch::from_blob((void *) data->m_wstr.data(), { - (int) data->m_wstr.size() - }, type).toType(at::ScalarType::Int).clone(); - } else if(data->is_range()) { - - ASSERT(data->at("start").second); - ASSERT(data->at("stop").second); - ASSERT(data->at("step").second); - ASSERT(data->at("start").second->is_arithmetic_type() || data->at("start").second->is_bool_type()); - ASSERT(data->at("stop").second->is_arithmetic_type() || data->at("stop").second->is_bool_type()); - ASSERT(data->at("step").second->is_arithmetic_type() || data->at("step").second->is_bool_type()); - - ObjPtr dict = Obj::CreateDict(); - if(data->at("start").second->is_floating() || data->at("stop").second->is_floating() || data->at("step").second->is_floating()) { - double value = data->at("start").second->GetValueAsNumber(); - double stop = data->at("stop").second->GetValueAsNumber(); - double step = data->at("step").second->GetValueAsNumber(); - for (; value < stop; value += step) { - dict->push_back(Obj::CreateValue(value, ObjType::None)); - } - type = toTorchType(ObjType::Double); - } else { - int64_t value = data->at("start").second->GetValueAsInteger(); - int64_t stop = data->at("stop").second->GetValueAsInteger(); - int64_t step = data->at("step").second->GetValueAsInteger(); - for (; value < stop; value += step) { - dict->push_back(Obj::CreateValue(value, ObjType::None)); - } - } - return ConvertToTensor(dict.get(), type, reshape); - - } else if(data->is_dictionary_type()) { - if(type == at::ScalarType::Undefined) { - type = at::ScalarType::Char; - } - std::vector shape; - - if(reshape) { - shape = TensorShapeFromDict(data); - ASSERT(shape.size()); - } - - // Из словаря - torch::Tensor result = ConvertToTensor(data->index_get({0}).get(), type, false); - if(result.dim() == 0) { - result.resize_(1); - } - for (int i = 1; i < data->size(); i++) { - torch::Tensor temp = ConvertToTensor(data->index_get({i}).get(), type, false); - if(temp.dim() == 0) { - temp.resize_(1); - } - result = torch::cat({result, temp}); - } - - if(reshape) { - return result.reshape(shape); - } - return result; - - } else if(data->is_none_type() || (data->is_dictionary_type() && data->size() == 0)) { - // Пустое значение или пустой словарь не конвертируются - LOG_RUNTIME("Not implemented!"); - - } else if(data->is_function()) { - // Как преобразовать функцию? И нужно ли это делать? - - LOG_RUNTIME("Not implemented!"); - } - // Остальные варианты преобразований выполнить нельзя (Error + служебные) - LOG_RUNTIME("Can`t convert type %d to tensor!", (int) data->m_var_type_current); -} - -at::TensorOptions newlang::ConvertToTensorOptions(const Obj * obj) { - if(!obj || obj->is_none_type()) { - - return at::TensorOptions(); - } - LOG_RUNTIME("Not implemented!"); -} - -at::DimnameList newlang::ConvertToDimnameList(const Obj * obj) { - if(!obj || obj->is_none_type()) { - - return {}; - } - LOG_RUNTIME("Not implemented!"); -} - ObjPtr Obj::CallNative(Context *ctx, Obj args) { if(!ctx || !ctx->m_runtime) { @@ -2027,11 +1849,11 @@ ObjPtr Obj::CallNative(Context *ctx, Obj args) { std::vector arg_types; std::vector arg_generic; - ObjType type_result = ctx->BaseTypeFromString(m_func_proto->m_type_name); + ObjType type_result = ctx->BaseTypeFromString(m_prototype->m_type_name); LLVMTypeRef return_llvm_type = toLLVMType(type_result); - bool is_ellipsis = (m_func_proto->size() && (*m_func_proto)[m_func_proto->size() - 1].second->getTermID() == TermID::ELLIPSIS); - size_t check_count = is_ellipsis ? m_func_proto->size() - 1 : m_func_proto->size(); + bool is_ellipsis = (m_prototype->size() && (*m_prototype)[m_prototype->size() - 1].second->getTermID() == TermID::ELLIPSIS); + size_t check_count = is_ellipsis ? m_prototype->size() - 1 : m_prototype->size(); bool pointer_exist = false; // Пропустить нулевой аргумент для нативных функций @@ -2046,21 +1868,21 @@ ObjPtr Obj::CallNative(Context *ctx, Obj args) { ObjType type = args[i].second->getTypeAsLimit(); if(pind < check_count) { - NL_CHECK(!(*m_func_proto)[pind].second->m_type_name.empty(), "Undefined type arg '%s'", (*m_func_proto)[pind].second->toString().c_str()); + NL_CHECK(!(*m_prototype)[pind].second->m_type_name.empty(), "Undefined type arg '%s'", (*m_prototype)[pind].second->toString().c_str()); - ObjType proto_type = typeFromString((*m_func_proto)[pind].second->m_type_name, ctx); + ObjType proto_type = typeFromString((*m_prototype)[pind].second->m_type_name, ctx); if(!canCast(type, proto_type)) { if(!((type == ObjType::StrChar || type == ObjType::FmtChar) && proto_type == ObjType::Char) || ((type == ObjType::StrWide || type == ObjType::FmtWide) && proto_type == ObjType::Int)) { - LOG_RUNTIME("Fail cast from '%s' to '%s'", (*m_func_proto)[pind].second->m_type_name.c_str(), newlang::toString(type)); + LOG_RUNTIME("Fail cast from '%s' to '%s'", (*m_prototype)[pind].second->m_type_name.c_str(), newlang::toString(type)); } } } ObjType check_type; if(pind < check_count) { - std::string temp_str = (*m_func_proto)[pind].second->m_type_name; - check_type = typeFromString((*m_func_proto)[pind].second->m_type_name, ctx); + std::string temp_str = (*m_prototype)[pind].second->m_type_name; + check_type = typeFromString((*m_prototype)[pind].second->m_type_name, ctx); } else { check_type = args[i].second->getType(); } @@ -2083,8 +1905,8 @@ ObjPtr Obj::CallNative(Context *ctx, Obj args) { arg_types.push_back(temp); arg_generic.push_back(args[i].second->GetGenericValueRef(temp)); - if(pind < check_count && (*m_func_proto)[pind].second->GetType()) { - if((*m_func_proto)[pind].second->GetType()->m_text.compare(newlang::toString(ObjType::FmtChar)) == 0) { + if(pind < check_count && (*m_prototype)[pind].second->GetType()) { + if((*m_prototype)[pind].second->GetType()->m_text.compare(newlang::toString(ObjType::FmtChar)) == 0) { NL_CHECK(ParsePrintfFormat(&args, i), "Fail format string or type args!"); } } @@ -2115,7 +1937,7 @@ ObjPtr Obj::CallNative(Context *ctx, Obj args) { // LLVMValueRef param_call[] = {LLVMGetParam(wrap, 0)}; LLVMValueRef func_call = LLVMAddFunction(module, "m_func_ptr", func_res_type); // Имя функции может пересечся с сужествующими при связывании????? - LLVMValueRef func_ret = LLVMBuildCall2(ctx->m_llvm_builder, func_res_type, func_call, args_param.data(), static_cast (args_param.size()), m_func_proto->m_text.c_str()); + LLVMValueRef func_ret = LLVMBuildCall2(ctx->m_llvm_builder, func_res_type, func_call, args_param.data(), static_cast (args_param.size()), m_prototype->m_text.c_str()); //return value LLVMBuildRet(ctx->m_llvm_builder, func_ret); @@ -2149,7 +1971,8 @@ ObjPtr Obj::CallNative(Context *ctx, Obj args) { // Map the global function in the external C++ code to the IR code, only the declaration in the IR code - LLVMAddGlobalMapping(engine, func_call, m_func_ptr); + ASSERT(at::holds_alternative(m_var)); + LLVMAddGlobalMapping(engine, func_call, at::get(m_var)); ObjPtr result = nullptr; @@ -2158,7 +1981,7 @@ ObjPtr Obj::CallNative(Context *ctx, Obj args) { #else bool skip_call = false; #endif - if(pointer_exist && skip_call) { + if(skip_call || (skip_call && pointer_exist)) { LOG_WARNING("LLVM reported error on Windows: \"MCJIT::runFunction does not support full-featured argument passing!!!!\""); result = Obj::CreateNone(); } else { @@ -2174,267 +1997,6 @@ ObjPtr Obj::CallNative(Context *ctx, Obj args) { return result; } -//ObjPtr Obj::CallNative(Context *ctx, Obj args) { -// -// if(!ctx || !ctx->m_runtime) { -// LOG_RUNTIME("Fail context for call native!"); -// } -// -// ffi_cif m_cif; -// std::vector m_args_type; -// std::vector m_args_ptr; -// -// union VALUE { -// const void *ptr; -// // ObjPtr obj; -// size_t size; -// int64_t integer; -// double number; -// bool boolean; -// }; -// std::vector m_args_val; -// VALUE temp; -// -// ASSERT(m_var_type_current == ObjType::NativeFunc); -// ASSERT(m_func_proto); -// -// if(!m_func_ptr) { -// NL_CHECK(m_module_name.empty() || ctx, "You cannot load a module without access to the runtime context!"); -// m_func_ptr = ctx->m_runtime->GetNativeAddr(m_func_mangle_name.empty() ? m_func_proto->m_text.c_str() : m_func_mangle_name.c_str(), -// m_module_name.empty() ? nullptr : m_module_name.c_str()); -// } -// NL_CHECK(m_func_ptr, "Fail load func name '%s' (%s) or fail load module '%s'!", m_func_proto->m_text.c_str(), -// m_func_mangle_name.empty() ? m_func_proto->m_text.c_str() : m_func_mangle_name.c_str(), -// m_module_name.empty() ? "none" : m_module_name.c_str()); -// -// bool is_ellipsis = (m_func_proto->size() && (*m_func_proto)[m_func_proto->size() - 1].second->getTermID() == TermID::ELLIPSIS); -// size_t check_count = is_ellipsis ? m_func_proto->size() - 1 : m_func_proto->size(); -// -// // Пропустить нулевой аргумент для нативных функций -// for (int i = 1; i < args.size(); i++) { -// -// ASSERT(args[i].second); -// if(args[i].second->m_is_reference) { -// LOG_RUNTIME("Argument REFERENCE! %s", args[i].second->toString().c_str()); -// } -// -// size_t pind = i - 1; // Индекс прототипа на единицу меньше из-за пустого нулевого аргумента -// -// ObjType type = args[i].second->getTypeAsLimit(); -// switch(type) { -// case ObjType::Bool: -// if(pind < check_count) { -// NL_CHECK(!(*m_func_proto)[pind].second->m_type_name.empty(), "Undefined type arg '%s'", (*m_func_proto)[pind].second->toString().c_str()); -// NL_CHECK(canCast(type, typeFromString((*m_func_proto)[pind].second->m_type_name, ctx)), "Fail cast from '%s' to '%s'", -// (*m_func_proto)[pind].second->m_type_name.c_str(), newlang::toString(type)); -// } -// m_args_type.push_back(ctx->m_runtime->m_ffi_type_uint8); -// temp.boolean = args[i].second->GetValueAsBoolean(); -// m_args_val.push_back(temp); -// break; -// -// case ObjType::Char: -// if(pind < check_count) { -// NL_CHECK(!(*m_func_proto)[pind].second->m_type_name.empty(), "Undefined type arg '%s'", (*m_func_proto)[pind].second->toString().c_str()); -// NL_CHECK(canCast(type, typeFromString((*m_func_proto)[pind].second->m_type_name, ctx)), "Fail cast from '%s' to '%s'", -// (*m_func_proto)[pind].second->m_type_name.c_str(), newlang::toString(type)); -// } -// m_args_type.push_back(ctx->m_runtime->m_ffi_type_sint8); -// temp.integer = args[i].second->GetValueAsInteger(); -// m_args_val.push_back(temp); -// break; -// -// case ObjType::Short: -// if(pind < check_count) { -// NL_CHECK(!(*m_func_proto)[pind].second->m_type_name.empty(), "Undefined type arg '%s'", (*m_func_proto)[pind].second->toString().c_str()); -// NL_CHECK(canCast(type, typeFromString((*m_func_proto)[pind].second->m_type_name, ctx)), "Fail cast from '%s' to '%s'", -// (*m_func_proto)[pind].second->m_type_name.c_str(), newlang::toString(type)); -// } -// m_args_type.push_back(ctx->m_runtime->m_ffi_type_sint16); -// temp.integer = args[i].second->GetValueAsInteger(); -// m_args_val.push_back(temp); -// break; -// -// case ObjType::Int: -// if(pind < check_count) { -// NL_CHECK(!(*m_func_proto)[pind].second->m_type_name.empty(), "Undefined type arg '%s'", (*m_func_proto)[pind].second->toString().c_str()); -// NL_CHECK(canCast(type, typeFromString((*m_func_proto)[pind].second->m_type_name, ctx)), "Fail cast from '%s' to '%s'", -// (*m_func_proto)[pind].second->m_type_name.c_str(), newlang::toString(type)); -// } -// m_args_type.push_back(ctx->m_runtime->m_ffi_type_sint32); -// temp.integer = args[i].second->GetValueAsInteger(); -// m_args_val.push_back(temp); -// break; -// -// case ObjType::Long: -// if(pind < check_count) { -// NL_CHECK(!(*m_func_proto)[pind].second->m_type_name.empty(), "Undefined type arg '%s'", (*m_func_proto)[pind].second->toString().c_str()); -// NL_CHECK(canCast(type, typeFromString((*m_func_proto)[pind].second->m_type_name, ctx)), "Fail cast from '%s' to '%s'", -// (*m_func_proto)[pind].second->m_type_name.c_str(), newlang::toString(type)); -// } -// m_args_type.push_back(ctx->m_runtime->m_ffi_type_sint64); -// temp.integer = args[i].second->GetValueAsInteger(); -// m_args_val.push_back(temp); -// break; -// -// case ObjType::Float: -// if(pind < check_count) { -// NL_CHECK(!(*m_func_proto)[pind].second->m_type_name.empty(), "Undefined type arg '%s'", (*m_func_proto)[pind].second->toString().c_str()); -// NL_CHECK(canCast(type, typeFromString((*m_func_proto)[pind].second->m_type_name, ctx)), "Fail cast from '%s' to '%s'", -// (*m_func_proto)[pind].second->m_type_name.c_str(), newlang::toString(type)); -// } -// m_args_type.push_back(ctx->m_runtime->m_ffi_type_float); -// temp.number = args[i].second->GetValueAsNumber(); -// m_args_val.push_back(temp); -// break; -// -// case ObjType::Double: -// if(pind < check_count) { -// NL_CHECK(!(*m_func_proto)[pind].second->m_type_name.empty(), "Undefined type arg '%s'", (*m_func_proto)[pind].second->toString().c_str()); -// NL_CHECK(canCast(type, typeFromString((*m_func_proto)[pind].second->m_type_name, ctx)), "Fail cast from '%s' to '%s'", -// (*m_func_proto)[pind].second->m_type_name.c_str(), newlang::toString(type)); -// } -// m_args_type.push_back(ctx->m_runtime->m_ffi_type_double); -// temp.number = args[i].second->GetValueAsNumber(); -// m_args_val.push_back(temp); -// break; -// -// case ObjType::StrChar: -// if(pind < check_count) { -// NL_CHECK(!(*m_func_proto)[pind].second->m_type_name.empty(), "Undefined type arg '%s'", (*m_func_proto)[pind].second->toString().c_str()); -// NL_CHECK(canCast(type, typeFromString((*m_func_proto)[pind].second->m_type_name, ctx)), "Fail cast from '%s' to '%s'", -// (*m_func_proto)[pind].second->m_type_name.c_str(), newlang::toString(type)); -// } -// m_args_type.push_back(ctx->m_runtime->m_ffi_type_pointer); -// temp.ptr = args[i].second->m_str.c_str(); -// m_args_val.push_back(temp); -// break; -// -// case ObjType::StrWide: -// if(pind < check_count) { -// NL_CHECK(!(*m_func_proto)[pind].second->m_type_name.empty(), "Undefined type arg '%s'", (*m_func_proto)[pind].second->toString().c_str()); -// NL_CHECK(canCast(type, typeFromString((*m_func_proto)[pind].second->m_type_name, ctx)), "Fail cast from '%s' to '%s'", -// (*m_func_proto)[pind].second->m_type_name.c_str(), newlang::toString(type)); -// } -// m_args_type.push_back(ctx->m_runtime->m_ffi_type_pointer); -// temp.ptr = args[i].second->m_wstr.c_str(); -// m_args_val.push_back(temp); -// break; -// -// case ObjType::Pointer: -// if(pind < check_count) { -// NL_CHECK(!(*m_func_proto)[pind].second->m_type_name.empty(), "Undefined type arg '%s'", (*m_func_proto)[pind].second->toString().c_str()); -// NL_CHECK(canCast(type, typeFromString((*m_func_proto)[pind].second->m_type_name, ctx)), "Fail cast from '%s' to '%s'", -// (*m_func_proto)[pind].second->m_type_name.c_str(), newlang::toString(type)); -// } -// m_args_type.push_back(ctx->m_runtime->m_ffi_type_pointer); -// temp.ptr = args[i].second->m_func_ptr; -// m_args_val.push_back(temp); -// break; -// -// default: -// LOG_RUNTIME("Native arg '%s' not implemented!", args[i].second->toString().c_str()); -// } -// if(pind < check_count && (*m_func_proto)[pind].second->GetType()) { -// if((*m_func_proto)[pind].second->GetType()->m_text.compare(newlang::toString(ObjType::FmtChar)) == 0) { -// NL_CHECK(ParsePrintfFormat(&args, i), "Fail format string or type args!"); -// } -// } -// } -// -// for (size_t i = 0; i < m_args_val.size(); i++) { -// m_args_ptr.push_back((void *) &m_args_val[i]); -// } -// -// NL_CHECK(!m_func_proto->m_type_name.empty(), "Undefined return type '%s'", m_func_proto->toString().c_str()); -// -// VALUE res_value; -// ffi_type *result_ffi_type = nullptr; -// -// ObjType type = ctx->BaseTypeFromString(m_func_proto->m_type_name); -// -// switch(type) { -// case ObjType::Bool: -// result_ffi_type = ctx->m_runtime->m_ffi_type_uint8; -// break; -// -// case ObjType::Char: -// result_ffi_type = ctx->m_runtime->m_ffi_type_sint8; -// break; -// -// case ObjType::Short: -// result_ffi_type = ctx->m_runtime->m_ffi_type_sint16; -// break; -// -// case ObjType::Int: -// result_ffi_type = ctx->m_runtime->m_ffi_type_sint32; -// break; -// -// case ObjType::Long: -// result_ffi_type = ctx->m_runtime->m_ffi_type_sint64; -// break; -// -// case ObjType::Float: -// result_ffi_type = ctx->m_runtime->m_ffi_type_float; -// break; -// -// case ObjType::Double: -// result_ffi_type = ctx->m_runtime->m_ffi_type_double; -// break; -// -// case ObjType::Pointer: -// case ObjType::StrChar: -// case ObjType::StrWide: -// result_ffi_type = ctx->m_runtime->m_ffi_type_pointer; -// break; -// -// default: -// LOG_RUNTIME("Native return type '%s' not implemented!", m_func_proto->m_type_name.c_str()); -// } -// -// ASSERT(m_func_abi == FFI_DEFAULT_ABI); // Нужны другие типы вызовов ??? -// if(ctx->m_runtime->m_ffi_prep_cif(&m_cif, m_func_abi, static_cast (m_args_type.size()), result_ffi_type, m_args_type.data()) == FFI_OK) { -// -// ctx->m_runtime->m_ffi_call(&m_cif, FFI_FN(m_func_ptr), &res_value, m_args_ptr.data()); -// -// if(result_ffi_type == ctx->m_runtime->m_ffi_type_uint8) { -// // Возвращаемый тип может быть как Byte, так и Bool -// return Obj::CreateValue(static_cast (res_value.integer), typeFromString(m_func_proto->m_type_name)); -// } else if(result_ffi_type == ctx->m_runtime->m_ffi_type_sint8) { -// return Obj::CreateValue(static_cast (res_value.integer), ObjType::Char); -// } else if(result_ffi_type == ctx->m_runtime->m_ffi_type_sint16) { -// return Obj::CreateValue(static_cast (res_value.integer), ObjType::Short); -// } else if(result_ffi_type == ctx->m_runtime->m_ffi_type_sint32) { -// return Obj::CreateValue(static_cast (res_value.integer), ObjType::Int); -// } else if(result_ffi_type == ctx->m_runtime->m_ffi_type_sint64) { -// return Obj::CreateValue(res_value.integer, ObjType::Long); -// } else if(result_ffi_type == ctx->m_runtime->m_ffi_type_float) { -// return Obj::CreateValue(res_value.number, ObjType::Float); -// } else if(result_ffi_type == ctx->m_runtime->m_ffi_type_double) { -// return Obj::CreateValue(res_value.number, ObjType::Double); -// } else if(result_ffi_type == ctx->m_runtime->m_ffi_type_pointer) { -// if(type == ObjType::StrChar) { -// return Obj::CreateString(reinterpret_cast (res_value.ptr)); -// } else if(type == ObjType::StrWide) { -// return Obj::CreateString(reinterpret_cast (res_value.ptr)); -// } else if(type == ObjType::Pointer) { -// ObjPtr result = ctx->GetTypeFromString(m_func_proto->m_type_name); -// result->m_func_ptr = (void *) res_value.ptr; -// result->m_var_is_init = true; -// return result; -// } else { -// LOG_RUNTIME("Error result type '%s' or not implemented!", m_func_proto->m_type_name.c_str()); -// } -// } else { -// LOG_RUNTIME("Native return type '%s' not implemented!", m_func_proto->m_type_name.c_str()); -// } -// } -// -// LOG_RUNTIME("Fail native call '%s'!", toString().c_str()); -// -// return Obj::CreateNone(); -//} - bool newlang::ParsePrintfFormat(Obj *args, int start) { if(!args) { @@ -2573,70 +2135,34 @@ bool newlang::ParsePrintfFormat(Obj *args, int start) { return result; } -void newlang::ConvertRangeToDict(Obj *from, Obj & to) { - - to.m_var_is_init = false; - - ASSERT(from); - ASSERT(from->is_range()); - ASSERT(from->at("start").second); - ASSERT(from->at("stop").second); - ASSERT(from->at("step").second); - - ASSERT(to.m_var_type_current == ObjType::Dictionary || to.m_var_type_current == ObjType::None); - - if(!to.is_dictionary_type()) { - to.m_var_type_current = ObjType::Dictionary; - } - - ObjPtr value = (*from)["start"].second->Clone(); - if((*value) < (*from)["stop"].second) { - ASSERT((*from)["step"].second->GetValueAsNumber() > 0); - while((*value) < (*from)["stop"].second) { - to.push_back(value->Clone()); - (*value) += (*from)["step"].second; - } - } else { - ASSERT((*from)["step"].second->GetValueAsNumber() < 0); - while((*value) > (*from)["stop"].second) { - - to.push_back(value->Clone()); - (*value) += (*from)["step"].second; - } - } - - to.m_var_is_init = true; -} +/* + * + * + */ void newlang::ConvertStringToTensor(const std::string &from, torch::Tensor &to, ObjType type) { - - ASSERT(!from.empty()); - ASSERT(type == ObjType::None || type == ObjType::Char || type == ObjType::Tensor); - to = torch::from_blob((void *) from.data(),{(int64_t) from.size()}, at::ScalarType::Char).clone(); + if(from.empty()) { + LOG_RUNTIME("Fail convert empty string to tensor!"); + } + to = torch::from_blob((void *) from.c_str(),{(int64_t) from.size()}, at::ScalarType::Char).clone().toType(toTorchType(type)); } void newlang::ConvertStringToTensor(const std::wstring &from, torch::Tensor &to, ObjType type) { - ASSERT(!from.empty()); - ASSERT(type == ObjType::None || type == ObjType::Int || type == ObjType::Tensor); + if(from.empty()) { + LOG_RUNTIME("Fail convert empty string to tensor!"); + } if(sizeof (wchar_t) == sizeof (int32_t)) { - to = torch::from_blob((void *) from.data(),{(int) from.size()}, torch::Dtype::Int); + to = torch::from_blob((void *) from.c_str(),{(int64_t) from.size()}, torch::Dtype::Int).clone().toType(toTorchType(type)); } else if(sizeof (wchar_t) == sizeof (int16_t)) { - to = torch::from_blob((void *) from.data(),{(int) from.size()}, torch::Dtype::Short); + to = torch::from_blob((void *) from.c_str(),{(int64_t) from.size()}, torch::Dtype::Short).clone().toType(toTorchType(type)); } else { - LOG_RUNTIME("Unsupport wchar_t size '%d'!!!", (int) sizeof (wchar_t)); } - to = to.toType(torch::Dtype::Int).clone(); } template void ConvertTensorToStringTemplate(const torch::Tensor &from, T &to, std::vector *index) { - if(from.dim() == 0) { - - ASSERT(index == nullptr); - to = from.toType(at::ScalarType::Char).item(); - return; - } + ASSERT(from.dim()); // Скаляры хранятся не тензорами, а нативными типами std::vector dims; if(index == nullptr) { @@ -2647,28 +2173,38 @@ template void ConvertTensorToStringTemplate(const torch::Tensor &fr int64_t pos = index->size(); if(pos == from.dim()) { + at::ScalarType torch_type; + switch(sizeof (to[0])) { + case 1: + torch_type = at::ScalarType::Char; + break; + case 2: + torch_type = at::ScalarType::Short; + break; + case 4: + torch_type = at::ScalarType::Int; + break; + default: + LOG_RUNTIME("Unsupported char size! %d", (int) sizeof (to[0])); + } for (int i = 0; i < from.size(pos - 1); i++) { (*index)[pos - 1] = i; - to += from.index(*index).toType(at::ScalarType::Char).item(); + to += from.index(*index).toType(torch_type).item(); } } else { index->push_back(0); for (int64_t i = 0; i < from.size(pos - 1); i++) { - ( - - *index)[pos - 1] = i; + (*index)[pos - 1] = i; ConvertTensorToString(from, to, index); } } } void newlang::ConvertTensorToString(const torch::Tensor &from, std::string &to, std::vector *index) { - ConvertTensorToStringTemplate(from, to, index); } void newlang::ConvertTensorToString(const torch::Tensor &from, std::wstring &to, std::vector *index) { - ConvertTensorToStringTemplate(from, to, index); } @@ -2680,11 +2216,7 @@ void newlang::ConvertTensorToDict(const torch::Tensor &from, Obj &to, std::vecto to.m_var_type_current = ObjType::Dictionary; } - if(from.dim() == 0) { - ASSERT(index == nullptr); - to.push_back(Obj::CreateTensor(from)); - return; - } + ASSERT(from.dim()); // Скаляры хранятся не тензорами, а нативными типами std::vector dims; if(index == nullptr) { @@ -2701,9 +2233,7 @@ void newlang::ConvertTensorToDict(const torch::Tensor &from, Obj &to, std::vecto } else { index->push_back(0); for (int64_t i = 0; i < from.size(pos - 1); i++) { - ( - - *index)[pos - 1] = i; + (*index)[pos - 1] = i; ConvertTensorToDict(from, to, index); } } @@ -2711,53 +2241,296 @@ void newlang::ConvertTensorToDict(const torch::Tensor &from, Obj &to, std::vecto to.m_var_is_init = true; } -void newlang::ConvertDictToTensor(Obj &from, torch::Tensor &to, ObjType type) { +/* + * Варианты преобраования типов + * Range -> Dict + * String -> Tensor + * Tensor -> String + * Tensor -> Dict + * Dict -> Tensor + */ +void Obj::toType_(ObjType type) { + if(m_var_type_current == type) { + return; + } else if(type == ObjType::None) { + clear_(); + return; + } else if(is_tensor() && isTensor(type)) { + + // Изменить тип тензора + if(isGenericType(type)) { + m_var_type_fixed = type; + } + + if(is_scalar()) { + if((isGenericType(type) && isContainsType(type, m_var_type_current)) || + (is_integral() && isIntegralType(type, true)) || (is_floating() && isFloatingType(type))) { + // Ничего менять ненужно + } else if(isIntegralType(type, true)) { + m_var = GetValueAsInteger(); + } else if(isFloatingType(type)) { + m_var = GetValueAsNumber(); + } else { + LOG_RUNTIME("Unknown convert value!"); + } + if(!isGenericType(type)) { + m_var_type_current = type; + } + + } else { + ASSERT(m_tensor.defined()); + if(!isGenericType(type)) { + m_tensor = m_tensor.toType(toTorchType(type)); + m_var_type_current = fromTorchType(m_tensor.scalar_type()); + } + } + + return; + + } else if(is_range() && isDictionary(type)) { + + + ObjPtr value = at("start").second; + ObjPtr stop = at("stop").second; + ObjPtr step = at("step").second; - torch::Tensor temp; - for (int i = 0; i < from.size(); i++) { - ConvertValueToTensor(from.at(i).second.get(), temp, type); + ASSERT(value); + ASSERT(stop); + ASSERT(step); - if(temp.dim() == 0) { - temp = temp.reshape({1}); + Variable::clear_(); + m_var_type_current = type; + + if((*value) < stop) { + ASSERT(step->GetValueAsNumber() > 0); + while((*value) < stop) { + push_back(value->Clone()); + (*value) += step; + } + } else { + ASSERT(step->GetValueAsNumber() < 0); + while((*value) > stop) { + push_back(value->Clone()); + (*value) += step; + } } + return; + + } else if(is_range() && isTensor(type)) { + + toType_(ObjType::Dictionary); + toType_(type); + return; - if(to.dim() != 1 || to.size(0) == 0) { - to = temp.clone(); + } else if(is_string_char_type() && isTensor(type)) { + + if(isGenericType(type)) { + m_var_type_fixed = type; + m_var_type_current = ObjType::Char; } else { + m_var_type_current = type; + } - to = torch::cat({to, temp}); + if(m_value.size() == 1) { + // Скаляр хранится в нативном типе + if(isIntegralType(m_var_type_current, true)) { + m_var = static_cast (m_value[0]); + } else { + ASSERT(isFloatingType(m_var_type_current)); + m_var = static_cast (m_value[0]); + } + } else { + ConvertStringToTensor(m_value, m_tensor, m_var_type_current); + } + m_value.clear(); + return; + + } else if(is_string_wide_type() && isTensor(type)) { + + if(isGenericType(type)) { + m_var_type_fixed = type; + if(sizeof (wchar_t) == 4) { + m_var_type_current = ObjType::Int; + } else { + ASSERT(sizeof (wchar_t) == 2); + m_var_type_current = ObjType::Short; + } + } else { + m_var_type_current = type; } - } - // if (dims) { - // to = to.reshape(*dims); - // } -} -void newlang::ConvertValueToTensor(Obj *from, torch::Tensor &to, ObjType type) { - ASSERT(from); - if(from->is_tensor()) { - to = from->m_value.clone(); - if(type == ObjType::None || type == ObjType::Tensor) { - return; + if(m_string.size() == 1) { + // Скаляр хранится в нативном типе + if(isIntegralType(m_var_type_current, true)) { + m_var = static_cast (m_string[0]); + } else { + ASSERT(isFloatingType(m_var_type_current)); + m_var = static_cast (m_string[0]); + } + } else { + ConvertStringToTensor(m_string, m_tensor, m_var_type_current); } - to = to.toType(toTorchType(type)); - // if (dims) { - // to = to.reshape(*dims); - // } - } else if(from->is_range()) { - ObjPtr temp = Obj::CreateNone(); - ConvertRangeToDict(from, *temp.get()); - ConvertDictToTensor(*temp.get(), to, type); - } else if(from->getType() == ObjType::StrChar) { - ConvertStringToTensor(from->m_str, to, type); - } else if(from->getType() == ObjType::StrWide) { - ConvertStringToTensor(from->m_wstr, to, type); - } else if(from->is_dictionary_type()) { - ConvertDictToTensor(*from, to, type); - } else { + m_string.clear(); + return; + + } else if(is_tensor() && isStringChar(type)) { + + if(is_scalar()) { + int64_t char_val = GetValueAsInteger(); + if((char_val < 0 && char_val < std::numeric_limits::min()) || + (char_val > std::numeric_limits::max())) { + LOG_ERROR("Single char overflow! %ld", char_val); + } + if(char_val < 0) { + // По стандарту char - знаковый тип + m_value.assign(1, static_cast (char_val)); + } else { + // Но часто про это забывают и забивают + m_value.assign(1, static_cast (char_val)); + } + m_var = at::monostate(); + } else { + ASSERT(!is_scalar()); + if(static_cast (m_var_type_current) > static_cast (ObjType::Char)) { + LOG_ERROR("Possible data loss when converting tensor %s to a byte string!", newlang::toString(m_var_type_current)); + } + ConvertTensorToString(m_tensor, m_value); + m_tensor.reset(); + } + m_var_type_current = type; + return; + + } else if(is_tensor() && isStringWide(type)) { + + if(is_scalar()) { + int64_t char_val = GetValueAsInteger(); + if((char_val < std::numeric_limits::min()) || + (char_val > std::numeric_limits::max())) { + LOG_ERROR("Single wchar_t overflow! %ld", char_val); + } + m_string.assign(1, static_cast (char_val)); + m_var = at::monostate(); + } else { + ASSERT(!is_scalar()); + ASSERT(sizeof (wchar_t) == 2 || sizeof (wchar_t) == 4); + if((sizeof (wchar_t) == 2 && static_cast (m_var_type_current) > static_cast (ObjType::Short)) || + (sizeof (wchar_t) == 4 && static_cast (m_var_type_current) > static_cast (ObjType::Int))) { + LOG_ERROR("Possible data loss when converting tensor %s to a wide string!", newlang::toString(m_var_type_current)); + } + ConvertTensorToString(m_tensor, m_string); + m_tensor.reset(); + } + m_var_type_current = type; + return; + + } else if(is_tensor() && type == ObjType::Fraction) { + + if(!is_scalar()) { + LOG_RUNTIME("Convert tensor to fraction support for scalar only!"); + } + if(is_integral()) { + m_fraction = std::make_shared(GetValueAsInteger()); + m_var = at::monostate(); + } else { + LOG_RUNTIME("Convert value '%s' to fraction not implemented!", toString().c_str()); + } + m_var_type_current = type; + return; + + } else if(is_tensor() && isDictionary(type)) { + + if(is_scalar() && is_integral()) { + ASSERT(at::holds_alternative(m_var)); + push_back(Obj::CreateValue(at::get(m_var))); + m_var = at::monostate(); + } else if(is_scalar() && is_floating()) { + ASSERT(at::holds_alternative(m_var)); + push_back(Obj::CreateValue(at::get(m_var))); + m_var = at::monostate(); + } else { + ASSERT(!is_scalar()); + if(!m_tensor.defined()) { + ASSERT(m_tensor.defined()); + } + ConvertTensorToDict(m_tensor, *this); + m_tensor.reset(); + } + m_var_type_current = type; + return; + + } else if(is_dictionary_type() && isTensor(type)) { + + ASSERT(!m_tensor.defined()); + + if(isGenericType(type)) { + m_var_type_fixed = type; + } + + if(!size()) { + LOG_RUNTIME("Fail convert empty dictionary to tensor!"); + } + + /* + * Все элементы словаря переводятся в требуемый тип и определется минимально + * возможный тип по его размерности среди всех элементов сконвертированных словаря. + */ + + for (int i = 0; i < size(); i++) { + at(i).second->toType_(type); + } + ObjType summary_type = getSummaryTensorType(this, ObjType::None); + + /* + * Создается итоговый тензор требуемого типа и в него последоватльно добаляются все элементы словаря. + */ + torch::Dtype summary_torch_type = toTorchType(static_cast (summary_type)); + if(at(0).second->is_scalar()) { + if(at(0).second->is_integral()) { + m_tensor = torch::full({1}, at(0).second->GetValueAsInteger(), summary_torch_type); + } else { + if(!at(0).second->is_floating()) { + ASSERT(at(0).second->is_floating()); + } + m_tensor = torch::full({1}, at(0).second->GetValueAsNumber(), summary_torch_type); + } + } else { + m_tensor = at(0).second->m_tensor.toType(summary_torch_type); + } + + for (int i = 1; i < size(); i++) { + + ObjPtr temp = at(i).second; + if(!temp) { + LOG_RUNTIME("Fail convert nullptr to tensor at index %d!", i); + } + + torch::Tensor temp_tensor; + if(temp->is_scalar()) { + ASSERT(!temp->m_tensor.defined()); + if(temp->is_integral()) { + temp_tensor = torch::full({1}, temp->GetValueAsInteger(), summary_torch_type); + } else { + if(!temp->is_floating()) { + ASSERT(temp->is_floating()); + } + temp_tensor = torch::full({1}, temp->GetValueAsNumber(), summary_torch_type); + } + } else { + ASSERT(temp->m_tensor.defined()); + temp_tensor = temp->m_tensor.toType(summary_torch_type); + } + + m_tensor = torch::cat({m_tensor, temp_tensor}); + } + + Variable::clear_(); + + m_var_type_current = summary_type; + + return; - LOG_RUNTIME("Fail convert object type %s to tensor (%s)!", newlang::toString(from->getType()), from->toString().c_str()); } + LOG_RUNTIME("Can`t convert object type %s to %s!", newlang::toString(m_var_type_current), newlang::toString(type)); } /* @@ -2792,9 +2565,9 @@ ObjPtr Obj::CreateBaseType(ObjType type) { TermPtr proto = Parser::ParseString(func_proto); ASSERT(proto->Left()); - * const_cast (&result->m_func_proto) = proto->Left(); + * const_cast (&result->m_prototype) = proto->Left(); - result->m_func_ptr = (void *) BaseTypeConstructor; + result->m_var = (void *) BaseTypeConstructor; result->m_is_const = true; return result; @@ -2947,16 +2720,16 @@ ObjPtr Obj::ConstructorSimpleType_(const Context *ctx, Obj & args) { if(dims.size() == 1 && dims[0] == 0) { // Скаляр if(args.size() == 2 && args[0].second->m_var_type_fixed == ObjType::Bool) { - - result->m_value = torch::scalar_tensor(result->empty() ? 0 : 1, at::ScalarType::Bool); + result->m_var = static_cast (result->empty() ? 0 : 1); + result->m_tensor.reset(); return result; - } else if(result->size() != 0) { LOG_RUNTIME("Only one value is required for a scalar!"); } dims.clear(); + } else { + result->m_tensor = result->m_tensor.reshape(dims); } - result->m_value = result->m_value.reshape(dims); } else { LOG_RUNTIME("Fail esing dimensions for type '%s'!", newlang::toString(result->getType())); @@ -3054,7 +2827,7 @@ ObjPtr Obj::ConstructorEnum_(const Context *ctx, Obj & args) { } else { enum_name = args.name(i); - if(args[i].second && (args[i].second->is_integer() || args[i].second->is_bool_type())) { + if(args[i].second && (args[i].second->is_integral())) { val_int = args[i].second->GetValueAsInteger(); } else if(!args[i].second || !args[i].second->is_none_type()) { LOG_RUNTIME("Field value '%s' %d must integer type!", args.name(i).c_str(), i); diff --git a/src/object.h b/src/object.h old mode 100755 new mode 100644 index 75e0aa90..6e22b80b --- a/src/object.h +++ b/src/object.h @@ -29,12 +29,12 @@ namespace newlang { * новые аргументы по мимо тех, которые уже определены в прототипе функции. */ - ObjType DictionarySummaryType(const Obj *obj); + // ObjType DictionarySummaryType(const Obj *obj); std::vector TensorShapeFromDict(const Obj *obj); - torch::Tensor ConvertToTensor(Obj *obj, at::ScalarType type = at::ScalarType::Undefined, bool reshape = true); - - at::TensorOptions ConvertToTensorOptions(const Obj *obj); - at::DimnameList ConvertToDimnameList(const Obj *obj); + // torch::Tensor ConvertToTensor(Obj *obj, at::ScalarType type = at::ScalarType::Undefined, bool reshape = true); + // + // at::TensorOptions ConvertToTensorOptions(const Obj *obj); + // at::DimnameList ConvertToDimnameList(const Obj *obj); bool ParsePrintfFormat(Obj *args, int start = 1); enum class ConcatMode : uint8_t { @@ -71,12 +71,13 @@ namespace newlang { return wide_line; } - ObjType getSummaryTensorType(ObjPtr & obj, ObjType start); - std::vector getTensorSizes(Obj *obj); - void calcTensorDims(ObjPtr & obj, std::vector &dims); - void testTensorDims(ObjPtr & obj, at::IntArrayRef dims, int64_t pos); - - + /* Для конвертирования словаря в тензор для вывода общего типа данных для всех элементов */ + ObjType getSummaryTensorType(Obj *obj, ObjType start); + void ConvertStringToTensor(const std::string &from, torch::Tensor &to, ObjType type = ObjType::None); + void ConvertStringToTensor(const std::wstring &from, torch::Tensor &to, ObjType type = ObjType::None); + void ConvertTensorToString(const torch::Tensor &from, std::string &to, std::vector *index = nullptr); + void ConvertTensorToString(const torch::Tensor &from, std::wstring &to, std::vector *index = nullptr); + void ConvertTensorToDict(const torch::Tensor &from, Obj &to, std::vector *index = nullptr); @@ -286,18 +287,16 @@ namespace newlang { typedef Variable::PairType PairType; Obj(ObjType type = ObjType::None, const char *var_name = nullptr, TermPtr func_proto = nullptr, ObjType fixed = ObjType::None, bool init = false) : - m_var_type_current(type), m_var_name(var_name ? var_name : ""), m_func_proto(func_proto) { - // m_ctx = nullptr; + m_var_type_current(type), m_var_name(var_name ? var_name : ""), m_prototype(func_proto) { m_is_const = false; m_check_args = false; - m_func_ptr = nullptr; m_dimensions = nullptr; - m_value = torch::empty({0}, isSimpleType(type) ? toTorchType(type) : at::ScalarType::Undefined); m_is_reference = false; - // m_func_abi = FFI_DEFAULT_ABI; m_var_type_fixed = fixed; m_var_is_init = init; m_is_const = false; + m_var = at::monostate(); + ASSERT(!m_tensor.defined()); } Obj(Context *ctx, const TermPtr term, bool as_value, Obj *local_vars); @@ -454,6 +453,16 @@ namespace newlang { return isString(m_var_type_current); } + [[nodiscard]] + inline bool is_string_char_type() const { + return isStringChar(m_var_type_current); + } + + [[nodiscard]] + inline bool is_string_wide_type() const { + return isStringWide(m_var_type_current); + } + [[nodiscard]] inline bool is_dictionary_type() const { return isDictionary(m_var_type_current); @@ -482,7 +491,7 @@ namespace newlang { [[nodiscard]] inline bool is_scalar() const { - return is_tensor() && m_value.dim() == 0; + return is_tensor() && !m_tensor.defined(); } [[nodiscard]] @@ -500,6 +509,11 @@ namespace newlang { return isIntegralType(m_var_type_current, false); } + [[nodiscard]] + inline bool is_integral() const { + return isIntegralType(m_var_type_current, true); + } + [[nodiscard]] inline bool is_complex() const { return isComplexType(m_var_type_current); @@ -525,6 +539,11 @@ namespace newlang { return isRange(m_var_type_current); } + [[nodiscard]] + inline bool is_fraction() const { + return m_var_type_current == ObjType::Fraction; + } + [[nodiscard]] inline bool is_type_name() const { return isTypeName(m_var_type_current); @@ -540,9 +559,6 @@ namespace newlang { return m_var_type_current == ObjType::Return || m_var_type_fixed == ObjType::Return; } - [[nodiscard]] - ObjType SummaryArithmeticType(ObjType type); - [[nodiscard]] inline bool is_defined_type() { return m_var_type_fixed != ObjType::None; @@ -560,11 +576,11 @@ namespace newlang { if (is_none_type()) { return true; } else if (m_var_type_current == ObjType::StrChar) { - return !m_var_is_init || m_str.empty(); + return !m_var_is_init || m_value.empty(); } else if (m_var_type_current == ObjType::StrWide) { - return !m_var_is_init || m_wstr.empty(); + return !m_var_is_init || m_string.empty(); } else if (is_tensor()) { - return !m_var_is_init || at::_is_zerotensor(m_value); + return !m_var_is_init || at::_is_zerotensor(m_tensor); } return Variable::empty(); } @@ -657,10 +673,6 @@ namespace newlang { return Variable::find(name); } - // Obj::const_iterator find(const std::string_view name) const { - // return Variable::find(name); - // } - Obj::iterator begin() { return Variable::begin(); } @@ -717,15 +729,15 @@ namespace newlang { void clear_(bool clear_iterator_name) { - m_str.clear(); - m_wstr.clear(); + m_value.clear(); + m_string.clear(); m_var_type_current = ObjType::None; m_class_parents.clear(); m_var_is_init = false; - m_value.reset(); + m_tensor.reset(); m_fraction.reset(); - // m_var = std::monostate(); + m_var = at::monostate(); // m_value.reset(); //???????????????? // m_items.clear(); } @@ -748,7 +760,7 @@ namespace newlang { ObjPtr operator-() { if (is_arithmetic_type()) { if (is_tensor()) { - m_value = -m_value; + m_tensor = -m_tensor; } else if (is_integer()) { SetValue_(-GetValueAsInteger()); } else if (isFloatingType(m_var_type_current)) { @@ -771,7 +783,7 @@ namespace newlang { ObjPtr &operator-(ObjPtr & obj) { if (is_tensor()) { - obj->m_value = torch::zeros_like(obj->m_value) - obj->m_value; + obj->m_tensor = torch::zeros_like(obj->m_tensor) - obj->m_tensor; return obj; } LOG_RUNTIME("Object '%s' not numeric!", obj->toString().c_str()); @@ -782,7 +794,7 @@ namespace newlang { ObjPtr operator++() { if (is_tensor()) { - m_value.add_(torch::ones_like(m_value)); + m_tensor.add_(torch::ones_like(m_tensor)); return shared(); } @@ -801,7 +813,7 @@ namespace newlang { ObjPtr operator--() { if (is_tensor()) { - m_value.sub_(torch::ones_like(m_value)); + m_tensor.sub_(torch::ones_like(m_tensor)); return shared(); } LOG_RUNTIME("Object '%s' not numeric!", toString().c_str()); @@ -981,14 +993,6 @@ namespace newlang { return false; } - // inline ObjPtr operator==(ObjPtr obj) { - // ASSERT(obj); - // return operator==(*obj); - // } - // - // inline ObjPtr operator==(Obj obj) { - // return op_equal(obj) ? Obj::Yes() : Obj::No(); - // } bool op_equal(Obj & value); inline bool op_accurate(ObjPtr obj) { @@ -997,15 +1001,6 @@ namespace newlang { } bool op_accurate(Obj & value); - // inline ObjPtr operator!=(ObjPtr obj) { - // ASSERT(obj); - // return operator!=(*obj); - // } - // - // inline ObjPtr operator!=(Obj obj) { - // return op_equal(obj) ? Obj::No() : Obj::Yes(); - // } - inline ObjPtr op_bit_and(ObjPtr obj, bool strong) { ASSERT(obj); return op_bit_and(*obj, strong); @@ -1224,21 +1219,51 @@ namespace newlang { return utf8_decode(GetValueAsString()); } - inline int64_t GetValueAsInteger() const { + int64_t GetValueAsInteger() const { TEST_INIT_(); + switch (m_var_type_current) { case ObjType::Bool: + if (at::holds_alternative(m_var)) { + return at::get(m_var); + } else if (at::holds_alternative(m_var)) { + return *at::get(m_var); + } case ObjType::Char: + if (at::holds_alternative(m_var)) { + return at::get(m_var); + } else if (at::holds_alternative(m_var)) { + return *at::get(m_var); + } case ObjType::Short: + if (at::holds_alternative(m_var)) { + return at::get(m_var); + } else if (at::holds_alternative(m_var)) { + return *at::get(m_var); + } case ObjType::Int: + if (at::holds_alternative(m_var)) { + return at::get(m_var); + } else if (at::holds_alternative(m_var)) { + return *at::get(m_var); + } case ObjType::Long: + if (at::holds_alternative(m_var)) { + return at::get(m_var); + } else if (at::holds_alternative(m_var)) { + return *at::get(m_var); + } case ObjType::Integer: - return m_value.toType(at::ScalarType::Long).item(); + if (at::holds_alternative(m_var)) { + return at::get(m_var); + } + ASSERT(!is_scalar()); + LOG_RUNTIME("Can`t convert tensor to scalar!"); case ObjType::Float: case ObjType::Double: case ObjType::Number: - return static_cast (m_value.item()); + return static_cast(GetValueAsNumber()); case ObjType::Fraction: ASSERT(m_fraction); @@ -1246,17 +1271,18 @@ namespace newlang { case ObjType::StrWide: case ObjType::FmtWide: - if (m_wstr.size() == 1) { - return m_wstr[0]; + if (m_string.size() == 1) { + return m_string[0]; } case ObjType::StrChar: case ObjType::FmtChar: - if (m_str.size() == 1) { - return m_str[0]; + if (m_value.size() == 1) { + return m_value[0]; } default: if (m_var_type_current == ObjType::Pointer || m_var_type_fixed == ObjType::Pointer) { - return reinterpret_cast (m_func_ptr); + ASSERT(at::holds_alternative(m_var)); + return reinterpret_cast (at::get(m_var)); } LOG_RUNTIME("Data type incompatible %s", toString().c_str()); } @@ -1265,10 +1291,29 @@ namespace newlang { inline double GetValueAsNumber() const { TEST_INIT_(); + switch (m_var_type_current) { + case ObjType::Float: + if (at::holds_alternative(m_var)) { + return at::get(m_var); + } else if (at::holds_alternative(m_var)) { + return *at::get(m_var); + } case ObjType::Double: - return m_value.item(); + if (at::holds_alternative(m_var)) { + return at::get(m_var); + } else if (at::holds_alternative(m_var)) { + return *at::get(m_var); + } + case ObjType::Number: + if (at::holds_alternative(m_var)) { + return at::get(m_var); + } + if (is_scalar()) { + ASSERT(!is_scalar()); + } + LOG_RUNTIME("Can`t convert tensor to scalar!"); case ObjType::Fraction: ASSERT(m_fraction); @@ -1287,16 +1332,17 @@ namespace newlang { return false; } if (is_scalar()) { - return m_value.toType(at::ScalarType::Bool).item(); + return GetValueAsInteger(); + //return m_tensor.toType(at::ScalarType::Bool).item(); } else if (isSimpleType(m_var_type_current)) { // Error: Boolean value of Tensor with more than one value is ambiguous - return !at::_is_zerotensor(m_value); + return !at::_is_zerotensor(m_tensor); } else { switch (m_var_type_current) { case ObjType::StrWide: - return !m_wstr.empty(); + return !m_string.empty(); case ObjType::StrChar: - return !m_str.empty(); + return !m_value.empty(); case ObjType::None: return false; @@ -1330,26 +1376,16 @@ namespace newlang { return LLVMCreateGenericValueOfFloat(type, GetValueAsNumber()); } else if (type == LLVMPointerType(LLVMInt8Type(), 0)) { if (getType() == ObjType::StrChar || getType() == ObjType::FmtChar) { - return LLVMCreateGenericValueOfPointer((void *) m_str.c_str()); + return LLVMCreateGenericValueOfPointer((void *) m_value.c_str()); } else if (getType() == ObjType::Pointer) { - return LLVMCreateGenericValueOfPointer(m_func_ptr); + ASSERT(at::holds_alternative(m_var)); + return LLVMCreateGenericValueOfPointer(at::get(m_var)); } } else if (type == LLVMPointerType(LLVMInt32Type(), 0)) { if (getType() == ObjType::StrWide || getType() == ObjType::FmtWide) { - return LLVMCreateGenericValueOfPointer((void *) m_wstr.c_str()); + return LLVMCreateGenericValueOfPointer((void *) m_string.c_str()); } } - // if (is_integer() || is_bool_type()) { - // return LLVMCreateGenericValueOfInt(type, GetValueAsInteger(), true); - // } else if (is_floating()) { - // return LLVMCreateGenericValueOfFloat(type, GetValueAsNumber()); - // } else if (getType() == ObjType::StrChar || getType() == ObjType::FmtChar) { - // return LLVMCreateGenericValueOfPointer((void *) m_str.c_str()); - // } else if (getType() == ObjType::StrWide) { - // return LLVMCreateGenericValueOfPointer((void *) m_wstr.c_str()); - // } else if (getType() == ObjType::Pointer) { - // return LLVMCreateGenericValueOfPointer(m_func_ptr); - // } LOG_RUNTIME("Not support LLVM type '%s'", newlang::toString(m_var_type_current)); } @@ -1379,25 +1415,13 @@ namespace newlang { } else if (type == ObjType::Pointer) { ObjPtr result = Obj::CreateType(type, ObjType::None, true); - result->m_func_ptr = LLVMGenericValueToPointer(ref); + result->m_var = LLVMGenericValueToPointer(ref); return result; } LOG_RUNTIME("Create to type '%s' form LLVM type not implemented!", newlang::toString(type)); } - at::Scalar toTorchScalar() { - at::Scalar result; - if (is_integer() || is_bool_type()) { - result = at::Scalar(GetValueAsInteger()); - } else if (is_floating()) { - result = at::Scalar(GetValueAsNumber()); - } else { - LOG_RUNTIME("Not support Torch ScalarType '%s'", newlang::toString(m_var_type_current)); - } - return result; - - } static ObjPtr CreateType(ObjType type, ObjType fixed = ObjType::None, bool is_init = false) { return std::make_shared(type, nullptr, nullptr, fixed, is_init); @@ -1515,10 +1539,8 @@ namespace newlang { } static ObjPtr CreateBool(bool value) { - ObjPtr result = CreateType(ObjType::None); - result->m_value = torch::scalar_tensor(value, torch::Dtype::Bool); - result->m_var_type_current = ObjType::Bool; - result->m_var_is_init = true; + ObjPtr result = CreateType(ObjType::Bool, ObjType::None, true); + result->SetValue_(value); return result; } @@ -1527,27 +1549,22 @@ namespace newlang { if (!isTensor(check_type)) { LOG_RUNTIME("Unsupport torch type %s (%d)!", at::toString(tensor.dtype().toScalarType()), (int) tensor.dtype().toScalarType()); } - ObjPtr result = CreateType(check_type); - result->m_value = tensor; - result->m_var_is_init = true; + ObjPtr result; + if (tensor.dim() == 0) { + if (tensor.is_floating_point()) { + result = Obj::CreateValue(tensor.item(), check_type); + } else { + ASSERT(!tensor.is_complex()); + result = Obj::CreateValue(tensor.item(), check_type); + } + } else { + result = CreateType(check_type); + result->m_tensor = tensor; + result->m_var_is_init = true; + } return result; } - static ObjPtr CreateTensor(ObjPtr data, ObjType type) { - torch::Tensor var = ConvertToTensor(data.get(), toTorchType(type), false); - // ConvertToTensor(data->index_get({0}).get(), type, false); - return CreateTensor(var); - } - - inline torch::Tensor toTensor() { - return ConvertToTensor(this); - } - - inline torch::Tensor & asTensor_() { - NL_CHECK(is_tensor(), "Fail type as Tensor"); - return m_value; - } - at::indexing::Slice toSlice() { NL_CHECK(is_range(), "Convert to slice supported for range only!"); @@ -1612,7 +1629,7 @@ namespace newlang { LOG_RUNTIME("Fail convert scalar type '%s' to Index!", newlang::toString(m_var_type_current)); } } else if (is_tensor()) { - return Index(m_value); + return Index(m_tensor); } else if (is_ellipsis()) { return Index(at::indexing::Ellipsis); } else if (is_range()) { @@ -1625,17 +1642,6 @@ namespace newlang { return GetValueAsBoolean(); } - inline operator at::Tensor() { - return ConvertToTensor(this); - } - - inline operator at::TensorOptions() const { - return ConvertToTensorOptions(this); - } - - inline operator at::DimnameList() const { - return ConvertToDimnameList(this); - } std::vector toIntVector(bool raise = true) const { std::vector result; @@ -1649,11 +1655,6 @@ namespace newlang { } - // ПЕРЕКРЫВАЕТ ДРУГИЕ МЕТОДЫ !!!!!!!!!!!!!! at::TensorOptions() - // inline operator std::string () const { - // return GetValueAsString(); - // } - template typename std::enable_if::value, ObjPtr>::type static CreateValue(T value, ObjType fix_type = ObjType::None) { @@ -1664,7 +1665,8 @@ namespace newlang { NL_CHECK(canCast(result->m_var_type_current, fix_type), "Fail cast type from '%s' to '%s'!", newlang::toString(result->m_var_type_current), newlang::toString(fix_type)); } - result->m_value = torch::scalar_tensor(value, toTorchType(result->m_var_type_current)); + result->m_var = static_cast (value); + // result->m_tensor = torch::scalar_tensor(value, toTorchType(result->m_var_type_current)); result->m_var_is_init = true; return result; } @@ -1679,14 +1681,15 @@ namespace newlang { NL_CHECK(canCast(result->m_var_type_current, fix_type), "Fail cast type from '%s' to '%s'!", newlang::toString(result->m_var_type_current), newlang::toString(fix_type)); } - result->m_value = torch::scalar_tensor(value, toTorchType(result->m_var_type_current)); + result->m_var = static_cast (value); + //result->m_tensor = torch::scalar_tensor(value, toTorchType(result->m_var_type_current)); result->m_var_is_init = true; return result; } static ObjPtr CreateString(const std::string str) { ObjPtr result = CreateType(ObjType::StrChar); - result->m_str = str; + result->m_value = str; result->m_var_type_fixed = ObjType::String; result->m_var_is_init = true; return result; @@ -1694,7 +1697,7 @@ namespace newlang { static ObjPtr CreateString(const std::wstring str) { ObjPtr result = CreateType(ObjType::StrWide); - result->m_wstr = str; + result->m_string = str; result->m_var_type_fixed = ObjType::String; result->m_var_is_init = true; return result; @@ -1702,16 +1705,14 @@ namespace newlang { inline static ObjPtr Yes() { ObjPtr result = std::make_shared(ObjType::Bool); - bool value = true; - result->m_value = torch::scalar_tensor(value); + result->m_var = static_cast (1); result->m_var_is_init = true; return result->MakeConst(); } inline static ObjPtr No() { ObjPtr result = std::make_shared(ObjType::Bool); - bool value = false; - result->m_value = torch::scalar_tensor(value); + result->m_var = static_cast (0); result->m_var_is_init = true; return result->MakeConst(); } @@ -1788,39 +1789,26 @@ namespace newlang { void CloneDataTo(Obj & clone) const; void ClonePropTo(Obj & clone) const; - virtual ~Obj() { - // Clear(); - } - - ObjPtr toType(ObjType target) const { - ObjPtr result = Clone(); - result->toType_(target); - return result; + inline ObjPtr toType(ObjType type) const { + ObjPtr clone = Clone(); + clone->toType_(type); + return clone; } - ObjPtr toType_(Obj *type); + /* + * Варианты преобраования типов + * Range -> Dict + * Tensor -> Dict + * Dict -> Tensor + * String -> Tensor + * Tensor -> String + */ void toType_(ObjType type); - ObjPtr toShape(ObjPtr dims) const { - ObjPtr result = Clone(); - result->toShape_(dims); - return result; - } - ObjPtr toShape_(ObjPtr shape); - - ObjPtr Convert(ObjType type, ObjPtr shape = nullptr) const { - ObjPtr result = Clone(); - result->Convert_(type, shape); - return result; + virtual ~Obj() { + clear_(); } - ObjPtr Convert_(ObjType type, ObjPtr shape = nullptr) { - if (shape) { - toShape_(shape); - } - toType_(type); - return shared(); - } const ObjPtr index_get(const std::vector & index) const; @@ -1839,14 +1827,7 @@ namespace newlang { template < typename T> typename std::enable_if::value, void>::type SetValue_(bool value) { - - TEST_CONST_(); - - ASSERT(m_var_type_current != ObjType::Class); - clear_(); - m_value = torch::scalar_tensor(value, torch::Dtype::Bool); - m_var_type_current = GetType(m_value); - m_var_is_init = true; + SetValue_(static_cast (value)); } template < typename T> @@ -1855,8 +1836,8 @@ namespace newlang { TEST_CONST_(); ASSERT(m_var_type_current != ObjType::Class); clear_(); - m_value = torch::scalar_tensor(value, toTorchType(typeFromLimit((int64_t) value))); - m_var_type_current = GetType(m_value); + m_var = static_cast (value); + m_var_type_current = typeFromLimit(static_cast (value)); m_var_is_init = true; } @@ -1867,8 +1848,8 @@ namespace newlang { TEST_CONST_(); ASSERT(m_var_type_current != ObjType::Class); clear_(); - m_value = torch::scalar_tensor(value, toTorchType(typeFromLimit(value))); - m_var_type_current = GetType(m_value); + m_var = static_cast (value); + m_var_type_current = typeFromLimit(value); m_var_is_init = true; } @@ -1892,7 +1873,7 @@ namespace newlang { testConvertType(ObjType::StrChar); m_var_type_current = ObjType::StrChar; } - m_str.swap(text); + m_value.swap(text); m_var_is_init = true; } @@ -1902,7 +1883,7 @@ namespace newlang { testConvertType(ObjType::StrWide); m_var_type_current = ObjType::StrWide; } - m_wstr.swap(text); + m_string.swap(text); m_var_is_init = true; } @@ -1931,7 +1912,19 @@ namespace newlang { } } if (new_type != m_var_type_current) { - m_value = m_value.toType(toTorchType(new_type)); + if (is_scalar()) { + if (isFloatingType(new_type) && isIntegralType(m_var_type_current, true)) { + // Для скаляров повышение типа с целочисленного на число с плавающий точкой + m_var = static_cast (GetValueAsInteger()); + } else { + // Измерение размерности, а не типа - ничего делать ненужно + ASSERT((isFloatingType(new_type) && isFloatingType(m_var_type_current)) || + (isIntegralType(new_type, true) && isIntegralType(m_var_type_current, true))); + } + } else { + ASSERT(m_tensor.defined()); + m_tensor = m_tensor.toType(toTorchType(new_type)); + } m_var_type_current = new_type; } } @@ -1944,39 +1937,134 @@ namespace newlang { } else if ((is_none_type() || is_tensor()) && value->is_tensor()) { if (value->empty()) { - m_value.reset(); + m_var = at::monostate(); + m_tensor.reset(); m_var_is_init = false; return; } if (!canCast(value->m_var_type_current, m_var_type_current)) { testConvertType(value->m_var_type_current); - toType_(value->getType()); } + if (is_none_type()) { - m_value = value->m_value; + + // Присаеваем данные пустому значению + ASSERT(at::holds_alternative(m_var)); + ASSERT(!m_tensor.defined()); + + if (value->is_scalar()) { + m_var = value->m_var; + // if (value->is_integral()) { + // m_var = value->GetValueAsInteger(); // Нужно считывать значение, т.к. может быть ссылка + // } else { + // ASSERT(value->is_floating()); + // m_var = value->GetValueAsNumber(); // Нужно считывать значение, т.к. может быть ссылка + // } + } else { + m_tensor = value->m_tensor.clone(); + } m_var_type_current = value->m_var_type_current; + } else { - if (m_value.dim() == 0 && value->m_value.dim() != 0) { - LOG_RUNTIME("Fail assign tensor to scalar!"); - } - if (!m_var_is_init) { - m_value = value->m_value.clone(); + // текущая переменная уже сожержит данные + + if (is_scalar() && value->is_scalar()) { + // Два скаляра + switch (m_var_type_current) { + case ObjType::Bool: + if (at::holds_alternative(m_var)) { + m_var = value->GetValueAsInteger(); + } else if (at::holds_alternative(m_var)) { + ASSERT(at::get(m_var)); + *at::get(m_var) = value->GetValueAsInteger(); + } + break; + case ObjType::Char: + if (at::holds_alternative(m_var)) { + m_var = value->GetValueAsInteger(); + } else if (at::holds_alternative(m_var)) { + ASSERT(at::get(m_var)); + *at::get(m_var) = static_cast(value->GetValueAsInteger()); + } + break; + case ObjType::Short: + if (at::holds_alternative(m_var)) { + m_var = value->GetValueAsInteger(); + } else if (at::holds_alternative(m_var)) { + ASSERT(at::get(m_var)); + *at::get(m_var) = static_cast(value->GetValueAsInteger()); + } + break; + case ObjType::Int: + if (at::holds_alternative(m_var)) { + m_var = value->GetValueAsInteger(); + } else if (at::holds_alternative(m_var)) { + ASSERT(at::get(m_var)); + *at::get(m_var) = static_cast(value->GetValueAsInteger()); + } + break; + case ObjType::Long: + if (at::holds_alternative(m_var)) { + m_var = value->GetValueAsInteger(); + } else if (at::holds_alternative(m_var)) { + ASSERT(at::get(m_var)); + *at::get(m_var) = value->GetValueAsInteger(); + } + break; + case ObjType::Float: + if (at::holds_alternative(m_var)) { + m_var = value->GetValueAsNumber(); + } else if (at::holds_alternative(m_var)) { + ASSERT(at::get(m_var)); + *at::get(m_var) = static_cast(value->GetValueAsNumber()); + } + break; + case ObjType::Double: + if (at::holds_alternative(m_var)) { + m_var = value->GetValueAsNumber(); + } else if (at::holds_alternative(m_var)) { + ASSERT(at::get(m_var)); + *at::get(m_var) = value->GetValueAsNumber(); + } + break; + default: + LOG_RUNTIME("Fail set value type '%s'!", newlang::toString(m_var_type_current)); + } + + } else if (is_scalar() && !value->is_scalar()) { + + m_var = at::monostate(); + ASSERT(!m_tensor.defined()); + m_tensor = value->m_tensor.clone(); + + } else if (!is_scalar() && value->is_scalar()) { + + // Установить одно значение для всех элементов тензора + if (is_integral()) { + m_tensor.set_(torch::scalar_tensor(value->GetValueAsInteger(), m_tensor.scalar_type())); + } else { + ASSERT(is_floating()); + m_tensor.set_(torch::scalar_tensor(value->GetValueAsNumber(), m_tensor.scalar_type())); + } + } else { - if (!m_value.sizes().equals(value->m_value.sizes()) && value->m_value.dim() != 0) { - LOG_RUNTIME("Different sizes of tensors!"); + // Продублировать значения тензора если они одинакового размера + if (m_tensor.sizes().equals(value->m_tensor.sizes())) { + m_tensor = value->m_tensor.toType(m_tensor.scalar_type()).clone(); } else { - setTensorValue(m_value, value->m_value); + LOG_RUNTIME("Different sizes of tensors!"); } } } m_var_is_init = true; return; + } else if ((is_none_type() || is_string_type()) && value->is_string_type()) { switch (m_var_type_current) { - case ObjType::None: + case ObjType::None: // @todo Какой тип сроки по умолчанию? Пока байтовые case ObjType::StrChar: case ObjType::FmtChar: SetValue_(value->GetValueAsString()); @@ -1988,24 +2076,25 @@ namespace newlang { } } else if (is_none_type() || isObjectType(m_var_type_current)) { + std::string old_name = m_var_name; clear_(); value->CloneDataTo(*this); value->ClonePropTo(*this); m_var_name.swap(old_name); m_var_is_init = true; - return; - } else if ((is_none_type() || m_var_type_current == ObjType::Pointer) && value->m_var_type_current == ObjType::Pointer) { - //@todo Check tree type !!! - std::string old_name = m_var_name; - value->CloneDataTo(*this); - value->ClonePropTo(*this); - m_var_name.swap(old_name); - m_var_is_init = true; + // } else if ((is_none_type() || m_var_type_current == ObjType::Pointer) && value->m_var_type_current == ObjType::Pointer) { + // //@todo Check tree type !!! + // + // std::string old_name = m_var_name; + // value->CloneDataTo(*this); + // value->ClonePropTo(*this); + // m_var_name.swap(old_name); + // m_var_is_init = true; + // return; - return; } else if ((is_none_type() || m_var_type_current == ObjType::Function) && value->is_function()) { //@todo Check function type args !!! @@ -2028,7 +2117,7 @@ namespace newlang { // m_var_name.swap(old_name); // m_var_is_init = true; // *const_cast (&m_func_proto) = save_proto; - m_block_source = value->m_block_source; + m_sequence = value->m_sequence; // m_var_type_current = save_type; return; @@ -2059,7 +2148,7 @@ namespace newlang { inline const TermPtr Proto() { - return m_func_proto; + return m_prototype; } protected: @@ -2072,38 +2161,55 @@ namespace newlang { ObjType m_var_type_fixed; ///< Максимальный размер для арифметических типов, который задается разработчиком bool m_var_is_init; ///< Содержит ли объект корректное значение ??? - // struct FuncInfo { - // const TermPtr m_func_proto; - // std::string m_func_mangle_name; - // void *m_func_ptr; - // ffi_abi m_func_abi; - // }; - // std::variant m_var; - + std::string m_namespace; std::string m_var_name; ///< Имя переменной, в которой хранится объект ObjPtr m_dimensions; ///< Размерности для ObjType::Type std::string m_class_name; ///< Имя класса объекта (у базовых типов отсуствует) std::vector m_class_parents; ///< Родительские классы (типы) - std::string m_namespace; - std::string m_str; - std::wstring m_wstr; mutable PairType m_str_pair; //< Для доступа к отдельным символам строк - const TermPtr m_func_proto; std::string m_func_mangle_name; std::string m_module_name; - void *m_func_ptr; - // ffi_abi m_func_abi; - torch::Tensor m_value; - std::shared_ptr m_fraction; - std::shared_ptr< Iterator > m_iterator; - TermPtr m_block_source; + // Применение variant необходимо для полей хранения данных, чтобы контролировать их инициализацию + // std::variant, std::shared_ptr< Iterator >, TermPtr> m_var; + + // std::variant m_var; + + struct NativeData { + void * ptr; + int64_t size; + }; + + at::variant> m_var; + + // union { + // int64_t m_integer; + // double m_number; + // void *m_pointer; ///< Содержит указатель на нативную функцию или область памяти с данными или скаляр + // }; + + std::string m_value; ///< Содержит байтовую строку или байтовый массив с данными для представления в нативном виде (Struct, Unuion, Enum) + std::wstring m_string; ///< Содержит строку широких символов + torch::Tensor m_tensor; ///< Содержит только размерные тензоры (скляры хранятся в поле m_pointer и не создают m_tensor.defined()) + std::shared_ptr m_fraction; ///< Содержит дробь из длинных чисел + std::shared_ptr< Iterator > m_iterator; ///< Итератор для данных + TermPtr m_sequence; ///< Последовательно распарсенных команд для выполнения + const TermPtr m_prototype; ///< Описание прототипп функции (или данных) + bool m_check_args; //< Проверять аргументы на корректность (для всех видов функций) @ref MakeArgs + /* Для будущей переделки системы типов и базового класса: + * Должен быть интерфейс с поддерживаемыми операциями для стандартных типов данных + * и набор реализаций для скаляров, строк, тензоров, нативных функций, дробей, внутренних функций и т.д. + */ + // SCOPE(protected) : bool m_is_const; //< Признак константы (по умолчанию изменения разрешено) bool m_is_reference; //< Признак ссылки на объект (mutable) diff --git a/src/parser.y b/src/parser.y index 3615a243..7040766b 100644 --- a/src/parser.y +++ b/src/parser.y @@ -1308,6 +1308,14 @@ op_factor: '*' addition: addition op_factor factor { + + if($op_factor->m_text.compare("/")==0 && $factor->m_text.compare("1")==0) { + // throw syntax_error(yyla.location, + NL_PARSER($op_factor, "Do not use division by one (e.g. 123/1), " + "as this operation does not make sense, but it is easy to " + "confuse it with the notation of a fraction literal (123\\1)."); + } + $$ = $2; $$->SetTermID(TermID::OPERATOR); $$->Append($1, Term::LEFT); diff --git a/src/pch.h b/src/pch.h index dc2eba01..2faa56ef 100644 --- a/src/pch.h +++ b/src/pch.h @@ -23,7 +23,6 @@ #include #include #include -#include #include #include diff --git a/src/test/alg_test.cpp b/src/test/alg_test.cpp index ada94f5f..8a3249fc 100644 --- a/src/test/alg_test.cpp +++ b/src/test/alg_test.cpp @@ -217,6 +217,13 @@ TEST(Alg, Foreach) { dict->push_back(Obj::Arg(50)); ASSERT_EQ(5, dict->size()); + temp = ctx.ExecStr("dict"); + ASSERT_TRUE(temp); + ASSERT_TRUE(temp->is_dictionary_type()); + ASSERT_FALSE(temp->is_scalar()); + ASSERT_TRUE(temp->GetValueAsBoolean()); + ASSERT_EQ(5, temp->size()); + temp = ctx.ExecStr(":Bool(dict)"); ASSERT_TRUE(temp); ASSERT_TRUE(temp->is_bool_type()); diff --git a/src/test/eval_test.cpp b/src/test/eval_test.cpp index 3dd42245..47047006 100644 --- a/src/test/eval_test.cpp +++ b/src/test/eval_test.cpp @@ -43,8 +43,9 @@ TEST(Eval, Assign) { ASSERT_TRUE(var1); ASSERT_TRUE(var1->is_arithmetic_type()); ASSERT_TRUE(var1->is_integer()); - ASSERT_EQ(var1->m_var_type_current, ObjType::Char); - ASSERT_EQ(var1->m_var_type_fixed, ObjType::None); + ASSERT_TRUE(at::holds_alternative(var1->m_var)); + ASSERT_EQ(var1->m_var_type_current, ObjType::Char) << newlang::toString(var1->m_var_type_current); + ASSERT_EQ(var1->m_var_type_fixed, ObjType::None) << newlang::toString(var1->m_var_type_fixed); ASSERT_STREQ("var1=123", var1->toString().c_str()); ASSERT_FALSE(ctx.find("var1") == ctx.end()); @@ -54,8 +55,8 @@ TEST(Eval, Assign) { ASSERT_THROW(ctx.ExecStr("var1 ::= 123"), Interrupt); ASSERT_TRUE(ctx.ExecStr("var1 = 100:Char")); - ASSERT_EQ(var1->m_var_type_current, ObjType::Char); - ASSERT_EQ(var1->m_var_type_fixed, ObjType::None); + ASSERT_EQ(var1->m_var_type_current, ObjType::Char) << newlang::toString(var1->m_var_type_current); + ASSERT_EQ(var1->m_var_type_fixed, ObjType::None) << newlang::toString(var1->m_var_type_fixed); ASSERT_STREQ("var1=100", var1->toString().c_str()); ASSERT_TRUE(ctx.ExecStr("var1 = 999")); @@ -181,8 +182,8 @@ TEST(Eval, Assign) { ASSERT_TRUE(tensor); ASSERT_EQ(ObjType::Bool, tensor->m_var_type_current) << toString(tensor->m_var_type_current); ASSERT_EQ(ObjType::None, tensor->m_var_type_fixed) << toString(tensor->m_var_type_fixed); - ASSERT_EQ(1, tensor->m_value.dim()); - ASSERT_EQ(4, tensor->m_value.size(0)); + ASSERT_EQ(1, tensor->m_tensor.dim()); + ASSERT_EQ(4, tensor->m_tensor.size(0)); ASSERT_EQ(1, tensor->index_get({0})->GetValueAsInteger()); ASSERT_EQ(1, tensor->index_get({1})->GetValueAsInteger()); ASSERT_EQ(0, tensor->index_get({2})->GetValueAsInteger()); @@ -202,9 +203,9 @@ TEST(Eval, Assign) { ASSERT_TRUE(tensor_all); ASSERT_EQ(ObjType::Double, tensor_all->m_var_type_current) << toString(tensor_all->m_var_type_current); ASSERT_EQ(ObjType::None, tensor_all->m_var_type_fixed) << toString(tensor_all->m_var_type_fixed); - ASSERT_EQ(2, tensor_all->m_value.dim()); - ASSERT_EQ(2, tensor_all->m_value.size(0)); - ASSERT_EQ(4, tensor_all->m_value.size(1)); + ASSERT_EQ(2, tensor_all->m_tensor.dim()) << tensor_all->m_tensor.size(0); + ASSERT_EQ(2, tensor_all->m_tensor.size(0)); + ASSERT_EQ(4, tensor_all->m_tensor.size(1)); ASSERT_STREQ("1", tensor_all->index_get({0, 0})->GetValueAsString().c_str()); ASSERT_STREQ("1", tensor_all->index_get({0, 1})->GetValueAsString().c_str()); @@ -223,6 +224,23 @@ TEST(Eval, Tensor) { Context ctx(RunTime::Init()); + ObjPtr ddd = ctx.ExecStr("(1,2,3,)"); + ASSERT_TRUE(ddd); + ASSERT_STREQ("(1, 2, 3,)", ddd->GetValueAsString().c_str()) << ddd->GetValueAsString().c_str(); + + ddd = ctx.ExecStr(":Tensor( (1,2,3,) )"); + ASSERT_TRUE(ddd); + ASSERT_STREQ("[1, 2, 3,]:Char", ddd->GetValueAsString().c_str()) << ddd->GetValueAsString().c_str(); + + + ddd = ctx.ExecStr(":Dictionary(1,2,3)"); + ASSERT_TRUE(ddd); + ASSERT_STREQ("(1, 2, 3,)", ddd->GetValueAsString().c_str()) << ddd->GetValueAsString().c_str(); + + ddd = ctx.ExecStr(":Dictionary( (1,2,3,) )"); + ASSERT_TRUE(ddd); + ASSERT_STREQ("((1, 2, 3,),)", ddd->GetValueAsString().c_str()) << ddd->GetValueAsString().c_str(); + ObjPtr tensor = ctx.ExecStr(":Tensor(1)"); ASSERT_TRUE(tensor); ASSERT_EQ(ObjType::Tensor, tensor->m_var_type_fixed) << toString(tensor->m_var_type_fixed); @@ -245,18 +263,18 @@ TEST(Eval, Tensor) { ObjPtr tt = ctx.ExecStr(":Tensor[3]( (1,2,3,) )"); ASSERT_TRUE(tt); - ASSERT_STREQ("[1, 2, 3,]:Char", tt->GetValueAsString().c_str()) << tensor->GetValueAsString().c_str(); + ASSERT_STREQ("[1, 2, 3,]:Char", tt->GetValueAsString().c_str()) << tt->GetValueAsString().c_str(); tt = ctx.ExecStr(":Int((1,2,3,))"); ASSERT_TRUE(tt); - ASSERT_STREQ("[1, 2, 3,]:Int", tt->GetValueAsString().c_str()) << tensor->GetValueAsString().c_str(); + ASSERT_STREQ("[1, 2, 3,]:Int", tt->GetValueAsString().c_str()) << tt->GetValueAsString().c_str(); tt = ctx.ExecStr(":Int[2,3]((1,2,3,4,5,6,))"); ASSERT_TRUE(tt); - EXPECT_EQ(2, tt->m_value.dim()); - EXPECT_EQ(2, tt->m_value.size(0)); - EXPECT_EQ(3, tt->m_value.size(1)); + EXPECT_EQ(2, tt->m_tensor.dim()); + EXPECT_EQ(2, tt->m_tensor.size(0)); + EXPECT_EQ(3, tt->m_tensor.size(1)); ASSERT_STREQ("[\n [1, 2, 3,], [4, 5, 6,],\n]:Int", tt->GetValueAsString().c_str()); @@ -291,7 +309,10 @@ TEST(Eval, Tensor) { // Может быть раскрытие словаря, который возвращает вызов функции // и может быть многократный вызов одной и той функции // :Int[3,2]( ... rand() ... ) + utils::Logger::LogLevelType save = utils::Logger::Instance()->SetLogLevel(LOG_LEVEL_INFO); tt = ctx.ExecStr(":Int[3,2]( ... rand() ... )"); + utils::Logger::Instance()->SetLogLevel(save); + ASSERT_TRUE(tt); std::string rand_str = tt->GetValueAsString(); ASSERT_TRUE(50 < tt->GetValueAsString().size()) << rand_str; @@ -397,12 +418,14 @@ TEST(Eval, TypesNative) { ObjPtr fopen = ctx.CreateNative("fopen(filename:StrChar, modes:StrChar):File"); ASSERT_TRUE(fopen); - ASSERT_TRUE(fopen->m_func_ptr); + ASSERT_TRUE(at::holds_alternative(fopen->m_var)); + ASSERT_TRUE(at::get(fopen->m_var)); ObjPtr fopen2 = ctx.ExecStr("@fopen2 ::= :Pointer('fopen(filename:StrChar, modes:StrChar):File')"); ASSERT_TRUE(fopen2); - ASSERT_TRUE(fopen2->m_func_ptr); - ASSERT_EQ(fopen->m_func_ptr, fopen2->m_func_ptr); + ASSERT_TRUE(at::holds_alternative(fopen2->m_var)); + ASSERT_TRUE(at::get(fopen2->m_var)); + ASSERT_EQ(at::get(fopen->m_var), at::get(fopen2->m_var)); ASSERT_TRUE(ctx.FindTerm("fopen2")); auto iter = ctx.m_global_terms.find("fopen2"); ASSERT_NE(iter, ctx.m_global_terms.end()); @@ -410,22 +433,25 @@ TEST(Eval, TypesNative) { ObjPtr fopen3 = ctx.ExecStr("@fopen3(filename:String, modes:String):File ::= " ":Pointer('fopen(filename:StrChar, modes:StrChar):File')"); ASSERT_TRUE(fopen3); - ASSERT_TRUE(fopen3->m_func_ptr); - ASSERT_EQ(fopen->m_func_ptr, fopen3->m_func_ptr); + ASSERT_TRUE(at::holds_alternative(fopen3->m_var)); + ASSERT_TRUE(at::get(fopen3->m_var)); + ASSERT_EQ(at::get(fopen->m_var), at::get(fopen3->m_var)); ObjPtr fclose = ctx.ExecStr("@fclose(stream:File):Int ::= :Pointer(\"fclose(stream:File):Int\")"); - ASSERT_TRUE(fclose); - ASSERT_TRUE(fclose->m_func_ptr); + ASSERT_TRUE(at::holds_alternative(fclose->m_var)); + ASSERT_TRUE(at::get(fclose->m_var)); ObjPtr fremove = ctx.ExecStr("@fremove(filename:String):Int ::= " ":Pointer(\"remove(filename:StrChar):Int\")"); ASSERT_TRUE(fremove); - ASSERT_TRUE(fremove->m_func_ptr); + ASSERT_TRUE(at::holds_alternative(fremove->m_var)); + ASSERT_TRUE(at::get(fremove->m_var)); ObjPtr frename = ctx.ExecStr("@rename(old:String, new:String):Int ::= " ":Pointer('rename(old:StrChar, new:StrChar):Int')"); ASSERT_TRUE(frename); - ASSERT_TRUE(frename->m_func_ptr); + ASSERT_TRUE(at::holds_alternative(frename->m_var)); + ASSERT_TRUE(at::get(frename->m_var)); ObjPtr fprintf = ctx.ExecStr("@fprintf(stream:File, format:FmtChar, ...):Int ::= " ":Pointer('fprintf(stream:File, format:FmtChar, ...):Int')"); @@ -589,12 +615,13 @@ TEST(ExecStr, Funcs) { ObjPtr p = ctx.ExecStr("printf := :Pointer('printf(format:FmtChar, ...):Int');"); ASSERT_TRUE(p); - ASSERT_TRUE(p->m_func_ptr); + ASSERT_TRUE(at::holds_alternative(p->m_var)); + ASSERT_TRUE(at::get(p->m_var)); ASSERT_STREQ("printf=printf(format:FmtChar, ...):Int{}", p->toString().c_str()); typedef int (* printf_type)(const char *, ...); - printf_type ttt = (printf_type) p->m_func_ptr; + printf_type ttt = (printf_type) at::get(p->m_var); ASSERT_EQ(7, (*ttt)("Test 1 ")); ASSERT_EQ(18, (*ttt)("%s", "Test Variadic call")); @@ -697,30 +724,32 @@ TEST(Eval, Convert) { ObjPtr obj_0 = ctx.ExecStr("0"); ASSERT_TRUE(obj_0); - ASSERT_EQ(at::ScalarType::Bool, obj_0->m_value.scalar_type()); + ASSERT_TRUE(obj_0->is_scalar()); + ASSERT_FALSE(obj_0->m_tensor.defined()); ASSERT_EQ(ObjType::Bool, obj_0->getType()); ASSERT_EQ(ObjType::None, obj_0->m_var_type_fixed); ASSERT_STREQ("0", obj_0->GetValueAsString().c_str()); ObjPtr obj_1 = ctx.ExecStr("1"); ASSERT_TRUE(obj_1); - ASSERT_EQ(at::ScalarType::Bool, obj_1->m_value.scalar_type()); + ASSERT_TRUE(obj_1->is_scalar()); + ASSERT_FALSE(obj_1->m_tensor.defined()); ASSERT_EQ(ObjType::Bool, obj_1->getType()); ASSERT_EQ(ObjType::None, obj_1->m_var_type_fixed); ASSERT_STREQ("1", obj_1->GetValueAsString().c_str()); ObjPtr obj_2 = ctx.ExecStr("2"); ASSERT_TRUE(obj_2); - ASSERT_EQ(at::ScalarType::Char, obj_2->m_value.scalar_type()); + ASSERT_TRUE(obj_2->is_scalar()); + ASSERT_FALSE(obj_2->m_tensor.defined()); ASSERT_EQ(ObjType::Char, obj_2->getType()); ASSERT_EQ(ObjType::None, obj_2->m_var_type_fixed); ASSERT_STREQ("2", obj_2->GetValueAsString().c_str()); ObjPtr obj_int = ctx.ExecStr(":Int(0)"); ASSERT_TRUE(obj_int); - ASSERT_TRUE(obj_int->is_tensor()); ASSERT_TRUE(obj_int->is_scalar()); - ASSERT_EQ(at::ScalarType::Int, obj_int->m_value.scalar_type()); + ASSERT_FALSE(obj_int->m_tensor.defined()); ASSERT_EQ(ObjType::Int, obj_int->getType()) << toString(obj_int->m_var_type_current); ASSERT_EQ(ObjType::Int, obj_int->m_var_type_fixed) << toString(obj_int->m_var_type_fixed); @@ -733,7 +762,7 @@ TEST(Eval, Convert) { ASSERT_TRUE(scalar); ASSERT_TRUE(scalar->is_tensor()); ASSERT_TRUE(scalar->is_scalar()); - ASSERT_EQ(at::ScalarType::Int, scalar->m_value.scalar_type()); + ASSERT_FALSE(scalar->m_tensor.defined()); ASSERT_EQ(ObjType::Int, scalar->getType()) << toString(scalar->m_var_type_current); ASSERT_EQ(ObjType::Int, scalar->m_var_type_fixed) << toString(scalar->m_var_type_fixed); @@ -749,26 +778,23 @@ TEST(Eval, Convert) { ASSERT_TRUE(ten->m_var_is_init); ASSERT_STREQ("[0,]:Bool", ten->GetValueAsString().c_str()); - ASSERT_EQ(0, ten->GetValueAsInteger()); - ObjPtr obj_ten = ctx.ExecStr(":Int([0,])"); ASSERT_TRUE(obj_ten); ASSERT_TRUE(obj_ten->is_tensor()); ASSERT_FALSE(obj_ten->is_scalar()); - ASSERT_EQ(at::ScalarType::Int, obj_ten->m_value.scalar_type()); + ASSERT_EQ(at::ScalarType::Int, obj_ten->m_tensor.scalar_type()); ASSERT_EQ(ObjType::Int, obj_ten->getType()) << toString(obj_ten->m_var_type_current); ASSERT_EQ(ObjType::Int, obj_ten->m_var_type_fixed) << toString(obj_ten->m_var_type_fixed); ASSERT_TRUE(obj_ten->m_var_is_init); ASSERT_STREQ("[0,]:Int", obj_ten->GetValueAsString().c_str()); - ASSERT_EQ(0, obj_ten->GetValueAsInteger()); ObjPtr obj_auto = ctx.ExecStr(":Int(0, 1, 2, 3)"); ASSERT_TRUE(obj_auto); - ASSERT_EQ(at::ScalarType::Int, obj_auto->m_value.scalar_type()); + ASSERT_EQ(at::ScalarType::Int, obj_auto->m_tensor.scalar_type()); ASSERT_EQ(ObjType::Int, obj_auto->getType()) << toString(obj_auto->m_var_type_current); ASSERT_EQ(ObjType::Int, obj_auto->m_var_type_fixed) << toString(obj_auto->m_var_type_fixed); @@ -1218,13 +1244,13 @@ TEST(Eval, Iterator) { // //} -class OpEvalTest : public ::testing::Test { +class EvalTester : public ::testing::Test { protected: Context m_ctx; ObjPtr m_result; std::string m_string; - OpEvalTest() : m_ctx(RunTime::Init()) { + EvalTester() : m_ctx(RunTime::Init()) { } const char *Test(std::string eval, Obj *vars) { @@ -1247,7 +1273,7 @@ class OpEvalTest : public ::testing::Test { } }; -TEST_F(OpEvalTest, Ops) { +TEST_F(EvalTester, Ops) { ASSERT_STREQ("10", Test("10")); ASSERT_STREQ("32", Test("10+22")); ASSERT_STREQ("5.1", Test("1.1+4")); diff --git a/src/test/object_test.cpp b/src/test/object_test.cpp index 6e6555d1..06549b47 100644 --- a/src/test/object_test.cpp +++ b/src/test/object_test.cpp @@ -77,7 +77,7 @@ TEST(ObjTest, String) { ObjPtr str_byte = Obj::CreateString("byte"); ASSERT_STREQ("byte", str_byte->GetValueAsString().c_str()); ASSERT_EQ(4, str_byte->size()); - ASSERT_EQ(4, str_byte->m_str.size()); + ASSERT_EQ(4, str_byte->m_value.size()); ASSERT_STREQ("b", (*str_byte)[0].second->GetValueAsString().c_str()); ASSERT_STREQ("y", (*str_byte)[1].second->GetValueAsString().c_str()); ASSERT_STREQ("t", (*str_byte)[2].second->GetValueAsString().c_str()); @@ -92,7 +92,7 @@ TEST(ObjTest, String) { ObjPtr str_char = Obj::CreateString(L"строка"); ASSERT_EQ(6, str_char->size()); - ASSERT_EQ(6, str_char->m_wstr.size()); + ASSERT_EQ(6, str_char->m_string.size()); ASSERT_STREQ("с", (*str_char)[0].second->GetValueAsString().c_str()); ASSERT_STREQ("т", (*str_char)[1].second->GetValueAsString().c_str()); @@ -754,9 +754,9 @@ TEST(ObjTest, Tensor) { ASSERT_EQ(ObjType::Int, t1->m_var_type_fixed); ASSERT_FALSE(t1->m_var_is_init); - ASSERT_EQ(2, t1->m_value.dim()); - ASSERT_EQ(2, t1->m_value.size(0)); - ASSERT_EQ(3, t1->m_value.size(1)); + ASSERT_EQ(2, t1->m_tensor.dim()); + ASSERT_EQ(2, t1->m_tensor.size(0)); + ASSERT_EQ(3, t1->m_tensor.size(1)); std::string from_str = "русские буквы для ПРОВЕРКИ КОНВЕРТАЦИИ символов"; std::wstring to_str = utf8_decode(from_str); @@ -766,25 +766,58 @@ TEST(ObjTest, Tensor) { // Байтовые строки ObjPtr str = Obj::CreateString("test"); - ObjPtr t_str = Obj::CreateTensor(str->toTensor()); + + ASSERT_STREQ("test", str->m_value.c_str()); + + torch::Tensor tstr_t; + + ConvertStringToTensor(str->m_value, tstr_t, ObjType::Char); + + ASSERT_TRUE(tstr_t.defined()); + ASSERT_EQ(tstr_t.index({0}).item(), 't'); + ASSERT_EQ(tstr_t.index({1}).item(), 'e'); + ASSERT_EQ(tstr_t.index({2}).item(), 's'); + ASSERT_EQ(tstr_t.index({3}).item(), 't'); + + + torch::Tensor tensot_temp = str->toType(ObjType::Tensor)->m_tensor; + ASSERT_TRUE(tensot_temp.defined()); + ASSERT_EQ(tensot_temp.index({0}).item(), 't'); + ASSERT_EQ(tensot_temp.index({1}).item(), 'e'); + ASSERT_EQ(tensot_temp.index({2}).item(), 's'); + ASSERT_EQ(tensot_temp.index({3}).item(), 't'); + + ObjPtr t_str = Obj::CreateTensor(tensot_temp); ASSERT_EQ(t_str->m_var_type_current, ObjType::Char) << toString(t_str->m_var_type_current); ASSERT_EQ(4, t_str->size()); - EXPECT_STREQ(t_str->toType(ObjType::StrWide)->GetValueAsString().c_str(), "test"); + ASSERT_TRUE(t_str->m_tensor.defined()); + + ASSERT_EQ(t_str->m_tensor.index({0}).item(), 't'); + ASSERT_EQ(t_str->m_tensor.index({1}).item(), 'e'); + ASSERT_EQ(t_str->m_tensor.index({2}).item(), 's'); + ASSERT_EQ(t_str->m_tensor.index({3}).item(), 't'); ASSERT_EQ(t_str->index_get({0})->GetValueAsInteger(), 't'); ASSERT_EQ(t_str->index_get({1})->GetValueAsInteger(), 'e'); ASSERT_EQ(t_str->index_get({2})->GetValueAsInteger(), 's'); ASSERT_EQ(t_str->index_get({3})->GetValueAsInteger(), 't'); + ASSERT_STREQ(t_str->toType(ObjType::StrWide)->GetValueAsString().c_str(), "test") << t_str->toType(ObjType::StrWide)->GetValueAsString(); + t_str->index_set_({1}, Obj::CreateString("E")); t_str->index_set_({2}, Obj::CreateString("S")); - EXPECT_STREQ(t_str->toType(ObjType::StrWide)->GetValueAsString().c_str(), "tESt"); + EXPECT_STREQ(t_str->toType(ObjType::StrWide)->GetValueAsString().c_str(), "tESt") << t_str->toType(ObjType::StrWide)->GetValueAsString(); // Символьные сторки ObjPtr wstr = Obj::CreateString(L"ТЕСТ"); - ObjPtr t_wstr = Obj::CreateTensor(wstr->toTensor()); - ASSERT_EQ(t_wstr->m_var_type_current, ObjType::Int); + ObjPtr t_wstr = Obj::CreateTensor(wstr->toType(ObjType::Tensor)->m_tensor); + if(sizeof (wchar_t) == 2) { + ASSERT_EQ(t_wstr->m_var_type_current, ObjType::Short); + } else { + ASSERT_TRUE(sizeof (wchar_t) == 4); + ASSERT_EQ(t_wstr->m_var_type_current, ObjType::Int); + } ASSERT_EQ(4, t_wstr->size()); ASSERT_EQ(t_wstr->index_get({0})->GetValueAsInteger(), L'Т'); @@ -792,12 +825,17 @@ TEST(ObjTest, Tensor) { ASSERT_EQ(t_wstr->index_get({2})->GetValueAsInteger(), L'С'); ASSERT_EQ(t_wstr->index_get({3})->GetValueAsInteger(), L'Т'); - EXPECT_STREQ(t_wstr->toType(ObjType::StrWide)->GetValueAsString().c_str(), "ТЕСТ"); + std::wstring test_wide = t_wstr->toType(ObjType::StrWide)->GetValueAsStringWide(); + EXPECT_STREQ(utf8_encode(test_wide).c_str(), "ТЕСТ"); + + std::string test_str = t_wstr->toType(ObjType::StrWide)->GetValueAsString(); + EXPECT_STREQ(test_str.c_str(), "ТЕСТ") << test_str; t_wstr->index_set_({1}, Obj::CreateString(L"е")); t_wstr->index_set_({2}, Obj::CreateString(L"с")); - EXPECT_STREQ(t_wstr->toType(ObjType::StrWide)->GetValueAsString().c_str(), "ТесТ"); + test_str = t_wstr->toType(ObjType::StrWide)->GetValueAsString(); + EXPECT_STREQ(test_str.c_str(), "ТесТ") << test_str; } diff --git a/src/test/parser_test.cpp b/src/test/parser_test.cpp index f4d58027..022dc530 100644 --- a/src/test/parser_test.cpp +++ b/src/test/parser_test.cpp @@ -110,6 +110,13 @@ TEST_F(ParserTest, LiteralFraction) { ASSERT_EQ(TermID::FRACTION, ast->getTermID()) << newlang::toString(ast->getTermID()); ASSERT_STREQ("1\\1", ast->toString().c_str()); + /* Защита от случайной операции деления на единицу вместо указания дроби */ + ASSERT_ANY_THROW(Parse("1/1")); + ASSERT_ANY_THROW(Parse("rrr := 1/1")); + ASSERT_NO_THROW(Parse("rrr := 1\\1")); + ASSERT_ANY_THROW(Parse("rrr := 11111111111111111/1")); + ASSERT_NO_THROW(Parse("rrr := 11111111111111111\\1")); + ASSERT_TRUE(Parse("100\\100;")); ASSERT_EQ(TermID::FRACTION, ast->getTermID()) << newlang::toString(ast->getTermID()); ASSERT_STREQ("100\\100", ast->toString().c_str()); diff --git a/src/test/speed_test.cpp b/src/test/speed_test.cpp index 1d58dbe4..0d9b1c3a 100644 --- a/src/test/speed_test.cpp +++ b/src/test/speed_test.cpp @@ -12,6 +12,11 @@ using namespace newlang; +/* + * Тест производительности на базе исходников из статьи + * https://towardsdatascience.com/how-fast-is-c-compared-to-python-978f18f474c7 + */ + char convert(char c) { if(c == 'A') return 'C'; if(c == 'C') return 'G'; @@ -74,30 +79,44 @@ TEST(Speed, NewLang) { Context::Reset(); Context ctx(RunTime::Init()); - std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now(); - setvbuf(stdin, nullptr, _IONBF, 0); setvbuf(stdout, nullptr, _IONBF, 0); setvbuf(stderr, nullptr, _IONBF, 0); - // std::string src; - // src = "@printf := :Pointer('printf(format:FmtChar, ...):Int'); @counter := 1; printf('%d',counter)"; - // ObjPtr test = ctx.ExecStr(src.c_str(), nullptr, true); - // ASSERT_TRUE(test); - // ASSERT_STREQ("0", test->GetValueAsString().c_str()); + + ObjPtr test; + + ObjPtr str = ctx.ExecStr("@str := 'ABCDEF\\n';", nullptr, true); + ASSERT_TRUE(str); + ASSERT_STREQ("ABCDEF\n", str->GetValueAsString().c_str()); + + test = ctx.ExecStr("@printf := :Pointer('printf(format:FmtChar, ...):Int'); @str := 'ABCDEF\\n'; printf('%s', str)", nullptr, true); + ASSERT_TRUE(test); + ASSERT_STREQ("7", test->GetValueAsString().c_str()); + + test = ctx.ExecStr("str[1] = 32; str", nullptr, true); + ASSERT_TRUE(test); + ASSERT_STREQ("A CDEF\n", test->GetValueAsString().c_str()); LLVMAddSymbol("convert", (void *) &convert); - // src = "@test_convert := :Pointer('convert(sym:Char):Char'); test_convert('A')"; - // ObjPtr test = ctx.ExecStr(src.c_str(), nullptr, true); - // ASSERT_TRUE(test); - // ASSERT_STREQ("67", test->GetValueAsString().c_str()); + ObjPtr test_convert = ctx.ExecStr("@test_convert := :Pointer('convert(sym:Char):Char')", nullptr, true); + ASSERT_TRUE(test_convert); + + test = ctx.ExecStr("test_convert('A')", nullptr, true); + ASSERT_TRUE(test); + ASSERT_STREQ("67", test->GetValueAsString().c_str()); + + test = ctx.ExecStr("str[1] = test_convert('A'); str", nullptr, true); + ASSERT_TRUE(test); + ASSERT_STREQ("ACCDEF\n", test->GetValueAsString().c_str()); utils::Logger::LogLevelType save = utils::Logger::Instance()->SetLogLevel(LOG_LEVEL_INFO); + std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now(); ObjPtr result = ctx.ExecFile("../examples/speed_test.nlp"); + std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now(); utils::Logger::Instance()->SetLogLevel(save); - std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now(); ASSERT_TRUE(result); @@ -134,6 +153,28 @@ TEST(Speed, NewLang) { * 7 символов без вывода строк - 8.43029 sec * 8 символов без вывода строк - 32.154832 sec * + * После переделки способа хранения скаляров в нативном виде, а не в тензорах + * Своя функция @convert + * 5 символов - 1.255214 сек (с вывоводм строк) 0.306725 sec - без вывода строк + * 6 символов - 15.995722 sec (с вывоводм строк) 1.253190 sec - без вывода строк + * 7 символов без вывода строк - 5.12946 sec + * 8 символов без вывода строк - 19.653851 sec + * + * Импорт С++ функции convert + * 5 символов - 1.195008 sec (с вывоводм строк) 0.351575 sec - без вывода строк + * 6 символов - 13.666785 sec (с вывоводм строк) 1.428339 sec - без вывода строк + * 7 символов без вывода строк - 5.628200 sec + * 8 символов без вывода строк - 22.258760 sec + * + * Start speed test NewLang + * From AAAAAAAAAA to TTTTTTTTTT + * Number of generated k-mers: 1048576 + * Test complete at 320.401650 sec (более 5 минут) + * + * Никакой оптимизации не проводилось. + * Программа не преобразуется в промежуточный byte-code, а интерпретируется какждый раз при выполнении. + * LLVM код вызова нативных функий генерируется каждый раз, не при создании функции. + * Возможности для оптимиации производительности чрезвычайно общширны ;-) */ } diff --git a/src/types.h b/src/types.h index 12ae34b0..cd2afa17 100644 --- a/src/types.h +++ b/src/types.h @@ -415,9 +415,16 @@ void ParserException(const char *msg, std::string &buffer, int row, int col); static_cast (t) <= static_cast (ObjType::Arithmetic); } + inline bool isStringChar(ObjType t) { + return t == ObjType::StrChar || t == ObjType::FmtChar || t == ObjType::ViewChar; + } + + inline bool isStringWide(ObjType t) { + return t == ObjType::StrWide || t == ObjType::ViewWide || t == ObjType::FmtWide; + } + inline bool isString(ObjType t) { - return t == ObjType::StrChar || t == ObjType::StrWide || t == ObjType::ViewWide || t == ObjType::ViewWide - || t == ObjType::String || t == ObjType::FmtChar || t == ObjType::FmtWide; + return isStringChar(t) || isStringWide(t) || t == ObjType::String; } inline bool isPlainDataType(ObjType t) { @@ -593,6 +600,8 @@ void ParserException(const char *msg, std::string &buffer, int row, int col); return true; } else if (isDictionary(from) && isDictionary(to)) { return true; + } else if (isFunction(from) && isFunction(to)) { + return true; } return false; } @@ -629,184 +638,6 @@ void ParserException(const char *msg, std::string &buffer, int row, int col); return canCast(typeFromString(from), typeFromString(to)); } - inline void setTensorValue(torch::Tensor &self, torch::Tensor &set) { - if (!at::canCast(set.scalar_type(), self.scalar_type())) { - LOG_RUNTIME("Can`t cast '%s' to '%s'!", at::toString(set.scalar_type()), at::toString(self.scalar_type())); - } - if (self.dim() == 0 && set.dim() != 0) { - LOG_RUNTIME("Fail assign tensor to scalar!"); - } - if (!self.sizes().equals(set.sizes()) && set.dim() != 0) { - LOG_RUNTIME("Different sizes of tensors!"); - } - - if (set.dim() != 0) { - self = set.clone(); - return; - - ASSERT(set.dim() == 0); - } - - bool *ptr_boll = nullptr; - signed char *ptr_char = nullptr; - int16_t *ptr_short = nullptr; - int32_t *ptr_int = nullptr; - int64_t *ptr_long = nullptr; - float *ptr_float = nullptr; - double *ptr_double = nullptr; - - if (self.dim() == 0 && set.dim() == 0) { - // scalar := scalar - switch (fromTorchType(self.scalar_type())) { - case ObjType::Bool: - ptr_boll = self.data_ptr(); - ASSERT(ptr_boll); - *ptr_boll = set.item().toBool(); - return; - case ObjType::Char: - ptr_char = self.data_ptr(); - ASSERT(ptr_char); - *ptr_char = set.item().toChar(); - return; - case ObjType::Short: - ptr_short = self.data_ptr(); - ASSERT(ptr_short); - *ptr_short = set.item().toShort(); - return; - case ObjType::Int: - ptr_int = self.data_ptr(); - ASSERT(ptr_int); - *ptr_int = set.item().toInt(); - return; - case ObjType::Long: - ptr_long = self.data_ptr(); - ASSERT(ptr_long); - *ptr_long = static_cast (set.item().toLong()); - return; - case ObjType::Float: - ptr_float = self.data_ptr(); - ASSERT(ptr_float); - *ptr_float = set.item().toFloat(); - return; - case ObjType::Double: - ptr_double = self.data_ptr(); - ASSERT(ptr_double); - *ptr_double = set.item().toDouble(); - return; - } - } else if (self.dim() != 0 && set.dim() == 0) { - // tensor := scalar - - if (self.dim() == 1) { - ObjType type = fromTorchType(self.scalar_type()); - if (ObjType::Bool == type) { - auto acc_bool = self.accessor (); - for (int i = 0; i < acc_bool.size(0); i++) { - acc_bool[i] = set.item().toBool(); - } - return; - } else if (ObjType::Char == type) { - auto acc_char = self.accessor (); - for (int i = 0; i < acc_char.size(0); i++) { - acc_char[i] = set.item().toChar(); - } - return; - } else if (ObjType::Short == type) { - auto acc_short = self.accessor(); - for (int i = 0; i < acc_short.size(0); i++) { - acc_short[i] = set.item().toShort(); - } - return; - } else if (ObjType::Int == type) { - auto acc_int = self.accessor(); - for (int i = 0; i < acc_int.size(0); i++) { - acc_int[i] = set.item().toInt(); - } - return; - } else if (ObjType::Long == type) { - auto acc_long = self.accessor(); - for (int i = 0; i < acc_long.size(0); i++) { - acc_long[i] = static_cast (set.item().toLong()); - } - return; - } else if (ObjType::Float == type) { - auto acc_float = self.accessor(); - for (int i = 0; i < acc_float.size(0); i++) { - acc_float[i] = set.item().toFloat(); - } - return; - } else if (ObjType::Double == type) { - auto acc_double = self.accessor(); - for (int i = 0; i < acc_double.size(0); i++) { - acc_double[i] = set.item().toDouble(); - } - return; - } - } else if (self.dim() == 2) { - ObjType type = fromTorchType(self.scalar_type()); - if (ObjType::Bool == type) { - auto acc_bool = self.accessor (); - for (int i = 0; i < acc_bool.size(0); i++) { - for (int j = 0; j < acc_bool.size(1); j++) { - acc_bool[i][j] = set.item().toBool(); - } - } - return; - } else if (ObjType::Char == type) { - auto acc_char = self.accessor (); - for (int i = 0; i < acc_char.size(0); i++) { - for (int j = 0; j < acc_char.size(1); j++) { - acc_char[i][j] = set.item().toChar(); - } - } - return; - } else if (ObjType::Short == type) { - auto acc_short = self.accessor(); - for (int i = 0; i < acc_short.size(0); i++) { - for (int j = 0; j < acc_short.size(1); j++) { - acc_short[i][j] = set.item().toShort(); - } - } - return; - } else if (ObjType::Int == type) { - auto acc_int = self.accessor(); - for (int i = 0; i < acc_int.size(0); i++) { - for (int j = 0; j < acc_int.size(1); j++) { - acc_int[i][j] = set.item().toInt(); - } - } - return; - } else if (ObjType::Long == type) { - auto acc_long = self.accessor(); - for (int i = 0; i < acc_long.size(0); i++) { - for (int j = 0; j < acc_long.size(1); j++) { - acc_long[i][j] = static_cast (set.item().toLong()); - } - } - return; - } else if (ObjType::Float == type) { - auto acc_float = self.accessor(); - for (int i = 0; i < acc_float.size(0); i++) { - for (int j = 0; j < acc_float.size(1); j++) { - acc_float[i][j] = set.item().toFloat(); - } - } - return; - } else if (ObjType::Double == type) { - auto acc_double = self.accessor(); - for (int i = 0; i < acc_double.size(0); i++) { - for (int j = 0; j < acc_double.size(1); j++) { - acc_double[i][j] = set.item().toDouble(); - } - } - return; - } - } - LOG_RUNTIME("Set data tensor for dims %d not implemented!", (int) self.dim()); - } - LOG_RUNTIME("Fail set data tensor type '%s'!", at::toString(self.scalar_type())); - } - inline int64_t parseInteger(const char *str) { char *ptr; std::string temp = str; @@ -942,26 +773,6 @@ void ParserException(const char *msg, std::string &buffer, int row, int col); } } - - /* - * Range -> Dict - * String -> Tensor - * Tensor -> String - * Dict -> Tensor - * Tensor -> Dict - */ - void ConvertRangeToDict(Obj *from, Obj &to); - - void ConvertStringToTensor(const std::string &from, torch::Tensor &to, ObjType type = ObjType::None); - void ConvertStringToTensor(const std::wstring &from, torch::Tensor &to, ObjType type = ObjType::None); - - void ConvertTensorToString(const torch::Tensor &from, std::string &to, std::vector *index = nullptr); - void ConvertTensorToString(const torch::Tensor &from, std::wstring &to, std::vector *index = nullptr); - - void ConvertDictToTensor(Obj &from, torch::Tensor &to, ObjType type = ObjType::Tensor); - void ConvertTensorToDict(const torch::Tensor &from, Obj &to, std::vector *index = nullptr); - void ConvertValueToTensor(Obj *from, torch::Tensor &to, ObjType type = ObjType::None); - } // namespace newlang #endif // INCLUDED_NEWLANG_TYPES_H_ From 8c14f61462333b374feba135b1129d5cff217b4e Mon Sep 17 00:00:00 2001 From: Aleksandr Ryabikov Date: Sat, 23 Jul 2022 20:38:47 +0300 Subject: [PATCH 28/31] =?UTF-8?q?=D0=9D=D0=BE=D0=B2=D1=8B=D0=B5=20=D1=82?= =?UTF-8?q?=D0=B5=D1=81=D1=82=D1=8B=20=D0=B4=D0=BB=D1=8F=20=D0=B4=D1=80?= =?UTF-8?q?=D0=BE=D0=B1=D0=B5=D0=B9=20=D0=B8=20=D1=81=D0=BA=D0=BE=D1=80?= =?UTF-8?q?=D0=BE=D1=81=D1=82=D0=B8=20(=D1=82=D0=BE=D1=87=D0=BD=D0=B5?= =?UTF-8?q?=D0=B5=20=D0=BC=D0=B5=D0=B4=D0=BB=D0=B5=D0=BD=D0=BD=D0=BE=D1=81?= =?UTF-8?q?=D1=82=D0=B8)=20=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D1=8B=20:-)=20?= =?UTF-8?q?=D0=9F=D0=BE=D1=84=D0=B8=D0=BA=D1=88=D0=B5=D0=BD=D1=8B=20=D0=B1?= =?UTF-8?q?=D0=B0=D0=B3=D0=B8=20=D1=81=20=D0=BE=D0=BF=D0=B5=D1=80=D0=B0?= =?UTF-8?q?=D1=82=D0=BE=D1=80=D0=B0=D1=85=20=D0=B8=20=D0=BF=D1=80=D0=BE?= =?UTF-8?q?=D1=86=D0=B5=D1=81=D1=81=D0=B5=20=D0=BF=D0=B5=D1=80=D0=B5=D0=B4?= =?UTF-8?q?=D0=B5=D0=BB=D0=BA=D0=B8=20=D0=B8=D1=82=D0=B5=D1=80=D0=B0=D1=82?= =?UTF-8?q?=D0=BE=D1=80=D0=BE=D0=B2=20=D0=B4=D0=B0=D0=BD=D0=BD=D1=8B=D1=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .vscode/launch.json | 5 +- .vscode/settings.json | 9 + .vscode/tasks.json | 2 +- CMakeLists.txt | 86 +- docs/index.md | 16 +- docs/syntax.md | 2 +- examples/fraction.nlp | 72 +- libffi/libffi.cpp | 239 +++++ libffi/libffi.sln | 31 + libffi/libffi.vcxproj | 143 +++ src/context.cpp | 56 +- src/context.h | 7 +- src/fraction.h | 98 ++- src/lexer.l | 12 +- src/nbproject/Makefile-Debug.mk | 12 +- src/nbproject/Makefile-Debug_LLVM.mk | 12 +- src/nbproject/Makefile-GCOV.mk | 12 +- src/nbproject/Makefile-LLVM.mk | 12 +- src/nbproject/Makefile-LLVM_GCC.mk | 12 +- src/nbproject/Makefile-Release.mk | 12 +- src/nbproject/Makefile-UnitTest-Win32.mk | 12 +- src/nbproject/Makefile-UnitTest-Win64.mk | 12 +- src/nbproject/Makefile-UnitTest.mk | 12 +- src/nbproject/Makefile-UnitTest_LLVM.mk | 12 +- src/nbproject/configurations.xml | 80 +- src/object.cpp | 815 ++++++++++++++++-- src/object.h | 236 ++++- src/parser.y | 165 ++-- src/term.h | 2 + src/test/eval_test.cpp | 116 ++- src/test/{speed_test.cpp => example_test.cpp} | 98 ++- src/test/object_test.cpp | 22 +- src/test/parser_test.cpp | 163 +++- src/types.h | 25 +- 34 files changed, 2127 insertions(+), 493 deletions(-) create mode 100644 libffi/libffi.cpp create mode 100644 libffi/libffi.sln create mode 100644 libffi/libffi.vcxproj rename src/test/{speed_test.cpp => example_test.cpp} (66%) diff --git a/.vscode/launch.json b/.vscode/launch.json index b015add7..f6e98dce 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -4,6 +4,7 @@ // Для получения дополнительной информации посетите: https://go.microsoft.com/fwlink/?linkid=830387 "version": "0.2.0", "configurations": [ + // { // "type": "gdb", // "request": "launch", @@ -43,7 +44,7 @@ "--gtest_shuffle", "--gtest_filter=Types.Convert:Eval.Tensor:Eval.Assign:ParserTest.Tensor1", ], - "cwd": "${workspaceFolder}/core", + "cwd": "${workspaceFolder}/src", "stopAtEntry": false, "environment": [ // {"name":"LD_LIBRARY_PATH","value": "$LD_LIBRARY_PATH;${workspaceFolder}/contrib/libtorch/lib"}, @@ -62,7 +63,7 @@ // "trace": true // }, // "sourceFileMap": { - // "${workspaceFolder}/core": "${workspaceFolder}/core", + // "${workspaceFolder}/src": "${workspaceFolder}/src", // "/build/gcc-4.8-fNUjSI/gcc-4.8-4.8.4/build/i686-linux-gnu/libstdc++-v3/include": "/usr/include/c++/4.8" // }, "setupCommands": [ diff --git a/.vscode/settings.json b/.vscode/settings.json index fcfd6f21..71ab6bf5 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,4 +1,13 @@ { + "terminal.integrated.shell.windows": "C:\\msys64\\usr\\bin\\bash.exe", + "terminal.integrated.shellArgs.windows": ["--login", "-i"], + "terminal.integrated.env.windows": + { + "MSYSTEM": "MINGW64", + "CHERE_INVOKING":"1", + "PATH" : "/mingw64/bin:/usr/local/bin:/usr/bin:/bin:/c/Windows/System32:/c/Windows:/c/Windows/System32/Wbem:/c/Windows/System32/WindowsPowerShell/v1.0/" + }, + /********* * CMake * *********/ diff --git a/.vscode/tasks.json b/.vscode/tasks.json index ec2fb9c1..7830c9e0 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -6,7 +6,7 @@ { "label": "Build Debug", "type": "shell", - "command": "cmake --build /home/rsashka/SOURCE/PUBLIC/NewLang/newlang/build --config Debug --target all --", + "command": "cmake --build ${workspaceFolder}/build --config Debug --target all --", "args": [], "problemMatcher": [], "group": { diff --git a/CMakeLists.txt b/CMakeLists.txt index 6aa3982e..e9146092 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -34,7 +34,7 @@ add_compile_options( # set(CMAKE_CXX_EXTENSIONS OFF) #endif() -# add_executable(GCC core/nlc.cpp) +# add_executable(GCC src/nlc.cpp) set(THREADS_PREFER_PTHREAD_FLAG ON) find_package(Threads REQUIRED) @@ -43,46 +43,46 @@ find_package(Threads REQUIRED) add_custom_command( OUTPUT # ${ATXT} - ${CMAKE_CURRENT_SOURCE_DIR}/core/parser.yy.h - ${CMAKE_CURRENT_SOURCE_DIR}/core/parser.yy.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/core/lexer.yy.h - ${CMAKE_CURRENT_SOURCE_DIR}/core/lexer.yy.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/core/location.hh + ${CMAKE_CURRENT_SOURCE_DIR}/src/parser.yy.h + ${CMAKE_CURRENT_SOURCE_DIR}/src/parser.yy.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/src/lexer.yy.h + ${CMAKE_CURRENT_SOURCE_DIR}/src/lexer.yy.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/src/location.hh COMMAND ./compile_syntax.sh - WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/core + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/src COMMENT "Compile syntax from files parser.y and lexer.l" DEPENDS - ${CMAKE_CURRENT_SOURCE_DIR}/core/compile_syntax.sh - ${CMAKE_CURRENT_SOURCE_DIR}/core/parser.y - ${CMAKE_CURRENT_SOURCE_DIR}/core/lexer.l + ${CMAKE_CURRENT_SOURCE_DIR}/src/compile_syntax.sh + ${CMAKE_CURRENT_SOURCE_DIR}/src/parser.y + ${CMAKE_CURRENT_SOURCE_DIR}/src/lexer.l VERBATIM) -file(GLOB CORE_SRC - ${CMAKE_CURRENT_SOURCE_DIR}/core/builtin.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/core/context.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/core/lexer.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/core/lexer.yy.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/core/newlang.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/core/object.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/core/parser.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/core/parser.yy.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/core/term.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/core/variable.cpp +file(GLOB src_SRC + ${CMAKE_CURRENT_SOURCE_DIR}/src/builtin.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/src/context.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/src/lexer.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/src/lexer.yy.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/src/newlang.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/src/object.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/src/parser.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/src/parser.yy.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/src/term.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/src/variable.cpp ${CMAKE_CURRENT_SOURCE_DIR}/contrib/logger/logger.cpp - # core/builtin.cpp - # core/context.cpp - # core/lexer.cpp - # core/lexer.yy.cpp - # core/newlang.cpp - # core/object.cpp - # core/parser.cpp - # core/parser.yy.cpp - # core/term.cpp - # core/variable.cpp + # src/builtin.cpp + # src/context.cpp + # src/lexer.cpp + # src/lexer.yy.cpp + # src/newlang.cpp + # src/object.cpp + # src/parser.cpp + # src/parser.yy.cpp + # src/term.cpp + # src/variable.cpp # contrib/logger/logger.cpp @@ -92,9 +92,9 @@ file(GLOB CORE_SRC file(GLOB TEST_SRC - ${CMAKE_CURRENT_SOURCE_DIR}/core/test/*.cpp) + ${CMAKE_CURRENT_SOURCE_DIR}/src/test/*.cpp) file(GLOB NLC_SRC - ${CMAKE_CURRENT_SOURCE_DIR}/core/nlc.cpp) + ${CMAKE_CURRENT_SOURCE_DIR}/src/nlc.cpp) link_directories(contrib/libtorch/lib) link_directories(contrib/libffi/output/lib) @@ -112,10 +112,10 @@ link_libraries( set(EXECUTABLE_OUTPUT_PATH ${CMAKE_SOURCE_DIR}) -add_executable(nlc ${CORE_SRC}) +add_executable(nlc ${src_SRC}) target_sources(nlc PRIVATE ${NLC_SRC}) -add_executable(newlang-unit-tests ${CORE_SRC}) +add_executable(newlang-unit-tests ${src_SRC}) target_sources(newlang-unit-tests PRIVATE ${TEST_SRC}) # и RUNTIME_OUTPUT_NAME @@ -128,9 +128,9 @@ ADD_DEFINITIONS(-DDEBUG) target_compile_options(newlang-unit-tests PRIVATE -DUNITTEST) -target_precompile_headers(newlang-unit-tests PRIVATE core/pch.h) -target_precompile_headers(nlc PRIVATE core/pch.h) -SET(PCH_DST core/pch.h) +target_precompile_headers(newlang-unit-tests PRIVATE src/pch.h) +target_precompile_headers(nlc PRIVATE src/pch.h) +SET(PCH_DST src/pch.h) @@ -156,6 +156,8 @@ endif() target_sources(newlang-unit-tests PRIVATE contrib/googletest/googletest/src/gtest_main.cc) target_sources(newlang-unit-tests PRIVATE contrib/googletest/googletest/src/gtest-all.cc) +target_include_directories(newlang-unit-tests PUBLIC contrib/libffi/win64/include) + target_include_directories(newlang-unit-tests PUBLIC contrib/googletest/googletest) target_include_directories(newlang-unit-tests PUBLIC contrib/googletest/googletest/include) @@ -165,7 +167,7 @@ include_directories( contrib/libtorch/include/torch/csrc/api/include contrib/libtorch/include contrib/tensorboard_logger/include - /usr/lib/llvm-13/include + # /usr/lib/llvm-13/include ) @@ -174,7 +176,7 @@ if(NOT MYLIB_TESTING) elseif(IS_SUBPROJECT) message(STATUS "Mylib не тестируется в режиме подмодуля") else() - target_sources(newlang-unit-tests PRIVATE core/test/) + target_sources(newlang-unit-tests PRIVATE src/test/) endif() enable_testing() @@ -187,5 +189,5 @@ enable_testing() # # Установить файлы "DataCache.txt" и "MessageLog.txt" в директорию "~/": # install(FILES DataCache.txt MessageLog.txt DESTINATION ~/) # Процесс описания установки папок аналогичен, за тем исключением, что вместо ключевого слова FILES следует указать DIRECTORY. Важно подметить, что при установке будет копироваться всё содержимое папки, а не только её название. Пример установки папок выглядит следующим образом: -# # Установить каталоги "MessageCollection" и "CoreFiles" в директорию "~/": -# install(DIRECTORY MessageCollection CoreFiles DESTINATION ~/) \ No newline at end of file +# # Установить каталоги "MessageCollection" и "srcFiles" в директорию "~/": +# install(DIRECTORY MessageCollection srcFiles DESTINATION ~/) \ No newline at end of file diff --git a/docs/index.md b/docs/index.md index 1ab9aed7..fcd6a488 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,3 +1,11 @@ +[ PASSED ] 212 tests. +[ FAILED ] 3 tests, listed below: +[ FAILED ] Eval.TypesNative +[ FAILED ] Eval.Fileio +[ FAILED ] ExecStr.Funcs + +MCJIT::runFunction does not support full-featured argument passing!!!! + # Проект *NewLang* *NewLang* - это язык программирования высокого уровня в котором можно сочетать стандартные алгоритмические конструкции с декларативным программированием и тензорными вычислениями для задач машинного обучения. @@ -52,7 +60,7 @@ #!./nlc --eval # Определение функции hello hello(str) := { - printf := @import('printf(format:Format, ...):Int'); # Импорт стандартной C функции + printf := @import('printf(format:FmtChar, ...):Int'); # Импорт стандартной C функции printf('%s\n', $str); # Вызов C функции с проверкой типов аргументов по строке формата }; hello('Привет, мир!'); # Вызвать функцию @@ -138,12 +146,12 @@ [libtorch-cxx11-abi-shared-with-deps-1.10.2+cpu.zip](https://download.pytorch.org/libtorch/cpu/libtorch-cxx11-abi-shared-with-deps-1.10.2%2Bcpu.zip)) - Активировать и скачать исходники субмодулей (`git submodule init && git submodule update`) - В каталоге *contrib* запустить файл `build.sh` для сборки библиотеки libffi -- В каталоге *core* запустить файл `compile_syntax.sh` для генерации файлов парсера и лексического анализатора. Также может потребоваться установка утилит *flex* и *bison*. Если что, у меня установлены flex 2.6.4 и bison (GNU Bison) 3.7.4 +- В каталоге *src* запустить файл `compile_syntax.sh` для генерации файлов парсера и лексического анализатора. Также может потребоваться установка утилит *flex* и *bison*. Если что, у меня установлены flex 2.6.4 и bison (GNU Bison) 3.7.4 ### Собрать -- Юнит-тесты (newlang_test): в каталоге *core* выполнить команду **`make CONF=UnitTest`** * -- Интерпретатор (nlc): в каталоге *core* выполнить команду **`make CONF=Debug`** * +- Юнит-тесты (newlang_test): в каталоге *src* выполнить команду **`make CONF=UnitTest`** * +- Интерпретатор (nlc): в каталоге *src* выполнить команду **`make CONF=Debug`** * --- *) - Сборка проекта выполняется обычной утилитой make, но сборочные файлы генерируются автоматически в давно устаревшей версии NetBeans 8.2, т.к. это единственная универсальная среда разработки с поддержкой Makefile "из коробки", тогда как в текущей версии Apache NetBeans полноценная поддержка разработки на С/С++ вообще отсутствует. Начал постепеный переход на использование редактора VSCodium (аналога VSCode, в котором вычищена телеметрия от Microsoft) и генерацию скиптов сборки с помощью сmake, но этот процесс пока не завершен. diff --git a/docs/syntax.md b/docs/syntax.md index 5eb2671e..88a30945 100644 --- a/docs/syntax.md +++ b/docs/syntax.md @@ -23,7 +23,7 @@ ``` var ::= 1.0; # Создать новую переменную var без указания типа var = 100; # Присвоить новое значение уже существующей переменной -printf := @import('printf(format:Format, ...):Int'); /* Создать новый или переопределить объект printf, который будет результатом выполнения глобальной функции @import */ +printf := @import('printf(format:FmtChar, ...):Int'); /* Создать новый или переопределить объект printf, который будет результатом выполнения глобальной функции @import */ ``` # Идентификаторы объектов и модификаторы diff --git a/examples/fraction.nlp b/examples/fraction.nlp index 7380ef8e..831c0873 100755 --- a/examples/fraction.nlp +++ b/examples/fraction.nlp @@ -1,10 +1,74 @@ #!../output/nlc --eval -@var1 := 12345678901234567865465491/1; -@var2 := 100_000_000_000_000_001\1; -@var2 *= @var1; +@printf := :Pointer('printf(format:FmtChar, ...):Int'); +/* +#@var1 := 12345678901234567865465491/1; +#@var2 := 100_000_000_000_000_001\1; +#@var2 *= @var1; +@fact_int(n:Int) := { + [n > 1] --> { + n *= fact_int(n-1); + }, [n==1] --> { + 1; + }, [_] --> { + -- "ERROR!!!" --; + }; + }; ---@var2--; +printf('Recursive factorial with integer overflow:\n'); +@item := (3, 2, 5, 10, 11, 12, 13,)?; +@fact := 0; +[ item ] <<-->> { + fact := fact_int(item?!); + printf('%d! -> %d\n', item?!, fact); #479001600 + item!; +}; +*/ + +@fact_range(n:Fraction) := { +printf('fact_range call %s\n', :StrChar(n)); + [n > 2] --> { + iter := (n-1)..2..-1?; # Итератор для множителей + [iter] <<-->> { + n *= iter!; + }; + }; + n +/* + [n > 1] --> { + n *= fact_frac(n-1); + }, [n==1] --> { + 1; + }, [_] --> { + -- "ERROR!!!" --; + }; */ + }; + +printf('Recursive factorial with fraction no overflow:\n'); +@big := (1, 2, 5, 10, 11, 12, 13, 20, 30, 100, 1000,)?; +@frac := 0\1; #fraction value bigint + +printf('>>>>>>>>>> %s! -> %s <<<<<<<<<<\n', :StrChar(big?!), :StrChar(frac)); + +[ big ] <<-->> { + printf('%s! -> ', :StrChar(big?!)); + frac := fact_range(big?!); + printf('%s\n', :StrChar(frac)); + big!; +}; + +/* +@fact_range(n:Integer) := { + result := 1\1; # Дробь для точного расчета больших чисел + iter := 2..(n+1)?; + [iter] <<-->>{ + result *= iter!; + } + result; +}; + +1000! = 402387260077093773543702433923003985719374864210714632543799910429938512398629020592044208486969404800479988610197196058631666872994808558901323829669944590997424504087073759918823627727188732519779505950995276120874975462497043601418278094646496291056393887437886487337119181045825783647849977012476632889835955735432513185323958463075557409114262417474349347553428646576611667797396668820291207379143853719588249808126867838374559731746136085379534524221586593201928090878297308431392844403281231558611036976801357304216168747609675871348312025478589320767169132448426236131412508780208000261683151027341827977704784635868170164365024153691398281264810213092761244896359928705114964975419909342221566832572080821333186116811553615836546984046708975602900950537616475847728421889679646244945160765353408198901385442487984959953319101723355556602139450399736280750137837615307127761926849034352625200015888535147331611702103968175921510907788019393178114194545257223865541461062892187960223838971476088506276862967146674697562911234082439208160153780889893964518263243671616762179168909779911903754031274622289988005195444414282012187361745992642956581746628302955570299024324153181617210465832036786906117260158783520751516284225540265170483304226143974286933061690897968482590125458327168226458066526769958652682272807075781391858178889652208164348344825993266043367660176999612831860788386150279465955131156552036093988180612138558600301435694527224206344631797460594682573103790084024432438465657245014402821885252470935190620929023136493273497565513958720559654228749774011413346962715422845862377387538230483865688976461927383814900140767310446640259899490222221765904339901886018566526485061799702356193897017860040811889729918311021171229845901641921068884387121855646124960798722908519296819372388642614839657382291123125024186649353143970137428531926649875337218940694281434118520158014123344828015051399694290153483077644569099073152433278288269864602789864321139083506217095002597389863554277196742822248757586765752344220207573630569498825087968928162753848863396909959826280956121450994871701244516461260379029309120889086942028510640182154399457156805941872748998094254742173582401063677404595741785160829230135358081840096996372524230560855903700624271243416909004153690105933983835777939410970027753472000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +*/ "OK"; \ No newline at end of file diff --git a/libffi/libffi.cpp b/libffi/libffi.cpp new file mode 100644 index 00000000..d8d346da --- /dev/null +++ b/libffi/libffi.cpp @@ -0,0 +1,239 @@ +// Запуск программы: CTRL+F5 или меню "Отладка" > "Запуск без отладки" +// Отладка программы: F5 или меню "Отладка" > "Запустить отладку" + +// Советы по началу работы +// 1. В окне обозревателя решений можно добавлять файлы и управлять ими. +// 2. В окне Team Explorer можно подключиться к системе управления версиями. +// 3. В окне "Выходные данные" можно просматривать выходные данные сборки и другие сообщения. +// 4. В окне "Список ошибок" можно просматривать ошибки. +// 5. Последовательно выберите пункты меню "Проект" > "Добавить новый элемент", чтобы создать файлы кода, или "Проект" > "Добавить существующий элемент", чтобы добавить в проект существующие файлы кода. +// 6. Чтобы снова открыть этот проект позже, выберите пункты меню "Файл" > "Открыть" > "Проект" и выберите SLN-файл. + +#include +#include +#include +#include +#include + + +#include "ffi.h" +#include + +unsigned char foo( + unsigned int, float); + +//#pragma comment(lib, "msys-2.0.dll") +//#pragma comment(lib, "libffi.dll.a") + +inline std::string utf8_encode(const std::wstring wstr) { + std::string utf8line; + + if (wstr.empty()) { + return utf8line; + } + utf8line = std::wstring_convert>().to_bytes(wstr.c_str()); + return utf8line; +} + + +std::string GetLastErrorMessage() { + wchar_t buffer[256]; + FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), buffer, sizeof(buffer), NULL); + return utf8_encode(buffer); +} +//std::string GetLastErrorMessage() { +// char buffer[256]; +// FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), buffer, sizeof(buffer), +// NULL); +// return buffer; +//} + +int main(int argc, const char **argv) { + // ffi_cif cif; + // ffi_type *arg_types[2]; + // void *arg_values[2]; + // ffi_status status; + + //// Because the return value from foo() is smaller than sizeof(long), it + //// must be passed as ffi_arg or ffi_sarg. + // ffi_arg result; + + //// Specify the data type of each argument. Available types are defined + //// in . + // arg_types[0] = &ffi_type_uint; + // arg_types[1] = &ffi_type_float; + + //// Prepare the ffi_cif structure. + // if ((status = ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &ffi_type_uint8, arg_types)) != FFI_OK) { + // // Handle the ffi_status error. + // } + + //// Specify the values of each argument. + // unsigned int arg1 = 42; + // float arg2 = 5.1f; + + // arg_values[0] = &arg1; + // arg_values[1] = &arg2; + + //// Invoke the function. + // ffi_call(&cif, FFI_FN(foo), &result, arg_values); + + //The ffi_arg 'result' now contains the unsigned char returned from foo(), + //which can be accessed by a typecast. + //printf("result is %hhu\n", (unsigned char)result); + + // std::vector dll = {L"msvcp140d.dll", + // L"vcruntime140d.dll", + // L"kernel32.dll", + // L"KernelBase.dll", + // L"vcruntime140_1d.dll", L"ucrtbased.dll", L"ntdll.dll"}; + + // HMODULE mod = 0; + // mod = GetModuleHandle(nullptr); + // if (!mod) { + // printf("Fail NULL module n"); + // } else { + // if (GetProcAddress(mod, "printf")) { + // printf("printf NULL \n"); + // return 0; + // } + // if (GetProcAddress(mod, "_printf")) { + // printf("___printf NULL \n"); + // return 0; + // } + // } + + // for (auto name: dll) { + // mod = GetModuleHandle(name.c_str()); + // if (!mod) { + // printf("Fail module %s \n", utf8_encode(name).c_str()); + // } else { + // if (GetProcAddress(mod, "printf")) { + // printf("printf %s \n", utf8_encode(name).c_str()); + // return 0; + // } + // if (GetProcAddress(mod, "_printf")) { + // printf("___printf %s \n", utf8_encode(name).c_str()); + // return 0; + // } + // } + // } + + #pragma comment(lib, "libffi-7.dll") + + //#pragma comment(lib, "legacy_stdio_definitions.lib") + //#pragma comment(lib, "legacy_stdio_wide_specifiers.lib") + + //#pragma comment(lib, "cygwin1.dll") + //#pragma comment(lib, "cygffi-6.dll") + HMODULE mod = LoadLibrary(L"msys-2.0.dll"); +// HMODULE mod = LoadLibrary(L"cygwin1.dll"); + + // HMODULE mod = GetModuleHandle(nullptr); + if (!mod) { + printf("Fail load msys-2.0.dll %s\n", GetLastErrorMessage().c_str()); + return 1; + } + + typedef void init_type(); + +// init_type *init = (init_type *)GetProcAddress(mod, "cygwin_dll_init"); + init_type *init = (init_type *)GetProcAddress(mod, "msys_dll_init"); + if (!init) { + printf("msys_dll_init not found!: %s\n", GetLastErrorMessage().c_str()); + return 1; + } + + (*init)(); + + void *ptr2 = nullptr; + ptr2 = GetProcAddress(mod, "printf"); + if (!ptr2) { + printf("printf not found!: %s\n", GetLastErrorMessage().c_str()); + return 1; + } + + //void *ptr_local = GetProcAddress(nullptr, "printf"); + //if (!ptr_local) { + // printf("Local printf not found!: %s\n", GetLastErrorMessage().c_str()); + // return 1; + //} + + void *ptr = &printf; + + printf("%s %p %p\n", ptr == ptr2 ? "Eq: " : " NOT EQ !!!!!!: ", ptr, ptr2); + + typedef int printf_type(const char *, ...); + + printf_type *ttt = (printf_type *)ptr; + (ttt)("Test 1\n"); + (ttt)("%s", "Test Variadic call\n"); + (ttt)("%s", "Начинаю тесты printf из msys-2.0.dll\n\n"); + + printf_type *ttt2 = (printf_type *)ptr2; + (ttt2)("Test 2 from dll\n"); + (ttt2)("%s", "Test 2 Variadic call form dll\n"); + (ttt2)("%s", "Тест_русских_символов\n"); + + + /* + * libtorch под Windows собирается для использования только с нативным компилятором и не может быть использовавана с MinGW для корсскомпиляции. + * VSCode (VSCodium) под Windows использует MinGW, поэтому остается использовать только Visual Studio + * В Visual Studio функции stdio реализованы встроенными и у меня не получилось динамически получить адрес printf во время выполнения (включая _NO_CRT_STDIO_INLINE и legacy_stdio_definitions.lib). + * Можно получить адрес printf в рантайме из msys-2.0.dll, но при попытки использования фунции внтури dlld возникает необрабатываемое исключение. + * Остановился на получении адресо в функий в рантайме с GetProcAddress из cygwin1.dll, хотя её нужно инициализировать перед использованием, т.е. вызывать void cygwin_dll_init(). + * Без инициализации возникает такое же исключение как и при msys-2.0.dll (функцию инициализации msys-2.0.dll ненашел). + * Функции из cygwin1.dll хоть и не виснут, но работают как-то странно и выводят только слова целиком. + * Возможно это связно с кодировкой исходников или другими настройками, но решил пока не заморачиваться. + * + * + */ + + + //ffi_cif m_cif; + //std::vector m_args_type; + //std::vector m_args_ptr; + + //union VALUE { + // const void *ptr; + // // ObjPtr obj; + // size_t size; + // int64_t integer; + // double number; + // bool boolean; + //}; + //std::vector m_args_val; + //VALUE temp; + + //m_args_type.push_back(&ffi_type_pointer); + //temp.ptr = "%s"; + //m_args_val.push_back(temp); + + //m_args_type.push_back(&ffi_type_pointer); + //temp.ptr = "test string LIBFFI\n"; + //m_args_val.push_back(temp); + + + //for (size_t i = 0; i < m_args_val.size(); i++) { + // m_args_ptr.push_back((void *)&m_args_val[i]); + //} + + //VALUE res_value; + //ffi_type *result_ffi_type = &ffi_type_sint32; + // + //ffi_abi m_func_abi = FFI_DEFAULT_ABI; + //if (ffi_prep_cif_var(&m_cif, m_func_abi, 1, static_cast(m_args_type.size()), result_ffi_type, m_args_type.data()) == FFI_OK) { + + // ffi_call(&m_cif, FFI_FN(ptr), &res_value, m_args_ptr.data()); + // printf("Returned %Id", res_value.integer); + + // return 0; + //} + return 1; +} + +// The target function. +unsigned char foo(unsigned int x, float y) { + unsigned char result = (unsigned char)(x - y); + return result; +} \ No newline at end of file diff --git a/libffi/libffi.sln b/libffi/libffi.sln new file mode 100644 index 00000000..8f256c2d --- /dev/null +++ b/libffi/libffi.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.2.32616.157 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libffi", "libffi.vcxproj", "{E5245938-CEF5-4BBC-9589-85528B597CE8}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {E5245938-CEF5-4BBC-9589-85528B597CE8}.Debug|x64.ActiveCfg = Debug|x64 + {E5245938-CEF5-4BBC-9589-85528B597CE8}.Debug|x64.Build.0 = Debug|x64 + {E5245938-CEF5-4BBC-9589-85528B597CE8}.Debug|x86.ActiveCfg = Debug|Win32 + {E5245938-CEF5-4BBC-9589-85528B597CE8}.Debug|x86.Build.0 = Debug|Win32 + {E5245938-CEF5-4BBC-9589-85528B597CE8}.Release|x64.ActiveCfg = Release|x64 + {E5245938-CEF5-4BBC-9589-85528B597CE8}.Release|x64.Build.0 = Release|x64 + {E5245938-CEF5-4BBC-9589-85528B597CE8}.Release|x86.ActiveCfg = Release|Win32 + {E5245938-CEF5-4BBC-9589-85528B597CE8}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {DECE1DB9-B726-46F9-9202-5CE5545F0316} + EndGlobalSection +EndGlobal diff --git a/libffi/libffi.vcxproj b/libffi/libffi.vcxproj new file mode 100644 index 00000000..2c3b810d --- /dev/null +++ b/libffi/libffi.vcxproj @@ -0,0 +1,143 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 16.0 + Win32Proj + {e5245938-cef5-4bbc-9589-85528b597ce8} + libffi + 10.0 + + + + Application + true + v143 + Unicode + + + Application + false + v143 + true + Unicode + + + Application + true + v143 + Unicode + + + Application + false + v143 + true + Unicode + + + + + + + + + + + + + + + + + + + + + Z:\NewLang\newlang\contrib\libffi\win64\lib;$(LibraryPath) + Z:\NewLang\newlang\contrib\libffi\win64\bin;$(ReferencePath) + Z:\NewLang\newlang\contrib\libffi\win64\include;C:\msys64\usr\include;$(IncludePath) + + + + Level3 + true + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + true + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + Level3 + true + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + $(srcLibraryDependencies);%(AdditionalDependencies) + + + + + Level3 + true + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + + + + + \ No newline at end of file diff --git a/src/context.cpp b/src/context.cpp index 06ac6ed0..88f976a9 100644 --- a/src/context.cpp +++ b/src/context.cpp @@ -770,8 +770,8 @@ ObjPtr Context::eval_WHILE(Context *ctx, const TermPtr &term, Obj * args) { try { - // LOG_DEBUG("result %s", result->toString().c_str()); - + LOG_DEBUG("result %s", result->toString().c_str()); + result = CreateRVal(ctx, term->Right(), args, false); cond = Eval(ctx, term->Left(), args, false); @@ -2281,7 +2281,7 @@ ObjPtr Context::CreateRVal(Context *ctx, TermPtr term, Obj * local_vars, bool in for (int i = 0; i < term->size(); i++) { ASSERT(!term->name(i).empty()); - result->push_back(CreateRVal(ctx, (*term)[i].second, local_vars), term->name(i).c_str()); + result->push_back(Eval(ctx, (*term)[i].second, local_vars), term->name(i).c_str()); } if(result->size() == 2) { @@ -2301,34 +2301,62 @@ ObjPtr Context::CreateRVal(Context *ctx, TermPtr term, Obj * local_vars, bool in ASSERT(term->Left()); - temp = ctx->GetTerm(term->Left()->GetFullName().c_str(), true); + temp = Eval(ctx, term->Left(), local_vars, false); if(!temp) { - LOG_RUNTIME("Term '%s' not found!", term->GetFullName().c_str()); + LOG_RUNTIME("Term '%s' not found!", term->Left()->GetFullName().c_str()); } args = Obj::CreateDict(); ctx->CreateArgs_(args, term, local_vars); + + /* + * Создание итератора + * ?, ?(), ?("Фильтр"), ?(func), ?(func, args...) + * + * Перебор элементов итератора + * !, !(), !(0), !(3), !(-3) + * + * dict! и dict!(0) эквивалентны + * dict! -> 1, dict! -> 2, dict! -> 3, dict! -> 4, dict! -> 5, dict! -> :IteratorEnd + * + * Различия отрицательного размера возвращаемого словаря для итератора + * dict!(-1) -> (1,), ... dict!(-1) -> (5,), dict!(-1) -> (:IteratorEnd,), + * dict!(1) -> (1,), ... dict!(1) -> (5,), dict!(1) -> (,), + * dict!(-3) -> (1, 2, 3,), dict!(-3) -> (4, 5, :IteratorEnd,) + * dict!(3) -> (1, 2, 3,), dict!(3) -> (4, 5,) + * + * Операторы ?! и !? эквивалентны и возвращают текущие данные без перемещения указателя итератора. + * + * Оператор ?? создает итератор и сразу его выполняет, возвращая все значения + * в виде элементов словаря, т.е. аналог последовательности ?(LINQ); !(:Long.__max__); + * + * Оператор !! - сбрасывает итератор в начальное состояние и возвращает первый элемент + */ + if(term->m_text.compare("?") == 0) { - return temp->MakeIterator(args.get()); - } else if(term->m_text.compare("??") == 0) { - return temp->IteratorReset(); + return temp->IteratorMake(args.get()); } else if(term->m_text.compare("!") == 0) { + ASSERT(!args->size() && "Argument processing not implemented"); return temp->IteratorNext(0); } else if(term->m_text.compare("!!") == 0) { - return temp->IteratorNext(1); + ASSERT(!args->size() && "Argument processing not implemented"); + temp->IteratorReset(); + return temp->IteratorData(); } else if(term->m_text.compare("!?") == 0 || term->m_text.compare("?!") == 0) { + return temp->IteratorData(); + } else if(term->m_text.compare("??") == 0) { val_int = std::numeric_limits::max(); if(args->empty() || (args->size() == 1 && args->at(0).second->is_integer())) { - result = temp->MakeIterator(Iterator::FIND_KEY_DEFAULT, false); + result = temp->IteratorMake(Iterator::FIND_KEY_DEFAULT, false); if(args->size()) { val_int = args->at(0).second->GetValueAsInteger(); } } else if(args->size() == 1 && args->at(0).second->is_string_type()) { - result = temp->MakeIterator(args->at(0).second->GetValueAsString(), false); + result = temp->IteratorMake(args->at(0).second->GetValueAsString(), false); } else if(args->size() == 2 && args->at(0).second->is_string_type() && args->at(1).second->is_integer()) { - result = temp->MakeIterator(args->at(0).second->GetValueAsString(), false); + result = temp->IteratorMake(args->at(0).second->GetValueAsString(), false); val_int = args->at(1).second->GetValueAsInteger(); } else { LOG_RUNTIME("Iterator`s args '%s' not allowed!", args->toString().c_str()); @@ -2349,9 +2377,9 @@ ObjPtr Context::CreateRVal(Context *ctx, TermPtr term, Obj * local_vars, bool in void Context::CreateArgs_(ObjPtr &args, TermPtr &term, Obj * local_vars) { for (int i = 0; i < term->size(); i++) { if(term->name(i).empty()) { - args->push_back(CreateRVal(this, (*term)[i].second, local_vars)); + args->push_back(Eval(this, (*term)[i].second, local_vars)); } else { - args->push_back(CreateRVal(this, (*term)[i].second, local_vars), term->name(i).c_str()); + args->push_back(Eval(this, (*term)[i].second, local_vars), term->name(i).c_str()); } } } \ No newline at end of file diff --git a/src/context.h b/src/context.h index 43a2a39c..f7becbe3 100644 --- a/src/context.h +++ b/src/context.h @@ -495,8 +495,13 @@ namespace newlang { ObjPtr GetTypeFromString(const std::string & type, bool *has_error = nullptr) { if (type.empty()) { - return Obj::CreateNone(); + if (has_error) { + *has_error = true; + return Obj::CreateNone(); + } + LOG_RUNTIME("Type name '%s' not found!", type.c_str()); } + auto result = m_types.find(type); if (result == m_types.end()) { if (has_error) { diff --git a/src/fraction.h b/src/fraction.h index 06beb5e7..4c46aa63 100644 --- a/src/fraction.h +++ b/src/fraction.h @@ -14,8 +14,8 @@ namespace newlang { ASSERT(value); } - BigNum(const unsigned long var) : BigNum() { - BN_set_word(value, var); + BigNum(const int64_t var) { + set_(var); } BigNum(const std::string str) : BigNum() { @@ -26,11 +26,29 @@ namespace newlang { VERIFY(BN_copy(value, copy.value)); } - BigNum& operator=(const BigNum & copy) { + inline BigNum& set_(const BigNum & copy) { VERIFY(BN_copy(value, copy.value)); return *this; } + inline BigNum& set_(const int64_t var) { + if (var < 0) { + BN_set_word(value, -var); + BN_set_negative(value, -1); + } else { + BN_set_word(value, var); + } + return *this; + } + + BigNum& operator=(const BigNum & var) { + return set_(var); + } + + BigNum& operator=(const int64_t var) { + return set_(var); + } + virtual ~BigNum() { if (value) { BN_free(value); @@ -186,21 +204,21 @@ namespace newlang { Fraction() : Fraction("0", "1") { } - Fraction(const int64_t value) : Fraction() { - if (value < 0) { - BN_set_word(m_numerator.value, -value); - BN_set_negative(m_numerator.value, -1); - } else { - BN_set_word(m_numerator.value, value); - } + Fraction(const int64_t value) { + set_(value); } - Fraction(const Fraction ©) : m_numerator(copy.m_numerator), m_denominator(copy.m_denominator) { + Fraction(const Fraction ©) { + set_(copy); } Fraction(const std::string numerator, const std::string denominator) { - m_numerator.SetFromString(numerator); - m_denominator.SetFromString(denominator); + set_(numerator, denominator); + } + + inline std::shared_ptr clone() const { + std::shared_ptr result = std::make_shared(*this); + return result; } std::string GetAsString() const { @@ -254,6 +272,29 @@ namespace newlang { ASSERT(rem.isZero()); } + Fraction &set_(const int64_t value) { + if (value < 0) { + BN_set_word(m_numerator.value, -value); + BN_set_negative(m_numerator.value, -1); + } else { + BN_set_word(m_numerator.value, value); + } + BN_set_word(m_denominator.value, 1); + return *this; + } + + Fraction &set_(const Fraction ©) { + m_numerator.set_(copy.m_numerator); + m_denominator.set_(copy.m_denominator); + return *this; + } + + Fraction &set_(const std::string numerator, const std::string denominator) { + m_numerator.SetFromString(numerator); + m_denominator.SetFromString(denominator); + return *this; + } + Fraction& operator*=(const Fraction &fraction) { m_numerator.mul(fraction.m_numerator); m_denominator.mul(fraction.m_denominator); @@ -265,6 +306,7 @@ namespace newlang { m_numerator.mul(fraction.m_denominator); m_denominator.mul(fraction.m_numerator); reduce(); + return *this; } @@ -279,6 +321,7 @@ namespace newlang { m_numerator.sub(sub_num); reduce(); + return *this; } @@ -292,52 +335,73 @@ namespace newlang { m_numerator.add(add_num); reduce(); + return *this; } Fraction& operator%=(const Fraction &fraction) { LOG_RUNTIME("Not implemented!"); + return *this; } Fraction &operator^=(const Fraction &) { LOG_RUNTIME("Operator '^=' not implementd!"); + return *this; } Fraction & operator|=(const Fraction &) { LOG_RUNTIME("Operator '|=' not implementd!"); + return *this; } Fraction &op_lshift_set(const Fraction &) { LOG_RUNTIME("Operator '<<=' not implementd!"); + return *this; } Fraction & op_rshift_set(const Fraction &) { LOG_RUNTIME("Operator '>>=' not implementd!"); + return *this; } const Fraction & op_rrshift_set(const Fraction &) { LOG_RUNTIME("Operator '>>>=' not implementd!"); + return *this; } Fraction& op_pow_(const Fraction &fraction) { LOG_RUNTIME("Not implemented!"); + return *this; } bool op_equal(const Fraction &fraction) const { - LOG_RUNTIME("Not implemented!"); - return false; + return BN_cmp(m_numerator.value, fraction.m_numerator.value) == 0 && + BN_cmp(m_denominator.value, fraction.m_denominator.value) == 0; } int op_compare(const Fraction &fraction) const { - LOG_RUNTIME("Not implemented!"); - return false; + if (BN_cmp(m_denominator.value, fraction.m_denominator.value) == 0) { + return BN_cmp(m_numerator.value, fraction.m_numerator.value); + } + + Fraction first(*this); + Fraction second(fraction); + + Fraction mul; + mul.m_numerator.set_(m_denominator); + second *= mul; + mul.m_numerator.set_(fraction.m_denominator); + first *= mul; + + ASSERT(BN_cmp(first.m_denominator.value, second.m_denominator.value) == 0); + return BN_cmp(first.m_numerator.value, second.m_numerator.value); } Fraction &op_div_ceil_(Fraction &fraction) { diff --git a/src/lexer.l b/src/lexer.l index d4bcf9df..e1044064 100644 --- a/src/lexer.l +++ b/src/lexer.l @@ -422,6 +422,10 @@ term [$@%]({ualpha}|[_])?({name})? "--" YY_TOKEN(EXIT); +"||" YY_TOKEN(OPERATOR); +"&&" YY_TOKEN(OPERATOR); +"^^" YY_TOKEN(OPERATOR); + ".>." YY_TOKEN(OPERATOR); ".<." YY_TOKEN(OPERATOR); ".>>." YY_TOKEN(OPERATOR); @@ -447,10 +451,10 @@ term [$@%]({ualpha}|[_])?({name})? ">" YY_TOKEN(OPERATOR); -"!!" YY_TOKEN_ONLY(ITERATOR_QQ); -"??" YY_TOKEN_ONLY(ITERATOR_QQ); -"?!" YY_TOKEN(ITERATOR); -"!?" YY_TOKEN(ITERATOR); +"!!" YY_TOKEN(ITERATOR); +"??" YY_TOKEN(ITERATOR); +"?!" YY_TOKEN_ONLY(ITERATOR_QQ); +"!?" YY_TOKEN_ONLY(ITERATOR_QQ); /* gobble up white-spaces */ diff --git a/src/nbproject/Makefile-Debug.mk b/src/nbproject/Makefile-Debug.mk index 14d5bab8..b9e6708a 100644 --- a/src/nbproject/Makefile-Debug.mk +++ b/src/nbproject/Makefile-Debug.mk @@ -50,12 +50,12 @@ OBJECTFILES= \ ${OBJECTDIR}/test/alg_test.o \ ${OBJECTDIR}/test/compiler_test.o \ ${OBJECTDIR}/test/eval_test.o \ + ${OBJECTDIR}/test/example_test.o \ ${OBJECTDIR}/test/fraction_test.o \ ${OBJECTDIR}/test/lexer_test.o \ ${OBJECTDIR}/test/nlc_test.o \ ${OBJECTDIR}/test/object_test.o \ ${OBJECTDIR}/test/parser_test.o \ - ${OBJECTDIR}/test/speed_test.o \ ${OBJECTDIR}/variable.o \ ${OBJECTDIR}/version.o @@ -214,6 +214,11 @@ ${OBJECTDIR}/test/eval_test.o: test/eval_test.cpp pch.h.gch ${RM} "$@.d" $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I. -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/eval_test.o test/eval_test.cpp +${OBJECTDIR}/test/example_test.o: test/example_test.cpp pch.h.gch + ${MKDIR} -p ${OBJECTDIR}/test + ${RM} "$@.d" + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I. -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/example_test.o test/example_test.cpp + ${OBJECTDIR}/test/fraction_test.o: test/fraction_test.cpp ${MKDIR} -p ${OBJECTDIR}/test ${RM} "$@.d" @@ -239,11 +244,6 @@ ${OBJECTDIR}/test/parser_test.o: test/parser_test.cpp pch.h.gch ${RM} "$@.d" $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I. -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/parser_test.o test/parser_test.cpp -${OBJECTDIR}/test/speed_test.o: test/speed_test.cpp pch.h.gch - ${MKDIR} -p ${OBJECTDIR}/test - ${RM} "$@.d" - $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I. -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/speed_test.o test/speed_test.cpp - : types.h pch.h.gch @echo Выполнение шага пользовательского сборки diff --git a/src/nbproject/Makefile-Debug_LLVM.mk b/src/nbproject/Makefile-Debug_LLVM.mk index af14c3bf..6fc44275 100644 --- a/src/nbproject/Makefile-Debug_LLVM.mk +++ b/src/nbproject/Makefile-Debug_LLVM.mk @@ -50,12 +50,12 @@ OBJECTFILES= \ ${OBJECTDIR}/test/alg_test.o \ ${OBJECTDIR}/test/compiler_test.o \ ${OBJECTDIR}/test/eval_test.o \ + ${OBJECTDIR}/test/example_test.o \ ${OBJECTDIR}/test/fraction_test.o \ ${OBJECTDIR}/test/lexer_test.o \ ${OBJECTDIR}/test/nlc_test.o \ ${OBJECTDIR}/test/object_test.o \ ${OBJECTDIR}/test/parser_test.o \ - ${OBJECTDIR}/test/speed_test.o \ ${OBJECTDIR}/variable.o \ ${OBJECTDIR}/version.o @@ -185,6 +185,11 @@ ${OBJECTDIR}/test/eval_test.o: test/eval_test.cpp ${RM} "$@.d" $(COMPILE.cc) -g -O2 -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I. -I.. -I/usr/lib/llvm-13/lib/clang/13.0.1/include -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/eval_test.o test/eval_test.cpp +${OBJECTDIR}/test/example_test.o: test/example_test.cpp + ${MKDIR} -p ${OBJECTDIR}/test + ${RM} "$@.d" + $(COMPILE.cc) -g -O2 -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I. -I.. -I/usr/lib/llvm-13/lib/clang/13.0.1/include -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/example_test.o test/example_test.cpp + ${OBJECTDIR}/test/fraction_test.o: test/fraction_test.cpp ${MKDIR} -p ${OBJECTDIR}/test ${RM} "$@.d" @@ -210,11 +215,6 @@ ${OBJECTDIR}/test/parser_test.o: test/parser_test.cpp ${RM} "$@.d" $(COMPILE.cc) -g -O2 -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I. -I.. -I/usr/lib/llvm-13/lib/clang/13.0.1/include -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/parser_test.o test/parser_test.cpp -${OBJECTDIR}/test/speed_test.o: test/speed_test.cpp - ${MKDIR} -p ${OBJECTDIR}/test - ${RM} "$@.d" - $(COMPILE.cc) -g -O2 -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I. -I.. -I/usr/lib/llvm-13/lib/clang/13.0.1/include -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/speed_test.o test/speed_test.cpp - ${OBJECTDIR}/variable.o: variable.cpp ${MKDIR} -p ${OBJECTDIR} ${RM} "$@.d" diff --git a/src/nbproject/Makefile-GCOV.mk b/src/nbproject/Makefile-GCOV.mk index db994638..0d6b593c 100644 --- a/src/nbproject/Makefile-GCOV.mk +++ b/src/nbproject/Makefile-GCOV.mk @@ -51,12 +51,12 @@ OBJECTFILES= \ ${OBJECTDIR}/test/alg_test.o \ ${OBJECTDIR}/test/compiler_test.o \ ${OBJECTDIR}/test/eval_test.o \ + ${OBJECTDIR}/test/example_test.o \ ${OBJECTDIR}/test/fraction_test.o \ ${OBJECTDIR}/test/lexer_test.o \ ${OBJECTDIR}/test/nlc_test.o \ ${OBJECTDIR}/test/object_test.o \ ${OBJECTDIR}/test/parser_test.o \ - ${OBJECTDIR}/test/speed_test.o \ ${OBJECTDIR}/variable.o \ ${OBJECTDIR}/version.o @@ -189,6 +189,11 @@ ${OBJECTDIR}/test/eval_test.o: test/eval_test.cpp ${RM} "$@.d" $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/eval_test.o test/eval_test.cpp +${OBJECTDIR}/test/example_test.o: test/example_test.cpp + ${MKDIR} -p ${OBJECTDIR}/test + ${RM} "$@.d" + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/example_test.o test/example_test.cpp + ${OBJECTDIR}/test/fraction_test.o: test/fraction_test.cpp ${MKDIR} -p ${OBJECTDIR}/test ${RM} "$@.d" @@ -214,11 +219,6 @@ ${OBJECTDIR}/test/parser_test.o: test/parser_test.cpp ${RM} "$@.d" $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/parser_test.o test/parser_test.cpp -${OBJECTDIR}/test/speed_test.o: test/speed_test.cpp - ${MKDIR} -p ${OBJECTDIR}/test - ${RM} "$@.d" - $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/speed_test.o test/speed_test.cpp - ${OBJECTDIR}/variable.o: variable.cpp ${MKDIR} -p ${OBJECTDIR} ${RM} "$@.d" diff --git a/src/nbproject/Makefile-LLVM.mk b/src/nbproject/Makefile-LLVM.mk index 5021b3c2..603bfb34 100644 --- a/src/nbproject/Makefile-LLVM.mk +++ b/src/nbproject/Makefile-LLVM.mk @@ -51,12 +51,12 @@ OBJECTFILES= \ ${OBJECTDIR}/test/alg_test.o \ ${OBJECTDIR}/test/compiler_test.o \ ${OBJECTDIR}/test/eval_test.o \ + ${OBJECTDIR}/test/example_test.o \ ${OBJECTDIR}/test/fraction_test.o \ ${OBJECTDIR}/test/lexer_test.o \ ${OBJECTDIR}/test/nlc_test.o \ ${OBJECTDIR}/test/object_test.o \ ${OBJECTDIR}/test/parser_test.o \ - ${OBJECTDIR}/test/speed_test.o \ ${OBJECTDIR}/variable.o \ ${OBJECTDIR}/version.o @@ -189,6 +189,11 @@ ${OBJECTDIR}/test/eval_test.o: test/eval_test.cpp ${RM} "$@.d" $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I/usr/lib/llvm-12/lib/clang/12.0.1/include -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I.. -std=c++14 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/eval_test.o test/eval_test.cpp +${OBJECTDIR}/test/example_test.o: test/example_test.cpp + ${MKDIR} -p ${OBJECTDIR}/test + ${RM} "$@.d" + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I/usr/lib/llvm-12/lib/clang/12.0.1/include -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I.. -std=c++14 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/example_test.o test/example_test.cpp + ${OBJECTDIR}/test/fraction_test.o: test/fraction_test.cpp ${MKDIR} -p ${OBJECTDIR}/test ${RM} "$@.d" @@ -214,11 +219,6 @@ ${OBJECTDIR}/test/parser_test.o: test/parser_test.cpp ${RM} "$@.d" $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I/usr/lib/llvm-12/lib/clang/12.0.1/include -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I.. -std=c++14 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/parser_test.o test/parser_test.cpp -${OBJECTDIR}/test/speed_test.o: test/speed_test.cpp - ${MKDIR} -p ${OBJECTDIR}/test - ${RM} "$@.d" - $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I/usr/lib/llvm-12/lib/clang/12.0.1/include -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I.. -std=c++14 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/speed_test.o test/speed_test.cpp - ${OBJECTDIR}/variable.o: variable.cpp ${MKDIR} -p ${OBJECTDIR} ${RM} "$@.d" diff --git a/src/nbproject/Makefile-LLVM_GCC.mk b/src/nbproject/Makefile-LLVM_GCC.mk index 8e780e3d..ac9ed1fa 100644 --- a/src/nbproject/Makefile-LLVM_GCC.mk +++ b/src/nbproject/Makefile-LLVM_GCC.mk @@ -51,12 +51,12 @@ OBJECTFILES= \ ${OBJECTDIR}/test/alg_test.o \ ${OBJECTDIR}/test/compiler_test.o \ ${OBJECTDIR}/test/eval_test.o \ + ${OBJECTDIR}/test/example_test.o \ ${OBJECTDIR}/test/fraction_test.o \ ${OBJECTDIR}/test/lexer_test.o \ ${OBJECTDIR}/test/nlc_test.o \ ${OBJECTDIR}/test/object_test.o \ ${OBJECTDIR}/test/parser_test.o \ - ${OBJECTDIR}/test/speed_test.o \ ${OBJECTDIR}/variable.o \ ${OBJECTDIR}/version.o @@ -189,6 +189,11 @@ ${OBJECTDIR}/test/eval_test.o: test/eval_test.cpp ${RM} "$@.d" $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I.. -std=c++14 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/eval_test.o test/eval_test.cpp +${OBJECTDIR}/test/example_test.o: test/example_test.cpp + ${MKDIR} -p ${OBJECTDIR}/test + ${RM} "$@.d" + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I.. -std=c++14 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/example_test.o test/example_test.cpp + ${OBJECTDIR}/test/fraction_test.o: test/fraction_test.cpp ${MKDIR} -p ${OBJECTDIR}/test ${RM} "$@.d" @@ -214,11 +219,6 @@ ${OBJECTDIR}/test/parser_test.o: test/parser_test.cpp ${RM} "$@.d" $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I.. -std=c++14 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/parser_test.o test/parser_test.cpp -${OBJECTDIR}/test/speed_test.o: test/speed_test.cpp - ${MKDIR} -p ${OBJECTDIR}/test - ${RM} "$@.d" - $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I.. -std=c++14 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/speed_test.o test/speed_test.cpp - ${OBJECTDIR}/variable.o: variable.cpp ${MKDIR} -p ${OBJECTDIR} ${RM} "$@.d" diff --git a/src/nbproject/Makefile-Release.mk b/src/nbproject/Makefile-Release.mk index c16fa408..1a76adad 100644 --- a/src/nbproject/Makefile-Release.mk +++ b/src/nbproject/Makefile-Release.mk @@ -51,12 +51,12 @@ OBJECTFILES= \ ${OBJECTDIR}/test/alg_test.o \ ${OBJECTDIR}/test/compiler_test.o \ ${OBJECTDIR}/test/eval_test.o \ + ${OBJECTDIR}/test/example_test.o \ ${OBJECTDIR}/test/fraction_test.o \ ${OBJECTDIR}/test/lexer_test.o \ ${OBJECTDIR}/test/nlc_test.o \ ${OBJECTDIR}/test/object_test.o \ ${OBJECTDIR}/test/parser_test.o \ - ${OBJECTDIR}/test/speed_test.o \ ${OBJECTDIR}/variable.o \ ${OBJECTDIR}/version.o @@ -175,6 +175,11 @@ ${OBJECTDIR}/test/eval_test.o: test/eval_test.cpp ${RM} "$@.d" $(COMPILE.cc) -O3 -Werror -I.. -std=c++14 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/eval_test.o test/eval_test.cpp +${OBJECTDIR}/test/example_test.o: test/example_test.cpp + ${MKDIR} -p ${OBJECTDIR}/test + ${RM} "$@.d" + $(COMPILE.cc) -O3 -Werror -I.. -std=c++14 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/example_test.o test/example_test.cpp + ${OBJECTDIR}/test/fraction_test.o: test/fraction_test.cpp ${MKDIR} -p ${OBJECTDIR}/test ${RM} "$@.d" @@ -200,11 +205,6 @@ ${OBJECTDIR}/test/parser_test.o: test/parser_test.cpp ${RM} "$@.d" $(COMPILE.cc) -O3 -Werror -I.. -std=c++14 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/parser_test.o test/parser_test.cpp -${OBJECTDIR}/test/speed_test.o: test/speed_test.cpp - ${MKDIR} -p ${OBJECTDIR}/test - ${RM} "$@.d" - $(COMPILE.cc) -O3 -Werror -I.. -std=c++14 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/speed_test.o test/speed_test.cpp - ${OBJECTDIR}/variable.o: variable.cpp ${MKDIR} -p ${OBJECTDIR} ${RM} "$@.d" diff --git a/src/nbproject/Makefile-UnitTest-Win32.mk b/src/nbproject/Makefile-UnitTest-Win32.mk index 67654f07..e39e58d4 100644 --- a/src/nbproject/Makefile-UnitTest-Win32.mk +++ b/src/nbproject/Makefile-UnitTest-Win32.mk @@ -51,12 +51,12 @@ OBJECTFILES= \ ${OBJECTDIR}/test/alg_test.o \ ${OBJECTDIR}/test/compiler_test.o \ ${OBJECTDIR}/test/eval_test.o \ + ${OBJECTDIR}/test/example_test.o \ ${OBJECTDIR}/test/fraction_test.o \ ${OBJECTDIR}/test/lexer_test.o \ ${OBJECTDIR}/test/nlc_test.o \ ${OBJECTDIR}/test/object_test.o \ ${OBJECTDIR}/test/parser_test.o \ - ${OBJECTDIR}/test/speed_test.o \ ${OBJECTDIR}/variable.o \ ${OBJECTDIR}/version.o @@ -216,6 +216,11 @@ ${OBJECTDIR}/test/eval_test.o: test/eval_test.cpp pch.h.gch ${RM} "$@.d" $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -I/usr/lib/llvm-13/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/eval_test.o test/eval_test.cpp +${OBJECTDIR}/test/example_test.o: test/example_test.cpp pch.h.gch + ${MKDIR} -p ${OBJECTDIR}/test + ${RM} "$@.d" + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -I/usr/lib/llvm-13/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/example_test.o test/example_test.cpp + ${OBJECTDIR}/test/fraction_test.o: test/fraction_test.cpp ${MKDIR} -p ${OBJECTDIR}/test ${RM} "$@.d" @@ -241,11 +246,6 @@ ${OBJECTDIR}/test/parser_test.o: test/parser_test.cpp pch.h.gch ${RM} "$@.d" $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -I/usr/lib/llvm-13/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/parser_test.o test/parser_test.cpp -${OBJECTDIR}/test/speed_test.o: test/speed_test.cpp pch.h.gch - ${MKDIR} -p ${OBJECTDIR}/test - ${RM} "$@.d" - $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -I/usr/lib/llvm-13/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/speed_test.o test/speed_test.cpp - : types.h pch.h.gch @echo Выполнение шага пользовательского сборки diff --git a/src/nbproject/Makefile-UnitTest-Win64.mk b/src/nbproject/Makefile-UnitTest-Win64.mk index b22985b8..a5a69dd7 100644 --- a/src/nbproject/Makefile-UnitTest-Win64.mk +++ b/src/nbproject/Makefile-UnitTest-Win64.mk @@ -51,12 +51,12 @@ OBJECTFILES= \ ${OBJECTDIR}/test/alg_test.o \ ${OBJECTDIR}/test/compiler_test.o \ ${OBJECTDIR}/test/eval_test.o \ + ${OBJECTDIR}/test/example_test.o \ ${OBJECTDIR}/test/fraction_test.o \ ${OBJECTDIR}/test/lexer_test.o \ ${OBJECTDIR}/test/nlc_test.o \ ${OBJECTDIR}/test/object_test.o \ ${OBJECTDIR}/test/parser_test.o \ - ${OBJECTDIR}/test/speed_test.o \ ${OBJECTDIR}/variable.o \ ${OBJECTDIR}/version.o @@ -216,6 +216,11 @@ ${OBJECTDIR}/test/eval_test.o: test/eval_test.cpp pch.h.gch ${RM} "$@.d" $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch-win/include/torch/csrc/api/include -I../contrib/libtorch-win/include -I../contrib/tensorboard_logger/include -I/usr/share/mingw-w64/include/ -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/eval_test.o test/eval_test.cpp +${OBJECTDIR}/test/example_test.o: test/example_test.cpp pch.h.gch + ${MKDIR} -p ${OBJECTDIR}/test + ${RM} "$@.d" + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch-win/include/torch/csrc/api/include -I../contrib/libtorch-win/include -I../contrib/tensorboard_logger/include -I/usr/share/mingw-w64/include/ -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/example_test.o test/example_test.cpp + ${OBJECTDIR}/test/fraction_test.o: test/fraction_test.cpp ${MKDIR} -p ${OBJECTDIR}/test ${RM} "$@.d" @@ -241,11 +246,6 @@ ${OBJECTDIR}/test/parser_test.o: test/parser_test.cpp pch.h.gch ${RM} "$@.d" $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch-win/include/torch/csrc/api/include -I../contrib/libtorch-win/include -I../contrib/tensorboard_logger/include -I/usr/share/mingw-w64/include/ -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/parser_test.o test/parser_test.cpp -${OBJECTDIR}/test/speed_test.o: test/speed_test.cpp pch.h.gch - ${MKDIR} -p ${OBJECTDIR}/test - ${RM} "$@.d" - $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch-win/include/torch/csrc/api/include -I../contrib/libtorch-win/include -I../contrib/tensorboard_logger/include -I/usr/share/mingw-w64/include/ -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/speed_test.o test/speed_test.cpp - : types.h pch.h.gch @echo Выполнение шага пользовательского сборки diff --git a/src/nbproject/Makefile-UnitTest.mk b/src/nbproject/Makefile-UnitTest.mk index 97f451d6..e9852ba1 100644 --- a/src/nbproject/Makefile-UnitTest.mk +++ b/src/nbproject/Makefile-UnitTest.mk @@ -51,12 +51,12 @@ OBJECTFILES= \ ${OBJECTDIR}/test/alg_test.o \ ${OBJECTDIR}/test/compiler_test.o \ ${OBJECTDIR}/test/eval_test.o \ + ${OBJECTDIR}/test/example_test.o \ ${OBJECTDIR}/test/fraction_test.o \ ${OBJECTDIR}/test/lexer_test.o \ ${OBJECTDIR}/test/nlc_test.o \ ${OBJECTDIR}/test/object_test.o \ ${OBJECTDIR}/test/parser_test.o \ - ${OBJECTDIR}/test/speed_test.o \ ${OBJECTDIR}/variable.o \ ${OBJECTDIR}/version.o @@ -219,6 +219,11 @@ ${OBJECTDIR}/test/eval_test.o: test/eval_test.cpp pch.h.gch ${RM} "$@.d" $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I. -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -I/usr/lib/llvm-13/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/eval_test.o test/eval_test.cpp +${OBJECTDIR}/test/example_test.o: test/example_test.cpp pch.h.gch + ${MKDIR} -p ${OBJECTDIR}/test + ${RM} "$@.d" + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I. -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -I/usr/lib/llvm-13/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/example_test.o test/example_test.cpp + ${OBJECTDIR}/test/fraction_test.o: test/fraction_test.cpp ${MKDIR} -p ${OBJECTDIR}/test ${RM} "$@.d" @@ -244,11 +249,6 @@ ${OBJECTDIR}/test/parser_test.o: test/parser_test.cpp pch.h.gch ${RM} "$@.d" $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I. -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -I/usr/lib/llvm-13/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/parser_test.o test/parser_test.cpp -${OBJECTDIR}/test/speed_test.o: test/speed_test.cpp pch.h.gch - ${MKDIR} -p ${OBJECTDIR}/test - ${RM} "$@.d" - $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I. -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -I/usr/lib/llvm-13/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/speed_test.o test/speed_test.cpp - : types.h pch.h.gch @echo Выполнение шага пользовательского сборки diff --git a/src/nbproject/Makefile-UnitTest_LLVM.mk b/src/nbproject/Makefile-UnitTest_LLVM.mk index e8e28655..ba18473a 100644 --- a/src/nbproject/Makefile-UnitTest_LLVM.mk +++ b/src/nbproject/Makefile-UnitTest_LLVM.mk @@ -51,12 +51,12 @@ OBJECTFILES= \ ${OBJECTDIR}/test/alg_test.o \ ${OBJECTDIR}/test/compiler_test.o \ ${OBJECTDIR}/test/eval_test.o \ + ${OBJECTDIR}/test/example_test.o \ ${OBJECTDIR}/test/fraction_test.o \ ${OBJECTDIR}/test/lexer_test.o \ ${OBJECTDIR}/test/nlc_test.o \ ${OBJECTDIR}/test/object_test.o \ ${OBJECTDIR}/test/parser_test.o \ - ${OBJECTDIR}/test/speed_test.o \ ${OBJECTDIR}/variable.o \ ${OBJECTDIR}/version.o @@ -191,6 +191,11 @@ ${OBJECTDIR}/test/eval_test.o: test/eval_test.cpp pch.h.pch ${RM} "$@.d" $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I. -I.. -I/usr/lib/llvm-13/lib/clang/13.0.1/include -I/usr/include/llvm-c-13 -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -include-pch pch.h.pch -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/eval_test.o test/eval_test.cpp +${OBJECTDIR}/test/example_test.o: test/example_test.cpp pch.h.pch + ${MKDIR} -p ${OBJECTDIR}/test + ${RM} "$@.d" + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I. -I.. -I/usr/lib/llvm-13/lib/clang/13.0.1/include -I/usr/include/llvm-c-13 -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -include-pch pch.h.pch -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/example_test.o test/example_test.cpp + ${OBJECTDIR}/test/fraction_test.o: test/fraction_test.cpp pch.h.pch ${MKDIR} -p ${OBJECTDIR}/test ${RM} "$@.d" @@ -216,11 +221,6 @@ ${OBJECTDIR}/test/parser_test.o: test/parser_test.cpp pch.h.pch ${RM} "$@.d" $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I. -I.. -I/usr/lib/llvm-13/lib/clang/13.0.1/include -I/usr/include/llvm-c-13 -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -include-pch pch.h.pch -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/parser_test.o test/parser_test.cpp -${OBJECTDIR}/test/speed_test.o: test/speed_test.cpp pch.h.pch - ${MKDIR} -p ${OBJECTDIR}/test - ${RM} "$@.d" - $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I. -I.. -I/usr/lib/llvm-13/lib/clang/13.0.1/include -I/usr/include/llvm-c-13 -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -include-pch pch.h.pch -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/speed_test.o test/speed_test.cpp - ${OBJECTDIR}/variable.o: variable.cpp pch.h.pch ${MKDIR} -p ${OBJECTDIR} ${RM} "$@.d" diff --git a/src/nbproject/configurations.xml b/src/nbproject/configurations.xml index 83240958..f6b81827 100644 --- a/src/nbproject/configurations.xml +++ b/src/nbproject/configurations.xml @@ -23,12 +23,12 @@ test/alg_test.cpp test/compiler_test.cpp test/eval_test.cpp + test/example_test.cpp test/fraction_test.cpp test/lexer_test.cpp test/nlc_test.cpp test/object_test.cpp test/parser_test.cpp - test/speed_test.cpp builtin.cpp context.cpp @@ -347,6 +347,11 @@ pch.h.gch + + + pch.h.gch + + @@ -369,11 +374,6 @@ pch.h.gch - - - pch.h.gch - - pch.h.gch @@ -629,6 +629,11 @@ + + + + + @@ -654,11 +659,6 @@ - - - - - @@ -821,6 +821,8 @@ + + @@ -831,8 +833,6 @@ - - @@ -1096,6 +1096,11 @@ pch.h.gch + + + pch.h.gch + + @@ -1118,11 +1123,6 @@ pch.h.gch - - - pch.h.gch - - pch.h.gch @@ -1395,37 +1395,37 @@ pch.h.pch - + -include-pch pch.h.pch pch.h.pch - + -include-pch pch.h.pch pch.h.pch - + -include-pch pch.h.pch pch.h.pch - + -include-pch pch.h.pch pch.h.pch - + -include-pch pch.h.pch pch.h.pch - + -include-pch pch.h.pch pch.h.pch @@ -1644,6 +1644,8 @@ + + @@ -1654,8 +1656,6 @@ - - @@ -1896,6 +1896,8 @@ + + @@ -1906,8 +1908,6 @@ - - @@ -2144,6 +2144,8 @@ + + @@ -2154,8 +2156,6 @@ - - @@ -2425,6 +2425,11 @@ pch.h.gch + + + pch.h.gch + + @@ -2447,11 +2452,6 @@ pch.h.gch - - - pch.h.gch - - pch.h.gch @@ -2726,6 +2726,11 @@ pch.h.gch + + + pch.h.gch + + @@ -2748,11 +2753,6 @@ pch.h.gch - - - pch.h.gch - - pch.h.gch diff --git a/src/object.cpp b/src/object.cpp index 452df616..c194128b 100644 --- a/src/object.cpp +++ b/src/object.cpp @@ -370,7 +370,7 @@ ObjType newlang::getSummaryTensorType(Obj *obj, ObjType start) { if(!obj) { return result; } - if(obj->is_dictionary_type()) { + if(obj->is_dictionary_type() || obj->is_range()) { for (int i = 0; i < obj->size(); i++) { result = getSummaryTensorType(obj->at(i).second.get(), result); } @@ -378,6 +378,8 @@ ObjType newlang::getSummaryTensorType(Obj *obj, ObjType start) { } else if(obj->is_arithmetic_type()) { if(isGenericType(obj->m_var_type_fixed)) { return std::max(obj->m_var_type_current, start); + } else if(start == ObjType::Fraction || obj->m_var_type_current == ObjType::Fraction || obj->m_var_type_fixed == ObjType::Fraction) { + return ObjType::Fraction; } else { if(start >= std::max(obj->m_var_type_current, obj->m_var_type_fixed)) { return start; @@ -449,9 +451,9 @@ ObjPtr Obj::operator+=(Obj value) { case ObjType::Fraction: if(value.m_var_type_current == ObjType::Fraction) { - m_fraction->operator+=(*(value.m_fraction.get())); + m_fraction.operator+=(value.m_fraction); } else { - m_fraction->operator+=(*(value.toType(ObjType::Fraction)->m_fraction.get())); + m_fraction.operator+=(value.toType(ObjType::Fraction)->m_fraction); } return shared(); @@ -507,9 +509,9 @@ ObjPtr Obj::operator-=(Obj value) { break; case ObjType::Fraction: if(value.m_var_type_current == ObjType::Fraction) { - m_fraction->operator-=(*(value.m_fraction.get())); + m_fraction.operator-=(value.m_fraction); } else { - m_fraction->operator-=(*(value.toType(ObjType::Fraction)->m_fraction.get())); + m_fraction.operator-=(value.toType(ObjType::Fraction)->m_fraction); } return shared(); } @@ -580,9 +582,9 @@ ObjPtr Obj::operator*=(Obj value) { case ObjType::Fraction: if(value.m_var_type_current == ObjType::Fraction) { - m_fraction->operator*=(*(value.m_fraction.get())); + m_fraction.operator*=(value.m_fraction); } else { - m_fraction->operator*=(*(value.toType(ObjType::Fraction)->m_fraction.get())); + m_fraction.operator*=(value.toType(ObjType::Fraction)->m_fraction); } return shared(); @@ -620,9 +622,9 @@ ObjPtr Obj::operator/=(Obj value) { return shared(); } else if(m_var_type_current == ObjType::Fraction) { if(value.m_var_type_current == ObjType::Fraction) { - m_fraction->operator/=(*(value.m_fraction.get())); + m_fraction.operator/=(value.m_fraction); } else { - m_fraction->operator/=(*(value.toType(ObjType::Fraction)->m_fraction.get())); + m_fraction.operator/=(value.toType(ObjType::Fraction)->m_fraction); } return shared(); } @@ -665,12 +667,12 @@ ObjPtr Obj::op_div_ceil_(Obj & value) { return shared(); } else if(m_var_type_current == ObjType::Fraction) { - // if(value.m_var_type_current == ObjType::Fraction) { - // m_fraction->operator/=(value.m_fraction); - // } else { - // m_fraction->operator/=(value.toType(ObjPtr::Fraction)->m_fraction); - // } - // return shared(); + if(value.m_var_type_current == ObjType::Fraction) { + m_fraction.op_div_ceil_(value.m_fraction); + } else { + m_fraction.op_div_ceil_(value.toType(ObjType::Fraction)->m_fraction); + } + return shared(); } LOG_RUNTIME("Operator '//' fail for '%s' and '%s'", toString().c_str(), value.toString().c_str()); } @@ -702,12 +704,12 @@ ObjPtr Obj::operator%=(Obj value) { } return shared(); } else if(m_var_type_current == ObjType::Fraction) { - // if(value.m_var_type_current == ObjType::Fraction) { - // m_fraction->operator*=(value.m_fraction); - // } else { - // m_fraction->operator*=(value.toType(ObjPtr::Fraction)->m_fraction); - // } - // return shared(); + if(value.m_var_type_current == ObjType::Fraction) { + m_fraction.operator%=(value.m_fraction); + } else { + m_fraction.operator%=(value.toType(ObjType::Fraction)->m_fraction); + } + return shared(); } LOG_RUNTIME("Operator '%%' fail for '%s' and '%s'", toString().c_str(), value.toString().c_str()); } @@ -744,12 +746,11 @@ void Obj::CloneDataTo(Obj & clone) const { clone.m_value = m_value; clone.m_string = m_string; - if(m_fraction) { - clone.m_fraction = std::make_shared(*m_fraction.get()); - } else { - clone.m_fraction = nullptr; - } + clone.m_fraction = *m_fraction.clone(); clone.m_iterator = m_iterator; + if(m_iter_range_value) { + clone.m_iter_range_value = m_iter_range_value->Clone(); + } clone.m_class_parents = m_class_parents; clone.m_class_name = m_class_name; @@ -1001,8 +1002,7 @@ std::string Obj::toString(bool deep) const { return result; case ObjType::Fraction: - ASSERT(m_fraction); - result += m_fraction->GetAsString(); + result += m_fraction.GetAsString(); return result; case ObjType::Iterator: @@ -1161,9 +1161,12 @@ std::string Obj::GetValueAsString() const { return result; case ObjType::Fraction: - ASSERT(m_fraction); - result += m_fraction->GetAsString(); + result += m_fraction.GetAsString(); return result; + + case ObjType::Iterator: + case ObjType::IteratorEnd: + return newlang::toString(m_var_type_current); } LOG_RUNTIME("Data type '%s' %d incompatible to string!", newlang::toString(m_var_type_current), (int) m_var_type_current); } @@ -1299,6 +1302,75 @@ ObjPtr Obj::Call(Context *ctx, Obj * args) { LOG_RUNTIME("Call by name not implemted '%s'!", toString().c_str()); } + + // ObjType type_result = ctx->BaseTypeFromString(m_prototype->m_type_name); + // LLVMTypeRef return_llvm_type = toLLVMType(type_result); + // + // bool is_ellipsis = (m_prototype->size() && (*m_prototype)[m_prototype->size() - 1].second->getTermID() == TermID::ELLIPSIS); + // size_t check_count = is_ellipsis ? m_prototype->size() - 1 : m_prototype->size(); + // + // bool pointer_exist = false; + // // Пропустить нулевой аргумент для нативных функций + // for (int i = 1; i < args.size(); i++) { + // + // ASSERT(args[i].second); + // if(args[i].second->m_is_reference) { + // LOG_RUNTIME("Argument REFERENCE! %s", args[i].second->toString().c_str()); + // } + // + // size_t pind = i - 1; // Индекс прототипа на единицу меньше из-за пустого нулевого аргумента + // + // ObjType type = args[i].second->getTypeAsLimit(); + // if(pind < check_count) { + // NL_CHECK(!(*m_prototype)[pind].second->m_type_name.empty(), "Undefined type arg '%s'", (*m_prototype)[pind].second->toString().c_str()); + // + // ObjType proto_type = typeFromString((*m_prototype)[pind].second->m_type_name, ctx); + // if(!canCast(type, proto_type)) { + // if(!((type == ObjType::StrChar || type == ObjType::FmtChar) && proto_type == ObjType::Char) || + // ((type == ObjType::StrWide || type == ObjType::FmtWide) && proto_type == ObjType::Int)) { + // LOG_RUNTIME("Fail cast from '%s' to '%s'", (*m_prototype)[pind].second->m_type_name.c_str(), newlang::toString(type)); + // } + // } + // } + // + // ObjType check_type; + // if(pind < check_count) { + // std::string temp_str = (*m_prototype)[pind].second->m_type_name; + // check_type = typeFromString((*m_prototype)[pind].second->m_type_name, ctx); + // } else { + // check_type = args[i].second->getType(); + // } + // + // if(args[i].second->is_string_type()) { + // pointer_exist = true; + // } + // + // if(check_type == ObjType::Bool && m_namespace.empty()) { + // // В чистом С (для пустого m_namespace) для логического типа используется тип int + // check_type = ObjType::Int; + // } + // if(check_type == ObjType::Iterator) { + // // У итератора передается не объект, а его данные + // ASSERT(args[i].second->m_iterator); + // check_type = args[i].second->m_iterator->data().second->getType(); + // } + // if((check_type == ObjType::FmtWide || check_type == ObjType::StrWide) || + // ((check_type == ObjType::FmtChar || check_type == ObjType::StrChar) && + // (args[i].second->getType() == ObjType::StrWide || args[i].second->getType() == ObjType::FmtWide))) { + // LOG_RUNTIME("Convert wide characters as native function arguments not supported!"); + // } + // + // LLVMTypeRef temp = toLLVMType(check_type); + // arg_types.push_back(temp); + // arg_generic.push_back(args[i].second->GetGenericValueRef(temp)); + // + // if(pind < check_count && (*m_prototype)[pind].second->GetType()) { + // if((*m_prototype)[pind].second->GetType()->m_text.compare(newlang::toString(ObjType::FmtChar)) == 0) { + // NL_CHECK(ParsePrintfFormat(&args, i), "Fail format string or type args!"); + // } + // } + // } + if(ctx) { ctx->pop_front(); } @@ -1342,6 +1414,22 @@ void Obj::ConvertToArgs_(Obj *in, bool check_valid, Context * ctx) { // if(check_valid && named) { // LOG_RUNTIME("Position %d requires a named argument!", (int) i + 1); // } + ObjType base_type = ObjType::None; + if(i < size()) { + if(ctx) { + bool has_error = false; + base_type = ctx->BaseTypeFromString((*m_prototype)[i].second->m_type_name, &has_error); + if(has_error && (*m_prototype)[i].second->getTermID() == TermID::ELLIPSIS) { + base_type = ObjType::Any; + } + } else { + base_type = typeFromString((*m_prototype)[i].second->m_type_name, ctx); + } + } else { + base_type = ObjType::Any; + } + + if(i < size()) { if(check_valid && at(i).second && at(i).second->getType() != ObjType::None) { if(!canCast((*in)[i].second->getType(), at(i).second->getType())) { @@ -1354,28 +1442,24 @@ void Obj::ConvertToArgs_(Obj *in, bool check_valid, Context * ctx) { } if(m_prototype && i < m_prototype->size()) { at(i).second->m_is_reference = (*m_prototype)[i].second->isRef(); - ObjType base_type = ObjType::None; - if(ctx) { - base_type = ctx->BaseTypeFromString((*m_prototype)[i].second->m_type_name); - } else { - base_type = typeFromString((*m_prototype)[i].second->m_type_name, ctx); - } ObjType limit_type = (*in)[i].second->getTypeAsLimit(); if(!canCast(limit_type, base_type)) { // Строку с одним символом можно преобразовать в арифметичсекий тип if(!(isArithmeticType(base_type) && (*in)[i].second->is_string_type() && (*in)[i].second->size() == 1)) { - LOG_RUNTIME("Fail cast value '%s' to type '%s'", - (*in)[i].second->toString().c_str(), (*m_prototype)[i].second->m_type_name.c_str()); + LOG_RUNTIME("Fail cast value %s%s to type %s", + (*in)[i].second->toString().c_str(), + newlang::toString((*in)[i].second->getType()), + (*m_prototype)[i].second->m_type_name.c_str()); } } } - at(i).second->op_assign((*in)[i].second); + at(i).second->op_assign((*in)[i].second->toType(base_type)); } else { if(check_valid && !is_ellipsis && m_prototype && i >= m_prototype->size()) { LOG_RUNTIME("Positional args overflow. Ptrototype '%s'!", m_prototype ? m_prototype->toString().c_str() : "Prototype not exists!"); } - push_back(in->at(i)); + push_back(in->at(i).second->toType(base_type), in->at(i).first); } } else { // named = true; @@ -1413,16 +1497,16 @@ void Obj::ConvertToArgs_(Obj *in, bool check_valid, Context * ctx) { } void Obj::CheckArgsValid() const { - // bool named = false; - // for (int i = 0; i < Variable::size(); i++) { - // // if(!at(i).second) { - // // - // // LOG_RUNTIME("Argument %d '%s' missed!", (int) i + 1, at(i).first.c_str()); - // // } + bool named = false; + for (int i = 0; i < Variable::size(); i++) { + if(!at(i).second) { + + LOG_RUNTIME("Argument %d '%s' missed!", (int) i + 1, at(i).first.c_str()); + } + } + // if(!CheckArgs_()) { + // LOG_RUNTIME("Fail arguments!"); // } - // // if(!CheckArgs_()) { - // // LOG_RUNTIME("Fail arguments!"); - // // } } /* @@ -1453,6 +1537,13 @@ int Obj::op_compare(Obj & value) { }; return 0; } + } else if(is_fraction()) { + + if(value.getType() == ObjType::Fraction) { + return m_fraction.op_compare(value.m_fraction); + } else { + return m_fraction.op_compare(*value.GetValueAsFraction()); + } } else if((is_string_type() && value.is_string_type())) { switch(m_var_type_current) { @@ -1508,6 +1599,14 @@ bool Obj::op_equal(Obj & value) { return GetValueAsBoolean() == value.GetValueAsBoolean(); } else if(is_string_type()) { return GetValueAsString().compare(value.GetValueAsString()) == 0; + } else if(is_fraction()) { + + if(value.getType() == ObjType::Fraction) { + return m_fraction.op_equal(value.m_fraction); + } else { + return m_fraction.op_equal(*value.GetValueAsFraction()); + } + } else if(is_dictionary_type() && value.is_dictionary_type()) { if(size() != value.size()) { return false; @@ -1669,12 +1768,11 @@ ObjPtr Obj::op_pow_(Obj & obj) { return shared(); } else if(is_fraction()) { - ASSERT(m_fraction); - ObjPtr temp = obj.toType(ObjType::Fraction); - ASSERT(temp); - ASSERT(temp->m_fraction); - - m_fraction->op_pow_(*temp->m_fraction.get()); + if(obj.getType() == ObjType::Fraction) { + m_fraction.op_pow_(obj.m_fraction); + } else { + m_fraction.op_pow_(*obj.GetValueAsFraction()); + } return shared(); } else if(m_var_type_current == ObjType::StrChar && obj.is_integral()) { @@ -1839,6 +1937,10 @@ std::vector newlang::TensorShapeFromDict(const Obj * obj) { return shape; } + +ObjPtr CallLibFFI_(Context *ctx, Obj args); +bool InitLibFFI_(const std::string name); + ObjPtr Obj::CallNative(Context *ctx, Obj args) { if(!ctx || !ctx->m_runtime) { @@ -1895,6 +1997,11 @@ ObjPtr Obj::CallNative(Context *ctx, Obj args) { // В чистом С (для пустого m_namespace) для логического типа используется тип int check_type = ObjType::Int; } + if(check_type == ObjType::Iterator) { + // У итератора передается не объект, а его данные + ASSERT(args[i].second->m_iterator); + check_type = args[i].second->m_iterator->data().second->getType(); + } if((check_type == ObjType::FmtWide || check_type == ObjType::StrWide) || ((check_type == ObjType::FmtChar || check_type == ObjType::StrChar) && (args[i].second->getType() == ObjType::StrWide || args[i].second->getType() == ObjType::FmtWide))) { @@ -1997,6 +2104,390 @@ ObjPtr Obj::CallNative(Context *ctx, Obj args) { return result; } +/* + * Так как под виндой не получается передавать аргументы в функции при вызове LLVMRunFunction + * похоже придется возвращатсья на libffi. А заодно и сделаю предкомпиляцию модулей LLVM + * при создании функции, а не как сейчас при каждом вызове. + * + * Вернул старый рабочий код, чтобы потом не искать его в истории. + */ + +bool InitLibFFI_(const std::string name) { + // std::string ffi_file; + + // typedef ffi_status ffi_prep_cif_type(ffi_cif *cif, ffi_abi abi, unsigned int nargs, ffi_type *rtype, ffi_type **atypes); + // typedef ffi_status ffi_prep_cif_var_type(ffi_cif *cif, ffi_abi abi, unsigned int nfixedargs, unsigned int ntotalargs, ffi_type *rtype, ffi_type **atypes); + // typedef void ffi_call_type(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue); + // ffi_type * m_ffi_type_void; + // ffi_type * m_ffi_type_uint8; + // ffi_type * m_ffi_type_sint8; + // ffi_type * m_ffi_type_uint16; + // ffi_type * m_ffi_type_sint16; + // ffi_type * m_ffi_type_uint32; + // ffi_type * m_ffi_type_sint32; + // ffi_type * m_ffi_type_uint64; + // ffi_type * m_ffi_type_sint64; + // ffi_type * m_ffi_type_float; + // ffi_type * m_ffi_type_double; + // ffi_type * m_ffi_type_pointer; + // + // ffi_prep_cif_type *m_ffi_prep_cif; + // ffi_prep_cif_var_type * m_ffi_prep_cif_var; + // ffi_call_type * m_ffi_call; + // + //#ifdef _MSC_VER + // + // std::wstring sys_file; + // std::string sys_init; + // + // //#define CYGWIN + //#ifdef CYGWIN + // sys_file = L"cygwin1.dll"; + // sys_init = "cygwin_dll_init"; + // ffi_file = "cygffi-6.dll"; + //#else + // sys_file = L"msys-2.0.dll"; + // sys_init = "msys_dll_init"; + // ffi_file = "libffi-7.dll"; + //#endif + // + // rt->m_msys = LoadLibrary(sys_file.c_str()); + // if (!rt->m_msys) { + // LOG_RUNTIME("Fail LoadLibrary %s: %s", sys_file.c_str(), RunTime::GetLastErrorMessage().c_str()); + // } + // + // typedef void init_type(); + // + // init_type *init = (init_type *) GetProcAddress((HMODULE) rt->m_msys, sys_init.c_str()); + // if (rt->m_msys && !init) { + // FreeLibrary((HMODULE) rt->m_msys); + // LOG_RUNTIME("Func %s not found! %s", sys_init.c_str(), RunTime::GetLastErrorMessage().c_str()); + // (*init)(); + // } + // rt->m_ffi_handle = LoadLibrary(utf8_decode(ffi_file).c_str()); + //#else + // std::string error; + // if (!llvm::sys::DynamicLibrary::LoadLibraryPermanently("libffi", &error)) { + // LOG_RUNTIME("Fail load library libffi.so '%s'", error.c_str()); + // } + // + // + // // ffi_file = "libffi.so"; + // // rt->m_ffi_handle = dlopen(ffi_file.c_str(), RTLD_NOW); + //#endif + // // + // // if (!rt->m_ffi_handle) { + // // LOG_RUNTIME("Fail load %s!", ffi_file.c_str()); + // // } + // + // rt->m_ffi_type_void = static_cast (GetDirectAddressFromLibrary(rt->m_ffi_handle, "ffi_type_void")); + // rt->m_ffi_type_uint8 = static_cast (GetDirectAddressFromLibrary(rt->m_ffi_handle, "ffi_type_uint8")); + // rt->m_ffi_type_sint8 = static_cast (GetDirectAddressFromLibrary(rt->m_ffi_handle, "ffi_type_sint8")); + // rt->m_ffi_type_uint16 = static_cast (GetDirectAddressFromLibrary(rt->m_ffi_handle, "ffi_type_uint16")); + // rt->m_ffi_type_sint16 = static_cast (GetDirectAddressFromLibrary(rt->m_ffi_handle, "ffi_type_sint16")); + // rt->m_ffi_type_uint32 = static_cast (GetDirectAddressFromLibrary(rt->m_ffi_handle, "ffi_type_uint32")); + // rt->m_ffi_type_sint32 = static_cast (GetDirectAddressFromLibrary(rt->m_ffi_handle, "ffi_type_sint32")); + // rt->m_ffi_type_uint64 = static_cast (GetDirectAddressFromLibrary(rt->m_ffi_handle, "ffi_type_uint64")); + // rt->m_ffi_type_sint64 = static_cast (GetDirectAddressFromLibrary(rt->m_ffi_handle, "ffi_type_sint64")); + // rt->m_ffi_type_float = static_cast (GetDirectAddressFromLibrary(rt->m_ffi_handle, "ffi_type_float")); + // rt->m_ffi_type_double = static_cast (GetDirectAddressFromLibrary(rt->m_ffi_handle, "ffi_type_double")); + // rt->m_ffi_type_pointer = static_cast (GetDirectAddressFromLibrary(rt->m_ffi_handle, "ffi_type_pointer")); + // + // rt->m_ffi_prep_cif = reinterpret_cast (GetDirectAddressFromLibrary(rt->m_ffi_handle, "ffi_prep_cif")); + // rt->m_ffi_prep_cif_var = reinterpret_cast (GetDirectAddressFromLibrary(rt->m_ffi_handle, "ffi_prep_cif_var")); + // rt->m_ffi_call = reinterpret_cast (GetDirectAddressFromLibrary(rt->m_ffi_handle, "ffi_call")); + // + // if (!(rt->m_ffi_type_uint8 && rt->m_ffi_type_sint8 && rt->m_ffi_type_uint16 && rt->m_ffi_type_sint16 && + // rt->m_ffi_type_uint32 && rt->m_ffi_type_sint32 && rt->m_ffi_type_uint64 && rt->m_ffi_type_sint64 && + // rt->m_ffi_type_float && rt->m_ffi_type_double && rt->m_ffi_type_pointer && rt->m_ffi_type_void && + // rt->m_ffi_prep_cif && rt->m_ffi_prep_cif_var && rt->m_ffi_call)) { + // LOG_RUNTIME("Fail init data from %s!", ffi_file.c_str()); + // } + // + // return rt; + // } + // + // inline static void * GetDirectAddressFromLibrary(void *handle, const char * name) { + //#ifdef _MSC_VER + // return static_cast (::GetProcAddress((HMODULE) handle, name)); + //#else + // void *res = llvm::sys::DynamicLibrary::SearchForAddressOfSymbol(name); + // if (res) { + // return res; + // } + // // if (m_llvm_engine) { + // // // ASSERT(m_llvm_engine); + // // return LLVMGetPointerToNamedFunction_(m_llvm_engine, name); + // // } + // return nullptr; + // // return dlsym(handle, name); + //#endif + // } + + return false; +} + +ObjPtr CallLibFFI_(Context *ctx, Obj args) { + // + // if(!ctx || !ctx->m_runtime) { + // LOG_RUNTIME("Fail context for call native!"); + // } + // + // ffi_cif m_cif; + // std::vector m_args_type; + // std::vector m_args_ptr; + // + // union VALUE { + // const void *ptr; + // // ObjPtr obj; + // size_t size; + // int64_t integer; + // double number; + // bool boolean; + // }; + // std::vector m_args_val; + // VALUE temp; + // + // ASSERT(m_var_type_current == ObjType::NativeFunc); + // ASSERT(m_func_proto); + // + // if(!m_func_ptr) { + // NL_CHECK(m_module_name.empty() || ctx, "You cannot load a module without access to the runtime context!"); + // m_func_ptr = ctx->m_runtime->GetNativeAddr(m_func_mangle_name.empty() ? m_func_proto->m_text.c_str() : m_func_mangle_name.c_str(), + // m_module_name.empty() ? nullptr : m_module_name.c_str()); + // } + // NL_CHECK(m_func_ptr, "Fail load func name '%s' (%s) or fail load module '%s'!", m_func_proto->m_text.c_str(), + // m_func_mangle_name.empty() ? m_func_proto->m_text.c_str() : m_func_mangle_name.c_str(), + // m_module_name.empty() ? "none" : m_module_name.c_str()); + // + // bool is_ellipsis = (m_func_proto->size() && (*m_func_proto)[m_func_proto->size() - 1].second->getTermID() == TermID::ELLIPSIS); + // size_t check_count = is_ellipsis ? m_func_proto->size() - 1 : m_func_proto->size(); + // + // // Пропустить нулевой аргумент для нативных функций + // for (int i = 1; i < args.size(); i++) { + // + // ASSERT(args[i].second); + // if(args[i].second->m_is_reference) { + // LOG_RUNTIME("Argument REFERENCE! %s", args[i].second->toString().c_str()); + // } + // + // size_t pind = i - 1; // Индекс прототипа на единицу меньше из-за пустого нулевого аргумента + // + // ObjType type = args[i].second->getTypeAsLimit(); + // switch(type) { + // case ObjType::Bool: + // if(pind < check_count) { + // NL_CHECK(!(*m_func_proto)[pind].second->m_type_name.empty(), "Undefined type arg '%s'", (*m_func_proto)[pind].second->toString().c_str()); + // NL_CHECK(canCast(type, typeFromString((*m_func_proto)[pind].second->m_type_name, ctx)), "Fail cast from '%s' to '%s'", + // (*m_func_proto)[pind].second->m_type_name.c_str(), newlang::toString(type)); + // } + // m_args_type.push_back(ctx->m_runtime->m_ffi_type_uint8); + // temp.boolean = args[i].second->GetValueAsBoolean(); + // m_args_val.push_back(temp); + // break; + // + // case ObjType::Char: + // if(pind < check_count) { + // NL_CHECK(!(*m_func_proto)[pind].second->m_type_name.empty(), "Undefined type arg '%s'", (*m_func_proto)[pind].second->toString().c_str()); + // NL_CHECK(canCast(type, typeFromString((*m_func_proto)[pind].second->m_type_name, ctx)), "Fail cast from '%s' to '%s'", + // (*m_func_proto)[pind].second->m_type_name.c_str(), newlang::toString(type)); + // } + // m_args_type.push_back(ctx->m_runtime->m_ffi_type_sint8); + // temp.integer = args[i].second->GetValueAsInteger(); + // m_args_val.push_back(temp); + // break; + // + // case ObjType::Short: + // if(pind < check_count) { + // NL_CHECK(!(*m_func_proto)[pind].second->m_type_name.empty(), "Undefined type arg '%s'", (*m_func_proto)[pind].second->toString().c_str()); + // NL_CHECK(canCast(type, typeFromString((*m_func_proto)[pind].second->m_type_name, ctx)), "Fail cast from '%s' to '%s'", + // (*m_func_proto)[pind].second->m_type_name.c_str(), newlang::toString(type)); + // } + // m_args_type.push_back(ctx->m_runtime->m_ffi_type_sint16); + // temp.integer = args[i].second->GetValueAsInteger(); + // m_args_val.push_back(temp); + // break; + // + // case ObjType::Int: + // if(pind < check_count) { + // NL_CHECK(!(*m_func_proto)[pind].second->m_type_name.empty(), "Undefined type arg '%s'", (*m_func_proto)[pind].second->toString().c_str()); + // NL_CHECK(canCast(type, typeFromString((*m_func_proto)[pind].second->m_type_name, ctx)), "Fail cast from '%s' to '%s'", + // (*m_func_proto)[pind].second->m_type_name.c_str(), newlang::toString(type)); + // } + // m_args_type.push_back(ctx->m_runtime->m_ffi_type_sint32); + // temp.integer = args[i].second->GetValueAsInteger(); + // m_args_val.push_back(temp); + // break; + // + // case ObjType::Long: + // if(pind < check_count) { + // NL_CHECK(!(*m_func_proto)[pind].second->m_type_name.empty(), "Undefined type arg '%s'", (*m_func_proto)[pind].second->toString().c_str()); + // NL_CHECK(canCast(type, typeFromString((*m_func_proto)[pind].second->m_type_name, ctx)), "Fail cast from '%s' to '%s'", + // (*m_func_proto)[pind].second->m_type_name.c_str(), newlang::toString(type)); + // } + // m_args_type.push_back(ctx->m_runtime->m_ffi_type_sint64); + // temp.integer = args[i].second->GetValueAsInteger(); + // m_args_val.push_back(temp); + // break; + // + // case ObjType::Float: + // if(pind < check_count) { + // NL_CHECK(!(*m_func_proto)[pind].second->m_type_name.empty(), "Undefined type arg '%s'", (*m_func_proto)[pind].second->toString().c_str()); + // NL_CHECK(canCast(type, typeFromString((*m_func_proto)[pind].second->m_type_name, ctx)), "Fail cast from '%s' to '%s'", + // (*m_func_proto)[pind].second->m_type_name.c_str(), newlang::toString(type)); + // } + // m_args_type.push_back(ctx->m_runtime->m_ffi_type_float); + // temp.number = args[i].second->GetValueAsNumber(); + // m_args_val.push_back(temp); + // break; + // + // case ObjType::Double: + // if(pind < check_count) { + // NL_CHECK(!(*m_func_proto)[pind].second->m_type_name.empty(), "Undefined type arg '%s'", (*m_func_proto)[pind].second->toString().c_str()); + // NL_CHECK(canCast(type, typeFromString((*m_func_proto)[pind].second->m_type_name, ctx)), "Fail cast from '%s' to '%s'", + // (*m_func_proto)[pind].second->m_type_name.c_str(), newlang::toString(type)); + // } + // m_args_type.push_back(ctx->m_runtime->m_ffi_type_double); + // temp.number = args[i].second->GetValueAsNumber(); + // m_args_val.push_back(temp); + // break; + // + // case ObjType::StrChar: + // if(pind < check_count) { + // NL_CHECK(!(*m_func_proto)[pind].second->m_type_name.empty(), "Undefined type arg '%s'", (*m_func_proto)[pind].second->toString().c_str()); + // NL_CHECK(canCast(type, typeFromString((*m_func_proto)[pind].second->m_type_name, ctx)), "Fail cast from '%s' to '%s'", + // (*m_func_proto)[pind].second->m_type_name.c_str(), newlang::toString(type)); + // } + // m_args_type.push_back(ctx->m_runtime->m_ffi_type_pointer); + // temp.ptr = args[i].second->m_str.c_str(); + // m_args_val.push_back(temp); + // break; + // + // case ObjType::StrWide: + // if(pind < check_count) { + // NL_CHECK(!(*m_func_proto)[pind].second->m_type_name.empty(), "Undefined type arg '%s'", (*m_func_proto)[pind].second->toString().c_str()); + // NL_CHECK(canCast(type, typeFromString((*m_func_proto)[pind].second->m_type_name, ctx)), "Fail cast from '%s' to '%s'", + // (*m_func_proto)[pind].second->m_type_name.c_str(), newlang::toString(type)); + // } + // m_args_type.push_back(ctx->m_runtime->m_ffi_type_pointer); + // temp.ptr = args[i].second->m_wstr.c_str(); + // m_args_val.push_back(temp); + // break; + // + // case ObjType::Pointer: + // if(pind < check_count) { + // NL_CHECK(!(*m_func_proto)[pind].second->m_type_name.empty(), "Undefined type arg '%s'", (*m_func_proto)[pind].second->toString().c_str()); + // NL_CHECK(canCast(type, typeFromString((*m_func_proto)[pind].second->m_type_name, ctx)), "Fail cast from '%s' to '%s'", + // (*m_func_proto)[pind].second->m_type_name.c_str(), newlang::toString(type)); + // } + // m_args_type.push_back(ctx->m_runtime->m_ffi_type_pointer); + // temp.ptr = args[i].second->m_func_ptr; + // m_args_val.push_back(temp); + // break; + // + // default: + // LOG_RUNTIME("Native arg '%s' not implemented!", args[i].second->toString().c_str()); + // } + // if(pind < check_count && (*m_func_proto)[pind].second->GetType()) { + // if((*m_func_proto)[pind].second->GetType()->m_text.compare(newlang::toString(ObjType::FmtChar)) == 0) { + // NL_CHECK(ParsePrintfFormat(&args, i), "Fail format string or type args!"); + // } + // } + // } + // + // for (size_t i = 0; i < m_args_val.size(); i++) { + // m_args_ptr.push_back((void *) &m_args_val[i]); + // } + // + // NL_CHECK(!m_func_proto->m_type_name.empty(), "Undefined return type '%s'", m_func_proto->toString().c_str()); + // + // VALUE res_value; + // ffi_type *result_ffi_type = nullptr; + // + // ObjType type = ctx->BaseTypeFromString(m_func_proto->m_type_name); + // + // switch(type) { + // case ObjType::Bool: + // result_ffi_type = ctx->m_runtime->m_ffi_type_uint8; + // break; + // + // case ObjType::Char: + // result_ffi_type = ctx->m_runtime->m_ffi_type_sint8; + // break; + // + // case ObjType::Short: + // result_ffi_type = ctx->m_runtime->m_ffi_type_sint16; + // break; + // + // case ObjType::Int: + // result_ffi_type = ctx->m_runtime->m_ffi_type_sint32; + // break; + // + // case ObjType::Long: + // result_ffi_type = ctx->m_runtime->m_ffi_type_sint64; + // break; + // + // case ObjType::Float: + // result_ffi_type = ctx->m_runtime->m_ffi_type_float; + // break; + // + // case ObjType::Double: + // result_ffi_type = ctx->m_runtime->m_ffi_type_double; + // break; + // + // case ObjType::Pointer: + // case ObjType::StrChar: + // case ObjType::StrWide: + // result_ffi_type = ctx->m_runtime->m_ffi_type_pointer; + // break; + // + // default: + // LOG_RUNTIME("Native return type '%s' not implemented!", m_func_proto->m_type_name.c_str()); + // } + // + // ASSERT(m_func_abi == FFI_DEFAULT_ABI); // Нужны другие типы вызовов ??? + // if(ctx->m_runtime->m_ffi_prep_cif(&m_cif, m_func_abi, static_cast (m_args_type.size()), result_ffi_type, m_args_type.data()) == FFI_OK) { + // + // ctx->m_runtime->m_ffi_call(&m_cif, FFI_FN(m_func_ptr), &res_value, m_args_ptr.data()); + // + // if(result_ffi_type == ctx->m_runtime->m_ffi_type_uint8) { + // // Возвращаемый тип может быть как Byte, так и Bool + // return Obj::CreateValue(static_cast (res_value.integer), typeFromString(m_func_proto->m_type_name)); + // } else if(result_ffi_type == ctx->m_runtime->m_ffi_type_sint8) { + // return Obj::CreateValue(static_cast (res_value.integer), ObjType::Char); + // } else if(result_ffi_type == ctx->m_runtime->m_ffi_type_sint16) { + // return Obj::CreateValue(static_cast (res_value.integer), ObjType::Short); + // } else if(result_ffi_type == ctx->m_runtime->m_ffi_type_sint32) { + // return Obj::CreateValue(static_cast (res_value.integer), ObjType::Int); + // } else if(result_ffi_type == ctx->m_runtime->m_ffi_type_sint64) { + // return Obj::CreateValue(res_value.integer, ObjType::Long); + // } else if(result_ffi_type == ctx->m_runtime->m_ffi_type_float) { + // return Obj::CreateValue(res_value.number, ObjType::Float); + // } else if(result_ffi_type == ctx->m_runtime->m_ffi_type_double) { + // return Obj::CreateValue(res_value.number, ObjType::Double); + // } else if(result_ffi_type == ctx->m_runtime->m_ffi_type_pointer) { + // if(type == ObjType::StrChar) { + // return Obj::CreateString(reinterpret_cast (res_value.ptr)); + // } else if(type == ObjType::StrWide) { + // return Obj::CreateString(reinterpret_cast (res_value.ptr)); + // } else if(type == ObjType::Pointer) { + // ObjPtr result = ctx->GetTypeFromString(m_func_proto->m_type_name); + // result->m_func_ptr = (void *) res_value.ptr; + // result->m_var_is_init = true; + // return result; + // } else { + // LOG_RUNTIME("Error result type '%s' or not implemented!", m_func_proto->m_type_name.c_str()); + // } + // } else { + // LOG_RUNTIME("Native return type '%s' not implemented!", m_func_proto->m_type_name.c_str()); + // } + // } + // + // LOG_RUNTIME("Fail native call '%s'!", toString().c_str()); + // + return Obj::CreateNone(); +} + bool newlang::ParsePrintfFormat(Obj *args, int start) { if(!args) { @@ -2051,6 +2542,7 @@ bool newlang::ParsePrintfFormat(Obj *args, int start) { } pos--; + ObjType test_type; ObjType cast = ObjType::None; switch(format[pos]) { @@ -2068,7 +2560,15 @@ bool newlang::ParsePrintfFormat(Obj *args, int start) { } else if(pos && format[pos - 1] == 'h') { cast = ObjType::Short; } - if(!canCast((*args)[aind].second->m_var_type_current, cast)) { + + if((*args)[aind].second->getType() == ObjType::Iterator) { + ASSERT((*args)[aind].second->m_iterator); + test_type = (*args)[aind].second->m_iterator->data().second->getType(); + } else { + test_type = (*args)[aind].second->m_var_type_current; + } + + if(!canCast(test_type, cast)) { LOG_WARNING("Cast '%s' to '%s' not supported!", newlang::toString((*args)[aind].second->m_var_type_current), newlang::toString(cast)); result = false; } @@ -2250,7 +2750,7 @@ void newlang::ConvertTensorToDict(const torch::Tensor &from, Obj &to, std::vecto * Dict -> Tensor */ void Obj::toType_(ObjType type) { - if(m_var_type_current == type) { + if(m_var_type_current == type || type == ObjType::Any || (is_string_char_type() && isString(type))) { return; } else if(type == ObjType::None) { clear_(); @@ -2429,7 +2929,7 @@ void Obj::toType_(ObjType type) { LOG_RUNTIME("Convert tensor to fraction support for scalar only!"); } if(is_integral()) { - m_fraction = std::make_shared(GetValueAsInteger()); + m_fraction = GetValueAsInteger(); m_var = at::monostate(); } else { LOG_RUNTIME("Convert value '%s' to fraction not implemented!", toString().c_str()); @@ -2600,8 +3100,17 @@ ObjPtr Obj::BaseTypeConstructor(const Context *ctx, Obj & args) { } else if(args[0].second->m_var_type_fixed == ObjType::Error || args[0].second->m_var_type_fixed == ObjType::ErrorParser || args[0].second->m_var_type_fixed == ObjType::ErrorRunTime || args[0].second->m_var_type_fixed == ObjType::ErrorSignal) { result = ConstructorError_(ctx, args); - } else { - + } else if(args[0].second->m_var_type_fixed == ObjType::StrChar && args.size() > 1) { + result = Obj::CreateString(""); + for (int i = 1; i < args.size(); i++) { + result->op_concat_(args[i].second, ConcatMode::Append); + } + } else if(args[0].second->m_var_type_fixed == ObjType::StrWide && args.size() > 1) { + result = Obj::CreateString(L""); + for (int i = 1; i < args.size(); i++) { + result->op_concat_(args[i].second, ConcatMode::Append); + } + } else if(args.size() == 1) { // Клонировать тип result = args[0].second->Clone(); if(result) { result->m_is_const = false; @@ -2768,6 +3277,15 @@ ObjPtr Obj::ConstructorNative_(const Context *ctx_const, Obj & args) { return ctx->CreateNative(args.at(1).second->GetValueAsString().c_str()); } +/* + * <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + * Различие между классом и словарям в том, что элементы словаря могут добавлятся и удаляться динамически, + * а у класса состав полей фиуксируется при определении и в последствии они не могут быть добалвены или удалены. + * Это нужно для возможности работы синтаксического анализатора на этапе компиляции программы. + * >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + * + */ + ObjPtr Obj::ConstructorClass_(const Context *ctx, Obj & args) { ObjPtr result = ConstructorDictionary_(ctx, args); result->m_var_type_fixed = ObjType::Class; @@ -2893,47 +3411,167 @@ const Iterator::IterPairType Iterator::m_interator_end = IterObj::pair template<> ObjPtr Iterator::read_and_next(int64_t count) { ObjPtr result; + static ObjPtr zero = Obj::CreateValue(0); if(count == 0) { - result = (*(*this)).second; - (*this)++; + if(m_iter_obj->m_var_type_current == ObjType::Range) { + + ObjPtr value = m_iter_obj->m_iter_range_value; + ObjPtr stop = m_iter_obj->at("stop").second; + ObjPtr step = m_iter_obj->at("step").second; + + ASSERT(value); + ASSERT(stop); + ASSERT(step); + + int up_direction = step->op_compare(*zero); + ASSERT(up_direction); + + if(up_direction < 0) { + if(value->op_compare(*stop) > 0) { + result = value->Clone(); + (*value) += step; + } else { + result = Iterator::m_interator_end.second->Clone(); + } + } else { + if(value->op_compare(*stop) < 0) { + result = value->Clone(); + (*value) += step; + } else { + result = Iterator::m_interator_end.second->Clone(); + } + } + + } else if(m_iter_obj->is_indexing()) { + result = (*(*this)).second; + (*this)++; + } else { + LOG_RUNTIME("Interator to type %s not implemented!", newlang::toString(m_iter_obj->m_var_type_current)); + } } else if(count < 0) { result = Obj::CreateDict(); - for (int64_t i = 0; i < -count; i++) { - if(*this != this->end()) { - result->push_back(*(*this)); - (*this)++; - } else { - result->push_back(Obj::CreateType(ObjType::IteratorEnd)); + result->m_var_is_init = true; + + if(m_iter_obj->m_var_type_current == ObjType::Range) { + + ObjPtr value = m_iter_obj->m_iter_range_value; + ObjPtr stop = m_iter_obj->at("stop").second; + ObjPtr step = m_iter_obj->at("step").second; + + ASSERT(value); + ASSERT(stop); + ASSERT(step); + + int up_direction = step->op_compare(*zero); + ASSERT(up_direction); + + bool next_value = true; + for (int64_t i = 0; i < -count; i++) { + + if(next_value) { + if(up_direction < 0) { + if(value->op_compare(*stop) < 0) { + next_value = false; + } else { + result->push_back(value->Clone()); + (*value) += step; + } + } else { + if(value->op_compare(*stop) > 0) { + next_value = false; + } else { + result->push_back(value->Clone()); + (*value) += step; + } + } + } else { + result->push_back(Obj::CreateType(ObjType::IteratorEnd)); + } } + + } else if(m_iter_obj->is_indexing()) { + + for (int64_t i = 0; i < -count; i++) { + if(*this != this->end()) { + result->push_back(*(*this)); + (*this)++; + } else { + result->push_back(Obj::CreateType(ObjType::IteratorEnd)); + } + } + + } else { + LOG_RUNTIME("Interator to type %s not implemented!", newlang::toString(m_iter_obj->m_var_type_current)); } } else { + result = Obj::CreateDict(); - while(*this != this->end() && result->size() < count) { - result->push_back(*(*this)); - (*this)++; + result->m_var_is_init = true; + + if(m_iter_obj->is_indexing()) { + while(*this != this->end() && result->size() < count) { + result->push_back(*(*this)); + (*this)++; + } + } else if(m_iter_obj->m_var_type_current == ObjType::Range) { + + ObjPtr value = m_iter_obj->m_iter_range_value; + ObjPtr stop = m_iter_obj->at("stop").second; + ObjPtr step = m_iter_obj->at("step").second; + + ASSERT(value); + ASSERT(stop); + ASSERT(step); + + int up_direction = step->op_compare(*zero); + ASSERT(up_direction); + + if(up_direction < 0) { + while(value->op_compare(*stop) > 0) { + result->push_back(value->Clone()); + (*value) += step; + } + } else { + while(value->op_compare(*stop) < 0) { + result->push_back(value->Clone()); + (*value) += step; + } + } + + m_iter_obj->m_iter_range_value = result->Clone(); + + } else { + LOG_RUNTIME("Interator to type %s not implemented!", newlang::toString(m_iter_obj->m_var_type_current)); } } + return result; } -ObjPtr Obj::MakeIterator(const std::string filter, bool check_create) { +ObjPtr Obj::IteratorMake(const std::string filter, bool check_create) { ObjPtr result = CreateType(ObjType::Iterator, ObjType::Iterator, true); - if(!is_indexing()) { + if(!(is_indexing() || m_var_type_current == ObjType::Range)) { if(getType() == ObjType::Iterator && !check_create) { return shared(); } LOG_RUNTIME("Can't create iterator from '%s'!", toString().c_str()); } result->m_iterator = std::make_shared> (shared(), filter); + ASSERT(result->m_iterator->m_iter_obj.get() == this); + ASSERT(!result->m_iterator->m_iter_obj->m_iter_range_value); + result->IteratorReset(); + if(is_range()) { + ASSERT(result->m_iterator->m_iter_obj->m_iter_range_value); + } return result; } -ObjPtr Obj::MakeIterator(Obj * args) { +ObjPtr Obj::IteratorMake(Obj * args) { ObjPtr result = CreateType(ObjType::Iterator, ObjType::Iterator, true); - if(!is_indexing()) { + if(!(is_indexing() || m_var_type_current == ObjType::Range)) { if(getType() == ObjType::Iterator) { return shared(); } @@ -2953,15 +3591,40 @@ ObjPtr Obj::MakeIterator(Obj * args) { } else { LOG_RUNTIME("Invalid arguments for iterator create! '%s'", args->toString().c_str()); } + ASSERT(result->m_iterator->m_iter_obj.get() == this); + ASSERT(!result->m_iterator->m_iter_obj->m_iter_range_value); + result->IteratorReset(); + if(is_range()) { + ASSERT(result->m_iterator->m_iter_obj->m_iter_range_value); + } return result; } +ObjPtr Obj::IteratorData() { + ASSERT(m_iterator); + if(m_iterator->m_iter_obj->is_range()) { + ASSERT(m_iterator->m_iter_obj->m_iter_range_value); + return m_iterator->m_iter_obj->m_iter_range_value->Clone(); + } else if(m_iterator->m_iter_obj->is_indexing()) { + return m_iterator->data().second; + } + LOG_RUNTIME("IteratorData not implemented for object type %s!", newlang::toString(m_iterator->m_iter_obj->m_var_type_current)); +} + ObjPtr Obj::IteratorReset() { if(m_var_type_current != ObjType::Iterator) { LOG_RUNTIME("Method available an iterator only!"); } ASSERT(m_iterator); - m_iterator->reset(); + + if(m_iterator->m_iter_obj->is_range()) { + ObjType summary_type = getSummaryTensorType(m_iterator->m_iter_obj.get(), ObjType::None); + m_iterator->m_iter_obj->m_iter_range_value = m_iterator->m_iter_obj->at("start").second->toType(summary_type); + } else if(m_iterator->m_iter_obj->is_indexing()) { + m_iterator->reset(); + } else { + LOG_RUNTIME("IteratorReset not implemented for object type %s!", newlang::toString(m_iterator->m_iter_obj->m_var_type_current)); + } return shared(); } diff --git a/src/object.h b/src/object.h index 6e22b80b..a83eb181 100644 --- a/src/object.h +++ b/src/object.h @@ -85,21 +85,67 @@ namespace newlang { * Требуется разделять конейнеры с данными и итераторы по данным. * В С++ контейнеры предоставялют итераторы непосредственно из самого контейнера. * Это удобно для использования в рукописном коде, но сложно контроллировать в генерируемом исходнике, - * т.к. требуется использовать и итертор и сам контейнер с данными (для сравнения с end()). + * т.к. требуется использовать и итертор и сам контейнер с данными (для сравнения текущего элемента с end()). * - * Логика работы с итераторами следующая. * Итератор - отдельный объект, которому для создания требуется контейнер с данными. - * Итератор два интерфейса перебора данных: - * 1. - первый интерфейс итератора как в С++ + * Итератор реализует два интерфейса перебора данных: + * 1. - первый интерфейс итератора как в С++ * 2. - второй интерфейс для использования в генерируемом коде с логикой NewLang * - * Разделение контейнера и итератора на два объекта позволит выполнять проверку на использование + * template Iterator - Обертка над классическим С++ итератором с добавлением возможности отбора + * элементов по имени поля или с помощь функции обратного вызова для пользовательской фильтрации. + * + * Программынй интерфейс итераторов для NewLang следующий: + * + * ObjPtr IteratorMake(const std::string filter) - создать итератор с возможностью фильтрации по имени поля (данные на начало) + * ObjPtr IteratorMake(Obj * args) - создать итератор с фильтрации с помощью пользовательской функции (данные на начало) + * ObjPtr IteratorReset() - Сбросить итератор на начало данных (возвращает сам итератор) + * ObjPtr IteratorData() - прочитать текущий элемент без смещения указателя. Если данных нет генерируется исключение "конец итератора" + * ObjPtr IteratorNext(int64_t count)- прочитать заданное кол-во элементов переместив указатель и вернуть словарь с ними. Если данных + * нет возвращается пустой словарь, а исключение "конец итератора" не генерируется + * + * Реализаиця итераторов NewLang с помощью данного интерфейса: + * + * Создание итератора + * ?, ?("Фильтр"), ?(func), ?(func, args...) - IteratorMake + * + * Перебор элементов итератора (IteratorData для ! без аргументов и IteratorNext в остальном случае) + * !, !(0), !(3), !(-3) + * + * dict! и dict!(0) <НЕ> эквивалентны, т.к. по разному обработывают конец данных + * dict! -> 1, dict! -> 2, dict! -> 3, dict! -> 4, dict! -> 5, dict! -> исключение "конец итератора" + * dict!(0) -> 1, dict!(0) -> 2, ... dict!(0) -> 5, dict!(0) -> :IteratorEnd (может :Empty - пустое значение ?? ) + * dict!(1) -> (1,), dict!(1) -> (2,), ... dict!(1) -> (5,), dict!(1) -> (,) + * + * Различия отрицательного размера возвращаемого словаря для итератора + * (Для отрцетельного размера всегда зозвращается словарь указанного размера) + * dict!(-1) -> (1,), ... dict!(-1) -> (5,), dict!(-1) -> (:IteratorEnd,), + * dict!(1) -> (1,), ... dict!(1) -> (5,), dict!(1) -> (,), + * dict!(-3) -> (1, 2, 3,), dict!(-3) -> (4, 5, :IteratorEnd,) + * dict!(3) -> (1, 2, 3,), dict!(3) -> (4, 5,) + * + * Операторы ?! и !? эквивалентны и возвращают текущие данные без перемещения указателя итератора (IteratorData) и не принимают аргументов. + * Остальные итераторы можно вызвать либо без скобок, либо с аргментами в скобрках. Вызов без аргументов зарпрешщен + * (чтобы не пересекаться с логикой копирования объектов и не делать для итераторов аругменты по умолчанию) + * + * Оператор ?? создает итератор и сразу его выполняет, возвращая все значения + * в виде элементов словаря, т.е. аналог последовательности ?(LINQ); !(:Long.__max__); + * + * Оператор !! без аргументов - сбрасывает итератор в начальное состояние (IteratorReset), + * Обператор !! с аргументами выполняется как ! с аругментами, но с начла коллекции. + * + * [ ] - оператор приведения данных в логический тип. Испольуется в алгоритмических конструкциях (проверка условий и циклы) + * Правила преобразования в логический тип: + * Словарь или класс - нет элементов - false, есть элементы - true + * Число - ноль или нулевой тензо - false, иначе true + * Строка - пустая строка false, иначе true + * Итератор - конец данных false, иначе true + * :IteratorEnd (:Empty ?) - всегда false + * None - true (Это объекст со значением пусто) + * Empty - false (Не инициализированный объект) * */ - - /* - * Итератор - */ + template class Iterator : public std::iterator { public: @@ -209,20 +255,28 @@ namespace newlang { return copy; } - inline const IterPairType &operator*() { + inline const IterPairType &data() { if (m_found == m_iter_obj->end()) { return m_interator_end; } return *m_found; } - inline const IterPairType &operator*() const { + inline const IterPairType &operator*() { + return data(); + } + + inline const IterPairType &data() const { if (m_found == m_iter_obj->end()) { return m_interator_end; } return *m_found; } + inline const IterPairType &operator*() const { + return data(); + } + ObjPtr read_and_next(int64_t count); const iterator &operator++() const { @@ -347,14 +401,15 @@ namespace newlang { return shared(); } - ObjPtr MakeIterator(const std::string, bool check_create = true); - ObjPtr MakeIterator(Obj *args); - ObjPtr IteratorReset(); + virtual ObjPtr IteratorMake(const std::string, bool check_create = true); + virtual ObjPtr IteratorMake(Obj *args); + virtual ObjPtr IteratorData(); + virtual ObjPtr IteratorReset(); + virtual ObjPtr IteratorNext(int64_t count); inline ObjPtr IteratorNext(ObjPtr count) { return IteratorNext(count->GetValueAsInteger()); } - ObjPtr IteratorNext(int64_t count); @@ -674,11 +729,17 @@ namespace newlang { } Obj::iterator begin() { - return Variable::begin(); + if (is_indexing() || m_var_type_current == ObjType::Range) { + return Variable::begin(); + } + LOG_RUNTIME("Interator for object type %s not implemented!", newlang::toString(m_var_type_current)); } Obj::iterator end() { - return Variable::end(); + if (is_indexing() || m_var_type_current == ObjType::Range) { + return Variable::end(); + } + LOG_RUNTIME("Interator for object type %s not implemented!", newlang::toString(m_var_type_current)); } Obj::const_iterator begin() const { @@ -736,7 +797,7 @@ namespace newlang { m_class_parents.clear(); m_var_is_init = false; m_tensor.reset(); - m_fraction.reset(); + m_fraction.set_(0); m_var = at::monostate(); // m_value.reset(); //???????????????? // m_items.clear(); @@ -1074,7 +1135,9 @@ namespace newlang { inline ObjPtr operator*=(ObjPtr obj) { - ASSERT(obj); + if (!obj) { + ASSERT(obj); + } return operator*=(*obj); } @@ -1219,6 +1282,18 @@ namespace newlang { return utf8_decode(GetValueAsString()); } + std::shared_ptr GetValueAsFraction() const { + TEST_INIT_(); + if (m_var_type_current == ObjType::Fraction) { + return m_fraction.clone(); + } else if (is_integral()) { + return std::make_shared(GetValueAsInteger()); + } else if (is_floating()) { + ASSERT("Not implemented!"); + } + LOG_RUNTIME("Value %s incompatible to Fraction or convert not implemented!", toString().c_str()); + } + int64_t GetValueAsInteger() const { TEST_INIT_(); @@ -1263,11 +1338,10 @@ namespace newlang { case ObjType::Float: case ObjType::Double: case ObjType::Number: - return static_cast(GetValueAsNumber()); + return static_cast (GetValueAsNumber()); case ObjType::Fraction: - ASSERT(m_fraction); - return m_fraction->GetAsInteger(); + return m_fraction.GetAsInteger(); case ObjType::StrWide: case ObjType::FmtWide: @@ -1279,14 +1353,18 @@ namespace newlang { if (m_value.size() == 1) { return m_value[0]; } + + case ObjType::Iterator: + ASSERT(m_iterator); + return m_iterator->data().second->GetValueAsInteger(); + default: if (m_var_type_current == ObjType::Pointer || m_var_type_fixed == ObjType::Pointer) { ASSERT(at::holds_alternative(m_var)); return reinterpret_cast (at::get(m_var)); } - LOG_RUNTIME("Data type incompatible %s", toString().c_str()); } - return 0; + LOG_RUNTIME("Data type incompatible %s", toString().c_str()); } inline double GetValueAsNumber() const { @@ -1316,8 +1394,11 @@ namespace newlang { LOG_RUNTIME("Can`t convert tensor to scalar!"); case ObjType::Fraction: - ASSERT(m_fraction); - return m_fraction->GetAsNumber(); + return m_fraction.GetAsNumber(); + + case ObjType::Iterator: + ASSERT(m_iterator); + return m_iterator->data().second->GetValueAsNumber(); default: if (is_simple() || is_string_type()) { @@ -1347,8 +1428,7 @@ namespace newlang { return false; case ObjType::Fraction: - ASSERT(m_fraction); - return m_fraction->GetAsInteger(); + return m_fraction.GetAsInteger(); case ObjType::Dictionary: case ObjType::Class: @@ -1362,6 +1442,20 @@ namespace newlang { } return false; + case ObjType::Iterator: + ASSERT(m_iterator); + ASSERT(m_iterator->m_iter_obj); + if (m_iterator->m_iter_obj->getType() == ObjType::Range) { + if (m_iterator->m_iter_obj->m_iter_range_value && m_iterator->m_iter_obj->m_iter_range_value->m_var_type_current != ObjType::IteratorEnd) { + return true; + } + } else { + if ((*m_iterator) != m_iterator->end()) { + return m_iterator->data().second->GetValueAsBoolean(); + } + } + return false; + default: LOG_RUNTIME("Type cast to bool %s", toString().c_str()); } @@ -1383,6 +1477,7 @@ namespace newlang { } } else if (type == LLVMPointerType(LLVMInt32Type(), 0)) { if (getType() == ObjType::StrWide || getType() == ObjType::FmtWide) { + return LLVMCreateGenericValueOfPointer((void *) m_string.c_str()); } } @@ -1422,8 +1517,8 @@ namespace newlang { LOG_RUNTIME("Create to type '%s' form LLVM type not implemented!", newlang::toString(type)); } - static ObjPtr CreateType(ObjType type, ObjType fixed = ObjType::None, bool is_init = false) { + return std::make_shared(type, nullptr, nullptr, fixed, is_init); } @@ -1443,20 +1538,21 @@ namespace newlang { // Если символ не найден - то вся строка является числом if (pos == std::string::npos) { - frac->m_fraction = std::make_shared(str, "1"); + frac->m_fraction.set_(0); } else { // Числитель - левая часть // Знаменатель - правая часть - frac->m_fraction = std::make_shared(str.substr(0, pos), str.substr(pos + 1, str.length())); + frac->m_fraction.set_(str.substr(0, pos), str.substr(pos + 1, str.length())); // Знаменатель не должен быть равен нулю - if (frac->m_fraction->m_denominator.isZero()) { + if (frac->m_fraction.m_denominator.isZero()) { LOG_RUNTIME("Denominator must be different from zero!"); } } frac->m_var_is_init = true; - if (str.compare(frac->m_fraction->GetAsString().c_str()) != 0) { - LOG_RUNTIME("Fraction value '%s' does not match source string '%s'!", frac->m_fraction->GetAsString().c_str(), str.c_str()); + if (str.compare(frac->m_fraction.GetAsString().c_str()) != 0) { + + LOG_RUNTIME("Fraction value '%s' does not match source string '%s'!", frac->m_fraction.GetAsString().c_str(), str.c_str()); } return frac; @@ -1479,6 +1575,7 @@ namespace newlang { static ObjPtr CreateBaseType(ObjType type); static ObjPtr CreateNone() { + return CreateType(ObjType::None, ObjType::None, true); } @@ -1489,6 +1586,7 @@ namespace newlang { obj->push_back(CreateValue(stop, ObjType::None), "stop"); obj->push_back(CreateValue(step, ObjType::None), "step"); obj->m_var_is_init = true; + return obj; } @@ -1503,6 +1601,7 @@ namespace newlang { obj->push_back(CreateValue(-1, ObjType::None), "step"); } obj->m_var_is_init = true; + return obj; } @@ -1532,6 +1631,7 @@ namespace newlang { case at::ScalarType::ComplexHalf: case at::ScalarType::ComplexFloat: return ObjType::ComplexFloat; + case at::ScalarType::ComplexDouble: return ObjType::ComplexDouble; } @@ -1541,6 +1641,7 @@ namespace newlang { static ObjPtr CreateBool(bool value) { ObjPtr result = CreateType(ObjType::Bool, ObjType::None, true); result->SetValue_(value); + return result; } @@ -1558,6 +1659,7 @@ namespace newlang { result = Obj::CreateValue(tensor.item(), check_type); } } else { + result = CreateType(check_type); result->m_tensor = tensor; result->m_var_is_init = true; @@ -1633,20 +1735,22 @@ namespace newlang { } else if (is_ellipsis()) { return Index(at::indexing::Ellipsis); } else if (is_range()) { + return Index(toSlice()); } LOG_RUNTIME("Fail convert object '%s' to Index!", toString().c_str()); } inline operator bool () const { + return GetValueAsBoolean(); } - std::vector toIntVector(bool raise = true) const { std::vector result; for (int i = 0; i < size(); i++) { if (raise && !at(i).second->is_integer()) { + LOG_RUNTIME("Item does not contain an integer value! '%s'", at(i).second->GetValueAsString().c_str()); } result.push_back(at(i).second->GetValueAsInteger()); @@ -1654,7 +1758,6 @@ namespace newlang { return result; } - template typename std::enable_if::value, ObjPtr>::type static CreateValue(T value, ObjType fix_type = ObjType::None) { @@ -1668,6 +1771,7 @@ namespace newlang { result->m_var = static_cast (value); // result->m_tensor = torch::scalar_tensor(value, toTorchType(result->m_var_type_current)); result->m_var_is_init = true; + return result; } @@ -1684,6 +1788,7 @@ namespace newlang { result->m_var = static_cast (value); //result->m_tensor = torch::scalar_tensor(value, toTorchType(result->m_var_type_current)); result->m_var_is_init = true; + return result; } @@ -1692,6 +1797,7 @@ namespace newlang { result->m_value = str; result->m_var_type_fixed = ObjType::String; result->m_var_is_init = true; + return result; } @@ -1700,6 +1806,7 @@ namespace newlang { result->m_string = str; result->m_var_type_fixed = ObjType::String; result->m_var_is_init = true; + return result; } @@ -1707,6 +1814,7 @@ namespace newlang { ObjPtr result = std::make_shared(ObjType::Bool); result->m_var = static_cast (1); result->m_var_is_init = true; + return result->MakeConst(); } @@ -1714,10 +1822,12 @@ namespace newlang { ObjPtr result = std::make_shared(ObjType::Bool); result->m_var = static_cast (0); result->m_var_is_init = true; + return result->MakeConst(); } inline static ObjPtr CreateDict() { + return Obj::CreateType(ObjType::Dictionary); } @@ -1730,13 +1840,22 @@ namespace newlang { result->push_back(elem); } result->m_var_is_init = true; + return result; } + /* + * <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + * Различие между классом и словарям в том, что элементы словаря могут добавлятся и удаляться динамически, + * а у класса состав полей фиуксируется при определении и в последствии они не могут быть добалвены или удалены. + * >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + * + */ inline static ObjPtr CreateClass(std::string name) { ObjPtr result = Obj::CreateType(ObjType::Class); result->m_class_name = name; result->m_var_is_init = true; + return result; } @@ -1750,6 +1869,7 @@ namespace newlang { result->push_back(elem); } result->m_var_is_init = true; + return result; } @@ -1761,6 +1881,7 @@ namespace newlang { CloneDataTo(*clone); ClonePropTo(*clone); if (new_name) { + clone->m_var_name = new_name; } return clone; @@ -1769,6 +1890,7 @@ namespace newlang { inline void CloneTo(Obj & clone) { if (&clone == this) { // Не клонировать сам в себя + return; } CloneDataTo(clone); @@ -1778,6 +1900,7 @@ namespace newlang { inline void CloneTo(ObjPtr & clone) { if (clone.get() == this) { // Не клонировать сам в себя + return; } clone.reset(); @@ -1792,6 +1915,7 @@ namespace newlang { inline ObjPtr toType(ObjType type) const { ObjPtr clone = Clone(); clone->toType_(type); + return clone; } @@ -1806,6 +1930,7 @@ namespace newlang { void toType_(ObjType type); virtual ~Obj() { + clear_(); } @@ -1815,11 +1940,13 @@ namespace newlang { inline ObjPtr index_set(const std::vector & index, const ObjPtr value) const { ObjPtr result = Clone(); result->index_set_(index, value); + return result; } ObjPtr index_set_(const std::vector & index, const ObjPtr value); inline ObjPtr op_set_index(ObjPtr index, ObjPtr value) { + return op_set_index(index->GetValueAsInteger(), value->GetValueAsString()); } ObjPtr op_set_index(int64_t index, std::string value); @@ -1827,12 +1954,14 @@ namespace newlang { template < typename T> typename std::enable_if::value, void>::type SetValue_(bool value) { + SetValue_(static_cast (value)); } template < typename T> typename std::enable_if::value, void>::type SetValue_(T value) { + TEST_CONST_(); ASSERT(m_var_type_current != ObjType::Class); clear_(); @@ -1856,6 +1985,7 @@ namespace newlang { template < typename T> typename std::enable_if::value, void>::type SetValue_(T text) { + std::string str(text); SetValue_(text); } @@ -1863,6 +1993,7 @@ namespace newlang { template < typename T> typename std::enable_if::value, void>::type SetValue_(T text) { + std::wstring str(text); SetValue_(text); } @@ -1870,6 +2001,7 @@ namespace newlang { void SetValue_(std::string text) { TEST_CONST_(); if (m_var_type_current != ObjType::StrChar) { + testConvertType(ObjType::StrChar); m_var_type_current = ObjType::StrChar; } @@ -1880,6 +2012,7 @@ namespace newlang { void SetValue_(std::wstring text) { TEST_CONST_(); if (m_var_type_current != ObjType::StrWide) { + testConvertType(ObjType::StrWide); m_var_type_current = ObjType::StrWide; } @@ -1889,6 +2022,7 @@ namespace newlang { inline void testConvertType(ObjType type) { if (m_var_type_fixed == ObjType::None || canCast(type, m_var_type_fixed)) { + return; } LOG_RUNTIME("Cannot changed type from '%s' to '%s'!", newlang::toString(type), newlang::toString(m_var_type_fixed)); @@ -1922,6 +2056,7 @@ namespace newlang { (isIntegralType(new_type, true) && isIntegralType(m_var_type_current, true))); } } else { + ASSERT(m_tensor.defined()); m_tensor = m_tensor.toType(toTorchType(new_type)); } @@ -1986,7 +2121,7 @@ namespace newlang { m_var = value->GetValueAsInteger(); } else if (at::holds_alternative(m_var)) { ASSERT(at::get(m_var)); - *at::get(m_var) = static_cast(value->GetValueAsInteger()); + *at::get(m_var) = static_cast (value->GetValueAsInteger()); } break; case ObjType::Short: @@ -1994,7 +2129,7 @@ namespace newlang { m_var = value->GetValueAsInteger(); } else if (at::holds_alternative(m_var)) { ASSERT(at::get(m_var)); - *at::get(m_var) = static_cast(value->GetValueAsInteger()); + *at::get(m_var) = static_cast (value->GetValueAsInteger()); } break; case ObjType::Int: @@ -2002,7 +2137,7 @@ namespace newlang { m_var = value->GetValueAsInteger(); } else if (at::holds_alternative(m_var)) { ASSERT(at::get(m_var)); - *at::get(m_var) = static_cast(value->GetValueAsInteger()); + *at::get(m_var) = static_cast (value->GetValueAsInteger()); } break; case ObjType::Long: @@ -2018,7 +2153,7 @@ namespace newlang { m_var = value->GetValueAsNumber(); } else if (at::holds_alternative(m_var)) { ASSERT(at::get(m_var)); - *at::get(m_var) = static_cast(value->GetValueAsNumber()); + *at::get(m_var) = static_cast (value->GetValueAsNumber()); } break; case ObjType::Double: @@ -2075,7 +2210,7 @@ namespace newlang { return; } - } else if (is_none_type() || isObjectType(m_var_type_current)) { + } else if ((is_none_type() || is_dictionary_type()) && (value->is_dictionary_type() || value->getType() == ObjType::Iterator)) { std::string old_name = m_var_name; clear_(); @@ -2103,8 +2238,20 @@ namespace newlang { value->ClonePropTo(*this); m_var_name.swap(old_name); m_var_is_init = true; + return; + } else if ((is_none_type() && value->getType() == ObjType::Fraction) || ((m_var_type_current == ObjType::Fraction) && value->is_arithmetic_type())) { + + if (is_none_type()) { + m_fraction = *value->GetValueAsFraction(); + m_var_is_init = true; + } else { + m_fraction.set_(*value->GetValueAsFraction()); + } + m_var = at::monostate(); + m_var_type_current = ObjType::Fraction; return; + } else if ((is_none_type() || m_var_type_current == ObjType::Function || m_var_type_current == ObjType::EVAL_FUNCTION) && (value->m_var_type_current == ObjType::BLOCK || value->m_var_type_current == ObjType::BLOCK_TRY)) { //@todo Check function type args !!! @@ -2115,9 +2262,9 @@ namespace newlang { // value->CloneDataTo(*this); // value->ClonePropTo(*this); // m_var_name.swap(old_name); - // m_var_is_init = true; // *const_cast (&m_func_proto) = save_proto; m_sequence = value->m_sequence; + m_var_is_init = value->m_var_is_init; // m_var_type_current = save_type; return; @@ -2198,8 +2345,9 @@ namespace newlang { std::string m_value; ///< Содержит байтовую строку или байтовый массив с данными для представления в нативном виде (Struct, Unuion, Enum) std::wstring m_string; ///< Содержит строку широких символов torch::Tensor m_tensor; ///< Содержит только размерные тензоры (скляры хранятся в поле m_pointer и не создают m_tensor.defined()) - std::shared_ptr m_fraction; ///< Содержит дробь из длинных чисел - std::shared_ptr< Iterator > m_iterator; ///< Итератор для данных + Fraction m_fraction; ///< Содержит дробь из длинных чисел + std::shared_ptr> m_iterator; ///< Итератор для данных + mutable ObjPtr m_iter_range_value; TermPtr m_sequence; ///< Последовательно распарсенных команд для выполнения const TermPtr m_prototype; ///< Описание прототипп функции (или данных) diff --git a/src/parser.y b/src/parser.y index 7040766b..7713a9b1 100644 --- a/src/parser.y +++ b/src/parser.y @@ -551,19 +551,14 @@ digits: digits_literal -range_val: rval_name +range_val: rval_range { $$ = $1; } - | digits - { - $$ = $1; - } -/* | '-' digits + | '(' arithmetic ')' { $$ = $2; - $$->m_text.insert(0,"-"); - } */ + } range: range_val RANGE range_val @@ -765,21 +760,21 @@ rval_name: lval } */ - -rval_var: rval_name +rval_range: rval_name { $$ = $1; } - | rval_name iter_all + | digits { - $$ = $2; - $$->Last()->Append($1, Term::LEFT); + $$ = $1; } | string { $$ = $1; } - | digits + + +rval_var: rval_range { $$ = $1; } @@ -804,35 +799,40 @@ rval: rval_var } -iter_call: '?' +iter: '?' { $$=$1; $$->SetTermID(TermID::ITERATOR); } - | ITERATOR /* ?! ?! */ + | '!' { $$=$1; + $$->SetTermID(TermID::ITERATOR); } - - -iter_all: '!' + | ITERATOR /* !! ?? */ { $$=$1; - $$->SetTermID(TermID::ITERATOR); } - | ITERATOR_QQ /* !! ?? */ + +iter_call: iter '(' args ')' + { + $$ = $1; + $$->SetArgs($args); + } + + +iter_all: ITERATOR_QQ /* !? ?! */ { $$=$1; $$->SetTermID(TermID::ITERATOR); } - | iter_call + | iter { $$=$1; } - | iter_call call + | iter_call { $$=$1; - $$->SetArgs($call); } @@ -867,18 +867,18 @@ arg: arg_name '=' $$->m_name.swap($1->m_text); $$->SetTermID(TermID::EMPTY); } - | arg_name '=' rval + | arg_name '=' logical { // Именованный аргумент - $$ = $rval; + $$ = $3; $$->SetName($1->getText()); } - | name type '=' rval + | name type '=' logical { // Именованный аргумент - $$ = $rval; + $$ = $4; $$->SetType($type); $$->SetName($1->getText()); } - | rval + | logical { // сюда попадают и именованные аргументы как операция присвоения значения $$ = $1; @@ -888,25 +888,25 @@ arg: arg_name '=' // Раскрыть элементы словаря в последовательность не именованных параметров $$ = $1; } - | ELLIPSIS rval + | ELLIPSIS logical { // Раскрыть элементы словаря в последовательность не именованных параметров $$ = $1; - $$->Append($rval, Term::RIGHT); + $$->Append($2, Term::RIGHT); } - | ELLIPSIS ELLIPSIS rval + | ELLIPSIS ELLIPSIS logical { // Раскрыть элементы словаря в последовательность ИМЕНОВАННЫХ параметров $$ = $2; $$->Append($1, Term::LEFT); - $$->Append($rval, Term::RIGHT); + $$->Append($3, Term::RIGHT); } - | ELLIPSIS rval ELLIPSIS + | ELLIPSIS logical ELLIPSIS { // Заполнить данные значением $$ = $1; $$->SetTermID(TermID::FILLING); - $$->Append($rval, Term::RIGHT); + $$->Append($2, Term::RIGHT); } args: arg @@ -1245,6 +1245,12 @@ block_call: '(' MIDDLE_CALL_BLOCK sequence '}' * Операции присвоения используют lvalue, многоточие или определение функций * Алгоритмы используют eval или блок кода (у matching) */ + +/* + * -> + | - | + * -> * | / | + * -> vars | ( ) + */ operator: OPERATOR { @@ -1257,11 +1263,7 @@ operator: OPERATOR } -arithmetic: addition - { - $$ = $1; - } - | arithmetic '+' addition +arithmetic: arithmetic '+' addition { $$ = $2; $$->SetTermID(TermID::OPERATOR); @@ -1275,18 +1277,21 @@ arithmetic: addition $$->Append($1, Term::LEFT); $$->Append($3, Term::RIGHT); } - | '-' addition /* %prec NEG */ - { - $$ = $2; - } - | digits digits + | addition digits { + if($digits->m_text[0] != '-') { + NL_PARSER($digits, "Missing operator!"); + } //@todo location - $$ = Term::Create(TermID::OPERATOR, $2->m_text.c_str(), 1, nullptr); + $$ = Term::Create(TermID::OPERATOR, $2->m_text.c_str(), 1, & @$); $$->Append($1, Term::LEFT); $2->m_text = $2->m_text.substr(1); $$->Append($2, Term::RIGHT); } + | addition + { + $$ = $1; + } op_factor: '*' @@ -1306,63 +1311,37 @@ op_factor: '*' $$ = $1; } -addition: addition op_factor factor +addition: addition op_factor factor { - - if($op_factor->m_text.compare("/")==0 && $factor->m_text.compare("1")==0) { - // throw syntax_error(yyla.location, + if($1->getTermID() == TermID::INTEGER && $op_factor->m_text.compare("/")==0 && $3->m_text.compare("1")==0) { NL_PARSER($op_factor, "Do not use division by one (e.g. 123/1), " "as this operation does not make sense, but it is easy to " "confuse it with the notation of a fraction literal (123\\1)."); } - $$ = $2; + $$ = $op_factor; $$->SetTermID(TermID::OPERATOR); $$->Append($1, Term::LEFT); $$->Append($3, Term::RIGHT); } -/* | '-' addition %prec NEG - { - $$ = $2; - } */ - -/* | digits digits op_factor factor - { -#warning PRIORITET OP - //@todo location - TermPtr temp = Term::Create(TermID::OPERATOR, $2->m_text.c_str(), 1, nullptr); - temp->Append($1, Term::LEFT); - $2->m_text = $2->m_text.substr(1); - temp->Append($2, Term::RIGHT); - - $$ = $3; - $$->SetTermID(TermID::OPERATOR); - $$->Append(temp, Term::LEFT); - $$->Append($4, Term::RIGHT); - } */ - | sfactor + | factor { $$ = $1; } - - -sfactor: factor - { - $$ = $1; - } factor: rval_var { $$ = $1; } - | '(' arithmetic ')' + | '-' factor { - $$ = $2; + $$ = Term::Create(TermID::OPERATOR, "-", 1, & @$); + $$->Append($2, Term::RIGHT); } -/* | '-' rval %prec NEG + | '(' arithmetic ')' { $$ = $2; - } */ + } @@ -1390,16 +1369,28 @@ logical: arithmetic { $$ = $1; } - | arithmetic operator arithmetic + | logical operator arithmetic { $$ = $2; $$->Append($1, Term::LEFT); $$->Append($3, Term::RIGHT); } + | arithmetic iter_all + { + $$ = $2; + $$->Last()->Append($1, Term::LEFT); + } + | logical operator arithmetic iter_all + { + $$ = $2; + $$->Append($1, Term::LEFT); + $iter_all->Last()->Append($arithmetic, Term::LEFT); + $$->Append($iter_all, Term::RIGHT); + } - + match_cond: '[' condition ']' { $$ = $condition; @@ -1572,10 +1563,10 @@ ast: END { driver.AstAddTerm($1); } -/* | comment - { - driver.AstAddTerm($1); - } */ +/* | comment Комменатарии не добавляются в AST, т.к. в парсере они не нужны, а + их потенциальное использование - документирование кода, решается + в Python стиле (первый текстовый литерал в коде) +*/ start : ast diff --git a/src/term.h b/src/term.h index 7e39ff77..ffd8d8c3 100644 --- a/src/term.h +++ b/src/term.h @@ -618,7 +618,9 @@ namespace newlang { return result; case TermID::OPERATOR: + result += " "; result += m_text; + result += " "; if (m_right) { result += m_right->toString(); } diff --git a/src/test/eval_test.cpp b/src/test/eval_test.cpp index 47047006..efbd2fda 100644 --- a/src/test/eval_test.cpp +++ b/src/test/eval_test.cpp @@ -1003,7 +1003,7 @@ TEST(Eval, Iterator) { ASSERT_STREQ("", dict->at(3).first.c_str()); ASSERT_STREQ("555", dict->at(4).first.c_str()); - ObjPtr dict1 = ctx.ExecStr("dict?!"); + ObjPtr dict1 = ctx.ExecStr("dict??"); ASSERT_TRUE(dict1); ASSERT_EQ(5, dict1->size()); ASSERT_EQ(1, dict1->at(0).second->GetValueAsInteger()); @@ -1057,24 +1057,24 @@ TEST(Eval, Iterator) { ASSERT_TRUE(*(iter->m_iterator) == iter->m_iterator->end()); - ctx.ExecStr("iter??"); - ASSERT_TRUE(*(iter->m_iterator) == iter->m_iterator->begin()); + ctx.ExecStr("iter!!"); + ASSERT_TRUE(*(iter->m_iterator) != iter->m_iterator->end()); - dict1 = ctx.ExecStr("iter!?(-3)"); + dict1 = ctx.ExecStr("iter??(-3)"); ASSERT_TRUE(dict1); ASSERT_EQ(3, dict1->size()); ASSERT_EQ(1, dict1->at(0).second->GetValueAsInteger()); ASSERT_EQ(2, dict1->at(1).second->GetValueAsInteger()); ASSERT_EQ(3, dict1->at(2).second->GetValueAsInteger()); - ObjPtr dict2 = ctx.ExecStr("iter!?(-3)"); + ObjPtr dict2 = ctx.ExecStr("iter??(-3)"); ASSERT_TRUE(dict2); ASSERT_EQ(3, dict2->size()); ASSERT_EQ(4, dict2->at(0).second->GetValueAsInteger()); ASSERT_EQ(5, dict2->at(1).second->GetValueAsInteger()); ASSERT_EQ(ObjType::IteratorEnd, dict2->at(2).second->getType()); - ObjPtr dict3 = ctx.ExecStr("iter!?(-3)"); + ObjPtr dict3 = ctx.ExecStr("iter??(-3)"); ASSERT_TRUE(dict3); ASSERT_EQ(3, dict1->size()); ASSERT_EQ(ObjType::IteratorEnd, dict3->at(0).second->getType()); @@ -1084,55 +1084,137 @@ TEST(Eval, Iterator) { ASSERT_TRUE(*(iter->m_iterator) == iter->m_iterator->end()); - ctx.ExecStr("iter??"); - ASSERT_TRUE(*(iter->m_iterator) == iter->m_iterator->begin()); + ctx.ExecStr("iter!!"); + ASSERT_TRUE(*(iter->m_iterator) != iter->m_iterator->end()); - dict1 = ctx.ExecStr("iter!?(3)"); + dict1 = ctx.ExecStr("iter??(3)"); ASSERT_TRUE(dict1); ASSERT_EQ(3, dict1->size()); ASSERT_EQ(1, dict1->at(0).second->GetValueAsInteger()); ASSERT_EQ(2, dict1->at(1).second->GetValueAsInteger()); ASSERT_EQ(3, dict1->at(2).second->GetValueAsInteger()); - dict2 = ctx.ExecStr("iter!?(3)"); + dict2 = ctx.ExecStr("iter??(3)"); ASSERT_TRUE(dict2); ASSERT_EQ(2, dict2->size()); ASSERT_EQ(4, dict2->at(0).second->GetValueAsInteger()); ASSERT_EQ(5, dict2->at(1).second->GetValueAsInteger()); - dict3 = ctx.ExecStr("iter!?(3)"); + dict3 = ctx.ExecStr("iter??(3)"); ASSERT_TRUE(dict3); ASSERT_EQ(0, dict3->size()); ASSERT_TRUE(*(iter->m_iterator) == iter->m_iterator->end()); - ctx.ExecStr("iter??"); - ASSERT_TRUE(*(iter->m_iterator) == iter->m_iterator->begin()); + ctx.ExecStr("iter!!"); + ASSERT_TRUE(*(iter->m_iterator) != iter->m_iterator->end()); - ObjPtr flt_res = ctx.ExecStr("dict!?('')"); + ObjPtr flt_res = ctx.ExecStr("dict??('')"); ASSERT_TRUE(flt_res); ASSERT_EQ(1, flt_res->size()); ASSERT_EQ(4, flt_res->at(0).second->GetValueAsInteger()); - ObjPtr flt1_res = ctx.ExecStr("dict!?('.',100)"); + ObjPtr flt1_res = ctx.ExecStr("dict??('.',100)"); ASSERT_TRUE(flt1_res); ASSERT_EQ(1, flt1_res->size()); ASSERT_EQ(1, flt1_res->at(0).second->GetValueAsInteger()); - ObjPtr flt2_res = ctx.ExecStr("dict!?('..',100)"); + ObjPtr flt2_res = ctx.ExecStr("dict??('..',100)"); ASSERT_TRUE(flt2_res); ASSERT_EQ(1, flt2_res->size()); ASSERT_EQ(2, flt2_res->at(0).second->GetValueAsInteger()); - ObjPtr flt3_res = ctx.ExecStr("dict!?('...',100)"); + ObjPtr flt3_res = ctx.ExecStr("dict??('...',100)"); ASSERT_TRUE(flt3_res); ASSERT_EQ(2, flt3_res->size()); ASSERT_EQ(3, flt3_res->at(0).second->GetValueAsInteger()); ASSERT_EQ(5, flt3_res->at(1).second->GetValueAsInteger()); + + + ObjPtr range_test = ctx.ExecStr("1\\1..1..-1", nullptr, true); + ASSERT_TRUE(range_test); + ASSERT_EQ(3, range_test->size()); + ASSERT_STREQ("1\\1", range_test->at(0).second->GetValueAsString().c_str()); + ASSERT_STREQ("1", range_test->at(1).second->GetValueAsString().c_str()); + ASSERT_STREQ("-1", range_test->at(2).second->GetValueAsString().c_str()); + ASSERT_STREQ("1\\1..1..-1", range_test->GetValueAsString().c_str()); + + // ObjPtr iter_test = ctx.ExecStr("(1,'sss',(,),2,3,)??", nullptr, true); + // ASSERT_TRUE(iter_test); + // ASSERT_STREQ("(1, 'sss', (,), 2, 3,)", iter_test->GetValueAsString().c_str()); + + ObjPtr iter_dict = ctx.ExecStr("1..1..(-1)??", nullptr, true); + ASSERT_TRUE(iter_dict); + ASSERT_STREQ("(,)", iter_dict->GetValueAsString().c_str()); + + iter_dict = ctx.ExecStr("2..1..(-1)??", nullptr, true); + ASSERT_TRUE(iter_dict); + ASSERT_STREQ("(2,)", iter_dict->GetValueAsString().c_str()); + + iter_dict = ctx.ExecStr("3..1..(-1)??", nullptr, true); + ASSERT_TRUE(iter_dict); + ASSERT_STREQ("(3, 2,)", iter_dict->GetValueAsString().c_str()); + + iter_dict = ctx.ExecStr("3\\1..1..(-1)??", nullptr, true); + ASSERT_TRUE(iter_dict); + ASSERT_STREQ("(3\\1, 2\\1,)", iter_dict->GetValueAsString().c_str()); + + ObjPtr iter_test = ctx.ExecStr("@iter_test := 3\\1..1..-1?", nullptr, true); + ASSERT_TRUE(iter_test); + ASSERT_TRUE(iter_test->m_iterator->m_iter_obj->m_iter_range_value); + ASSERT_STREQ("3\\1", iter_test->m_iterator->m_iter_obj->m_iter_range_value->GetValueAsString().c_str()) << iter_test->m_iterator->m_iter_obj->m_iter_range_value->GetValueAsString().c_str(); + ASSERT_EQ(iter_test->getType(), ObjType::Iterator); + + ObjPtr while_test = ctx.ExecStr("[iter_test]<<-->>{--'EXIT'--}", nullptr, true); + ASSERT_TRUE(while_test); + ASSERT_STREQ("EXIT", while_test->GetValueAsString().c_str()) << while_test->GetValueAsString().c_str(); + + iter_test = ctx.ExecStr("@iter_dict := (1,2,3,)?", nullptr, true); + ASSERT_TRUE(iter_test); +// ASSERT_TRUE(iter_test->m_iterator->m_iter_obj->m_iter_range_value); +// ASSERT_STREQ("3\\1", iter_test->m_iterator->m_iter_obj->m_iter_range_value->GetValueAsString().c_str()) << iter_test->m_iterator->m_iter_obj->m_iter_range_value->GetValueAsString().c_str(); + ASSERT_EQ(iter_test->getType(), ObjType::Iterator); + + while_test = ctx.ExecStr("[iter_dict]<<-->>{--'EXIT'--}", nullptr, true); + ASSERT_TRUE(while_test); + ASSERT_STREQ("EXIT", while_test->GetValueAsString().c_str()) << while_test->GetValueAsString().c_str(); + + iter_test = ctx.ExecStr("iter_test!?", nullptr, true); + ASSERT_TRUE(iter_test); + ASSERT_STREQ("3\\1", iter_test->GetValueAsString().c_str()); + + iter_test = ctx.ExecStr("iter_test!", nullptr, true); + ASSERT_TRUE(iter_test); + ASSERT_STREQ("3\\1", iter_test->GetValueAsString().c_str()); + + iter_test = ctx.ExecStr("iter_test!?", nullptr, true); + ASSERT_TRUE(iter_test); + ASSERT_STREQ("2\\1", iter_test->GetValueAsString().c_str()); + + iter_test = ctx.ExecStr("iter_test?!", nullptr, true); + ASSERT_TRUE(iter_test); + ASSERT_STREQ("2\\1", iter_test->GetValueAsString().c_str()); + + iter_test = ctx.ExecStr("iter_test!", nullptr, true); + ASSERT_TRUE(iter_test); + ASSERT_STREQ("2\\1", iter_test->GetValueAsString().c_str()); + + iter_test = ctx.ExecStr("iter_test!", nullptr, true); + ASSERT_TRUE(iter_test); + ASSERT_STREQ(":IteratorEnd", iter_test->GetValueAsString().c_str()); + + iter_test = ctx.ExecStr("iter_test", nullptr, true); + ASSERT_TRUE(iter_test); + ASSERT_STREQ(":Iterator", iter_test->GetValueAsString().c_str()); + + while_test = ctx.ExecStr("[iter_test]<<-->>{--'EXIT'--}", nullptr, true); + ASSERT_TRUE(while_test); + ASSERT_STRNE("EXIT", while_test->GetValueAsString().c_str()) << while_test->GetValueAsString().c_str(); + } //TEST(Eval, Brother) { diff --git a/src/test/speed_test.cpp b/src/test/example_test.cpp similarity index 66% rename from src/test/speed_test.cpp rename to src/test/example_test.cpp index 0d9b1c3a..9e594b1a 100644 --- a/src/test/speed_test.cpp +++ b/src/test/example_test.cpp @@ -25,7 +25,7 @@ char convert(char c) { return ' '; } -TEST(Speed, CPP) { +TEST(Example, SpeedCPP) { LOG_INFO("Start speed test C++"); @@ -74,7 +74,7 @@ TEST(Speed, CPP) { } -TEST(Speed, NewLang) { +TEST(Example, SpeedNewLang) { Context::Reset(); Context ctx(RunTime::Init()); @@ -83,7 +83,7 @@ TEST(Speed, NewLang) { setvbuf(stdout, nullptr, _IONBF, 0); setvbuf(stderr, nullptr, _IONBF, 0); - + ObjPtr test; ObjPtr str = ctx.ExecStr("@str := 'ABCDEF\\n';", nullptr, true); @@ -126,7 +126,7 @@ TEST(Speed, NewLang) { int sec = std::chrono::duration_cast(end - begin).count(); int ms = std::chrono::duration_cast(end - begin).count() % 1000000; - LOG_INFO("Test complete at %d.%d sec", sec, ms); + LOG_INFO("Test speed complete at %d.%d sec", sec, ms); /* * @@ -178,4 +178,94 @@ TEST(Speed, NewLang) { */ } +TEST(Example, Fraction) { + + Context::Reset(); + Context ctx(RunTime::Init()); + + setvbuf(stdin, nullptr, _IONBF, 0); + setvbuf(stdout, nullptr, _IONBF, 0); + setvbuf(stderr, nullptr, _IONBF, 0); + + ObjPtr test; + //@fact_recur(n:Integer) := { + // [n > 1] --> { + // -- n * fact_recur(n-1) --; + // }; + // 1; + //}; + + ObjPtr str = ctx.ExecStr("@str := 'ABCDEF\\n';", nullptr, true); + ASSERT_TRUE(str); + ASSERT_STREQ("ABCDEF\n", str->GetValueAsString().c_str()); + + ObjPtr test_printf = ctx.ExecStr("@test_printf := :Pointer('printf(format:FmtChar, ...):Int')", nullptr, true); + ASSERT_TRUE(test_printf); + ASSERT_STREQ("test_printf={}", test_printf->GetValueAsString().c_str()); + + ObjPtr iter = ctx.ExecStr("@iterator := (1, 5, 9999,)?", nullptr, true); + ASSERT_TRUE(iter); + ASSERT_TRUE(iter->getType() == ObjType::Iterator); + ASSERT_TRUE(iter->m_iterator); + ASSERT_TRUE(*iter->m_iterator.get() == iter->m_iterator->begin()); + ASSERT_TRUE(*iter->m_iterator.get() != iter->m_iterator->end()); + + ObjPtr test_frac = ctx.ExecStr("@test_frac := 999\\123", nullptr, true); + ASSERT_TRUE(test_frac); + ASSERT_TRUE(test_frac->getType() == ObjType::Fraction); + ASSERT_STREQ("999\\123", test_frac->GetValueAsString().c_str()); + + ObjPtr str_frac = ctx.ExecStr(":StrChar(test_frac)", nullptr, true); + ASSERT_TRUE(str_frac); + ASSERT_TRUE(str_frac->getType() == ObjType::StrChar) << newlang::toString(str_frac->getType()); + ASSERT_STREQ("999\\123", str_frac->GetValueAsString().c_str()) << str_frac->GetValueAsString(); + + ObjPtr test_prn = ctx.ExecStr("test_printf('%s', :StrChar(test_frac))", nullptr, true); + ASSERT_TRUE(test_prn); + ASSERT_STREQ("7", test_prn->GetValueAsString().c_str()); + + ObjPtr test_arg = ctx.ExecStr("@test_arg(arg:Fraction) := {$arg}", nullptr, true); + ASSERT_TRUE(test_arg); + ASSERT_TRUE(test_arg->is_function()); + ASSERT_FALSE(test_arg->is_none_type()); + ASSERT_STREQ("test_arg={}", test_arg->GetValueAsString().c_str()); + + + + ObjPtr frac_test; + ASSERT_ANY_THROW(test_arg->Call(&ctx)); // Нет обязательно аргумента + ASSERT_ANY_THROW(test_arg->Call(&ctx, Obj::Arg("неправильный тип аругумента"))); + + frac_test = test_arg->Call(&ctx, Obj::Arg(1)); + ASSERT_TRUE(frac_test); + ASSERT_EQ(ObjType::Fraction, frac_test->getType()) << newlang::toString(frac_test->getType()); + + frac_test = ctx.ExecStr("test_arg(1)", nullptr, true); + ASSERT_TRUE(frac_test); + ASSERT_STREQ("1\\1", frac_test->GetValueAsString().c_str()); + + + + utils::Logger::LogLevelType save = utils::Logger::Instance()->SetLogLevel(LOG_LEVEL_INFO); + std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now(); + ObjPtr result = ctx.ExecFile("../examples/fraction.nlp"); + std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now(); + utils::Logger::Instance()->SetLogLevel(save); + + + + ASSERT_TRUE(result); + ASSERT_TRUE(result->is_string_type()) << result->toString(); + ASSERT_STREQ("OK", result->GetValueAsString().c_str()); + + + int sec = std::chrono::duration_cast(end - begin).count(); + int ms = std::chrono::duration_cast(end - begin).count() % 1000000; + LOG_INFO("Test fraction complete at %d.%d sec", sec, ms); + + /* + * + */ +} + #endif // UNITTEST \ No newline at end of file diff --git a/src/test/object_test.cpp b/src/test/object_test.cpp index 06549b47..0b0f0b43 100644 --- a/src/test/object_test.cpp +++ b/src/test/object_test.cpp @@ -875,27 +875,7 @@ TEST(ObjTest, Iterator) { ASSERT_EQ(dict->size(), copy->size()); - /* - * Создание итератора - * ?, ?(), ?("Фильтр"), ?(func), ?(func, args...) - * - * Перебор элементов итератора - * !, !(), !(0), !(3), !(-3) - * - * dict! и dict!(0) эквивалентны - * dict! -> 1, dict! -> 2, dict! -> 3, dict! -> 4, dict! -> 5, dict! -> :IteratorEnd - * Различия отрицательного размера возвращаемого словаря для итератора - * dict!(-1) -> (1,), ... dict!(-1) -> (5,), dict!(-1) -> (:IteratorEnd,), - * dict!(1) -> (1,), ... dict!(1) -> (5,), dict!(1) -> (,), - * dict!(-3) -> (1, 2, 3,), dict!(-3) -> (4, 5, :IteratorEnd,) - * dict!(3) -> (1, 2, 3,), dict!(3) -> (4, 5,) - * - * !? или ?! эквиваленты и создают итератор и сразу его выполняет, - * вовзращая все значения в виде элементов словаря, т.е. ?(LINQ); !(:Long.__max__) - * А зачем может быть нужен итератор "??" - может сброс в начальное состояние??? - * Итератор !! эквиваленетен вызову !(1) - */ - + ASSERT_TRUE(iter == iter.begin()); ObjPtr one = iter.read_and_next(0); diff --git a/src/test/parser_test.cpp b/src/test/parser_test.cpp index 022dc530..5fe33830 100644 --- a/src/test/parser_test.cpp +++ b/src/test/parser_test.cpp @@ -640,6 +640,18 @@ TEST_F(ParserTest, TermCollection2) { ASSERT_EQ(TermID::TENSOR, (*ast)[1].second->getTermID()) << newlang::toString((*ast)[1].second->getTermID()); } + +TEST_F(ParserTest, OpsCall) { + ASSERT_TRUE(Parse("call(1+1)")); + ASSERT_TRUE(Parse("call(1-1)")); + ASSERT_TRUE(Parse("call(1\\1-1)")); + ASSERT_TRUE(Parse("call(term+1)")); + ASSERT_TRUE(Parse("call(term-1)")); + ASSERT_TRUE(Parse("call(term+term)")); + ASSERT_TRUE(Parse("call(term-term)")); + ASSERT_TRUE(Parse("call(term-term,term*2)")); +} + TEST_F(ParserTest, ArgMixedFail) { // EXPECT_THROW( // Parse("term(arg2=arg3, arg1);"), std::runtime_error @@ -802,26 +814,83 @@ TEST_F(ParserTest, MathNeg) { TermPtr op = ast->Right(); ASSERT_TRUE(op); ASSERT_STREQ("-456", op->m_text.c_str()); + + + ASSERT_TRUE(Parse("1000-456")); + ASSERT_STREQ("-", ast->m_text.c_str()); + ASSERT_TRUE(ast->Left()); + ASSERT_TRUE(ast->Right()); + ASSERT_STREQ("1000", ast->Left()->m_text.c_str()); + op = ast->Right(); + ASSERT_TRUE(op); + ASSERT_STREQ("456", op->m_text.c_str()); + + ASSERT_TRUE(Parse("-(456)")); + ASSERT_STREQ("-", ast->m_text.c_str()); + ASSERT_FALSE(ast->Left()); + ASSERT_TRUE(ast->Right()); + op = ast->Right(); + ASSERT_TRUE(op); + ASSERT_STREQ("456", op->m_text.c_str()); + + ASSERT_ANY_THROW(Parse("1000 456")); } -TEST_F(ParserTest, DISABLED_MathPioritet) { - ASSERT_TRUE(Parse("test := 123+456*789;")); - ASSERT_STREQ(":=", ast->m_text.c_str()); +TEST_F(ParserTest, MathPrioritet) { + ASSERT_TRUE(Parse("1+2*3")); + ASSERT_STREQ("+", ast->m_text.c_str()); ASSERT_TRUE(ast->Left()); ASSERT_TRUE(ast->Right()); - ASSERT_STREQ("test", ast->Left()->m_text.c_str()); + ASSERT_STREQ("1", ast->Left()->m_text.c_str()); TermPtr op = ast->Right(); ASSERT_TRUE(op); ASSERT_STREQ("*", op->m_text.c_str()); ASSERT_TRUE(op->Right()); - ASSERT_STREQ("789", op->Right()->m_text.c_str()); ASSERT_TRUE(op->Left()); - ASSERT_STREQ("+", op->Left()->m_text.c_str()); - TermPtr op2 = op->Right(); - ASSERT_TRUE(op2->Left()); - ASSERT_TRUE(op2->Right()); - ASSERT_STREQ("123", op2->Left()->m_text.c_str()); - ASSERT_STREQ("456", op2->Right()->m_text.c_str()); + ASSERT_STREQ("2", op->Left()->m_text.c_str()); + ASSERT_STREQ("3", op->Right()->m_text.c_str()); + + + ASSERT_TRUE(Parse("1*2+3")); + ASSERT_STREQ("+", ast->m_text.c_str()); + ASSERT_TRUE(ast->Left()); + ASSERT_TRUE(ast->Right()); + ASSERT_STREQ("3", ast->Right()->m_text.c_str()); + op = ast->Left(); + ASSERT_TRUE(op); + ASSERT_STREQ("*", op->m_text.c_str()); + ASSERT_TRUE(op->Right()); + ASSERT_TRUE(op->Left()); + ASSERT_STREQ("1", op->Left()->m_text.c_str()); + ASSERT_STREQ("2", op->Right()->m_text.c_str()); + + + ASSERT_TRUE(Parse("(1*2)+3")); + ASSERT_STREQ("+", ast->m_text.c_str()); + ASSERT_TRUE(ast->Left()); + ASSERT_TRUE(ast->Right()); + ASSERT_STREQ("3", ast->Right()->m_text.c_str()); + op = ast->Left(); + ASSERT_TRUE(op); + ASSERT_STREQ("*", op->m_text.c_str()); + ASSERT_TRUE(op->Right()); + ASSERT_TRUE(op->Left()); + ASSERT_STREQ("1", op->Left()->m_text.c_str()); + ASSERT_STREQ("2", op->Right()->m_text.c_str()); + + + ASSERT_TRUE(Parse("1*(2+3)")); + ASSERT_STREQ("*", ast->m_text.c_str()); + ASSERT_TRUE(ast->Left()); + ASSERT_TRUE(ast->Right()); + ASSERT_STREQ("1", ast->Left()->m_text.c_str()); + op = ast->Right(); + ASSERT_TRUE(op); + ASSERT_STREQ("+", op->m_text.c_str()); + ASSERT_TRUE(op->Right()); + ASSERT_TRUE(op->Left()); + ASSERT_STREQ("2", op->Left()->m_text.c_str()); + ASSERT_STREQ("3", op->Right()->m_text.c_str()); } TEST_F(ParserTest, CodeSimple) { @@ -1059,12 +1128,12 @@ TEST_F(ParserTest, ArgsArray1) { TEST_F(ParserTest, LogicEq) { ASSERT_TRUE(Parse("var := 1==2;")); - ASSERT_STREQ("var := 1==2;", ast->toString().c_str()); + ASSERT_STREQ("var := 1 == 2;", ast->toString().c_str()); } TEST_F(ParserTest, LogicNe) { ASSERT_TRUE(Parse("var := 1!=2;")); - ASSERT_STREQ("var := 1!=2;", ast->toString().c_str()); + ASSERT_STREQ("var := 1 != 2;", ast->toString().c_str()); } TEST_F(ParserTest, InstanceName) { @@ -1123,12 +1192,12 @@ TEST_F(ParserTest, FunctionSimple5) { TEST_F(ParserTest, FunctionTrans0) { ASSERT_TRUE(Parse("func(arg1, arg2=123) :&&= $arg1 == $arg2, $11 == $arg1;")); - ASSERT_STREQ("func(arg1, arg2=123) :&&= $arg1==$arg2, $11==$arg1", ast->toString().c_str()); + ASSERT_STREQ("func(arg1, arg2=123) :&&= $arg1 == $arg2, $11 == $arg1", ast->toString().c_str()); } TEST_F(ParserTest, FunctionTrans1) { ASSERT_TRUE(Parse("human::eq(test=human) :&&= $0==$test;")); - ASSERT_STREQ("human::eq(test=human) :&&= $0==$test;", ast->toString().c_str()); + ASSERT_STREQ("human::eq(test=human) :&&= $0 == $test;", ast->toString().c_str()); } TEST_F(ParserTest, FunctionTrans2) { @@ -1143,12 +1212,12 @@ TEST_F(ParserTest, FunctionTrans3) { TEST_F(ParserTest, FunctionTrans4) { ASSERT_TRUE(Parse("func(arg1, arg2 = 5) :- { [$arg1 < $arg2] -> {%{ return $arg1; %}}; };")); - ASSERT_STREQ("func(arg1, arg2=5) :- {[$arg1<$arg2]->{%{ return $arg1; %}};};", ast->toString().c_str()); + ASSERT_STREQ("func(arg1, arg2=5) :- {[$arg1 < $arg2]->{%{ return $arg1; %}};};", ast->toString().c_str()); } TEST_F(ParserTest, FunctionTrans5) { - ASSERT_TRUE(Parse("func(arg1, arg2 = 5) :- { [$arg1 < $arg2] -> {%{ return $arg1; %}}, [_] -> {%{ return $arg2; %}}; };")); - ASSERT_STREQ("func(arg1, arg2=5) :- {[$arg1<$arg2]->{%{ return $arg1; %}},\n [_]->{%{ return $arg2; %}};};", ast->toString().c_str()); + ASSERT_TRUE(Parse("func(arg1, arg2 = 5) :- { [$arg1<$arg2] -> {%{ return $arg1; %}}, [_] -> {%{ return $arg2; %}}; };")); + ASSERT_STREQ("func(arg1, arg2=5) :- {[$arg1 < $arg2]->{%{ return $arg1; %}},\n [_]->{%{ return $arg2; %}};};", ast->toString().c_str()); } TEST_F(ParserTest, FunctionRussian1) { @@ -1295,22 +1364,22 @@ TEST_F(ParserTest, DISABLED_Ellipsis1) { // ASSERT_STREQ("$name := term2;", ast->toString().c_str()); //} -TEST_F(ParserTest, DISABLED_Ellipsis2) { - ASSERT_TRUE(Parse("@name := term2(... arg);")); - ASSERT_EQ(TermID::CREATE, ast->getTermID()) << newlang::toString(ast->getTermID()); - ASSERT_STREQ("@name := term2(... arg);", ast->toString().c_str()); +TEST_F(ParserTest, Ellipsis2) { + ASSERT_TRUE(Parse("@name := term2( ... arg);")); + ASSERT_EQ(TermID::CREATE_OR_ASSIGN, ast->getTermID()) << newlang::toString(ast->getTermID()); + ASSERT_STREQ("@name := term2(...arg);", ast->toString().c_str()); } TEST_F(ParserTest, Func1) { ASSERT_TRUE(Parse("func_arg(arg1 :Char, arg2) :Char := { $arg1+$arg2; };")); ASSERT_EQ(TermID::CREATE_OR_ASSIGN, ast->getTermID()) << newlang::toString(ast->getTermID()); - ASSERT_STREQ("func_arg(arg1:Char, arg2):Char := {$arg1+$arg2;};", ast->toString().c_str()); + ASSERT_STREQ("func_arg(arg1:Char, arg2):Char := {$arg1 + $arg2;};", ast->toString().c_str()); } TEST_F(ParserTest, Func2) { ASSERT_TRUE(Parse("func_arg(arg1:&Char, &arg2) :&Char := { $arg1+$arg2; };")); ASSERT_EQ(TermID::CREATE_OR_ASSIGN, ast->getTermID()) << newlang::toString(ast->getTermID()); - ASSERT_STREQ("func_arg(arg1:&Char, &arg2):&Char := {$arg1+$arg2;};", ast->toString().c_str()); + ASSERT_STREQ("func_arg(arg1:&Char, &arg2):&Char := {$arg1 + $arg2;};", ast->toString().c_str()); } TEST_F(ParserTest, Func3) { @@ -1556,30 +1625,30 @@ TEST_F(ParserTest, Operators) { ASSERT_TRUE(Parse("(){val ++ val() / (val - val());};")); } -TEST_F(ParserTest, DISABLED_Repeat0) { - ASSERT_TRUE(Parse("[human || $ttttt && 123 != test[0].field ] <<-->> if_1;")); - ASSERT_STREQ("[human || $ttttt && 123 != test[0].field]<<-->>{if_1;};", ast->toString().c_str()); +TEST_F(ParserTest, Repeat0) { + ASSERT_TRUE(Parse("[human || $ttttt && 123 != test[0].field ] <<-->> if_1;")); + ASSERT_STREQ("[human || $ttttt && 123 != test[0].field]<<-->>if_1;", ast->toString().c_str()); } TEST_F(ParserTest, Repeat1) { ASSERT_TRUE(Parse("[test == human] <<-->> if_1;")); - ASSERT_STREQ("[test==human]<<-->>if_1;", ast->toString().c_str()); + ASSERT_STREQ("[test == human]<<-->>if_1;", ast->toString().c_str()); } TEST_F(ParserTest, Repeat2) { ASSERT_TRUE(Parse("[test != human] <<-->> {if_1;};")); - ASSERT_STREQ("[test!=human]<<-->>{if_1;};", ast->toString().c_str()); + ASSERT_STREQ("[test != human]<<-->>{if_1;};", ast->toString().c_str()); - ASSERT_TRUE(Parse("{if_1;} <<-->> [test != human];")); - ASSERT_STREQ("{if_1;}<<-->>[test!=human];", ast->toString().c_str()); + ASSERT_TRUE(Parse("{if_1;} <<-->> [test!=human];")); + ASSERT_STREQ("{if_1;}<<-->>[test != human];", ast->toString().c_str()); } TEST_F(ParserTest, Repeat3) { ASSERT_TRUE(Parse("[test != human] <<-->> {if_1;if_2;then3;};")); - ASSERT_STREQ("[test!=human]<<-->>{if_1; if_2; then3;};", ast->toString().c_str()); + ASSERT_STREQ("[test != human]<<-->>{if_1; if_2; then3;};", ast->toString().c_str()); ASSERT_TRUE(Parse("{if_1;if_2;then3;} <<-->> [test != human];")); - ASSERT_STREQ("{if_1; if_2; then3;}<<-->>[test!=human];", ast->toString().c_str()); + ASSERT_STREQ("{if_1; if_2; then3;}<<-->>[test != human];", ast->toString().c_str()); } TEST_F(ParserTest, Repeat4) { @@ -1616,8 +1685,8 @@ TEST_F(ParserTest, Repeat6) { } TEST_F(ParserTest, Repeat7) { - ASSERT_TRUE(Parse("[test[0].@field != $test()!!] <<-->> if_1;")); - ASSERT_STREQ("[test[0].@field!=$test()!!]<<-->>if_1;", ast->toString().c_str()); + ASSERT_TRUE(Parse("[test[0].@field != $test!] <<-->> if_1;")); + ASSERT_STREQ("[test[0].@field!=$test!]<<-->>if_1;", ast->toString().c_str()); } TEST_F(ParserTest, Range) { @@ -1638,10 +1707,18 @@ TEST_F(ParserTest, Range2) { ASSERT_STREQ("[i()]<<-->>@error(\"Error\");", ast->toString().c_str()); } -TEST_F(ParserTest, DISABLED_Follow0) { +TEST_F(ParserTest, RangeCall) { + ASSERT_TRUE(Parse("0.1..(1+1)")); + ASSERT_TRUE(Parse("0.1..(1*2)")); + ASSERT_TRUE(Parse("0.1..term()")); + ASSERT_TRUE(Parse("0.1..term()..(1*2+2-term)")); + ASSERT_TRUE(Parse("$term..(term()+$term)..(-1*2+2-@term())")); +} + +TEST_F(ParserTest, Follow) { //@todo Не получается сделать парсер с простым if, т.к. требуется вторая закрывающая точка с запятой - ASSERT_TRUE(Parse("[test == human || ttttt && 123 != test.field ] -> if_1;")); - ASSERT_STREQ("[test==human]->{if_1;};", ast->toString().c_str()); + ASSERT_TRUE(Parse("[test == human || ttttt&&123!=test.field ] -> if_1;")); + ASSERT_STREQ("[test == human || ttttt && 123 != test.field]->if_1;", ast->toString().c_str()); } TEST_F(ParserTest, Follow0) { @@ -1667,17 +1744,17 @@ TEST_F(ParserTest, Follow0) { TEST_F(ParserTest, Follow1) { //@todo Не получается сделать парсер с простым if, т.к. требуется вторая закрывающая точка с запятой ASSERT_TRUE(Parse("[test == human] -> if_1;")); - ASSERT_STREQ("[test==human]->if_1;", ast->toString().c_str()); + ASSERT_STREQ("[test == human]->if_1;", ast->toString().c_str()); } TEST_F(ParserTest, Follow2) { ASSERT_TRUE(Parse("[test != human] -> {if_1;};")); - ASSERT_STREQ("[test!=human]->{if_1;}", ast->toString().c_str()); + ASSERT_STREQ("[test != human]->{if_1;}", ast->toString().c_str()); } TEST_F(ParserTest, Follow3) { - ASSERT_TRUE(Parse("[test != human] -> {if_1;if_2;then3;};")); - ASSERT_STREQ("[test!=human]->{if_1; if_2; then3;}", ast->toString().c_str()); + ASSERT_TRUE(Parse("[test!=human] -> {if_1;if_2;then3;};")); + ASSERT_STREQ("[test != human]->{if_1; if_2; then3;}", ast->toString().c_str()); } TEST_F(ParserTest, Follow4) { @@ -1695,7 +1772,7 @@ TEST_F(ParserTest, Follow6) { // ASSERT_STREQ("(@test1)->{then1;},\n ($test2)->{then2;},\n (@test3+$test3)->{then3;},\n _ ->{else; else();};", ast->toString().c_str()); } -TEST_F(ParserTest, DISABLED_Follow7) { +TEST_F(ParserTest, Follow7) { ASSERT_TRUE(Parse("[test.field[0] > iter!!] -> if_1;")); // ASSERT_STREQ("(test.field[0].field2>iter!!)->{if_1;};", ast->toString().c_str()); } diff --git a/src/types.h b/src/types.h index cd2afa17..b60e5717 100644 --- a/src/types.h +++ b/src/types.h @@ -584,17 +584,20 @@ void ParserException(const char *msg, std::string &buffer, int row, int col); if (from == to || from == ObjType::None || to == ObjType::None) { // Преобразовывать ненужно или указан тип по по умолчанию return true; - } else if (isSimpleType(from) && isSimpleType(to)) { - // Для простых типов приведение типов почти как в Torch, только с учетом размера данных - // Запрещено: Big size -> Small Size, т.е. Byte_tensor *= Int_tensor. - // Разрешено: Bool -> Byte, Char -> Short -> Int -> Long -> Float, Double -> ComplexFloat, ComplexDouble - // т.е. Int_tensor += Bool_tensor или ComplexFloat_tensor *= Short_tensor. - - // return at::canCast(toTorchType(from), toTorchType(to)) - // && (from <= to || from == ObjType::Bool || from <= ObjType::Char || (isFloatingType(from) && - // isFloatingType(to))); - return (from <= to || (isFloatingType(from) && isFloatingType(to))); - + } else if (isSimpleType(from)) { + if (isSimpleType(to)) { + // Для простых типов приведение типов почти как в Torch, только с учетом размера данных + // Запрещено: Big size -> Small Size, т.е. Byte_tensor *= Int_tensor. + // Разрешено: Bool -> Byte, Char -> Short -> Int -> Long -> Float, Double -> ComplexFloat, ComplexDouble + // т.е. Int_tensor += Bool_tensor или ComplexFloat_tensor *= Short_tensor. + + // return at::canCast(toTorchType(from), toTorchType(to)) + // && (from <= to || from == ObjType::Bool || from <= ObjType::Char || (isFloatingType(from) && + // isFloatingType(to))); + return (from <= to || (isFloatingType(from) && isFloatingType(to))); + } else if (to == ObjType::Fraction) { + return true; + } } else if (isString(from) && isString(to)) {// && isObjectType(to)) { // Строковые типы конвертируются только В объект, т.к. нативные типы не изменяются return true; From d086a5f2fe6915bb588448ab51b83d4097ba3ff0 Mon Sep 17 00:00:00 2001 From: Aleksandr Ryabikov Date: Sun, 31 Jul 2022 19:00:33 +0300 Subject: [PATCH 29/31] =?UTF-8?q?=D0=9E=D1=82=D0=BB=D0=B0=D0=B4=D0=B8?= =?UTF-8?q?=D0=BB=20=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D1=83=20=D1=81=20=D0=B8?= =?UTF-8?q?=D1=82=D0=B5=D1=80=D0=B0=D1=82=D0=BE=D1=80=D0=B0=D0=BC=D0=B8=20?= =?UTF-8?q?=D0=B8=20=D0=BF=D1=80=D0=B8=D0=BC=D0=B5=D1=80=20=D0=B2=D1=8B?= =?UTF-8?q?=D1=87=D0=B8=D1=81=D0=BB=D0=B5=D0=BD=D0=B8=D1=8F=20=D1=84=D0=B0?= =?UTF-8?q?=D0=BA=D1=82=D0=BE=D1=80=D0=B8=D0=B0=D0=BB=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- examples/fraction.nlp | 48 ++------ src/context.cpp | 27 ++-- src/context.h | 6 +- src/fraction.h | 4 + src/nbproject/Makefile-Debug.mk | 6 + src/nbproject/configurations.xml | 26 ++++ src/object.cpp | 188 +++++++++++++++------------- src/object.h | 203 +++++++++++++++++++++---------- src/test/alg_test.cpp | 20 +-- src/test/eval_test.cpp | 143 ++++++++++++++++------ src/test/example_test.cpp | 2 +- src/test/parser_test.cpp | 4 +- src/types.h | 2 +- src/variable.h | 2 + 14 files changed, 434 insertions(+), 247 deletions(-) diff --git a/examples/fraction.nlp b/examples/fraction.nlp index 831c0873..6c5108e4 100755 --- a/examples/fraction.nlp +++ b/examples/fraction.nlp @@ -1,10 +1,6 @@ #!../output/nlc --eval @printf := :Pointer('printf(format:FmtChar, ...):Int'); -/* -#@var1 := 12345678901234567865465491/1; -#@var2 := 100_000_000_000_000_001\1; -#@var2 *= @var1; @fact_int(n:Int) := { [n > 1] --> { @@ -16,8 +12,8 @@ }; }; -printf('Recursive factorial with integer overflow:\n'); -@item := (3, 2, 5, 10, 11, 12, 13,)?; +printf('Recursive factorial with integer overflow at most 13!:\n'); +@item := (1, 2, 3, 4, 5, 10, 11, 12, 13,)?; @fact := 0; [ item ] <<-->> { fact := fact_int(item?!); @@ -25,32 +21,22 @@ printf('Recursive factorial with integer overflow:\n'); item!; }; -*/ + + @fact_range(n:Fraction) := { -printf('fact_range call %s\n', :StrChar(n)); [n > 2] --> { - iter := (n-1)..2..-1?; # Итератор для множителей - [iter] <<-->> { + iter := (n-1)..1..-1?; # Итератор для множителей + [iter?!] <<-->> { n *= iter!; }; }; n -/* - [n > 1] --> { - n *= fact_frac(n-1); - }, [n==1] --> { - 1; - }, [_] --> { - -- "ERROR!!!" --; - }; */ }; -printf('Recursive factorial with fraction no overflow:\n'); -@big := (1, 2, 5, 10, 11, 12, 13, 20, 30, 100, 1000,)?; -@frac := 0\1; #fraction value bigint - -printf('>>>>>>>>>> %s! -> %s <<<<<<<<<<\n', :StrChar(big?!), :StrChar(frac)); +printf('Recursive factorial without overflow with fractional value:\n'); +@big := (1, 2, 3, 4, 5, 10, 11, 12, 13, 20, 30, 100, 1000,)?; +@frac := 0\1; # fraction value support bigint [ big ] <<-->> { printf('%s! -> ', :StrChar(big?!)); @@ -59,16 +45,6 @@ printf('>>>>>>>>>> %s! -> %s <<<<<<<<<<\n', :StrChar(big?!), :StrChar(frac)) big!; }; -/* -@fact_range(n:Integer) := { - result := 1\1; # Дробь для точного расчета больших чисел - iter := 2..(n+1)?; - [iter] <<-->>{ - result *= iter!; - } - result; -}; - -1000! = 402387260077093773543702433923003985719374864210714632543799910429938512398629020592044208486969404800479988610197196058631666872994808558901323829669944590997424504087073759918823627727188732519779505950995276120874975462497043601418278094646496291056393887437886487337119181045825783647849977012476632889835955735432513185323958463075557409114262417474349347553428646576611667797396668820291207379143853719588249808126867838374559731746136085379534524221586593201928090878297308431392844403281231558611036976801357304216168747609675871348312025478589320767169132448426236131412508780208000261683151027341827977704784635868170164365024153691398281264810213092761244896359928705114964975419909342221566832572080821333186116811553615836546984046708975602900950537616475847728421889679646244945160765353408198901385442487984959953319101723355556602139450399736280750137837615307127761926849034352625200015888535147331611702103968175921510907788019393178114194545257223865541461062892187960223838971476088506276862967146674697562911234082439208160153780889893964518263243671616762179168909779911903754031274622289988005195444414282012187361745992642956581746628302955570299024324153181617210465832036786906117260158783520751516284225540265170483304226143974286933061690897968482590125458327168226458066526769958652682272807075781391858178889652208164348344825993266043367660176999612831860788386150279465955131156552036093988180612138558600301435694527224206344631797460594682573103790084024432438465657245014402821885252470935190620929023136493273497565513958720559654228749774011413346962715422845862377387538230483865688976461927383814900140767310446640259899490222221765904339901886018566526485061799702356193897017860040811889729918311021171229845901641921068884387121855646124960798722908519296819372388642614839657382291123125024186649353143970137428531926649875337218940694281434118520158014123344828015051399694290153483077644569099073152433278288269864602789864321139083506217095002597389863554277196742822248757586765752344220207573630569498825087968928162753848863396909959826280956121450994871701244516461260379029309120889086942028510640182154399457156805941872748998094254742173582401063677404595741785160829230135358081840096996372524230560855903700624271243416909004153690105933983835777939410970027753472000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 -*/ -"OK"; \ No newline at end of file +# Check factorial 1000! +[frac == 402387260077093773543702433923003985719374864210714632543799910429938512398629020592044208486969404800479988610197196058631666872994808558901323829669944590997424504087073759918823627727188732519779505950995276120874975462497043601418278094646496291056393887437886487337119181045825783647849977012476632889835955735432513185323958463075557409114262417474349347553428646576611667797396668820291207379143853719588249808126867838374559731746136085379534524221586593201928090878297308431392844403281231558611036976801357304216168747609675871348312025478589320767169132448426236131412508780208000261683151027341827977704784635868170164365024153691398281264810213092761244896359928705114964975419909342221566832572080821333186116811553615836546984046708975602900950537616475847728421889679646244945160765353408198901385442487984959953319101723355556602139450399736280750137837615307127761926849034352625200015888535147331611702103968175921510907788019393178114194545257223865541461062892187960223838971476088506276862967146674697562911234082439208160153780889893964518263243671616762179168909779911903754031274622289988005195444414282012187361745992642956581746628302955570299024324153181617210465832036786906117260158783520751516284225540265170483304226143974286933061690897968482590125458327168226458066526769958652682272807075781391858178889652208164348344825993266043367660176999612831860788386150279465955131156552036093988180612138558600301435694527224206344631797460594682573103790084024432438465657245014402821885252470935190620929023136493273497565513958720559654228749774011413346962715422845862377387538230483865688976461927383814900140767310446640259899490222221765904339901886018566526485061799702356193897017860040811889729918311021171229845901641921068884387121855646124960798722908519296819372388642614839657382291123125024186649353143970137428531926649875337218940694281434118520158014123344828015051399694290153483077644569099073152433278288269864602789864321139083506217095002597389863554277196742822248757586765752344220207573630569498825087968928162753848863396909959826280956121450994871701244516461260379029309120889086942028510640182154399457156805941872748998094254742173582401063677404595741785160829230135358081840096996372524230560855903700624271243416909004153690105933983835777939410970027753472000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\1] +-> "OK"; \ No newline at end of file diff --git a/src/context.cpp b/src/context.cpp index 88f976a9..fe22e491 100644 --- a/src/context.cpp +++ b/src/context.cpp @@ -575,7 +575,7 @@ ObjPtr Context::CREATE_OR_ASSIGN(Context *ctx, const TermPtr &term, Obj *local_v ASSERT(list_obj.size() == list_term.size()); if(term->Right()->getTermID() == TermID::ELLIPSIS) { - if(rval->is_dictionary_type() || rval->is_tensor()) { + if(rval->is_dictionary_type() || rval->is_tensor_type()) { if(!rval->empty() && rval->is_scalar()) { LOG_RUNTIME("Fail expand scalar!"); } @@ -770,8 +770,8 @@ ObjPtr Context::eval_WHILE(Context *ctx, const TermPtr &term, Obj * args) { try { - LOG_DEBUG("result %s", result->toString().c_str()); - +// LOG_DEBUG("result %s", result->toString().c_str()); + result = CreateRVal(ctx, term->Right(), args, false); cond = Eval(ctx, term->Left(), args, false); @@ -1542,9 +1542,9 @@ ObjPtr Context::CreateNative(TermPtr proto, const char *module, bool lazzy, cons // result->m_var = m_runtime->GetNativeAddr( // result->m_func_mangle_name.empty() ? proto->m_text.c_str() : result->m_func_mangle_name.c_str(), module); - if(result->is_function() || type == ObjType::Pointer) { + if(result->is_function_type() || type == ObjType::Pointer) { NL_CHECK(at::get(result->m_var), "Error getting address '%s' from '%s'!", proto->toString().c_str(), module); - } else if(ptr && result->is_tensor()) { + } else if(ptr && result->is_tensor_type()) { // result->m_tensor = torch::from_blob(at::get(result->m_var),{ // }, toTorchType(type)); result->m_var_is_init = true; @@ -1713,7 +1713,7 @@ ObjPtr Context::CreateLVal(Context *ctx, TermPtr term, Obj * args) { } else if(type) { result->m_var_type_current = typeFromString(type->getText().c_str(), ctx); result->m_var_type_fixed = result->m_var_type_current; - if(result->is_tensor()) { + if(result->is_tensor_type()) { std::vector dims; if(type->m_dims.size()) { for (size_t i = 0; i < type->m_dims.size(); i++) { @@ -2103,7 +2103,7 @@ ObjPtr Context::CreateRVal(Context *ctx, TermPtr term, Obj * local_vars, bool in ASSERT(result->m_var_type_fixed == type); // Размерность, если указана - result->m_dimensions = Obj::CreateType(result->m_var_type_current, result->m_var_type_current, true); + result->m_dimensions = Obj::CreateType(ObjType::Dictionary, ObjType::Dictionary, true); for (size_t i = 0; i < term->m_dims.size(); i++) { result->m_dimensions->push_back(CreateRVal(ctx, term->m_dims[i], local_vars)); } @@ -2232,7 +2232,11 @@ ObjPtr Context::CreateRVal(Context *ctx, TermPtr term, Obj * local_vars, bool in result->m_var_is_init = true; if(term->getTermID() == TermID::TENSOR) { - result->m_var_type_fixed = typeFromString(term->m_type_name, ctx); + if(term->m_type_name.empty()) { + result->m_var_type_fixed = ObjType::None; + } else { + result->m_var_type_fixed = typeFromString(term->m_type_name, ctx); + } type = getSummaryTensorType(result.get(), result->m_var_type_fixed); if(type != ObjType::None) { @@ -2279,6 +2283,7 @@ ObjPtr Context::CreateRVal(Context *ctx, TermPtr term, Obj * local_vars, bool in case TermID::RANGE: + result->m_var_type_current = ObjType::Dictionary; for (int i = 0; i < term->size(); i++) { ASSERT(!term->name(i).empty()); result->push_back(Eval(ctx, (*term)[i].second, local_vars), term->name(i).c_str()); @@ -2349,14 +2354,14 @@ ObjPtr Context::CreateRVal(Context *ctx, TermPtr term, Obj * local_vars, bool in val_int = std::numeric_limits::max(); if(args->empty() || (args->size() == 1 && args->at(0).second->is_integer())) { - result = temp->IteratorMake(Iterator::FIND_KEY_DEFAULT, false); + result = temp->IteratorMake(nullptr, false); if(args->size()) { val_int = args->at(0).second->GetValueAsInteger(); } } else if(args->size() == 1 && args->at(0).second->is_string_type()) { - result = temp->IteratorMake(args->at(0).second->GetValueAsString(), false); + result = temp->IteratorMake(args->at(0).second->GetValueAsString().c_str(), false); } else if(args->size() == 2 && args->at(0).second->is_string_type() && args->at(1).second->is_integer()) { - result = temp->IteratorMake(args->at(0).second->GetValueAsString(), false); + result = temp->IteratorMake(args->at(0).second->GetValueAsString().c_str(), false); val_int = args->at(1).second->GetValueAsInteger(); } else { LOG_RUNTIME("Iterator`s args '%s' not allowed!", args->toString().c_str()); diff --git a/src/context.h b/src/context.h index f7becbe3..e5368225 100644 --- a/src/context.h +++ b/src/context.h @@ -105,8 +105,6 @@ namespace newlang { class Context : public Variable > { public: - friend class Obj; - static ObjPtr eval_END(Context *ctx, const TermPtr & term, Obj * args); static ObjPtr func_NOT_SUPPORT(Context *ctx, const TermPtr & term, Obj * args); @@ -363,7 +361,7 @@ namespace newlang { for (int i = 0; i < size(); i++) { if (pred_compare(start, at(i).first)) { ObjPtr object = at(i).second.lock(); - if (object && object->is_function()) { + if (object && object->is_function_type()) { result.push_back(utf8_decode(prefix + at(i).first) + L"("); } else if (object) { result.push_back(utf8_decode(prefix + at(i).first)); @@ -378,7 +376,7 @@ namespace newlang { if (find_global) { for (int i = 0; i < m_global_terms.size(); i++) { if (pred_compare(start, m_global_terms.at(i).first)) { - if (m_global_terms.at(i).second->is_function()) { + if (m_global_terms.at(i).second->is_function_type()) { result.push_back(utf8_decode(prefix + m_global_terms.at(i).first) + L"("); } else { result.push_back(utf8_decode(prefix + m_global_terms.at(i).first)); diff --git a/src/fraction.h b/src/fraction.h index 4c46aa63..63332b59 100644 --- a/src/fraction.h +++ b/src/fraction.h @@ -228,6 +228,10 @@ namespace newlang { return result; } + int64_t GetAsBoolean() const { + return !m_numerator.isZero(); + } + int64_t GetAsInteger() const { if (m_denominator.isZero()) { LOG_RUNTIME("Denominator must be different from zero!"); diff --git a/src/nbproject/Makefile-Debug.mk b/src/nbproject/Makefile-Debug.mk index b9e6708a..bc4b3533 100644 --- a/src/nbproject/Makefile-Debug.mk +++ b/src/nbproject/Makefile-Debug.mk @@ -89,6 +89,11 @@ ${OBJECTDIR}/_ext/e16507f5/logger.o: ../contrib/logger/logger.cpp ${RM} "$@.d" $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I. -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -std=c++14 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/_ext/e16507f5/logger.o ../contrib/logger/logger.cpp +temp/syntax.temp.txt: ../docs/op_iterator.md ../docs/syntax.md + ${MKDIR} -p temp + @echo Выполнение шага пользовательского сборки + mkdir temp || pandoc -t plain ../docs/syntax.md > temp/syntax.temp.txt + temp/syntax.temp.txt: ../docs/syntax.md ../docs/syntax.md ${MKDIR} -p temp @echo Выполнение шага пользовательского сборки @@ -277,6 +282,7 @@ ${OBJECTDIR}/version.o: version.cpp .clean-conf: ${CLEAN_SUBPROJECTS} ${RM} -r ${CND_BUILDDIR}/${CND_CONF} ${RM} temp/syntax.temp.txt + ${RM} temp/syntax.temp.txt ${RM} ${RM} ${RM} diff --git a/src/nbproject/configurations.xml b/src/nbproject/configurations.xml index f6b81827..784b6043 100644 --- a/src/nbproject/configurations.xml +++ b/src/nbproject/configurations.xml @@ -5,6 +5,7 @@ ../docs/CNAME ../docs/_config.yml ../docs/index.md + ../docs/op_iterator.md ../docs/syntax.md + + + mkdir temp || pandoc -t plain ../docs/syntax.md > temp/syntax.temp.txt + temp/syntax.temp.txt + ../docs/syntax.md + + mkdir temp || pandoc -t plain ../docs/syntax.md > temp/syntax.temp.txt @@ -487,6 +495,8 @@ + + @@ -730,6 +740,8 @@ + + @@ -930,6 +942,8 @@ + + @@ -1241,6 +1255,8 @@ + + @@ -1526,6 +1542,8 @@ + + @@ -1778,6 +1796,8 @@ + + @@ -2026,6 +2046,8 @@ + + @@ -2263,6 +2285,8 @@ + + @@ -2564,6 +2588,8 @@ + + diff --git a/src/object.cpp b/src/object.cpp index c194128b..97b30f7a 100644 --- a/src/object.cpp +++ b/src/object.cpp @@ -11,9 +11,6 @@ using namespace newlang; -template <> -const std::string Iterator::FIND_KEY_DEFAULT = "(.|\\n)*"; - std::ostream &operator<<(std::ostream &out, newlang::Obj &var) { out << var.toString().c_str(); return out; @@ -63,7 +60,7 @@ const char* Interrupt::what() const noexcept { } int64_t Obj::size(int64_t dim) const { - if(is_tensor()) { + if(is_tensor_type()) { if(is_scalar()) { if(dim != 0) { LOG_RUNTIME("Scalar has zero dimension!"); @@ -121,7 +118,7 @@ int64_t Obj::resize_(int64_t new_size, ObjPtr fill, const std::string name) { } else if(is_dictionary_type()) { return Variable::resize(new_size, fill ? fill : Obj::CreateNone(), name); - } else if(is_tensor()) { + } else if(is_tensor_type()) { std::vector sizes; for (int i = 0; i < m_tensor.dim(); i++) { sizes.push_back(m_tensor.size(i)); @@ -195,7 +192,7 @@ const Variable::PairType & Obj::at(int64_t index) const { } LOG_RUNTIME("Index '%ld' not exists in byte string '%s'!", index, "WIDE"); - } else if(is_tensor()) { + } else if(is_tensor_type()) { ASSERT(!is_scalar()); torch::Tensor t = m_tensor.index({index}); m_str_pair = pair(Obj::CreateTensor(t)); @@ -218,7 +215,7 @@ Variable::PairType & Obj::at(int64_t index) { } LOG_RUNTIME("Index '%ld' not exists in byte string '%s'!", index, "WIDE"); - } else if(is_tensor()) { + } else if(is_tensor_type()) { ASSERT(!is_scalar()); ASSERT(m_tensor.defined()); torch::Tensor t = m_tensor.index({(int) index}); @@ -255,7 +252,7 @@ const ObjPtr Obj::index_get(const std::vector &index) const { } LOG_RUNTIME("Index '%s' not exists in WIDE string '%s'!", IndexToString(index).c_str(), utf8_encode(m_string).c_str()); - } else if(is_tensor()) { + } else if(is_tensor_type()) { ASSERT(!is_scalar()); ASSERT(m_tensor.defined()); torch::Tensor t = m_tensor.index(index); @@ -300,7 +297,7 @@ ObjPtr Obj::index_set_(const std::vector &index, const ObjPtr value) { } LOG_RUNTIME("Index '%s' not exists in byte string '%s'!", IndexToString(index).c_str(), "WIDE"); - } else if(is_tensor()) { + } else if(is_tensor_type()) { ASSERT(!is_scalar()); ASSERT(m_tensor.defined()); @@ -392,8 +389,8 @@ ObjType newlang::getSummaryTensorType(Obj *obj, ObjType start) { } ObjPtr Obj::operator+=(Obj value) { - if(is_tensor()) { - if(value.is_tensor()) { + if(is_tensor_type()) { + if(value.is_tensor_type()) { testResultIntegralType(value.m_var_type_current, true); if(is_scalar() && value.is_scalar()) { if(is_floating()) { @@ -464,7 +461,7 @@ ObjPtr Obj::operator+=(Obj value) { ObjPtr Obj::operator-=(Obj value) { if(m_var_type_current == ObjType::None) { m_var_type_current = value.m_var_type_current; - } else if(is_tensor() && value.is_tensor()) { + } else if(is_tensor_type() && value.is_tensor_type()) { testResultIntegralType(value.m_var_type_current, true); if(is_scalar() && value.is_scalar()) { if(is_floating()) { @@ -521,7 +518,7 @@ ObjPtr Obj::operator-=(Obj value) { ObjPtr Obj::operator*=(Obj value) { if(m_var_type_current == ObjType::None) { m_var_type_current = value.m_var_type_current; - } else if(is_tensor() && value.is_tensor()) { + } else if(is_tensor_type() && value.is_tensor_type()) { testResultIntegralType(value.m_var_type_current, true); if(is_scalar() && value.is_scalar()) { if(is_floating()) { @@ -593,7 +590,7 @@ ObjPtr Obj::operator*=(Obj value) { } ObjPtr Obj::operator/=(Obj value) { - if(is_tensor() && value.is_tensor()) { + if(is_tensor_type() && value.is_tensor_type()) { testResultIntegralType(ObjType::Double, true); if(is_scalar() && value.is_scalar()) { if(is_floating()) { @@ -632,7 +629,7 @@ ObjPtr Obj::operator/=(Obj value) { } ObjPtr Obj::op_div_ceil_(Obj & value) { - if(is_tensor() && value.is_tensor()) { + if(is_tensor_type() && value.is_tensor_type()) { ObjType type = m_var_type_current; testResultIntegralType(ObjType::Float, false); if(is_scalar() && value.is_scalar()) { @@ -678,7 +675,7 @@ ObjPtr Obj::op_div_ceil_(Obj & value) { } ObjPtr Obj::operator%=(Obj value) { - if(is_tensor() && value.is_tensor()) { + if(is_tensor_type() && value.is_tensor_type()) { testResultIntegralType(value.m_var_type_current, true); if(is_scalar() && value.is_scalar()) { if(is_floating()) { @@ -773,16 +770,16 @@ void Obj::ClonePropTo(Obj & clone) const { for (int i = 0; i < Variable::size(); i++) { if(Variable::at(i).second) { if(Variable::at(i).second->m_is_reference || Variable::at(i).second->m_is_reference) { - clone.push_back(Variable::at(i)); + clone.Variable::push_back(Variable::at(i)); } else { - clone.push_back(Variable::at(i).second->Clone(nullptr), name(i)); + clone.Variable::push_back(Variable::at(i).second->Clone(nullptr), name(i)); } } else { if(name(i).empty()) { LOG_RUNTIME("Null arg %d without name! %s", i, toString().c_str()); } // Объекта может не быть у обязательных параметров функций - clone.push_back(nullptr, name(i)); + clone.Variable::push_back(nullptr, name(i)); } } } @@ -830,7 +827,7 @@ std::string Obj::toString(bool deep) const { } result += "_"; return result; - } else if(is_tensor()) { + } else if(is_tensor_type()) { if(is_scalar()) { result += GetValueAsString(); } else { @@ -1266,11 +1263,12 @@ ObjPtr Obj::Call(Context *ctx, Obj * args) { ObjPtr result = Clone(); result->m_value = format(result->m_value, args); return result; - } else if(is_function() || m_var_type_current == ObjType::Type) { + } else if(is_function_type() || m_var_type_current == ObjType::Type) { Obj local; ObjPtr param; if(m_prototype) { param = std::make_shared(ctx, m_prototype, false, &local); + param->m_var_type_current = ObjType::Dictionary; } else { param = Obj::CreateDict(); } @@ -1401,7 +1399,7 @@ void Obj::ConvertToArgs_(Obj *in, bool check_valid, Context * ctx) { if(check_valid && size()) { if(at(size() - 1).first.compare("...") == 0) { is_ellipsis = true; - erase(size() - 1); + Variable::erase(size() - 1); } } for (int i = 0; i < in->size(); i++) { @@ -1422,8 +1420,10 @@ void Obj::ConvertToArgs_(Obj *in, bool check_valid, Context * ctx) { if(has_error && (*m_prototype)[i].second->getTermID() == TermID::ELLIPSIS) { base_type = ObjType::Any; } - } else { + } else if(!(*m_prototype)[i].second->m_type_name.empty()) { base_type = typeFromString((*m_prototype)[i].second->m_type_name, ctx); + } else { + base_type = ObjType::Any; } } else { base_type = ObjType::Any; @@ -1572,7 +1572,7 @@ int Obj::op_compare(Obj & value) { bool Obj::op_equal(Obj & value) { if(this == &value) { return true; - } else if(is_tensor()) { + } else if(is_tensor_type()) { ObjType summary_type = static_cast (std::max( static_cast (m_var_type_current), static_cast (value.m_var_type_current))); @@ -1658,7 +1658,7 @@ ObjPtr Obj::op_bit_and_set(Obj &obj, bool strong) { } return shared(); } - } else if(is_tensor() && obj.is_tensor()) { + } else if(is_tensor_type() && obj.is_tensor_type()) { int pos = 0; while(pos < size()) { if(!obj.exist(at(pos).second, strong)) { @@ -1749,7 +1749,7 @@ bool Obj::op_duck_test_prop(Obj *base, Obj *value, bool strong) { } ObjPtr Obj::op_pow_(Obj & obj) { - if(is_tensor()) { + if(is_tensor_type()) { ASSERT(obj.is_arithmetic_type()); if(is_scalar()) { double temp = pow(GetValueAsNumber(), obj.GetValueAsNumber()); @@ -1801,7 +1801,7 @@ bool Obj::op_duck_test(Obj *value, bool strong) { } if(strong) { - if(value->is_simple()) { + if(value->is_simple_type()) { if(m_var_type_current == value->m_var_type_current || (is_string_type() && value->is_string_type())) { return true; } @@ -1813,7 +1813,7 @@ bool Obj::op_duck_test(Obj *value, bool strong) { return (m_var_type_current == ObjType::Long || m_var_type_current == ObjType::Double); } else if(is_string_type() && value->is_string_type()) { return true; - } else if(is_function() && value->is_function()) { + } else if(is_function_type() && value->is_function_type()) { return true; } else if(value->m_var_type_current == ObjType::Dictionary || value->m_var_type_current == ObjType::Class) { if(m_var_type_current == ObjType::Dictionary || m_var_type_current == ObjType::Class) { @@ -1896,7 +1896,7 @@ int64_t newlang::ConcatData(Obj *dest, Obj &src, ConcatMode mode) { size++; } - } else if(dest->is_tensor()) { + } else if(dest->is_tensor_type()) { if(dest->m_var_type_current == src.m_var_type_current) { if(dest->m_tensor.dim() == 0) { @@ -1920,7 +1920,7 @@ int64_t newlang::ConcatData(Obj *dest, Obj &src, ConcatMode mode) { } void ShapeFromDict(const Obj *obj, std::vector &shape) { - if(obj && (obj->is_dictionary_type() || (obj->is_tensor() && !obj->is_scalar()))) { + if(obj && (obj->is_dictionary_type() || (obj->is_tensor_type() && !obj->is_scalar()))) { if(!obj->size()) { LOG_RUNTIME("Cannot tensor shape from empty dictionary!"); } @@ -2755,7 +2755,7 @@ void Obj::toType_(ObjType type) { } else if(type == ObjType::None) { clear_(); return; - } else if(is_tensor() && isTensor(type)) { + } else if(is_tensor_type() && isTensor(type)) { // Изменить тип тензора if(isGenericType(type)) { @@ -2790,30 +2790,13 @@ void Obj::toType_(ObjType type) { } else if(is_range() && isDictionary(type)) { - ObjPtr value = at("start").second; - ObjPtr stop = at("stop").second; - ObjPtr step = at("step").second; - - ASSERT(value); - ASSERT(stop); - ASSERT(step); - + ObjPtr iter = IteratorMake(); + ObjPtr temp = iter->IteratorNext(std::numeric_limits::max()); Variable::clear_(); - m_var_type_current = type; - - if((*value) < stop) { - ASSERT(step->GetValueAsNumber() > 0); - while((*value) < stop) { - push_back(value->Clone()); - (*value) += step; - } - } else { - ASSERT(step->GetValueAsNumber() < 0); - while((*value) > stop) { - push_back(value->Clone()); - (*value) += step; - } + for (auto &elem : *temp) { + Variable::push_back(elem); } + m_var_type_current = type; return; } else if(is_range() && isTensor(type)) { @@ -2873,7 +2856,7 @@ void Obj::toType_(ObjType type) { m_string.clear(); return; - } else if(is_tensor() && isStringChar(type)) { + } else if(is_tensor_type() && isStringChar(type)) { if(is_scalar()) { int64_t char_val = GetValueAsInteger(); @@ -2900,7 +2883,7 @@ void Obj::toType_(ObjType type) { m_var_type_current = type; return; - } else if(is_tensor() && isStringWide(type)) { + } else if(is_tensor_type() && isStringWide(type)) { if(is_scalar()) { int64_t char_val = GetValueAsInteger(); @@ -2923,7 +2906,7 @@ void Obj::toType_(ObjType type) { m_var_type_current = type; return; - } else if(is_tensor() && type == ObjType::Fraction) { + } else if(is_tensor_type() && type == ObjType::Fraction) { if(!is_scalar()) { LOG_RUNTIME("Convert tensor to fraction support for scalar only!"); @@ -2937,7 +2920,7 @@ void Obj::toType_(ObjType type) { m_var_type_current = type; return; - } else if(is_tensor() && isDictionary(type)) { + } else if(is_tensor_type() && isDictionary(type)) { if(is_scalar() && is_integral()) { ASSERT(at::holds_alternative(m_var)); @@ -3407,16 +3390,18 @@ ObjPtr Obj::ConstructorInterraption_(const Context* ctx, Obj& args, ObjType type template<> const Iterator::IterPairType Iterator::m_interator_end = IterObj::pair(Obj::CreateType(ObjType::IteratorEnd, ObjType::IteratorEnd, true)); +static const ObjPtr zero = Obj::CreateValue(0); template<> ObjPtr Iterator::read_and_next(int64_t count) { ObjPtr result; - static ObjPtr zero = Obj::CreateValue(0); if(count == 0) { if(m_iter_obj->m_var_type_current == ObjType::Range) { - ObjPtr value = m_iter_obj->m_iter_range_value; + ASSERT(m_iter_obj->m_iter_range_value); + + ObjPtr value = m_iter_obj->m_iter_range_value; //->Clone(); ObjPtr stop = m_iter_obj->at("stop").second; ObjPtr step = m_iter_obj->at("step").second; @@ -3432,18 +3417,19 @@ ObjPtr Iterator::read_and_next(int64_t count) { result = value->Clone(); (*value) += step; } else { - result = Iterator::m_interator_end.second->Clone(); + result = Obj::CreateType(ObjType::IteratorEnd, ObjType::IteratorEnd, true); } } else { if(value->op_compare(*stop) < 0) { result = value->Clone(); (*value) += step; } else { - result = Iterator::m_interator_end.second->Clone(); + result = Obj::CreateType(ObjType::IteratorEnd, ObjType::IteratorEnd, true); } } + // m_iter_obj->m_iter_range_value = value; - } else if(m_iter_obj->is_indexing()) { + } else if(m_iter_obj->is_indexing()) { result = (*(*this)).second; (*this)++; } else { @@ -3456,7 +3442,9 @@ ObjPtr Iterator::read_and_next(int64_t count) { if(m_iter_obj->m_var_type_current == ObjType::Range) { - ObjPtr value = m_iter_obj->m_iter_range_value; + ASSERT(m_iter_obj->m_iter_range_value); + + ObjPtr value = m_iter_obj->m_iter_range_value; //->Clone(); ObjPtr stop = m_iter_obj->at("stop").second; ObjPtr step = m_iter_obj->at("step").second; @@ -3487,9 +3475,10 @@ ObjPtr Iterator::read_and_next(int64_t count) { } } } else { - result->push_back(Obj::CreateType(ObjType::IteratorEnd)); + result->push_back(Obj::CreateType(ObjType::IteratorEnd, ObjType::IteratorEnd, true)); } } + //m_iter_obj->m_iter_range_value = value; } else if(m_iter_obj->is_indexing()) { @@ -3498,7 +3487,7 @@ ObjPtr Iterator::read_and_next(int64_t count) { result->push_back(*(*this)); (*this)++; } else { - result->push_back(Obj::CreateType(ObjType::IteratorEnd)); + result->push_back(Obj::CreateType(ObjType::IteratorEnd, ObjType::IteratorEnd, true)); } } @@ -3511,14 +3500,11 @@ ObjPtr Iterator::read_and_next(int64_t count) { result = Obj::CreateDict(); result->m_var_is_init = true; - if(m_iter_obj->is_indexing()) { - while(*this != this->end() && result->size() < count) { - result->push_back(*(*this)); - (*this)++; - } - } else if(m_iter_obj->m_var_type_current == ObjType::Range) { + if(m_iter_obj->m_var_type_current == ObjType::Range) { + + ASSERT(m_iter_obj->m_iter_range_value); - ObjPtr value = m_iter_obj->m_iter_range_value; + ObjPtr value = m_iter_obj->m_iter_range_value; //->Clone(); ObjPtr stop = m_iter_obj->at("stop").second; ObjPtr step = m_iter_obj->at("step").second; @@ -3540,9 +3526,13 @@ ObjPtr Iterator::read_and_next(int64_t count) { (*value) += step; } } - - m_iter_obj->m_iter_range_value = result->Clone(); - + // m_iter_obj->m_iter_range_value.swap(value); + + } else if(m_iter_obj->is_indexing()) { + while(*this != this->end() && result->size() < count) { + result->push_back(*(*this)); + (*this)++; + } } else { LOG_RUNTIME("Interator to type %s not implemented!", newlang::toString(m_iter_obj->m_var_type_current)); } @@ -3551,7 +3541,7 @@ ObjPtr Iterator::read_and_next(int64_t count) { return result; } -ObjPtr Obj::IteratorMake(const std::string filter, bool check_create) { +ObjPtr Obj::IteratorMake(const char * filter, bool check_create) { ObjPtr result = CreateType(ObjType::Iterator, ObjType::Iterator, true); if(!(is_indexing() || m_var_type_current == ObjType::Range)) { if(getType() == ObjType::Iterator && !check_create) { @@ -3572,17 +3562,17 @@ ObjPtr Obj::IteratorMake(const std::string filter, bool check_create) { ObjPtr Obj::IteratorMake(Obj * args) { ObjPtr result = CreateType(ObjType::Iterator, ObjType::Iterator, true); if(!(is_indexing() || m_var_type_current == ObjType::Range)) { - if(getType() == ObjType::Iterator) { - return shared(); - } + // if(getType() == ObjType::Iterator) { + // return shared(); + // } LOG_RUNTIME("Can't create iterator from '%s'!", toString().c_str()); } if(!args || args->size() == 0) { result->m_iterator = std::make_shared> (shared()); } else if(args->size() == 1 && args->at(0).second && args->at(0).second->is_string_type()) { - result->m_iterator = std::make_shared> (shared(), args->GetValueAsString()); - } else if(args->size() >= 1 && args->at(0).second && args->at(0).second->is_function()) { + result->m_iterator = std::make_shared> (shared(), args->GetValueAsString().c_str()); + } else if(args->size() >= 1 && args->at(0).second && args->at(0).second->is_function_type()) { ASSERT(false); // ObjPtr func = args->at(0).second; // ObjPtr func_arg = args->Clone(); @@ -3601,10 +3591,44 @@ ObjPtr Obj::IteratorMake(Obj * args) { } ObjPtr Obj::IteratorData() { + if(!(m_var_type_current == ObjType::Iterator || m_var_type_current == ObjType::IteratorEnd)) { + LOG_RUNTIME("Object '%s' not iterator!", toString().c_str()); + } + + if(m_var_type_current == ObjType::IteratorEnd) { + return Iterator::m_interator_end.second; + } + ASSERT(m_iterator); + ASSERT(m_iterator->m_iter_obj); + if(m_iterator->m_iter_obj->is_range()) { + ASSERT(m_iterator->m_iter_obj->m_iter_range_value); - return m_iterator->m_iter_obj->m_iter_range_value->Clone(); + + ObjPtr value = m_iterator->m_iter_obj->m_iter_range_value; //->Clone(); + ObjPtr stop = m_iterator->m_iter_obj->at("stop").second; + ObjPtr step = m_iterator->m_iter_obj->at("step").second; + + ASSERT(value); + ASSERT(stop); + ASSERT(step); + + int up_direction = step->op_compare(*zero); + ASSERT(up_direction); + + if(up_direction < 0) { + if(value->op_compare(*stop) > 0) { + return value->Clone(); + } + } else { + if(value->op_compare(*stop) < 0) { + return value->Clone(); + } + } + + return Iterator::m_interator_end.second; + } else if(m_iterator->m_iter_obj->is_indexing()) { return m_iterator->data().second; } diff --git a/src/object.h b/src/object.h index a83eb181..15b73d8c 100644 --- a/src/object.h +++ b/src/object.h @@ -79,8 +79,6 @@ namespace newlang { void ConvertTensorToString(const torch::Tensor &from, std::wstring &to, std::vector *index = nullptr); void ConvertTensorToDict(const torch::Tensor &from, Obj &to, std::vector *index = nullptr); - - /* * Требуется разделять конейнеры с данными и итераторы по данным. * В С++ контейнеры предоставялют итераторы непосредственно из самого контейнера. @@ -100,16 +98,16 @@ namespace newlang { * ObjPtr IteratorMake(const std::string filter) - создать итератор с возможностью фильтрации по имени поля (данные на начало) * ObjPtr IteratorMake(Obj * args) - создать итератор с фильтрации с помощью пользовательской функции (данные на начало) * ObjPtr IteratorReset() - Сбросить итератор на начало данных (возвращает сам итератор) - * ObjPtr IteratorData() - прочитать текущий элемент без смещения указателя. Если данных нет генерируется исключение "конец итератора" - * ObjPtr IteratorNext(int64_t count)- прочитать заданное кол-во элементов переместив указатель и вернуть словарь с ними. Если данных - * нет возвращается пустой словарь, а исключение "конец итератора" не генерируется + * ObjPtr IteratorData() - прочитать текущий элемент без смещения указателя. Если данных нет возвращается "конец итератора" + * ObjPtr IteratorNext(int64_t count)- прочитать заданное кол-во элементов и переместить итератор на следующий элемент. + * При не нулевом кол-ве, данные возвращаются как элементы словаря. Если указан кол-во элеметов 0 - возвращается текущий элемент. * * Реализаиця итераторов NewLang с помощью данного интерфейса: * * Создание итератора * ?, ?("Фильтр"), ?(func), ?(func, args...) - IteratorMake * - * Перебор элементов итератора (IteratorData для ! без аргументов и IteratorNext в остальном случае) + * Перебор элементов итератора * !, !(0), !(3), !(-3) * * dict! и dict!(0) <НЕ> эквивалентны, т.к. по разному обработывают конец данных @@ -144,8 +142,45 @@ namespace newlang { * None - true (Это объекст со значением пусто) * Empty - false (Не инициализированный объект) * + * + * Логика обработки ссылок + * term1 := term; # Объект term1 - копия term. + * term2 := &term; # Объект term2 - ссылка на term (одни и те же данные, т.е. shared_ptr ссылаются на один и тот же объект) + * &term3 := term; # Создать объект term3 и вернуть ссылку на него (сахар для term3 := term; &term3;) + * + * + * copy(arg) := {}; # Обычная функция принимает любой аргумент как <КОПИЮ> значения + * copy(term1); # ОК - передается <КОПИЯ> term1 + * copy(term2); # ОК - передается <КОПИЯ> term2 + * copy(&term1); # ОК - передается ссылка на term1 (На самом деле копия ссылки, которая указывает на те же данные) + * copy(&term2); # ОК- передается ссылка на term2 (На самом деле копия ссылки, которая указывает на те же данные) + * + * ptr(&arg) := {}; # Функция, которая принимает только аргумент - <ссылку> + * ptr(term1); # Ошибка при компиляции - нужно передавать ссылку !!!!!!!! + * ptr(&term1); # ОК + * ptr(&term2); # ОК + * ptr(term2); # Ошибка при компиляции - нужно передавать ссылку, несмотря на то что term2 УЖЕ содержит ссылку !!!!!!!! + * + * + * + * + * <% - Кнстанты и свойста> + * Значением константы может быть любой литерал (строка или число) + * + * Так как константа определяется во время компиляции, то её значение может быть использовано компилятором + * для анализа исходного текста программы после парсинга ATS и на основе их значений влиять на генерируемый + * трансплайтером финальный код на языке реализации. + * + * Константа доступна во время выполнения для чтения как значение системного поля __option__ ( для константы %option) + * ::%option - Глобальная область видимости для константы + * + * С помощью констант реализуется одноименный функционал (переменные только для чтения), путем установки + * соответствующего поля (term%const=1; или term%const=0;) + * + * <Для релиза компилатора, т.к. требует анализа исходникой на уровне файла и предназаначена для генерации кода на С++> + * */ - + template class Iterator : public std::iterator { public: @@ -175,15 +210,15 @@ namespace newlang { typedef IterCmp CompareFuncType(const IterPairType &pair, const T *args, void *extra); - static const std::string FIND_KEY_DEFAULT; + // static const std::string FIND_KEY_DEFAULT; /** * Итератор для элементов списка с regex фильтром по имени элемента (по умолчанию для всех элементов списка) * @param obj * @param find_key */ - explicit Iterator(std::shared_ptr obj, const std::string find_key = Iterator::FIND_KEY_DEFAULT) : - Iterator(obj, &CompareFuncDefault, reinterpret_cast (const_cast (&find_key)), static_cast (this)) { + explicit Iterator(std::shared_ptr obj, const char * find_key = "(.|\\n)*") : + Iterator(obj, &CompareFuncDefault, reinterpret_cast (const_cast (find_key)), static_cast (this)) { } /** @@ -194,12 +229,12 @@ namespace newlang { * @param extra */ Iterator(std::shared_ptr obj, CompareFuncType *func, T *arg, void * extra = nullptr) : - m_iter_obj(obj), m_match(), m_func(func), m_func_args(arg), m_func_extra(extra), m_found(m_iter_obj->begin()) { + m_iter_obj(obj), m_match(), m_func(func), m_func_args(arg), m_func_extra(extra), m_found(m_iter_obj->begin()), m_base_filter(nullptr) { search_loop(); } Iterator(const Iterator &iter) : m_iter_obj(iter.m_iter_obj), m_match(iter.m_match), m_func(iter.m_func), - m_func_args(iter.m_func_args), m_func_extra(iter.m_func_extra), m_found(iter.m_found) { + m_func_args(iter.m_func_args), m_func_extra(iter.m_func_extra), m_found(iter.m_found), m_base_filter(iter.m_base_filter) { } SCOPE(private) : @@ -209,32 +244,36 @@ namespace newlang { CompareFuncType *m_func; T *m_func_args; void *m_func_extra; - mutable typename Variable::iterator m_found; + const char * m_base_filter; static const IterPairType m_interator_end; static IterCmp CompareFuncDefault(const IterPairType &pair, const T *filter, void *extra) { - const std::string * str_filter = reinterpret_cast (filter); + const char * str_filter = reinterpret_cast (filter); Iterator * iter = static_cast (extra); if (iter && str_filter) { - iter->m_func_args = nullptr; // Передается однократно при создании объекта - iter->m_filter = *str_filter; + iter->m_base_filter = str_filter; + iter->m_func_args = nullptr; // Строка для фильтрации передается однократно при создании объекта + iter->m_filter.assign(str_filter); if (!iter->m_filter.empty()) { try { iter->m_match = std::regex(iter->m_filter); } catch (const std::regex_error &err) { - LOG_RUNTIME("Regular expression for '%s' error '%s'!", str_filter->c_str(), err.what()); + LOG_RUNTIME("Regular expression for '%s' error '%s'!", str_filter, err.what()); } } } if (iter) { - if (iter->m_filter.empty()) { + if (iter->m_base_filter == nullptr) { // Без фильтра отдаются вообще все поля + return IterCmp::Yes; + } else if (iter->m_filter.empty()) { // Если передана пустая строка, то выдаются только поля без имен return pair.first.empty() ? IterCmp::Yes : IterCmp::No; } else { + // Иначе если имя поля совпадает с регуляркой return std::regex_match(pair.first, iter->m_match) ? IterCmp::Yes : IterCmp::No; } } @@ -401,7 +440,7 @@ namespace newlang { return shared(); } - virtual ObjPtr IteratorMake(const std::string, bool check_create = true); + virtual ObjPtr IteratorMake(const char * filter = nullptr, bool check_create = true); virtual ObjPtr IteratorMake(Obj *args); virtual ObjPtr IteratorData(); virtual ObjPtr IteratorReset(); @@ -484,10 +523,16 @@ namespace newlang { m_class_name = name; } - inline bool isConst() const { + [[nodiscard]] + inline bool is_const() const { return m_is_const; } + [[nodiscard]] + inline bool is_init() const { + return m_var_is_init; + } + [[nodiscard]] inline bool is_none_type() const { return m_var_type_current == ObjType::None; @@ -535,27 +580,27 @@ namespace newlang { } [[nodiscard]] - inline bool is_class() const { + inline bool is_class_type() const { return isClass(m_var_type_current); } [[nodiscard]] - inline bool is_simple() const { + inline bool is_simple_type() const { return isSimpleType(m_var_type_current); } [[nodiscard]] inline bool is_scalar() const { - return is_tensor() && !m_tensor.defined(); + return is_tensor_type() && !m_tensor.defined(); } [[nodiscard]] - inline bool is_function() const { + inline bool is_function_type() const { return isFunction(m_var_type_current); } [[nodiscard]] - inline bool is_tensor() const { + inline bool is_tensor_type() const { return isTensor(m_var_type_current); } @@ -581,7 +626,7 @@ namespace newlang { [[nodiscard]] inline bool is_indexing() const { - return is_tensor() || is_string_type() || is_dictionary_type() || is_class(); + return is_tensor_type() || is_string_type() || is_dictionary_type() || is_class_type() || is_error() || is_return() || is_function_type(); } [[nodiscard]] @@ -634,7 +679,7 @@ namespace newlang { return !m_var_is_init || m_value.empty(); } else if (m_var_type_current == ObjType::StrWide) { return !m_var_is_init || m_string.empty(); - } else if (is_tensor()) { + } else if (is_tensor_type()) { return !m_var_is_init || at::_is_zerotensor(m_tensor); } return Variable::empty(); @@ -673,7 +718,7 @@ namespace newlang { * @return */ ObjPtr operator()(Context *ctx) { - Obj args; + Obj args(ObjType::Dictionary); return Call(ctx, &args); } @@ -689,7 +734,7 @@ namespace newlang { } inline ObjPtr Call(Context *ctx) { - Obj args; + Obj args(ObjType::Dictionary); return Call(ctx, &args); } @@ -697,9 +742,9 @@ namespace newlang { typename std::enable_if::value, ObjPtr>::type inline Call(Context *ctx, T ... args) { auto list = {args...}; - Obj arg; + Obj arg(ObjType::Dictionary); for (auto &elem : list) { - arg.push_back(elem); + arg.Variable::push_back(elem); } return Call(ctx, &arg); } @@ -715,17 +760,26 @@ namespace newlang { template typename std::enable_if < std::is_integral::value && !std::is_pointer::value, const PairType &>::type inline operator[](const I index) { - return at(index); + if (is_indexing() || m_var_type_current == ObjType::Range) { + return at(index); + } + LOG_RUNTIME("Operator at for object type %s not implemented!", newlang::toString(m_var_type_current)); } template typename std::enable_if < std::is_same::value || std::is_pointer::value, const PairType &>::type inline operator[](const N name) { - return at(name); + if (is_indexing() || m_var_type_current == ObjType::Range) { + return at(name); + } + LOG_RUNTIME("Operator at for object type %s not implemented!", newlang::toString(m_var_type_current)); } Obj::iterator find(const std::string name) { - return Variable::find(name); + if (is_indexing() || m_var_type_current == ObjType::Range) { + return Variable::find(name); + } + LOG_RUNTIME("Operator find for object type %s not implemented!", newlang::toString(m_var_type_current)); } Obj::iterator begin() { @@ -743,31 +797,52 @@ namespace newlang { } Obj::const_iterator begin() const { - return Variable::begin(); + if (is_indexing() || m_var_type_current == ObjType::Range) { + return Variable::begin(); + } + LOG_RUNTIME("Interator for object type %s not implemented!", newlang::toString(m_var_type_current)); } Obj::const_iterator end() const { - return Variable::end(); + if (is_indexing() || m_var_type_current == ObjType::Range) { + return Variable::end(); + } + LOG_RUNTIME("Interator for object type %s not implemented!", newlang::toString(m_var_type_current)); } PairType & push_back(const PairType & p) { - return Variable::push_back(p); + if (is_indexing()) { + return Variable::push_back(p); + } + LOG_RUNTIME("Operator push_back for object type %s not implemented!", newlang::toString(m_var_type_current)); } PairType & push_back(const Type value, const std::string &name = "") { - return Variable::push_back(value, name); + if (is_indexing()) { + return Variable::push_back(value, name); + } + LOG_RUNTIME("Operator push_back for object type %s not implemented!", newlang::toString(m_var_type_current)); } Obj::iterator at_index(const int64_t index) { - return Variable::at_index(index); + if (is_indexing()) { + return Variable::at_index(index); + } + LOG_RUNTIME("Operator at_index for object type %s not implemented!", newlang::toString(m_var_type_current)); } Obj::const_iterator at_index_const(const int64_t index) const { - return Variable::at_index_const(index); + if (is_indexing()) { + return Variable::at_index_const(index); + } + LOG_RUNTIME("Operator at_index_const for object type %s not implemented!", newlang::toString(m_var_type_current)); } Obj::const_iterator insert(Obj::const_iterator pos, const PairType &data) { - return Variable::insert(pos, data); + if (is_indexing()) { + return Variable::insert(pos, data); + } + LOG_RUNTIME("Operator insert for object type %s not implemented!", newlang::toString(m_var_type_current)); } const std::string & name(const int64_t index) const override { @@ -775,15 +850,21 @@ namespace newlang { } int64_t resize(int64_t new_size, const Type fill, const std::string &name = "") override { - return Variable::resize(new_size, fill, name); + if (is_indexing()) { + return Variable::resize(new_size, fill, name); + } + LOG_RUNTIME("Operator resize for object type %s not implemented!", newlang::toString(m_var_type_current)); } void erase(const int64_t index) override { - Variable::erase(index); + if (is_indexing()) { + Variable::erase(index); + return; + } + LOG_RUNTIME("Operator erase(index) for object type %s not implemented!", newlang::toString(m_var_type_current)); } void clear_() override { - Variable::clear_(); clear_(true); } @@ -820,7 +901,7 @@ namespace newlang { ObjPtr operator-() { if (is_arithmetic_type()) { - if (is_tensor()) { + if (is_tensor_type()) { m_tensor = -m_tensor; } else if (is_integer()) { SetValue_(-GetValueAsInteger()); @@ -836,14 +917,14 @@ namespace newlang { ObjPtr & operator+(ObjPtr & obj) { - if (is_tensor()) { + if (is_tensor_type()) { return obj; } LOG_RUNTIME("Object '%s' not numeric!", obj->toString().c_str()); } ObjPtr &operator-(ObjPtr & obj) { - if (is_tensor()) { + if (is_tensor_type()) { obj->m_tensor = torch::zeros_like(obj->m_tensor) - obj->m_tensor; return obj; } @@ -854,7 +935,7 @@ namespace newlang { //префиксная версия возвращает значение после инкремента ObjPtr operator++() { - if (is_tensor()) { + if (is_tensor_type()) { m_tensor.add_(torch::ones_like(m_tensor)); return shared(); @@ -873,7 +954,7 @@ namespace newlang { //префиксная версия возвращает значение после декремента ObjPtr operator--() { - if (is_tensor()) { + if (is_tensor_type()) { m_tensor.sub_(torch::ones_like(m_tensor)); return shared(); } @@ -1254,7 +1335,7 @@ namespace newlang { } else { if (elem.second) { - if (deep || !(elem.second->is_tensor() || elem.second->getType() == ObjType::Class)) { + if (deep || !(elem.second->is_tensor_type() || elem.second->getType() == ObjType::Class)) { str.append(elem.first); str.append("="); str.append(elem.second->toString(false)); @@ -1401,7 +1482,7 @@ namespace newlang { return m_iterator->data().second->GetValueAsNumber(); default: - if (is_simple() || is_string_type()) { + if (is_simple_type() || is_string_type()) { return static_cast (GetValueAsInteger()); } } @@ -1409,7 +1490,7 @@ namespace newlang { } inline bool GetValueAsBoolean() const { - if (!m_var_is_init) { + if (!m_var_is_init || m_var_type_current == ObjType::IteratorEnd) { return false; } if (is_scalar()) { @@ -1428,7 +1509,7 @@ namespace newlang { return false; case ObjType::Fraction: - return m_fraction.GetAsInteger(); + return m_fraction.GetAsBoolean(); case ObjType::Dictionary: case ObjType::Class: @@ -1581,18 +1662,17 @@ namespace newlang { template static ObjPtr CreateRange(T1 start, T2 stop, T3 step) { - ObjPtr obj = CreateType(ObjType::Range); + ObjPtr obj = CreateType(ObjType::Dictionary, ObjType::Range, true); obj->push_back(CreateValue(start, ObjType::None), "start"); obj->push_back(CreateValue(stop, ObjType::None), "stop"); obj->push_back(CreateValue(step, ObjType::None), "step"); - obj->m_var_is_init = true; - + obj->m_var_type_current = ObjType::Range; return obj; } template static ObjPtr CreateRange(T1 start, T2 stop) { - ObjPtr obj = CreateType(ObjType::Range); + ObjPtr obj = CreateType(ObjType::Dictionary, ObjType::Range, true); obj->push_back(CreateValue(start, ObjType::None), "start"); obj->push_back(CreateValue(stop, ObjType::None), "stop"); if (start < stop) { @@ -1600,7 +1680,7 @@ namespace newlang { } else { obj->push_back(CreateValue(-1, ObjType::None), "step"); } - obj->m_var_is_init = true; + obj->m_var_type_current = ObjType::Range; return obj; } @@ -1730,7 +1810,7 @@ namespace newlang { default: LOG_RUNTIME("Fail convert scalar type '%s' to Index!", newlang::toString(m_var_type_current)); } - } else if (is_tensor()) { + } else if (is_tensor_type()) { return Index(m_tensor); } else if (is_ellipsis()) { return Index(at::indexing::Ellipsis); @@ -2069,7 +2149,7 @@ namespace newlang { if (value->is_none_type()) { clear_(); return; - } else if ((is_none_type() || is_tensor()) && value->is_tensor()) { + } else if ((is_none_type() || is_tensor_type()) && value->is_tensor_type()) { if (value->empty()) { m_var = at::monostate(); @@ -2230,7 +2310,8 @@ namespace newlang { // m_var_is_init = true; // return; - } else if ((is_none_type() || m_var_type_current == ObjType::Function) && value->is_function()) { + } else if (((is_none_type() || m_var_type_current == ObjType::Function) && value->is_function_type()) || + ((is_none_type() || m_var_type_current == ObjType::Pointer) && value->m_var_type_current == ObjType::Pointer)) { //@todo Check function type args !!! std::string old_name = m_var_name; diff --git a/src/test/alg_test.cpp b/src/test/alg_test.cpp index 8a3249fc..bc12c49f 100644 --- a/src/test/alg_test.cpp +++ b/src/test/alg_test.cpp @@ -275,7 +275,7 @@ TEST(Alg, Foreach) { ObjPtr tensor = ctx.ExecStr("tensor := [10,11,12,]"); ASSERT_TRUE(tensor); - ASSERT_TRUE(tensor->is_tensor()); + ASSERT_TRUE(tensor->is_tensor_type()); ASSERT_TRUE(tensor->GetValueAsBoolean()); ASSERT_EQ(3, tensor->size()); ASSERT_EQ(10, (*tensor)[0].second->GetValueAsInteger()); @@ -284,12 +284,12 @@ TEST(Alg, Foreach) { temp = ctx.ExecStr("counter, tensor := ... tensor "); ASSERT_TRUE(temp); - ASSERT_TRUE(temp->is_tensor()); + ASSERT_TRUE(temp->is_tensor_type()); ASSERT_EQ(2, temp->size()); ASSERT_EQ(10, counter->GetValueAsInteger()); - ASSERT_TRUE(tensor->is_tensor()); + ASSERT_TRUE(tensor->is_tensor_type()); ASSERT_TRUE(tensor->GetValueAsBoolean()); ASSERT_EQ(2, tensor ->size()); ASSERT_EQ(11, (*tensor)[0].second->GetValueAsInteger()); @@ -297,33 +297,33 @@ TEST(Alg, Foreach) { temp = ctx.ExecStr("counter, tensor := ... tensor "); ASSERT_TRUE(temp); - ASSERT_TRUE(temp->is_tensor()); + ASSERT_TRUE(temp->is_tensor_type()); ASSERT_EQ(1, temp->size()); ASSERT_EQ(11, counter->GetValueAsInteger()); - ASSERT_TRUE(tensor->is_tensor()); + ASSERT_TRUE(tensor->is_tensor_type()); ASSERT_TRUE(tensor->GetValueAsBoolean()); ASSERT_EQ(1, tensor ->size()); ASSERT_EQ(12, (*tensor)[0].second->GetValueAsInteger()); temp = ctx.ExecStr("counter, tensor := ... tensor "); ASSERT_TRUE(temp); - ASSERT_TRUE(temp->is_tensor()); + ASSERT_TRUE(temp->is_tensor_type()); ASSERT_EQ(0, temp->size()); ASSERT_EQ(12, counter->GetValueAsInteger()); - ASSERT_TRUE(tensor->is_tensor()); + ASSERT_TRUE(tensor->is_tensor_type()); ASSERT_FALSE(tensor->GetValueAsBoolean()); ASSERT_EQ(0, tensor ->size()); temp = ctx.ExecStr("counter, tensor := ... tensor"); ASSERT_TRUE(temp); - ASSERT_TRUE(temp->is_tensor()); + ASSERT_TRUE(temp->is_tensor_type()); ASSERT_TRUE(temp->empty()); ASSERT_FALSE(tensor->GetValueAsBoolean()); - ASSERT_TRUE(tensor->is_tensor()); + ASSERT_TRUE(tensor->is_tensor_type()); ASSERT_TRUE(tensor->empty()); ASSERT_TRUE(counter); @@ -338,7 +338,7 @@ TEST(Alg, Foreach) { ASSERT_TRUE(temp2->is_integer()); ASSERT_EQ(210, temp2->GetValueAsInteger()); ASSERT_EQ(210, summa2->GetValueAsInteger()); - ASSERT_TRUE(tensor2->is_tensor()); + ASSERT_TRUE(tensor2->is_tensor_type()); ASSERT_FALSE(tensor2->GetValueAsBoolean()); ObjPtr tensor_size = ctx.ExecStr("tensor_size := [10,20,30,40,]"); diff --git a/src/test/eval_test.cpp b/src/test/eval_test.cpp index efbd2fda..99621bee 100644 --- a/src/test/eval_test.cpp +++ b/src/test/eval_test.cpp @@ -92,7 +92,7 @@ TEST(Eval, Assign) { ObjPtr var_num = ctx.ExecStr("var_num := 123.456: Number"); ASSERT_TRUE(var_num); ASSERT_TRUE(var_num->is_arithmetic_type()); - ASSERT_TRUE(var_num->is_tensor()); + ASSERT_TRUE(var_num->is_tensor_type()); // ASSERT_EQ(var_num->m_var_type_current, ObjType::Double); // ASSERT_EQ(var_num->m_var_type_fixed, ObjType::Number); ASSERT_STREQ("var_num=123.456", var_num->toString().c_str()); @@ -108,7 +108,7 @@ TEST(Eval, Assign) { var_long = 987654321; ObjPtr var_export = ctx.ExecStr("var_export := :Pointer(\"var_long:Long\")"); ASSERT_TRUE(var_export); - ASSERT_TRUE(var_export->is_tensor()) << var_export; + ASSERT_TRUE(var_export->is_tensor_type()) << var_export; ASSERT_EQ(var_export->getType(), ObjType::Long); ASSERT_STREQ("var_export=987654321", var_export->toString().c_str()); var_long = 123132132; @@ -121,7 +121,7 @@ TEST(Eval, Assign) { ObjPtr func_export = ctx.ExecStr("func_export := :Pointer(\"func_export(arg1:Long, arg2:Char=100):Long\")"); ASSERT_TRUE(func_export); - ASSERT_TRUE(func_export->is_function()) << func_export; + ASSERT_TRUE(func_export->is_function_type()) << func_export; ASSERT_EQ(func_export->getType(), ObjType::NativeFunc); ASSERT_STREQ("func_export=func_export(arg1:Long, arg2:Char=100):Long{}", func_export->toString().c_str()); @@ -152,7 +152,7 @@ TEST(Eval, Assign) { // Функция возвращает словарь с именами объектов в текущем контексте ObjPtr func_eval = ctx.ExecStr("func_eval(arg1, arg2) := {$;}"); ASSERT_TRUE(func_eval); - ASSERT_TRUE(func_eval->is_function()) << func_eval; + ASSERT_TRUE(func_eval->is_function_type()) << func_eval; ASSERT_EQ(func_eval->getType(), ObjType::EVAL_FUNCTION) << toString(func_eval->getType()); ASSERT_STREQ("func_eval=func_eval(arg1, arg2):={$;}", func_eval->toString().c_str()); @@ -760,7 +760,7 @@ TEST(Eval, Convert) { ObjPtr scalar = ctx.ExecStr(":Int[0](0)"); ASSERT_TRUE(scalar); - ASSERT_TRUE(scalar->is_tensor()); + ASSERT_TRUE(scalar->is_tensor_type()); ASSERT_TRUE(scalar->is_scalar()); ASSERT_FALSE(scalar->m_tensor.defined()); ASSERT_EQ(ObjType::Int, scalar->getType()) << toString(scalar->m_var_type_current); @@ -773,7 +773,7 @@ TEST(Eval, Convert) { ObjPtr ten = ctx.ExecStr("[0,]"); ASSERT_TRUE(ten); - ASSERT_TRUE(ten->is_tensor()); + ASSERT_TRUE(ten->is_tensor_type()); ASSERT_FALSE(ten->is_scalar()); ASSERT_TRUE(ten->m_var_is_init); @@ -782,7 +782,7 @@ TEST(Eval, Convert) { ObjPtr obj_ten = ctx.ExecStr(":Int([0,])"); ASSERT_TRUE(obj_ten); - ASSERT_TRUE(obj_ten->is_tensor()); + ASSERT_TRUE(obj_ten->is_tensor_type()); ASSERT_FALSE(obj_ten->is_scalar()); ASSERT_EQ(at::ScalarType::Int, obj_ten->m_tensor.scalar_type()); ASSERT_EQ(ObjType::Int, obj_ten->getType()) << toString(obj_ten->m_var_type_current); @@ -834,7 +834,7 @@ TEST(Eval, Convert) { ObjPtr obj_frac = ctx.ExecStr(":Fraction(0)"); ASSERT_TRUE(obj_frac); - ASSERT_FALSE(obj_frac->is_tensor()); + ASSERT_FALSE(obj_frac->is_tensor_type()); ASSERT_FALSE(obj_frac->is_scalar()); ASSERT_EQ(ObjType::Fraction, obj_frac->getType()) << toString(obj_frac->m_var_type_current); @@ -1018,6 +1018,40 @@ TEST(Eval, Iterator) { ASSERT_STREQ("555", dict1->at(4).first.c_str()); + ObjPtr iter_d = dict->IteratorMake(); + + ASSERT_TRUE(iter_d); + ASSERT_EQ(iter_d->getType(), ObjType::Iterator); + + ASSERT_STREQ("1", iter_d->IteratorData()->toString().c_str()); + ASSERT_STREQ("1", iter_d->IteratorNext(0)->toString().c_str()); + + ASSERT_STREQ("2", iter_d->IteratorData()->toString().c_str()); + ASSERT_STREQ("2", iter_d->IteratorNext(0)->toString().c_str()); + + ASSERT_STREQ("3", iter_d->IteratorData()->toString().c_str()); + ASSERT_STREQ("3", iter_d->IteratorNext(0)->toString().c_str()); + + ASSERT_STREQ("4", iter_d->IteratorData()->toString().c_str()); + ASSERT_STREQ("4", iter_d->IteratorNext(0)->toString().c_str()); + + ASSERT_STREQ("5", iter_d->IteratorData()->toString().c_str()); + ASSERT_STREQ("5", iter_d->IteratorNext(0)->toString().c_str()); + + ASSERT_STREQ(":IteratorEnd", iter_d->IteratorData()->toString().c_str()); + ObjPtr iter_end = iter_d->IteratorNext(0); + ASSERT_TRUE(iter_end); + EXPECT_EQ(ObjType::IteratorEnd, iter_end->getType()) << newlang::toString(iter_end->getType()); + EXPECT_FALSE(iter_end->GetValueAsBoolean()); + ASSERT_STREQ(":IteratorEnd", iter_end->IteratorData()->toString().c_str()); + + iter_end = iter_d->IteratorNext(0); + ASSERT_TRUE(iter_end); + ASSERT_EQ(ObjType::IteratorEnd, iter_end->getType()); + ASSERT_FALSE(iter_end->GetValueAsBoolean()); + ASSERT_STREQ(":IteratorEnd", iter_d->IteratorData()->toString().c_str()); + + ObjPtr iter = ctx.ExecStr("iter := dict?"); ASSERT_TRUE(iter); @@ -1133,8 +1167,8 @@ TEST(Eval, Iterator) { ASSERT_EQ(3, flt3_res->at(0).second->GetValueAsInteger()); ASSERT_EQ(5, flt3_res->at(1).second->GetValueAsInteger()); - - + + ObjPtr range_test = ctx.ExecStr("1\\1..1..-1", nullptr, true); ASSERT_TRUE(range_test); ASSERT_EQ(3, range_test->size()); @@ -1163,8 +1197,10 @@ TEST(Eval, Iterator) { ASSERT_TRUE(iter_dict); ASSERT_STREQ("(3\\1, 2\\1,)", iter_dict->GetValueAsString().c_str()); - ObjPtr iter_test = ctx.ExecStr("@iter_test := 3\\1..1..-1?", nullptr, true); + ObjPtr iter_test = ctx.ExecStr("&@iter_test := 3\\1..1..-1?", nullptr, true); ASSERT_TRUE(iter_test); + ASSERT_TRUE(iter_test->m_iterator); + ASSERT_TRUE(iter_test->m_iterator->m_iter_obj); ASSERT_TRUE(iter_test->m_iterator->m_iter_obj->m_iter_range_value); ASSERT_STREQ("3\\1", iter_test->m_iterator->m_iter_obj->m_iter_range_value->GetValueAsString().c_str()) << iter_test->m_iterator->m_iter_obj->m_iter_range_value->GetValueAsString().c_str(); ASSERT_EQ(iter_test->getType(), ObjType::Iterator); @@ -1173,48 +1209,77 @@ TEST(Eval, Iterator) { ASSERT_TRUE(while_test); ASSERT_STREQ("EXIT", while_test->GetValueAsString().c_str()) << while_test->GetValueAsString().c_str(); - iter_test = ctx.ExecStr("@iter_dict := (1,2,3,)?", nullptr, true); - ASSERT_TRUE(iter_test); -// ASSERT_TRUE(iter_test->m_iterator->m_iter_obj->m_iter_range_value); -// ASSERT_STREQ("3\\1", iter_test->m_iterator->m_iter_obj->m_iter_range_value->GetValueAsString().c_str()) << iter_test->m_iterator->m_iter_obj->m_iter_range_value->GetValueAsString().c_str(); - ASSERT_EQ(iter_test->getType(), ObjType::Iterator); + iter_dict = ctx.ExecStr("@iter_dict := (1,2,3,)?", nullptr, true); + ASSERT_TRUE(iter_dict); + // ASSERT_TRUE(iter_dict->m_iterator->m_iter_obj->m_iter_range_value); + // ASSERT_STREQ("3\\1", iter_dict->m_iterator->m_iter_obj->m_iter_range_value->GetValueAsString().c_str()) << iter_test->m_iterator->m_iter_obj->m_iter_range_value->GetValueAsString().c_str(); + ASSERT_EQ(iter_dict->getType(), ObjType::Iterator); while_test = ctx.ExecStr("[iter_dict]<<-->>{--'EXIT'--}", nullptr, true); ASSERT_TRUE(while_test); ASSERT_STREQ("EXIT", while_test->GetValueAsString().c_str()) << while_test->GetValueAsString().c_str(); - iter_test = ctx.ExecStr("iter_test!?", nullptr, true); - ASSERT_TRUE(iter_test); - ASSERT_STREQ("3\\1", iter_test->GetValueAsString().c_str()); + ObjPtr item_val = ctx.ExecStr("iter_test!?", nullptr, true); + ASSERT_TRUE(item_val); + ASSERT_STREQ("3\\1", item_val->GetValueAsString().c_str()); - iter_test = ctx.ExecStr("iter_test!", nullptr, true); - ASSERT_TRUE(iter_test); - ASSERT_STREQ("3\\1", iter_test->GetValueAsString().c_str()); + item_val = ctx.ExecStr("iter_test!", nullptr, true); + ASSERT_TRUE(item_val); + ASSERT_STREQ("3\\1", item_val->GetValueAsString().c_str()); - iter_test = ctx.ExecStr("iter_test!?", nullptr, true); - ASSERT_TRUE(iter_test); - ASSERT_STREQ("2\\1", iter_test->GetValueAsString().c_str()); + item_val = ctx.ExecStr("iter_test!?", nullptr, true); + ASSERT_TRUE(item_val); + ASSERT_STREQ("2\\1", item_val->GetValueAsString().c_str()); - iter_test = ctx.ExecStr("iter_test?!", nullptr, true); - ASSERT_TRUE(iter_test); - ASSERT_STREQ("2\\1", iter_test->GetValueAsString().c_str()); + item_val = ctx.ExecStr("iter_test?!", nullptr, true); + ASSERT_TRUE(item_val); + ASSERT_STREQ("2\\1", item_val->GetValueAsString().c_str()); - iter_test = ctx.ExecStr("iter_test!", nullptr, true); - ASSERT_TRUE(iter_test); - ASSERT_STREQ("2\\1", iter_test->GetValueAsString().c_str()); + ASSERT_STREQ(":Iterator", iter_test->GetValueAsString().c_str()); + ASSERT_TRUE(iter_test->m_iterator); + ASSERT_TRUE(iter_test->m_iterator->m_iter_obj); + ASSERT_STREQ("2\\1", iter_test->m_iterator->m_iter_obj->m_iter_range_value->GetValueAsString().c_str()); + ASSERT_STREQ("3\\1..1..-1", iter_test->m_iterator->m_iter_obj->GetValueAsString().c_str()); - iter_test = ctx.ExecStr("iter_test!", nullptr, true); - ASSERT_TRUE(iter_test); - ASSERT_STREQ(":IteratorEnd", iter_test->GetValueAsString().c_str()); + item_val = ctx.ExecStr("iter_test!", nullptr, true); + ASSERT_TRUE(item_val); + ASSERT_STREQ("2\\1", item_val->GetValueAsString().c_str()); + ASSERT_TRUE(item_val->GetValueAsBoolean()); + + ASSERT_STREQ(":Iterator", iter_test->GetValueAsString().c_str()); + ASSERT_TRUE(iter_test->m_iterator); + ASSERT_TRUE(iter_test->m_iterator->m_iter_obj); + ASSERT_STREQ("1\\1", iter_test->m_iterator->m_iter_obj->m_iter_range_value->GetValueAsString().c_str()); + ASSERT_STREQ("3\\1..1..-1", iter_test->m_iterator->m_iter_obj->GetValueAsString().c_str()); + + item_val = ctx.ExecStr("iter_test!", nullptr, true); + ASSERT_TRUE(item_val); - iter_test = ctx.ExecStr("iter_test", nullptr, true); - ASSERT_TRUE(iter_test); ASSERT_STREQ(":Iterator", iter_test->GetValueAsString().c_str()); - - while_test = ctx.ExecStr("[iter_test]<<-->>{--'EXIT'--}", nullptr, true); + ASSERT_TRUE(iter_test->m_iterator); + ASSERT_TRUE(iter_test->m_iterator->m_iter_obj); + ASSERT_STREQ("1\\1", iter_test->m_iterator->m_iter_obj->m_iter_range_value->GetValueAsString().c_str()); + ASSERT_STREQ("3\\1..1..-1", iter_test->m_iterator->m_iter_obj->GetValueAsString().c_str()); + + + + ASSERT_TRUE(iter_test->m_iterator->m_iter_obj); + ASSERT_STREQ("3\\1..1..-1", iter_test->m_iterator->m_iter_obj->GetValueAsString().c_str()); + + ASSERT_STREQ(":IteratorEnd", item_val->GetValueAsString().c_str()); + ASSERT_FALSE(item_val->GetValueAsBoolean()); + + item_val = ctx.ExecStr("iter_test", nullptr, true); + ASSERT_TRUE(item_val); + ASSERT_STREQ(":Iterator", item_val->GetValueAsString().c_str()); + + ASSERT_STREQ(":IteratorEnd", item_val->IteratorData()->GetValueAsString().c_str()); + ASSERT_FALSE(item_val->IteratorNext(0)->GetValueAsBoolean()); + + while_test = ctx.ExecStr("[iter_test?!]<<-->>{--'EXIT'--}", nullptr, true); ASSERT_TRUE(while_test); ASSERT_STRNE("EXIT", while_test->GetValueAsString().c_str()) << while_test->GetValueAsString().c_str(); - + } //TEST(Eval, Brother) { diff --git a/src/test/example_test.cpp b/src/test/example_test.cpp index 9e594b1a..182c83aa 100644 --- a/src/test/example_test.cpp +++ b/src/test/example_test.cpp @@ -226,7 +226,7 @@ TEST(Example, Fraction) { ObjPtr test_arg = ctx.ExecStr("@test_arg(arg:Fraction) := {$arg}", nullptr, true); ASSERT_TRUE(test_arg); - ASSERT_TRUE(test_arg->is_function()); + ASSERT_TRUE(test_arg->is_function_type()); ASSERT_FALSE(test_arg->is_none_type()); ASSERT_STREQ("test_arg={}", test_arg->GetValueAsString().c_str()); diff --git a/src/test/parser_test.cpp b/src/test/parser_test.cpp index 5fe33830..432036df 100644 --- a/src/test/parser_test.cpp +++ b/src/test/parser_test.cpp @@ -1686,7 +1686,7 @@ TEST_F(ParserTest, Repeat6) { TEST_F(ParserTest, Repeat7) { ASSERT_TRUE(Parse("[test[0].@field != $test!] <<-->> if_1;")); - ASSERT_STREQ("[test[0].@field!=$test!]<<-->>if_1;", ast->toString().c_str()); + ASSERT_STREQ("[test[0].@field != $test!]<<-->>if_1;", ast->toString().c_str()); } TEST_F(ParserTest, Range) { @@ -1772,7 +1772,7 @@ TEST_F(ParserTest, Follow6) { // ASSERT_STREQ("(@test1)->{then1;},\n ($test2)->{then2;},\n (@test3+$test3)->{then3;},\n _ ->{else; else();};", ast->toString().c_str()); } -TEST_F(ParserTest, Follow7) { +TEST_F(ParserTest, DISABLED_Follow7) { ASSERT_TRUE(Parse("[test.field[0] > iter!!] -> if_1;")); // ASSERT_STREQ("(test.field[0].field2>iter!!)->{if_1;};", ast->toString().c_str()); } diff --git a/src/types.h b/src/types.h index b60e5717..a0886170 100644 --- a/src/types.h +++ b/src/types.h @@ -581,7 +581,7 @@ void ParserException(const char *msg, std::string &buffer, int row, int col); * Используется в интепретаторе и при выполнении для выдачи предупреждений */ inline bool canCastLimit(const ObjType from, const ObjType to) { - if (from == to || from == ObjType::None || to == ObjType::None) { + if (from == to || from == ObjType::None || to == ObjType::None || to == ObjType::Any) { // Преобразовывать ненужно или указан тип по по умолчанию return true; } else if (isSimpleType(from)) { diff --git a/src/variable.h b/src/variable.h index 139daefe..6beed8bc 100644 --- a/src/variable.h +++ b/src/variable.h @@ -71,6 +71,8 @@ namespace newlang { typedef PTR Type; typedef std::pair PairType; typedef std::list ListType; + + friend class Context; template typename std::enable_if < std::is_integral::value && !std::is_pointer::value, const PairType &>::type From e66940c06fa71df121a21d5526aa982e57c766af Mon Sep 17 00:00:00 2001 From: Aleksandr Ryabikov Date: Wed, 10 Aug 2022 07:52:14 +0300 Subject: [PATCH 30/31] =?UTF-8?q?=D0=9F=D1=80=D0=B8=D0=B2=D0=B5=D0=BB=20?= =?UTF-8?q?=D0=BA=20=D0=B5=D0=B4=D0=B8=D0=BD=D0=BE=D0=BC=D1=83=20=D0=B2?= =?UTF-8?q?=D0=B8=D0=B4=D1=83=20=D0=BD=D0=B0=D0=B8=D0=BC=D0=B5=D0=BD=D0=BE?= =?UTF-8?q?=D0=B2=D0=B0=D0=BD=D0=B8=D1=8F=20=D1=82=D0=B8=D0=BF=D0=BE=D0=B2?= =?UTF-8?q?=20(Char=20->=20Int8,=20Short=20->=20Int16=20=D0=B8=20=D1=82.?= =?UTF-8?q?=D0=B4.)=20=D0=B8=20=D0=BF=D0=B5=D1=80=D0=B5=D0=B8=D0=BC=D0=B5?= =?UTF-8?q?=D0=BD=D0=BE=D0=B2=D0=B0=D0=BB=20=D1=82=D0=B8=D0=BF=20Fraction?= =?UTF-8?q?=20=D0=B2=20Rational=20=D0=98=D1=81=D0=BF=D1=80=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D1=8B=20=D0=BE=D0=BF=D0=B5=D1=80=D0=B0=D1=82=D0=BE?= =?UTF-8?q?=D1=80=D1=8B,=20=D0=BF=D1=80=D0=B8=D0=B2=D0=BE=D0=B4=D1=8F?= =?UTF-8?q?=D1=89=D0=B8=D0=B5=20=D0=BA=20=D0=B8=D0=B7=D0=BC=D0=B5=D0=BD?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D1=8E=20=D1=80=D0=B5=D0=B7=D1=83=D0=BB=D1=8C?= =?UTF-8?q?=D1=82=D0=B8=D1=80=D1=83=D1=8E=D1=89=D0=B8=D1=85=20=D1=82=D0=B8?= =?UTF-8?q?=D0=BF=D0=BE=D0=B2=20(=D0=BD=D1=83=D0=B6=D0=BD=D0=BE=20=D0=B4?= =?UTF-8?q?=D1=83=D0=BC=D0=B0=D1=82=D1=8C,=20=D1=87=D1=82=D0=BE=20=D0=B4?= =?UTF-8?q?=D0=B5=D0=BB=D0=B0=D1=82=D1=8C=20=D1=81=20=D0=BF=D0=B5=D1=80?= =?UTF-8?q?=D0=B5=D0=BF=D0=BE=D0=BD=D0=B5=D0=BD=D0=B8=D0=B5=D0=BC=3F)=20?= =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=D1=8B=20=D0=BF?= =?UTF-8?q?=D1=80=D0=B8=D0=BC=D0=B5=D1=80=D1=8B=20=D0=BF=D1=80=D0=BE=D0=B3?= =?UTF-8?q?=D1=80=D0=B0=D0=BC=D0=BC=20=D0=A0=D0=B5=D0=B0=D0=BB=D0=B8=D0=B7?= =?UTF-8?q?=D0=BE=D0=B2=D0=B0=D0=BD=20=D0=B2=D1=8B=D0=B7=D0=BE=D0=B2=20?= =?UTF-8?q?=D0=BD=D0=B0=D1=82=D0=B8=D0=B2=D0=BD=D1=8B=D1=85=20=D1=84=D1=83?= =?UTF-8?q?=D0=BD=D0=BA=D1=86=D0=B8=D0=B9=20=D0=B1=D0=B5=D0=B7=20=D0=B2?= =?UTF-8?q?=D0=BE=D0=B7=D0=B2=D1=80=D0=B0=D1=89=D0=B0=D0=B5=D0=BC=D0=BE?= =?UTF-8?q?=D0=B3=D0=BE=20=D0=B7=D0=BD=D0=B0=D1=87=D0=B5=D0=BD=D0=B8=D1=8F?= =?UTF-8?q?=20(void)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- examples/dsl.nlp | 2 +- examples/fileio.nlp | 28 +- examples/foreach.nlp | 28 +- examples/{fraction.nlp => rational.nlp} | 10 +- examples/speed_test.nlp | 6 +- examples/speed_test.py | 2 +- examples/tensor.nlp | 25 ++ src/context.cpp | 76 ++-- src/lexer.l | 2 +- src/nbproject/Makefile-Debug.mk | 12 +- src/nbproject/Makefile-Debug_LLVM.mk | 12 +- src/nbproject/Makefile-GCOV.mk | 12 +- src/nbproject/Makefile-LLVM.mk | 12 +- src/nbproject/Makefile-LLVM_GCC.mk | 12 +- src/nbproject/Makefile-Release.mk | 12 +- src/nbproject/Makefile-UnitTest-Win32.mk | 12 +- src/nbproject/Makefile-UnitTest-Win64.mk | 12 +- src/nbproject/Makefile-UnitTest.mk | 12 +- src/nbproject/Makefile-UnitTest_LLVM.mk | 12 +- src/nbproject/configurations.xml | 155 +++++--- src/nbproject/project.xml | 1 + src/newlang.cpp | 4 +- src/object.cpp | 257 ++++++------- src/object.h | 161 +++++---- src/parser.y | 28 +- src/{fraction.h => rational.h} | 90 ++--- src/term.cpp | 2 +- src/term.h | 12 +- src/test/alg_test.cpp | 6 +- src/test/compiler_test.cpp | 14 +- src/test/eval_test.cpp | 342 +++++++++--------- src/test/example_test.cpp | 52 ++- src/test/lexer_test.cpp | 2 +- src/test/nlc_test.cpp | 2 +- src/test/object_test.cpp | 148 +++++--- src/test/parser_test.cpp | 196 +++++----- .../{fraction_test.cpp => rational_test.cpp} | 2 +- src/types.h | 146 ++++---- 38 files changed, 1038 insertions(+), 881 deletions(-) rename examples/{fraction.nlp => rational.nlp} (93%) create mode 100755 examples/tensor.nlp rename src/{fraction.h => rational.h} (80%) rename src/test/{fraction_test.cpp => rational_test.cpp} (98%) diff --git a/examples/dsl.nlp b/examples/dsl.nlp index 400cf2dc..fab8f08a 100755 --- a/examples/dsl.nlp +++ b/examples/dsl.nlp @@ -13,7 +13,7 @@ \parent \\$$\\\ \local \\$\\\ \global \\@\\\ -????????????? \int var\\${var}:Int\\\ # Use: \int integer = 100; ??????????????????????? +????????????? \int var\\${var}:Int32\\\ # Use: \int integer = 100; ??????????????????????? \if(cond) \\ ($cond) -> \\\ diff --git a/examples/fileio.nlp b/examples/fileio.nlp index f3444f6a..2d4bd7ec 100755 --- a/examples/fileio.nlp +++ b/examples/fileio.nlp @@ -14,15 +14,15 @@ #extern FILE *fdopen (int __fd, const char *__modes) __THROW __wur; -@fclose(stream:File):Int ::= :Pointer("fclose(stream:File):Int");; -#@fcloseall():Int ::= :Pointer("fcloseall():Int");; +@fclose(stream:File):Int32 ::= :Pointer("fclose(stream:File):Int32");; +#@fcloseall():Int32 ::= :Pointer("fcloseall():Int32");; -@fflush(stream:File):Int ::= :Pointer("fflush(stream:File):Int");; -#@fflush_unlocked(stream:File):Int ::= :Pointer("fflush_unlocked(stream:File):Int");; +@fflush(stream:File):Int32 ::= :Pointer("fflush(stream:File):Int32");; +#@fflush_unlocked(stream:File):Int32 ::= :Pointer("fflush_unlocked(stream:File):Int32");; -@fremove(filename:String):Int ::= :Pointer("remove(filename:StrChar):Int");; +@fremove(filename:String):Int32 ::= :Pointer("remove(filename:StrChar):Int32");; -@frename(old:String, new:String):Int ::= :Pointer("rename(old:StrChar, new:StrChar):Int");; +@frename(old:String, new:String):Int32 ::= :Pointer("rename(old:StrChar, new:StrChar):Int32");; @ftmpfile():File ::= :Pointer("tmpfile():File");; #@ftmpfile64():File ::= :Pointer("tmpfile64():File");; @@ -34,17 +34,17 @@ -@fprintf(stream:File, format:FmtChar, ...):Int ::= :Pointer("fprintf(stream:File, format:FmtChar, ...):Int");; -@fscanf(stream:File, format:FmtChar, ...):Int ::= :Pointer("fscanf(stream:File, format:FmtChar, ...):Int");; +@fprintf(stream:File, format:FmtChar, ...):Int32 ::= :Pointer("fprintf(stream:File, format:FmtChar, ...):Int32");; +@fscanf(stream:File, format:FmtChar, ...):Int32 ::= :Pointer("fscanf(stream:File, format:FmtChar, ...):Int32");; -@fgetc(stream:File):Int ::= :Pointer("fgetc(stream:File):Int");; +@fgetc(stream:File):Int32 ::= :Pointer("fgetc(stream:File):Int32");; -#@fgetc_unlocked(stream:File):Int ::= :Pointer("fgetc_unlocked(stream:File):Int");; +#@fgetc_unlocked(stream:File):Int32 ::= :Pointer("fgetc_unlocked(stream:File):Int32");; -@fungetc(c:Int, stream:File):Int ::= :Pointer("ungetc(c:Int, stream:File):Int");; +@fungetc(c:Int32, stream:File):Int32 ::= :Pointer("ungetc(c:Int32, stream:File):Int32");; -@fputc(c:Int, stream:File):Int ::= :Pointer("fputc(c:Int, stream:File):Int");; -@fputs(string:String, stream:File):Int ::= :Pointer("fputs(c:StrChar, stream:File):Int");; +@fputc(c:Int32, stream:File):Int32 ::= :Pointer("fputc(c:Int32, stream:File):Int32");; +@fputs(string:String, stream:File):Int32 ::= :Pointer("fputs(c:StrChar, stream:File):Int32");; #extern size_t fread (void *__restrict __ptr, size_t __size, @@ -60,7 +60,7 @@ # size_t __n, FILE *__restrict __stream); # SEEK ::= :Enum(SET=0, CUR=1, END=2); -@fseek(stream:File, offset:Long, whence:Int):Int ::= :Pointer("fseek(stream:File, offset:Long, whence:Int):Int");; +@fseek(stream:File, offset:Int64, whence:Int32):Int32 ::= :Pointer("fseek(stream:File, offset:Int64, whence:Int32):Int32");; #extern long int ftell (FILE *__stream) __wur; diff --git a/examples/foreach.nlp b/examples/foreach.nlp index cda266cc..b5da5d8f 100755 --- a/examples/foreach.nlp +++ b/examples/foreach.nlp @@ -14,15 +14,15 @@ #extern FILE *fdopen (int __fd, const char *__modes) __THROW __wur; -@fclose(stream:File):Int ::= :Pointer("fclose(stream:File):Int");; -@fcloseall():Int ::= :Pointer("fcloseall():Int");; +@fclose(stream:File):Int32 ::= :Pointer("fclose(stream:File):Int32");; +@fcloseall():Int32 ::= :Pointer("fcloseall():Int32");; -@fflush(stream:File):Int ::= :Pointer("fflush(stream:File):Int");; -@fflush_unlocked(stream:File):Int ::= :Pointer("fflush_unlocked(stream:File):Int");; +@fflush(stream:File):Int32 ::= :Pointer("fflush(stream:File):Int32");; +@fflush_unlocked(stream:File):Int32 ::= :Pointer("fflush_unlocked(stream:File):Int32");; -@fremove(filename:String):Int ::= :Pointer("remove(filename:StrChar):Int");; +@fremove(filename:String):Int32 ::= :Pointer("remove(filename:StrChar):Int32");; -@frename(old:String, new:String):Int ::= :Pointer("rename(old:StrChar, new:StrChar):Int");; +@frename(old:String, new:String):Int32 ::= :Pointer("rename(old:StrChar, new:StrChar):Int32");; @ftmpfile():File ::= :Pointer("tmpfile():File");; @ftmpfile64():File ::= :Pointer("tmpfile64():File");; @@ -34,17 +34,17 @@ -@fprintf(stream:File, format:Format, ...):Int ::= :Pointer("fprintf(stream:File, format:Format, ...):Int");; -@fscanf(stream:File, format:Format, ...):Int ::= :Pointer("fscanf(stream:File, format:Format, ...):Int");; +@fprintf(stream:File, format:Format, ...):Int32 ::= :Pointer("fprintf(stream:File, format:Format, ...):Int32");; +@fscanf(stream:File, format:Format, ...):Int32 ::= :Pointer("fscanf(stream:File, format:Format, ...):Int32");; -@fgetc(stream:File):Int ::= :Pointer("fgetc(stream:File):Int");; +@fgetc(stream:File):Int32 ::= :Pointer("fgetc(stream:File):Int32");; -@fgetc_unlocked(stream:File):Int ::= :Pointer("fgetc_unlocked(stream:File):Int");; +@fgetc_unlocked(stream:File):Int32 ::= :Pointer("fgetc_unlocked(stream:File):Int32");; -@fungetc(c:Int, stream:File):Int ::= :Pointer("ungetc(c:Int, stream:File):Int");; +@fungetc(c:Int32, stream:File):Int32 ::= :Pointer("ungetc(c:Int32, stream:File):Int32");; -@fputc(c:Int, stream:File):Int ::= :Pointer("fputc(c:Int, stream:File):Int");; -@fputs(string:String, stream:File):Int ::= :Pointer("fputs(c:StrChar, stream:File):Int");; +@fputc(c:Int32, stream:File):Int32 ::= :Pointer("fputc(c:Int32, stream:File):Int32");; +@fputs(string:String, stream:File):Int32 ::= :Pointer("fputs(c:StrChar, stream:File):Int32");; #extern size_t fread (void *__restrict __ptr, size_t __size, @@ -60,7 +60,7 @@ # size_t __n, FILE *__restrict __stream); # SEEK ::= :Enum(SET=0, CUR=1, END=2); -@fseek(stream:File, offset:Long, whence:Int):Int ::= :Pointer("fseek(stream:File, offset:Long, whence:Int):Int");; +@fseek(stream:File, offset:Int64, whence:Int32):Int32 ::= :Pointer("fseek(stream:File, offset:Int64, whence:Int32):Int32");; #extern long int ftell (FILE *__stream) __wur; diff --git a/examples/fraction.nlp b/examples/rational.nlp similarity index 93% rename from examples/fraction.nlp rename to examples/rational.nlp index 6c5108e4..ef1375c3 100755 --- a/examples/fraction.nlp +++ b/examples/rational.nlp @@ -1,8 +1,8 @@ #!../output/nlc --eval -@printf := :Pointer('printf(format:FmtChar, ...):Int'); +@printf := :Pointer('printf(format:FmtChar, ...):Int32'); -@fact_int(n:Int) := { +@fact_int(n:Int32) := { [n > 1] --> { n *= fact_int(n-1); }, [n==1] --> { @@ -24,7 +24,7 @@ printf('Recursive factorial with integer overflow at most 13!:\n'); -@fact_range(n:Fraction) := { +@fact_range(n:Rational) := { [n > 2] --> { iter := (n-1)..1..-1?; # Итератор для множителей [iter?!] <<-->> { @@ -34,9 +34,9 @@ printf('Recursive factorial with integer overflow at most 13!:\n'); n }; -printf('Recursive factorial without overflow with fractional value:\n'); +printf('Recursive factorial without overflow with rationalal value:\n'); @big := (1, 2, 3, 4, 5, 10, 11, 12, 13, 20, 30, 100, 1000,)?; -@frac := 0\1; # fraction value support bigint +@frac := 0\1; # rational value support bigint [ big ] <<-->> { printf('%s! -> ', :StrChar(big?!)); diff --git a/examples/speed_test.nlp b/examples/speed_test.nlp index 78f7f927..f1aaf1bc 100755 --- a/examples/speed_test.nlp +++ b/examples/speed_test.nlp @@ -1,10 +1,10 @@ #!../output/nlc -@printf := :Pointer('printf(format:FmtChar, ...):Int'); +@printf := :Pointer('printf(format:FmtChar, ...):Int32'); printf('\nStart speed test NewLang\n'); -@convert := :Pointer('convert(sym:Char):Char'); +@convert := :Pointer('convert(sym:Int8):Int8'); /* @convert(c) := {{ @@ -69,7 +69,7 @@ printf('From %s to %s\n', s, s_last ); }; }; -printf('Number of generated k-mers: %d\n', counter); +printf('Float of generated k-mers: %d\n', counter); "OK"; diff --git a/examples/speed_test.py b/examples/speed_test.py index 5c760570..8001aef9 100755 --- a/examples/speed_test.py +++ b/examples/speed_test.py @@ -37,5 +37,5 @@ def convert(c): # You can uncomment the next line to see all k-mers. # print(s) -print("Number of generated k-mers: {}".format(counter)) +print("Float of generated k-mers: {}".format(counter)) diff --git a/examples/tensor.nlp b/examples/tensor.nlp new file mode 100755 index 00000000..159f3a53 --- /dev/null +++ b/examples/tensor.nlp @@ -0,0 +1,25 @@ +#!../output/nlc --eval + +@printf := :Pointer('printf(format:FmtChar, ...):Int32'); + +@tensor := :Tensor[5,5](1, -2, 3, 4, 5, 6, 42, ...); +printf('%s\n', :StrChar(tensor)); + +@mult := tensor * 100; +printf('*=2 -> %s\n', :StrChar(mult)); + +mult += 11; +printf('+= 11 -> %s\n', :StrChar(mult)); + +@srand := :Pointer('srand(seed:Int32):None'); +srand(100); +@rand := :Pointer('rand():Int32'); +@matrix := :Tensor[10,10]( ... rand() ...); +printf('rand -> %s\n', :StrChar(matrix)); + +@matrix *= 1; +printf('rand -> %s\n', :StrChar(matrix)); + + +# Check factorial 1000! +[ matrix ] -> "OK"; \ No newline at end of file diff --git a/src/context.cpp b/src/context.cpp index fe22e491..15fbb51a 100644 --- a/src/context.cpp +++ b/src/context.cpp @@ -86,23 +86,23 @@ Context::Context(RuntimePtr global) : m_llvm_builder(LLVMCreateBuilder()) { VERIFY(RegisterTypeHierarchy(ObjType::Any,{})); VERIFY(RegisterTypeHierarchy(ObjType::Arithmetic,{":Any"})); - VERIFY(RegisterTypeHierarchy(ObjType::Fraction,{":Arithmetic"})); + VERIFY(RegisterTypeHierarchy(ObjType::Rational,{":Arithmetic"})); VERIFY(RegisterTypeHierarchy(ObjType::Tensor,{":Arithmetic"})); VERIFY(RegisterTypeHierarchy(ObjType::Integer,{":Tensor"})); VERIFY(RegisterTypeHierarchy(ObjType::Bool,{":Integer"})); - VERIFY(RegisterTypeHierarchy(ObjType::Char,{":Integer"})); - VERIFY(RegisterTypeHierarchy(ObjType::Short,{":Integer"})); - VERIFY(RegisterTypeHierarchy(ObjType::Int,{":Integer"})); - VERIFY(RegisterTypeHierarchy(ObjType::Long,{":Integer"})); + VERIFY(RegisterTypeHierarchy(ObjType::Int8,{":Integer"})); + VERIFY(RegisterTypeHierarchy(ObjType::Int16,{":Integer"})); + VERIFY(RegisterTypeHierarchy(ObjType::Int32,{":Integer"})); + VERIFY(RegisterTypeHierarchy(ObjType::Int64,{":Integer"})); - VERIFY(RegisterTypeHierarchy(ObjType::Number,{":Tensor"})); - VERIFY(RegisterTypeHierarchy(ObjType::Float,{":Number"})); - VERIFY(RegisterTypeHierarchy(ObjType::Double,{":Number"})); + VERIFY(RegisterTypeHierarchy(ObjType::Float,{":Tensor"})); + VERIFY(RegisterTypeHierarchy(ObjType::Float32,{":Float"})); + VERIFY(RegisterTypeHierarchy(ObjType::Float64,{":Float"})); VERIFY(RegisterTypeHierarchy(ObjType::Complex,{":Tensor"})); - VERIFY(RegisterTypeHierarchy(ObjType::ComplexFloat,{":Complex"})); - VERIFY(RegisterTypeHierarchy(ObjType::ComplexDouble,{":Complex"})); + VERIFY(RegisterTypeHierarchy(ObjType::Complex32,{":Complex"})); + VERIFY(RegisterTypeHierarchy(ObjType::Complex64,{":Complex"})); VERIFY(RegisterTypeHierarchy(ObjType::String,{":Any"})); VERIFY(RegisterTypeHierarchy(ObjType::StrChar,{":String"})); @@ -409,7 +409,7 @@ inline ObjPtr Context::eval_EVAL(Context *ctx, const TermPtr &term, Obj *args) { return CreateRVal(ctx, term, args); } -inline ObjPtr Context::eval_FRACTION(Context *ctx, const TermPtr &term, Obj *args) { +inline ObjPtr Context::eval_RATIONAL(Context *ctx, const TermPtr &term, Obj *args) { return CreateRVal(ctx, term, args); } @@ -1475,12 +1475,12 @@ ObjPtr Context::CreateNative(TermPtr proto, const char *module, bool lazzy, cons type = typeFromString(proto->m_type_name, this); switch(type) { case ObjType::Bool: - case ObjType::Char: - case ObjType::Short: - case ObjType::Int: - case ObjType::Long: - case ObjType::Float: - case ObjType::Double: + case ObjType::Int8: + case ObjType::Int16: + case ObjType::Int32: + case ObjType::Int64: + case ObjType::Float32: + case ObjType::Float64: case ObjType::Pointer: break; default: @@ -1516,22 +1516,22 @@ ObjPtr Context::CreateNative(TermPtr proto, const char *module, bool lazzy, cons case ObjType::Bool: result->m_var = static_cast (ptr); break; - case ObjType::Char: + case ObjType::Int8: result->m_var = static_cast (ptr); break; - case ObjType::Short: + case ObjType::Int16: result->m_var = static_cast (ptr); break; - case ObjType::Int: + case ObjType::Int32: result->m_var = static_cast (ptr); break; - case ObjType::Long: + case ObjType::Int64: result->m_var = static_cast (ptr); break; - case ObjType::Float: + case ObjType::Float32: result->m_var = static_cast (ptr); break; - case ObjType::Double: + case ObjType::Float64: result->m_var = static_cast (ptr); break; @@ -1761,15 +1761,15 @@ void Context::ItemTensorEval_(torch::Tensor &tensor, c10::IntArrayRef shape, std for (ind[pos] = 0; ind[pos].integer() < shape[pos]; ind[pos] = ind[pos].integer() + 1) { switch(type) { - case ObjType::Char: - case ObjType::Short: - case ObjType::Int: - case ObjType::Long: + case ObjType::Int8: + case ObjType::Int16: + case ObjType::Int32: + case ObjType::Int64: value = at::Scalar(obj->Call(this)->GetValueAsInteger()); // args tensor.index_put_(ind, value); break; - case ObjType::Float: - case ObjType::Double: + case ObjType::Float32: + case ObjType::Float64: value = at::Scalar(obj->Call(this)->GetValueAsNumber()); // args tensor.index_put_(ind, value); @@ -1792,32 +1792,32 @@ void Context::ItemTensorEval(torch::Tensor &self, ObjPtr obj, ObjPtr args) { double *ptr_double = nullptr; switch(fromTorchType(self.scalar_type())) { - case ObjType::Char: + case ObjType::Int8: ptr_char = self.data_ptr(); ASSERT(ptr_char); *ptr_char = static_cast (obj->Call(this)->GetValueAsInteger()); return; - case ObjType::Short: + case ObjType::Int16: ptr_short = self.data_ptr(); ASSERT(ptr_short); *ptr_short = static_cast (obj->Call(this)->GetValueAsInteger()); return; - case ObjType::Int: + case ObjType::Int32: ptr_int = self.data_ptr(); ASSERT(ptr_int); *ptr_int = static_cast (obj->Call(this)->GetValueAsInteger()); return; - case ObjType::Long: + case ObjType::Int64: ptr_long = self.data_ptr(); ASSERT(ptr_long); *ptr_long = static_cast (obj->Call(this)->GetValueAsInteger()); return; - case ObjType::Float: + case ObjType::Float32: ptr_float = self.data_ptr(); ASSERT(ptr_float); *ptr_float = static_cast (obj->Call(this)->GetValueAsNumber()); return; - case ObjType::Double: + case ObjType::Float64: ptr_double = self.data_ptr(); ASSERT(ptr_double); *ptr_double = static_cast (obj->Call(this)->GetValueAsNumber()); @@ -2299,8 +2299,8 @@ ObjPtr Context::CreateRVal(Context *ctx, TermPtr term, Obj * local_vars, bool in return result; - case TermID::FRACTION: - return Obj::CreateFraction(term->m_text); + case TermID::RATIONAL: + return Obj::CreateRational(term->m_text); case TermID::ITERATOR: @@ -2334,7 +2334,7 @@ ObjPtr Context::CreateRVal(Context *ctx, TermPtr term, Obj * local_vars, bool in * Операторы ?! и !? эквивалентны и возвращают текущие данные без перемещения указателя итератора. * * Оператор ?? создает итератор и сразу его выполняет, возвращая все значения - * в виде элементов словаря, т.е. аналог последовательности ?(LINQ); !(:Long.__max__); + * в виде элементов словаря, т.е. аналог последовательности ?(LINQ); !(:Int64.__max__); * * Оператор !! - сбрасывает итератор в начальное состояние и возвращает первый элемент */ diff --git a/src/lexer.l b/src/lexer.l index e1044064..57eb95f5 100644 --- a/src/lexer.l +++ b/src/lexer.l @@ -366,7 +366,7 @@ term [$@%]({ualpha}|[_])?({name})? -?{number}[-+]{number}j | {number}j YY_TOKEN(COMPLEX); -?{number}[-+]{number}i | {number}i YY_TOKEN(COMPLEX); --?{integer}\\-?{integer} YY_TOKEN(FRACTION); +-?{integer}\\-?{integer} YY_TOKEN(RATIONAL); -?{integer} YY_TOKEN(INTEGER); {number} YY_TOKEN(NUMBER); diff --git a/src/nbproject/Makefile-Debug.mk b/src/nbproject/Makefile-Debug.mk index bc4b3533..6cae2677 100644 --- a/src/nbproject/Makefile-Debug.mk +++ b/src/nbproject/Makefile-Debug.mk @@ -51,11 +51,11 @@ OBJECTFILES= \ ${OBJECTDIR}/test/compiler_test.o \ ${OBJECTDIR}/test/eval_test.o \ ${OBJECTDIR}/test/example_test.o \ - ${OBJECTDIR}/test/fraction_test.o \ ${OBJECTDIR}/test/lexer_test.o \ ${OBJECTDIR}/test/nlc_test.o \ ${OBJECTDIR}/test/object_test.o \ ${OBJECTDIR}/test/parser_test.o \ + ${OBJECTDIR}/test/rational_test.o \ ${OBJECTDIR}/variable.o \ ${OBJECTDIR}/version.o @@ -224,11 +224,6 @@ ${OBJECTDIR}/test/example_test.o: test/example_test.cpp pch.h.gch ${RM} "$@.d" $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I. -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/example_test.o test/example_test.cpp -${OBJECTDIR}/test/fraction_test.o: test/fraction_test.cpp - ${MKDIR} -p ${OBJECTDIR}/test - ${RM} "$@.d" - $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I. -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/fraction_test.o test/fraction_test.cpp - ${OBJECTDIR}/test/lexer_test.o: test/lexer_test.cpp pch.h.gch ${MKDIR} -p ${OBJECTDIR}/test ${RM} "$@.d" @@ -249,6 +244,11 @@ ${OBJECTDIR}/test/parser_test.o: test/parser_test.cpp pch.h.gch ${RM} "$@.d" $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I. -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/parser_test.o test/parser_test.cpp +${OBJECTDIR}/test/rational_test.o: test/rational_test.cpp + ${MKDIR} -p ${OBJECTDIR}/test + ${RM} "$@.d" + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I. -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/rational_test.o test/rational_test.cpp + : types.h pch.h.gch @echo Выполнение шага пользовательского сборки diff --git a/src/nbproject/Makefile-Debug_LLVM.mk b/src/nbproject/Makefile-Debug_LLVM.mk index 6fc44275..d6152f08 100644 --- a/src/nbproject/Makefile-Debug_LLVM.mk +++ b/src/nbproject/Makefile-Debug_LLVM.mk @@ -51,11 +51,11 @@ OBJECTFILES= \ ${OBJECTDIR}/test/compiler_test.o \ ${OBJECTDIR}/test/eval_test.o \ ${OBJECTDIR}/test/example_test.o \ - ${OBJECTDIR}/test/fraction_test.o \ ${OBJECTDIR}/test/lexer_test.o \ ${OBJECTDIR}/test/nlc_test.o \ ${OBJECTDIR}/test/object_test.o \ ${OBJECTDIR}/test/parser_test.o \ + ${OBJECTDIR}/test/rational_test.o \ ${OBJECTDIR}/variable.o \ ${OBJECTDIR}/version.o @@ -190,11 +190,6 @@ ${OBJECTDIR}/test/example_test.o: test/example_test.cpp ${RM} "$@.d" $(COMPILE.cc) -g -O2 -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I. -I.. -I/usr/lib/llvm-13/lib/clang/13.0.1/include -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/example_test.o test/example_test.cpp -${OBJECTDIR}/test/fraction_test.o: test/fraction_test.cpp - ${MKDIR} -p ${OBJECTDIR}/test - ${RM} "$@.d" - $(COMPILE.cc) -g -O2 -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I. -I.. -I/usr/lib/llvm-13/lib/clang/13.0.1/include -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/fraction_test.o test/fraction_test.cpp - ${OBJECTDIR}/test/lexer_test.o: test/lexer_test.cpp ${MKDIR} -p ${OBJECTDIR}/test ${RM} "$@.d" @@ -215,6 +210,11 @@ ${OBJECTDIR}/test/parser_test.o: test/parser_test.cpp ${RM} "$@.d" $(COMPILE.cc) -g -O2 -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I. -I.. -I/usr/lib/llvm-13/lib/clang/13.0.1/include -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/parser_test.o test/parser_test.cpp +${OBJECTDIR}/test/rational_test.o: test/rational_test.cpp + ${MKDIR} -p ${OBJECTDIR}/test + ${RM} "$@.d" + $(COMPILE.cc) -g -O2 -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I. -I.. -I/usr/lib/llvm-13/lib/clang/13.0.1/include -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/rational_test.o test/rational_test.cpp + ${OBJECTDIR}/variable.o: variable.cpp ${MKDIR} -p ${OBJECTDIR} ${RM} "$@.d" diff --git a/src/nbproject/Makefile-GCOV.mk b/src/nbproject/Makefile-GCOV.mk index 0d6b593c..dabab067 100644 --- a/src/nbproject/Makefile-GCOV.mk +++ b/src/nbproject/Makefile-GCOV.mk @@ -52,11 +52,11 @@ OBJECTFILES= \ ${OBJECTDIR}/test/compiler_test.o \ ${OBJECTDIR}/test/eval_test.o \ ${OBJECTDIR}/test/example_test.o \ - ${OBJECTDIR}/test/fraction_test.o \ ${OBJECTDIR}/test/lexer_test.o \ ${OBJECTDIR}/test/nlc_test.o \ ${OBJECTDIR}/test/object_test.o \ ${OBJECTDIR}/test/parser_test.o \ + ${OBJECTDIR}/test/rational_test.o \ ${OBJECTDIR}/variable.o \ ${OBJECTDIR}/version.o @@ -194,11 +194,6 @@ ${OBJECTDIR}/test/example_test.o: test/example_test.cpp ${RM} "$@.d" $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/example_test.o test/example_test.cpp -${OBJECTDIR}/test/fraction_test.o: test/fraction_test.cpp - ${MKDIR} -p ${OBJECTDIR}/test - ${RM} "$@.d" - $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/fraction_test.o test/fraction_test.cpp - ${OBJECTDIR}/test/lexer_test.o: test/lexer_test.cpp ${MKDIR} -p ${OBJECTDIR}/test ${RM} "$@.d" @@ -219,6 +214,11 @@ ${OBJECTDIR}/test/parser_test.o: test/parser_test.cpp ${RM} "$@.d" $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/parser_test.o test/parser_test.cpp +${OBJECTDIR}/test/rational_test.o: test/rational_test.cpp + ${MKDIR} -p ${OBJECTDIR}/test + ${RM} "$@.d" + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/rational_test.o test/rational_test.cpp + ${OBJECTDIR}/variable.o: variable.cpp ${MKDIR} -p ${OBJECTDIR} ${RM} "$@.d" diff --git a/src/nbproject/Makefile-LLVM.mk b/src/nbproject/Makefile-LLVM.mk index 603bfb34..f4e19262 100644 --- a/src/nbproject/Makefile-LLVM.mk +++ b/src/nbproject/Makefile-LLVM.mk @@ -52,11 +52,11 @@ OBJECTFILES= \ ${OBJECTDIR}/test/compiler_test.o \ ${OBJECTDIR}/test/eval_test.o \ ${OBJECTDIR}/test/example_test.o \ - ${OBJECTDIR}/test/fraction_test.o \ ${OBJECTDIR}/test/lexer_test.o \ ${OBJECTDIR}/test/nlc_test.o \ ${OBJECTDIR}/test/object_test.o \ ${OBJECTDIR}/test/parser_test.o \ + ${OBJECTDIR}/test/rational_test.o \ ${OBJECTDIR}/variable.o \ ${OBJECTDIR}/version.o @@ -194,11 +194,6 @@ ${OBJECTDIR}/test/example_test.o: test/example_test.cpp ${RM} "$@.d" $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I/usr/lib/llvm-12/lib/clang/12.0.1/include -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I.. -std=c++14 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/example_test.o test/example_test.cpp -${OBJECTDIR}/test/fraction_test.o: test/fraction_test.cpp - ${MKDIR} -p ${OBJECTDIR}/test - ${RM} "$@.d" - $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I/usr/lib/llvm-12/lib/clang/12.0.1/include -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I.. -std=c++14 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/fraction_test.o test/fraction_test.cpp - ${OBJECTDIR}/test/lexer_test.o: test/lexer_test.cpp ${MKDIR} -p ${OBJECTDIR}/test ${RM} "$@.d" @@ -219,6 +214,11 @@ ${OBJECTDIR}/test/parser_test.o: test/parser_test.cpp ${RM} "$@.d" $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I/usr/lib/llvm-12/lib/clang/12.0.1/include -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I.. -std=c++14 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/parser_test.o test/parser_test.cpp +${OBJECTDIR}/test/rational_test.o: test/rational_test.cpp + ${MKDIR} -p ${OBJECTDIR}/test + ${RM} "$@.d" + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I/usr/lib/llvm-12/lib/clang/12.0.1/include -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I.. -std=c++14 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/rational_test.o test/rational_test.cpp + ${OBJECTDIR}/variable.o: variable.cpp ${MKDIR} -p ${OBJECTDIR} ${RM} "$@.d" diff --git a/src/nbproject/Makefile-LLVM_GCC.mk b/src/nbproject/Makefile-LLVM_GCC.mk index ac9ed1fa..5c362566 100644 --- a/src/nbproject/Makefile-LLVM_GCC.mk +++ b/src/nbproject/Makefile-LLVM_GCC.mk @@ -52,11 +52,11 @@ OBJECTFILES= \ ${OBJECTDIR}/test/compiler_test.o \ ${OBJECTDIR}/test/eval_test.o \ ${OBJECTDIR}/test/example_test.o \ - ${OBJECTDIR}/test/fraction_test.o \ ${OBJECTDIR}/test/lexer_test.o \ ${OBJECTDIR}/test/nlc_test.o \ ${OBJECTDIR}/test/object_test.o \ ${OBJECTDIR}/test/parser_test.o \ + ${OBJECTDIR}/test/rational_test.o \ ${OBJECTDIR}/variable.o \ ${OBJECTDIR}/version.o @@ -194,11 +194,6 @@ ${OBJECTDIR}/test/example_test.o: test/example_test.cpp ${RM} "$@.d" $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I.. -std=c++14 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/example_test.o test/example_test.cpp -${OBJECTDIR}/test/fraction_test.o: test/fraction_test.cpp - ${MKDIR} -p ${OBJECTDIR}/test - ${RM} "$@.d" - $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I.. -std=c++14 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/fraction_test.o test/fraction_test.cpp - ${OBJECTDIR}/test/lexer_test.o: test/lexer_test.cpp ${MKDIR} -p ${OBJECTDIR}/test ${RM} "$@.d" @@ -219,6 +214,11 @@ ${OBJECTDIR}/test/parser_test.o: test/parser_test.cpp ${RM} "$@.d" $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I.. -std=c++14 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/parser_test.o test/parser_test.cpp +${OBJECTDIR}/test/rational_test.o: test/rational_test.cpp + ${MKDIR} -p ${OBJECTDIR}/test + ${RM} "$@.d" + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I.. -std=c++14 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/rational_test.o test/rational_test.cpp + ${OBJECTDIR}/variable.o: variable.cpp ${MKDIR} -p ${OBJECTDIR} ${RM} "$@.d" diff --git a/src/nbproject/Makefile-Release.mk b/src/nbproject/Makefile-Release.mk index 1a76adad..39442004 100644 --- a/src/nbproject/Makefile-Release.mk +++ b/src/nbproject/Makefile-Release.mk @@ -52,11 +52,11 @@ OBJECTFILES= \ ${OBJECTDIR}/test/compiler_test.o \ ${OBJECTDIR}/test/eval_test.o \ ${OBJECTDIR}/test/example_test.o \ - ${OBJECTDIR}/test/fraction_test.o \ ${OBJECTDIR}/test/lexer_test.o \ ${OBJECTDIR}/test/nlc_test.o \ ${OBJECTDIR}/test/object_test.o \ ${OBJECTDIR}/test/parser_test.o \ + ${OBJECTDIR}/test/rational_test.o \ ${OBJECTDIR}/variable.o \ ${OBJECTDIR}/version.o @@ -180,11 +180,6 @@ ${OBJECTDIR}/test/example_test.o: test/example_test.cpp ${RM} "$@.d" $(COMPILE.cc) -O3 -Werror -I.. -std=c++14 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/example_test.o test/example_test.cpp -${OBJECTDIR}/test/fraction_test.o: test/fraction_test.cpp - ${MKDIR} -p ${OBJECTDIR}/test - ${RM} "$@.d" - $(COMPILE.cc) -O3 -Werror -I.. -std=c++14 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/fraction_test.o test/fraction_test.cpp - ${OBJECTDIR}/test/lexer_test.o: test/lexer_test.cpp ${MKDIR} -p ${OBJECTDIR}/test ${RM} "$@.d" @@ -205,6 +200,11 @@ ${OBJECTDIR}/test/parser_test.o: test/parser_test.cpp ${RM} "$@.d" $(COMPILE.cc) -O3 -Werror -I.. -std=c++14 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/parser_test.o test/parser_test.cpp +${OBJECTDIR}/test/rational_test.o: test/rational_test.cpp + ${MKDIR} -p ${OBJECTDIR}/test + ${RM} "$@.d" + $(COMPILE.cc) -O3 -Werror -I.. -std=c++14 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/rational_test.o test/rational_test.cpp + ${OBJECTDIR}/variable.o: variable.cpp ${MKDIR} -p ${OBJECTDIR} ${RM} "$@.d" diff --git a/src/nbproject/Makefile-UnitTest-Win32.mk b/src/nbproject/Makefile-UnitTest-Win32.mk index e39e58d4..44a79630 100644 --- a/src/nbproject/Makefile-UnitTest-Win32.mk +++ b/src/nbproject/Makefile-UnitTest-Win32.mk @@ -52,11 +52,11 @@ OBJECTFILES= \ ${OBJECTDIR}/test/compiler_test.o \ ${OBJECTDIR}/test/eval_test.o \ ${OBJECTDIR}/test/example_test.o \ - ${OBJECTDIR}/test/fraction_test.o \ ${OBJECTDIR}/test/lexer_test.o \ ${OBJECTDIR}/test/nlc_test.o \ ${OBJECTDIR}/test/object_test.o \ ${OBJECTDIR}/test/parser_test.o \ + ${OBJECTDIR}/test/rational_test.o \ ${OBJECTDIR}/variable.o \ ${OBJECTDIR}/version.o @@ -221,11 +221,6 @@ ${OBJECTDIR}/test/example_test.o: test/example_test.cpp pch.h.gch ${RM} "$@.d" $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -I/usr/lib/llvm-13/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/example_test.o test/example_test.cpp -${OBJECTDIR}/test/fraction_test.o: test/fraction_test.cpp - ${MKDIR} -p ${OBJECTDIR}/test - ${RM} "$@.d" - $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -I/usr/lib/llvm-13/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/fraction_test.o test/fraction_test.cpp - ${OBJECTDIR}/test/lexer_test.o: test/lexer_test.cpp pch.h.gch ${MKDIR} -p ${OBJECTDIR}/test ${RM} "$@.d" @@ -246,6 +241,11 @@ ${OBJECTDIR}/test/parser_test.o: test/parser_test.cpp pch.h.gch ${RM} "$@.d" $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -I/usr/lib/llvm-13/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/parser_test.o test/parser_test.cpp +${OBJECTDIR}/test/rational_test.o: test/rational_test.cpp + ${MKDIR} -p ${OBJECTDIR}/test + ${RM} "$@.d" + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -I/usr/lib/llvm-13/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/rational_test.o test/rational_test.cpp + : types.h pch.h.gch @echo Выполнение шага пользовательского сборки diff --git a/src/nbproject/Makefile-UnitTest-Win64.mk b/src/nbproject/Makefile-UnitTest-Win64.mk index a5a69dd7..abb3e8db 100644 --- a/src/nbproject/Makefile-UnitTest-Win64.mk +++ b/src/nbproject/Makefile-UnitTest-Win64.mk @@ -52,11 +52,11 @@ OBJECTFILES= \ ${OBJECTDIR}/test/compiler_test.o \ ${OBJECTDIR}/test/eval_test.o \ ${OBJECTDIR}/test/example_test.o \ - ${OBJECTDIR}/test/fraction_test.o \ ${OBJECTDIR}/test/lexer_test.o \ ${OBJECTDIR}/test/nlc_test.o \ ${OBJECTDIR}/test/object_test.o \ ${OBJECTDIR}/test/parser_test.o \ + ${OBJECTDIR}/test/rational_test.o \ ${OBJECTDIR}/variable.o \ ${OBJECTDIR}/version.o @@ -221,11 +221,6 @@ ${OBJECTDIR}/test/example_test.o: test/example_test.cpp pch.h.gch ${RM} "$@.d" $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch-win/include/torch/csrc/api/include -I../contrib/libtorch-win/include -I../contrib/tensorboard_logger/include -I/usr/share/mingw-w64/include/ -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/example_test.o test/example_test.cpp -${OBJECTDIR}/test/fraction_test.o: test/fraction_test.cpp - ${MKDIR} -p ${OBJECTDIR}/test - ${RM} "$@.d" - $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch-win/include/torch/csrc/api/include -I../contrib/libtorch-win/include -I../contrib/tensorboard_logger/include -I/usr/share/mingw-w64/include/ -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/fraction_test.o test/fraction_test.cpp - ${OBJECTDIR}/test/lexer_test.o: test/lexer_test.cpp pch.h.gch ${MKDIR} -p ${OBJECTDIR}/test ${RM} "$@.d" @@ -246,6 +241,11 @@ ${OBJECTDIR}/test/parser_test.o: test/parser_test.cpp pch.h.gch ${RM} "$@.d" $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch-win/include/torch/csrc/api/include -I../contrib/libtorch-win/include -I../contrib/tensorboard_logger/include -I/usr/share/mingw-w64/include/ -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/parser_test.o test/parser_test.cpp +${OBJECTDIR}/test/rational_test.o: test/rational_test.cpp + ${MKDIR} -p ${OBJECTDIR}/test + ${RM} "$@.d" + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch-win/include/torch/csrc/api/include -I../contrib/libtorch-win/include -I../contrib/tensorboard_logger/include -I/usr/share/mingw-w64/include/ -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/rational_test.o test/rational_test.cpp + : types.h pch.h.gch @echo Выполнение шага пользовательского сборки diff --git a/src/nbproject/Makefile-UnitTest.mk b/src/nbproject/Makefile-UnitTest.mk index e9852ba1..73479be9 100644 --- a/src/nbproject/Makefile-UnitTest.mk +++ b/src/nbproject/Makefile-UnitTest.mk @@ -52,11 +52,11 @@ OBJECTFILES= \ ${OBJECTDIR}/test/compiler_test.o \ ${OBJECTDIR}/test/eval_test.o \ ${OBJECTDIR}/test/example_test.o \ - ${OBJECTDIR}/test/fraction_test.o \ ${OBJECTDIR}/test/lexer_test.o \ ${OBJECTDIR}/test/nlc_test.o \ ${OBJECTDIR}/test/object_test.o \ ${OBJECTDIR}/test/parser_test.o \ + ${OBJECTDIR}/test/rational_test.o \ ${OBJECTDIR}/variable.o \ ${OBJECTDIR}/version.o @@ -224,11 +224,6 @@ ${OBJECTDIR}/test/example_test.o: test/example_test.cpp pch.h.gch ${RM} "$@.d" $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I. -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -I/usr/lib/llvm-13/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/example_test.o test/example_test.cpp -${OBJECTDIR}/test/fraction_test.o: test/fraction_test.cpp - ${MKDIR} -p ${OBJECTDIR}/test - ${RM} "$@.d" - $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I. -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -I/usr/lib/llvm-13/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/fraction_test.o test/fraction_test.cpp - ${OBJECTDIR}/test/lexer_test.o: test/lexer_test.cpp pch.h.gch ${MKDIR} -p ${OBJECTDIR}/test ${RM} "$@.d" @@ -249,6 +244,11 @@ ${OBJECTDIR}/test/parser_test.o: test/parser_test.cpp pch.h.gch ${RM} "$@.d" $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I. -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -I/usr/lib/llvm-13/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/parser_test.o test/parser_test.cpp +${OBJECTDIR}/test/rational_test.o: test/rational_test.cpp + ${MKDIR} -p ${OBJECTDIR}/test + ${RM} "$@.d" + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I. -I.. -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -I../contrib/tensorboard_logger/include -I/usr/lib/llvm-13/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/rational_test.o test/rational_test.cpp + : types.h pch.h.gch @echo Выполнение шага пользовательского сборки diff --git a/src/nbproject/Makefile-UnitTest_LLVM.mk b/src/nbproject/Makefile-UnitTest_LLVM.mk index ba18473a..62faab19 100644 --- a/src/nbproject/Makefile-UnitTest_LLVM.mk +++ b/src/nbproject/Makefile-UnitTest_LLVM.mk @@ -52,11 +52,11 @@ OBJECTFILES= \ ${OBJECTDIR}/test/compiler_test.o \ ${OBJECTDIR}/test/eval_test.o \ ${OBJECTDIR}/test/example_test.o \ - ${OBJECTDIR}/test/fraction_test.o \ ${OBJECTDIR}/test/lexer_test.o \ ${OBJECTDIR}/test/nlc_test.o \ ${OBJECTDIR}/test/object_test.o \ ${OBJECTDIR}/test/parser_test.o \ + ${OBJECTDIR}/test/rational_test.o \ ${OBJECTDIR}/variable.o \ ${OBJECTDIR}/version.o @@ -196,11 +196,6 @@ ${OBJECTDIR}/test/example_test.o: test/example_test.cpp pch.h.pch ${RM} "$@.d" $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I. -I.. -I/usr/lib/llvm-13/lib/clang/13.0.1/include -I/usr/include/llvm-c-13 -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -include-pch pch.h.pch -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/example_test.o test/example_test.cpp -${OBJECTDIR}/test/fraction_test.o: test/fraction_test.cpp pch.h.pch - ${MKDIR} -p ${OBJECTDIR}/test - ${RM} "$@.d" - $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I. -I.. -I/usr/lib/llvm-13/lib/clang/13.0.1/include -I/usr/include/llvm-c-13 -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -include-pch pch.h.pch -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/fraction_test.o test/fraction_test.cpp - ${OBJECTDIR}/test/lexer_test.o: test/lexer_test.cpp pch.h.pch ${MKDIR} -p ${OBJECTDIR}/test ${RM} "$@.d" @@ -221,6 +216,11 @@ ${OBJECTDIR}/test/parser_test.o: test/parser_test.cpp pch.h.pch ${RM} "$@.d" $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I. -I.. -I/usr/lib/llvm-13/lib/clang/13.0.1/include -I/usr/include/llvm-c-13 -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -include-pch pch.h.pch -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/parser_test.o test/parser_test.cpp +${OBJECTDIR}/test/rational_test.o: test/rational_test.cpp pch.h.pch + ${MKDIR} -p ${OBJECTDIR}/test + ${RM} "$@.d" + $(COMPILE.cc) -g -DDEBUG -DLOG_LEVEL_NORMAL=LOG_LEVEL_DEBUG -DPDC_WIDE -DUNITTEST -I. -I.. -I/usr/lib/llvm-13/lib/clang/13.0.1/include -I/usr/include/llvm-c-13 -I/usr/include/x86_64-linux-gnu/c++/10 -I/usr/include/c++/10 -I/usr/local/include -I/usr/include -I../contrib/googletest/googletest -I../contrib/googletest/googletest/include -I../contrib/Tensorflow/bazel-bin/tensorflow/include -I../contrib/Lyra/include -I../contrib/libtorch/include/torch/csrc/api/include -I../contrib/libtorch/include -include-pch pch.h.pch -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/test/rational_test.o test/rational_test.cpp + ${OBJECTDIR}/variable.o: variable.cpp pch.h.pch ${MKDIR} -p ${OBJECTDIR} ${RM} "$@.d" diff --git a/src/nbproject/configurations.xml b/src/nbproject/configurations.xml index 784b6043..8a9db4bb 100644 --- a/src/nbproject/configurations.xml +++ b/src/nbproject/configurations.xml @@ -16,20 +16,21 @@ ../examples/dsl.nlp ../examples/fileio.nlp ../examples/foreach.nlp - ../examples/fraction.nlp + ../examples/rational.nlp ../examples/speed_test.nlp ../examples/speed_test.py + ../examples/tensor.nlp test/alg_test.cpp test/compiler_test.cpp test/eval_test.cpp test/example_test.cpp - test/fraction_test.cpp test/lexer_test.cpp test/nlc_test.cpp test/object_test.cpp test/parser_test.cpp + test/rational_test.cpp builtin.cpp context.cpp @@ -47,13 +48,13 @@ autocomplete.h builtin.h context.h - fraction.h lexer.h newlang.h nlc.h object.h parser.h pch.h + rational.h term.h types.h variable.h @@ -92,12 +93,28 @@ ../LICENSE Makefile + + + + ../.clang-format + ../.gitignore + ../.gitmodules + ../LICENSE + Makefile + ../README.md lexer.l parser.y /home/rsashka/SOURCE/PUBLIC/NewLang/newlang/test + /home/rsashka/SOURCE/PUBLIC/NewLang/newlang/test Makefile @@ -205,12 +222,14 @@ - + + + @@ -234,8 +253,6 @@ pch.h.gch - - parser.h parser.yy.h pch.h.gch location.hh @@ -328,6 +345,8 @@ + + @@ -360,8 +379,6 @@ pch.h.gch - - pch.h.gch @@ -382,6 +399,8 @@ pch.h.gch + + pch.h.gch @@ -509,12 +528,14 @@ - + + + @@ -531,8 +552,6 @@ - - @@ -612,6 +631,8 @@ + + @@ -644,11 +665,6 @@ - - - - - @@ -669,6 +685,11 @@ + + + + + @@ -754,12 +775,14 @@ - + + + @@ -770,8 +793,6 @@ - - @@ -821,6 +842,8 @@ + + @@ -835,8 +858,6 @@ - - @@ -845,6 +866,8 @@ + + @@ -960,12 +983,14 @@ - + + + @@ -989,8 +1014,6 @@ pch.h.gch - - location.hh @@ -1083,6 +1106,8 @@ + + @@ -1115,8 +1140,6 @@ pch.h.gch - - pch.h.gch @@ -1137,6 +1160,8 @@ pch.h.gch + + pch.h.gch @@ -1269,12 +1294,14 @@ - + + + @@ -1293,8 +1320,6 @@ - - -include-pch pch.h.pch @@ -1380,6 +1405,8 @@ + + @@ -1417,31 +1444,31 @@ pch.h.pch - + -include-pch pch.h.pch pch.h.pch - + -include-pch pch.h.pch pch.h.pch - + -include-pch pch.h.pch pch.h.pch - + -include-pch pch.h.pch pch.h.pch - + -include-pch pch.h.pch pch.h.pch @@ -1556,12 +1583,14 @@ - + + + @@ -1575,8 +1604,6 @@ - - parser.yy.h parser.yy.cpp location.hh @@ -1644,6 +1671,8 @@ + + @@ -1664,8 +1693,6 @@ - - @@ -1674,6 +1701,8 @@ + + @@ -1810,12 +1839,14 @@ - + + + @@ -1829,8 +1860,6 @@ - - parser.yy.h parser.yy.cpp location.hh @@ -1898,6 +1927,8 @@ + + @@ -1918,8 +1949,6 @@ - - @@ -1928,6 +1957,8 @@ + + @@ -2060,12 +2091,14 @@ - + + + @@ -2079,8 +2112,6 @@ - - parser.yy.h parser.yy.cpp location.hh @@ -2148,6 +2179,8 @@ + + @@ -2168,8 +2201,6 @@ - - @@ -2178,6 +2209,8 @@ + + @@ -2299,12 +2332,14 @@ - + + + @@ -2328,8 +2363,6 @@ pch.h.gch - - location.hh @@ -2422,6 +2455,8 @@ + + @@ -2454,8 +2489,6 @@ pch.h.gch - - pch.h.gch @@ -2476,6 +2509,8 @@ pch.h.gch + + pch.h.gch @@ -2602,12 +2637,14 @@ - + + + @@ -2631,8 +2668,6 @@ pch.h.gch - - location.hh @@ -2725,6 +2760,8 @@ + + @@ -2757,8 +2794,6 @@ pch.h.gch - - pch.h.gch @@ -2779,6 +2814,8 @@ pch.h.gch + + pch.h.gch diff --git a/src/nbproject/project.xml b/src/nbproject/project.xml index cd9abda6..49e2b761 100644 --- a/src/nbproject/project.xml +++ b/src/nbproject/project.xml @@ -11,6 +11,7 @@ /home/rsashka/SOURCE/PUBLIC/NewLang/newlang/test + /home/rsashka/SOURCE/PUBLIC/NewLang/newlang/test diff --git a/src/newlang.cpp b/src/newlang.cpp index d24e4d12..4b8f0431 100644 --- a/src/newlang.cpp +++ b/src/newlang.cpp @@ -365,8 +365,8 @@ std::string newlang::MangaledFuncCPP(const char *name, const char *space) { return result; } -//Char _ZN7newlang4CharEPKNS_7ContextERKNS_6ObjectE -//Short _ZN7newlang5ShortEPKNS_7ContextERKNS_6ObjectE +//Int8 _ZN7newlang4CharEPKNS_7ContextERKNS_6ObjectE +//Int16 _ZN7newlang5ShortEPKNS_7ContextERKNS_6ObjectE //Char_ _ZN7newlang5Char_EPNS_7ContextERNS_6ObjectE //Short_ _ZN7newlang6Short_EPNS_7ContextERNS_6ObjectE diff --git a/src/object.cpp b/src/object.cpp index 97b30f7a..660ed91b 100644 --- a/src/object.cpp +++ b/src/object.cpp @@ -375,8 +375,8 @@ ObjType newlang::getSummaryTensorType(Obj *obj, ObjType start) { } else if(obj->is_arithmetic_type()) { if(isGenericType(obj->m_var_type_fixed)) { return std::max(obj->m_var_type_current, start); - } else if(start == ObjType::Fraction || obj->m_var_type_current == ObjType::Fraction || obj->m_var_type_fixed == ObjType::Fraction) { - return ObjType::Fraction; + } else if(start == ObjType::Rational || obj->m_var_type_current == ObjType::Rational || obj->m_var_type_fixed == ObjType::Rational) { + return ObjType::Rational; } else { if(start >= std::max(obj->m_var_type_current, obj->m_var_type_fixed)) { return start; @@ -396,7 +396,7 @@ ObjPtr Obj::operator+=(Obj value) { if(is_floating()) { ASSERT(at::holds_alternative(m_var)); m_var = GetValueAsNumber() + value.GetValueAsNumber(); - m_var_type_current = ObjType::Double; + m_var_type_current = ObjType::Float64; } else if(is_integral() && value.is_integral()) { ASSERT(at::holds_alternative(m_var)); m_var = GetValueAsInteger() + value.GetValueAsInteger(); @@ -446,11 +446,11 @@ ObjPtr Obj::operator+=(Obj value) { } break; - case ObjType::Fraction: - if(value.m_var_type_current == ObjType::Fraction) { - m_fraction.operator+=(value.m_fraction); + case ObjType::Rational: + if(value.m_var_type_current == ObjType::Rational) { + m_rational.operator+=(value.m_rational); } else { - m_fraction.operator+=(value.toType(ObjType::Fraction)->m_fraction); + m_rational.operator+=(value.toType(ObjType::Rational)->m_rational); } return shared(); @@ -467,7 +467,7 @@ ObjPtr Obj::operator-=(Obj value) { if(is_floating()) { ASSERT(at::holds_alternative(m_var)); m_var = GetValueAsNumber() - value.GetValueAsNumber(); - m_var_type_current = ObjType::Double; + m_var_type_current = ObjType::Float64; } else if(is_integral() && value.is_integral()) { ASSERT(at::holds_alternative(m_var)); m_var = GetValueAsInteger() - value.GetValueAsInteger(); @@ -504,11 +504,11 @@ ObjPtr Obj::operator-=(Obj value) { return shared(); } break; - case ObjType::Fraction: - if(value.m_var_type_current == ObjType::Fraction) { - m_fraction.operator-=(value.m_fraction); + case ObjType::Rational: + if(value.m_var_type_current == ObjType::Rational) { + m_rational.operator-=(value.m_rational); } else { - m_fraction.operator-=(value.toType(ObjType::Fraction)->m_fraction); + m_rational.operator-=(value.toType(ObjType::Rational)->m_rational); } return shared(); } @@ -524,7 +524,7 @@ ObjPtr Obj::operator*=(Obj value) { if(is_floating()) { ASSERT(at::holds_alternative(m_var)); m_var = GetValueAsNumber() * value.GetValueAsNumber(); - m_var_type_current = ObjType::Double; + m_var_type_current = ObjType::Float64; } else if(is_integral() && value.is_integral()) { ASSERT(at::holds_alternative(m_var)); m_var = GetValueAsInteger() * value.GetValueAsInteger(); @@ -577,11 +577,11 @@ ObjPtr Obj::operator*=(Obj value) { return shared(); } - case ObjType::Fraction: - if(value.m_var_type_current == ObjType::Fraction) { - m_fraction.operator*=(value.m_fraction); + case ObjType::Rational: + if(value.m_var_type_current == ObjType::Rational) { + m_rational.operator*=(value.m_rational); } else { - m_fraction.operator*=(value.toType(ObjType::Fraction)->m_fraction); + m_rational.operator*=(value.toType(ObjType::Rational)->m_rational); } return shared(); @@ -591,12 +591,12 @@ ObjPtr Obj::operator*=(Obj value) { ObjPtr Obj::operator/=(Obj value) { if(is_tensor_type() && value.is_tensor_type()) { - testResultIntegralType(ObjType::Double, true); + testResultIntegralType(ObjType::Float64, true); if(is_scalar() && value.is_scalar()) { if(is_floating()) { ASSERT(at::holds_alternative(m_var)); m_var = GetValueAsNumber() / value.GetValueAsNumber(); - m_var_type_current = ObjType::Double; + m_var_type_current = ObjType::Float64; } else if(is_integral() && value.is_integral()) { ASSERT(at::holds_alternative(m_var)); m_var = GetValueAsInteger() / value.GetValueAsInteger(); @@ -617,11 +617,11 @@ ObjPtr Obj::operator/=(Obj value) { m_tensor.div_(value.m_tensor); } return shared(); - } else if(m_var_type_current == ObjType::Fraction) { - if(value.m_var_type_current == ObjType::Fraction) { - m_fraction.operator/=(value.m_fraction); + } else if(m_var_type_current == ObjType::Rational) { + if(value.m_var_type_current == ObjType::Rational) { + m_rational.operator/=(value.m_rational); } else { - m_fraction.operator/=(value.toType(ObjType::Fraction)->m_fraction); + m_rational.operator/=(value.toType(ObjType::Rational)->m_rational); } return shared(); } @@ -631,12 +631,12 @@ ObjPtr Obj::operator/=(Obj value) { ObjPtr Obj::op_div_ceil_(Obj & value) { if(is_tensor_type() && value.is_tensor_type()) { ObjType type = m_var_type_current; - testResultIntegralType(ObjType::Float, false); + testResultIntegralType(ObjType::Float32, false); if(is_scalar() && value.is_scalar()) { if(is_floating()) { ASSERT(at::holds_alternative(m_var)); m_var = floor(GetValueAsNumber() / value.GetValueAsNumber()); - m_var_type_current = ObjType::Double; + m_var_type_current = ObjType::Float64; } else if(is_integral() && value.is_integral()) { ASSERT(at::holds_alternative(m_var)); m_var = static_cast (GetValueAsInteger() / value.GetValueAsInteger()); @@ -658,16 +658,16 @@ ObjPtr Obj::op_div_ceil_(Obj & value) { m_tensor = m_tensor.toType(toTorchType(type)); } // ObjType type = m_var_type_current; - // testResultIntegralType(ObjType::Float, false); + // testResultIntegralType(ObjType::Float32, false); // m_tensor.div_(value.m_tensor, "floor"); // m_tensor = m_tensor.toType(toTorchType(type)); return shared(); - } else if(m_var_type_current == ObjType::Fraction) { - if(value.m_var_type_current == ObjType::Fraction) { - m_fraction.op_div_ceil_(value.m_fraction); + } else if(m_var_type_current == ObjType::Rational) { + if(value.m_var_type_current == ObjType::Rational) { + m_rational.op_div_ceil_(value.m_rational); } else { - m_fraction.op_div_ceil_(value.toType(ObjType::Fraction)->m_fraction); + m_rational.op_div_ceil_(value.toType(ObjType::Rational)->m_rational); } return shared(); } @@ -700,11 +700,11 @@ ObjPtr Obj::operator%=(Obj value) { m_tensor.fmod_(value.m_tensor); } return shared(); - } else if(m_var_type_current == ObjType::Fraction) { - if(value.m_var_type_current == ObjType::Fraction) { - m_fraction.operator%=(value.m_fraction); + } else if(m_var_type_current == ObjType::Rational) { + if(value.m_var_type_current == ObjType::Rational) { + m_rational.operator%=(value.m_rational); } else { - m_fraction.operator%=(value.toType(ObjType::Fraction)->m_fraction); + m_rational.operator%=(value.toType(ObjType::Rational)->m_rational); } return shared(); } @@ -743,7 +743,7 @@ void Obj::CloneDataTo(Obj & clone) const { clone.m_value = m_value; clone.m_string = m_string; - clone.m_fraction = *m_fraction.clone(); + clone.m_rational = *m_rational.clone(); clone.m_iterator = m_iterator; if(m_iter_range_value) { clone.m_iter_range_value = m_iter_range_value->Clone(); @@ -998,8 +998,8 @@ std::string Obj::toString(bool deep) const { result += "..."; return result; - case ObjType::Fraction: - result += m_fraction.GetAsString(); + case ObjType::Rational: + result += m_rational.GetAsString(); return result; case ObjType::Iterator: @@ -1086,17 +1086,17 @@ std::string Obj::GetValueAsString() const { case ObjType::Tensor: case ObjType::Bool: - case ObjType::Char: - case ObjType::Short: - case ObjType::Int: - case ObjType::Long: + case ObjType::Int8: + case ObjType::Int16: + case ObjType::Int32: + case ObjType::Int64: case ObjType::Integer: + case ObjType::Float32: + case ObjType::Float64: case ObjType::Float: - case ObjType::Double: - case ObjType::Number: case ObjType::Complex: - case ObjType::ComplexFloat: - case ObjType::ComplexDouble: + case ObjType::Complex32: + case ObjType::Complex64: if(is_scalar()) { if(is_integral()) { return std::to_string(GetValueAsInteger()); @@ -1157,8 +1157,8 @@ std::string Obj::GetValueAsString() const { result += toString(); return result; - case ObjType::Fraction: - result += m_fraction.GetAsString(); + case ObjType::Rational: + result += m_rational.GetAsString(); return result; case ObjType::Iterator: @@ -1324,8 +1324,8 @@ ObjPtr Obj::Call(Context *ctx, Obj * args) { // // ObjType proto_type = typeFromString((*m_prototype)[pind].second->m_type_name, ctx); // if(!canCast(type, proto_type)) { - // if(!((type == ObjType::StrChar || type == ObjType::FmtChar) && proto_type == ObjType::Char) || - // ((type == ObjType::StrWide || type == ObjType::FmtWide) && proto_type == ObjType::Int)) { + // if(!((type == ObjType::StrChar || type == ObjType::FmtChar) && proto_type == ObjType::Int8) || + // ((type == ObjType::StrWide || type == ObjType::FmtWide) && proto_type == ObjType::Int32)) { // LOG_RUNTIME("Fail cast from '%s' to '%s'", (*m_prototype)[pind].second->m_type_name.c_str(), newlang::toString(type)); // } // } @@ -1345,7 +1345,7 @@ ObjPtr Obj::Call(Context *ctx, Obj * args) { // // if(check_type == ObjType::Bool && m_namespace.empty()) { // // В чистом С (для пустого m_namespace) для логического типа используется тип int - // check_type = ObjType::Int; + // check_type = ObjType::Int32; // } // if(check_type == ObjType::Iterator) { // // У итератора передается не объект, а его данные @@ -1537,12 +1537,12 @@ int Obj::op_compare(Obj & value) { }; return 0; } - } else if(is_fraction()) { + } else if(is_rational()) { - if(value.getType() == ObjType::Fraction) { - return m_fraction.op_compare(value.m_fraction); + if(value.getType() == ObjType::Rational) { + return m_rational.op_compare(value.m_rational); } else { - return m_fraction.op_compare(*value.GetValueAsFraction()); + return m_rational.op_compare(*value.GetValueAsRational()); } } else if((is_string_type() && value.is_string_type())) { @@ -1599,12 +1599,12 @@ bool Obj::op_equal(Obj & value) { return GetValueAsBoolean() == value.GetValueAsBoolean(); } else if(is_string_type()) { return GetValueAsString().compare(value.GetValueAsString()) == 0; - } else if(is_fraction()) { + } else if(is_rational()) { - if(value.getType() == ObjType::Fraction) { - return m_fraction.op_equal(value.m_fraction); + if(value.getType() == ObjType::Rational) { + return m_rational.op_equal(value.m_rational); } else { - return m_fraction.op_equal(*value.GetValueAsFraction()); + return m_rational.op_equal(*value.GetValueAsRational()); } } else if(is_dictionary_type() && value.is_dictionary_type()) { @@ -1637,7 +1637,7 @@ bool Obj::op_accurate(Obj & value) { } ObjPtr Obj::op_bit_and_set(Obj &obj, bool strong) { - if(m_var_type_current == ObjType::Long) { + if(m_var_type_current == ObjType::Int64) { if(m_var_type_current == obj.m_var_type_current) { m_tensor.bitwise_and_(obj.m_tensor); // m_values.integer &= obj.m_values.integer; @@ -1766,12 +1766,12 @@ ObjPtr Obj::op_pow_(Obj & obj) { m_tensor.pow_(obj.GetValueAsNumber()); } return shared(); - } else if(is_fraction()) { + } else if(is_rational()) { - if(obj.getType() == ObjType::Fraction) { - m_fraction.op_pow_(obj.m_fraction); + if(obj.getType() == ObjType::Rational) { + m_rational.op_pow_(obj.m_rational); } else { - m_fraction.op_pow_(*obj.GetValueAsFraction()); + m_rational.op_pow_(*obj.GetValueAsRational()); } return shared(); @@ -1781,11 +1781,11 @@ ObjPtr Obj::op_pow_(Obj & obj) { } else if(m_var_type_current == ObjType::StrWide && obj.is_integral()) { m_string = repeat(m_string, obj.GetValueAsInteger()); return shared(); - } else if(m_var_type_current == ObjType::Fraction) { - // if(value.m_var_type_current == ObjType::Fraction) { - // m_fraction->op_pow_(value.m_fraction); + } else if(m_var_type_current == ObjType::Rational) { + // if(value.m_var_type_current == ObjType::Rational) { + // m_rational->op_pow_(value.m_rational); // } else { - // m_fraction->op_pow_(value.toType(ObjPtr::Fraction)->m_fraction); + // m_rational->op_pow_(value.toType(ObjPtr::Rational)->m_rational); // } // return shared(); } @@ -1809,8 +1809,8 @@ bool Obj::op_duck_test(Obj *value, bool strong) { } return op_duck_test_prop(this, value, strong); } - if(value->m_var_type_current == ObjType::Long || value->m_var_type_current == ObjType::Double) { - return (m_var_type_current == ObjType::Long || m_var_type_current == ObjType::Double); + if(value->m_var_type_current == ObjType::Int64 || value->m_var_type_current == ObjType::Float64) { + return (m_var_type_current == ObjType::Int64 || m_var_type_current == ObjType::Float64); } else if(is_string_type() && value->is_string_type()) { return true; } else if(is_function_type() && value->is_function_type()) { @@ -1974,8 +1974,8 @@ ObjPtr Obj::CallNative(Context *ctx, Obj args) { ObjType proto_type = typeFromString((*m_prototype)[pind].second->m_type_name, ctx); if(!canCast(type, proto_type)) { - if(!((type == ObjType::StrChar || type == ObjType::FmtChar) && proto_type == ObjType::Char) || - ((type == ObjType::StrWide || type == ObjType::FmtWide) && proto_type == ObjType::Int)) { + if(!((type == ObjType::StrChar || type == ObjType::FmtChar) && proto_type == ObjType::Int8) || + ((type == ObjType::StrWide || type == ObjType::FmtWide) && proto_type == ObjType::Int32)) { LOG_RUNTIME("Fail cast from '%s' to '%s'", (*m_prototype)[pind].second->m_type_name.c_str(), newlang::toString(type)); } } @@ -1995,7 +1995,7 @@ ObjPtr Obj::CallNative(Context *ctx, Obj args) { if(check_type == ObjType::Bool && m_namespace.empty()) { // В чистом С (для пустого m_namespace) для логического типа используется тип int - check_type = ObjType::Int; + check_type = ObjType::Int32; } if(check_type == ObjType::Iterator) { // У итератора передается не объект, а его данные @@ -2042,14 +2042,25 @@ ObjPtr Obj::CallNative(Context *ctx, Obj args) { args_param.push_back(LLVMGetParam(wrap, i - 1)); } - // LLVMValueRef param_call[] = {LLVMGetParam(wrap, 0)}; LLVMValueRef func_call = LLVMAddFunction(module, "m_func_ptr", func_res_type); // Имя функции может пересечся с сужествующими при связывании????? - LLVMValueRef func_ret = LLVMBuildCall2(ctx->m_llvm_builder, func_res_type, func_call, args_param.data(), static_cast (args_param.size()), m_prototype->m_text.c_str()); - //return value - LLVMBuildRet(ctx->m_llvm_builder, func_ret); + if(type_result == ObjType::None) { + ASSERT(return_llvm_type == LLVMVoidType()); + LLVMBuildCall2(ctx->m_llvm_builder, func_res_type, func_call, args_param.data(), static_cast (args_param.size()), ""); + LLVMBuildRetVoid(ctx->m_llvm_builder); + } else { + ASSERT(return_llvm_type != LLVMVoidType()); + LLVMValueRef func_ret = LLVMBuildCall2(ctx->m_llvm_builder, func_res_type, func_call, args_param.data(), static_cast (args_param.size()), m_prototype->m_text.c_str()); + LLVMBuildRet(ctx->m_llvm_builder, func_ret); + } +#ifdef UNITTEST + char *dump = LLVMPrintValueToString(wrap); + LOG_DEBUG("LLVM DUMP %s:\n%s\r\r", toString().c_str(), dump); + LLVMDisposeMessage(dump); +#endif + char *error = nullptr; if(LLVMVerifyModule(module, LLVMReturnStatusAction, &error)) { LOG_RUNTIME("LLVMVerifyModule %s", error ? error : ""); @@ -2060,13 +2071,6 @@ ObjPtr Obj::CallNative(Context *ctx, Obj args) { } - -#ifdef UNITTEST - char *dump = LLVMPrintValueToString(wrap); - LOG_DEBUG("LLVM DUMP %s:\n%s\r\r", toString().c_str(), dump); - LLVMDisposeMessage(dump); -#endif - LLVMExecutionEngineRef engine; if(LLVMCreateExecutionEngineForModule(&engine, module, &error)) { LOG_RUNTIME("Failed to create execution engine '%s'!", error ? error : ""); @@ -2286,7 +2290,7 @@ ObjPtr CallLibFFI_(Context *ctx, Obj args) { // m_args_val.push_back(temp); // break; // - // case ObjType::Char: + // case ObjType::Int8: // if(pind < check_count) { // NL_CHECK(!(*m_func_proto)[pind].second->m_type_name.empty(), "Undefined type arg '%s'", (*m_func_proto)[pind].second->toString().c_str()); // NL_CHECK(canCast(type, typeFromString((*m_func_proto)[pind].second->m_type_name, ctx)), "Fail cast from '%s' to '%s'", @@ -2297,7 +2301,7 @@ ObjPtr CallLibFFI_(Context *ctx, Obj args) { // m_args_val.push_back(temp); // break; // - // case ObjType::Short: + // case ObjType::Int16: // if(pind < check_count) { // NL_CHECK(!(*m_func_proto)[pind].second->m_type_name.empty(), "Undefined type arg '%s'", (*m_func_proto)[pind].second->toString().c_str()); // NL_CHECK(canCast(type, typeFromString((*m_func_proto)[pind].second->m_type_name, ctx)), "Fail cast from '%s' to '%s'", @@ -2308,7 +2312,7 @@ ObjPtr CallLibFFI_(Context *ctx, Obj args) { // m_args_val.push_back(temp); // break; // - // case ObjType::Int: + // case ObjType::Int32: // if(pind < check_count) { // NL_CHECK(!(*m_func_proto)[pind].second->m_type_name.empty(), "Undefined type arg '%s'", (*m_func_proto)[pind].second->toString().c_str()); // NL_CHECK(canCast(type, typeFromString((*m_func_proto)[pind].second->m_type_name, ctx)), "Fail cast from '%s' to '%s'", @@ -2319,7 +2323,7 @@ ObjPtr CallLibFFI_(Context *ctx, Obj args) { // m_args_val.push_back(temp); // break; // - // case ObjType::Long: + // case ObjType::Int64: // if(pind < check_count) { // NL_CHECK(!(*m_func_proto)[pind].second->m_type_name.empty(), "Undefined type arg '%s'", (*m_func_proto)[pind].second->toString().c_str()); // NL_CHECK(canCast(type, typeFromString((*m_func_proto)[pind].second->m_type_name, ctx)), "Fail cast from '%s' to '%s'", @@ -2330,7 +2334,7 @@ ObjPtr CallLibFFI_(Context *ctx, Obj args) { // m_args_val.push_back(temp); // break; // - // case ObjType::Float: + // case ObjType::Float32: // if(pind < check_count) { // NL_CHECK(!(*m_func_proto)[pind].second->m_type_name.empty(), "Undefined type arg '%s'", (*m_func_proto)[pind].second->toString().c_str()); // NL_CHECK(canCast(type, typeFromString((*m_func_proto)[pind].second->m_type_name, ctx)), "Fail cast from '%s' to '%s'", @@ -2341,7 +2345,7 @@ ObjPtr CallLibFFI_(Context *ctx, Obj args) { // m_args_val.push_back(temp); // break; // - // case ObjType::Double: + // case ObjType::Float64: // if(pind < check_count) { // NL_CHECK(!(*m_func_proto)[pind].second->m_type_name.empty(), "Undefined type arg '%s'", (*m_func_proto)[pind].second->toString().c_str()); // NL_CHECK(canCast(type, typeFromString((*m_func_proto)[pind].second->m_type_name, ctx)), "Fail cast from '%s' to '%s'", @@ -2411,27 +2415,27 @@ ObjPtr CallLibFFI_(Context *ctx, Obj args) { // result_ffi_type = ctx->m_runtime->m_ffi_type_uint8; // break; // - // case ObjType::Char: + // case ObjType::Int8: // result_ffi_type = ctx->m_runtime->m_ffi_type_sint8; // break; // - // case ObjType::Short: + // case ObjType::Int16: // result_ffi_type = ctx->m_runtime->m_ffi_type_sint16; // break; // - // case ObjType::Int: + // case ObjType::Int32: // result_ffi_type = ctx->m_runtime->m_ffi_type_sint32; // break; // - // case ObjType::Long: + // case ObjType::Int64: // result_ffi_type = ctx->m_runtime->m_ffi_type_sint64; // break; // - // case ObjType::Float: + // case ObjType::Float32: // result_ffi_type = ctx->m_runtime->m_ffi_type_float; // break; // - // case ObjType::Double: + // case ObjType::Float64: // result_ffi_type = ctx->m_runtime->m_ffi_type_double; // break; // @@ -2454,17 +2458,17 @@ ObjPtr CallLibFFI_(Context *ctx, Obj args) { // // Возвращаемый тип может быть как Byte, так и Bool // return Obj::CreateValue(static_cast (res_value.integer), typeFromString(m_func_proto->m_type_name)); // } else if(result_ffi_type == ctx->m_runtime->m_ffi_type_sint8) { - // return Obj::CreateValue(static_cast (res_value.integer), ObjType::Char); + // return Obj::CreateValue(static_cast (res_value.integer), ObjType::Int8); // } else if(result_ffi_type == ctx->m_runtime->m_ffi_type_sint16) { - // return Obj::CreateValue(static_cast (res_value.integer), ObjType::Short); + // return Obj::CreateValue(static_cast (res_value.integer), ObjType::Int16); // } else if(result_ffi_type == ctx->m_runtime->m_ffi_type_sint32) { - // return Obj::CreateValue(static_cast (res_value.integer), ObjType::Int); + // return Obj::CreateValue(static_cast (res_value.integer), ObjType::Int32); // } else if(result_ffi_type == ctx->m_runtime->m_ffi_type_sint64) { - // return Obj::CreateValue(res_value.integer, ObjType::Long); + // return Obj::CreateValue(res_value.integer, ObjType::Int64); // } else if(result_ffi_type == ctx->m_runtime->m_ffi_type_float) { - // return Obj::CreateValue(res_value.number, ObjType::Float); + // return Obj::CreateValue(res_value.number, ObjType::Float32); // } else if(result_ffi_type == ctx->m_runtime->m_ffi_type_double) { - // return Obj::CreateValue(res_value.number, ObjType::Double); + // return Obj::CreateValue(res_value.number, ObjType::Float64); // } else if(result_ffi_type == ctx->m_runtime->m_ffi_type_pointer) { // if(type == ObjType::StrChar) { // return Obj::CreateString(reinterpret_cast (res_value.ptr)); @@ -2554,11 +2558,11 @@ bool newlang::ParsePrintfFormat(Obj *args, int start) { case 'u': //%u Десятичное целое без знака case 'x': //%x Шестнадцатеричное без знака (буквы на нижнем регистре) case 'X': //%X Шестнадцатеричное без знака (буквы на верхнем регистре) - cast = ObjType::Int; + cast = ObjType::Int32; if(pos && (format[pos - 1] == 'l' || format[pos - 1] == 'L')) { - cast = ObjType::Long; + cast = ObjType::Int64; } else if(pos && format[pos - 1] == 'h') { - cast = ObjType::Short; + cast = ObjType::Int16; } if((*args)[aind].second->getType() == ObjType::Iterator) { @@ -2581,7 +2585,7 @@ bool newlang::ParsePrintfFormat(Obj *args, int start) { case 'g'://%g В зависимости от того, какой вывод будет короче, используется %е или %f case 'G'://%G В зависимости от того, какой вывод будет короче, используется %Е или %F - cast = ObjType::Double; + cast = ObjType::Float64; if(!canCast((*args)[aind].second->m_var_type_current, cast)) { LOG_WARNING("Cast '%s' to '%s' not supported!", newlang::toString((*args)[aind].second->m_var_type_current), newlang::toString(cast)); result = false; @@ -2589,9 +2593,9 @@ bool newlang::ParsePrintfFormat(Obj *args, int start) { break; case 'c': - cast = ObjType::Char; + cast = ObjType::Int8; if(pos && (format[pos - 1] == 'l' || format[pos - 1] == 'L')) { - cast = ObjType::Int; + cast = ObjType::Int32; } if(!canCast((*args)[aind].second->m_var_type_current, cast)) { LOG_WARNING("Cast '%s' to '%s' not supported!", newlang::toString((*args)[aind].second->m_var_type_current), newlang::toString(cast)); @@ -2797,6 +2801,7 @@ void Obj::toType_(ObjType type) { Variable::push_back(elem); } m_var_type_current = type; + m_var_type_fixed = ObjType::None; return; } else if(is_range() && isTensor(type)) { @@ -2809,7 +2814,7 @@ void Obj::toType_(ObjType type) { if(isGenericType(type)) { m_var_type_fixed = type; - m_var_type_current = ObjType::Char; + m_var_type_current = ObjType::Int8; } else { m_var_type_current = type; } @@ -2833,10 +2838,10 @@ void Obj::toType_(ObjType type) { if(isGenericType(type)) { m_var_type_fixed = type; if(sizeof (wchar_t) == 4) { - m_var_type_current = ObjType::Int; + m_var_type_current = ObjType::Int32; } else { ASSERT(sizeof (wchar_t) == 2); - m_var_type_current = ObjType::Short; + m_var_type_current = ObjType::Int16; } } else { m_var_type_current = type; @@ -2874,7 +2879,7 @@ void Obj::toType_(ObjType type) { m_var = at::monostate(); } else { ASSERT(!is_scalar()); - if(static_cast (m_var_type_current) > static_cast (ObjType::Char)) { + if(static_cast (m_var_type_current) > static_cast (ObjType::Int8)) { LOG_ERROR("Possible data loss when converting tensor %s to a byte string!", newlang::toString(m_var_type_current)); } ConvertTensorToString(m_tensor, m_value); @@ -2896,8 +2901,8 @@ void Obj::toType_(ObjType type) { } else { ASSERT(!is_scalar()); ASSERT(sizeof (wchar_t) == 2 || sizeof (wchar_t) == 4); - if((sizeof (wchar_t) == 2 && static_cast (m_var_type_current) > static_cast (ObjType::Short)) || - (sizeof (wchar_t) == 4 && static_cast (m_var_type_current) > static_cast (ObjType::Int))) { + if((sizeof (wchar_t) == 2 && static_cast (m_var_type_current) > static_cast (ObjType::Int16)) || + (sizeof (wchar_t) == 4 && static_cast (m_var_type_current) > static_cast (ObjType::Int32))) { LOG_ERROR("Possible data loss when converting tensor %s to a wide string!", newlang::toString(m_var_type_current)); } ConvertTensorToString(m_tensor, m_string); @@ -2906,16 +2911,16 @@ void Obj::toType_(ObjType type) { m_var_type_current = type; return; - } else if(is_tensor_type() && type == ObjType::Fraction) { + } else if(is_tensor_type() && type == ObjType::Rational) { if(!is_scalar()) { - LOG_RUNTIME("Convert tensor to fraction support for scalar only!"); + LOG_RUNTIME("Convert tensor to rational support for scalar only!"); } if(is_integral()) { - m_fraction = GetValueAsInteger(); + m_rational = GetValueAsInteger(); m_var = at::monostate(); } else { - LOG_RUNTIME("Convert value '%s' to fraction not implemented!", toString().c_str()); + LOG_RUNTIME("Convert value '%s' to rational not implemented!", toString().c_str()); } m_var_type_current = type; return; @@ -3019,20 +3024,20 @@ void Obj::toType_(ObjType type) { /* * ТИПЫ ДАННЫХ (без аргументов) * - * :type_int := :Int; # Синоним типа Int во время компиляции (тип не может быть изменен) - * :type_int := :Int(); # Копия типа Int во время выполнения (тип может быть изменен после Mutable) - * var_type := :Int; # Тип в переменной, которую можно передавать как аргумент в функции + * :type_int := :Int32; # Синоним типа Int32 во время компиляции (тип не может быть изменен) + * :type_int := :Int32(); # Копия типа Int32 во время выполнения (тип может быть изменен после Mutable) + * var_type := :Int32; # Тип в переменной, которую можно передавать как аргумент в функции * * * ЗНАЧЕНИЯ УКАЗАННЫХ ТИПОВ (при наличии аргументов) * - * scalar_int := :Int(0); # Преобразование типа во время выполнения с автоматической размерностью (скаляр) - * scalar_int := :Int[0](0); # Преобразование типа во время выполнения с указанием размерности (скаляр) - * scalar_int := :Int[0]([0,]); # Преобразование типа во время выполнения с указанием размерности (скаляр) + * scalar_int := :Int32(0); # Преобразование типа во время выполнения с автоматической размерностью (скаляр) + * scalar_int := :Int32[0](0); # Преобразование типа во время выполнения с указанием размерности (скаляр) + * scalar_int := :Int32[0]([0,]); # Преобразование типа во время выполнения с указанием размерности (скаляр) * - * tensor_int := :Int([0,]); # Преобразование типа во время выполнения с автоматической размерностью (тензор) - * tensor_int := :Int[1](0); # Преобразование типа во время выполнения с указанием размерности (тензор) - * tensor_int := :Int[...](0); # Преобразование типа во время выполнения с произвольной размернотью (тензор) + * tensor_int := :Int32([0,]); # Преобразование типа во время выполнения с автоматической размерностью (тензор) + * tensor_int := :Int32[1](0); # Преобразование типа во время выполнения с указанием размерности (тензор) + * tensor_int := :Int32[...](0); # Преобразование типа во время выполнения с произвольной размернотью (тензор) */ ObjPtr Obj::CreateBaseType(ObjType type) { diff --git a/src/object.h b/src/object.h index 15b73d8c..b311798a 100644 --- a/src/object.h +++ b/src/object.h @@ -6,7 +6,7 @@ #include #include -#include +#include namespace newlang { @@ -127,7 +127,7 @@ namespace newlang { * (чтобы не пересекаться с логикой копирования объектов и не делать для итераторов аругменты по умолчанию) * * Оператор ?? создает итератор и сразу его выполняет, возвращая все значения - * в виде элементов словаря, т.е. аналог последовательности ?(LINQ); !(:Long.__max__); + * в виде элементов словаря, т.е. аналог последовательности ?(LINQ); !(:Int64.__max__); * * Оператор !! без аргументов - сбрасывает итератор в начальное состояние (IteratorReset), * Обператор !! с аргументами выполняется как ! с аругментами, но с начла коллекции. @@ -640,8 +640,8 @@ namespace newlang { } [[nodiscard]] - inline bool is_fraction() const { - return m_var_type_current == ObjType::Fraction; + inline bool is_rational() const { + return m_var_type_current == ObjType::Rational; } [[nodiscard]] @@ -878,7 +878,7 @@ namespace newlang { m_class_parents.clear(); m_var_is_init = false; m_tensor.reset(); - m_fraction.set_(0); + m_rational.set_(0); m_var = at::monostate(); // m_value.reset(); //???????????????? // m_items.clear(); @@ -1363,16 +1363,16 @@ namespace newlang { return utf8_decode(GetValueAsString()); } - std::shared_ptr GetValueAsFraction() const { + std::shared_ptr GetValueAsRational() const { TEST_INIT_(); - if (m_var_type_current == ObjType::Fraction) { - return m_fraction.clone(); + if (m_var_type_current == ObjType::Rational) { + return m_rational.clone(); } else if (is_integral()) { - return std::make_shared(GetValueAsInteger()); + return std::make_shared(GetValueAsInteger()); } else if (is_floating()) { ASSERT("Not implemented!"); } - LOG_RUNTIME("Value %s incompatible to Fraction or convert not implemented!", toString().c_str()); + LOG_RUNTIME("Value %s incompatible to Rational or convert not implemented!", toString().c_str()); } int64_t GetValueAsInteger() const { @@ -1385,25 +1385,25 @@ namespace newlang { } else if (at::holds_alternative(m_var)) { return *at::get(m_var); } - case ObjType::Char: + case ObjType::Int8: if (at::holds_alternative(m_var)) { return at::get(m_var); } else if (at::holds_alternative(m_var)) { return *at::get(m_var); } - case ObjType::Short: + case ObjType::Int16: if (at::holds_alternative(m_var)) { return at::get(m_var); } else if (at::holds_alternative(m_var)) { return *at::get(m_var); } - case ObjType::Int: + case ObjType::Int32: if (at::holds_alternative(m_var)) { return at::get(m_var); } else if (at::holds_alternative(m_var)) { return *at::get(m_var); } - case ObjType::Long: + case ObjType::Int64: if (at::holds_alternative(m_var)) { return at::get(m_var); } else if (at::holds_alternative(m_var)) { @@ -1416,13 +1416,13 @@ namespace newlang { ASSERT(!is_scalar()); LOG_RUNTIME("Can`t convert tensor to scalar!"); + case ObjType::Float32: + case ObjType::Float64: case ObjType::Float: - case ObjType::Double: - case ObjType::Number: return static_cast (GetValueAsNumber()); - case ObjType::Fraction: - return m_fraction.GetAsInteger(); + case ObjType::Rational: + return m_rational.GetAsInteger(); case ObjType::StrWide: case ObjType::FmtWide: @@ -1453,19 +1453,19 @@ namespace newlang { switch (m_var_type_current) { - case ObjType::Float: + case ObjType::Float32: if (at::holds_alternative(m_var)) { return at::get(m_var); } else if (at::holds_alternative(m_var)) { return *at::get(m_var); } - case ObjType::Double: + case ObjType::Float64: if (at::holds_alternative(m_var)) { return at::get(m_var); } else if (at::holds_alternative(m_var)) { return *at::get(m_var); } - case ObjType::Number: + case ObjType::Float: if (at::holds_alternative(m_var)) { return at::get(m_var); } @@ -1474,8 +1474,8 @@ namespace newlang { } LOG_RUNTIME("Can`t convert tensor to scalar!"); - case ObjType::Fraction: - return m_fraction.GetAsNumber(); + case ObjType::Rational: + return m_rational.GetAsNumber(); case ObjType::Iterator: ASSERT(m_iterator); @@ -1508,8 +1508,8 @@ namespace newlang { case ObjType::None: return false; - case ObjType::Fraction: - return m_fraction.GetAsBoolean(); + case ObjType::Rational: + return m_rational.GetAsBoolean(); case ObjType::Dictionary: case ObjType::Class: @@ -1603,7 +1603,7 @@ namespace newlang { return std::make_shared(type, nullptr, nullptr, fixed, is_init); } - static ObjPtr CreateFraction(const std::string val) { + static ObjPtr CreateRational(const std::string val) { std::string str; std::remove_copy(val.begin(), val.end(), back_inserter(str), '_'); @@ -1612,31 +1612,31 @@ namespace newlang { LOG_RUNTIME("Empty string!"); } - ObjPtr frac = Obj::CreateType(ObjType::Fraction); + ObjPtr obj = Obj::CreateType(ObjType::Rational); // Ищем разделитель дроби size_t pos = str.find("\\"); // Если символ не найден - то вся строка является числом if (pos == std::string::npos) { - frac->m_fraction.set_(0); + obj->m_rational.set_(0); } else { // Числитель - левая часть // Знаменатель - правая часть - frac->m_fraction.set_(str.substr(0, pos), str.substr(pos + 1, str.length())); + obj->m_rational.set_(str.substr(0, pos), str.substr(pos + 1, str.length())); // Знаменатель не должен быть равен нулю - if (frac->m_fraction.m_denominator.isZero()) { + if (obj->m_rational.m_denominator.isZero()) { LOG_RUNTIME("Denominator must be different from zero!"); } } - frac->m_var_is_init = true; - if (str.compare(frac->m_fraction.GetAsString().c_str()) != 0) { + obj->m_var_is_init = true; + if (str.compare(obj->m_rational.GetAsString().c_str()) != 0) { - LOG_RUNTIME("Fraction value '%s' does not match source string '%s'!", frac->m_fraction.GetAsString().c_str(), str.c_str()); + LOG_RUNTIME("Rational value '%s' does not match source string '%s'!", obj->m_rational.GetAsString().c_str(), str.c_str()); } - return frac; + return obj; } @@ -1691,29 +1691,30 @@ namespace newlang { return ObjType::Bool; case at::ScalarType::Half: case at::ScalarType::BFloat16: + return ObjType::Float16; case at::ScalarType::Float: - return ObjType::Float; + return ObjType::Float32; case at::ScalarType::Double: - return ObjType::Double; + return ObjType::Float64; case at::ScalarType::Byte: case at::ScalarType::Char: case at::ScalarType::QInt8: case at::ScalarType::QUInt8: case at::ScalarType::QUInt4x2: - return ObjType::Char; + return ObjType::Int8; case at::ScalarType::Short: - return ObjType::Short; + return ObjType::Int16; case at::ScalarType::Int: case at::ScalarType::QInt32: - return ObjType::Int; + return ObjType::Int32; case at::ScalarType::Long: - return ObjType::Long; + return ObjType::Int64; case at::ScalarType::ComplexHalf: + return ObjType::Complex16; case at::ScalarType::ComplexFloat: - return ObjType::ComplexFloat; - + return ObjType::Complex32; case at::ScalarType::ComplexDouble: - return ObjType::ComplexDouble; + return ObjType::Complex64; } LOG_RUNTIME("Fail tensor type %s", val.toString().c_str()); } @@ -1802,10 +1803,10 @@ namespace newlang { case ObjType::Bool: return Index(GetValueAsBoolean()); - case ObjType::Char: - case ObjType::Short: - case ObjType::Int: - case ObjType::Long: + case ObjType::Int8: + case ObjType::Int16: + case ObjType::Int32: + case ObjType::Int64: return Index(GetValueAsInteger()); default: LOG_RUNTIME("Fail convert scalar type '%s' to Index!", newlang::toString(m_var_type_current)); @@ -2110,19 +2111,27 @@ namespace newlang { inline void testResultIntegralType(ObjType type, bool upscalint) { ObjType new_type = m_var_type_current; - if (!canCast(type, m_var_type_current)) { - testConvertType(type); - new_type = type; - } - bool check = false; - if (upscalint && isIntegralType(m_var_type_current, true) && isIntegralType(type, true)) { - if (type < ObjType::Long) { - new_type = static_cast (static_cast (type) + 1); - check = true; + + if (((is_integral() && isIntegralType(type, true)) || (is_floating() && isFloatingType(type))) + && static_cast (type) <= static_cast (m_var_type_current)) { + // type already including to current type + + } else { + + if (!canCast(type, m_var_type_current)) { + testConvertType(type); + new_type = type; } - if (check && m_var_type_fixed != ObjType::None && !canCast(new_type, m_var_type_fixed)) { - new_type = type; // Тип данных менять нельзя, но сама операция возможна - LOG_WARNING("Data type '%s' cannot be changed to '%s', loss of precision is possible!", newlang::toString(type), newlang::toString(m_var_type_fixed)); + bool check = false; + if (upscalint && isIntegralType(m_var_type_current, true) && isIntegralType(type, true)) { + if (type < ObjType::Int64) { + new_type = static_cast (static_cast (type) + 1); + check = true; + } + if (check && m_var_type_fixed != ObjType::None && !canCast(new_type, m_var_type_fixed)) { + new_type = type; // Тип данных менять нельзя, но сама операция возможна + LOG_WARNING("Data type '%s' cannot be changed to '%s', loss of precision is possible!", newlang::toString(type), newlang::toString(m_var_type_fixed)); + } } } if (new_type != m_var_type_current) { @@ -2196,7 +2205,7 @@ namespace newlang { *at::get(m_var) = value->GetValueAsInteger(); } break; - case ObjType::Char: + case ObjType::Int8: if (at::holds_alternative(m_var)) { m_var = value->GetValueAsInteger(); } else if (at::holds_alternative(m_var)) { @@ -2204,7 +2213,7 @@ namespace newlang { *at::get(m_var) = static_cast (value->GetValueAsInteger()); } break; - case ObjType::Short: + case ObjType::Int16: if (at::holds_alternative(m_var)) { m_var = value->GetValueAsInteger(); } else if (at::holds_alternative(m_var)) { @@ -2212,7 +2221,7 @@ namespace newlang { *at::get(m_var) = static_cast (value->GetValueAsInteger()); } break; - case ObjType::Int: + case ObjType::Int32: if (at::holds_alternative(m_var)) { m_var = value->GetValueAsInteger(); } else if (at::holds_alternative(m_var)) { @@ -2220,7 +2229,7 @@ namespace newlang { *at::get(m_var) = static_cast (value->GetValueAsInteger()); } break; - case ObjType::Long: + case ObjType::Int64: if (at::holds_alternative(m_var)) { m_var = value->GetValueAsInteger(); } else if (at::holds_alternative(m_var)) { @@ -2228,7 +2237,7 @@ namespace newlang { *at::get(m_var) = value->GetValueAsInteger(); } break; - case ObjType::Float: + case ObjType::Float32: if (at::holds_alternative(m_var)) { m_var = value->GetValueAsNumber(); } else if (at::holds_alternative(m_var)) { @@ -2236,7 +2245,7 @@ namespace newlang { *at::get(m_var) = static_cast (value->GetValueAsNumber()); } break; - case ObjType::Double: + case ObjType::Float64: if (at::holds_alternative(m_var)) { m_var = value->GetValueAsNumber(); } else if (at::holds_alternative(m_var)) { @@ -2321,16 +2330,16 @@ namespace newlang { m_var_is_init = true; return; - } else if ((is_none_type() && value->getType() == ObjType::Fraction) || ((m_var_type_current == ObjType::Fraction) && value->is_arithmetic_type())) { + } else if ((is_none_type() && value->getType() == ObjType::Rational) || ((m_var_type_current == ObjType::Rational) && value->is_arithmetic_type())) { if (is_none_type()) { - m_fraction = *value->GetValueAsFraction(); + m_rational = *value->GetValueAsRational(); m_var_is_init = true; } else { - m_fraction.set_(*value->GetValueAsFraction()); + m_rational.set_(*value->GetValueAsRational()); } m_var = at::monostate(); - m_var_type_current = ObjType::Fraction; + m_var_type_current = ObjType::Rational; return; } else if ((is_none_type() || m_var_type_current == ObjType::Function || m_var_type_current == ObjType::EVAL_FUNCTION) && (value->m_var_type_current == ObjType::BLOCK || value->m_var_type_current == ObjType::BLOCK_TRY)) { @@ -2354,7 +2363,7 @@ namespace newlang { LOG_RUNTIME("Set value type '%s' not implemented!", newlang::toString(m_var_type_current)); } - static std::string format(std::string format, Obj *args); + static std::string format(std::string format, Obj * args); bool CallAll(const char *func_name, ObjPtr &arg_in, ObjPtr &result, ObjPtr object = nullptr, size_t limit = 0); // ? @@ -2364,7 +2373,7 @@ namespace newlang { static ObjPtr CreateFunc(Context *ctx, TermPtr proto, ObjType type, const std::string var_name = ""); static ObjPtr CreateFunc(std::string proto, FunctionType *func_addr, ObjType type = ObjType::Function); - ObjPtr ConvertToArgs(Obj *args, bool check_valid, Context *ctx) const { + ObjPtr ConvertToArgs(Obj *args, bool check_valid, Context * ctx) const { ObjPtr result = Clone(); result->ConvertToArgs_(args, check_valid, ctx); @@ -2404,7 +2413,7 @@ namespace newlang { // Применение variant необходимо для полей хранения данных, чтобы контролировать их инициализацию // std::variant, std::shared_ptr< Iterator >, TermPtr> m_var; + // std::shared_ptr, std::shared_ptr< Iterator >, TermPtr> m_var; // std::variant m_var; @@ -2413,9 +2422,9 @@ namespace newlang { int64_t size; }; - at::variant> m_var; + Rational, torch::Tensor, std::string, std::wstring, TermPtr, Iterator < Obj>> m_var; // union { // int64_t m_integer; @@ -2426,8 +2435,8 @@ namespace newlang { std::string m_value; ///< Содержит байтовую строку или байтовый массив с данными для представления в нативном виде (Struct, Unuion, Enum) std::wstring m_string; ///< Содержит строку широких символов torch::Tensor m_tensor; ///< Содержит только размерные тензоры (скляры хранятся в поле m_pointer и не создают m_tensor.defined()) - Fraction m_fraction; ///< Содержит дробь из длинных чисел - std::shared_ptr> m_iterator; ///< Итератор для данных + Rational m_rational; ///< Содержит дробь из длинных чисел + std::shared_ptr> m_iterator; ///< Итератор для данных mutable ObjPtr m_iter_range_value; TermPtr m_sequence; ///< Последовательно распарсенных команд для выполнения const TermPtr m_prototype; ///< Описание прототипп функции (или данных) diff --git a/src/parser.y b/src/parser.y index 7713a9b1..7c589b05 100644 --- a/src/parser.y +++ b/src/parser.y @@ -69,13 +69,13 @@ * Термины в CamelCase соответствуют типам данных NewLang * БНФ лексики NewLang * - * Integer ::= целые числа | целые числа "_" целые числа (Bool, Char, Short, Int, Long + BigNum) - * Number ::= с плавающей точкой (Float, Double) - * Complex ::= комплексные числа (ComplexFloat, ComplexDouble) - * Fraction ::= Integer "\" Integer (Представление BigNum / BigNum) - * Currency ::= "`" Integer | "`" Integer "." Integer (Представление Fraction == BigNum / 10000) + * Integer ::= целые числа | целые числа "_" целые числа (Bool, Int8, Int16, Int32, Int64 + BigNum) + * Float ::= с плавающей точкой (Float32, Float64) + * Complex ::= комплексные числа (Complex32, Complex64) + * Rational ::= Integer "\" Integer (Представление BigNum / BigNum) + * Currency ::= "`" Integer | "`" Integer "." Integer (Представление Rational == BigNum / 10000) * - * Ariphmetic ::= Integer | Number | Complex | Fraction + * Ariphmetic ::= Integer | Float | Complex | Rational * * StrChar ::= "'" символы "'" * StrWide ::= "\"" символы "\"" @@ -144,7 +144,7 @@ * * # Инициализация для функции demo * @::var = _; - * @print := NewLang(import= «printf(format:FmtChar, ...):Int» ); + * @print := NewLang(import= «printf(format:FmtChar, ...):Int32» ); * --; * * %{ std::string demo(const char *arg) {; $var = arg; %} @@ -176,13 +176,13 @@ * NewLang(load="module_name", init=1); * * __constructor1() := NewLang(import = 'class():class'); - * __constructor2(arg) := NewLang(import = 'class(arg:Int):class'); + * __constructor2(arg) := NewLang(import = 'class(arg:Int32):class'); * __constructor3(arg) := NewLang(import = 'class(arg:StrChar):class'); * * :class::class(arg=_) ::= { * arg:? => { # Выполняется не точное сравнение c приведеним типов * :None -> __constructor1(); - * :Int -> __constructor2(arg); + * :Int32 -> __constructor2(arg); * :String -> __constructor3(arg); * _ -> -- "Неизвестный тип аргумента" --; * } @@ -261,7 +261,7 @@ * _var := 1; # защиенное поле объекта * __var := 1; # приватное поле объекта * __var__ := 1; # Системное - * var1, var2, var3:Int := _; # Переменная объекта + * var1, var2, var3:Int32 := _; # Переменная объекта * * :class.var_class - к статическому полю * @@ -331,9 +331,9 @@ star_arg = [STAR] STAR ID %token INTEGER "Integer" -%token NUMBER "Number" +%token NUMBER "Float" %token COMPLEX "Complex" -%token FRACTION "Fraction" +%token RATIONAL "Rational" %token STRCHAR "StrChar" %token STRWIDE "StrWide" %token TEMPLATE "Template" @@ -533,7 +533,7 @@ digits_literal: INTEGER $$ = $1; $$->SetType(nullptr); } - | FRACTION + | RATIONAL { $$ = $1; $$->SetType(nullptr); @@ -1316,7 +1316,7 @@ addition: addition op_factor factor if($1->getTermID() == TermID::INTEGER && $op_factor->m_text.compare("/")==0 && $3->m_text.compare("1")==0) { NL_PARSER($op_factor, "Do not use division by one (e.g. 123/1), " "as this operation does not make sense, but it is easy to " - "confuse it with the notation of a fraction literal (123\\1)."); + "confuse it with the notation of a rational literal (123\\1)."); } $$ = $op_factor; diff --git a/src/fraction.h b/src/rational.h similarity index 80% rename from src/fraction.h rename to src/rational.h index 63332b59..9190b8c2 100644 --- a/src/fraction.h +++ b/src/rational.h @@ -1,7 +1,7 @@ #include "pch.h" -#ifndef FRACTION_H -#define FRACTION_H +#ifndef RATIONAL_H +#define RATIONAL_H #include @@ -192,7 +192,7 @@ namespace newlang { }; - class Fraction { + class Rational { public: BigNum m_numerator; // Числитель @@ -201,23 +201,23 @@ namespace newlang { public: // Конструктор принимает значения числителя и знаменателя - Fraction() : Fraction("0", "1") { + Rational() : Rational("0", "1") { } - Fraction(const int64_t value) { + Rational(const int64_t value) { set_(value); } - Fraction(const Fraction ©) { + Rational(const Rational ©) { set_(copy); } - Fraction(const std::string numerator, const std::string denominator) { + Rational(const std::string numerator, const std::string denominator) { set_(numerator, denominator); } - inline std::shared_ptr clone() const { - std::shared_ptr result = std::make_shared(*this); + inline std::shared_ptr clone() const { + std::shared_ptr result = std::make_shared(*this); return result; } @@ -276,7 +276,7 @@ namespace newlang { ASSERT(rem.isZero()); } - Fraction &set_(const int64_t value) { + Rational &set_(const int64_t value) { if (value < 0) { BN_set_word(m_numerator.value, -value); BN_set_negative(m_numerator.value, -1); @@ -287,40 +287,40 @@ namespace newlang { return *this; } - Fraction &set_(const Fraction ©) { + Rational &set_(const Rational ©) { m_numerator.set_(copy.m_numerator); m_denominator.set_(copy.m_denominator); return *this; } - Fraction &set_(const std::string numerator, const std::string denominator) { + Rational &set_(const std::string numerator, const std::string denominator) { m_numerator.SetFromString(numerator); m_denominator.SetFromString(denominator); return *this; } - Fraction& operator*=(const Fraction &fraction) { - m_numerator.mul(fraction.m_numerator); - m_denominator.mul(fraction.m_denominator); + Rational& operator*=(const Rational &rational) { + m_numerator.mul(rational.m_numerator); + m_denominator.mul(rational.m_denominator); reduce(); return *this; } - Fraction& operator/=(const Fraction &fraction) { - m_numerator.mul(fraction.m_denominator); - m_denominator.mul(fraction.m_numerator); + Rational& operator/=(const Rational &rational) { + m_numerator.mul(rational.m_denominator); + m_denominator.mul(rational.m_numerator); reduce(); return *this; } - Fraction& operator-=(const Fraction &fraction) { + Rational& operator-=(const Rational &rational) { - BigNum sub_num(fraction.m_numerator); + BigNum sub_num(rational.m_numerator); sub_num.mul(m_denominator); - m_numerator.mul(fraction.m_denominator); - m_denominator.mul(fraction.m_denominator); + m_numerator.mul(rational.m_denominator); + m_denominator.mul(rational.m_denominator); m_numerator.sub(sub_num); @@ -329,12 +329,12 @@ namespace newlang { return *this; } - Fraction& operator+=(const Fraction &fraction) { - BigNum add_num(fraction.m_numerator); + Rational& operator+=(const Rational &rational) { + BigNum add_num(rational.m_numerator); add_num.mul(m_denominator); - m_numerator.mul(fraction.m_denominator); - m_denominator.mul(fraction.m_denominator); + m_numerator.mul(rational.m_denominator); + m_denominator.mul(rational.m_denominator); m_numerator.add(add_num); @@ -343,77 +343,77 @@ namespace newlang { return *this; } - Fraction& operator%=(const Fraction &fraction) { + Rational& operator%=(const Rational &rational) { LOG_RUNTIME("Not implemented!"); return *this; } - Fraction &operator^=(const Fraction &) { + Rational &operator^=(const Rational &) { LOG_RUNTIME("Operator '^=' not implementd!"); return *this; } - Fraction & operator|=(const Fraction &) { + Rational & operator|=(const Rational &) { LOG_RUNTIME("Operator '|=' not implementd!"); return *this; } - Fraction &op_lshift_set(const Fraction &) { + Rational &op_lshift_set(const Rational &) { LOG_RUNTIME("Operator '<<=' not implementd!"); return *this; } - Fraction & op_rshift_set(const Fraction &) { + Rational & op_rshift_set(const Rational &) { LOG_RUNTIME("Operator '>>=' not implementd!"); return *this; } - const Fraction & op_rrshift_set(const Fraction &) { + const Rational & op_rrshift_set(const Rational &) { LOG_RUNTIME("Operator '>>>=' not implementd!"); return *this; } - Fraction& op_pow_(const Fraction &fraction) { + Rational& op_pow_(const Rational &rational) { LOG_RUNTIME("Not implemented!"); return *this; } - bool op_equal(const Fraction &fraction) const { - return BN_cmp(m_numerator.value, fraction.m_numerator.value) == 0 && - BN_cmp(m_denominator.value, fraction.m_denominator.value) == 0; + bool op_equal(const Rational &rational) const { + return BN_cmp(m_numerator.value, rational.m_numerator.value) == 0 && + BN_cmp(m_denominator.value, rational.m_denominator.value) == 0; } - int op_compare(const Fraction &fraction) const { - if (BN_cmp(m_denominator.value, fraction.m_denominator.value) == 0) { - return BN_cmp(m_numerator.value, fraction.m_numerator.value); + int op_compare(const Rational &rational) const { + if (BN_cmp(m_denominator.value, rational.m_denominator.value) == 0) { + return BN_cmp(m_numerator.value, rational.m_numerator.value); } - Fraction first(*this); - Fraction second(fraction); + Rational first(*this); + Rational second(rational); - Fraction mul; + Rational mul; mul.m_numerator.set_(m_denominator); second *= mul; - mul.m_numerator.set_(fraction.m_denominator); + mul.m_numerator.set_(rational.m_denominator); first *= mul; ASSERT(BN_cmp(first.m_denominator.value, second.m_denominator.value) == 0); return BN_cmp(first.m_numerator.value, second.m_numerator.value); } - Fraction &op_div_ceil_(Fraction &fraction) { + Rational &op_div_ceil_(Rational &rational) { LOG_RUNTIME("Not implemented!"); return *this; } }; }; -#endif /* FRACTION_H */ +#endif /* RATIONAL_H */ diff --git a/src/term.cpp b/src/term.cpp index 96992780..68878822 100644 --- a/src/term.cpp +++ b/src/term.cpp @@ -10,7 +10,7 @@ size_t newlang::IndexArg(TermPtr term) { char * pEnd = nullptr; size_t index = std::strtoul(term->getText().data() + 1, &pEnd, 10); if(term->m_text.data() + term->getText().size() != pEnd) { - LOG_RUNTIME("Number error '%s' or out of range!", term->getText().c_str()); + LOG_RUNTIME("Float error '%s' or out of range!", term->getText().c_str()); } return index; } diff --git a/src/term.h b/src/term.h index ffd8d8c3..d8c0ef78 100644 --- a/src/term.h +++ b/src/term.h @@ -31,7 +31,7 @@ namespace newlang { _(EVAL) \ _(COMMENT) \ \ - _(FRACTION) \ + _(RATIONAL) \ \ _(NONE) \ _(EMPTY) \ @@ -646,7 +646,7 @@ namespace newlang { return result; case TermID::SYMBOL: - case TermID::FRACTION: + case TermID::RATIONAL: case TermID::COMPLEX: case TermID::MACRO: return m_text; @@ -1027,12 +1027,12 @@ namespace newlang { NL_PARSER(type, "Error cast '%s' to integer type '%s'", m_text.c_str(), m_type_name.c_str()); } } else if (m_id == TermID::NUMBER) { - ObjType type_val = typeFromLimit(parseDouble(m_text.c_str()), ObjType::Float); + ObjType type_val = typeFromLimit(parseDouble(m_text.c_str()), ObjType::Float32); if (!canCastLimit(type_val, typeFromString(m_type_name))) { NL_PARSER(type, "Error cast '%s' to numeric type '%s'", m_text.c_str(), m_type_name.c_str()); } } else if (m_id == TermID::COMPLEX) { - ObjType type_val = typeFromLimit(parseComplex(m_text.c_str()), ObjType::ComplexFloat); + ObjType type_val = typeFromLimit(parseComplex(m_text.c_str()), ObjType::Complex32); if (!canCastLimit(type_val, typeFromString(m_type_name))) { NL_PARSER(type, "Error cast '%s' to complex type '%s'", m_text.c_str(), m_type_name.c_str()); } @@ -1045,9 +1045,9 @@ namespace newlang { if (m_id == TermID::INTEGER) { m_type_name = newlang::toString(typeFromLimit(parseInteger(m_text.c_str()), ObjType::Bool)); } else if (m_id == TermID::NUMBER) { - m_type_name = newlang::toString(typeFromLimit(parseDouble(m_text.c_str()), ObjType::Float)); + m_type_name = newlang::toString(typeFromLimit(parseDouble(m_text.c_str()), ObjType::Float32)); } else if (m_id == TermID::COMPLEX) { - m_type_name = newlang::toString(typeFromLimit(parseComplex(m_text.c_str()), ObjType::ComplexFloat)); + m_type_name = newlang::toString(typeFromLimit(parseComplex(m_text.c_str()), ObjType::Complex32)); } else if (m_id == TermID::STRCHAR) { m_type_name = newlang::toString(ObjType::StrChar); } else if (m_id == TermID::STRWIDE) { diff --git a/src/test/alg_test.cpp b/src/test/alg_test.cpp index bc12c49f..447c41e2 100644 --- a/src/test/alg_test.cpp +++ b/src/test/alg_test.cpp @@ -491,11 +491,11 @@ TEST(Alg, Return) { ASSERT_FALSE(result); try { - result = ctx.ExecStr("--:Int--", nullptr, false); + result = ctx.ExecStr("--:Int32--", nullptr, false); } catch (Interrupt &except) { - ASSERT_STREQ(":Int", except.m_obj->m_class_name.c_str()); + ASSERT_STREQ(":Int32", except.m_obj->m_class_name.c_str()); ASSERT_EQ(0, except.m_obj->size()); - ASSERT_STREQ(":Int", except.m_obj->toString().c_str()); + ASSERT_STREQ(":Int32", except.m_obj->toString().c_str()); } ASSERT_FALSE(result); diff --git a/src/test/compiler_test.cpp b/src/test/compiler_test.cpp index e1d394f8..2b4320c8 100644 --- a/src/test/compiler_test.cpp +++ b/src/test/compiler_test.cpp @@ -540,8 +540,8 @@ TEST(Compiler, DISABLED_FuncsTypes) { RuntimePtr opts = RunTime::Init(); Context ctx(opts); -#define FUNC_ARG "func_arg(arg1: Char, arg2): Char := { $arg1+$arg2; };" -#define FUNC_RES "func_res(arg1: Char, arg2: Int): Integer := { $arg2+=$arg1; };" +#define FUNC_ARG "func_arg(arg1: Int8, arg2): Int8 := { $arg1+$arg2; };" +#define FUNC_RES "func_res(arg1: Int8, arg2: Int32): Integer := { $arg2+=$arg1; };" TermPtr func; Parser parser(func); @@ -549,12 +549,12 @@ TEST(Compiler, DISABLED_FuncsTypes) { std::ostringstream sstr; // Не соответствие типа функции в операторе - parser.Parse(FUNC_ARG FUNC_RES "\n$res:Char := func_arg(100, 100); $res += func_res(100, 100);"); + parser.Parse(FUNC_ARG FUNC_RES "\n$res:Int8 := func_arg(100, 100); $res += func_res(100, 100);"); sstr.str(""); ASSERT_THROW(NewLang::MakeCppFile(func, sstr, nullptr, &ctx), Interrupt) << sstr.str(); // Компилится без ошибок - parser.Parse(FUNC_ARG "\nfunc_arg(Char(100), 100);"); + parser.Parse(FUNC_ARG "\nfunc_arg(Int8(100), 100);"); sstr.str(""); ASSERT_NO_THROW(NewLang::MakeCppFile(func, sstr, nullptr, &ctx)) << sstr.str(); @@ -564,12 +564,12 @@ TEST(Compiler, DISABLED_FuncsTypes) { ASSERT_THROW(NewLang::MakeCppFile(func, sstr, nullptr, &ctx), Interrupt) << sstr.str(); // Не соответствие типа функции - parser.Parse(FUNC_ARG FUNC_RES "\n$res:Char := func_res(100, 1000);"); + parser.Parse(FUNC_ARG FUNC_RES "\n$res:Int8 := func_res(100, 1000);"); sstr.str(""); ASSERT_THROW(NewLang::MakeCppFile(func, sstr, nullptr, &ctx), Interrupt) << sstr.str(); // Не соответствие типа функции в операторе - parser.Parse(FUNC_ARG FUNC_RES "\n$res:Char := func_arg(100, 100); $res += func_res(100, 100);"); + parser.Parse(FUNC_ARG FUNC_RES "\n$res:Int8 := func_arg(100, 100); $res += func_res(100, 100);"); sstr.str(""); ASSERT_THROW(NewLang::MakeCppFile(func, sstr, nullptr, &ctx), Interrupt) << sstr.str(); @@ -579,7 +579,7 @@ TEST(Compiler, DISABLED_FuncsTypes) { ASSERT_NO_THROW(NewLang::MakeCppFile(func, sstr, nullptr, &ctx)) << sstr.str(); // Тип есть, но делается каст возвращаемого типа у функции - parser.Parse(FUNC_ARG FUNC_RES "\n$res: Char := func_arg(100, 100); $res += Char(func_res(100, 100));"); + parser.Parse(FUNC_ARG FUNC_RES "\n$res: Int8 := func_arg(100, 100); $res += Int8(func_res(100, 100));"); sstr.str(""); ASSERT_NO_THROW(NewLang::MakeCppFile(func, sstr, nullptr, &ctx)) << sstr.str(); diff --git a/src/test/eval_test.cpp b/src/test/eval_test.cpp index 99621bee..94a5ce6f 100644 --- a/src/test/eval_test.cpp +++ b/src/test/eval_test.cpp @@ -44,7 +44,7 @@ TEST(Eval, Assign) { ASSERT_TRUE(var1->is_arithmetic_type()); ASSERT_TRUE(var1->is_integer()); ASSERT_TRUE(at::holds_alternative(var1->m_var)); - ASSERT_EQ(var1->m_var_type_current, ObjType::Char) << newlang::toString(var1->m_var_type_current); + ASSERT_EQ(var1->m_var_type_current, ObjType::Int8) << newlang::toString(var1->m_var_type_current); ASSERT_EQ(var1->m_var_type_fixed, ObjType::None) << newlang::toString(var1->m_var_type_fixed); ASSERT_STREQ("var1=123", var1->toString().c_str()); ASSERT_FALSE(ctx.find("var1") == ctx.end()); @@ -54,8 +54,8 @@ TEST(Eval, Assign) { ASSERT_THROW(ctx.ExecStr("var1 ::= 123"), Interrupt); - ASSERT_TRUE(ctx.ExecStr("var1 = 100:Char")); - ASSERT_EQ(var1->m_var_type_current, ObjType::Char) << newlang::toString(var1->m_var_type_current); + ASSERT_TRUE(ctx.ExecStr("var1 = 100:Int8")); + ASSERT_EQ(var1->m_var_type_current, ObjType::Int8) << newlang::toString(var1->m_var_type_current); ASSERT_EQ(var1->m_var_type_fixed, ObjType::None) << newlang::toString(var1->m_var_type_fixed); ASSERT_STREQ("var1=100", var1->toString().c_str()); @@ -89,12 +89,12 @@ TEST(Eval, Assign) { list = ctx.ExecStr("$"); ASSERT_STREQ("$=('var_str',)", list->toString().c_str()); - ObjPtr var_num = ctx.ExecStr("var_num := 123.456: Number"); + ObjPtr var_num = ctx.ExecStr("var_num := 123.456: Float"); ASSERT_TRUE(var_num); ASSERT_TRUE(var_num->is_arithmetic_type()); ASSERT_TRUE(var_num->is_tensor_type()); - // ASSERT_EQ(var_num->m_var_type_current, ObjType::Double); - // ASSERT_EQ(var_num->m_var_type_fixed, ObjType::Number); + // ASSERT_EQ(var_num->m_var_type_current, ObjType::Float64); + // ASSERT_EQ(var_num->m_var_type_fixed, ObjType::Float); ASSERT_STREQ("var_num=123.456", var_num->toString().c_str()); list = ctx.ExecStr("$"); @@ -106,10 +106,10 @@ TEST(Eval, Assign) { var_long = 987654321; - ObjPtr var_export = ctx.ExecStr("var_export := :Pointer(\"var_long:Long\")"); + ObjPtr var_export = ctx.ExecStr("var_export := :Pointer(\"var_long:Int64\")"); ASSERT_TRUE(var_export); ASSERT_TRUE(var_export->is_tensor_type()) << var_export; - ASSERT_EQ(var_export->getType(), ObjType::Long); + ASSERT_EQ(var_export->getType(), ObjType::Int64); ASSERT_STREQ("var_export=987654321", var_export->toString().c_str()); var_long = 123132132; ASSERT_STREQ("var_export=123132132", var_export->toString().c_str()); @@ -119,11 +119,11 @@ TEST(Eval, Assign) { list = ctx.ExecStr("$"); ASSERT_STREQ("$=('var_str', 'var_num', 'var_export',)", list->toString().c_str()); - ObjPtr func_export = ctx.ExecStr("func_export := :Pointer(\"func_export(arg1:Long, arg2:Char=100):Long\")"); + ObjPtr func_export = ctx.ExecStr("func_export := :Pointer(\"func_export(arg1:Int64, arg2:Int8=100):Int64\")"); ASSERT_TRUE(func_export); ASSERT_TRUE(func_export->is_function_type()) << func_export; ASSERT_EQ(func_export->getType(), ObjType::NativeFunc); - ASSERT_STREQ("func_export=func_export(arg1:Long, arg2:Char=100):Long{}", func_export->toString().c_str()); + ASSERT_STREQ("func_export=func_export(arg1:Int64, arg2:Int8=100):Int64{}", func_export->toString().c_str()); ObjPtr result = func_export->Call(&ctx, Obj::Arg(200), Obj::Arg(10)); ASSERT_TRUE(result); @@ -193,15 +193,15 @@ TEST(Eval, Assign) { ObjPtr tensor2 = ctx.ExecStr("[222,333,3333,]"); ASSERT_TRUE(tensor2); - ASSERT_STREQ("[222, 333, 3333,]:Short", tensor2->GetValueAsString().c_str()); + ASSERT_STREQ("[222, 333, 3333,]:Int16", tensor2->GetValueAsString().c_str()); ObjPtr tensorf = ctx.ExecStr("[1.2, 0.22, 0.69,]"); ASSERT_TRUE(tensorf); - ASSERT_STREQ("[1.2, 0.22, 0.69,]:Double", tensorf->GetValueAsString().c_str()); + ASSERT_STREQ("[1.2, 0.22, 0.69,]:Float64", tensorf->GetValueAsString().c_str()); ObjPtr tensor_all = ctx.ExecStr("[ [1, 1, 0, 0,], [10, 10, 0.1, 0.2,], ]"); ASSERT_TRUE(tensor_all); - ASSERT_EQ(ObjType::Double, tensor_all->m_var_type_current) << toString(tensor_all->m_var_type_current); + ASSERT_EQ(ObjType::Float64, tensor_all->m_var_type_current) << toString(tensor_all->m_var_type_current); ASSERT_EQ(ObjType::None, tensor_all->m_var_type_fixed) << toString(tensor_all->m_var_type_fixed); ASSERT_EQ(2, tensor_all->m_tensor.dim()) << tensor_all->m_tensor.size(0); ASSERT_EQ(2, tensor_all->m_tensor.size(0)); @@ -217,7 +217,7 @@ TEST(Eval, Assign) { ASSERT_STREQ("0.1", tensor_all->index_get({1, 2})->GetValueAsString().c_str()); ASSERT_STREQ("0.2", tensor_all->index_get({1, 3})->GetValueAsString().c_str()); - ASSERT_STREQ("[\n [1, 1, 0, 0,], [10, 10, 0.1, 0.2,],\n]:Double", tensor_all->GetValueAsString().c_str()); + ASSERT_STREQ("[\n [1, 1, 0, 0,], [10, 10, 0.1, 0.2,],\n]:Float64", tensor_all->GetValueAsString().c_str()); } TEST(Eval, Tensor) { @@ -230,7 +230,7 @@ TEST(Eval, Tensor) { ddd = ctx.ExecStr(":Tensor( (1,2,3,) )"); ASSERT_TRUE(ddd); - ASSERT_STREQ("[1, 2, 3,]:Char", ddd->GetValueAsString().c_str()) << ddd->GetValueAsString().c_str(); + ASSERT_STREQ("[1, 2, 3,]:Int8", ddd->GetValueAsString().c_str()) << ddd->GetValueAsString().c_str(); ddd = ctx.ExecStr(":Dictionary(1,2,3)"); @@ -255,75 +255,81 @@ TEST(Eval, Tensor) { tensor = ctx.ExecStr(":Tensor([1,2,3,])"); ASSERT_TRUE(tensor); - ASSERT_STREQ("[1, 2, 3,]:Char", tensor->GetValueAsString().c_str()) << tensor->GetValueAsString().c_str(); + ASSERT_STREQ("[1, 2, 3,]:Int8", tensor->GetValueAsString().c_str()) << tensor->GetValueAsString().c_str(); - tensor = ctx.ExecStr(":Int([1,])"); + tensor = ctx.ExecStr(":Int32([1,])"); ASSERT_TRUE(tensor); - ASSERT_STREQ("[1,]:Int", tensor->GetValueAsString().c_str()) << tensor->GetValueAsString().c_str(); + ASSERT_STREQ("[1,]:Int32", tensor->GetValueAsString().c_str()) << tensor->GetValueAsString().c_str(); ObjPtr tt = ctx.ExecStr(":Tensor[3]( (1,2,3,) )"); ASSERT_TRUE(tt); - ASSERT_STREQ("[1, 2, 3,]:Char", tt->GetValueAsString().c_str()) << tt->GetValueAsString().c_str(); + ASSERT_STREQ("[1, 2, 3,]:Int8", tt->GetValueAsString().c_str()) << tt->GetValueAsString().c_str(); - tt = ctx.ExecStr(":Int((1,2,3,))"); + tt = ctx.ExecStr(":Int32((1,2,3,))"); ASSERT_TRUE(tt); - ASSERT_STREQ("[1, 2, 3,]:Int", tt->GetValueAsString().c_str()) << tt->GetValueAsString().c_str(); + ASSERT_STREQ("[1, 2, 3,]:Int32", tt->GetValueAsString().c_str()) << tt->GetValueAsString().c_str(); - tt = ctx.ExecStr(":Int[2,3]((1,2,3,4,5,6,))"); + tt = ctx.ExecStr(":Int32[2,3]((1,2,3,4,5,6,))"); ASSERT_TRUE(tt); EXPECT_EQ(2, tt->m_tensor.dim()); EXPECT_EQ(2, tt->m_tensor.size(0)); EXPECT_EQ(3, tt->m_tensor.size(1)); - ASSERT_STREQ("[\n [1, 2, 3,], [4, 5, 6,],\n]:Int", tt->GetValueAsString().c_str()); + ASSERT_STREQ("[\n [1, 2, 3,], [4, 5, 6,],\n]:Int32", tt->GetValueAsString().c_str()); ObjPtr str = ctx.ExecStr(":Tensor('first second')"); ASSERT_TRUE(str); - ASSERT_STREQ("[102, 105, 114, 115, 116, 32, 115, 101, 99, 111, 110, 100,]:Char", str->GetValueAsString().c_str()); + ASSERT_STREQ("[102, 105, 114, 115, 116, 32, 115, 101, 99, 111, 110, 100,]:Int8", str->GetValueAsString().c_str()); tt = ctx.ExecStr(":Tensor((first='first', space=32, second='second',))"); ASSERT_TRUE(tt); - ASSERT_STREQ("[102, 105, 114, 115, 116, 32, 115, 101, 99, 111, 110, 100,]:Char", tt->GetValueAsString().c_str()); + ASSERT_STREQ("[102, 105, 114, 115, 116, 32, 115, 101, 99, 111, 110, 100,]:Int8", tt->GetValueAsString().c_str()); ASSERT_TRUE(str->op_equal(tt)); - tt = ctx.ExecStr(":Int[6,2](\"Тензор Int \")"); + tt = ctx.ExecStr(":Int32[7,2](\"Тензор Int32 \")"); ASSERT_TRUE(tt); ASSERT_STREQ("[\n [1058, 1077,], [1085, 1079,], [1086, 1088,], [32, 73,], " - "[110, 116,], [32, 32,],\n]:Int", + "[110, 116,], [51, 50,], [32, 32,],\n]:Int32", tt->GetValueAsString().c_str()); tt = ctx.ExecStr(":Tensor(99)"); ASSERT_TRUE(tt); ASSERT_STREQ("99", tt->GetValueAsString().c_str()); - tt = ctx.ExecStr(":Double[10,2](0, ... )"); + tt = ctx.ExecStr(":Float64[10,2](0, ... )"); ASSERT_TRUE(tt); ASSERT_STREQ("[\n [0, 0,], [0, 0,], [0, 0,], [0, 0,], [0, 0,], [0, 0,], [0, " - "0,], [0, 0,], [0, 0,], [0, 0,],\n]:Double", + "0,], [0, 0,], [0, 0,], [0, 0,],\n]:Float64", tt->GetValueAsString().c_str()); - ObjPtr rand = ctx.ExecStr("rand := :Pointer('rand():Int')"); + ObjPtr srand = ctx.ExecStr("srand := :Pointer('srand(seed:Int32):None')"); + + ObjPtr ret = srand->Call(&ctx, Obj::Arg(100)); + ASSERT_TRUE(ret); + ASSERT_TRUE(ret->is_none_type()); + + ObjPtr rand = ctx.ExecStr("rand := :Pointer('rand():Int32')"); // Может быть раскрытие словаря, который возвращает вызов функции // и может быть многократный вызов одной и той функции - // :Int[3,2]( ... rand() ... ) + // :Int32[3,2]( ... rand() ... ) utils::Logger::LogLevelType save = utils::Logger::Instance()->SetLogLevel(LOG_LEVEL_INFO); - tt = ctx.ExecStr(":Int[3,2]( ... rand() ... )"); + tt = ctx.ExecStr(":Int32[3,2]( ... rand() ... )"); utils::Logger::Instance()->SetLogLevel(save); ASSERT_TRUE(tt); std::string rand_str = tt->GetValueAsString(); ASSERT_TRUE(50 < tt->GetValueAsString().size()) << rand_str; - tt = ctx.ExecStr(":Int[5,2]( 0..10 )"); + tt = ctx.ExecStr(":Int32[5,2]( 0..10 )"); ASSERT_TRUE(tt); - ASSERT_STREQ("[\n [0, 1,], [2, 3,], [4, 5,], [6, 7,], [8, 9,],\n]:Int", tt->GetValueAsString().c_str()); + ASSERT_STREQ("[\n [0, 1,], [2, 3,], [4, 5,], [6, 7,], [8, 9,],\n]:Int32", tt->GetValueAsString().c_str()); - tt = ctx.ExecStr(":Double[5,2]( 0..10 )"); + tt = ctx.ExecStr(":Float64[5,2]( 0..10 )"); ASSERT_TRUE(tt); - ASSERT_STREQ("[\n [0, 1,], [2, 3,], [4, 5,], [6, 7,], [8, 9,],\n]:Double", tt->GetValueAsString().c_str()); + ASSERT_STREQ("[\n [0, 1,], [2, 3,], [4, 5,], [6, 7,], [8, 9,],\n]:Float64", tt->GetValueAsString().c_str()); tt = ctx.ExecStr("0..1..0.1"); ASSERT_TRUE(tt); @@ -335,7 +341,7 @@ TEST(Eval, Tensor) { tt = ctx.ExecStr(":Tensor( 0..0.99..0.1 )"); ASSERT_TRUE(tt); - ASSERT_STREQ("[0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9,]:Double", tt->GetValueAsString().c_str()); + ASSERT_STREQ("[0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9,]:Float64", tt->GetValueAsString().c_str()); } TEST(Eval, FuncSimple) { @@ -392,7 +398,7 @@ TEST(Eval, TypesNative) { ASSERT_EQ(2, types.size()); // ASSERT_STREQ(":Bool", utf8_encode(types[0]).c_str()); - // ASSERT_STREQ(":Char", utf8_encode(types[1]).c_str()); + // ASSERT_STREQ(":Int8", utf8_encode(types[1]).c_str()); types = ctx.SelectPredict(":", 5); ASSERT_EQ(7, types.size()); @@ -437,30 +443,30 @@ TEST(Eval, TypesNative) { ASSERT_TRUE(at::get(fopen3->m_var)); ASSERT_EQ(at::get(fopen->m_var), at::get(fopen3->m_var)); - ObjPtr fclose = ctx.ExecStr("@fclose(stream:File):Int ::= :Pointer(\"fclose(stream:File):Int\")"); + ObjPtr fclose = ctx.ExecStr("@fclose(stream:File):Int32 ::= :Pointer(\"fclose(stream:File):Int32\")"); ASSERT_TRUE(at::holds_alternative(fclose->m_var)); ASSERT_TRUE(at::get(fclose->m_var)); - ObjPtr fremove = ctx.ExecStr("@fremove(filename:String):Int ::= " - ":Pointer(\"remove(filename:StrChar):Int\")"); + ObjPtr fremove = ctx.ExecStr("@fremove(filename:String):Int32 ::= " + ":Pointer(\"remove(filename:StrChar):Int32\")"); ASSERT_TRUE(fremove); ASSERT_TRUE(at::holds_alternative(fremove->m_var)); ASSERT_TRUE(at::get(fremove->m_var)); - ObjPtr frename = ctx.ExecStr("@rename(old:String, new:String):Int ::= " - ":Pointer('rename(old:StrChar, new:StrChar):Int')"); + ObjPtr frename = ctx.ExecStr("@rename(old:String, new:String):Int32 ::= " + ":Pointer('rename(old:StrChar, new:StrChar):Int32')"); ASSERT_TRUE(frename); ASSERT_TRUE(at::holds_alternative(frename->m_var)); ASSERT_TRUE(at::get(frename->m_var)); - ObjPtr fprintf = ctx.ExecStr("@fprintf(stream:File, format:FmtChar, ...):Int ::= " - ":Pointer('fprintf(stream:File, format:FmtChar, ...):Int')"); + ObjPtr fprintf = ctx.ExecStr("@fprintf(stream:File, format:FmtChar, ...):Int32 ::= " + ":Pointer('fprintf(stream:File, format:FmtChar, ...):Int32')"); ASSERT_TRUE(fremove); - ObjPtr fputc = ctx.ExecStr("@fputc(c:Int, stream:File):Int ::= " - ":Pointer('fputc(c:Int, stream:File):Int')"); + ObjPtr fputc = ctx.ExecStr("@fputc(c:Int32, stream:File):Int32 ::= " + ":Pointer('fputc(c:Int32, stream:File):Int32')"); ASSERT_TRUE(fremove); - ObjPtr fputs = ctx.ExecStr("@fputs(s:String, stream:File):Int ::= " - ":Pointer('fputs(s:StrChar, stream:File):Int')"); + ObjPtr fputs = ctx.ExecStr("@fputs(s:String, stream:File):Int32 ::= " + ":Pointer('fputs(s:StrChar, stream:File):Int32')"); ASSERT_TRUE(fputs); std::filesystem::create_directories("temp"); @@ -487,38 +493,38 @@ TEST(Eval, TypesNative) { /* * Enum (перечисление) использование символьного названия поля вместо "магического" числа * - * :EnumStruct = :Enum(One:Int=1, Two=..., Three=10) - все поля имеют имена и автоматическую нумерацию + могут иметь тип + * :EnumStruct = :Enum(One:Int32=1, Two=..., Three=10) - все поля имеют имена и автоматическую нумерацию + могут иметь тип * :EnumStruct.One * var = :EnumStruct(thread, gpu); * - * :TypeStruct = :Struct(One:Int=1, Two:Char=0, Three=10) - все типы поле определены - * :Class(One:Int=1, Two=..., Three=10) - * :Class3 = :Class1(One:Int=1, Two=..., Three=10), Class2(One:Int=1, Two=..., Three=10); + * :TypeStruct = :Struct(One:Int32=1, Two:Int8=0, Three=10) - все типы поле определены + * :Class(One:Int32=1, Two=..., Three=10) + * :Class3 = :Class1(One:Int32=1, Two=..., Three=10), Class2(One:Int32=1, Two=..., Three=10); * - * (One:Int=1, Two=_, Three=10,):Enum(thread, gpu) использовать тип значения в имени поля вместо общего типа ----- Enum(One, Two=2, Three=3):Int ------ + * (One:Int32=1, Two=_, Three=10,):Enum(thread, gpu) использовать тип значения в имени поля вместо общего типа ----- Enum(One, Two=2, Three=3):Int32 ------ * [[ One, Two=2, Three=3 ]]:Enum(thread, gpu) * * :Seek::SET или @Seek::SET - статическое зачение у глобального типа * Seek.SET или $Seek.SET - статическое зачение у глобального типа */ - ObjPtr SEEK1 = ctx.ExecStr("@SEEK1 ::= :Enum(SET:Int=10, \"CUR\", END=20)"); + ObjPtr SEEK1 = ctx.ExecStr("@SEEK1 ::= :Enum(SET:Int32=10, \"CUR\", END=20)"); ASSERT_TRUE(SEEK1); ASSERT_EQ(3, SEEK1->size()); ASSERT_TRUE((*SEEK1)[0].second); - ASSERT_EQ(ObjType::Char, (*SEEK1)[0].second->getType()) << newlang::toString((*SEEK1)[0].second->getType()); - ASSERT_EQ(ObjType::Char, (*SEEK1)[0].second->m_var_type_fixed) << newlang::toString((*SEEK1)[0].second->m_var_type_fixed); + ASSERT_EQ(ObjType::Int8, (*SEEK1)[0].second->getType()) << newlang::toString((*SEEK1)[0].second->getType()); + ASSERT_EQ(ObjType::Int8, (*SEEK1)[0].second->m_var_type_fixed) << newlang::toString((*SEEK1)[0].second->m_var_type_fixed); ASSERT_EQ(10, (*SEEK1)[0].second->GetValueAsInteger()); ASSERT_TRUE((*SEEK1)[1].second); - ASSERT_EQ(ObjType::Char, (*SEEK1)[1].second->getType()) << newlang::toString((*SEEK1)[1].second->getType()); - ASSERT_EQ(ObjType::Char, (*SEEK1)[1].second->m_var_type_fixed) << newlang::toString((*SEEK1)[1].second->m_var_type_fixed); + ASSERT_EQ(ObjType::Int8, (*SEEK1)[1].second->getType()) << newlang::toString((*SEEK1)[1].second->getType()); + ASSERT_EQ(ObjType::Int8, (*SEEK1)[1].second->m_var_type_fixed) << newlang::toString((*SEEK1)[1].second->m_var_type_fixed); ASSERT_EQ(11, (*SEEK1)[1].second->GetValueAsInteger()); ASSERT_TRUE((*SEEK1)[2].second); - ASSERT_EQ(ObjType::Char, (*SEEK1)[2].second->getType()) << newlang::toString((*SEEK1)[2].second->getType()); - ASSERT_EQ(ObjType::Char, (*SEEK1)[2].second->m_var_type_fixed) << newlang::toString((*SEEK1)[2].second->m_var_type_fixed); + ASSERT_EQ(ObjType::Int8, (*SEEK1)[2].second->getType()) << newlang::toString((*SEEK1)[2].second->getType()); + ASSERT_EQ(ObjType::Int8, (*SEEK1)[2].second->m_var_type_fixed) << newlang::toString((*SEEK1)[2].second->m_var_type_fixed); ASSERT_EQ(20, (*SEEK1)[2].second->GetValueAsInteger()); ASSERT_EQ(10, (*SEEK1)["SET"].second->GetValueAsInteger()); @@ -533,7 +539,7 @@ TEST(Eval, TypesNative) { ASSERT_EQ(1, (*SEEK2)[1].second->GetValueAsInteger()); ASSERT_EQ(ObjType::Bool, (*SEEK2)[1].second->getType()); ASSERT_EQ(300, (*SEEK2)[2].second->GetValueAsInteger()); - ASSERT_EQ(ObjType::Short, (*SEEK2)[2].second->getType()); + ASSERT_EQ(ObjType::Int16, (*SEEK2)[2].second->getType()); ASSERT_EQ(0, (*SEEK2)["SET"].second->GetValueAsInteger()); ASSERT_EQ(1, (*SEEK2)["CUR"].second->GetValueAsInteger()); ASSERT_EQ(300, (*SEEK2)["END"].second->GetValueAsInteger()); @@ -559,8 +565,8 @@ TEST(Eval, TypesNative) { ASSERT_TRUE(F_res); ASSERT_EQ(2, F_res->GetValueAsInteger()); - ObjPtr seek = ctx.ExecStr("@fseek(stream:File, offset:Long, whence:Int):Int ::= " - ":Pointer('fseek(stream:File, offset:Long, whence:Int):Int')"); + ObjPtr seek = ctx.ExecStr("@fseek(stream:File, offset:Int64, whence:Int32):Int32 ::= " + ":Pointer('fseek(stream:File, offset:Int64, whence:Int32):Int32')"); ASSERT_TRUE(seek); F_res = ctx.ExecStr("fseek(F2, 10, @SEEK.SET)"); @@ -600,7 +606,7 @@ TEST(Eval, Fileio) { //@todo try and catch segfault // ASSERT_ANY_THROW( - // // Double free + // // Float64 free // file_res = ctx.ExecStr("fclose(file)");); // // Context::Reset(); @@ -613,11 +619,11 @@ TEST(ExecStr, Funcs) { EXPECT_TRUE(ctx.m_runtime->GetNativeAddr("printf")); - ObjPtr p = ctx.ExecStr("printf := :Pointer('printf(format:FmtChar, ...):Int');"); + ObjPtr p = ctx.ExecStr("printf := :Pointer('printf(format:FmtChar, ...):Int32');"); ASSERT_TRUE(p); ASSERT_TRUE(at::holds_alternative(p->m_var)); ASSERT_TRUE(at::get(p->m_var)); - ASSERT_STREQ("printf=printf(format:FmtChar, ...):Int{}", p->toString().c_str()); + ASSERT_STREQ("printf=printf(format:FmtChar, ...):Int32{}", p->toString().c_str()); typedef int (* printf_type)(const char *, ...); @@ -654,34 +660,34 @@ TEST(ExecStr, Funcs) { } /* - * scalar_int := 100:Int; # Тип скаляра во время компиляции - * scalar_int := 100:Int(__device__="GPU"); # Тип скаляра во время компиляции - * scalar_int := 100:Int(); ?????? # Тип скаляра во время компиляции - * :type_int := :Int; # Синоним типа Int во время компиляции (тип не может быть изменен) - * :type_int := :Int(); # Копия типа Int во время выполнения (тип может быть изменен после Mutable) + * scalar_int := 100:Int32; # Тип скаляра во время компиляции + * scalar_int := 100:Int32(__device__="GPU"); # Тип скаляра во время компиляции + * scalar_int := 100:Int32(); ?????? # Тип скаляра во время компиляции + * :type_int := :Int32; # Синоним типа Int32 во время компиляции (тип не может быть изменен) + * :type_int := :Int32(); # Копия типа Int32 во время выполнения (тип может быть изменен после Mutable) * - * scalar_int := :Int(0); # Преобразование типа во время выполнения с автоматической размерностью (скаляр) - * scalar_int := :Int[0](0); # Преобразование типа во время выполнения с указанием размерности (скаляр) - * scalar_int := :Int[0]([0,]); # Преобразование типа во время выполнения с указанием размерности (скаляр) + * scalar_int := :Int32(0); # Преобразование типа во время выполнения с автоматической размерностью (скаляр) + * scalar_int := :Int32[0](0); # Преобразование типа во время выполнения с указанием размерности (скаляр) + * scalar_int := :Int32[0]([0,]); # Преобразование типа во время выполнения с указанием размерности (скаляр) * - * tensor_int := :Int([0,]); # Преобразование типа во время выполнения с автоматической размерностью (тензор) - * tensor_int := :Int[1](0); # Преобразование типа во время выполнения с указанием размерности (тензор) - * tensor_int := :Int[...](0); # Преобразование типа во время выполнения с произвольной размернотью (тензор) + * tensor_int := :Int32([0,]); # Преобразование типа во время выполнения с автоматической размерностью (тензор) + * tensor_int := :Int32[1](0); # Преобразование типа во время выполнения с указанием размерности (тензор) + * tensor_int := :Int32[...](0); # Преобразование типа во время выполнения с произвольной размернотью (тензор) * * - * :синоним := :Int; # Неизменяемый ????? - * :копия := :Int(); # Изменяемый ????? + * :синоним := :Int32; # Неизменяемый ????? + * :копия := :Int32(); # Изменяемый ????? * * Mutable(:синоним); # Ошибка * Mutable(:копия); # Норма * - * :Int(1); # Не меняет размерность, только тип !!!! - * :Int[2, ...](100, 200); # Одномерный тензор Int произвольного размера - * :Int([,], 100, 200); # Объединить аргументы, если их несколько и преобразовать их тип к Int - * :Int[0](10000000); # Преобразовать тип к скаляру - * :Int[2](100, 200); # Преобразовать аргументы в тензор указанной размерности и заданного типа - * :Int[2,1](100, 200); # Преобразовать аргументы в тензор указанной размерности и заданного типа - * :Int[1,2](100, 200); # Преобразовать аргументы в тензор указанной размерности и заданного типа + * :Int32(1); # Не меняет размерность, только тип !!!! + * :Int32[2, ...](100, 200); # Одномерный тензор Int32 произвольного размера + * :Int32([,], 100, 200); # Объединить аргументы, если их несколько и преобразовать их тип к Int32 + * :Int32[0](10000000); # Преобразовать тип к скаляру + * :Int32[2](100, 200); # Преобразовать аргументы в тензор указанной размерности и заданного типа + * :Int32[2,1](100, 200); # Преобразовать аргументы в тензор указанной размерности и заданного типа + * :Int32[1,2](100, 200); # Преобразовать аргументы в тензор указанной размерности и заданного типа * */ TEST(Eval, Convert) { @@ -694,26 +700,26 @@ TEST(Eval, Convert) { RuntimePtr opts = RunTime::Init(); Context ctx(opts); - ObjPtr type_int = ctx.ExecStr(":Int"); + ObjPtr type_int = ctx.ExecStr(":Int32"); ASSERT_TRUE(type_int); ASSERT_EQ(ObjType::Type, type_int->getType()) << toString(type_int->m_var_type_current); - ASSERT_EQ(ObjType::Int, type_int->m_var_type_fixed) << toString(type_int->m_var_type_fixed); + ASSERT_EQ(ObjType::Int32, type_int->m_var_type_fixed) << toString(type_int->m_var_type_fixed); ASSERT_EQ(0, type_int->size()); - ObjPtr type_dim = ctx.ExecStr(":Int[0]"); + ObjPtr type_dim = ctx.ExecStr(":Int32[0]"); ASSERT_TRUE(type_dim); ASSERT_EQ(ObjType::Type, type_dim->getType()) << toString(type_dim->m_var_type_current); - ASSERT_EQ(ObjType::Int, type_dim->m_var_type_fixed) << toString(type_dim->m_var_type_fixed); + ASSERT_EQ(ObjType::Int32, type_dim->m_var_type_fixed) << toString(type_dim->m_var_type_fixed); ASSERT_TRUE(type_dim->m_dimensions); ASSERT_EQ(1, type_dim->m_dimensions->size()); ASSERT_EQ(0, (*type_dim->m_dimensions)[0].second->GetValueAsInteger()); - ObjPtr type_ell = ctx.ExecStr(":Int[10, ...]"); + ObjPtr type_ell = ctx.ExecStr(":Int32[10, ...]"); ASSERT_TRUE(type_ell); ASSERT_EQ(ObjType::Type, type_ell->getType()); - ASSERT_EQ(ObjType::Int, type_ell->m_var_type_fixed); + ASSERT_EQ(ObjType::Int32, type_ell->m_var_type_fixed); ASSERT_TRUE(type_ell->m_dimensions); ASSERT_EQ(2, type_ell->m_dimensions->size()); @@ -742,29 +748,29 @@ TEST(Eval, Convert) { ASSERT_TRUE(obj_2); ASSERT_TRUE(obj_2->is_scalar()); ASSERT_FALSE(obj_2->m_tensor.defined()); - ASSERT_EQ(ObjType::Char, obj_2->getType()); + ASSERT_EQ(ObjType::Int8, obj_2->getType()); ASSERT_EQ(ObjType::None, obj_2->m_var_type_fixed); ASSERT_STREQ("2", obj_2->GetValueAsString().c_str()); - ObjPtr obj_int = ctx.ExecStr(":Int(0)"); + ObjPtr obj_int = ctx.ExecStr(":Int32(0)"); ASSERT_TRUE(obj_int); ASSERT_TRUE(obj_int->is_scalar()); ASSERT_FALSE(obj_int->m_tensor.defined()); - ASSERT_EQ(ObjType::Int, obj_int->getType()) << toString(obj_int->m_var_type_current); - ASSERT_EQ(ObjType::Int, obj_int->m_var_type_fixed) << toString(obj_int->m_var_type_fixed); + ASSERT_EQ(ObjType::Int32, obj_int->getType()) << toString(obj_int->m_var_type_current); + ASSERT_EQ(ObjType::Int32, obj_int->m_var_type_fixed) << toString(obj_int->m_var_type_fixed); ASSERT_TRUE(obj_int->m_var_is_init); ASSERT_STREQ("0", obj_int->GetValueAsString().c_str()); ASSERT_EQ(0, obj_int->GetValueAsInteger()); - ObjPtr scalar = ctx.ExecStr(":Int[0](0)"); + ObjPtr scalar = ctx.ExecStr(":Int32[0](0)"); ASSERT_TRUE(scalar); ASSERT_TRUE(scalar->is_tensor_type()); ASSERT_TRUE(scalar->is_scalar()); ASSERT_FALSE(scalar->m_tensor.defined()); - ASSERT_EQ(ObjType::Int, scalar->getType()) << toString(scalar->m_var_type_current); - ASSERT_EQ(ObjType::Int, scalar->m_var_type_fixed) << toString(scalar->m_var_type_fixed); + ASSERT_EQ(ObjType::Int32, scalar->getType()) << toString(scalar->m_var_type_current); + ASSERT_EQ(ObjType::Int32, scalar->m_var_type_fixed) << toString(scalar->m_var_type_fixed); ASSERT_TRUE(scalar->m_var_is_init); ASSERT_STREQ("0", scalar->GetValueAsString().c_str()); @@ -780,35 +786,35 @@ TEST(Eval, Convert) { ASSERT_STREQ("[0,]:Bool", ten->GetValueAsString().c_str()); - ObjPtr obj_ten = ctx.ExecStr(":Int([0,])"); + ObjPtr obj_ten = ctx.ExecStr(":Int32([0,])"); ASSERT_TRUE(obj_ten); ASSERT_TRUE(obj_ten->is_tensor_type()); ASSERT_FALSE(obj_ten->is_scalar()); ASSERT_EQ(at::ScalarType::Int, obj_ten->m_tensor.scalar_type()); - ASSERT_EQ(ObjType::Int, obj_ten->getType()) << toString(obj_ten->m_var_type_current); - ASSERT_EQ(ObjType::Int, obj_ten->m_var_type_fixed) << toString(obj_ten->m_var_type_fixed); + ASSERT_EQ(ObjType::Int32, obj_ten->getType()) << toString(obj_ten->m_var_type_current); + ASSERT_EQ(ObjType::Int32, obj_ten->m_var_type_fixed) << toString(obj_ten->m_var_type_fixed); ASSERT_TRUE(obj_ten->m_var_is_init); - ASSERT_STREQ("[0,]:Int", obj_ten->GetValueAsString().c_str()); + ASSERT_STREQ("[0,]:Int32", obj_ten->GetValueAsString().c_str()); - ObjPtr obj_auto = ctx.ExecStr(":Int(0, 1, 2, 3)"); + ObjPtr obj_auto = ctx.ExecStr(":Int32(0, 1, 2, 3)"); ASSERT_TRUE(obj_auto); ASSERT_EQ(at::ScalarType::Int, obj_auto->m_tensor.scalar_type()); - ASSERT_EQ(ObjType::Int, obj_auto->getType()) << toString(obj_auto->m_var_type_current); - ASSERT_EQ(ObjType::Int, obj_auto->m_var_type_fixed) << toString(obj_auto->m_var_type_fixed); + ASSERT_EQ(ObjType::Int32, obj_auto->getType()) << toString(obj_auto->m_var_type_current); + ASSERT_EQ(ObjType::Int32, obj_auto->m_var_type_fixed) << toString(obj_auto->m_var_type_fixed); ASSERT_TRUE(obj_auto->m_var_is_init); - ASSERT_STREQ("[0, 1, 2, 3,]:Int", obj_auto->GetValueAsString().c_str()); + ASSERT_STREQ("[0, 1, 2, 3,]:Int32", obj_auto->GetValueAsString().c_str()); - ObjPtr obj_float = ctx.ExecStr(":Float[2,2](3, 4, 1, 2)"); + ObjPtr obj_float = ctx.ExecStr(":Float32[2,2](3, 4, 1, 2)"); ASSERT_TRUE(obj_float); - ASSERT_EQ(ObjType::Float, obj_float->getType()) << toString(obj_float->m_var_type_current); - ASSERT_EQ(ObjType::Float, obj_float->m_var_type_fixed) << toString(obj_float->m_var_type_fixed); + ASSERT_EQ(ObjType::Float32, obj_float->getType()) << toString(obj_float->m_var_type_current); + ASSERT_EQ(ObjType::Float32, obj_float->m_var_type_fixed) << toString(obj_float->m_var_type_fixed); ASSERT_TRUE(obj_float->m_var_is_init); - ASSERT_STREQ("[\n [3, 4,], [1, 2,],\n]:Float", obj_float->GetValueAsString().c_str()); + ASSERT_STREQ("[\n [3, 4,], [1, 2,],\n]:Float32", obj_float->GetValueAsString().c_str()); @@ -816,27 +822,27 @@ TEST(Eval, Convert) { ObjPtr frac_0 = ctx.ExecStr("0\\1"); ASSERT_TRUE(frac_0); - ASSERT_EQ(ObjType::Fraction, frac_0->getType()); + ASSERT_EQ(ObjType::Rational, frac_0->getType()); ASSERT_EQ(ObjType::None, frac_0->m_var_type_fixed); ASSERT_STREQ("0\\1", frac_0->GetValueAsString().c_str()); ObjPtr frac_1 = ctx.ExecStr("1\\1"); ASSERT_TRUE(frac_1); - ASSERT_EQ(ObjType::Fraction, frac_1->getType()); + ASSERT_EQ(ObjType::Rational, frac_1->getType()); ASSERT_EQ(ObjType::None, frac_1->m_var_type_fixed); ASSERT_STREQ("1\\1", frac_1->GetValueAsString().c_str()); ObjPtr frac_2 = ctx.ExecStr("222_222_222_222222_222_222_222\\1_1_1_1"); ASSERT_TRUE(frac_2); - ASSERT_EQ(ObjType::Fraction, frac_2->getType()); + ASSERT_EQ(ObjType::Rational, frac_2->getType()); ASSERT_EQ(ObjType::None, frac_2->m_var_type_fixed); ASSERT_STREQ("222222222222222222222222\\1111", frac_2->GetValueAsString().c_str()); - ObjPtr obj_frac = ctx.ExecStr(":Fraction(0)"); + ObjPtr obj_frac = ctx.ExecStr(":Rational(0)"); ASSERT_TRUE(obj_frac); ASSERT_FALSE(obj_frac->is_tensor_type()); ASSERT_FALSE(obj_frac->is_scalar()); - ASSERT_EQ(ObjType::Fraction, obj_frac->getType()) << toString(obj_frac->m_var_type_current); + ASSERT_EQ(ObjType::Rational, obj_frac->getType()) << toString(obj_frac->m_var_type_current); ASSERT_TRUE(obj_frac->m_var_is_init); ASSERT_STREQ("0\\1", obj_frac->GetValueAsString().c_str()); @@ -1295,7 +1301,7 @@ TEST(Eval, Iterator) { // * @Tim := :Human(Sex.male, parent=(Tom,)); // * // * Brother(h1, h2) := $h1 != $h2, $h1.sex==male, $h1.parent * $h2.parent; -// * printf := :Native("printf(format:FmtChar, ...):Int"); +// * printf := :Native("printf(format:FmtChar, ...):Int32"); // * // * h1 := $?; // * [ h1 ] <<-->> { @@ -1551,10 +1557,10 @@ TEST(EvalOp, InstanceName) { */ ObjPtr obj_bool = Obj::CreateBool(true); - ObjPtr obj_char = Obj::CreateValue(20); // ObjType::Char - ObjPtr obj_short = Obj::CreateValue(300); // ObjType::Short - ObjPtr obj_int = Obj::CreateValue(100000); // ObjType::Int - ObjPtr obj_long = Obj::CreateValue(999999999999); // ObjType::Long + ObjPtr obj_char = Obj::CreateValue(20); // ObjType::Int8 + ObjPtr obj_short = Obj::CreateValue(300); // ObjType::Int16 + ObjPtr obj_int = Obj::CreateValue(100000); // ObjType::Int32 + ObjPtr obj_long = Obj::CreateValue(999999999999); // ObjType::Int64 ObjPtr str_char = Obj::CreateString("Байтовая строка"); ObjPtr str_wide = Obj::CreateString(L"Широкая строка"); @@ -1566,40 +1572,40 @@ TEST(EvalOp, InstanceName) { obj_class2->m_class_parents.push_back(obj_class1); ASSERT_TRUE(obj_bool->op_class_test(":Bool", &ctx)); - ASSERT_TRUE(obj_char->op_class_test(":Char", &ctx)); - ASSERT_TRUE(obj_char->op_class_test(":Short", &ctx)); - ASSERT_TRUE(obj_bool->op_class_test(":Int", &ctx)); - ASSERT_TRUE(obj_bool->op_class_test(":Long", &ctx)); + ASSERT_TRUE(obj_char->op_class_test(":Int8", &ctx)); + ASSERT_TRUE(obj_char->op_class_test(":Int16", &ctx)); + ASSERT_TRUE(obj_bool->op_class_test(":Int32", &ctx)); + ASSERT_TRUE(obj_bool->op_class_test(":Int64", &ctx)); ASSERT_TRUE(obj_bool->op_class_test(":Tensor", &ctx)); ASSERT_TRUE(obj_bool->op_class_test(":Arithmetic", &ctx)); ASSERT_TRUE(obj_bool->op_class_test(":Any", &ctx)); ASSERT_FALSE(obj_bool->op_class_test(":None", &ctx)); ASSERT_FALSE(obj_char->op_class_test(":Bool", &ctx)); - ASSERT_TRUE(obj_char->op_class_test(":Char", &ctx)); - ASSERT_TRUE(obj_char->op_class_test(":Short", &ctx)); - ASSERT_TRUE(obj_char->op_class_test(":Int", &ctx)); - ASSERT_TRUE(obj_char->op_class_test(":Long", &ctx)); + ASSERT_TRUE(obj_char->op_class_test(":Int8", &ctx)); + ASSERT_TRUE(obj_char->op_class_test(":Int16", &ctx)); + ASSERT_TRUE(obj_char->op_class_test(":Int32", &ctx)); + ASSERT_TRUE(obj_char->op_class_test(":Int64", &ctx)); ASSERT_TRUE(obj_char->op_class_test(":Tensor", &ctx)); ASSERT_TRUE(obj_char->op_class_test(":Arithmetic", &ctx)); ASSERT_TRUE(obj_char->op_class_test(":Any", &ctx)); ASSERT_FALSE(obj_char->op_class_test(":None", &ctx)); ASSERT_FALSE(obj_short->op_class_test(":Bool", &ctx)); - ASSERT_FALSE(obj_short->op_class_test(":Char", &ctx)); - ASSERT_TRUE(obj_short->op_class_test(":Short", &ctx)); - ASSERT_TRUE(obj_short->op_class_test(":Int", &ctx)); - ASSERT_TRUE(obj_short->op_class_test(":Long", &ctx)); + ASSERT_FALSE(obj_short->op_class_test(":Int8", &ctx)); + ASSERT_TRUE(obj_short->op_class_test(":Int16", &ctx)); + ASSERT_TRUE(obj_short->op_class_test(":Int32", &ctx)); + ASSERT_TRUE(obj_short->op_class_test(":Int64", &ctx)); ASSERT_TRUE(obj_short->op_class_test(":Tensor", &ctx)); ASSERT_TRUE(obj_short->op_class_test(":Arithmetic", &ctx)); ASSERT_TRUE(obj_short->op_class_test(":Any", &ctx)); ASSERT_FALSE(obj_short->op_class_test(":None", &ctx)); ASSERT_FALSE(obj_int->op_class_test(":Bool", &ctx)); - ASSERT_FALSE(obj_int->op_class_test(":Char", &ctx)); - ASSERT_FALSE(obj_int->op_class_test(":Short", &ctx)); - ASSERT_TRUE(obj_int->op_class_test(":Int", &ctx)); - ASSERT_TRUE(obj_int->op_class_test(":Long", &ctx)); + ASSERT_FALSE(obj_int->op_class_test(":Int8", &ctx)); + ASSERT_FALSE(obj_int->op_class_test(":Int16", &ctx)); + ASSERT_TRUE(obj_int->op_class_test(":Int32", &ctx)); + ASSERT_TRUE(obj_int->op_class_test(":Int64", &ctx)); ASSERT_TRUE(obj_int->op_class_test(":Tensor", &ctx)); ASSERT_TRUE(obj_int->op_class_test(":Arithmetic", &ctx)); ASSERT_TRUE(obj_int->op_class_test(":Any", &ctx)); @@ -1607,11 +1613,11 @@ TEST(EvalOp, InstanceName) { ASSERT_FALSE(obj_long->op_class_test(":Bool", &ctx)); - ASSERT_FALSE(obj_long->op_class_test(":Char", &ctx)); - ASSERT_FALSE(obj_long->op_class_test(":Short", &ctx)); - ASSERT_EQ(obj_long->m_var_type_current, ObjType::Long); - ASSERT_FALSE(obj_long->op_class_test(":Int", &ctx)); - ASSERT_TRUE(obj_long->op_class_test(":Long", &ctx)); + ASSERT_FALSE(obj_long->op_class_test(":Int8", &ctx)); + ASSERT_FALSE(obj_long->op_class_test(":Int16", &ctx)); + ASSERT_EQ(obj_long->m_var_type_current, ObjType::Int64); + ASSERT_FALSE(obj_long->op_class_test(":Int32", &ctx)); + ASSERT_TRUE(obj_long->op_class_test(":Int64", &ctx)); ASSERT_TRUE(obj_long->op_class_test(":Tensor", &ctx)); ASSERT_TRUE(obj_long->op_class_test(":Arithmetic", &ctx)); ASSERT_TRUE(obj_long->op_class_test(":Any", &ctx)); @@ -1655,13 +1661,13 @@ TEST(EvalOp, InstanceName) { - // [,]:Bool ~ :Int + // [,]:Bool ~ :Int32 ObjPtr obj_empty_bool = ctx.ExecStr("[,]:Bool"); ASSERT_TRUE(obj_empty_bool->op_class_test(":Bool", &ctx)); - ASSERT_TRUE(obj_empty_bool->op_class_test(":Char", &ctx)); - ASSERT_TRUE(obj_empty_bool->op_class_test(":Short", &ctx)); - ASSERT_TRUE(obj_empty_bool->op_class_test(":Int", &ctx)); - ASSERT_TRUE(obj_empty_bool->op_class_test(":Long", &ctx)); + ASSERT_TRUE(obj_empty_bool->op_class_test(":Int8", &ctx)); + ASSERT_TRUE(obj_empty_bool->op_class_test(":Int16", &ctx)); + ASSERT_TRUE(obj_empty_bool->op_class_test(":Int32", &ctx)); + ASSERT_TRUE(obj_empty_bool->op_class_test(":Int64", &ctx)); ASSERT_TRUE(obj_empty_bool->op_class_test(":Tensor", &ctx)); ASSERT_TRUE(obj_empty_bool->op_class_test(":Arithmetic", &ctx)); ASSERT_TRUE(obj_empty_bool->op_class_test(":Any", &ctx)); @@ -1671,13 +1677,13 @@ TEST(EvalOp, InstanceName) { ASSERT_FALSE(obj_empty_bool->op_class_test(":None", &ctx)); - // [,]:Int ~ :Bool - ObjPtr obj_empty_int = ctx.ExecStr("[,]:Int"); + // [,]:Int32 ~ :Bool + ObjPtr obj_empty_int = ctx.ExecStr("[,]:Int32"); ASSERT_FALSE(obj_empty_int->op_class_test(":Bool", &ctx)); - ASSERT_FALSE(obj_empty_int->op_class_test(":Char", &ctx)); - ASSERT_FALSE(obj_empty_int->op_class_test(":Short", &ctx)); - ASSERT_TRUE(obj_empty_int->op_class_test(":Int", &ctx)); - ASSERT_TRUE(obj_empty_int->op_class_test(":Long", &ctx)); + ASSERT_FALSE(obj_empty_int->op_class_test(":Int8", &ctx)); + ASSERT_FALSE(obj_empty_int->op_class_test(":Int16", &ctx)); + ASSERT_TRUE(obj_empty_int->op_class_test(":Int32", &ctx)); + ASSERT_TRUE(obj_empty_int->op_class_test(":Int64", &ctx)); ASSERT_TRUE(obj_empty_int->op_class_test(":Tensor", &ctx)); ASSERT_TRUE(obj_empty_int->op_class_test(":Arithmetic", &ctx)); ASSERT_TRUE(obj_empty_int->op_class_test(":Any", &ctx)); @@ -1690,7 +1696,7 @@ TEST(EvalOp, InstanceName) { // (,):Class ~ :Class ObjPtr obj_class = ctx.ExecStr("(,):Class"); ASSERT_FALSE(obj_class->op_class_test(":Bool", &ctx)); - ASSERT_FALSE(obj_class->op_class_test(":Char", &ctx)); + ASSERT_FALSE(obj_class->op_class_test(":Int8", &ctx)); ASSERT_FALSE(obj_class->op_class_test(":Tensor", &ctx)); ASSERT_FALSE(obj_class->op_class_test(":Arithmetic", &ctx)); ASSERT_TRUE(obj_class->op_class_test(":Any", &ctx)); @@ -1705,7 +1711,7 @@ TEST(EvalOp, InstanceName) { ObjPtr obj_class3 = ctx.ExecStr("(,):Class2"); obj_class3->m_class_parents.push_back(obj_class); ASSERT_FALSE(obj_class3->op_class_test(":Bool", &ctx)); - ASSERT_FALSE(obj_class3->op_class_test(":Char", &ctx)); + ASSERT_FALSE(obj_class3->op_class_test(":Int8", &ctx)); ASSERT_FALSE(obj_class3->op_class_test(":Tensor", &ctx)); ASSERT_FALSE(obj_class3->op_class_test(":Arithmetic", &ctx)); ASSERT_TRUE(obj_class3->op_class_test(":Any", &ctx)); @@ -1720,7 +1726,7 @@ TEST(EvalOp, InstanceName) { - ObjPtr res = ctx.ExecStr(":Int ~ :Int"); + ObjPtr res = ctx.ExecStr(":Int32 ~ :Int32"); ASSERT_TRUE(res); ASSERT_TRUE(res->is_bool_type()); ASSERT_TRUE(res->GetValueAsBoolean()); @@ -1733,16 +1739,16 @@ TEST(EvalOp, InstanceName) { ASSERT_NO_THROW(ctx.ExecStr("1.0 ~ :FAIL_TYPE")); std::map test_name = { - {"0 ~ :Int", true}, - {"1 ~ :Int", true}, + {"0 ~ :Int32", true}, + {"1 ~ :Int32", true}, {"1 ~ :Bool", true}, {"1 ~ :Integer", true}, - {"1 ~ :Number", true}, - {"1 ~ :Double", true}, + {"1 ~ :Float", true}, + {"1 ~ :Float64", true}, {"10 ~ :Bool", false}, {"10 !~ :Bool", true}, - {"1 ~ :Float", true}, - {"1.0 ~ :Double", true}, + {"1 ~ :Float32", true}, + {"1.0 ~ :Float64", true}, {"1.0 ~ :Integer", false}, {"1.0 ~ :FAIL_TYPE", false}, @@ -1750,14 +1756,14 @@ TEST(EvalOp, InstanceName) { {"\"\" ~ :StrWide", true}, {"'' ~ :String", true}, {"\"\" ~ :String", true}, - {"\"\" ~ :Int", false}, + {"\"\" ~ :Int32", false}, {"\"\" ~ :None", false}, - {":Int ~ :Int", true}, - {":Int ~ :Bool", false}, + {":Int32 ~ :Int32", true}, + {":Int32 ~ :Bool", false}, - {"[,]:Int ~ :Bool", false}, - {"[,]:Bool ~ :Int", true}, + {"[,]:Int32 ~ :Bool", false}, + {"[,]:Bool ~ :Int32", true}, {"(,):Class ~ :Class", true}, {"(,):ClassNameNotFound ~ :Class", false}, diff --git a/src/test/example_test.cpp b/src/test/example_test.cpp index 182c83aa..5af8e5fc 100644 --- a/src/test/example_test.cpp +++ b/src/test/example_test.cpp @@ -70,7 +70,7 @@ TEST(Example, SpeedCPP) { std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now(); int sec = std::chrono::duration_cast(end - begin).count(); int ms = std::chrono::duration_cast(end - begin).count() % 1000000; - LOG_INFO("Number of generated k-mers: %d at %d.%d sec", counter, sec, ms); + LOG_INFO("Float of generated k-mers: %d at %d.%d sec", counter, sec, ms); } @@ -90,7 +90,7 @@ TEST(Example, SpeedNewLang) { ASSERT_TRUE(str); ASSERT_STREQ("ABCDEF\n", str->GetValueAsString().c_str()); - test = ctx.ExecStr("@printf := :Pointer('printf(format:FmtChar, ...):Int'); @str := 'ABCDEF\\n'; printf('%s', str)", nullptr, true); + test = ctx.ExecStr("@printf := :Pointer('printf(format:FmtChar, ...):Int32'); @str := 'ABCDEF\\n'; printf('%s', str)", nullptr, true); ASSERT_TRUE(test); ASSERT_STREQ("7", test->GetValueAsString().c_str()); @@ -100,7 +100,7 @@ TEST(Example, SpeedNewLang) { LLVMAddSymbol("convert", (void *) &convert); - ObjPtr test_convert = ctx.ExecStr("@test_convert := :Pointer('convert(sym:Char):Char')", nullptr, true); + ObjPtr test_convert = ctx.ExecStr("@test_convert := :Pointer('convert(sym:Int8):Int8')", nullptr, true); ASSERT_TRUE(test_convert); test = ctx.ExecStr("test_convert('A')", nullptr, true); @@ -131,14 +131,14 @@ TEST(Example, SpeedNewLang) { /* * * Start speed test C++ - * Number of generated k-mers: 67108864 at 2.502049 sec + * Float of generated k-mers: 67108864 at 2.502049 sec * * Start - * Number of generated k-mers: 67108864 + * Float of generated k-mers: 67108864 * real 0m33,794s * * Start speed test NewLang - * Number of generated k-mers: 67108864 + * Float of generated k-mers: 67108864 * Test complete at ???????????????????? * * Своя функция @convert @@ -168,7 +168,7 @@ TEST(Example, SpeedNewLang) { * * Start speed test NewLang * From AAAAAAAAAA to TTTTTTTTTT - * Number of generated k-mers: 1048576 + * Float of generated k-mers: 1048576 * Test complete at 320.401650 sec (более 5 минут) * * Никакой оптимизации не проводилось. @@ -178,7 +178,7 @@ TEST(Example, SpeedNewLang) { */ } -TEST(Example, Fraction) { +TEST(Example, Rational) { Context::Reset(); Context ctx(RunTime::Init()); @@ -199,7 +199,7 @@ TEST(Example, Fraction) { ASSERT_TRUE(str); ASSERT_STREQ("ABCDEF\n", str->GetValueAsString().c_str()); - ObjPtr test_printf = ctx.ExecStr("@test_printf := :Pointer('printf(format:FmtChar, ...):Int')", nullptr, true); + ObjPtr test_printf = ctx.ExecStr("@test_printf := :Pointer('printf(format:FmtChar, ...):Int32')", nullptr, true); ASSERT_TRUE(test_printf); ASSERT_STREQ("test_printf={}", test_printf->GetValueAsString().c_str()); @@ -212,7 +212,7 @@ TEST(Example, Fraction) { ObjPtr test_frac = ctx.ExecStr("@test_frac := 999\\123", nullptr, true); ASSERT_TRUE(test_frac); - ASSERT_TRUE(test_frac->getType() == ObjType::Fraction); + ASSERT_TRUE(test_frac->getType() == ObjType::Rational); ASSERT_STREQ("999\\123", test_frac->GetValueAsString().c_str()); ObjPtr str_frac = ctx.ExecStr(":StrChar(test_frac)", nullptr, true); @@ -224,7 +224,7 @@ TEST(Example, Fraction) { ASSERT_TRUE(test_prn); ASSERT_STREQ("7", test_prn->GetValueAsString().c_str()); - ObjPtr test_arg = ctx.ExecStr("@test_arg(arg:Fraction) := {$arg}", nullptr, true); + ObjPtr test_arg = ctx.ExecStr("@test_arg(arg:Rational) := {$arg}", nullptr, true); ASSERT_TRUE(test_arg); ASSERT_TRUE(test_arg->is_function_type()); ASSERT_FALSE(test_arg->is_none_type()); @@ -238,7 +238,7 @@ TEST(Example, Fraction) { frac_test = test_arg->Call(&ctx, Obj::Arg(1)); ASSERT_TRUE(frac_test); - ASSERT_EQ(ObjType::Fraction, frac_test->getType()) << newlang::toString(frac_test->getType()); + ASSERT_EQ(ObjType::Rational, frac_test->getType()) << newlang::toString(frac_test->getType()); frac_test = ctx.ExecStr("test_arg(1)", nullptr, true); ASSERT_TRUE(frac_test); @@ -248,7 +248,7 @@ TEST(Example, Fraction) { utils::Logger::LogLevelType save = utils::Logger::Instance()->SetLogLevel(LOG_LEVEL_INFO); std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now(); - ObjPtr result = ctx.ExecFile("../examples/fraction.nlp"); + ObjPtr result = ctx.ExecFile("../examples/rational.nlp"); std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now(); utils::Logger::Instance()->SetLogLevel(save); @@ -261,11 +261,35 @@ TEST(Example, Fraction) { int sec = std::chrono::duration_cast(end - begin).count(); int ms = std::chrono::duration_cast(end - begin).count() % 1000000; - LOG_INFO("Test fraction complete at %d.%d sec", sec, ms); + LOG_INFO("Test rational complete at %d.%d sec", sec, ms); /* * */ } + + +TEST(Example, Tensor) { + + Context::Reset(); + Context ctx(RunTime::Init()); + + setvbuf(stdin, nullptr, _IONBF, 0); + setvbuf(stdout, nullptr, _IONBF, 0); + setvbuf(stderr, nullptr, _IONBF, 0); + + + utils::Logger::LogLevelType save = utils::Logger::Instance()->SetLogLevel(LOG_LEVEL_INFO); + std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now(); + ObjPtr result = ctx.ExecFile("../examples/tensor.nlp"); + std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now(); + utils::Logger::Instance()->SetLogLevel(save); + + + ASSERT_TRUE(result); + ASSERT_TRUE(result->is_string_type()) << result->toString(); + ASSERT_STREQ("OK", result->GetValueAsString().c_str()); +} + #endif // UNITTEST \ No newline at end of file diff --git a/src/test/lexer_test.cpp b/src/test/lexer_test.cpp index c0df6092..2d2bea54 100644 --- a/src/test/lexer_test.cpp +++ b/src/test/lexer_test.cpp @@ -168,7 +168,7 @@ TEST_F(Lexer, Integer) { EXPECT_STREQ("123", tokens[2]->getText().c_str()) << tokens[2]->getText(); } -TEST_F(Lexer, Number) { +TEST_F(Lexer, Float) { ASSERT_EQ(1, Parse("1.e10")); EXPECT_EQ(1, Count(TermID::NUMBER)); EXPECT_STREQ("1.e10", tokens[0]->getText().c_str()); diff --git a/src/test/nlc_test.cpp b/src/test/nlc_test.cpp index 1df65e24..c1e3b924 100644 --- a/src/test/nlc_test.cpp +++ b/src/test/nlc_test.cpp @@ -129,7 +129,7 @@ TEST(NLC, EvalHelloWorld) { std::string cmd; cmd += "#!./dist/Debug/GNU-Linux/nlc --eval\n"; - cmd += "hello(str='') := { printf := :Pointer('printf(format:FmtChar, ...):Int'); printf('%s', $str); $str;};\n"; + cmd += "hello(str='') := { printf := :Pointer('printf(format:FmtChar, ...):Int32'); printf('%s', $str); $str;};\n"; cmd += "hello('Привет, мир!\\n');"; std::filesystem::create_directories("temp"); diff --git a/src/test/object_test.cpp b/src/test/object_test.cpp index 0b0f0b43..0f15916e 100644 --- a/src/test/object_test.cpp +++ b/src/test/object_test.cpp @@ -2,7 +2,7 @@ #ifdef UNITTEST -#include "fraction.h" +#include "rational.h" #include #include @@ -33,28 +33,28 @@ TEST(ObjTest, Value) { ASSERT_EQ(ObjType::Bool, var.getType()); var.SetValue_(1.0); - ASSERT_EQ(ObjType::Double, var.getType()); + ASSERT_EQ(ObjType::Float64, var.getType()); var.SetValue_(true); ASSERT_EQ(ObjType::Bool, var.getType()); var.SetValue_(2); - ASSERT_EQ(ObjType::Char, var.getType()); + ASSERT_EQ(ObjType::Int8, var.getType()); var.SetValue_(-100); - ASSERT_EQ(ObjType::Char, var.getType()); + ASSERT_EQ(ObjType::Int8, var.getType()); var.SetValue_(1000); - ASSERT_EQ(ObjType::Short, var.getType()); + ASSERT_EQ(ObjType::Int16, var.getType()); var.SetValue_(100000); - ASSERT_EQ(ObjType::Int, var.getType()); + ASSERT_EQ(ObjType::Int32, var.getType()); var.SetValue_(10000000000); - ASSERT_EQ(ObjType::Long, var.getType()); + ASSERT_EQ(ObjType::Int64, var.getType()); var.SetValue_(2.0); - ASSERT_EQ(ObjType::Double, var.getType()); + ASSERT_EQ(ObjType::Float64, var.getType()); var.SetValue_(false); ASSERT_EQ(ObjType::Bool, var.getType()); @@ -250,8 +250,8 @@ TEST(ObjTest, Eq) { ObjPtr var_bool = Obj::CreateBool(true); ObjPtr var_empty = Obj::CreateNone(); - ASSERT_EQ(var_int->m_var_type_current, ObjType::Char) << (int) var_int->getType(); - ASSERT_EQ(var_num->m_var_type_current, ObjType::Double) << (int) var_num->getType(); + ASSERT_EQ(var_int->m_var_type_current, ObjType::Int8) << (int) var_int->getType(); + ASSERT_EQ(var_num->m_var_type_current, ObjType::Float64) << (int) var_num->getType(); ASSERT_EQ(var_str->m_var_type_current, ObjType::StrWide) << (int) var_str->getType(); ASSERT_EQ(var_bool->m_var_type_current, ObjType::Bool) << (int) var_bool->getType(); ASSERT_EQ(var_empty->m_var_type_current, ObjType::None) << (int) var_empty->getType(); @@ -306,6 +306,48 @@ TEST(ObjTest, Eq) { ASSERT_TRUE(var_empty->op_accurate(var_empty2)); } + +TEST(ObjTest, Ops) { + + ObjPtr var_zero = Obj::CreateValue(0, ObjType::None); + ASSERT_TRUE(var_zero->is_bool_type()); + ASSERT_TRUE(var_zero->is_arithmetic_type()); + ASSERT_EQ(ObjType::Bool, var_zero->m_var_type_current); + + ObjPtr var_bool = Obj::CreateBool(true); + ASSERT_TRUE(var_bool->is_bool_type()); + ASSERT_TRUE(var_bool->is_arithmetic_type()); + ASSERT_EQ(ObjType::Bool, var_bool->m_var_type_current); + + ObjPtr var_char = Obj::CreateValue(100); + ASSERT_TRUE(var_char->is_arithmetic_type()); + ASSERT_EQ(ObjType::Int8, var_char->m_var_type_current); + + ObjPtr var_int = Obj::CreateValue(100000); + ASSERT_TRUE(var_int->is_arithmetic_type()); + ASSERT_EQ(ObjType::Int32, var_int->m_var_type_current) << newlang::toString(var_char->m_var_type_current); + + ObjPtr var_float = Obj::CreateValue(1.0); + ASSERT_TRUE(var_float->is_arithmetic_type()); + ASSERT_EQ(ObjType::Float64, var_float->m_var_type_current) << newlang::toString(var_char->m_var_type_current); + + ObjPtr var_tensor = Obj::CreateRange(0, 10)->toType(ObjType::Int32); + ASSERT_TRUE(var_tensor->is_arithmetic_type()); + ASSERT_EQ(ObjType::Int32, var_tensor->m_var_type_current) << newlang::toString(var_char->m_var_type_current); + + var_tensor->operator *=(var_bool); + ASSERT_TRUE(var_tensor->is_arithmetic_type()); + EXPECT_EQ(ObjType::Int32, var_tensor->m_var_type_current) << newlang::toString(var_char->m_var_type_current); + + var_tensor->operator *=(var_int); + ASSERT_TRUE(var_tensor->is_arithmetic_type()); + EXPECT_EQ(ObjType::Int32, var_tensor->m_var_type_current) << newlang::toString(var_char->m_var_type_current); + + var_tensor->operator *=(var_float); + ASSERT_TRUE(var_tensor->is_arithmetic_type()); + EXPECT_EQ(ObjType::Float64, var_tensor->m_var_type_current) << newlang::toString(var_char->m_var_type_current); +} + TEST(ObjTest, Exist) { Obj var_array(ObjType::Dictionary); @@ -445,22 +487,22 @@ TEST(ObjTest, CreateFromInteger) { ObjPtr var = Context::CreateRVal(&ctx, Parser::ParseString("123")); ASSERT_TRUE(var); - ASSERT_EQ(ObjType::Char, var->getType()) << toString(var->getType()); + ASSERT_EQ(ObjType::Int8, var->getType()) << toString(var->getType()); ASSERT_EQ(123, var->GetValueAsInteger()); ObjPtr var2 = ctx.ExecStr("123"); ASSERT_TRUE(var2); - ASSERT_EQ(ObjType::Char, var2->getType()) << toString(var2->getType()); + ASSERT_EQ(ObjType::Int8, var2->getType()) << toString(var2->getType()); ASSERT_EQ(123, var2->GetValueAsInteger()); var = Context::CreateRVal(&ctx, Parser::ParseString("-123")); ASSERT_TRUE(var); - ASSERT_EQ(ObjType::Char, var->getType()) << toString(var->getType()); + ASSERT_EQ(ObjType::Int8, var->getType()) << toString(var->getType()); ASSERT_EQ(-123, var->GetValueAsInteger()); var2 = ctx.ExecStr("-123"); ASSERT_TRUE(var2); - ASSERT_EQ(ObjType::Char, var2->getType()) << toString(var2->getType()); + ASSERT_EQ(ObjType::Int8, var2->getType()) << toString(var2->getType()); ASSERT_EQ(-123, var2->GetValueAsInteger()); ASSERT_ANY_THROW(Context::CreateRVal(&ctx, Term::Create(TermID::INTEGER, ""))); @@ -474,22 +516,22 @@ TEST(ObjTest, CreateFromNumber) { ObjPtr var = Context::CreateRVal(&ctx, Parser::ParseString("123.123")); ASSERT_TRUE(var); - ASSERT_EQ(ObjType::Double, var->getType()); + ASSERT_EQ(ObjType::Float64, var->getType()); ASSERT_DOUBLE_EQ(123.123, var->GetValueAsNumber()); ObjPtr var2 = ctx.ExecStr("123.123"); ASSERT_TRUE(var2); - ASSERT_EQ(ObjType::Double, var2->getType()); + ASSERT_EQ(ObjType::Float64, var2->getType()); ASSERT_DOUBLE_EQ(123.123, var2->GetValueAsNumber()); var = Context::CreateRVal(&ctx, Parser::ParseString("-123.123")); ASSERT_TRUE(var); - ASSERT_EQ(ObjType::Double, var->getType()); + ASSERT_EQ(ObjType::Float64, var->getType()); ASSERT_DOUBLE_EQ(-123.123, var->GetValueAsNumber()); var2 = ctx.ExecStr("-123.123"); ASSERT_TRUE(var2); - ASSERT_EQ(ObjType::Double, var2->getType()); + ASSERT_EQ(ObjType::Float64, var2->getType()); ASSERT_DOUBLE_EQ(-123.123, var2->GetValueAsNumber()); ASSERT_ANY_THROW(Context::CreateRVal(&ctx, Term::Create(TermID::NUMBER, ""))); @@ -522,42 +564,42 @@ TEST(ObjTest, CreateFromString) { ASSERT_STREQ("строка", var2->GetValueAsString().c_str()); } -TEST(ObjTest, CreateFromFraction) { +TEST(ObjTest, CreateFromRational) { Context ctx(RunTime::Init()); ObjPtr var = Context::CreateRVal(&ctx, Parser::ParseString("123\\1")); ASSERT_TRUE(var); - ASSERT_EQ(ObjType::Fraction, var->getType()) << toString(var->getType()); + ASSERT_EQ(ObjType::Rational, var->getType()) << toString(var->getType()); ASSERT_EQ(123, var->GetValueAsInteger()); ASSERT_DOUBLE_EQ(123.0, var->GetValueAsNumber()); ObjPtr var2 = ctx.ExecStr("123\\1"); ASSERT_TRUE(var2); - ASSERT_EQ(ObjType::Fraction, var2->getType()) << toString(var2->getType()); + ASSERT_EQ(ObjType::Rational, var2->getType()) << toString(var2->getType()); ASSERT_EQ(123, var2->GetValueAsInteger()); ASSERT_DOUBLE_EQ(123, var2->GetValueAsNumber()); var = Context::CreateRVal(&ctx, Parser::ParseString("-123\\1")); ASSERT_TRUE(var); - ASSERT_EQ(ObjType::Fraction, var->getType()) << toString(var->getType()); + ASSERT_EQ(ObjType::Rational, var->getType()) << toString(var->getType()); ASSERT_EQ(-123, var->GetValueAsInteger()); ASSERT_DOUBLE_EQ(-123.0, var->GetValueAsNumber()); var2 = ctx.ExecStr("-123\\1"); ASSERT_TRUE(var2); - ASSERT_EQ(ObjType::Fraction, var2->getType()) << toString(var2->getType()); + ASSERT_EQ(ObjType::Rational, var2->getType()) << toString(var2->getType()); ASSERT_EQ(-123, var2->GetValueAsInteger()); ASSERT_DOUBLE_EQ(-123, var2->GetValueAsNumber()); - ASSERT_ANY_THROW(Context::CreateRVal(&ctx, Term::Create(TermID::FRACTION, "1\\0"))); - ASSERT_ANY_THROW(Context::CreateRVal(&ctx, Term::Create(TermID::FRACTION, "1\\"))); - ASSERT_ANY_THROW(Context::CreateRVal(&ctx, Term::Create(TermID::FRACTION, ""))); - ASSERT_ANY_THROW(Context::CreateRVal(&ctx, Term::Create(TermID::FRACTION, "asdsdff"))); - ASSERT_ANY_THROW(Context::CreateRVal(&ctx, Term::Create(TermID::FRACTION, "asdsdff\\dddddd"))); - ASSERT_ANY_THROW(Context::CreateRVal(&ctx, Term::Create(TermID::FRACTION, "123asdsdff\\dddddd"))); - ASSERT_ANY_THROW(Context::CreateRVal(&ctx, Term::Create(TermID::FRACTION, "123\\111dddddd"))); - ASSERT_ANY_THROW(Context::CreateRVal(&ctx, Term::Create(TermID::FRACTION, "123wwwww\\111"))); + ASSERT_ANY_THROW(Context::CreateRVal(&ctx, Term::Create(TermID::RATIONAL, "1\\0"))); + ASSERT_ANY_THROW(Context::CreateRVal(&ctx, Term::Create(TermID::RATIONAL, "1\\"))); + ASSERT_ANY_THROW(Context::CreateRVal(&ctx, Term::Create(TermID::RATIONAL, ""))); + ASSERT_ANY_THROW(Context::CreateRVal(&ctx, Term::Create(TermID::RATIONAL, "asdsdff"))); + ASSERT_ANY_THROW(Context::CreateRVal(&ctx, Term::Create(TermID::RATIONAL, "asdsdff\\dddddd"))); + ASSERT_ANY_THROW(Context::CreateRVal(&ctx, Term::Create(TermID::RATIONAL, "123asdsdff\\dddddd"))); + ASSERT_ANY_THROW(Context::CreateRVal(&ctx, Term::Create(TermID::RATIONAL, "123\\111dddddd"))); + ASSERT_ANY_THROW(Context::CreateRVal(&ctx, Term::Create(TermID::RATIONAL, "123wwwww\\111"))); } TEST(Args, All) { @@ -573,13 +615,13 @@ TEST(Args, All) { ObjPtr arg_999 = Obj::CreateDict(Obj::Arg(Obj::CreateValue(999, ObjType::None))); - EXPECT_EQ(ObjType::Short, (*arg_999)[0].second->getType()) << torch::toString(toTorchType((*arg_999)[0].second->getType())); + EXPECT_EQ(ObjType::Int16, (*arg_999)[0].second->getType()) << torch::toString(toTorchType((*arg_999)[0].second->getType())); ObjPtr arg_empty_named = Obj::CreateDict(Obj::Arg()); ASSERT_EQ(ObjType::None, (*arg_empty_named)[0].second->getType()); ObjPtr arg_123_named = Obj::CreateDict(Obj::Arg(123, "named")); - EXPECT_EQ(ObjType::Char, (*arg_123_named)[0].second->getType()) << torch::toString(toTorchType((*arg_123_named)[0].second->getType())); + EXPECT_EQ(ObjType::Int8, (*arg_123_named)[0].second->getType()) << torch::toString(toTorchType((*arg_123_named)[0].second->getType())); ObjPtr arg_999_123_named = Obj::CreateDict(); ASSERT_EQ(0, arg_999_123_named->size()); @@ -633,8 +675,8 @@ TEST(Args, All) { ObjPtr arg_extra = Obj::CreateDict(Obj::Arg(Obj::CreateValue(999, ObjType::None)), Obj::Arg(123, "named")); ASSERT_EQ(2, arg_extra->size()); - EXPECT_EQ(ObjType::Short, (*arg_extra)[0].second->getType()) << torch::toString(toTorchType((*arg_extra)[0].second->getType())); - EXPECT_EQ(ObjType::Char, (*arg_extra)[1].second->getType()) << torch::toString(toTorchType((*arg_extra)[1].second->getType())); + EXPECT_EQ(ObjType::Int16, (*arg_extra)[0].second->getType()) << torch::toString(toTorchType((*arg_extra)[0].second->getType())); + EXPECT_EQ(ObjType::Int8, (*arg_extra)[1].second->getType()) << torch::toString(toTorchType((*arg_extra)[1].second->getType())); ObjPtr proto3_extra = proto3.ConvertToArgs(arg_extra.get(), true, nullptr); @@ -713,23 +755,23 @@ TEST(Types, FromLimit) { std::multimap IntTypes = { {0, ObjType::Bool}, {1, ObjType::Bool}, - {2, ObjType::Char}, - {127, ObjType::Char}, - // {255, ObjType::Char}, - {256, ObjType::Short}, - {-1, ObjType::Char}, - {-200, ObjType::Short}, - {66000, ObjType::Int}, - {-33000, ObjType::Int}, - {5000000000, ObjType::Long}, + {2, ObjType::Int8}, + {127, ObjType::Int8}, + // {255, ObjType::Int8}, + {256, ObjType::Int16}, + {-1, ObjType::Int8}, + {-200, ObjType::Int16}, + {66000, ObjType::Int32}, + {-33000, ObjType::Int32}, + {5000000000, ObjType::Int64}, }; for (auto elem : IntTypes) { ASSERT_EQ(elem.second, typeFromLimit(elem.first)) << elem.first << " " << toString(elem.second); } - ASSERT_EQ(ObjType::Double, typeFromLimit(1.0)); - ASSERT_EQ(ObjType::Float, typeFromLimit(0.0)); + ASSERT_EQ(ObjType::Float64, typeFromLimit(1.0)); + ASSERT_EQ(ObjType::Float32, typeFromLimit(0.0)); } @@ -747,11 +789,11 @@ TEST(ObjTest, Tensor) { RuntimePtr opts = RunTime::Init(); Context ctx(opts); - TermPtr term = Parser::ParseString("var:Int[2,3]"); + TermPtr term = Parser::ParseString("var:Int32[2,3]"); ObjPtr t1 = Context::CreateLVal(&ctx, term); - ASSERT_EQ(ObjType::Int, t1->m_var_type_current); - ASSERT_EQ(ObjType::Int, t1->m_var_type_fixed); + ASSERT_EQ(ObjType::Int32, t1->m_var_type_current); + ASSERT_EQ(ObjType::Int32, t1->m_var_type_fixed); ASSERT_FALSE(t1->m_var_is_init); ASSERT_EQ(2, t1->m_tensor.dim()); @@ -771,7 +813,7 @@ TEST(ObjTest, Tensor) { torch::Tensor tstr_t; - ConvertStringToTensor(str->m_value, tstr_t, ObjType::Char); + ConvertStringToTensor(str->m_value, tstr_t, ObjType::Int8); ASSERT_TRUE(tstr_t.defined()); ASSERT_EQ(tstr_t.index({0}).item(), 't'); @@ -788,7 +830,7 @@ TEST(ObjTest, Tensor) { ASSERT_EQ(tensot_temp.index({3}).item(), 't'); ObjPtr t_str = Obj::CreateTensor(tensot_temp); - ASSERT_EQ(t_str->m_var_type_current, ObjType::Char) << toString(t_str->m_var_type_current); + ASSERT_EQ(t_str->m_var_type_current, ObjType::Int8) << toString(t_str->m_var_type_current); ASSERT_EQ(4, t_str->size()); ASSERT_TRUE(t_str->m_tensor.defined()); @@ -813,10 +855,10 @@ TEST(ObjTest, Tensor) { ObjPtr wstr = Obj::CreateString(L"ТЕСТ"); ObjPtr t_wstr = Obj::CreateTensor(wstr->toType(ObjType::Tensor)->m_tensor); if(sizeof (wchar_t) == 2) { - ASSERT_EQ(t_wstr->m_var_type_current, ObjType::Short); + ASSERT_EQ(t_wstr->m_var_type_current, ObjType::Int16); } else { ASSERT_TRUE(sizeof (wchar_t) == 4); - ASSERT_EQ(t_wstr->m_var_type_current, ObjType::Int); + ASSERT_EQ(t_wstr->m_var_type_current, ObjType::Int32); } ASSERT_EQ(4, t_wstr->size()); diff --git a/src/test/parser_test.cpp b/src/test/parser_test.cpp index 432036df..802d2ca2 100644 --- a/src/test/parser_test.cpp +++ b/src/test/parser_test.cpp @@ -105,9 +105,9 @@ TEST_F(ParserTest, LiteralEval2) { ASSERT_STREQ("`strbyte(term(), 123);`", ast->toString().c_str()); } -TEST_F(ParserTest, LiteralFraction) { +TEST_F(ParserTest, LiteralRational) { ASSERT_TRUE(Parse("1\\1;")); - ASSERT_EQ(TermID::FRACTION, ast->getTermID()) << newlang::toString(ast->getTermID()); + ASSERT_EQ(TermID::RATIONAL, ast->getTermID()) << newlang::toString(ast->getTermID()); ASSERT_STREQ("1\\1", ast->toString().c_str()); /* Защита от случайной операции деления на единицу вместо указания дроби */ @@ -118,11 +118,11 @@ TEST_F(ParserTest, LiteralFraction) { ASSERT_NO_THROW(Parse("rrr := 11111111111111111\\1")); ASSERT_TRUE(Parse("100\\100;")); - ASSERT_EQ(TermID::FRACTION, ast->getTermID()) << newlang::toString(ast->getTermID()); + ASSERT_EQ(TermID::RATIONAL, ast->getTermID()) << newlang::toString(ast->getTermID()); ASSERT_STREQ("100\\100", ast->toString().c_str()); ASSERT_TRUE(Parse("123456789123456789123456789\\123456789123456789123456789;")); - ASSERT_EQ(TermID::FRACTION, ast->getTermID()) << newlang::toString(ast->getTermID()); + ASSERT_EQ(TermID::RATIONAL, ast->getTermID()) << newlang::toString(ast->getTermID()); ASSERT_STREQ("123456789123456789123456789\\123456789123456789123456789", ast->toString().c_str()); } @@ -150,9 +150,9 @@ TEST_F(ParserTest, TermName) { } TEST_F(ParserTest, Tensor1) { - ASSERT_TRUE(Parse("[,]:Char")); + ASSERT_TRUE(Parse("[,]:Int8")); ASSERT_EQ(TermID::TENSOR, ast->getTermID()) << newlang::toString(ast->getTermID()); - ASSERT_STREQ("[,]:Char", ast->toString().c_str()); + ASSERT_STREQ("[,]:Int8", ast->toString().c_str()); ASSERT_TRUE(Parse("term[1];")); ASSERT_EQ(TermID::TERM, ast->getTermID()) << newlang::toString(ast->getTermID()); @@ -235,23 +235,23 @@ TEST_F(ParserTest, Tensor4) { ASSERT_TRUE(Parse(":Type( \"str\" )")); ASSERT_STREQ(":Type(\"str\")", ast->toString().c_str()); - ASSERT_TRUE(Parse(":Int[3]( \"str\" ) ")); - ASSERT_STREQ(":Int[3](\"str\")", ast->toString().c_str()); + ASSERT_TRUE(Parse(":Int32[3]( \"str\" ) ")); + ASSERT_STREQ(":Int32[3](\"str\")", ast->toString().c_str()); - ASSERT_TRUE(Parse(":Int[2,2](1,2,3,4);")); - ASSERT_STREQ(":Int[2,2](1, 2, 3, 4)", ast->toString().c_str()); + ASSERT_TRUE(Parse(":Int32[2,2](1,2,3,4);")); + ASSERT_STREQ(":Int32[2,2](1, 2, 3, 4)", ast->toString().c_str()); - ASSERT_TRUE(Parse(":Int[2,2]( 0, ... )")); - ASSERT_STREQ(":Int[2,2](0, ...)", ast->toString().c_str()); + ASSERT_TRUE(Parse(":Int32[2,2]( 0, ... )")); + ASSERT_STREQ(":Int32[2,2](0, ...)", ast->toString().c_str()); - ASSERT_TRUE(Parse(":Int( ... ... dict )")); - ASSERT_STREQ(":Int(... ...dict)", ast->toString().c_str()); + ASSERT_TRUE(Parse(":Int32( ... ... dict )")); + ASSERT_STREQ(":Int32(... ...dict)", ast->toString().c_str()); - ASSERT_TRUE(Parse(":Int( ... dict )")); - ASSERT_STREQ(":Int(...dict)", ast->toString().c_str()); + ASSERT_TRUE(Parse(":Int32( ... dict )")); + ASSERT_STREQ(":Int32(...dict)", ast->toString().c_str()); - ASSERT_TRUE(Parse(":Int[2,2]( ... rand() ... )")); - ASSERT_STREQ(":Int[2,2](...rand()...)", ast->toString().c_str()); + ASSERT_TRUE(Parse(":Int32[2,2]( ... rand() ... )")); + ASSERT_STREQ(":Int32[2,2](...rand()...)", ast->toString().c_str()); ASSERT_TRUE(Parse(":type[10]( 1, 2, ... rand() ... )")); ASSERT_STREQ(":type[10](1, 2, ...rand()...)", ast->toString().c_str()); @@ -289,31 +289,31 @@ TEST_F(ParserTest, ScalarType) { ASSERT_TRUE(Parse("2;")); ASSERT_STREQ("2", ast->toString().c_str()); - ASSERT_STREQ(":Char", ast->m_type_name.c_str()); + ASSERT_STREQ(":Int8", ast->m_type_name.c_str()); ASSERT_TRUE(Parse("2_2;")); ASSERT_STREQ("2_2", ast->toString().c_str()); - ASSERT_STREQ(":Char", ast->m_type_name.c_str()); + ASSERT_STREQ(":Int8", ast->m_type_name.c_str()); ASSERT_TRUE(Parse("-1;")); ASSERT_STREQ("-1", ast->toString().c_str()); - ASSERT_STREQ(":Char", ast->m_type_name.c_str()); + ASSERT_STREQ(":Int8", ast->m_type_name.c_str()); ASSERT_TRUE(Parse("256;")); ASSERT_STREQ("256", ast->toString().c_str()); - ASSERT_STREQ(":Short", ast->m_type_name.c_str()); + ASSERT_STREQ(":Int16", ast->m_type_name.c_str()); ASSERT_TRUE(Parse("10_000;")); ASSERT_STREQ("10_000", ast->toString().c_str()); - ASSERT_STREQ(":Short", ast->m_type_name.c_str()); + ASSERT_STREQ(":Int16", ast->m_type_name.c_str()); ASSERT_TRUE(Parse("100_000;")); ASSERT_STREQ("100_000", ast->toString().c_str()); - ASSERT_STREQ(":Int", ast->m_type_name.c_str()); + ASSERT_STREQ(":Int32", ast->m_type_name.c_str()); ASSERT_TRUE(Parse("0.0;")); ASSERT_STREQ("0.0", ast->toString().c_str()); - ASSERT_STREQ(":Float", ast->m_type_name.c_str()); + ASSERT_STREQ(":Float32", ast->m_type_name.c_str()); @@ -321,102 +321,102 @@ TEST_F(ParserTest, ScalarType) { ASSERT_STREQ("0:Bool", ast->toString().c_str()); ASSERT_STREQ(":Bool", ast->m_type_name.c_str()); - ASSERT_TRUE(Parse("0:Int;")); - ASSERT_STREQ("0:Int", ast->toString().c_str()); - ASSERT_STREQ(":Int", ast->m_type_name.c_str()); + ASSERT_TRUE(Parse("0:Int32;")); + ASSERT_STREQ("0:Int32", ast->toString().c_str()); + ASSERT_STREQ(":Int32", ast->m_type_name.c_str()); - ASSERT_TRUE(Parse("0:Long;")); - ASSERT_STREQ("0:Long", ast->toString().c_str()); - ASSERT_STREQ(":Long", ast->m_type_name.c_str()); + ASSERT_TRUE(Parse("0:Int64;")); + ASSERT_STREQ("0:Int64", ast->toString().c_str()); + ASSERT_STREQ(":Int64", ast->m_type_name.c_str()); - ASSERT_TRUE(Parse("0:Float;")); - ASSERT_STREQ("0:Float", ast->toString().c_str()); - ASSERT_STREQ(":Float", ast->m_type_name.c_str()); + ASSERT_TRUE(Parse("0:Float32;")); + ASSERT_STREQ("0:Float32", ast->toString().c_str()); + ASSERT_STREQ(":Float32", ast->m_type_name.c_str()); // ASSERT_TRUE(Parse("0 : Half")); // ASSERT_STREQ("0:Half", ast->toString().c_str()); // ASSERT_STREQ(":Half", ast->m_type_name.c_str()); - ASSERT_TRUE(Parse("0:Double;")); - ASSERT_STREQ("0:Double", ast->toString().c_str()); - ASSERT_STREQ(":Double", ast->m_type_name.c_str()); + ASSERT_TRUE(Parse("0:Float64;")); + ASSERT_STREQ("0:Float64", ast->toString().c_str()); + ASSERT_STREQ(":Float64", ast->m_type_name.c_str()); ASSERT_TRUE(Parse("1:Bool;")); ASSERT_STREQ("1:Bool", ast->toString().c_str()); ASSERT_STREQ(":Bool", ast->m_type_name.c_str()); - ASSERT_TRUE(Parse("1:Char;")); - ASSERT_STREQ("1:Char", ast->toString().c_str()); - ASSERT_STREQ(":Char", ast->m_type_name.c_str()); + ASSERT_TRUE(Parse("1:Int8;")); + ASSERT_STREQ("1:Int8", ast->toString().c_str()); + ASSERT_STREQ(":Int8", ast->m_type_name.c_str()); - ASSERT_TRUE(Parse("1:Char;")); - ASSERT_STREQ("1:Char", ast->toString().c_str()); - ASSERT_STREQ(":Char", ast->m_type_name.c_str()); + ASSERT_TRUE(Parse("1:Int8;")); + ASSERT_STREQ("1:Int8", ast->toString().c_str()); + ASSERT_STREQ(":Int8", ast->m_type_name.c_str()); - ASSERT_TRUE(Parse("1:Double;")); - ASSERT_STREQ("1:Double", ast->toString().c_str()); - ASSERT_STREQ(":Double", ast->m_type_name.c_str()); + ASSERT_TRUE(Parse("1:Float64;")); + ASSERT_STREQ("1:Float64", ast->toString().c_str()); + ASSERT_STREQ(":Float64", ast->m_type_name.c_str()); - ASSERT_TRUE(Parse("2:Short;")); - ASSERT_STREQ("2:Short", ast->toString().c_str()); - ASSERT_STREQ(":Short", ast->m_type_name.c_str()); + ASSERT_TRUE(Parse("2:Int16;")); + ASSERT_STREQ("2:Int16", ast->toString().c_str()); + ASSERT_STREQ(":Int16", ast->m_type_name.c_str()); - ASSERT_TRUE(Parse("2_2:Int;")); - ASSERT_STREQ("2_2:Int", ast->toString().c_str()); - ASSERT_STREQ(":Int", ast->m_type_name.c_str()); + ASSERT_TRUE(Parse("2_2:Int32;")); + ASSERT_STREQ("2_2:Int32", ast->toString().c_str()); + ASSERT_STREQ(":Int32", ast->m_type_name.c_str()); - ASSERT_TRUE(Parse("-1:Char;")); - ASSERT_STREQ("-1:Char", ast->toString().c_str()); - ASSERT_STREQ(":Char", ast->m_type_name.c_str()); + ASSERT_TRUE(Parse("-1:Int8;")); + ASSERT_STREQ("-1:Int8", ast->toString().c_str()); + ASSERT_STREQ(":Int8", ast->m_type_name.c_str()); - ASSERT_TRUE(Parse("-1 :Long;")); - ASSERT_STREQ("-1:Long", ast->toString().c_str()); - ASSERT_STREQ(":Long", ast->m_type_name.c_str()); + ASSERT_TRUE(Parse("-1 :Int64;")); + ASSERT_STREQ("-1:Int64", ast->toString().c_str()); + ASSERT_STREQ(":Int64", ast->m_type_name.c_str()); - ASSERT_TRUE(Parse("256 :Short;")); - ASSERT_STREQ("256:Short", ast->toString().c_str()); - ASSERT_STREQ(":Short", ast->m_type_name.c_str()); + ASSERT_TRUE(Parse("256 :Int16;")); + ASSERT_STREQ("256:Int16", ast->toString().c_str()); + ASSERT_STREQ(":Int16", ast->m_type_name.c_str()); - ASSERT_TRUE(Parse("10_000 :Long;")); - ASSERT_STREQ("10_000:Long", ast->toString().c_str()); - ASSERT_STREQ(":Long", ast->m_type_name.c_str()); + ASSERT_TRUE(Parse("10_000 :Int64;")); + ASSERT_STREQ("10_000:Int64", ast->toString().c_str()); + ASSERT_STREQ(":Int64", ast->m_type_name.c_str()); // ASSERT_THROW(Parse("10__000"), parser_exception); - ASSERT_TRUE(Parse("100_000: Int;")); - ASSERT_STREQ("100_000:Int", ast->toString().c_str()); - ASSERT_STREQ(":Int", ast->m_type_name.c_str()); + ASSERT_TRUE(Parse("100_000: Int32;")); + ASSERT_STREQ("100_000:Int32", ast->toString().c_str()); + ASSERT_STREQ(":Int32", ast->m_type_name.c_str()); - ASSERT_TRUE(Parse("1.0 : Float;")); - ASSERT_STREQ("1.0:Float", ast->toString().c_str()); - ASSERT_STREQ(":Float", ast->m_type_name.c_str()); + ASSERT_TRUE(Parse("1.0 : Float32;")); + ASSERT_STREQ("1.0:Float32", ast->toString().c_str()); + ASSERT_STREQ(":Float32", ast->m_type_name.c_str()); - ASSERT_TRUE(Parse("-0.0 :Double;")); - ASSERT_STREQ("-0.0:Double", ast->toString().c_str()); - ASSERT_STREQ(":Double", ast->m_type_name.c_str()); + ASSERT_TRUE(Parse("-0.0 :Float64;")); + ASSERT_STREQ("-0.0:Float64", ast->toString().c_str()); + ASSERT_STREQ(":Float64", ast->m_type_name.c_str()); ASSERT_THROW(Parse("2:Bool;"), Interrupt); ASSERT_THROW(Parse("-1:Bool;"), Interrupt); - // ASSERT_THROW(Parse("-1:Char"), parser_exception); - ASSERT_THROW(Parse("300:Char;"), Interrupt); - ASSERT_THROW(Parse("100000:Short;"), Interrupt); + // ASSERT_THROW(Parse("-1:Int8"), parser_exception); + ASSERT_THROW(Parse("300:Int8;"), Interrupt); + ASSERT_THROW(Parse("100000:Int16;"), Interrupt); ASSERT_THROW(Parse("0.0:Bool;"), Interrupt); - ASSERT_THROW(Parse("0.0:Char;"), Interrupt); - ASSERT_THROW(Parse("0.0:Int;"), Interrupt); - ASSERT_THROW(Parse("0.0:Long;"), Interrupt); + ASSERT_THROW(Parse("0.0:Int8;"), Interrupt); + ASSERT_THROW(Parse("0.0:Int32;"), Interrupt); + ASSERT_THROW(Parse("0.0:Int64;"), Interrupt); } TEST_F(ParserTest, TensorType) { - ASSERT_TRUE(Parse("term:Char[1,2] := [ [1,2,],[3,4,],];")); - ASSERT_STREQ("term:Char[1,2] := [[1, 2,], [3, 4,],];", ast->toString().c_str()); + ASSERT_TRUE(Parse("term:Int8[1,2] := [ [1,2,],[3,4,],];")); + ASSERT_STREQ("term:Int8[1,2] := [[1, 2,], [3, 4,],];", ast->toString().c_str()); ASSERT_TRUE(Parse("term[..., 3] := 0;")); ASSERT_STREQ("term[..., 3] := 0;", ast->toString().c_str()); - ASSERT_TRUE(Parse("term []= [2, 3,]:Int;")); - ASSERT_STREQ("term []= [2, 3,]:Int;", ast->toString().c_str()); + ASSERT_TRUE(Parse("term []= [2, 3,]:Int32;")); + ASSERT_STREQ("term []= [2, 3,]:Int32;", ast->toString().c_str()); // ASSERT_TRUE(Parse("term[1, 3] :$type []= [[1,2,3,],];")); // ASSERT_STREQ("term[1, 3]:$type []= [[1, 2, 3,],];", ast->toString().c_str()); @@ -597,9 +597,9 @@ TEST_F(ParserTest, TermArgMixed) { } TEST_F(ParserTest, ArgsType) { - ASSERT_TRUE(Parse("term(bool:Bool=term(100), int:Int=100, long:Long=@term()):Double:={long;};")); + ASSERT_TRUE(Parse("term(bool:Bool=term(100), int:Int32=100, long:Int64=@term()):Float64:={long;};")); ASSERT_EQ(TermID::CREATE_OR_ASSIGN, ast->getTermID()) << newlang::toString(ast->getTermID()); - ASSERT_STREQ("term(bool:Bool=term(100), int:Int=100, long:Long=@term()):Double := {long;};", ast->toString().c_str()); + ASSERT_STREQ("term(bool:Bool=term(100), int:Int32=100, long:Int64=@term()):Float64 := {long;};", ast->toString().c_str()); } TEST_F(ParserTest, TermCall) { @@ -1340,21 +1340,21 @@ TEST_F(ParserTest, DISABLED_Ellipsis1) { // ASSERT_STREQ("0.1-0.20j;", ast->toString().c_str()); //} // -//TEST_F(ParserTest, Fraction) { +//TEST_F(ParserTest, Rational) { // ASSERT_TRUE(Parse("1\\1")); -// ASSERT_EQ(TermID::FRACTION, ast->getTermID()) << newlang::toString(ast->getTermID()); +// ASSERT_EQ(TermID::RATIONAL, ast->getTermID()) << newlang::toString(ast->getTermID()); // ASSERT_STREQ("1\\1;", ast->toString().c_str()); //} // -//TEST_F(ParserTest, Fraction2) { +//TEST_F(ParserTest, Rational2) { // ASSERT_TRUE(Parse("1\\-20")); -// ASSERT_EQ(TermID::FRACTION, ast->getTermID()) << newlang::toString(ast->getTermID()); +// ASSERT_EQ(TermID::RATIONAL, ast->getTermID()) << newlang::toString(ast->getTermID()); // ASSERT_STREQ("1\\-20;", ast->toString().c_str()); //} // -//TEST_F(ParserTest, Fraction3) { +//TEST_F(ParserTest, Rational3) { // ASSERT_TRUE(Parse("-3\\+11")); -// ASSERT_EQ(TermID::FRACTION, ast->getTermID()) << newlang::toString(ast->getTermID()); +// ASSERT_EQ(TermID::RATIONAL, ast->getTermID()) << newlang::toString(ast->getTermID()); // ASSERT_STREQ("-3\\+11;", ast->toString().c_str()); //} // @@ -1371,21 +1371,21 @@ TEST_F(ParserTest, Ellipsis2) { } TEST_F(ParserTest, Func1) { - ASSERT_TRUE(Parse("func_arg(arg1 :Char, arg2) :Char := { $arg1+$arg2; };")); + ASSERT_TRUE(Parse("func_arg(arg1 :Int8, arg2) :Int8 := { $arg1+$arg2; };")); ASSERT_EQ(TermID::CREATE_OR_ASSIGN, ast->getTermID()) << newlang::toString(ast->getTermID()); - ASSERT_STREQ("func_arg(arg1:Char, arg2):Char := {$arg1 + $arg2;};", ast->toString().c_str()); + ASSERT_STREQ("func_arg(arg1:Int8, arg2):Int8 := {$arg1 + $arg2;};", ast->toString().c_str()); } TEST_F(ParserTest, Func2) { - ASSERT_TRUE(Parse("func_arg(arg1:&Char, &arg2) :&Char := { $arg1+$arg2; };")); + ASSERT_TRUE(Parse("func_arg(arg1:&Int8, &arg2) :&Int8 := { $arg1+$arg2; };")); ASSERT_EQ(TermID::CREATE_OR_ASSIGN, ast->getTermID()) << newlang::toString(ast->getTermID()); - ASSERT_STREQ("func_arg(arg1:&Char, &arg2):&Char := {$arg1 + $arg2;};", ast->toString().c_str()); + ASSERT_STREQ("func_arg(arg1:&Int8, &arg2):&Int8 := {$arg1 + $arg2;};", ast->toString().c_str()); } TEST_F(ParserTest, Func3) { - ASSERT_TRUE(Parse("$res:Char ::= func_arg(100, 100);")); + ASSERT_TRUE(Parse("$res:Int8 ::= func_arg(100, 100);")); ASSERT_EQ(TermID::CREATE, ast->getTermID()) << newlang::toString(ast->getTermID()); - ASSERT_STREQ("$res:Char ::= func_arg(100, 100);", ast->toString().c_str()); + ASSERT_STREQ("$res:Int8 ::= func_arg(100, 100);", ast->toString().c_str()); } TEST_F(ParserTest, Func4) { @@ -2137,7 +2137,7 @@ TEST_F(ParserTest, MacroDSL) { } TEST_F(ParserTest, HelloWorld) { - ASSERT_TRUE(Parse("hello(str=\"\") := { printf(format:FmtChar, ...):Int := :Pointer('printf'); printf('%s', $1); $str;};")); + ASSERT_TRUE(Parse("hello(str=\"\") := { printf(format:FmtChar, ...):Int32 := :Pointer('printf'); printf('%s', $1); $str;};")); // ASSERT_STREQ("!!!!!!!!!!!!!!", ast->toString().c_str()); } diff --git a/src/test/fraction_test.cpp b/src/test/rational_test.cpp similarity index 98% rename from src/test/fraction_test.cpp rename to src/test/rational_test.cpp index 3894e087..4da25d45 100644 --- a/src/test/fraction_test.cpp +++ b/src/test/rational_test.cpp @@ -8,7 +8,7 @@ #include #include -#include +#include using namespace newlang; diff --git a/src/types.h b/src/types.h index a0886170..52743b7d 100644 --- a/src/types.h +++ b/src/types.h @@ -153,23 +153,25 @@ void ParserException(const char *msg, std::string &buffer, int row, int col); _(None, 0) \ \ _(Bool, 1) \ - _(Char, 2) \ - _(Short, 3) \ - _(Int, 4) \ - _(Long, 5) \ + _(Int8, 2) \ + _(Int16, 3) \ + _(Int32, 4) \ + _(Int64, 5) \ _(Integer, 15) \ \ - _(Float, 16) \ - _(Double, 17) \ - _(Number, 24) \ + _(Float16, 16) \ + _(Float32, 17) \ + _(Float64, 18) \ + _(Float, 24) \ \ - _(ComplexFloat, 25) \ - _(ComplexDouble, 26) \ + _(Complex16, 25) \ + _(Complex32, 26) \ + _(Complex64, 27) \ _(Complex, 31) \ \ _(Tensor, 32) \ \ - _(Fraction, 33) \ + _(Rational, 33) \ \ _(Arithmetic, 47) \ \ @@ -219,11 +221,11 @@ void ParserException(const char *msg, std::string &buffer, int row, int col); _(ErrorSignal, 243) // BigNum - Длинные целые числа произвольного размера 100:Big - // Currency - Fraction со знаменателем `10000 -1`000.00 `-1000 100:Curr - // Fraction - произвольная дробь с длинными числами 100\1 100:Frac + // Currency - Rational со знаменателем `10000 -1`000.00 `-1000 100:Curr + // Rational - произвольная дробь с длинными числами 100\1 100:Frac // Frac_tion \1 -> Curr_ency `1.0000 -> Big_Num 100`100`000. 100'100'000. - //Форматирующий символ дроби (fraction slash, U+2044) позволяет создавать произвольные дроби следующим образом: + //Форматирующий символ дроби (rational slash, U+2044) позволяет создавать произвольные дроби следующим образом: // последовательность цифр числителя + форматирующий символ дроби + последовательность цифр знаменателя // — при выводе на экран или на печать это должно преобразовываться в правильно сформированную дробь. // Например, 22⁄371 должна показываться как 22/371 или как 22 371 {\displaystyle {\frac {22}{371}}} {\displaystyle @@ -233,11 +235,11 @@ void ParserException(const char *msg, std::string &buffer, int row, int col); //{6}{7}}}) // целую часть нужно отделять от числителя дробной части подходящим пробелом (например, пробелом нулевой ширины U+200B). // - //Кроме того, существует символ ⅟ (fraction numerator one, U+215F), позволяющий формировать дроби с числителем, + //Кроме того, существует символ ⅟ (rational numerator one, U+215F), позволяющий формировать дроби с числителем, //равным 1. // "/-5 " - квадратный корень из 5, "3/-5" - корень третьей степени ???? // "1/_5" - Одна пятая ?? - // https://github.com/python/cpython/blob/main/Lib/fractions.py + // https://github.com/python/cpython/blob/main/Lib/rationals.py // //_RATIONAL_FORMAT = re.compile(r""" // \A\s* # optional whitespace at the start, @@ -247,7 +249,7 @@ void ParserException(const char *msg, std::string &buffer, int row, int col); // (?: # followed by // (?:/(?P\d+(_\d+)*))? # an optional denominator // | # or - // (?:\.(?Pd*|\d+(_\d+)*))? # an optional fractional part + // (?:\.(?Pd*|\d+(_\d+)*))? # an optional rationalal part // (?:E(?P[-+]?\d+(_\d+)*))? # and optional exponent // ) // \s*\Z # and optional whitespace to finish @@ -265,7 +267,7 @@ void ParserException(const char *msg, std::string &buffer, int row, int col); * - может быть изменяемым / не изменяемым (если тип указан явно) * - местом хранения (тензор/ссылка на последовательность байт) * Строки: - * - Обычные (UTF8), тип данных Char + * - Обычные (UTF8), тип данных Int8 * - Широкие (WIDE), тип данных wchar_t * - Нативные обычные ViewChar * - Нативные широкие ViewWide @@ -292,24 +294,24 @@ void ParserException(const char *msg, std::string &buffer, int row, int col); * * Автоматическое приведение типов в выражениях происходит по следующим правилам. * - Если тип указан явно, то он не может быть изменен - * - Определяется общий тип (Bool, Integer, Number, Complex). + * - Определяется общий тип (Bool, Integer, Float, Complex). * - Если тип литерала явно не указан, то выбирается минимальный байтовый размер для общего типа. * - В выражениях тензор-скаляр, тензором должен быть самый левый элемент выражения. * - Итоговым типом поседовательности выражений является тип первого вычисленного элемента. * - В операторах присвоения вычисление типа происходит дважды, сперва для правой части выражения, а потом для оператора * присовения. * - Тип меньшего размера может автоматически приводится к типу большему размеру или к более сложному типу - * bool -> char -> short -> int -> long -> float -> double -> complexfloat -> complexdouble + * bool -> char -> short -> int -> long -> float -> double -> Complex32 -> Complex64 * var := 1.0 + 2; // float - * var := 1 + 1000; // Short т.к. первый тип изменяемый - * var := 1:Char + 1000; // Ошибка в выражении т.к. первый тип не изменяемый Short -x-> Char - * var:Char := 1 + 1000; // Ошибка в присвоении т.к. тип не изменяемый Short -x-> Char - * var := 1000 + 2; // Short + * var := 1 + 1000; // Int16 т.к. первый тип изменяемый + * var := 1:Int8 + 1000; // Ошибка в выражении т.к. первый тип не изменяемый Int16 -x-> Int8 + * var:Int8 := 1 + 1000; // Ошибка в присвоении т.к. тип не изменяемый Int16 -x-> Int8 + * var := 1000 + 2; // Int16 * var := 1000 + 2.0; // Ошибка float -> short, но может быть var := 1000.0 + 2; * var := 1:Bool + 2; // Ошибка byte -> bool, но может быть var := 2 + 1:Bool; * * - Итоговым типом поседовательности выражений является тип первого вычисленого элемента. - * var := 1.0 + 2; // float var := 1000 + 2; // Short var := 1000 + 2.0; + * var := 1.0 + 2; // float var := 1000 + 2; // Int16 var := 1000 + 2.0; * - * АПриведение ра * Совместимость типов данныъ между собой определяется по следующему принципу. @@ -348,7 +350,7 @@ void ParserException(const char *msg, std::string &buffer, int row, int col); inline bool isGenericType(ObjType t) { switch (t) { case ObjType::Integer: // Любое ЦЕЛОЕ число включая логический тип - case ObjType::Number: // Любое число с ПЛАВАЮЩЕЙ ТОЧКОЙ + case ObjType::Float: // Любое число с ПЛАВАЮЩЕЙ ТОЧКОЙ case ObjType::Complex: // Любое КОМПЛЕКСНОЕ число case ObjType::Tensor: // Любое число в виде тензора (включая логический тип) case ObjType::Arithmetic: // Все числа, включая длинные, дроби и денежный формат @@ -369,8 +371,8 @@ void ParserException(const char *msg, std::string &buffer, int row, int col); } inline bool isBaseType(ObjType t) { - return t == ObjType::Bool || t == ObjType::Char || t == ObjType::Short || t == ObjType::Int - || t == ObjType::Long || t == ObjType::Float || t == ObjType::Double; + return t == ObjType::Bool || t == ObjType::Int8 || t == ObjType::Int16 || t == ObjType::Int32 + || t == ObjType::Int64 || t == ObjType::Float32 || t == ObjType::Float64; } inline bool isFunction(ObjType t) { @@ -388,17 +390,17 @@ void ParserException(const char *msg, std::string &buffer, int row, int col); } inline bool isIntegralType(ObjType t, bool includeBool) { - return (static_cast (t) >= static_cast (ObjType::Char) && + return (static_cast (t) >= static_cast (ObjType::Int8) && static_cast (t) <= static_cast (ObjType::Integer)) || (includeBool && t == ObjType::Bool); } inline bool isFloatingType(ObjType t) { - return t == ObjType::Float || t == ObjType::Double || t == ObjType::Number; + return t == ObjType::Float32 || t == ObjType::Float64 || t == ObjType::Float; } inline bool isComplexType(ObjType t) { - return t == ObjType::ComplexFloat || t == ObjType::ComplexDouble || t == ObjType::Complex; + return t == ObjType::Complex32 || t == ObjType::Complex64 || t == ObjType::Complex; } inline bool isTensor(ObjType t) { @@ -459,24 +461,26 @@ void ParserException(const char *msg, std::string &buffer, int row, int col); switch (t) { case ObjType::Bool: return at::ScalarType::Bool; - case ObjType::Char: + case ObjType::Int8: return at::ScalarType::Char; - case ObjType::Short: + case ObjType::Int16: return at::ScalarType::Short; - case ObjType::Int: + case ObjType::Int32: return at::ScalarType::Int; - case ObjType::Long: + case ObjType::Int64: case ObjType::Integer: return at::ScalarType::Long; - case ObjType::Float: + case ObjType::Float32: case ObjType::Tensor: return at::ScalarType::Float; - case ObjType::Double: - case ObjType::Number: + case ObjType::Float64: + case ObjType::Float: return at::ScalarType::Double; - case ObjType::ComplexFloat: + case ObjType::Complex16: + return at::ScalarType::ComplexHalf; + case ObjType::Complex32: return at::ScalarType::ComplexFloat; - case ObjType::ComplexDouble: + case ObjType::Complex64: case ObjType::Complex: return at::ScalarType::ComplexDouble; } @@ -491,53 +495,57 @@ void ParserException(const char *msg, std::string &buffer, int row, int col); case at::ScalarType::Char: case at::ScalarType::QInt8: case at::ScalarType::QUInt8: - return ObjType::Char; + return ObjType::Int8; case at::ScalarType::Short: - return ObjType::Short; + return ObjType::Int16; case at::ScalarType::Int: case at::ScalarType::QInt32: - return ObjType::Int; + return ObjType::Int32; case at::ScalarType::Long: - return ObjType::Long; - case at::ScalarType::Float: + return ObjType::Int64; case at::ScalarType::BFloat16: - return ObjType::Float; + case at::ScalarType::Half: + return ObjType::Float16; + case at::ScalarType::Float: + return ObjType::Float32; case at::ScalarType::Double: - return ObjType::Double; + return ObjType::Float64; + case at::ScalarType::ComplexHalf: + return ObjType::Complex16; case at::ScalarType::ComplexFloat: - return ObjType::ComplexFloat; + return ObjType::Complex32; case at::ScalarType::ComplexDouble: - return ObjType::ComplexDouble; + return ObjType::Complex64; } LOG_RUNTIME("Can`t convert type '%s' to ObjType!", at::toString(t)); } - inline ObjType typeFromLimit(int64_t value, ObjType type_default = ObjType::Long) { + inline ObjType typeFromLimit(int64_t value, ObjType type_default = ObjType::Int64) { if (value == 1 || value == 0) { return ObjType::Bool; } else if (value < std::numeric_limits::min() || value > std::numeric_limits::max()) { ASSERT(value > std::numeric_limits::min()); ASSERT(value < std::numeric_limits::max()); - return ObjType::Long; + return ObjType::Int64; } else if (value < std::numeric_limits::min() || value > std::numeric_limits::max()) { - return ObjType::Int; + return ObjType::Int32; } else if (value < std::numeric_limits::min() || value > std::numeric_limits::max()) { //-127 < ... > 128 - return ObjType::Short; + return ObjType::Int16; } else { - return ObjType::Char; + return ObjType::Int8; } return type_default; } - inline ObjType typeFromLimit(double value, ObjType type_default = ObjType::Float) { + inline ObjType typeFromLimit(double value, ObjType type_default = ObjType::Float32) { if (std::equal_to()(value, 0)) { return type_default; } - return ObjType::Double; + return ObjType::Float64; } - inline ObjType typeFromLimit(std::complex value, ObjType type_default = ObjType::ComplexFloat) { + inline ObjType typeFromLimit(std::complex value, ObjType type_default = ObjType::Complex32) { LOG_RUNTIME("Not implemented!"); } @@ -549,20 +557,20 @@ void ParserException(const char *msg, std::string &buffer, int row, int col); return LLVMVoidType(); case ObjType::Bool: return LLVMInt1Type(); - case ObjType::Char: + case ObjType::Int8: return LLVMInt8Type(); - case ObjType::Short: + case ObjType::Int16: return LLVMInt16Type(); - case ObjType::Int: + case ObjType::Int32: return LLVMInt32Type(); - case ObjType::Long: + case ObjType::Int64: case ObjType::Integer: return LLVMInt64Type(); - case ObjType::Float: + case ObjType::Float32: case ObjType::Tensor: return LLVMFloatType(); - case ObjType::Double: - case ObjType::Number: + case ObjType::Float64: + case ObjType::Float: return LLVMDoubleType(); case ObjType::Pointer: @@ -588,14 +596,14 @@ void ParserException(const char *msg, std::string &buffer, int row, int col); if (isSimpleType(to)) { // Для простых типов приведение типов почти как в Torch, только с учетом размера данных // Запрещено: Big size -> Small Size, т.е. Byte_tensor *= Int_tensor. - // Разрешено: Bool -> Byte, Char -> Short -> Int -> Long -> Float, Double -> ComplexFloat, ComplexDouble - // т.е. Int_tensor += Bool_tensor или ComplexFloat_tensor *= Short_tensor. + // Разрешено: Bool -> Byte, Int8 -> Int16 -> Int32 -> Int64 -> Float32, Float64 -> Complex32, Complex64 + // т.е. Int_tensor += Bool_tensor или Complex32_tensor *= Short_tensor. // return at::canCast(toTorchType(from), toTorchType(to)) - // && (from <= to || from == ObjType::Bool || from <= ObjType::Char || (isFloatingType(from) && + // && (from <= to || from == ObjType::Bool || from <= ObjType::Int8 || (isFloatingType(from) && // isFloatingType(to))); return (from <= to || (isFloatingType(from) && isFloatingType(to))); - } else if (to == ObjType::Fraction) { + } else if (to == ObjType::Rational) { return true; } } else if (isString(from) && isString(to)) {// && isObjectType(to)) { @@ -749,12 +757,12 @@ void ParserException(const char *msg, std::string &buffer, int row, int col); return isTensor(type); case ObjType::Integer: // Любое ЦЕЛОЕ число включая логический тип return isIntegralType(type, true); - case ObjType::Number: // Любое число с ПЛАВАЮЩЕЙ ТОЧКОЙ + case ObjType::Float: // Любое число с ПЛАВАЮЩЕЙ ТОЧКОЙ return isFloatingType(type) || isIntegralType(type, true); case ObjType::Complex: // Любое КОМПЛЕКСНОЕ число return isIntegralType(type, true) || isFloatingType(type) || isComplexType(type); case ObjType::Arithmetic: // Любое число - return isIntegralType(type, true) || isFloatingType(type) || isComplexType(type) || type == ObjType::Fraction; + return isIntegralType(type, true) || isFloatingType(type) || isComplexType(type) || type == ObjType::Rational; case ObjType::String: // Строка любого типа return isString(type); case ObjType::Object: // Любой объект (Class или Dictionary) From 252380fc381b7e38f37c3b6ba9f77fd4cc7e40c9 Mon Sep 17 00:00:00 2001 From: Aleksandr Ryabikov Date: Thu, 11 Aug 2022 14:21:34 +0300 Subject: [PATCH 31/31] =?UTF-8?q?=D0=9F=D0=BE=D0=BF=D1=80=D0=B0=D0=B2?= =?UTF-8?q?=D0=B8=D0=BB=20=D0=BE=D1=88=D0=B8=D0=B1=D0=BA=D1=83=20=D0=BF?= =?UTF-8?q?=D1=80=D0=B8=20=D1=81=D0=BE=D0=B7=D0=B4=D0=B0=D0=BD=D0=B8=D0=B8?= =?UTF-8?q?=20=D0=B0=D1=80=D0=B3=D1=83=D0=BC=D0=B5=D0=BD=D1=82=D0=BE=D0=B2?= =?UTF-8?q?=20=D0=BF=D1=80=D0=B8=20=D0=B2=D1=8B=D0=B7=D0=BE=D0=B2=D0=B5=20?= =?UTF-8?q?=D1=84=D1=83=D0=BD=D0=BA=D1=86=D0=B8=D0=B8=20+=20=D0=BF=D0=B5?= =?UTF-8?q?=D1=80=D0=B5=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=BA=D0=B0=20=D0=B4?= =?UTF-8?q?=D0=BE=D0=BA=D1=83=D0=BC=D0=B5=D0=BD=D1=82=D0=B0=D1=86=D0=B8?= =?UTF-8?q?=D0=B8=20=D0=B4=D0=BB=D1=8F=20=D1=80=D0=B5=D0=BB=D0=B8=D0=B7?= =?UTF-8?q?=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/index.md | 160 ++++----------- docs/iterators.md | 245 ++++++++++++++++++++++ docs/ops.md | 168 +++++++++++++++ docs/syntax.md | 100 +++++---- docs/types.md | 251 +++++++++++++++++++++++ examples/fact_1000.nlp | 9 + examples/hello.nlp | 9 + src/nbproject/Makefile-Debug.mk | 6 + src/nbproject/Makefile-UnitTest_LLVM.mk | 6 +- src/nbproject/Makefile-variables.mk | 4 +- src/nbproject/Package-UnitTest_LLVM.bash | 4 +- src/nbproject/configurations.xml | 70 ++++++- src/object.cpp | 10 +- src/object.h | 12 +- src/test/example_test.cpp | 50 ++++- src/test/object_test.cpp | 17 ++ 16 files changed, 928 insertions(+), 193 deletions(-) create mode 100644 docs/iterators.md create mode 100644 docs/ops.md create mode 100644 docs/types.md create mode 100755 examples/fact_1000.nlp create mode 100755 examples/hello.nlp diff --git a/docs/index.md b/docs/index.md index fcd6a488..79d6cb94 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,21 +1,15 @@ -[ PASSED ] 212 tests. -[ FAILED ] 3 tests, listed below: -[ FAILED ] Eval.TypesNative -[ FAILED ] Eval.Fileio -[ FAILED ] ExecStr.Funcs - -MCJIT::runFunction does not support full-featured argument passing!!!! - # Проект *NewLang* *NewLang* - это язык программирования высокого уровня в котором можно сочетать стандартные алгоритмические конструкции с декларативным программированием и тензорными вычислениями для задач машинного обучения. -Основной особенностью языка является простой, логичный и не противоречивый синтаксис, который основан не на использовании зарезервированных ключевых слов, а на строгой системе грамматических правил с использованием знаков препинания (в список которых входят и операторы языка). +Основной особенностью языка является простой, логичный и не противоречивый синтаксис, который основан не на использовании зарезервированных ключевых слов, а на строгой системе грамматических правил с использованием знаков препинания (в которые входят и операторы языка). + +Текущая версия 0.2 от ????????????.08.2022 ([Новое в текущей версии и история выпусков](https://newlang.net/version.html)) ## Основные свойства и особенности языка: - Возможность работы как в режиме интерпретатора, так и компилятора* -- Динамическая и статическая типизация с возможностью указания типов в явном виде. -- Статическая типизация является условно строгой (автоматическое приведение типов отсутствует, но допускается преобразование между некоторыми типами данных, например, целое число может быть автоматически преобразовано в вещественное, но не наоборот) +- Динамическая и статическая типизация с возможностью указания типов в явном виде. +- Статическая типизация является условно строгой (автоматическое приведение типов отсутствует, но допускается преобразование между некоторыми типами данных, например, целое число может быть автоматически преобразовано в вещественное или рациональное, но не наоборот) - Автоматическое управление памятью - ООП в виде явного наследования классов и [«утиная»](https://ru.wikipedia.org/wiki/%D0%A3%D1%82%D0%B8%D0%BD%D0%B0%D1%8F_%D1%82%D0%B8%D0%BF%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F) типизация - На уровне синтаксиса поддержка нескольких типов функций (обычные и [чистые функции без побочных эффектов](https://ru.wikipedia.org/wiki/%D0%A7%D0%B8%D1%81%D1%82%D0%BE%D1%82%D0%B0_%D1%84%D1%83%D0%BD%D0%BA%D1%86%D0%B8%D0%B8)) @@ -25,145 +19,79 @@ MCJIT::runFunction does not support full-featured argument passing!!!! - Имеется REPL [read-eval-print loop — «цикл: чтение — вычисление — вывод»](https://ru.wikipedia.org/wiki/REPL) ---------- -*) Данные возможности запалнированы к реализации при создании компилятора +*) Данные возможности запланированы к реализации при создании компилятора ## Зачем нужен *NewLang*? + У всех современных языков программирования происходит постоянное развитие (читай усложнение) синтаксиса по мере выхода новых версий. Это является своего рода, платой за появление новых возможностей и воспринимается пользователями как естественное явление. Но одновременно является и серьезной проблемой, т.к. с выходом новых версий добавляются новые ключевые слова и синтаксические конструкции, что неизбежно повышает порог входа для новых пользователей. Еще одним следствием этого процесса становится постоянное повышение сложности разработки и трудоемкости поддержки уже созданных программных продуктов, когда старый код дорабатывается с применением уже новых стандартов. -У *NewLang* сложность языковых конструкций естественно ограничена за счет разделения синтаксиса языка на две части, что упрощает его изучение и использование. +У *NewLang* сложность языковых конструкций естественно ограничена за счет разделения синтаксиса языка на две части, что упрощает его изучение и использование. -*Основной синтаксис* — для написания программ в объектно-ориентированном (императивном) и декларативном стилях, который основан не на зарезервированных ключевых словах, а на строгих грамматических правилах и *Расширенный синтаксис* — когда основного синтаксиса становится недостаточно, или требуется использовать языковую конструкцию языка реализации. +*Основной синтаксис* — для написания программ в объектно-ориентированном (императивном) и декларативном стилях, который основан не на зарезервированных ключевых словах, а на строгих грамматических правилах и Расширенный синтаксис — когда основного синтаксиса становится недостаточно, или требуется использовать языковую конструкцию языка реализации. -Еще одно неудобство современных мейнстримовых языков, большинство из них были созданы до начала эпохи машинного обучения, поэтому тензорные вычисления у них выполнены в виде отдельных библиотек, а не встроены в основной синтаксис языка и систему базовых типов. +Еще одно неудобство современных мейнстримовых языков, большинство из них были созданы до начала эпохи машинного обучения, поэтому тензорные вычисления у них выполнены в виде отдельных библиотек, а не встроены в основной синтаксис языка и систему базовых типов. Это же касается и вычислений с неограниченной точностью, которая так же не поддерживается синтаксисом языка и реализуется с помощью вызовов библиотечных функций. -У *NewLang* тензорные вычисления доступны «из коробки» (используется библиотека [libtorch](https://pytorch.org/)), а арифметические типы данных являются скалярами (тензорами нулевой размерности). +У *NewLang* тензорные вычисления доступны «из коробки» (используется библиотека [libtorch](https://pytorch.org/)), а арифметические типы данных являются скалярами (тензорами нулевой размерности). Так же «из коробки» и на уровне синтаксиса поддерживаются рациональные числа неограниченной точности, которые реализованы с использованием длинной арифметики из библиотеки OpenSSL. -### Основной синтаксис -Основной синтаксис *NewLang* - простой и логичный за счет того, что он построен исключительно на грамматических правилах и не использует каких либо зарезервированных ключевых слов, а все буквенно-символьные последовательности рассматриваются как идентификаторы в которых можно использовать любые не-ASCII символы. +[Синтаксис языка](https://newlang.net/syntax.html) -Идеализированная цель отказа от ключевых слов, приблизить чтение исходного текста программы при описании логики работы алгоритма к чтению обычного текста за счет использования знаков препинания. +[Подробное описание системы типов](https://newlang.net/types.html) -> конечно *запятая* человек может вычленять ключевые управляющие слова языка и *слеш* или учитывать форматирование программы *запятая* чтобы на их основе понимать синтаксические конструкции *запятая* хотя при обычном чтении мы привыкли опирается именно на семантику знаков препинания *точка* мы конечно можем писать знаки препинания и обычным текстом *запятая* но согласитесь *запятая* что тогда *открытая скобка* например *запятая* вот такой вот текст *закрытая скобка* будет очень не удобно читать *точка* +[Операторы и управляющие конструкции](https://newlang.net/ops.html) -Названия встроенных типов или имена служебных функции системной библиотеки определяются конкретной реализацией языка, поэтому не являются зарезервированными ключевыми словами и при необходимости могут быть переопределены, например, для создания собственного, предметно-ориентированного диалекта (DSL - domain-specific language). Но сама структура программы и логика выполняемого алгоритма все равно останутся понятны всем, кто знаком правилами основного синтаксиса *NewLang*. -### Расширенный синтаксис -Расширенный синтаксис — это возможность вставить в текст программы *NewLang* исходнй код на языке реализации, что позволяет использовать практически любые возможности С/С++. - -Обработка расширенного синтаксиса происходит на этапе компиляции приложения, а взаимодействие между основным -и расширенным синтаксисами происходит за счет совместного использования идентификаторов, которое полностью прозрачно для пользователя и подчиняется единым грамматическим правилам основного синтаксиса. - -*Пример скрипта Hello world! на NewLang* +**Пример скрипта Hello world! на NewLang** ``` - #!./nlc --eval + #!../output/nlc --eval + # Определение функции hello hello(str) := { - printf := @import('printf(format:FmtChar, ...):Int'); # Импорт стандартной C функции - printf('%s\n', $str); # Вызов C функции с проверкой типов аргументов по строке формата + printf := :Pointer('printf(format:FmtChar, ...):Int32'); # Импорт стандартной C функции + printf('%s', $str); # Вызов C функции с проверкой типов аргументов по строке формата + $str; }; hello('Привет, мир!'); # Вызвать функцию ``` -Вывод: `Привет, мир!` - -## Еще немного примеров: -Любая последовательность вычислений возвращает результат выполнения последнего оператора. -Поэтому выполнение одной команды или последовательности команд всегда возвращает какой либо результат, а оператор возврата из функции необязателен, так как результатом будет значение последнего вычисленного выражения. - -### Создание переменных - > scalar := 42 - 42 - - > tensor := [1,2,3,4,5,] # Тип тензора выводится автоматически - [1, 2, 3, 4, 5,]:Char - - > str := '$1 string' # Создание байтовой строки - $1 string - -### Арифметические операции - > tensor * 2 - [2, 4, 6, 8, 10,]:Short - - > tensor * 20 - [20, 40, 60, 80, 100,]:Short - - > tensor * 0.5 - [0.5, 1, 1.5, 2, 2.5,]:Double - - > tensor / 2 # Результата деления — число с плавающей точкой - [0.5, 1, 1.5, 2, 2.5,]:Double - - > tensor // 2 # Целочисленное деление без остатка - [0, 1, 1, 2, 2,]:Char - - > tensor % 2 # Целочисленный остаток от деления - [1, 0, 1, 0, 1,]:Char - -### Строковые операции - > str = 'сцепеление строк ' ++ str - сцепеление строк $1 string - - > str('строка как шаблон') # символ $1 в строке заменяется на первый аргумент - сцепеление строк строка как шаблон string - -## Преобразование данных -В эпоху машинного обучения тензоры являются основным элементом вычислений, поэтому функции создания и преобразования типов обязательно должны поддерживать тензоры. Данная поддержка заключается в следующим: - -Название типов данных должно начинатся на символ двоеточия, а операция создания данных заданного типа заключается в записи нужного типа даннх в виде вызова функции, т.е. :Int(10) - создает скаляр указанного типа с значением 10. - -А так как тензоры могту иметь больше одного значения, то и в качестве аргументов можно передавать более одного значения и результатом будет тензор содержащий указанные значения с автоматическим преобразованим переданных значений к требуемому типу. - -Подробнее про особенности преобразования типов можно посмотреть в [полном описании синтаксиса](https://github.com/rsashka/newlang/blob/master/Syntax.md). - - > tstr := :Tensor("Тест"); # Создать тензор из строки широких символов - [1058, 1077, 1089, 1090,]:Int +Вывод (первая строка выводится с помощью printf, а вторая - возвращаемое значение функции hello): +``` +Привет, мир! +Привет, мир! +``` - > t2 := :Tensor[2,2]("Тест"); # Тоже самое, но тензор указанной размерности - [ - [1058, 1077,], [1089, 1090,], - ]:Int +**Пример скрипта для вычисления факториала 1000 на NewLang** +``` + #!../output/nlc --eval - > :StrWide(tstr) # Создать символьную строку из тензора - Тест + @fact := 1\1; # Рациональное число без органичений точности + @mult := 1000..1..-1?; # Получить итератор для множителей от 1000 до 2 + [mult?!] <<-->> { # Цикл, пока не закончатся данные итератора + fact *= mult!; # Получить текущий множитель и перейти на следующий элемент итератора + }; + fact # Вывести итоговый результат - > :Double(t2) # Изменить тип данных тезора без изменения размерности - [ - [1058, 1077,], [1089, 1090,], - ]:Double +``` +Вывод: `402387260077093773543702433923003985719374864210714632543799910429938512398629020592044208486969404800479988610197196058631666872994808558901323829669944590997424504087073759918823627727188732519779505950995276120874975462497043601418278094646496291056393887437886487337119181045825783647849977012476632889835955735432513185323958463075557409114262417474349347553428646576611667797396668820291207379143853719588249808126867838374559731746136085379534524221586593201928090878297308431392844403281231558611036976801357304216168747609675871348312025478589320767169132448426236131412508780208000261683151027341827977704784635868170164365024153691398281264810213092761244896359928705114964975419909342221566832572080821333186116811553615836546984046708975602900950537616475847728421889679646244945160765353408198901385442487984959953319101723355556602139450399736280750137837615307127761926849034352625200015888535147331611702103968175921510907788019393178114194545257223865541461062892187960223838971476088506276862967146674697562911234082439208160153780889893964518263243671616762179168909779911903754031274622289988005195444414282012187361745992642956581746628302955570299024324153181617210465832036786906117260158783520751516284225540265170483304226143974286933061690897968482590125458327168226458066526769958652682272807075781391858178889652208164348344825993266043367660176999612831860788386150279465955131156552036093988180612138558600301435694527224206344631797460594682573103790084024432438465657245014402821885252470935190620929023136493273497565513958720559654228749774011413346962715422845862377387538230483865688976461927383814900140767310446640259899490222221765904339901886018566526485061799702356193897017860040811889729918311021171229845901641921068884387121855646124960798722908519296819372388642614839657382291123125024186649353143970137428531926649875337218940694281434118520158014123344828015051399694290153483077644569099073152433278288269864602789864321139083506217095002597389863554277196742822248757586765752344220207573630569498825087968928162753848863396909959826280956121450994871701244516461260379029309120889086942028510640182154399457156805941872748998094254742173582401063677404595741785160829230135358081840096996372524230560855903700624271243416909004153690105933983835777939410970027753472000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\1` - > t3 := :Char[4]( t2 ) # Изменить размерность тензора и его тип (в данном случае с частичной потерей данных) - [34, 53, 65, 66,]:Char -## [Полное описание синтаксиса](https://newlang.net/syntax.html) +### Загрузки +[Бинарная сборка REPL (пока только под Ubuntu)](https://newlang.net/nlc) +[Архив с необходимыми разделяемыми библиотеками](https://newlang.net/env) -## Сборка REPL из исходников (пока только под Linux) +## Так же можно собрать из исходников ### Подготовка репозитория - Скачать исходники [https://github.com/rsashka/newlang](https://github.com/rsashka/newlang) - Скачать и развернуть архив [libtorch](https://pytorch.org/) в каталоге *contrib* (PyTorch Build: Stable (1.10.*) -> Your OS: Linux -> Package: LibTorch -> Language: C++ / Java -> Compute Platform: CPU -> Download here (cxx11 ABI): [libtorch-cxx11-abi-shared-with-deps-1.10.2+cpu.zip](https://download.pytorch.org/libtorch/cpu/libtorch-cxx11-abi-shared-with-deps-1.10.2%2Bcpu.zip)) - Активировать и скачать исходники субмодулей (`git submodule init && git submodule update`) -- В каталоге *contrib* запустить файл `build.sh` для сборки библиотеки libffi +- В каталоге *contrib* запустить файл `build.sh` - В каталоге *src* запустить файл `compile_syntax.sh` для генерации файлов парсера и лексического анализатора. Также может потребоваться установка утилит *flex* и *bison*. Если что, у меня установлены flex 2.6.4 и bison (GNU Bison) 3.7.4 - -### Собрать -- Юнит-тесты (newlang_test): в каталоге *src* выполнить команду **`make CONF=UnitTest`** * -- Интерпретатор (nlc): в каталоге *src* выполнить команду **`make CONF=Debug`** * +### Сборка +- Юнит-тесты (nlc_test): в каталоге *src* выполнить команду **`make CONF=UnitTest_LLVM`** * +- Интерпретатор (nlc): в каталоге *src* выполнить команду **`make CONF=Debug_LLVM`** * --- *) - Сборка проекта выполняется обычной утилитой make, но сборочные файлы генерируются автоматически в давно устаревшей версии NetBeans 8.2, т.к. это единственная универсальная среда разработки с поддержкой Makefile "из коробки", тогда как в текущей версии Apache NetBeans полноценная поддержка разработки на С/С++ вообще отсутствует. Начал постепеный переход на использование редактора VSCodium (аналога VSCode, в котором вычищена телеметрия от Microsoft) и генерацию скиптов сборки с помощью сmake, но этот процесс пока не завершен. - - -# Планы на будущее -Текущая версия, это скорее тестовая платформа для проверки декларируемых концепций и основного синтаксиса. Если говорить о планах, то в настоящий момент роадмап развития NewLang следующий: -- Добавить в язык макросы для более простого использовани за счет использования концепции DSL -- Реализовать длинную арифметику и дроби -- Сделать какую нибудь логическую игру (крестики нолики, судоку или что-то похожее) с алгоритмическим выбором следующего хода и его вычислением с помощью машинного обучения. -- Написать много разных примеров для оценки синтаксиса. -- Доработать синтаксис с учетом полученного опыта и обратной связи. -- Восстановить работоспособность компилятора для генерации исполняемых файлов. -- Сделать очередную большую чистку кода. -- Переработать и задокументировать получившуюся семантику языка с учетом всех возможностей и выпустить первую полнофункциональную версию NewLang. - diff --git a/docs/iterators.md b/docs/iterators.md new file mode 100644 index 00000000..9544acef --- /dev/null +++ b/docs/iterators.md @@ -0,0 +1,245 @@ +# Итераторы + +Итератор в С++ — это объект, который может перебирать элементы в контейнере и предоставлять доступ к отдельным элементам. Все контейнеры стандартной библиотеки С++ предоставляют итераторы, чтобы алгоритмы могли получить доступ к их элементам стандартным способом, независимо от типа контейнера, в котором сохранены элементы. что итератор C++ это интерфес у которого перегружены некоторые операции, такие как инкремент, обращение по ссылки и пр., но сам итератор концептуяально является указателем и для контроля завершения итератора требуется сравнивать текущий элемент в последей позицией в контейнере (т.е. для сравнения текущего элемента с end()). + +Итераторы в NewLang и итераторы в C++ очень сильно отличаются. + + +Требуется разделять конейнеры с данными и итераторы по данным. +В С++ контейнеры данных предоставялют итераторы, для работы с которыми требуются сами контейнеры непосредствено. +Это удобно для использования в рукописном коде, но сложно контроллировать в генерируемом исходнике, + * т.к. требуется использовать и итертор и сам контейнер с данными (для сравнения текущего элемента с end()). + * + * Итератор - отдельный объект, которому для создания требуется контейнер с данными. + * Итератор реализует два интерфейса перебора данных: + * 1. - первый интерфейс итератора как в С++ + * 2. - второй интерфейс для использования в генерируемом коде с логикой NewLang + * + * template Iterator - Обертка над классическим С++ итератором с добавлением возможности отбора + * элементов по имени поля или с помощь функции обратного вызова для пользовательской фильтрации. + * + * Программынй интерфейс итераторов для NewLang следующий: + * + * ObjPtr IteratorMake(const std::string filter) - создать итератор с возможностью фильтрации по имени поля (данные на начало) + * ObjPtr IteratorMake(Obj * args) - создать итератор с фильтрации с помощью пользовательской функции (данные на начало) + * ObjPtr IteratorReset() - Сбросить итератор на начало данных (возвращает сам итератор) + * ObjPtr IteratorData() - прочитать текущий элемент без смещения указателя. Если данных нет возвращается "конец итератора" + * ObjPtr IteratorNext(int64_t count)- прочитать заданное кол-во элементов и переместить итератор на следующий элемент. + * При не нулевом кол-ве, данные возвращаются как элементы словаря. Если указан кол-во элеметов 0 - возвращается текущий элемент. + * + * Реализаиця итераторов NewLang с помощью данного интерфейса: + * + * Создание итератора + * ?, ?("Фильтр"), ?(func), ?(func, args...) - IteratorMake + * + * Перебор элементов итератора + * !, !(0), !(3), !(-3) + * + * dict! и dict!(0) <НЕ> эквивалентны, т.к. по разному обработывают конец данных + * dict! -> 1, dict! -> 2, dict! -> 3, dict! -> 4, dict! -> 5, dict! -> исключение "конец итератора" + * dict!(0) -> 1, dict!(0) -> 2, ... dict!(0) -> 5, dict!(0) -> :IteratorEnd (может :Empty - пустое значение ?? ) + * dict!(1) -> (1,), dict!(1) -> (2,), ... dict!(1) -> (5,), dict!(1) -> (,) + * + * Различия отрицательного размера возвращаемого словаря для итератора + * (Для отрцетельного размера всегда зозвращается словарь указанного размера) + * dict!(-1) -> (1,), ... dict!(-1) -> (5,), dict!(-1) -> (:IteratorEnd,), + * dict!(1) -> (1,), ... dict!(1) -> (5,), dict!(1) -> (,), + * dict!(-3) -> (1, 2, 3,), dict!(-3) -> (4, 5, :IteratorEnd,) + * dict!(3) -> (1, 2, 3,), dict!(3) -> (4, 5,) + * + * Операторы ?! и !? эквивалентны и возвращают текущие данные без перемещения указателя итератора (IteratorData) и не принимают аргументов. + * Остальные итераторы можно вызвать либо без скобок, либо с аргментами в скобрках. Вызов без аргументов зарпрешщен + * (чтобы не пересекаться с логикой копирования объектов и не делать для итераторов аругменты по умолчанию) + * + * Оператор ?? создает итератор и сразу его выполняет, возвращая все значения + * в виде элементов словаря, т.е. аналог последовательности ?(LINQ); !(:Int64.__max__); + * + * Оператор !! без аргументов - сбрасывает итератор в начальное состояние (IteratorReset), + * Обператор !! с аргументами выполняется как ! с аругментами, но с начла коллекции. + + + +``` +dict := (1,2,3,); # Словарь с тремя элемнтами +iter := dict?; # Итератор по всем элементам словаря +iter!; # Вернется 1 +iter!; # Вернется 2 +iter!; # Вернется 3 +iter!; # Произойдет исключение "конец итератора" + +iter?!; # Произойдет исключение "конец итератора" + + ``` + + + * Перебор элементов итератора + * !, !(0), !(3), !(-3) + * + * dict! и dict!(0) <НЕ> эквивалентны, т.к. по разному обработывают конец данных + * dict! -> 1, dict! -> 2, dict! -> 3, dict! -> 4, dict! -> 5, dict! -> исключение "конец итератора" + * dict!(0) -> 1, dict!(0) -> 2, ... dict!(0) -> 5, dict!(0) -> :IteratorEnd (может :Empty - пустое значение ?? ) + * dict!(1) -> (1,), dict!(1) -> (2,), ... dict!(1) -> (5,), dict!(1) -> (,) + * + * Различия отрицательного размера возвращаемого словаря для итератора + * (Для отрцетельного размера всегда зозвращается словарь указанного размера) + * dict!(-1) -> (1,), ... dict!(-1) -> (5,), dict!(-1) -> (:IteratorEnd,), + * dict!(1) -> (1,), ... dict!(1) -> (5,), dict!(1) -> (,), + * dict!(-3) -> (1, 2, 3,), dict!(-3) -> (4, 5, :IteratorEnd,) + * dict!(3) -> (1, 2, 3,), dict!(3) -> (4, 5,) + * + * Операторы ?! и !? эквивалентны и возвращают текущие данные без перемещения указателя итератора (IteratorData) и не принимают аргументов. + * Остальные итераторы можно вызвать либо без скобок, либо с аргментами в скобрках. Вызов без аргументов зарпрешщен + * (чтобы не пересекаться с логикой копирования объектов и не делать для итераторов аругменты по умолчанию) + * + * Оператор ?? создает итератор и сразу его выполняет, возвращая все значения + * в виде элементов словаря, т.е. аналог последовательности ?(LINQ); !(:Int64.__max__); + * + * Оператор !! без аргументов - сбрасывает итератор в начальное состояние (IteratorReset), + * Обператор !! с аргументами выполняется как ! с аругментами, но с начла коллекции. + * + * [ ] - оператор приведения данных в логический тип. Испольуется в алгоритмических конструкциях (проверка условий и циклы) + * Правила преобразования в логический тип: + * Словарь или класс - нет элементов - false, есть элементы - true + * Число - ноль или нулевой тензо - false, иначе true + * Строка - пустая строка false, иначе true + * Итератор - конец данных false, иначе true + * :IteratorEnd (:Empty ?) - всегда false + * None - true (Это объекст со значением пусто) + * Empty - false (Не инициализированный объект) + * + * + * Логика обработки ссылок + * term1 := term; # Объект term1 - копия term. + * term2 := &term; # Объект term2 - ссылка на term (одни и те же данные, т.е. shared_ptr ссылаются на один и тот же объект) + * &term3 := term; # Создать объект term3 и вернуть ссылку на него (сахар для term3 := term; &term3;) + * + * + * copy(arg) := {}; # Обычная функция принимает любой аргумент как <КОПИЮ> значения + * copy(term1); # ОК - передается <КОПИЯ> term1 + * copy(term2); # ОК - передается <КОПИЯ> term2 + * copy(&term1); # ОК - передается ссылка на term1 (На самом деле копия ссылки, которая указывает на те же данные) + * copy(&term2); # ОК- передается ссылка на term2 (На самом деле копия ссылки, которая указывает на те же данные) + * + * ptr(&arg) := {}; # Функция, которая принимает только аргумент - <ссылку> + * ptr(term1); # Ошибка при компиляции - нужно передавать ссылку !!!!!!!! + * ptr(&term1); # ОК + * ptr(&term2); # ОК + * ptr(term2); # Ошибка при компиляции - нужно передавать ссылку, несмотря на то что term2 УЖЕ содержит ссылку !!!!!!!! + + + + + +Итераторы в NewLang и итераторы в C++ очень сильно отличаются. + + +Требуется разделять конейнеры с данными и итераторы по данным. +В С++ контейнеры данных предоставялют итераторы, для работы с которыми требуются сами контейнеры непосредствено. +Это удобно для использования в рукописном коде, но сложно контроллировать в генерируемом исходнике, + * т.к. требуется использовать и итертор и сам контейнер с данными (для сравнения текущего элемента с end()). + * + * Итератор - отдельный объект, которому для создания требуется контейнер с данными. + * Итератор реализует два интерфейса перебора данных: + * 1. - первый интерфейс итератора как в С++ + * 2. - второй интерфейс для использования в генерируемом коде с логикой NewLang + * + * template Iterator - Обертка над классическим С++ итератором с добавлением возможности отбора + * элементов по имени поля или с помощь функции обратного вызова для пользовательской фильтрации. + * + * Программынй интерфейс итераторов для NewLang следующий: + * + * ObjPtr IteratorMake(const std::string filter) - создать итератор с возможностью фильтрации по имени поля (данные на начало) + * ObjPtr IteratorMake(Obj * args) - создать итератор с фильтрации с помощью пользовательской функции (данные на начало) + * ObjPtr IteratorReset() - Сбросить итератор на начало данных (возвращает сам итератор) + * ObjPtr IteratorData() - прочитать текущий элемент без смещения указателя. Если данных нет возвращается "конец итератора" + * ObjPtr IteratorNext(int64_t count)- прочитать заданное кол-во элементов и переместить итератор на следующий элемент. + * При не нулевом кол-ве, данные возвращаются как элементы словаря. Если указан кол-во элеметов 0 - возвращается текущий элемент. + * + * Реализаиця итераторов NewLang с помощью данного интерфейса: + * + * Создание итератора + * ?, ?("Фильтр"), ?(func), ?(func, args...) - IteratorMake + * + * Перебор элементов итератора + * !, !(0), !(3), !(-3) + * + * dict! и dict!(0) <НЕ> эквивалентны, т.к. по разному обработывают конец данных + * dict! -> 1, dict! -> 2, dict! -> 3, dict! -> 4, dict! -> 5, dict! -> исключение "конец итератора" + * dict!(0) -> 1, dict!(0) -> 2, ... dict!(0) -> 5, dict!(0) -> :IteratorEnd (может :Empty - пустое значение ?? ) + * dict!(1) -> (1,), dict!(1) -> (2,), ... dict!(1) -> (5,), dict!(1) -> (,) + * + * Различия отрицательного размера возвращаемого словаря для итератора + * (Для отрцетельного размера всегда зозвращается словарь указанного размера) + * dict!(-1) -> (1,), ... dict!(-1) -> (5,), dict!(-1) -> (:IteratorEnd,), + * dict!(1) -> (1,), ... dict!(1) -> (5,), dict!(1) -> (,), + * dict!(-3) -> (1, 2, 3,), dict!(-3) -> (4, 5, :IteratorEnd,) + * dict!(3) -> (1, 2, 3,), dict!(3) -> (4, 5,) + * + * Операторы ?! и !? эквивалентны и возвращают текущие данные без перемещения указателя итератора (IteratorData) и не принимают аргументов. + * Остальные итераторы можно вызвать либо без скобок, либо с аргментами в скобрках. Вызов без аргументов зарпрешщен + * (чтобы не пересекаться с логикой копирования объектов и не делать для итераторов аругменты по умолчанию) + * + * Оператор ?? создает итератор и сразу его выполняет, возвращая все значения + * в виде элементов словаря, т.е. аналог последовательности ?(LINQ); !(:Int64.__max__); + * + * Оператор !! без аргументов - сбрасывает итератор в начальное состояние (IteratorReset), + * Обператор !! с аргументами выполняется как ! с аругментами, но с начла коллекции. + + + + рах и итераторы в C++ очень сильно отличаются. + + +Требуется разделять конейнеры с данными и итераторы по данным. +В С++ контейнеры данных предоставялют итераторы, для работы с которыми требуются сами контейнеры непосредствено. +Это удобно для использования в рукописном коде, но сложно контроллировать в генерируемом исходнике, + * т.к. требуется использовать и итертор и сам контейнер с данными (для сравнения текущего элемента с end()). + * + * Итератор - отдельный объект, которому для создания требуется контейнер с данными. + * Итератор реализует два интерфейса перебора данных: + * 1. - первый интерфейс итератора как в С++ + * 2. - второй интерфейс для использования в генерируемом коде с логикой NewLang + * + * template Iterator - Обертка над классическим С++ итератором с добавлением возможности отбора + * элементов по имени поля или с помощь функции обратного вызова для пользовательской фильтрации. + * + * Программынй интерфейс итераторов для NewLang следующий: + * + * ObjPtr IteratorMake(const std::string filter) - создать итератор с возможностью фильтрации по имени поля (данные на начало) + * ObjPtr IteratorMake(Obj * args) - создать итератор с фильтрации с помощью пользовательской функции (данные на начало) + * ObjPtr IteratorReset() - Сбросить итератор на начало данных (возвращает сам итератор) + * ObjPtr IteratorData() - прочитать текущий элемент без смещения указателя. Если данных нет возвращается "конец итератора" + * ObjPtr IteratorNext(int64_t count)- прочитать заданное кол-во элементов и переместить итератор на следующий элемент. + * При не нулевом кол-ве, данные возвращаются как элементы словаря. Если указан кол-во элеметов 0 - возвращается текущий элемент. + * + * Реализаиця итераторов NewLang с помощью данного интерфейса: + * + * Создание итератора + * ?, ?("Фильтр"), ?(func), ?(func, args...) - IteratorMake + * + * Перебор элементов итератора + * !, !(0), !(3), !(-3) + * + * dict! и dict!(0) <НЕ> эквивалентны, т.к. по разному обработывают конец данных + * dict! -> 1, dict! -> 2, dict! -> 3, dict! -> 4, dict! -> 5, dict! -> исключение "конец итератора" + * dict!(0) -> 1, dict!(0) -> 2, ... dict!(0) -> 5, dict!(0) -> :IteratorEnd (может :Empty - пустое значение ?? ) + * dict!(1) -> (1,), dict!(1) -> (2,), ... dict!(1) -> (5,), dict!(1) -> (,) + * + * Различия отрицательного размера возвращаемого словаря для итератора + * (Для отрцетельного размера всегда зозвращается словарь указанного размера) + * dict!(-1) -> (1,), ... dict!(-1) -> (5,), dict!(-1) -> (:IteratorEnd,), + * dict!(1) -> (1,), ... dict!(1) -> (5,), dict!(1) -> (,), + * dict!(-3) -> (1, 2, 3,), dict!(-3) -> (4, 5, :IteratorEnd,) + * dict!(3) -> (1, 2, 3,), dict!(3) -> (4, 5,) + * + * Операторы ?! и !? эквивалентны и возвращают текущие данные без перемещения указателя итератора (IteratorData) и не принимают аргументов. + * Остальные итераторы можно вызвать либо без скобок, либо с аргментами в скобрках. Вызов без аргументов зарпрешщен + * (чтобы не пересекаться с логикой копирования объектов и не делать для итераторов аругменты по умолчанию) + * + * Оператор ?? создает итератор и сразу его выполняет, возвращая все значения + * в виде элементов словаря, т.е. аналог последовательности ?(LINQ); !(:Int64.__max__); + * + * Оператор !! без аргументов - сбрасывает итератор в начальное состояние (IteratorReset), + * Обператор !! с аргументами выполняется как ! с аругментами, но с начла коллекции. + + diff --git a/docs/ops.md b/docs/ops.md new file mode 100644 index 00000000..ad1017e5 --- /dev/null +++ b/docs/ops.md @@ -0,0 +1,168 @@ +# Операторы и управляющие конструкции + +## Создания объектов и присвоения новых значений +Для создания объектов и присвоения им новых значений в NewLang используется сразу три разных оператора: +- **::=** - используется только для создания новых объектов, а если объект с таким именем уже существует, то генерируется ошибка. +- **:=** - используется для тех же целей, но если объект с таким именем уже существует, то ошибки не происходит, а новое значение присваивается уже существующему объекту. +- **=** - применяется только для присвоения значения уже существующим объектам, и если объект с указанным именем отсутствует, то тоже происходит ошибка выполнения. + +Использование трех разных операторов для создания/изменения объектов позволяет более гибко контролировать подобные операции и выявлять логические ошибки в коде на более раннем этапе. Если же не требуется строго контролировать момент создание объектов и присвоения им значений, можно пользовать есдинственным оператором **:=**. + +``` +var ::= 1.0; # Создать новую переменную var без явного указания типа +var = 100; # Присвоить новое значение уже существующей переменной +printf := :Pointer('printf(format:FmtChar, ...):Int32'); /* Создать новый или переопределить существующий объект printf */ +``` + +### Присваивание значения сразу нескольким переменным и оператор распаковки словаря +*NewLang* поддерживает операцию присваивания сразу нескольким переменным, которые должны быть перечислены через запятую слева от оператора присвоения. С правой стороны от оператора присвоения может находится одно или несколкьо значений или оператор распаковки словаря **...** (многоточие). Оператор распаковки словаря можно использовать и при передаче аргументов в функцию. + +Причем словарь может быть указан и с левой стороны от оператора присвоения и таким образом можно записать самый простой способ перебора всех его элементов: `item, dict := ... dict;`, т.е. когда цикле первый элемент словаря сохраняется в переменую item, а из самого словаря удалется. + + +## Арифметические операторы + +Все операторы имеют парный аналог с присвоением значения: +- **+** и **+=** — сложение арифметических типов данных; +- **-** и **-=** — вычитание арифметических типов данных; +- **/** и **/=** — деление (результат число с плавающей точкой); +- **//** и **//**= — целочисленное деление с округлением к меньшему числу (как в Python); +- **\*** и **\*=** — умножение; +- **\*\*** и **\*\*=** — возведение в степень (он же используется и для повторения текстовых строк); + +## Операторы сравнения: +- **<**, **>**, **<=**, **>=** — классические для сравнения скаляров +- **==** и **!=** — операторы сравнения с автоматическим приведением совместимых типов для любых объектов +- **===** и **!==** — операторы точного сравнения для любых объектов (автоматического приведения типов не выполняется) + + +## Проверка типа (имени класса объекта): + +Для оператора проверки имени класса объекта используется символ тильда ~. Он немного похож на оператор instanceof в Java. Левым операндом должен быть проверяемый объект, а правым — проверяемый тип, который можно указать строкой литералом, переменной строкового типа или именем проверяемого класса непосредственно. Результатом операции будет истина, если правый операнд содержит название класса проверяемого объекта или он присутствует в иерархии наследования. + +``` + name := "class"; # Строковая переменная с именем класса + var ~ name; + var ~ :class; # Имя типа + var ~ "class"; # Строка литерал с именем типа +``` + +## Утиная типизация + +Оператор утиной типизации, два символа тильны ~~ — приблизительный аналог функции isinstance() в Python, который для простых типов сравнивает непосредственную совместимость типа левого операнда по отношению к правому. А для словарей и классов в левом операнде проверяется наличие всех имен полей, присутствующих у правого операнда, т.е.: + +``` + (field1=«value», field2=2,) ~~ (); # Истина (т. е. левый операнд словарь) + (field1=«value», field2=2,) ~~ (field1=_); # Тоже истина (т. к. поле field1 присутствует у левого операнда) + (field1=«value», field2=2,) ~~ (not_found=_); # Ложь, т.к. поле not_found у левого операнда отсутствует +``` + +Строгая утиная типизация **~~~** — для простых типов сравнивается идентичности типов без учета совместимости, а для составных типов происходит сравнение всех свойств с помощью оператора строгого равенства. Для данной операции, пустой тип совместим только с другим пустим типом. + +# Управляющие конструкции + +К управляющим конструкциям языка NewLang относятся условный оператор, два вида циклов, оператор оценки выражения, оператор прерывания последовательности выполнения команд и перехват прерывания. Операторы проверки условий всегда указываются в квадратных скобках, а последовательность команд для выполнения — в фигурных. + +## Условный оператор + +В качестве оператора проверки условия используется синтаксическая конструкция, соответствующая по смыслу термину «следует», т.е. тире и угловая скобка **->** или с двумя тире для большей наглядности **-->**. Такая запись условного оператора очень похожа на математическую и легко объединяется в последовательности для проверки множественных условий вида «else if». + +В общем случае условный оператор имеет вид: **[** условие **] --> {** действие **};** или c условием иначе **[** условие **] --> {** действие **}, [_] --> {** действие иначе **};** + +Для наглядности записанный с отступами: +``` + [ условие1 ] -> { действие1 }, + [ условие2 ] -> действие2, + [ условие3 ] -> действие3, + [_] -> {действие_иначе}; +``` + +# Оценка выражения + +Синтаксическая конструкция с помощью которой реализуется аналог оператора switch выглядит следующим образом: +``` + [ $var ] ==> { + [1] -> { code }; # Выполнится проверка условия $var == 1 + [1, 2] -> { code }; # Выполнится проверка условия ($var == 1 || $var == 2) + [_] -> { code default }; # Ветка условия иначе + }; +``` +Что очень похоже на Pattern Matching, но все же не является сопоставлением с образцом, а скорее более краткая запись множественого оператора сравнения Так как в качестве оператора для оценки могут быть использован любые имеющиеся операторы сравнения на равенство: +- **==>** — проверка на равенство с приведением типов; +- **===>** — проверка на точное равенство; +- **~>** — проверка типа (имени класса); +- **~~>** — утиная типизация; +- **~~~>** — строгая утиная типизация. + +Но если в качестве оператора сравнения использовать оператор утиной типизации, то оценка выражения превращается в классический Pattern Matching: +``` + $value := (f1=1, f2="2",); + [ $value ] ~~~> { + [ (f1=_, ), (f1=_, f2=0, ) ] -> { code }; # Поле f2 отсутствует или число + [(f1=_, f2="",), (f1=_, f2='',)] -> { code }; # Поле f2 строка + [_] -> { code default }; # Код по умолчанию + }; +``` + +# Операторы циклов + +Для указания операторов циклов используются управляющие **<<->>** или **<<-->>** между условием цикла, проверкой логического выражения, которое указывается в квадратных скобках и телом цикла. В зависимости от взаимного расположения условия и тела, цикл может быть с предусловием (while) или постусловием (do while): +``` + [условие while] <<->> { + тело цикла while + }; + + { + тело цикла do while + } <<-->> [условие do while]; +``` + +Привер реализации цикла foreach для суммирования всех элементов словаря (или одномерного тензора) с использованием оператора раскрытия списка: +``` + summa := 0; + dict := (1,2,3,4,5,); + [ dict ] <<-->> { # Условие цикла, пока есть данные + item, dict := ... dict; # Результат оператора распаковка словаря - первый его элемент перемещается в item + summa += item; # Вычисление суммы всех элементов словаря + }; +``` + +## Операторы прерывания выполнения (оператор возврата) + +В качестве оператора прерывания/возврата используется два символа минус --. Оператор позволяет прервать выполнение последовательности команд и/или вернуть данные из текущей функции/блока кода и является самым близким аналогом оператора return и throw одновременно. Для того чтобы вернуть данные, их необходимо указать между двумя операторами прерывания, т.е. --100--; # Вернуть указанное значение. Если возвращаемое значение не указано явно, то будет возвращено значение None. + +## Следование (блок кода/лямбда функция) + +Алгоритмическая конструкция, которая отвечает последовательное выполнение нескольких команд/операторов и возвращающая результат выполнения последнего из них. Также, результатом выполнения может быть значение, которое возвращается с помощью оператора прерывания (возврата). Это очень похоже на классическую лямбда функцию, только она выполняется сразу во время определения, а в переменную сохраняется уже результат её выполнения. + +Следование без перехвата прерывания оформляется в виде последовательности обычных и фигурных скобок, т.е. (){ run code }; или тоже самое, но сохраняет результата выполнения в переменной: $result := (){ run(); code() };. Но если внутри такой функции будет выполнен оператор прерывания, то она никогда вернет управления и не сохранит возвращаемое значение в переменой $result! + +Чтобы перехватывать прерывания, в том числе и возвращаемые значения, необходимо использовать конструкция следования с перехватом прерываний, которая оформляется в виде последовательности обычных и двойных фигурных скобок, т.е. $error := (){{ run(); error();code() }};. Такая конструкция перехватывает все возвраты и прерывания, если они возникают во время выполнения последовательности команд. В этом случае любой результат будет сохранен в переменной $error как при нормальном завершении, так и в случае возникновения ошибки. + +Для более тонкой настройки перехвата прерываний следует использовать типизированную конструкцию, когда в явном виде указывается, какие типы прерываний следует перехватывать. $runtime := (){{ run(); error(); code() }}:ErrorRuntime;. Такая конструкция вернет результат только в случае успешного завершения (когда с помощью оператора прерывания возвращается не типизированное значение, например, --"Строка"--;), или при создании прерывания с указанием конкретного типа --:ErrorRuntime("Описание ошибки")--;. А вот при возникновении любого другого типизированного прерывания, значение перехвачено не будет и все отработает как самый первый вариант, т.е. без перехвата прерывания и без сохранения возвращаемого значения в переменную. + +## Стратегия обработки ошибок + +Обработка ошибок состоит из комбинации двух элементов: оператора прерывания выполнения с указанием типа возвращаемого значения и алгоритмической конструкции следование с возможностью перехвата прерывания заданного типа. + +Это немного отличается от классического варианта обработки исключений, который в обычных языках программирования обычно оформляется ключевыми словами try… catch… finally с различными вариациями. Ведь основная цель подобных синтаксических конструкций — выделить участок кода, где возможно возникновение ошибки, перехватить и обработать правильный тип данных (исключений), т.к. NewLang не делает различий между операторами возврата и генерации исключения. + +Подход к обработке исключений следующий: + +Программный код, который может привести к ошибке, заключается в двойные фигурные скобки, а результат выполнения такого блока кода присваивается переменной. После этого анализируется возвращенное значение, например, оператором сравнения по образцу: + +``` +$result := (){{ # начало аналога блока try + $value := call_or_exception1(); + [условие1] -> { -- :Error -- }; + [условие2] -> { -- $value -- }; + $value := call_or_exception2(); +}}; # конец аналога блока try + +[$result] ~> { # Для сравнения по образцу использовать оператор проверки типа (имени класса) + [:ErrorParser] -> {Код обработки ошибок парсера}; + [:ErrorRunTime] -> {Код обработки ошибок времени выполнения}; + [:Error] -> { Код обработки остальных ошибок }; + [_] -> { Обработка нормальных данных $value без ошибок }; +}; +``` \ No newline at end of file diff --git a/docs/syntax.md b/docs/syntax.md index 88a30945..02ddc2d4 100644 --- a/docs/syntax.md +++ b/docs/syntax.md @@ -1,50 +1,42 @@ # Синтаксис NewLang -При разработке синтаксиса я старался придерживаться уже сложившихся в IT индустрии правил, чтобы не генерировать множественных смыслов, которые будут зависеть от контекста. - -**Основы** +## Основы - Операторы разделяются точкой с запятой «;». -- Отступы и переводы строк игнорируются (очень хотелось иметь возможность автоматического форматирование кода). -- Многострочные комментарии в исходном коде соответствуют стилю С/С++ и должны располагаться между символами /* и */. Вложенность многострочных комментариев не поддерживается. +- Отступы и переводы строк игнорируются. - Однострочные комментарии начинаются с символа «#» до перевода строки, что соответствует комментариям в стиле Python и Bash. +- Многострочные комментарии в соответствуют стилю С/С++ и должны располагаться между символами /* и */. Многосточные комментарии могут быть вложенными. - Последовательность команд, которая должна выполняться как единое целое, заключается в фигурные скобки «{}». -- Программные вставки расширенного синтаксиса на языке реализации заключается в фигурные скобки со знаком процента %{ /* тут может быть любой код на C/C++*/ %}, как в лексерах lex и flex. +- Программные вставки на языке реализации заключается в фигурные скобки со знаком процента %{ /* тут может быть любой код на C/C++*/ %} (такой синтаксис соотвествсует принятому в лексерах). -# Создания объектов и присвоения новых значений +## Идентификаторы объектов и модификаторы -Для создания объектов и присвоения им новых значений в NewLang используется сразу три разных оператора: -- **::=** используется только для создания новых объектов, а если объект с таким именем уже существует, то генерируется ошибка. -- **:=** используется для тех же целей, но если объект с таким именем уже существует, то ошибки не происходит, а новое значение присваивается уже существующему объекту. -- **=** применяется только для присвоения значения уже существующим объектам, и если объект с указанным именем отсутствует, то тоже происходит ошибка выполнения. +В качестве идентификаторов можно использовать буквы, цифры и знаки подчеркивания в любых комбинациях, при условии, что первый символ идентификатора не является цифрой. -Использование трех разных операторов для создания/изменения объектов позволяет более гибко контролировать подобные операции и выявлять логические ошибки в коде на более раннем этапе. +В *NewLang* существует возможность указания назначение, область видимости и времени жизни объекта с помощью модификатора — специального символа перед именем переменной. Это может показаться немного похожим на венгерскую нотацию, но в отличие от нее, модификатор не имеет отношения к типу объекта и не является частью имени идентификатора. К тому же в качестве модификаторов используется строго определённые символы, назначение которых определено заранее. -``` -var ::= 1.0; # Создать новую переменную var без указания типа -var = 100; # Присвоить новое значение уже существующей переменной -printf := @import('printf(format:FmtChar, ...):Int'); /* Создать новый или переопределить объект printf, который будет результатом выполнения глобальной функции @import */ -``` +- **$** — в начале имени обозначает локальную переменную, время жизни которой ограничено текущей областью видимости и при её завершении локальная переменная уничтожается. +- **@** — обозначает глобальную переменную, а сам объект сохраняет свое состояние даже после выхода из текущей области видимости. +- **:** — двоеточие вначале идентификатора используется в качестве модификатора для указания имени типа данных. +- **\\** — обратная коса черта вначале идентификатора используется в качестве модификатора для указания имени макроса. -# Идентификаторы объектов и модификаторы +Семантика обращения к аргументам функций очень похоже на работу с аргументами в bash скриптах, где $1 или $arg — порядковый номер или имя аргумента (происходит обращение к локальным переменным в текущей области видимости). -В качестве идентификаторов можно использовать буквы, цифры и знаки подчеркивания в любых комбинациях, при условии, что первый символ идентификатора не является цифрой. -В NewLang существует возможность указания области видимости и времени жизни объекта с помощью модификатора — специального символа перед именем переменной. Это может показаться немного похожим на венгерскую нотацию, но в отличие от нее, модификатор не имеет отношения к типу объекта и не является частью имени идентификатора. К тому же в качестве модификаторов используется строго определённые символы, назначение которых определено заранее. +## Использование модификаторов является обязательным в следующих случаях: + +- При указании имени макроса или типа данных, так как макросы и типы всегда создаются в глобальной области видимости, а их символьные имена должны быть уникальными. +- При обращении к объектам NewLang внутри программных вставок кода на языке реализации, так как они используется как маркеры при поиске идентификаторов NewLang в коде С/С++. + +В остальных случаях, для обращения к переменным указывать их модификаторы необязательно. И если при обращении к объекту модификатор не указан, то сперва ищется локальная переменная, а потом глобальная с таким же именем. Причем, локальная переменная будет перекрывать глобальную. + +Так же следует иметь в виду, что компилятор может генерировать код для прямого обращения к локальным объектам уже на этапе компиляции, тогда как для обращения к глобальным объектам, или если модификатор области видимости отсутствует, компилятор вынужден каждый раз встраивать в код runtime вызов функции поиска объекта в глобальной таблице символов по его имени. + -- **$** - в начале имени обозначает локальную переменную, время жизни которой ограничено текущей областью видимости и при её завершении локальная переменная уничтожается. -- **@** - обозначает глобальную переменную, а сам объект сохраняет свое состояние даже после выхода из текущей области видимости. -- **:** - двоеточие вначале имени используется в качестве модификатора для указания типа. -Семантика обращения к аргументам функций очень похоже на работу с аргументами в bash скриптах, где $1 или $arg — порядковый номер или имя аргумента (происходит обращение к локальным переменным в текущей области видимости). -### Использование модификаторов является обязательным только в двух случаях: -- При создании нового типа данных, так как типы всегда создаются в глобальной области видимости, а их символьные имена должны быть уникальными. -- При обращении к объектам NewLang внутри программных вставок кода на языке реализации, так как они используется как маркеры при поиске идентификаторов NewLang в коде С/С++. -В остальных случаях, для обращения к переменным указывать их модификаторы не обязательно. И если при обращении к объекту модификатор не указан, то сперва ищется локальная переменная, а потом глобальная с таким же именем. Причем, локальная переменная будет перекрывать глобальную. -Так же следует иметь в виду, что компилятор может генерировать код для прямого обращения к локальным объектам уже на этапе компиляции, тогда как для обращения к глобальным объектам, или если модификатор области видимости отсутствует, компилятор вынужден каждый раз встраивать runtime вызов функции поиска объекта в глобальной таблице символов. # Система типов @@ -68,7 +60,7 @@ printf := @import('printf(format:FmtChar, ...):Int'); /* Создать новы З.Ы. И даже зная об этом, все равно умудрился недавно словить баг с отрицательными индексами у словарей! -Имена встроенных арифметических типов говорят сами за себя: Char, Short, Int, Long, Float, Double, ComplexFloat, ComplexDouble. Отдельным типом идет логический тип Bool, который может принимать значения только 0 или 1 (false/true соответственно), и в зависимости от выполняемой операции может быть отнесен к целочисленным типам, так и не входить в их состав (данный подход интерпретации логического типа данных был взят из библиотеки Torch). +Имена встроенных арифметических типов говорят сами за себя: Int8, Int16, Int32, Int64, Float32, Float64, Complex32, Complex64. Отдельным типом идет логический тип Bool, который может принимать значения только 0 или 1 (false/true соответственно), и в зависимости от выполняемой операции может быть отнесен к целочисленным типам, так и не входить в их состав (данный подход интерпретации логического типа данных был взят из библиотеки Torch). ``` // Treat bool as a distinct "category," to be consistent with type promotion // rules (e.g. `bool_tensor + 5 -> int64_tensor`). If `5` was in the same @@ -81,7 +73,7 @@ printf := @import('printf(format:FmtChar, ...):Int'); /* Создать новы // * `uint8_tensor + 5 -> int64_tensor` would be undesirable. ``` -В будущем планируется добавить классы чисел для длинной арифметики и дробей, для чего зарезервированы названия типов BigNum, Currency и Fraction. +В будущем планируется добавить классы чисел для длинной арифметики и дробей, для чего зарезервированы названия типов BigNum, Currency и Rational. Доступ к элементам тензора происходит по целочисленному индексу, который начинается с 0. Для многомерного тензора, индексы элемента перечисляются в квадратных скобках через запятую. Поддерживается доступ к элементам через отрицательный индекс, который обрабатывается точно так же, как в Python (-1 последний элемент, -2 предпоследний и т.д.). @@ -89,10 +81,10 @@ printf := @import('printf(format:FmtChar, ...):Int'); /* Создать новы *Примеры:* ``` -$var_char := 123; # Тип Char выводится автоматически -$var_short := 1000; # Тип Short выводится автоматически +$var_char := 123; # Тип Int8 выводится автоматически +$var_short := 1000; # Тип Int16 выводится автоматически $var_bool := [0, 1, 0, 1,]; # Тензор из 4 элементов. Тип Bool выводится автоматически -$tensor[10,10]:Int := 1; # Тензор Int размером 2x2 инициализированный 1 +$tensor[10,10]:Int32 := 1; # Тензор Int32 размером 2x2 инициализированный 1 $scalar := $tensor[5,5]; # Присвоить скаляру значение указанного элемента тензора ``` @@ -131,7 +123,7 @@ $result := $template("шаблон", name = "Строка"); # result = "Стр ## Перечисление, структура и объединение *:Enum*, *:Struct* и *:Union* — это такие же словари, только на их элементы накладываются определнные ограничения. Каждый эелемент должен иметь уникальное имя, а его тип данных должен быть простым, т.е. числом или строкой фиксированного размера. -, соотвествующие типах имеют уникальные имена и целочисленные значение, которое явно указывается при определении или вычисляется автоматически (на единицу больше предыдущего элемента). У перечислений тип значения указывается сразу после закрывающей скобки через двоеточие (ONE=1, TWO=, THREE=): Int. +, соотвествующие типах имеют уникальные имена и целочисленные значение, которое явно указывается при определении или вычисляется автоматически (на единицу больше предыдущего элемента). У перечислений тип значения указывается сразу после закрывающей скобки через двоеточие (ONE=1, TWO=, THREE=): Int32. ## Классы @@ -198,8 +190,8 @@ func_xor(arg1, arg2) :^^= arg1==3, arg2 > 0; # Простая чистая фу ``` $var := _; # Создать не инициализированную переменную $var2 := var; # Ошибка!!! Нельзя прочитать неинициализированную переменную var -$var = 1000; # У переменной будет тип Short (минимальный размер для хранения значения) -$var = 0,5; # Ошибка!!! Short ← Float не совместимы +$var = 1000; # У переменной будет тип Int16 (минимальный размер для хранения значения) +$var = 0,5; # Ошибка!!! Int16 ← Float32 не совместимы $var = _; # Очистить значение переменной $var = 0,5; # Теперь можно, т. к. None совместим с любым типом ``` @@ -223,7 +215,7 @@ $tensor[…, 0] = 0; # Обнулить все первые элементы в ### Явное приведение типов Несмотря на динамическую типизацию языка, если тип переменной указан явно, то автоматическое приведение типов не выполняется, и чтобы присвоить переменой значение не совместимого типа, требуется явное преобразование. -Так как символьные названия типов относятся к деталям реализации, то явное преобразование в конкретный тип данных производится с помощью вызова функции с именем типа, т.е. :Bool(), :StrWide(), :Long() и т.д. +Так как символьные названия типов относятся к деталям реализации, то явное преобразование в конкретный тип данных производится с помощью вызова функции с именем типа, т.е. :Bool(), :StrWide(), :Int64() и т.д. Для преобразования любого типа данных в строку ещё можно использовать оператор конкатенации строк, которой преобразует любой тип данных в строковое представление. Но, так как строковых типов два (байтовые и широкие строки), то тип строки определяется первым аргументом в операторе конкатенации/сцепления **++**. Также преобразовать любое значение в строковое можно с помощью строки-шаблона. @@ -241,52 +233,52 @@ val := 12345; # Число ``` > tstr := :Tensor("Тест"); # Создать тензор из строки широких символов -[1058, 1077, 1089, 1090,]:Int +[1058, 1077, 1089, 1090,]:Int32 > t2 := :Tensor[2,2]("Тест"); # Тоже самое, но тензор указанной размерности [ [1058, 1077,], [1089, 1090,], -]:Int +]:Int32 > :StrWide(tstr) # Создать символьную строку из тензора Тест -> :Double(t2) # Изменить тип данных тезора без изменения размерности +> :Float64(t2) # Изменить тип данных тезора без изменения размерности [ [1058, 1077,], [1089, 1090,], -]:Double +]:Float64 -> t3 := :Char[4]( t2 ) # Изменить размерность тензора и его тип (в данном случае с частичной потерей данных) -[34, 53, 65, 66,]:Char +> t3 := :Int8[4]( t2 ) # Изменить размерность тензора и его тип (в данном случае с частичной потерей данных) +[34, 53, 65, 66,]:Int8 >:Tensor( (1,2,3,) ); # Тензор из словаря -[1, 2, 3,]:Char +[1, 2, 3,]:Int8 >:Tensor( 'first second' ) # Байтовая строка в тензор -[102, 105, 114, 115, 116, 32, 115, 101, 99, 111, 110, 100,]:Char +[102, 105, 114, 115, 116, 32, 115, 101, 99, 111, 110, 100,]:Int8 >:Tensor( (first='first', space=32, second='second',) ) # Получаем тензор из словаря с такими же данными -[102, 105, 114, 115, 116, 32, 115, 101, 99, 111, 110, 100,]:Char +[102, 105, 114, 115, 116, 32, 115, 101, 99, 111, 110, 100,]:Int8 ->:Double[10,2]( 0, ...) # Тензор заданного формата с нулями, где многоточие повторяет последние указанные данные до получения тензора требуемого размера +>:Float64[10,2]( 0, ...) # Тензор заданного формата с нулями, где многоточие повторяет последние указанные данные до получения тензора требуемого размера [ [0, 0,], [0, 0,], [0, 0,], [0, 0,], [0, 0,], [0, 0,], [0, 0,], [0, 0,], [0, 0,], [0, 0,], -]:Double +]:Float64 ->:Int[3,2]( ... rand() ...) # Тензор со случайными данными, где между многоточиями указана функция, которую следуюет вызывать каждый раз при получении нового элеменета тензора +>:Int32[3,2]( ... rand() ...) # Тензор со случайными данными, где между многоточиями указана функция, которую следуюет вызывать каждый раз при получении нового элеменета тензора # Пришлось придумывать новую конструкцию, т.к. многоточие перед именем, это оператор раскрытия словаря, а многоточие после имени, это повторение последнего значения до конца заданной размерности. [ [1804289383, 846930886,], [1681692777, 1714636915,], [1957747793, 424238335,], -]:Int +]:Int32 ->:Int[5,2]( 0..10 ); # Создание тензора из диапзона +>:Int32[5,2]( 0..10 ); # Создание тензора из диапзона [ [0, 1,], [2, 3,], [4, 5,], [6, 7,], [8, 9,], -]:Int +]:Int32 >:Tensor( 0..0.99..0.1 ); # Или даже так -[0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9,]:Double +[0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9,]:Float64 ``` diff --git a/docs/types.md b/docs/types.md new file mode 100644 index 00000000..ec8a67cc --- /dev/null +++ b/docs/types.md @@ -0,0 +1,251 @@ +# Система типов NewLang +Так *NewLang* является языком с динамической типизацией, то явное указание типа не влияет на размер памяти, занимаемой переменной и в основном определяет логические ограничения на возможность присвоения переменной значения другого типа. + +Информация о типах используется при проверке их совместимости, когда существующему объекту присваивается значение другого типа. Такая операция возможна только когда типы совместимы между собой и допускают автоматическое приведение. Это справедливо как во время парсинга/компиляции исходного теста, так и во время выполнения в режимах интерпретатора и/или скомпилированного файла. + +## Простые типы + +### Арифметические типы данных + +Арифметические типы данных являются тензорами (кроме рациональных чисел) — массивами одного типа с произвольным количеством измерений и одинаковым размером столбцов в каждом. Единичное число тоже тензор нулевого размера. + +Поддерживаются только знаковые целые числа, т.к. в беззнаковых числах особая нужда отсутствует, а проблем с ними можно найти очень много на ровном месте. + +Проблемы беззнаковых чисел (из интернета): + +> Во-первых, вычитание двух беззнаковых чисел, например 3 и 5. 3 минус 5 равно 4294967294, т.к. -2 не может быть представлено как беззнаковое число. > Во-вторых, непредвиденное поведение может возникнуть при смешивании целочисленных значений со знаком и без знака. С++ может свободно преобразовывать числа со знаком и без знака, но не проверяет диапазон, чтобы убедиться, что вы не переполняете свой тип данных. +В C++ всё же есть несколько случаев, когда можно (или необходимо) использовать беззнаковые числа. Во-первых, числа без знака предпочтительнее при работе с битами. Во-вторых, использование беззнаковых чисел связанных с индексацией массивов. + +Но это не мой случай, так как индекс может быть отрицательным и даже не числом, а диапазоном или многоточием. + +*З.Ы. И даже зная об этом, все равно умудрился недавно словить баг с отрицательными индексами у словарей!* + +Имена встроенных арифметических типов: Int8, Int16, Int32, Int64, Float16, Float32, Float64, Complex16, Complex32, Complex64. Отдельным типом идет логический тип Bool, который может принимать значения только 0 или 1 (false/true соответственно), и в зависимости от выполняемой операции может быть отнесен к целочисленным типам, так и не входить в их состав (данный подход интерпретации логического типа данных был взят из библиотеки Torch). +``` +// Treat bool as a distinct "category," to be consistent with type promotion +// rules (e.g. `bool_tensor + 5 -> int64_tensor`). If `5` was in the same +// category as `bool_tensor`, we would not promote. Differing categories +// implies `bool_tensor += 5` is disallowed. +// +// NB: numpy distinguishes "unsigned" as a category to get the desired +// `bool_tensor + 5 -> int64_tensor` behavior. We don't, because: +// * We don't want the performance hit of checking the runtime sign of Scalars. +// * `uint8_tensor + 5 -> int64_tensor` would be undesirable. +``` + +Доступ к элементам тензора происходит по целочисленному индексу, который начинается с 0. Для многомерного тензора, индексы элемента перечисляются в квадратных скобках через запятую. Поддерживается доступ к элементам через отрицательный индекс, который обрабатывается точно так же, как в Python (-1 последний элемент, -2 предпоследний и т.д.). + +Литерал тензор в тексте программы записывается в квадратных скобках с обязательной завершающей запятой, т.е. [1, 2,] — это литерал одномерный тензор из двух чисел. После закрывающей скобки тип тензора может быть указан в явном виде. Если тип не указан, то он выводится автоматически на основании указанных данных и выбирается минимально возможный байтовый размер, который позволяет сохранить все значения без потери точности. + +Так же существует отдельный тип для представления рациональных чисел неограниченной точности. Они записываются в форме обыкновенной дроби, в которой числитель должен быть целым числом, а знаменатель натуральным. В качестве разделителя дроби используется обратная косая черта, т.е. 1\1 - рациональное число 1, -5\1 - запись рационального числа -5 и т.д. + +Примеры: +``` +$var_char := 123; # Тип Int8 выводится автоматически +$var_short := 1000; # Тип Int16 выводится автоматически +$var_bool := [0, 1, 0, 1,]; # Тензор из 4 элементов. Тип Bool выводится автоматически +$tensor[10,10]:Int32 := 1; # Тензор Int32 размером 2x2 инициализированный 1 +$scalar := $tensor[5,5]; # Присвоить скаляру значение указанного элемента тензора +``` + + +## Строки +Поддерживаются два типа строк, StrWide — символьные (широкие) и StrChar — байтовые. Различия между ними заключается в типе единичного элемента. У символьных строк единичным элементом является широкий символ wchar_t, а у байтовой строки единичным элементом является один байт (точнее Int8, т.е. байт со знаком). Символьные строки литералы в исходном тексте записывается в «двойных кавычках», а байтовые строки в 'одинарных кавычках'. + +Количество элементов символьной строки возвращается в широких символах, а размер байтовой строки в байтах, поэтому и обращение к элементу строки по индексу происходит соответственно либо к символу, либо к байту. + +Важный момент. К любой переменной можно обратиться так же, как к функции (записав после её имени круглые скобки). Результатом этой операции будет создание копии/клона объекта. Причем некоторые типы (словари, классы и символьные строки) можно использовать в качестве шаблона при создании копии объекта с модифицированными свойствами, если новые и/или изменяемые значения указать в скобках, как аргументы при вызовах функций. Так, если при создании копии в скобках указать набор новых данных, то результирующая копия будет содержать уже измененные данные. + +Например: +``` +$template := "${name} $1"; # Обычная строка широких символов +$result := $template("шаблон", name = "Строка"); # result = "Строка шаблон" +``` + +## Системные типы + +### :Pointer — указатель на системную область памяти или нативную функцию + +Так как любой программе приходится взаимодействовать с внешним миром, то по неволе приходится закладывать возможность использования других библиотек и системы типов данных, и для этих целей служит тип *:Pointer*. Он создается при импорте функций из внешних библиотек и вручную его создать нельзя. Но можно вывести его значение, например для отладки. + +### :Plain — указатель на представление данных в бинарном виде + +Для взаимодействия с внешними библиотеками требуется еще и обмен данными. И для этих целей служит тип данных *:Plain* — который также является указателем, но на двоичное представление данных в области памяти. Конечно, если их можно представить в виде одного фрагмента. + + + +## Составные типы данных: + +### Словарь + +Словарь (*:Dictionary*) — набор данных произвольного типа с доступом к отдельным элементам по целочисленному индексу или по имени элемента при его наличии (он похож и на tuple и на структуру одновременно). Словари от тензоров отличаются тем, что являются одномерными, но каждый элемент может содержать произвольное количество элементов любого типа, в том числе и другие словари. + +Доступ к элементам словарей происходит по имени элемента, которое записывается через точку от имени переменной, либо по целочисленному индексу. Индекс также начинается с 0 и как у тензоров и тоже может быть отрицательным. + +Литерал с типом «словарь» в тексте программы записывается в круглых скобках с обязательной завершающей запятой, т. е. (,) — пустой словарь, (1, 2= «2», name=3,). + +### Перечисление, структура и объединение + +*:Enum*, *:Struct* и *:Union* — это такие же словари, только на их элементы накладываются определённые ограничения. Каждый элемент должен иметь уникальное имя, а его тип данных должен быть простым, т.е. числом или строкой фиксированного размера. Эти типы данных так же относятся к группе *:Plain* и могут быть представлены в двоичном виде в одной области мишинной памяти. + +### Классы + +Класс (реализован частично) — тип данных, с помощью которого реализуется один из принципов ООП — наследование. При создании экземпляра класса создается новая переменная, у которой сохраняется информацию о своем родителе и которая наследует от него свойства и методы. Тип данных *:Class* аналогичен словарю, но все свойства обязаны иметь имена (хотя доступ к свойствам класса по индексу так же возможен). + + +## Функции + +Синтаксис *NewLang* поддерживать несколько типов функций (а в будущем и методов классов): обычные функции, чистые функции и простые чистые функции. + +Для всех типов функций поддерживаются аргументы по умолчанию. При создании функции, её аргументы указываются как в Python, т.е. вначале идут обязательные аргументы, потом аргументы со значениями по умолчанию, где имя аргумента отделяется от его значения по умолчанию знаком равно =. Если функция допускает обработку произвольного количества аргументов, то последним в списке параметров указывается многоточие ... (три точки подряд) . + +### Обычная функция + +Обычная функция — такие функции являются именно обычными функциями в понимании С/С++. Внутри них можно писать совершенно любой код, включая проверки условий, циклы, вызовы других функций и т.д. + +Внутри обычной функции можно обращаться к локальным и глобальным объектам, и они могут содержаться вставки на языке реализации*, например, для вызова функций из внешних библиотек. + +Вставки на языке реализации оформляются в виде **%{** ... **%}** и могут содержать любой текст на С/С++, а прямо из него можно обращаться к локальным и глобальным объектам NewLang так же, как и в обычном синтаксисе, указывая первым символом имени соответствующий модификатор (*$* для локальных объектов и *@* для глобальных). + +Технически, такая программная вставка просто переносится трансплайтером непосредственно в исходный текст генерируемого файла, а все идентификаторы *NewLang* специальным образом декорируются (добавляются специальные маркеры для их идентификации), после этого исходный текст подается на вход обычному компилятору С++. Для локальных объектов трансплайтер может генерировать код для прямого доступа к объекту на этапе компиляции, а для работы с глобальными объектами вынужден использовать runtime вызовы функции поиска в таблице символов. +*** +*) — Программные вставки на языке реализации обрабатываются только во время компиляции + +Например: +``` +print(str) := { + %{ + printf("%s", static_cast($str)); /* Прямой вызов С функции */ + %} +}; +``` + +## Чистые функции + +Чистая функция — это тоже обычная функция, только в том смысле, какой в него вкладывает функциональное программирование. Создание чистой функции происходит с помощью операторов **:-** или **::-**, а сам оператор заимствован из языка Пролог. У чистой функции отсутствует доступ к контексту и глобальным переменным, поэтому она может обрабатывать только те данные, которые были ей переданы в качестве аргументов. + +Программные вставки на языке реализации внутри чистых функций не запрещены и могут использоваться, например, для отладки. Но делается это на страх и риск разработчика. Именно он отвечает за их «чистоту», например при вызове функций из внешних библиотек. + +``` +Sum1(arg1, arg2) :- {$arg1+$arg2;}; # Создать или переопределить простую функцию, которая возвращает сумму аргументов +Sum2(arg1, arg2) ::- {$arg1+$arg2;}; # Тоже самое, но если функция с таким именем уже существует, то будет ошибка +``` + +#### Простые чистые функции + +Простые чистые функции — отдельный класс чистых функций, которые предназначены только для вычисления логического результата (т.е. они являются предикатами) и их отличает упрощенная формой записи. Тело простой чистой функции состоит из последовательности операторов, которые разделяются запятыми и заканчивается, как и любое выражение, точкой с запятой. Все операторы простой чистой функции приводятся к булевому значению, а итоговый результат функции вычисляется по одной из возможных логических операций: **И**, **ИЛИ** и **исключающее ИЛИ**. + +Например: +``` +func_and(arg1, arg2) :&&= arg1==3, arg2 > 0; # Простая чистая функция Логическое И +func_or(arg1, arg2) :||= arg1==3, arg2 > 0; # Простая чистая функция Логическое ИЛИ +func_xor(arg1, arg2) :^^= arg1==3, arg2 > 0; # Простая чистая функция Исключающее ИЛИ +``` + +## Специальные типы данных: + +### Пусто (:None) + +*:None* (пусто) — не содержит значения (точнее имеет одно значение *None*). Указывается в тексте программы как один подчерк «_». Значение *None* имеют не инициализированные переменные и при попытке чтения из такой переменной возникает ошибка. + +Тип переменной может быть явно указан или выведен автоматически из присваиваемого значения. Присвоить новое значение уже инициализированной переменной можно только для совместимого типа, так как неявное преобразование типов не допускаются. + +``` +$var := _; # Создать не инициализированную переменную +$var2 := var; # Ошибка!!! Нельзя прочитать неинициализированную переменную var +$var = 1000; # У переменной будет тип Short (минимальный размер для хранения значения) +$var = 0,5; # Ошибка!!! Short ← Float не совместимы +$var = _; # Очистить значение переменной +$var = 0,5; # Теперь можно, т. к. None совместим с любым типом +``` + +### Диапазон (:Range) + +Диапазон — специальный тип данных, являющейся приблизительным аналогом типа «генератор» в Python. К диапазону можно обращаться как к итератору и он будет поочередно выдавать элементы в указанном интервале с заданным шагом. Диапазон в тексте программы указывается как два или три элемента через две точки, например 1..5 — диапазон от единицы до пяти с шагом по умолчанию 1. В качестве параметров диапазона можно указывать не только литералы, но и имена переменных и даже рациональные числа. Например, 0,1..$stop..0,1 — диапазон от 0,1 до значения, указанного в переменной $stop с шагом 0,1 или 0..1\10 - диапазон рациональных числе от 0 до 10. + +Диапазон целых чисел можно использовать в качестве индекса у тензоров (точнее, у любых объектов, которые допускают доступ к своим элементам по индексу, т.е. тензоры, словари и текстовые строки). Фактический, это поведение аналогично slice в языке Python и array[1:5] в Python означает тоже самое, что и array[1..5] в *NewLang*. + +В качестве индекса у тензоров еще можно указать произвольное количество измерений с помощью многоточия, т.е. +``` +$tensor[…, 0] = 0; # Обнулить все первые элементы в каждом измерении. +``` + + +## Итераторы + +Итераторы в *NewLang*, как и в остальных языках программирования, предназначены для перебора элементов. Но, в отличии от итераторов в С++, итераторы *NewLang* являются самостоятельными объектаим, а не уаказателями на отдельные элементы объекта-контейнера. Итераторы *NewLang* поддерживают фильтрацию элементов по имени или функциональный аналог LINQ за счет использования функций обратного вызова для сравнения элементов во время работы итератора. + +Для работы с итераторами используются следующий синтаксис: + - **?** или **?(** текст **)** - создание итератора без фильтра или с *regex* фильтрацией по имени поля + - **?(** func, args... **)** - создание итератора с использованием функции обратного вызова (аналог LINQ) + - **!** или **!(** количество возвращаемых элементов **)** - перебор элементов итератора + - **?!** или **!?** - получить текущий элемент без перемещение курсора + - **!!** - сбросить указатель итератора в начальное состояние (на первый элемент) + - **??** - создать итератор и сразу его выполнить, возвращая все значения в виде элементов словаря. Это своего рода синтаксический сахар для краткой записи последовательности команд *?*( фильтр ); !(9223372036854775807); + + Так как использование итераторов сложно показать на паре примеров, то подробное описание сделано в виде отдельного материала который можно посмотреть [тут: ](https://newlang.net/iterators.html) + + + +# Преобразование типов + +## Явное приведение типов + +Несмотря на динамическую типизацию языка, если тип переменной указан явно, то автоматическое приведение типов не выполняется, и чтобы присвоить переменой значение не совместимого типа, требуется его явное преобразование. + +Так как символьные названия типов относятся к деталям реализации, то явное преобразование в конкретный тип данных производится с помощью вызова функции с именем типа, т.е. :Bool(), :StrWide(), :Int64() и т.д. + +Примеры: +``` +> tstr := :Tensor("Тест"); # Создать тензор из строки широких символов с автоматическим выводом типа + #(тип Int32 будет на системах с Linux, а под Windows тип тензора будет Int16) +[1058, 1077, 1089, 1090,]:Int32 + +> t2 := :Tensor[2,2]("Тест"); # Тоже самое, но тензор заданной размерности +[ + [1058, 1077,], [1089, 1090,], +]:Int32 + +> :StrWide(tstr) # Создать символьную строку из тензора +Тест + +> :Float64(t2) # Изменить тип данных тезора без изменения размерности +[ + [1058, 1077,], [1089, 1090,], +]:Float64 + +> t3 := :Int8[4]( t2 ) # Изменить размерность тензора и его тип (в данном случае с частичной потерей данных) +[34, 53, 65, 66,]:Int8 + +>:Tensor( (1,2,3,) ); # Тензор из словаря +[1, 2, 3,]:Int8 + +>:Tensor( 'first second' ) # Байтовая строка в тензор +[102, 105, 114, 115, 116, 32, 115, 101, 99, 111, 110, 100,]:Int8 + +>:Tensor( (first='first', space=32, second='second',) ) # Получаем тензор из словаря с такими же данными +[102, 105, 114, 115, 116, 32, 115, 101, 99, 111, 110, 100,]:Int8 + +>:Float64[10,2]( 0, ...) # Тензор заданного формата с нулями, где многоточие повторяет последние указанные данные до получения тензора требуемого размера +[ + [0, 0,], [0, 0,], [0, 0,], [0, 0,], [0, 0,], [0, 0,], [0, 0,], [0, 0,], [0, 0,], [0, 0,], +]:Float64 + +>:Int32[3,2]( ... rand() ...) # Тензор со случайными данными, где между многоточиями указана функция, +# которую следует вызывать каждый раз при получении нового элемента тензора +# +# Тут пришлось придумывать новую синтаксическую конструкцию для вызовы фанкции для каждого нового элемента, +# т.к. многоточие перед идентификатором, это оператор раскрытия словаря, а многоточие после идентификатора, +# это повторение последнего значения до конца заданной размерности. +[ + [1804289383, 846930886,], [1681692777, 1714636915,], [1957747793, 424238335,], +]:Int32 + +>:Int32[5,2]( 0..10 ); # Создание тензора из диапазона +[ + [0, 1,], [2, 3,], [4, 5,], [6, 7,], [8, 9,], +]:Int32 + +>:Tensor( 0..0.99..0.1 ); # Или даже так +[0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9,]:Float64 +``` diff --git a/examples/fact_1000.nlp b/examples/fact_1000.nlp new file mode 100755 index 00000000..1d5ffe9d --- /dev/null +++ b/examples/fact_1000.nlp @@ -0,0 +1,9 @@ +#!../output/nlc --eval + + +@fact := 1\1; # Рациональное число без органичений точности +@mult := 1000..1..-1?; # Получить итератор для множителей из диапазона +[mult?!] <<-->> { # Цикл перемножения, пока не закончатся данные итератора + fact *= mult!; # Получить текущий множитель и перейти на следующий элемент итератора +}; +fact # Вывести итоговый результат 402387260077093773543702433923003985719374864210714632543799910429938512398629020592044208486969404800479988610197196058631666872994808558901323829669944590997424504087073759918823627727188732519779505950995276120874975462497043601418278094646496291056393887437886487337119181045825783647849977012476632889835955735432513185323958463075557409114262417474349347553428646576611667797396668820291207379143853719588249808126867838374559731746136085379534524221586593201928090878297308431392844403281231558611036976801357304216168747609675871348312025478589320767169132448426236131412508780208000261683151027341827977704784635868170164365024153691398281264810213092761244896359928705114964975419909342221566832572080821333186116811553615836546984046708975602900950537616475847728421889679646244945160765353408198901385442487984959953319101723355556602139450399736280750137837615307127761926849034352625200015888535147331611702103968175921510907788019393178114194545257223865541461062892187960223838971476088506276862967146674697562911234082439208160153780889893964518263243671616762179168909779911903754031274622289988005195444414282012187361745992642956581746628302955570299024324153181617210465832036786906117260158783520751516284225540265170483304226143974286933061690897968482590125458327168226458066526769958652682272807075781391858178889652208164348344825993266043367660176999612831860788386150279465955131156552036093988180612138558600301435694527224206344631797460594682573103790084024432438465657245014402821885252470935190620929023136493273497565513958720559654228749774011413346962715422845862377387538230483865688976461927383814900140767310446640259899490222221765904339901886018566526485061799702356193897017860040811889729918311021171229845901641921068884387121855646124960798722908519296819372388642614839657382291123125024186649353143970137428531926649875337218940694281434118520158014123344828015051399694290153483077644569099073152433278288269864602789864321139083506217095002597389863554277196742822248757586765752344220207573630569498825087968928162753848863396909959826280956121450994871701244516461260379029309120889086942028510640182154399457156805941872748998094254742173582401063677404595741785160829230135358081840096996372524230560855903700624271243416909004153690105933983835777939410970027753472000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\1 diff --git a/examples/hello.nlp b/examples/hello.nlp new file mode 100755 index 00000000..2d8ccab4 --- /dev/null +++ b/examples/hello.nlp @@ -0,0 +1,9 @@ +#!../output/nlc --eval + +# Определение функции hello +hello(str) := { + printf := :Pointer('printf(format:FmtChar, ...):Int32'); # Импорт стандартной C функции + printf('%s\n', $str); # Вызов C функции с проверкой типов аргументов по строке формата + $str; +}; +hello('Привет, мир!'); # Вызвать функцию diff --git a/src/nbproject/Makefile-Debug.mk b/src/nbproject/Makefile-Debug.mk index 6cae2677..734317f4 100644 --- a/src/nbproject/Makefile-Debug.mk +++ b/src/nbproject/Makefile-Debug.mk @@ -99,6 +99,11 @@ temp/syntax.temp.txt: ../docs/syntax.md ../docs/syntax.md @echo Выполнение шага пользовательского сборки mkdir temp || pandoc -t plain ../docs/syntax.md > temp/syntax.temp.txt +temp/syntax.temp.txt: ../docs/version.md ../docs/syntax.md + ${MKDIR} -p temp + @echo Выполнение шага пользовательского сборки + mkdir temp || pandoc -t plain ../docs/syntax.md > temp/syntax.temp.txt + ${OBJECTDIR}/builtin.o: builtin.cpp parser.h parser.yy.h pch.h.gch location.hh ${MKDIR} -p ${OBJECTDIR} ${RM} "$@.d" @@ -283,6 +288,7 @@ ${OBJECTDIR}/version.o: version.cpp ${RM} -r ${CND_BUILDDIR}/${CND_CONF} ${RM} temp/syntax.temp.txt ${RM} temp/syntax.temp.txt + ${RM} temp/syntax.temp.txt ${RM} ${RM} ${RM} diff --git a/src/nbproject/Makefile-UnitTest_LLVM.mk b/src/nbproject/Makefile-UnitTest_LLVM.mk index 62faab19..88f764d9 100644 --- a/src/nbproject/Makefile-UnitTest_LLVM.mk +++ b/src/nbproject/Makefile-UnitTest_LLVM.mk @@ -79,11 +79,11 @@ LDLIBSOPTIONS=-L../contrib/libtorch/lib -L/usr/lib/x86_64-linux-gnu -Wl,-rpath,' # Build Targets .build-conf: ${BUILD_SUBPROJECTS} - "${MAKE}" -f nbproject/Makefile-${CND_CONF}.mk ../output/nlc_unit_test + "${MAKE}" -f nbproject/Makefile-${CND_CONF}.mk ../output/nlc_test -../output/nlc_unit_test: ${OBJECTFILES} +../output/nlc_test: ${OBJECTFILES} ${MKDIR} -p ../output - ${LINK.cc} -o ../output/nlc_unit_test ${OBJECTFILES} ${LDLIBSOPTIONS} `llvm-config-13 --libs --ldflags` -fuse-ld=lld-13 -g + ${LINK.cc} -o ../output/nlc_test ${OBJECTFILES} ${LDLIBSOPTIONS} `llvm-config-13 --libs --ldflags` -fuse-ld=lld-13 -g ${OBJECTDIR}/_ext/1e501df/gtest-all.o: ../contrib/googletest/googletest/src/gtest-all.cc ${MKDIR} -p ${OBJECTDIR}/_ext/1e501df diff --git a/src/nbproject/Makefile-variables.mk b/src/nbproject/Makefile-variables.mk index 2e98751d..00987ec5 100644 --- a/src/nbproject/Makefile-variables.mk +++ b/src/nbproject/Makefile-variables.mk @@ -41,8 +41,8 @@ CND_PACKAGE_PATH_UnitTest=dist/UnitTest/GNU-Linux/package/src.tar # UnitTest_LLVM configuration CND_PLATFORM_UnitTest_LLVM=CLang-Linux CND_ARTIFACT_DIR_UnitTest_LLVM=../output -CND_ARTIFACT_NAME_UnitTest_LLVM=nlc_unit_test -CND_ARTIFACT_PATH_UnitTest_LLVM=../output/nlc_unit_test +CND_ARTIFACT_NAME_UnitTest_LLVM=nlc_test +CND_ARTIFACT_PATH_UnitTest_LLVM=../output/nlc_test CND_PACKAGE_DIR_UnitTest_LLVM=dist/UnitTest_LLVM/CLang-Linux/package CND_PACKAGE_NAME_UnitTest_LLVM=src.tar CND_PACKAGE_PATH_UnitTest_LLVM=dist/UnitTest_LLVM/CLang-Linux/package/src.tar diff --git a/src/nbproject/Package-UnitTest_LLVM.bash b/src/nbproject/Package-UnitTest_LLVM.bash index 62718126..c288a7f5 100644 --- a/src/nbproject/Package-UnitTest_LLVM.bash +++ b/src/nbproject/Package-UnitTest_LLVM.bash @@ -13,8 +13,8 @@ CND_BUILDDIR=build CND_DLIB_EXT=so NBTMPDIR=${CND_BUILDDIR}/${CND_CONF}/${CND_PLATFORM}/tmp-packaging TMPDIRNAME=tmp-packaging -OUTPUT_PATH=../output/nlc_unit_test -OUTPUT_BASENAME=nlc_unit_test +OUTPUT_PATH=../output/nlc_test +OUTPUT_BASENAME=nlc_test PACKAGE_TOP_DIR=src/ # Functions diff --git a/src/nbproject/configurations.xml b/src/nbproject/configurations.xml index 8a9db4bb..a038f1de 100644 --- a/src/nbproject/configurations.xml +++ b/src/nbproject/configurations.xml @@ -7,6 +7,7 @@ ../docs/index.md ../docs/op_iterator.md ../docs/syntax.md + ../docs/version.md ../examples/_run.sh ../examples/dsl.nlp + ../examples/fact_1000.nlp ../examples/fileio.nlp ../examples/foreach.nlp + ../examples/hello.nlp ../examples/rational.nlp ../examples/speed_test.nlp ../examples/speed_test.py @@ -214,14 +217,25 @@ + + + mkdir temp || pandoc -t plain ../docs/syntax.md > temp/syntax.temp.txt + temp/syntax.temp.txt + ../docs/syntax.md + + + + + + @@ -520,14 +534,20 @@ + + + + + + @@ -767,14 +787,20 @@ + + + + + + @@ -975,14 +1001,20 @@ syntax_help.cpp + + + + + + @@ -1241,7 +1273,7 @@ false - ../output/nlc_unit_test + ../output/nlc_test ../contrib/libtorch/lib /usr/lib/x86_64-linux-gnu @@ -1286,14 +1318,20 @@ + + + + + + @@ -1575,14 +1613,20 @@ + + + + + + @@ -1831,14 +1875,20 @@ + + + + + + @@ -2083,14 +2133,20 @@ + + + + + + @@ -2324,14 +2380,20 @@ + + + + + + @@ -2629,14 +2691,20 @@ + + + + + + diff --git a/src/object.cpp b/src/object.cpp index 660ed91b..839613ff 100644 --- a/src/object.cpp +++ b/src/object.cpp @@ -1415,10 +1415,14 @@ void Obj::ConvertToArgs_(Obj *in, bool check_valid, Context * ctx) { ObjType base_type = ObjType::None; if(i < size()) { if(ctx) { - bool has_error = false; - base_type = ctx->BaseTypeFromString((*m_prototype)[i].second->m_type_name, &has_error); - if(has_error && (*m_prototype)[i].second->getTermID() == TermID::ELLIPSIS) { + if((*m_prototype)[i].second->m_type_name.empty()) { base_type = ObjType::Any; + } else { + bool has_error = false; + base_type = ctx->BaseTypeFromString((*m_prototype)[i].second->m_type_name, &has_error); + if(has_error && (*m_prototype)[i].second->getTermID() == TermID::ELLIPSIS) { + base_type = ObjType::Any; + } } } else if(!(*m_prototype)[i].second->m_type_name.empty()) { base_type = typeFromString((*m_prototype)[i].second->m_type_name, ctx); diff --git a/src/object.h b/src/object.h index b311798a..19d943d7 100644 --- a/src/object.h +++ b/src/object.h @@ -1874,20 +1874,14 @@ namespace newlang { } static ObjPtr CreateString(const std::string str) { - ObjPtr result = CreateType(ObjType::StrChar); + ObjPtr result = CreateType(ObjType::StrChar, ObjType::String, true); result->m_value = str; - result->m_var_type_fixed = ObjType::String; - result->m_var_is_init = true; - return result; } static ObjPtr CreateString(const std::wstring str) { - ObjPtr result = CreateType(ObjType::StrWide); + ObjPtr result = CreateType(ObjType::StrWide, ObjType::String, true); result->m_string = str; - result->m_var_type_fixed = ObjType::String; - result->m_var_is_init = true; - return result; } @@ -2388,7 +2382,7 @@ namespace newlang { return m_prototype; } - protected: + SCOPE(protected): void ConvertToArgs_(Obj *args, bool check_valid, Context *ctx = nullptr); // Обновить параметры для вызова функции или элементы у словаря при создании копии diff --git a/src/test/example_test.cpp b/src/test/example_test.cpp index 5af8e5fc..058ae810 100644 --- a/src/test/example_test.cpp +++ b/src/test/example_test.cpp @@ -268,8 +268,6 @@ TEST(Example, Rational) { */ } - - TEST(Example, Tensor) { Context::Reset(); @@ -286,10 +284,56 @@ TEST(Example, Tensor) { std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now(); utils::Logger::Instance()->SetLogLevel(save); - + ASSERT_TRUE(result); ASSERT_TRUE(result->is_string_type()) << result->toString(); ASSERT_STREQ("OK", result->GetValueAsString().c_str()); } +TEST(Example, Hello) { + + Context::Reset(); + Context ctx(RunTime::Init()); + + + ObjPtr prn = ctx.ExecStr("@prn := :Pointer('printf(format:FmtChar, ...):Int32')"); + ASSERT_TRUE(prn); + + ObjPtr res = prn->Call(&ctx, Obj::Arg(Obj::CreateString("Привет, мир!\n"))); + ASSERT_TRUE(res); + ASSERT_TRUE(res->is_integer()) << res->toString(); + ASSERT_STREQ("22", res->GetValueAsString().c_str()); + + ObjPtr func = ctx.ExecStr("@func(arg) := {$arg}"); + ASSERT_TRUE(func); + + res = func->Call(&ctx, Obj::Arg(Obj::CreateString("TEST"))); + ASSERT_TRUE(res); + ASSERT_TRUE(res->is_string_char_type()) << res->toString(); + ASSERT_STREQ("TEST", res->GetValueAsString().c_str()); + // hello(str) := { + // printf := :Pointer('printf(format:FmtChar, ...):Int32'); # Импорт стандартной C функции + // printf('%s\n', $str); # Вызов C функции с проверкой типов аргументов по строке формата + // }; + // hello('Привет, мир!'); # Вызвать функцию + + + setvbuf(stdin, nullptr, _IONBF, 0); + setvbuf(stdout, nullptr, _IONBF, 0); + setvbuf(stderr, nullptr, _IONBF, 0); + + + utils::Logger::LogLevelType save = utils::Logger::Instance()->SetLogLevel(LOG_LEVEL_INFO); + std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now(); + ObjPtr result = ctx.ExecFile("../examples/hello.nlp"); + std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now(); + utils::Logger::Instance()->SetLogLevel(save); + + + ASSERT_TRUE(result); + ASSERT_TRUE(result->is_string_type()) << result->toString(); + ASSERT_STREQ("Привет, мир!", result->GetValueAsString().c_str()); +} + + #endif // UNITTEST \ No newline at end of file diff --git a/src/test/object_test.cpp b/src/test/object_test.cpp index 0f15916e..b5642050 100644 --- a/src/test/object_test.cpp +++ b/src/test/object_test.cpp @@ -732,6 +732,23 @@ TEST(Args, All) { ASSERT_TRUE(any->at(1).second); ASSERT_STREQ("\"СТРОКА\"", (*any)[1].second->toString().c_str()); + + ASSERT_TRUE(p.Parse("func(arg) := {}")); + Obj proto_func(&ctx, ast->Left(), false, &local); + // ASSERT_TRUE(proto_any.m_is_ellipsis); + ASSERT_EQ(1, proto_func.size()); + ASSERT_STREQ("arg", proto_func.at(0).first.c_str()); + ASSERT_EQ(nullptr, proto_func.at(0).second); + + ObjPtr arg_str2 = Obj::CreateDict(Obj::Arg("STRING")); + + proto_func.ConvertToArgs_(arg_str2.get(), true, nullptr); + ASSERT_EQ(1, proto_func.size()); + ASSERT_STREQ("arg", proto_func.at(0).first.c_str()); + ASSERT_TRUE(proto_func.at(0).second); + ASSERT_STREQ("'STRING'", proto_func[0].second->toString().c_str()); + ASSERT_EQ(ObjType::StrChar, proto_func[0].second->getType()); + // ASSERT_TRUE(p.Parse("min(arg, ...) := {}")); Obj min_proto(&ctx, ast->Left(), false, &local);