Skip to content

Commit 1e43dbb

Browse files
committed
Language/ASTParser: alternative lexeme
1 parent 1388ebc commit 1e43dbb

11 files changed

Lines changed: 209 additions & 99 deletions

File tree

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,8 @@
5151
### 🔣 Languages (Parsers, Compilers, VM)
5252
- Tools to create parsers and compilers (CSS, INI, HTML, JSON, Markdown, XML) (work in progress <img src="resources/loading.gif" width="12" height="12"/>)
5353
- [`CLikeCompiler`](modules/Language/CLikeCompiler.mpp) - Compiler for C-inspired language
54-
- [`MetaCircularEvaluator`](modules/Language/MetaCircularEvaluator.mpp) - Homoiconic meta-circular evaluator with extensible reflexivity
55-
- [`TreeParser`](modules/Language/TreeParser.mpp) - Tree parser (work in progress <img src="resources/loading.gif" width="12" height="12"/>)
54+
- [`MetaEvaluator`](modules/Language/MetaEvaluator.mpp) - Homoiconic meta-circular evaluator with extensible reflexivity
55+
- [`ASTParser`](modules/Language/ASTParser.mpp) - AST parser (work in progress <img src="resources/loading.gif" width="12" height="12"/>)
5656
- [`VirtualMachine`](modules/Language/VirtualMachine.mpp) - Generic virtual machine
5757

5858
### 📝 Logging & Benchmarking
Lines changed: 94 additions & 66 deletions
Large diffs are not rendered by default.

modules/Language/GrammarParser.mpp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
export module CppUtils.Language.GrammarParser;
2+
3+
import std;
4+
import CppUtils.Language.ASTParser;
5+
import CppUtils.Logger;
6+
import CppUtils.String;
7+
8+
export namespace CppUtils::Language
9+
{
10+
struct GrammarParser: public ASTParser
11+
{
12+
GrammarParser()
13+
{
14+
using namespace std::literals;
15+
using Logger = Logger<"CppUtils">;
16+
17+
constexpr auto source = R"(
18+
enter { call{enter} }
19+
leave { call{leave} }
20+
delete { call{delete} }
21+
readChar { call{readChar} }
22+
stepCursorForward { call{stepCursorForward} }
23+
24+
declarations
25+
)"sv;
26+
27+
auto cursor = CppUtils::String::Cursor{source};
28+
if (auto result = operator()(cursor); not result)
29+
Logger::print<"error">("Error: {}\nPosition: {}\nChar: '{}'", result.error(), cursor.position, cursor.getCurrent());
30+
}
31+
};
32+
}

modules/Language/Language.mpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
export module CppUtils.Language;
22

33
export import CppUtils.Language.AST;
4-
export import CppUtils.Language.TreeParser;
4+
export import CppUtils.Language.ASTParser;
5+
export import CppUtils.Language.GrammarParser;
56
export import CppUtils.Language.VirtualMachine;
6-
export import CppUtils.Language.MetaCircularEvaluator;
7+
export import CppUtils.Language.MetaEvaluator;

modules/Language/MetaCircularEvaluator.mpp renamed to modules/Language/MetaEvaluator.mpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
export module CppUtils.Language.MetaCircularEvaluator;
1+
export module CppUtils.Language.MetaEvaluator;
22

33
import std;
44
import CppUtils.String;
55
import CppUtils.Language.AST;
66

77
export namespace CppUtils::Language
88
{
9-
struct MetaCircularEvaluator
9+
struct MetaEvaluator
1010
{
1111
using Cursor = String::Cursor<std::string_view>;
1212

@@ -42,6 +42,8 @@ export namespace CppUtils::Language
4242
return result;
4343
if (not grammar.get().exists(instruction.value)) [[unlikely]]
4444
return {};
45+
if (not grammar.get().exists(instruction.value)) [[unlikely]]
46+
return std::unexpected{"Unknown lexeme"};
4547
lexemes = std::ref(grammar.get()[instruction.value].nodes);
4648
}
4749
exit = false;
@@ -53,7 +55,7 @@ export namespace CppUtils::Language
5355
return scopes.back().get();
5456
}
5557

56-
std::unordered_map<String::Token, std::function<std::expected<void, std::string_view>(Cursor&, const ASTNode&, MetaCircularEvaluator&)>> functions;
58+
std::unordered_map<String::Token, std::function<std::expected<void, std::string_view>(Cursor&, const ASTNode&, MetaEvaluator&)>> functions;
5759
ASTNode rootAst = {0uz, {ASTNode{String::hash("main")}}};
5860
std::vector<std::reference_wrapper<ASTNode>> scopes = {std::ref(rootAst)};
5961
bool exit = false;
Lines changed: 28 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,32 @@
1-
export module CppUtils.UnitTests.Language.TreeParser;
1+
export module CppUtils.UnitTests.Language.ASTParser;
22

33
import std;
44
import CppUtils;
55

6-
export namespace CppUtils::UnitTest::Language::TreeParser
6+
export namespace CppUtils::UnitTest::Language::ASTParser
77
{
88
inline auto _ = TestSuite{
9-
"Language/TreeParser",
10-
{"Logger", "Container/Tree", "Language/MetaCircularEvaluator"},
9+
"Language/ASTParser",
10+
{"Logger", "Container/Tree", "Language/MetaEvaluator"},
1111
[](auto& suite) {
1212
using namespace std::literals;
1313
using namespace CppUtils::String::Literals;
1414
using Logger = CppUtils::Logger<"CppUtils">;
1515

16+
static constexpr auto addStack = [](CppUtils::Language::ASTParser& interpreter) {
17+
using ASTNode = CppUtils::Language::ASTNode;
18+
auto& mainNode = interpreter.rootAst["main"_token];
19+
// clang-format off
20+
mainNode.nodes.insert(std::begin(mainNode.nodes), {
21+
ASTNode{"call"_token, {ASTNode{"new"_token, {ASTNode{"stack"_token}}}}},
22+
ASTNode{"call"_token, {ASTNode{"enter"_token}}}
23+
});
24+
// clang-format on
25+
};
26+
1627
suite.addTest("Empty source", [&] {
17-
auto interpreter = CppUtils::Language::TreeParser{};
28+
auto interpreter = CppUtils::Language::ASTParser{};
29+
addStack(interpreter);
1830
constexpr auto source = ""sv;
1931
auto cursor = CppUtils::String::Cursor{source};
2032

@@ -27,7 +39,8 @@ export namespace CppUtils::UnitTest::Language::TreeParser
2739
});
2840

2941
suite.addTest("Whitespaces", [&] {
30-
auto interpreter = CppUtils::Language::TreeParser{};
42+
auto interpreter = CppUtils::Language::ASTParser{};
43+
addStack(interpreter);
3144
constexpr auto source = R"(
3245

3346
)"sv;
@@ -42,7 +55,8 @@ export namespace CppUtils::UnitTest::Language::TreeParser
4255
});
4356

4457
suite.addTest("Parse token", [&] {
45-
auto interpreter = CppUtils::Language::TreeParser{};
58+
auto interpreter = CppUtils::Language::ASTParser{};
59+
addStack(interpreter);
4660
constexpr auto source = "parent"sv;
4761
auto cursor = CppUtils::String::Cursor{source};
4862

@@ -58,7 +72,8 @@ export namespace CppUtils::UnitTest::Language::TreeParser
5872
});
5973

6074
suite.addTest("Empty node", [&] {
61-
auto interpreter = CppUtils::Language::TreeParser{};
75+
auto interpreter = CppUtils::Language::ASTParser{};
76+
addStack(interpreter);
6277
constexpr auto source = "parent{}"sv;
6378
auto cursor = CppUtils::String::Cursor{source};
6479

@@ -79,9 +94,10 @@ export namespace CppUtils::UnitTest::Language::TreeParser
7994
});
8095

8196
suite.addTest("Parse value", [&] {
82-
auto interpreter = CppUtils::Language::TreeParser{};
97+
auto interpreter = CppUtils::Language::ASTParser{};
98+
addStack(interpreter);
8399
constexpr auto source = R"(
84-
'a
100+
'a'
85101
)"sv;
86102
auto cursor = CppUtils::String::Cursor{source};
87103

@@ -96,7 +112,8 @@ export namespace CppUtils::UnitTest::Language::TreeParser
96112
});
97113

98114
suite.addTest("Nested nodes", [&] {
99-
auto interpreter = CppUtils::Language::TreeParser{};
115+
auto interpreter = CppUtils::Language::ASTParser{};
116+
addStack(interpreter);
100117
constexpr auto source = R"(
101118
parent {
102119
child1

tests/Language/CLikeCompiler.mpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ export namespace CppUtils::UnitTest::Language::CLikeCompiler
88
/*
99
inline auto _ = TestSuite{
1010
"Language/CLikeCompiler",
11-
{"Logger", "Language/TreeParser"},
11+
{"Logger", "Language/ASTParser"},
1212
[]([[maybe_unused]] auto& suite) {
1313
using namespace std::literals;
1414
using Logger = CppUtils::Logger<"CppUtils">;

tests/Language/GrammarParser.mpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
export module CppUtils.UnitTests.Language.GrammarParser;
2+
3+
import std;
4+
import CppUtils;
5+
6+
export namespace CppUtils::UnitTest::Language::GrammarParser
7+
{
8+
inline auto _ = TestSuite{
9+
"Language/GrammarParser",
10+
{"Language/ASTParser"},
11+
[](auto& suite) {
12+
using namespace std::literals;
13+
using namespace CppUtils::String::Literals;
14+
using Logger = CppUtils::Logger<"CppUtils">;
15+
16+
suite.addTest("Empty source", [&] {
17+
auto interpreter = CppUtils::Language::GrammarParser{};
18+
constexpr auto source = ""sv;
19+
auto cursor = CppUtils::String::Cursor{source};
20+
21+
auto result = interpreter(cursor);
22+
if (not result)
23+
Logger::print<"error">("Error: {}\nPosition: {}\nChar: '{}'", result.error(), cursor.position, cursor.getCurrent());
24+
25+
suite.expect(result.has_value());
26+
});
27+
}};
28+
}
Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,23 @@
1-
export module CppUtils.UnitTests.Language.MetaCircularEvaluator;
1+
export module CppUtils.UnitTests.Language.MetaEvaluator;
22

33
import std;
44
import CppUtils;
55

6-
export namespace CppUtils::UnitTest::Language::MetaCircularEvaluator
6+
export namespace CppUtils::UnitTest::Language::MetaEvaluator
77
{
88
inline auto _ = TestSuite{
9-
"Language/MetaCircularEvaluator",
9+
"Language/MetaEvaluator",
1010
{"Logger", "Container/Tree"},
1111
[](auto& suite) {
1212
using namespace std::literals;
1313
using namespace CppUtils::String::Literals;
1414
using Logger = CppUtils::Logger<"CppUtils">;
15-
using MetaCircularEvaluator = CppUtils::Language::MetaCircularEvaluator;
16-
using Cursor = CppUtils::Language::MetaCircularEvaluator::Cursor;
15+
using MetaEvaluator = CppUtils::Language::MetaEvaluator;
16+
using Cursor = CppUtils::Language::MetaEvaluator::Cursor;
1717
using ASTNode = CppUtils::Language::ASTNode;
1818

1919
suite.addTest("Empty source", [&] {
20-
auto interpreter = MetaCircularEvaluator{};
20+
auto interpreter = MetaEvaluator{};
2121
constexpr auto source = ""sv;
2222
auto cursor = Cursor{source};
2323

@@ -30,11 +30,11 @@ export namespace CppUtils::UnitTest::Language::MetaCircularEvaluator
3030
});
3131

3232
suite.addTest("Call function", [&] {
33-
auto interpreter = MetaCircularEvaluator{};
33+
auto interpreter = MetaEvaluator{};
3434
constexpr auto source = ""sv;
3535
auto cursor = Cursor{source};
3636

37-
interpreter.functions["test"_token] = [](Cursor&, const ASTNode&, MetaCircularEvaluator& context) -> std::expected<void, std::string_view> {
37+
interpreter.functions["test"_token] = [](Cursor&, const ASTNode&, MetaEvaluator& context) -> std::expected<void, std::string_view> {
3838
auto& scopeNodes = context.getScope().nodes;
3939
scopeNodes.emplace_back(42uz);
4040
return {};
@@ -58,11 +58,11 @@ export namespace CppUtils::UnitTest::Language::MetaCircularEvaluator
5858
});
5959

6060
suite.addTest("Call lexeme", [&] {
61-
auto interpreter = MetaCircularEvaluator{};
61+
auto interpreter = MetaEvaluator{};
6262
constexpr auto source = ""sv;
6363
auto cursor = Cursor{source};
6464

65-
interpreter.functions["test"_token] = [](Cursor&, const ASTNode&, MetaCircularEvaluator& context) -> std::expected<void, std::string_view> {
65+
interpreter.functions["test"_token] = [](Cursor&, const ASTNode&, MetaEvaluator& context) -> std::expected<void, std::string_view> {
6666
auto& scopeNodes = context.getScope().nodes;
6767
scopeNodes.emplace_back(42uz);
6868
return {};

tests/Terminal/Canvas.mpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ export namespace CppUtils::UnitTest::Terminal::Canvas
8282
auto ballVelocity = CppUtils::Container::Vec2<float>{1.f, 1.f};
8383
auto charPosition = CppUtils::Container::Size2{};
8484

85-
for (auto i = 0uz; i <= 500; ++i)
85+
for (auto i = 0uz; i <= 500uz; ++i)
8686
{
8787
canvas.print(charPosition, ".");
8888
auto previousBallPosition = ballPosition;

0 commit comments

Comments
 (0)