Skip to content

Commit cf033fd

Browse files
committed
Language/MetaCircularVirtualMachine: iteration to branches
1 parent 16259e6 commit cf033fd

4 files changed

Lines changed: 158 additions & 183 deletions

File tree

modules/Language/MetaCircularParser.mpp

Lines changed: 38 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,15 @@ export namespace CppUtils::Language
1818
using namespace std::literals;
1919
using namespace String::Literals;
2020

21-
addFunction<MetaCircularParser>("size"_token, [](MetaCircularParser& interpreter, MeshNodePtr instruction) -> std::expected<void, std::string_view> {
21+
addFunction<MetaCircularParser>("size"_token, [](MetaCircularParser& interpreter, MeshNodePtr instruction) -> std::expected<MeshNodePtr, std::string_view> {
2222
auto destinationNode = instruction.at("destination"_token).and_then([](auto branch) { return branch.front(); });
2323
if (not destinationNode)
2424
return std::unexpected{"size: No destination"sv};
2525
destinationNode->setValue(std::size(interpreter.source));
26-
return {};
26+
return next(instruction);
2727
});
2828

29-
addFunction<MetaCircularParser>("read"_token, [](MetaCircularParser& interpreter, MeshNodePtr instruction) -> std::expected<void, std::string_view> {
29+
addFunction<MetaCircularParser>("read"_token, [](MetaCircularParser& interpreter, MeshNodePtr instruction) -> std::expected<MeshNodePtr, std::string_view> {
3030
auto positionNode = instruction.at("position"_token).and_then([](auto branch) { return branch.front(); });
3131
if (not positionNode)
3232
return std::unexpected{"read: No position"sv};
@@ -39,10 +39,10 @@ export namespace CppUtils::Language
3939
if (not destinationNode)
4040
return std::unexpected{"read: No destination"sv};
4141
destinationNode->setValue(static_cast<std::size_t>(interpreter.source[position]));
42-
return {};
42+
return next(instruction);
4343
});
4444

45-
addFunction<MetaCircularParser>("hash"_token, [](MetaCircularParser&, MeshNodePtr instruction) -> std::expected<void, std::string_view> {
45+
addFunction<MetaCircularParser>("hash"_token, [](MetaCircularParser&, MeshNodePtr instruction) -> std::expected<MeshNodePtr, std::string_view> {
4646
auto charNode = instruction.at("char"_token).and_then([](auto branch) { return branch.front(); });
4747
if (not charNode)
4848
return std::unexpected{"hash: No character"sv};
@@ -57,23 +57,19 @@ export namespace CppUtils::Language
5757

5858
const auto result = (static_cast<std::uint64_t>(character) ^ currentHash) * Type::HashPrime;
5959
destinationNode->setValue(result);
60-
return {};
60+
return next(instruction);
6161
});
6262

6363
// Etat global
6464
auto positionNode = context["position"_token] >> MeshNodePtr::make(0uz);
6565
auto accumulatorNode = context["accumulator"_token] >> MeshNodePtr::make(Type::HashOffset);
6666
auto targetNode = context["target"_token] >> MeshNodePtr::make(0uz);
6767

68-
// Fonctions bytecode
68+
// Fonctions
6969
auto lowLevelTokenParser = context["scope"_token] >> MeshNodePtr::make("lowLevelTokenParser"_token);
70-
auto parseTokenNode = lowLevelTokenParser["parseToken"_token] >> MeshNodePtr::make("parseToken"_token);
71-
auto onSeparatorNode = lowLevelTokenParser["onSeparator"_token] >> MeshNodePtr::make("onSeparator"_token);
72-
auto onCharacterNode = lowLevelTokenParser["onCharacter"_token] >> MeshNodePtr::make("onCharacter"_token);
73-
74-
// Branchement
75-
lowLevelTokenParser[static_cast<Type::Token>(true)] >> onSeparatorNode;
76-
lowLevelTokenParser[static_cast<Type::Token>(false)] >> onCharacterNode;
70+
auto parseTokenNode = lowLevelTokenParser["parseToken"_token] >> MeshNodePtr::make("jump"_token);
71+
auto onSeparatorNode = lowLevelTokenParser["onSeparator"_token] >> MeshNodePtr::make("jump"_token);
72+
auto onCharacterNode = lowLevelTokenParser["onCharacter"_token] >> MeshNodePtr::make("jump"_token);
7773

7874
// Variables de travail
7975
auto workingVariablesBranch = lowLevelTokenParser["workingVariables"_token];
@@ -86,78 +82,72 @@ export namespace CppUtils::Language
8682
auto hashOffsetNode = workingVariablesBranch >> MeshNodePtr::make(Type::HashOffset);
8783

8884
// Fonction onSeparatorNode
85+
MeshNodePtr onSeparatorEnd;
8986
{
90-
auto instructions = onSeparatorNode["instructions"_token];
91-
auto storeInstruction = instructions >> MeshNodePtr::make("define"_token);
87+
auto storeInstruction = onSeparatorNode["next"_token] >> MeshNodePtr::make("define"_token);
9288
storeInstruction["value"_token] >> accumulatorNode;
9389
storeInstruction["target"_token] >> targetNode;
9490

95-
auto resetInstruction = instructions >> MeshNodePtr::make("define"_token);
91+
auto resetInstruction = storeInstruction["next"_token] >> MeshNodePtr::make("define"_token);
9692
resetInstruction["value"_token] >> hashOffsetNode;
9793
resetInstruction["target"_token] >> accumulatorNode;
94+
onSeparatorEnd = resetInstruction;
9895
}
9996

10097
// Fonction onCharacterNode
98+
MeshNodePtr onCharacterEnd;
10199
{
102-
auto instructions = onCharacterNode["instructions"_token];
103-
auto hashInstruction = instructions >> MeshNodePtr::make("hash"_token);
100+
auto hashInstruction = onCharacterNode["next"_token] >> MeshNodePtr::make("hash"_token);
104101
hashInstruction["char"_token] >> currentCharNode;
105102
hashInstruction["accumulator"_token] >> accumulatorNode;
106103
hashInstruction["destination"_token] >> accumulatorNode;
104+
onCharacterEnd = hashInstruction;
107105
}
108106

109107
// Fonction parseTokenNode
110108
{
111-
auto instructions = parseTokenNode["instructions"_token];
112-
113-
// 0: isNotEnd = position < size
114-
auto checkEndInstruction = instructions >> MeshNodePtr::make("<"_token);
109+
// isNotEnd = position < size
110+
auto checkEndInstruction = parseTokenNode["next"_token] >> MeshNodePtr::make("<"_token);
115111
checkEndInstruction["lhs"_token] >> positionNode;
116112
checkEndInstruction["rhs"_token] >> sourceSizeNode;
117113
checkEndInstruction["result"_token] >> isNotEndSourceNode;
118114

119-
// 1: jump to 3 if isNotEnd
120-
auto jumpIfNotEmpty = instructions >> MeshNodePtr::make("jump"_token);
115+
// jump to readInstruction if isNotEnd
116+
auto jumpIfNotEmpty = checkEndInstruction["next"_token] >> MeshNodePtr::make("jump"_token);
121117
jumpIfNotEmpty["condition"_token] >> isNotEndSourceNode;
122-
jumpIfNotEmpty["index"_token] >> MeshNodePtr::make(3uz);
123118

124-
// 2: return if position >= size
125-
instructions >> MeshNodePtr::make("return"_token);
119+
// return if position >= size
120+
jumpIfNotEmpty["else"_token] >> MeshNodePtr::make("return"_token);
126121

127-
// 3: read
128-
auto readInstruction = instructions >> MeshNodePtr::make("read"_token);
122+
// read
123+
auto readInstruction = jumpIfNotEmpty["next"_token] >> MeshNodePtr::make("read"_token);
129124
readInstruction["position"_token] >> positionNode;
130125
readInstruction["destination"_token] >> currentCharNode;
131126

132-
// 4: isSeparator = currentChar == ';'
133-
auto compareInstruction = instructions >> MeshNodePtr::make("=="_token);
127+
// isSeparator = currentChar == ';'
128+
auto compareInstruction = readInstruction["next"_token] >> MeshNodePtr::make("=="_token);
134129
compareInstruction["lhs"_token] >> currentCharNode;
135130
compareInstruction["rhs"_token] >> separatorNode;
136131
compareInstruction["result"_token] >> isSeparatorNode;
137132

138-
// 5: jump to 8 (onSeparator) if isSeparator is true
139-
auto jumpToSeparator = instructions >> MeshNodePtr::make("jump"_token);
133+
// jump to onSeparator if isSeparator is true
134+
auto jumpToSeparator = compareInstruction["next"_token] >> MeshNodePtr::make("jump"_token);
140135
jumpToSeparator["condition"_token] >> isSeparatorNode;
141-
jumpToSeparator["index"_token] >> MeshNodePtr::make(8uz);
142-
143-
// 6: call onCharacter
144-
instructions >> onCharacterNode;
145-
146-
// 7: jump to 9 (increment)
147-
auto jumpToIncrement = instructions >> MeshNodePtr::make("jump"_token);
148-
jumpToIncrement["index"_token] >> MeshNodePtr::make(9uz);
136+
jumpToSeparator["next"_token] >> onSeparatorNode;
149137

150-
// 8: call onSeparator
151-
instructions >> onSeparatorNode;
138+
// call onCharacter
139+
jumpToSeparator["else"_token] >> onCharacterNode;
152140

153-
// 9: position++
154-
auto incrementInstruction = instructions >> MeshNodePtr::make("+"_token);
141+
// position++
142+
auto incrementInstruction = MeshNodePtr::make("+"_token);
143+
onCharacterEnd["next"_token] >> incrementInstruction;
144+
onSeparatorEnd["next"_token] >> incrementInstruction;
155145
incrementInstruction["lhs"_token] >> positionNode;
156146
incrementInstruction["rhs"_token] >> oneNode;
157147
incrementInstruction["result"_token] >> positionNode;
158148

159-
// 10: loop back to 0
160-
instructions >> MeshNodePtr::make("jump"_token)["index"_token] >> MeshNodePtr::make(0uz);
149+
// loop back to 0
150+
incrementInstruction["next"_token] >> checkEndInstruction;
161151
}
162152
}
163153
};

0 commit comments

Comments
 (0)