From 465999965471b8d5df7d79e22b006b64fbde92ad Mon Sep 17 00:00:00 2001 From: arakov Date: Wed, 27 Mar 2024 22:20:40 +0100 Subject: [PATCH] #637 : working on unit test support --- doc/todo.txt | 10 ++- elenasrc3/common/dump.cpp | 9 +- elenasrc3/common/dump.h | 42 ++++++++- elenasrc3/common/tree.h | 32 ++++++- elenasrc3/common/ustring.cpp | 2 +- elenasrc3/common/ustring.h | 9 +- elenasrc3/elc/cliconst.h | 2 +- elenasrc3/elc/vs/elc.vcxproj | 4 + elenasrc3/elena-tests/bt_optimization.cpp | 1 + elenasrc3/elena-tests/bt_optimization.h | 24 +++++ elenasrc3/elena-tests/bt_tests.cpp | 8 ++ elenasrc3/elena-tests/common.cpp | 1 + elenasrc3/elena-tests/common.h | 11 +++ elenasrc3/elena-tests/compiler_tests.cpp | 10 +++ elenasrc3/elena-tests/elena-tests.vcxproj | 7 +- elenasrc3/elena-tests/test.cpp | 6 -- elenasrc3/engine/bcwriter.h | 2 +- elenasrc3/engine/scriptreader.cpp | 2 +- elenasrc3/engine/scriptreader.h | 2 +- elenasrc3/engine/serializer.cpp | 105 ++++++++++++++++++++++ elenasrc3/engine/serializer.h | 31 +++++++ elenasrc3/engine/syntaxtree.cpp | 1 + elenasrc3/engine/syntaxtree.h | 6 +- tests60/sandbox/sandbox.l | 12 +-- 24 files changed, 308 insertions(+), 31 deletions(-) create mode 100644 elenasrc3/elena-tests/bt_optimization.cpp create mode 100644 elenasrc3/elena-tests/bt_optimization.h create mode 100644 elenasrc3/elena-tests/bt_tests.cpp create mode 100644 elenasrc3/elena-tests/common.cpp create mode 100644 elenasrc3/elena-tests/common.h create mode 100644 elenasrc3/elena-tests/compiler_tests.cpp delete mode 100644 elenasrc3/elena-tests/test.cpp create mode 100644 elenasrc3/engine/serializer.cpp create mode 100644 elenasrc3/engine/serializer.h diff --git a/doc/todo.txt b/doc/todo.txt index 2f90ce584..f9d3edbc8 100644 --- a/doc/todo.txt +++ b/doc/todo.txt @@ -16,14 +16,20 @@ In development: port:win64 gui,helloworld gui sample (button), chat sample, win64 script samples -------------------------------------- - #617 + - #637 : all bt tests -------------------------------------- - - #637 + - serialize / deserialize tree : syntax tree + - serialize / deserialize tree : build tree + + - #637 : ByRefOpMark - message, property, weak operation + + - remove Serializer / ScriptReader from elc project (when no longer is required) - port : rest of system module from lib50 === Iteration 22 === -------------------------------------- - dev: async programming (instant messagange sample (chat) ), #608 + dev: async programming (instant messagange sample (chat) ), #608, #637 (all bc tests) op: opt:pi under 6 sec, #601 maint: #506 diff --git a/elenasrc3/common/dump.cpp b/elenasrc3/common/dump.cpp index f5b6cd400..e822de41f 100644 --- a/elenasrc3/common/dump.cpp +++ b/elenasrc3/common/dump.cpp @@ -3,7 +3,7 @@ // // This file contains the implementation of ELENA Engine Data Section // classes. -// (C)2021-2022, by Aleksey Rakov +// (C)2021-2024, by Aleksey Rakov //--------------------------------------------------------------------------- #include "common.h" @@ -152,3 +152,10 @@ bool ByteArray :: insert(pos_t position, const void* s, pos_t length) void ByteArray :: trim(pos_t position) { } + +// --- DynamicUStrWriter --- + +DynamicUStrWriter::DynamicUStrWriter(DynamicUStr* target) +{ + _target = target; +} diff --git a/elenasrc3/common/dump.h b/elenasrc3/common/dump.h index e58f9dcd3..2e1d1dc56 100644 --- a/elenasrc3/common/dump.h +++ b/elenasrc3/common/dump.h @@ -3,7 +3,7 @@ // // This header contains the declaration of ELENA Engine Data Memory dump // classes. -// (C)2021-2022, by Aleksey Rakov +// (C)2021-2024, by Aleksey Rakov //--------------------------------------------------------------------------- #ifndef DUMP_H @@ -141,6 +141,46 @@ namespace elena_lang } }; + // --- DynamicUStrWriter --- + class DynamicUStrWriter : public TextWriter + { + DynamicUStr* _target; + + public: + bool isOpen() const override { return true; } + + pos_t position() const override { return _target->length_pos(); } + + bool seek(pos_t position) + { + if (_target->length_pos() < position) + return false; + + _target->trim(position); + return true; + } + + bool writeNewLine() override + { + char ch = '\n'; + + return write(&ch, 1); + } + + bool write(const char* s, pos_t length) + { + _target->append(s, length); + + return true; + } + + void reset() + { + _target->clear(); + } + + DynamicUStrWriter(DynamicUStr* target); + }; } #endif // DUMP_H \ No newline at end of file diff --git a/elenasrc3/common/tree.h b/elenasrc3/common/tree.h index a7b55e325..138a6ffe3 100644 --- a/elenasrc3/common/tree.h +++ b/elenasrc3/common/tree.h @@ -3,7 +3,7 @@ // // This file contains ELENA Tree template classes // -// (C)2021-2023, by Aleksey Rakov +// (C)2021-2024, by Aleksey Rakov //--------------------------------------------------------------------------- #ifndef TREE_H @@ -720,6 +720,36 @@ namespace elena_lang return counter; } + static void serialize(Node& node, void(*encoder)(TextWriter&, Key, ustr_t, int, void*), TextWriter& writer, void* arg) + { + encoder(writer, node.key, node.identifier(), node.arg.value, arg); + Node current = node.firstChild(); + while (current != defKey) { + serialize(current, encoder, writer, arg); + + current = current.nextNode(); + } + + encoder(writer, defKey, nullptr, 0, nullptr); + } + + static void deserialize(Node root, bool(*reader)(Key&, IdentifierString&, int&, void*), void* arg) + { + Key key = defKey; + IdentifierString strArg; + int intArg; + + Node current = {}; + while (reader(key, strArg, intArg, arg)) { + if (strArg.length() > 0) { + current = root.appendChild(key, *strArg); + } + else current = root.appendChild(key, intArg); + + deserialize(current, reader, arg); + } + } + Tree() = default; }; } diff --git a/elenasrc3/common/ustring.cpp b/elenasrc3/common/ustring.cpp index 0ff947767..f8faf6baa 100644 --- a/elenasrc3/common/ustring.cpp +++ b/elenasrc3/common/ustring.cpp @@ -3,7 +3,7 @@ // // This file contains String classes implementations // -// (C)2021-2023, by Aleksey Rakov +// (C)2021-2024, by Aleksey Rakov // (C)1994-2004, Unicode, Inc. //--------------------------------------------------------------------------- diff --git a/elenasrc3/common/ustring.h b/elenasrc3/common/ustring.h index 3fc0037aa..1f51e4e5c 100644 --- a/elenasrc3/common/ustring.h +++ b/elenasrc3/common/ustring.h @@ -3,7 +3,7 @@ // // This header contains UTF8 String classes declarations // -// (C)2021-2022, by Aleksey Rakov +// (C)2021-2024, by Aleksey Rakov //--------------------------------------------------------------------------- #ifndef USTRING_H @@ -675,6 +675,12 @@ namespace elena_lang _string[0] = 0; } + void trim(size_t position) + { + if (_string) + _string[position] = 0; + } + DynamicString() { _size = 0; @@ -690,6 +696,7 @@ namespace elena_lang }; + typedef DynamicString DynamicUStr; } #endif // USTRING_H diff --git a/elenasrc3/elc/cliconst.h b/elenasrc3/elc/cliconst.h index f7881c7ba..39f18565d 100644 --- a/elenasrc3/elc/cliconst.h +++ b/elenasrc3/elc/cliconst.h @@ -13,7 +13,7 @@ namespace elena_lang { - #define ELC_REVISION_NUMBER 0x0244 + #define ELC_REVISION_NUMBER 0x0245 #if defined _M_IX86 || _M_X64 diff --git a/elenasrc3/elc/vs/elc.vcxproj b/elenasrc3/elc/vs/elc.vcxproj index 50b6a82b1..f83538c1b 100644 --- a/elenasrc3/elc/vs/elc.vcxproj +++ b/elenasrc3/elc/vs/elc.vcxproj @@ -181,7 +181,9 @@ + + @@ -232,7 +234,9 @@ + + diff --git a/elenasrc3/elena-tests/bt_optimization.cpp b/elenasrc3/elena-tests/bt_optimization.cpp new file mode 100644 index 000000000..1d9f38c57 --- /dev/null +++ b/elenasrc3/elena-tests/bt_optimization.cpp @@ -0,0 +1 @@ +#include "pch.h" diff --git a/elenasrc3/elena-tests/bt_optimization.h b/elenasrc3/elena-tests/bt_optimization.h new file mode 100644 index 000000000..969e66cdb --- /dev/null +++ b/elenasrc3/elena-tests/bt_optimization.h @@ -0,0 +1,24 @@ +//--------------------------------------------------------------------------- +// E L E N A P r o j e c t: ELENA Compiler +// +// This header contains ELENA Test Optimization Fixture declarations +// (C)2024, by Aleksey Rakov +//--------------------------------------------------------------------------- + +#ifndef BTOPTIMIZATION_H +#define BTOPTIMIZATION_H + +#include "common.h" + +namespace elena_lang +{ + class BTOptimization1 : public testing::Test + { + protected: + void SetUp() override + { + } + }; +} + +#endif diff --git a/elenasrc3/elena-tests/bt_tests.cpp b/elenasrc3/elena-tests/bt_tests.cpp new file mode 100644 index 000000000..c6bc1c797 --- /dev/null +++ b/elenasrc3/elena-tests/bt_tests.cpp @@ -0,0 +1,8 @@ +#include "pch.h" +#include "bt_optimization.h" + +using namespace elena_lang; +TEST_F(BTOptimization1, BuildTapeTest) { + EXPECT_EQ(1, 1); + EXPECT_TRUE(true); +} \ No newline at end of file diff --git a/elenasrc3/elena-tests/common.cpp b/elenasrc3/elena-tests/common.cpp new file mode 100644 index 000000000..1d9f38c57 --- /dev/null +++ b/elenasrc3/elena-tests/common.cpp @@ -0,0 +1 @@ +#include "pch.h" diff --git a/elenasrc3/elena-tests/common.h b/elenasrc3/elena-tests/common.h new file mode 100644 index 000000000..f23cddc62 --- /dev/null +++ b/elenasrc3/elena-tests/common.h @@ -0,0 +1,11 @@ +//--------------------------------------------------------------------------- +// E L E N A P r o j e c t: ELENA Compiler +// +// This header contains ELENA Test Common declarations +// (C)2024, by Aleksey Rakov +//--------------------------------------------------------------------------- + +#ifndef COMMON_H +#define COMMON_H + +#endif \ No newline at end of file diff --git a/elenasrc3/elena-tests/compiler_tests.cpp b/elenasrc3/elena-tests/compiler_tests.cpp new file mode 100644 index 000000000..f0d75b404 --- /dev/null +++ b/elenasrc3/elena-tests/compiler_tests.cpp @@ -0,0 +1,10 @@ +#include "pch.h" +// ------------------------------------------------ +#include "bt_optimization.h" + +using namespace elena_lang; + +TEST_F(BTOptimization1, CompilerTest) { + EXPECT_EQ(1, 1); + EXPECT_TRUE(true); +} \ No newline at end of file diff --git a/elenasrc3/elena-tests/elena-tests.vcxproj b/elenasrc3/elena-tests/elena-tests.vcxproj index c763f507e..0d0684b6f 100644 --- a/elenasrc3/elena-tests/elena-tests.vcxproj +++ b/elenasrc3/elena-tests/elena-tests.vcxproj @@ -117,9 +117,14 @@ + + - + + + + Create Create diff --git a/elenasrc3/elena-tests/test.cpp b/elenasrc3/elena-tests/test.cpp deleted file mode 100644 index e238589d2..000000000 --- a/elenasrc3/elena-tests/test.cpp +++ /dev/null @@ -1,6 +0,0 @@ -#include "pch.h" - -TEST(TestCaseName, TestName) { - EXPECT_EQ(1, 1); - EXPECT_TRUE(true); -} \ No newline at end of file diff --git a/elenasrc3/engine/bcwriter.h b/elenasrc3/engine/bcwriter.h index 86c40a711..0a5cff855 100644 --- a/elenasrc3/engine/bcwriter.h +++ b/elenasrc3/engine/bcwriter.h @@ -3,7 +3,7 @@ // // This file contains ELENA byte code writer class. // -// (C)2021-2023, by Aleksey Rakov +// (C)2021-2024, by Aleksey Rakov //--------------------------------------------------------------------------- #ifndef BCWRITER_H diff --git a/elenasrc3/engine/scriptreader.cpp b/elenasrc3/engine/scriptreader.cpp index eb4e9297e..1d18102e0 100644 --- a/elenasrc3/engine/scriptreader.cpp +++ b/elenasrc3/engine/scriptreader.cpp @@ -3,7 +3,7 @@ // // This file contains ELENA ScriptReader class implementation. // -// (C)2021-2023, by Aleksey Rakov +// (C)2021-2024, by Aleksey Rakov //--------------------------------------------------------------------------- #include "elena.h" diff --git a/elenasrc3/engine/scriptreader.h b/elenasrc3/engine/scriptreader.h index 245aefb77..c46a3a50f 100644 --- a/elenasrc3/engine/scriptreader.h +++ b/elenasrc3/engine/scriptreader.h @@ -3,7 +3,7 @@ // // This header contains ELENA Script Reader class declaration. // -// (C)2021-2023, by Aleksey Rakov +// (C)2021-2024, by Aleksey Rakov //--------------------------------------------------------------------------- #ifndef SCRIPTREADER_H diff --git a/elenasrc3/engine/serializer.cpp b/elenasrc3/engine/serializer.cpp new file mode 100644 index 000000000..998cccb48 --- /dev/null +++ b/elenasrc3/engine/serializer.cpp @@ -0,0 +1,105 @@ +//--------------------------------------------------------------------------- +// E L E N A P r o j e c t: ELENA Compiler +// +// This header contains ELENA Tree Serializer classes implementation. +// +// (C)2021-2024, by Aleksey Rakov +//--------------------------------------------------------------------------- + +#include "elena.h" +// -------------------------------------------------------------------------- +#include "serializer.h" +#include "scriptreader.h" + +using namespace elena_lang; + +// --- SyntaxTreeReader --- + +void syntaxTreeEncoder(TextWriter& writer, SyntaxKey key, ustr_t strArg, int arg, void* extraArg) +{ + if (key == SyntaxKey::None) { + writer.writeTextLine(")"); + + return; + } + + TokenMap* map = static_cast(extraArg); + + ustr_t keyName = map->retrieve(nullptr, key, [](SyntaxKey arg, ustr_t value, SyntaxKey current) + { + return current == arg; + }); + + writer.writeText(keyName); + if (!strArg.empty()) { + writer.writeChar('"'); + writer.writeText(strArg); + writer.writeChar('"'); + writer.writeChar(' '); + } + else if (arg) { + String number; + number.appendInt(arg); + writer.writeText(number.str()); + writer.writeChar(' '); + } + + writer.writeTextLine("("); +} + +void SyntaxTreeSerializer :: save(SyntaxNode node, DynamicUStr& target) +{ + TokenMap list(SyntaxKey::None); + SyntaxTree::loadTokens(list); + + DynamicUStrWriter writer(&target); + + SyntaxTree::serialize(node, syntaxTreeEncoder, writer, &list); +} + +struct LoadScope +{ + ScriptReader scriptReader; + TokenMap list; + + LoadScope(UStrReader* reader) + : scriptReader(4, reader), list(SyntaxKey::None) + { + } +}; + +bool syntaxTreeReader(SyntaxKey& key, IdentifierString& strValue, int& value, void* arg) +{ + LoadScope* scope = static_cast(arg); + + ScriptToken token; + scope->scriptReader.read(token); + if (token.compare(")")) + return false; + + key = scope->list.get(*token.token); + + scope->scriptReader.read(token); + if (token.state == dfaQuote) { + strValue.copy(*token.token); + + scope->scriptReader.read(token); + } + else if (token.state == dfaInteger) { + value = StrConvertor::toInt(*token.token, 10); + + scope->scriptReader.read(token); + } + + return true; +} + +void SyntaxTreeSerializer :: load(ustr_t source, SyntaxNode& target) +{ + StringTextReader reader(source.str()); + LoadScope scope(&reader); + + SyntaxTree::loadTokens(scope.list); + + SyntaxTree::deserialize(target, syntaxTreeReader, &scope); +} diff --git a/elenasrc3/engine/serializer.h b/elenasrc3/engine/serializer.h new file mode 100644 index 000000000..9b3f5d9a1 --- /dev/null +++ b/elenasrc3/engine/serializer.h @@ -0,0 +1,31 @@ +//--------------------------------------------------------------------------- +// E L E N A P r o j e c t: ELENA Compiler +// +// This header contains ELENA Tree Serializer classes declaration. +// +// (C)2021-2024, by Aleksey Rakov +//--------------------------------------------------------------------------- + +#ifndef SERIALIZER_H +#define SERIALIZER_H + +#include "syntaxtree.h" +#include "buildtree.h" + +namespace elena_lang +{ + // --- BuildTreeReader --- + class BuildTreeSerializer + { + }; + + // --- SyntaxTreeReader --- + class SyntaxTreeSerializer + { + public: + static void save(SyntaxNode node, DynamicUStr& target); + static void load(ustr_t source, SyntaxNode& target); + }; +} + +#endif // SERIALIZER_H \ No newline at end of file diff --git a/elenasrc3/engine/syntaxtree.cpp b/elenasrc3/engine/syntaxtree.cpp index 857c38eb2..bbc10782d 100644 --- a/elenasrc3/engine/syntaxtree.cpp +++ b/elenasrc3/engine/syntaxtree.cpp @@ -9,6 +9,7 @@ #include "elena.h" // -------------------------------------------------------------------------- #include "syntaxtree.h" +#include "scriptreader.h" using namespace elena_lang; diff --git a/elenasrc3/engine/syntaxtree.h b/elenasrc3/engine/syntaxtree.h index dcd2c92de..b4717f9a1 100644 --- a/elenasrc3/engine/syntaxtree.h +++ b/elenasrc3/engine/syntaxtree.h @@ -3,7 +3,7 @@ // // This file contains Syntax Tree class declaration // -// (C)2021-2023, by Aleksey Rakov +// (C)2021-2024, by Aleksey Rakov //--------------------------------------------------------------------------- #ifndef SYNTAXTREE_H @@ -246,9 +246,5 @@ namespace elena_lang static void copyNodeSafe(SyntaxTreeWriter& writer, SyntaxNode node, bool includingNode = false); static void saveNode(SyntaxNode node, MemoryBase* section, bool includingNode = false); }; - - // --- BuildTreeWriter --- - } - #endif diff --git a/tests60/sandbox/sandbox.l b/tests60/sandbox/sandbox.l index dde06eae2..374d4490b 100644 --- a/tests60/sandbox/sandbox.l +++ b/tests60/sandbox/sandbox.l @@ -1,16 +1,12 @@ - -public class A +public singleton Tester { - internal constructor() + int getValue() { + ^ 2; } - - load(ref int retVal) - { - retVal := 2 - } } public program() { + int r := Tester.getValue() } \ No newline at end of file