Skip to content

Commit 5bc17f3

Browse files
committed
Language/MetaCircularEvaluator: Parse value
1 parent dc0b22d commit 5bc17f3

2 files changed

Lines changed: 50 additions & 14 deletions

File tree

modules/Language/MetaCircularEvaluator.mpp

Lines changed: 35 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import CppUtils.Language.AST;
88

99
export namespace CppUtils::Language
1010
{
11-
struct MetaCircularEvaluator final
11+
struct MetaCircularEvaluator
1212
{
1313
using Cursor = String::Cursor<std::string_view>;
1414

@@ -183,11 +183,11 @@ export namespace CppUtils::Language
183183
functions["^"_token] = [](Cursor&, const ASTNode& instruction, MetaCircularEvaluator& context) { return binaryOperator(std::bit_xor{}, instruction, context); };
184184
functions["!"_token] = [](Cursor&, const ASTNode&, MetaCircularEvaluator& context) { return unaryOperator(std::bit_not{}, context); };
185185

186-
functions["if"_token] = [](Cursor& cursor, const ASTNode& instruction, MetaCircularEvaluator& context) -> std::expected<void, std::string_view> {
186+
static constexpr auto condition = [](auto operation, Cursor& cursor, const ASTNode& instruction, MetaCircularEvaluator& context) -> std::expected<void, std::string_view> {
187187
auto& scopeNodes = context.getScope().nodes;
188188
if (std::empty(scopeNodes)) [[unlikely]]
189-
return std::unexpected{"if: No value to check"};
190-
if (scopeNodes.back().value)
189+
return std::unexpected{"condition: No value to check"};
190+
if (operation(scopeNodes.back().value))
191191
{
192192
auto lexemes = std::ref(instruction.nodes);
193193
for (auto instructionPosition = 0uz; not context.exit and instructionPosition < std::size(lexemes.get()); ++instructionPosition)
@@ -200,6 +200,10 @@ export namespace CppUtils::Language
200200
}
201201
return {};
202202
};
203+
204+
functions["if"_token] = [](Cursor& cursor, const ASTNode& instruction, MetaCircularEvaluator& context) { return condition(std::identity{}, cursor, instruction, context); };
205+
functions["else"_token] = [](Cursor& cursor, const ASTNode& instruction, MetaCircularEvaluator& context) { return condition(std::logical_not{}, cursor, instruction, context); };
206+
203207
functions["while"_token] = [](Cursor& cursor, const ASTNode& instruction, MetaCircularEvaluator& context) -> std::expected<void, std::string_view> {
204208
auto& scopeNodes = context.getScope().nodes;
205209
if (std::empty(instruction.nodes)) [[unlikely]]
@@ -285,8 +289,7 @@ export namespace CppUtils::Language
285289
ASTNode{"parseTreeNodes"_token},
286290
ASTNode{"skipSpaces"_token},
287291
ASTNode{"call"_token, {ASTNode{"isEndOfString"_token}}},
288-
ASTNode{"call"_token, {ASTNode{"not"_token}}},
289-
ASTNode{"call"_token, {ASTNode{"if"_token, {
292+
ASTNode{"call"_token, {ASTNode{"else"_token, {
290293
ASTNode{"call"_token, {ASTNode{"delete"_token}}},
291294
ASTNode{"call"_token, {ASTNode{"syntaxError"_token}}}
292295
}}}},
@@ -298,7 +301,20 @@ export namespace CppUtils::Language
298301
}}}}
299302
}},
300303
ASTNode{"parseTreeNode"_token, {
301-
ASTNode{"parseToken"_token},
304+
ASTNode{"skipSpaces"_token},
305+
ASTNode{"call"_token, {ASTNode{"readChar"_token}}},
306+
ASTNode{"isValueChar"_token},
307+
ASTNode{"call"_token, {ASTNode{"if"_token, {
308+
ASTNode{"call"_token, {ASTNode{"delete"_token}}},
309+
ASTNode{"call"_token, {ASTNode{"delete"_token}}},
310+
ASTNode{"call"_token, {ASTNode{"stepCursorForward"_token}}},
311+
ASTNode{"parseValue"_token}
312+
}}}},
313+
ASTNode{"call"_token, {ASTNode{"else"_token, {
314+
ASTNode{"call"_token, {ASTNode{"delete"_token}}},
315+
ASTNode{"call"_token, {ASTNode{"delete"_token}}},
316+
ASTNode{"parseToken"_token}
317+
}}}},
302318
ASTNode{"call"_token, {ASTNode{"enter"_token}}},
303319
ASTNode{"call"_token, {ASTNode{"optional"_token, {
304320
ASTNode{"parseOpeningBrace"_token},
@@ -355,6 +371,15 @@ export namespace CppUtils::Language
355371
}}}},
356372
ASTNode{"call"_token, {ASTNode{"delete"_token}}}
357373
}},
374+
ASTNode{"isValueChar"_token, {
375+
ASTNode{"call"_token, {ASTNode{"new"_token, {ASTNode{'\''}}}}},
376+
ASTNode{"call"_token, {ASTNode{"=="_token}}},
377+
ASTNode{"call"_token, {ASTNode{"return"_token}}}
378+
}},
379+
ASTNode{"parseValue"_token, {
380+
ASTNode{"call"_token, {ASTNode{"readChar"_token}}},
381+
ASTNode{"call"_token, {ASTNode{"stepCursorForward"_token}}}
382+
}},
358383
ASTNode{"isTokenChar"_token, {
359384
ASTNode{"isSpace"_token},
360385
ASTNode{"call"_token, {ASTNode{"if"_token, {
@@ -370,8 +395,7 @@ export namespace CppUtils::Language
370395
}}}},
371396
ASTNode{"call"_token, {ASTNode{"delete"_token}}},
372397
ASTNode{"call"_token, {ASTNode{"new"_token, {ASTNode{'}'}}}}},
373-
ASTNode{"call"_token, {ASTNode{"=="_token}}},
374-
ASTNode{"call"_token, {ASTNode{"not"_token}}},
398+
ASTNode{"call"_token, {ASTNode{"!="_token}}},
375399
ASTNode{"call"_token, {ASTNode{"return"_token}}}
376400
}},
377401
ASTNode{"countTokenLength"_token, {
@@ -399,7 +423,6 @@ export namespace CppUtils::Language
399423
ASTNode{"call"_token, {ASTNode{"delete"_token}}}
400424
}},
401425
ASTNode{"parseToken"_token, {
402-
ASTNode{"skipSpaces"_token},
403426
ASTNode{"call"_token, {ASTNode{"getCursorPosition"_token}}},
404427
ASTNode{"countTokenLength"_token},
405428
ASTNode{"call"_token, {ASTNode{"=="_token, {ASTNode{"rhs"_token, {ASTNode{0}}}}}}},
@@ -422,8 +445,7 @@ export namespace CppUtils::Language
422445
ASTNode{"call"_token, {ASTNode{"delete"_token}}},
423446
ASTNode{"call"_token, {ASTNode{"readChar"_token}}},
424447
ASTNode{"call"_token, {ASTNode{"new"_token, {ASTNode{'{'}}}}},
425-
ASTNode{"call"_token, {ASTNode{"=="_token}}},
426-
ASTNode{"call"_token, {ASTNode{"not"_token}}},
448+
ASTNode{"call"_token, {ASTNode{"!="_token}}},
427449
ASTNode{"call"_token, {ASTNode{"if"_token, {
428450
ASTNode{"call"_token, {ASTNode{"delete"_token}}},
429451
ASTNode{"call"_token, {ASTNode{"delete"_token}}},
@@ -443,8 +465,7 @@ export namespace CppUtils::Language
443465
ASTNode{"call"_token, {ASTNode{"delete"_token}}},
444466
ASTNode{"call"_token, {ASTNode{"readChar"_token}}},
445467
ASTNode{"call"_token, {ASTNode{"new"_token, {ASTNode{'}'}}}}},
446-
ASTNode{"call"_token, {ASTNode{"=="_token}}},
447-
ASTNode{"call"_token, {ASTNode{"not"_token}}},
468+
ASTNode{"call"_token, {ASTNode{"!="_token}}},
448469
ASTNode{"call"_token, {ASTNode{"if"_token, {
449470
ASTNode{"call"_token, {ASTNode{"delete"_token}}},
450471
ASTNode{"call"_token, {ASTNode{"delete"_token}}},

tests/Language/MetaCircularEvaluator.mpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,21 @@ export namespace CppUtils::UnitTest::Language::MetaCircularEvaluator
3939
suite.expectEqual(std::size(interpreter.getScope().nodes.front().nodes), 0uz);
4040
});
4141

42+
suite.addTest("Parse value", [&] {
43+
auto interpreter = CppUtils::Language::MetaCircularEvaluator{};
44+
constexpr auto source = R"(
45+
'a
46+
)"sv;
47+
auto cursor = CppUtils::String::Cursor{source};
48+
auto result = interpreter(cursor);
49+
if (not result)
50+
Logger::print<"error">("Error: {}\nPosition: {}\nChar: '{}'", result.error(), cursor.position, cursor.getCurrent());
51+
52+
suite.expect(result.has_value());
53+
suite.expectEqual(std::size(interpreter.getScope().nodes), 1uz);
54+
suite.expectEqual(interpreter.getScope().nodes.front().value, static_cast<String::Token>('a'));
55+
});
56+
4257
suite.addTest("Parse tree", [&] {
4358
auto interpreter = CppUtils::Language::MetaCircularEvaluator{};
4459
constexpr auto source = R"(

0 commit comments

Comments
 (0)