mirror of
https://github.com/arabine/open-story-teller.git
synced 2025-12-06 17:09:06 +01:00
(wip) compiler with ast
This commit is contained in:
parent
bbf149dedd
commit
d3a8b10120
10 changed files with 18631 additions and 26 deletions
27
.gitignore
vendored
27
.gitignore
vendored
|
|
@ -5,8 +5,6 @@ www-docs/node_modules/
|
|||
|
||||
*.lock
|
||||
|
||||
build-story-editor-Desktop_Qt_6_4_1_GCC_64bit-Debug/
|
||||
|
||||
docs/resources/
|
||||
|
||||
docs/node_modules/
|
||||
|
|
@ -21,23 +19,11 @@ hardware/kicad/ost-pico-addon/fp-info-cache
|
|||
|
||||
*.png~
|
||||
|
||||
build-story-editor-Desktop_Qt_6_5_1_GCC_64bit-Debug/
|
||||
|
||||
build-story-editor-Desktop_Qt_6_5_1_MinGW_64_bit-Debug/
|
||||
|
||||
build-story-editor-Desktop_Qt_6_5_1_MinGW_64_bit-Release/
|
||||
|
||||
build-story-editor-Desktop_Qt_6_5_1_MSVC2019_64bit-Debug/
|
||||
|
||||
release/
|
||||
|
||||
story-editor/windows-setup/Output/
|
||||
|
||||
build-story-editor-Desktop_Qt_6_5_1_GCC_64bit-Release/
|
||||
|
||||
build-story-player-Desktop_Qt_6_5_1_GCC_64bit-Debug/
|
||||
|
||||
build-story-player-Desktop_Qt_GCC_64bit-Debug/
|
||||
|
||||
*.user
|
||||
|
||||
|
|
@ -47,20 +33,12 @@ software/.vscode/.cortex-debug.registers.state.json
|
|||
|
||||
story-player/build/
|
||||
|
||||
story-editor/tools/build-audio-System_Qt5_15_8-Debug/
|
||||
|
||||
|
||||
software/.vscode/.cortex-debug.peripherals.state.json
|
||||
story-editor/build
|
||||
|
||||
build-story-editor-v2-System_Qt5_15_8-Debug/
|
||||
|
||||
story-editor-v2/src/CMakeSettings.json
|
||||
|
||||
story-editor-v2/imgui.ini
|
||||
|
||||
story-editor-v2/src/.vscode/
|
||||
|
||||
build-story-editor-v2-Desktop-Debug/
|
||||
|
||||
build-story-editor-Desktop-Debug/
|
||||
|
||||
|
|
@ -75,7 +53,6 @@ software/.cache/
|
|||
story-editor/.idea/
|
||||
|
||||
|
||||
build-story-editor-Desktop_Qt_GCC_64bit-Debug/
|
||||
|
||||
firmware/build/
|
||||
|
||||
|
|
@ -107,3 +84,5 @@ story-editor/cmake-build-debug/
|
|||
story-editor/.flatpak-builder
|
||||
story-editor/flatpak_build/
|
||||
story-editor/AppDir/
|
||||
|
||||
core/story-manager/tests/build
|
||||
|
|
|
|||
5
.vscode/settings.json
vendored
5
.vscode/settings.json
vendored
|
|
@ -1,10 +1,11 @@
|
|||
{
|
||||
|
||||
"cmake.sourceDirectory": [
|
||||
"${workspaceFolder}/core/chip32/tests",
|
||||
"${workspaceFolder}/core/story-manager/tests",
|
||||
"${workspaceFolder}/story-editor",
|
||||
"${workspaceFolder}/story-player-raylib",
|
||||
"${workspaceFolder}/software",
|
||||
"${workspaceFolder}/core/chip32/tests"
|
||||
"${workspaceFolder}/software"
|
||||
],
|
||||
"files.associations": {
|
||||
"*.css": "tailwindcss",
|
||||
|
|
|
|||
306
core/chip32/chip32_compiler.cpp
Normal file
306
core/chip32/chip32_compiler.cpp
Normal file
|
|
@ -0,0 +1,306 @@
|
|||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <cctype>
|
||||
#include <memory>
|
||||
#include <fstream>
|
||||
enum class TokenType {
|
||||
FUNC, IDENTIFIER, INT, CONST, VAR, IF, ELSE, WHILE, NUMBER, ASSIGN, PLUS, MINUS, MULT, DIV, SEMICOLON,
|
||||
LPAREN, RPAREN, LBRACE, RBRACE, END, GREATER, LESS, EQUAL, NOTEQUAL
|
||||
};
|
||||
|
||||
struct Token {
|
||||
TokenType type;
|
||||
std::string value;
|
||||
};
|
||||
|
||||
class Lexer {
|
||||
public:
|
||||
Lexer(const std::string& input) : input(input), pos(0) {}
|
||||
|
||||
std::vector<Token> tokenize() {
|
||||
std::vector<Token> tokens;
|
||||
|
||||
while (pos < input.size()) {
|
||||
if (std::isspace(input[pos])) {
|
||||
++pos;
|
||||
} else if (std::isalpha(input[pos])) {
|
||||
std::string ident = readIdentifier();
|
||||
if (ident == "func") {
|
||||
tokens.push_back({TokenType::FUNC, ident});
|
||||
} else if (ident == "int") {
|
||||
tokens.push_back({TokenType::INT, ident});
|
||||
} else if (ident == "const") {
|
||||
tokens.push_back({TokenType::CONST, ident});
|
||||
} else if (ident == "var") {
|
||||
tokens.push_back({TokenType::VAR, ident});
|
||||
} else if (ident == "if") {
|
||||
tokens.push_back({TokenType::IF, ident});
|
||||
} else if (ident == "else") {
|
||||
tokens.push_back({TokenType::ELSE, ident});
|
||||
} else if (ident == "while") {
|
||||
tokens.push_back({TokenType::WHILE, ident});
|
||||
} else {
|
||||
tokens.push_back({TokenType::IDENTIFIER, ident});
|
||||
}
|
||||
} else if (std::isdigit(input[pos])) {
|
||||
tokens.push_back({TokenType::NUMBER, readNumber()});
|
||||
} else {
|
||||
switch (input[pos]) {
|
||||
case '(': tokens.push_back({TokenType::LPAREN, "("}); break;
|
||||
case ')': tokens.push_back({TokenType::RPAREN, ")"}); break;
|
||||
case '{': tokens.push_back({TokenType::LBRACE, "{"}); break;
|
||||
case '}': tokens.push_back({TokenType::RBRACE, "}"}); break;
|
||||
case '=': tokens.push_back({TokenType::ASSIGN, "="}); break;
|
||||
case '+': tokens.push_back({TokenType::PLUS, "+"}); break;
|
||||
case '-': tokens.push_back({TokenType::MINUS, "-"}); break;
|
||||
case '*': tokens.push_back({TokenType::MULT, "*"}); break;
|
||||
case '/': tokens.push_back({TokenType::DIV, "/"}); break;
|
||||
case ';': tokens.push_back({TokenType::SEMICOLON, ";"}); break;
|
||||
case '>': tokens.push_back({TokenType::GREATER, ">"}); break;
|
||||
case '<': tokens.push_back({TokenType::LESS, "<"}); break;
|
||||
default: std::cerr << "Caractère inattendu : " << input[pos] << std::endl;
|
||||
}
|
||||
++pos;
|
||||
}
|
||||
}
|
||||
tokens.push_back({TokenType::END, ""});
|
||||
return tokens;
|
||||
}
|
||||
|
||||
private:
|
||||
std::string input;
|
||||
size_t pos;
|
||||
|
||||
std::string readIdentifier() {
|
||||
size_t start = pos;
|
||||
while (pos < input.size() && std::isalnum(input[pos])) ++pos;
|
||||
return input.substr(start, pos - start);
|
||||
}
|
||||
|
||||
std::string readNumber() {
|
||||
size_t start = pos;
|
||||
while (pos < input.size() && std::isdigit(input[pos])) ++pos;
|
||||
return input.substr(start, pos - start);
|
||||
}
|
||||
};
|
||||
|
||||
// AST Nodes
|
||||
struct ASTNode {
|
||||
virtual ~ASTNode() = default;
|
||||
virtual void print(int indent = 0) const = 0;
|
||||
virtual void generateAssembly(std::ofstream& out) const = 0;
|
||||
};
|
||||
|
||||
struct ExpressionNode : public ASTNode {
|
||||
std::string value;
|
||||
ExpressionNode(std::string value) : value(std::move(value)) {}
|
||||
|
||||
void print(int indent = 0) const override {
|
||||
std::cout << std::string(indent, ' ') << "Number: " << value << std::endl;
|
||||
}
|
||||
|
||||
void generateAssembly(std::ofstream& out) const override {
|
||||
out << "\tmov eax, " << value << "\n";
|
||||
}
|
||||
};
|
||||
|
||||
struct BinaryOpNode : public ASTNode {
|
||||
std::unique_ptr<ASTNode> left;
|
||||
std::unique_ptr<ASTNode> right;
|
||||
TokenType op;
|
||||
|
||||
BinaryOpNode(std::unique_ptr<ASTNode> left, TokenType op, std::unique_ptr<ASTNode> right)
|
||||
: left(std::move(left)), op(op), right(std::move(right)) {}
|
||||
|
||||
void print(int indent = 0) const override {
|
||||
std::cout << std::string(indent, ' ') << "BinaryOp: ";
|
||||
left->print(indent + 2);
|
||||
std::cout << std::string(indent + 2, ' ') << (op == TokenType::PLUS ? "+" :
|
||||
op == TokenType::MINUS ? "-" :
|
||||
op == TokenType::MULT ? "*" : "/") << std::endl;
|
||||
right->print(indent + 2);
|
||||
}
|
||||
|
||||
void generateAssembly(std::ofstream& out) const override {
|
||||
left->generateAssembly(out);
|
||||
out << "\tpush eax\n";
|
||||
right->generateAssembly(out);
|
||||
out << "\tpop ebx\n";
|
||||
|
||||
switch (op) {
|
||||
case TokenType::PLUS: out << "\tadd eax, ebx\n"; break;
|
||||
case TokenType::MINUS: out << "\tsub eax, ebx\n"; break;
|
||||
case TokenType::MULT: out << "\timul eax, ebx\n"; break;
|
||||
case TokenType::DIV: out << "\tcdq\n\tidiv ebx\n"; break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct AssignmentNode : public ASTNode {
|
||||
std::string varName;
|
||||
std::unique_ptr<ASTNode> expression;
|
||||
|
||||
AssignmentNode(std::string varName, std::unique_ptr<ASTNode> expression)
|
||||
: varName(std::move(varName)), expression(std::move(expression)) {}
|
||||
|
||||
void print(int indent = 0) const override {
|
||||
std::cout << std::string(indent, ' ') << "Assignment: " << varName << " = " << std::endl;
|
||||
expression->print(indent + 2);
|
||||
}
|
||||
|
||||
void generateAssembly(std::ofstream& out) const override {
|
||||
expression->generateAssembly(out);
|
||||
out << "\tmov [" << varName << "], eax\n";
|
||||
}
|
||||
};
|
||||
|
||||
struct FunctionNode : public ASTNode {
|
||||
std::string name;
|
||||
std::vector<std::unique_ptr<ASTNode>> body;
|
||||
|
||||
FunctionNode(std::string name) : name(std::move(name)) {}
|
||||
|
||||
void print(int indent = 0) const override {
|
||||
std::cout << "Function: " << name << std::endl;
|
||||
for (const auto& stmt : body) {
|
||||
stmt->print(indent + 2);
|
||||
}
|
||||
}
|
||||
|
||||
void generateAssembly(std::ofstream& out) const override {
|
||||
out << "." << name << ":\n";
|
||||
for (const auto& stmt : body) {
|
||||
stmt->generateAssembly(out);
|
||||
}
|
||||
out << "\tret\n";
|
||||
}
|
||||
};
|
||||
|
||||
struct StatementNode : public ASTNode {
|
||||
|
||||
};
|
||||
|
||||
|
||||
struct VariableDeclarationNode : public StatementNode {
|
||||
std::string name;
|
||||
std::unique_ptr<ExpressionNode> value;
|
||||
|
||||
void print(int indent = 0) const override {
|
||||
std::cout << std::string(indent, ' ') << "VarDecl: " << name << std::endl;
|
||||
}
|
||||
|
||||
void generateAssembly(std::ofstream& out) const override {}
|
||||
};
|
||||
|
||||
struct IfNode : public StatementNode {
|
||||
std::unique_ptr<ExpressionNode> condition;
|
||||
std::vector<std::unique_ptr<ASTNode>> thenBranch;
|
||||
std::vector<std::unique_ptr<ASTNode>> elseBranch;
|
||||
|
||||
void print(int indent = 0) const override {
|
||||
std::cout << std::string(indent, ' ') << "If Statement" << std::endl;
|
||||
}
|
||||
|
||||
void generateAssembly(std::ofstream& out) const override {}
|
||||
};
|
||||
|
||||
struct WhileNode : public StatementNode {
|
||||
std::unique_ptr<ExpressionNode> condition;
|
||||
std::vector<std::unique_ptr<ASTNode>> body;
|
||||
|
||||
void print(int indent = 0) const override {
|
||||
std::cout << std::string(indent, ' ') << "While Statement" << std::endl;
|
||||
}
|
||||
|
||||
void generateAssembly(std::ofstream& out) const override {}
|
||||
};
|
||||
|
||||
|
||||
|
||||
class Parser {
|
||||
public:
|
||||
Parser(const std::vector<Token>& tokens) : tokens(tokens), pos(0) {}
|
||||
|
||||
std::unique_ptr<ASTNode> parse() {
|
||||
if (match(TokenType::FUNC)) {
|
||||
consume(TokenType::FUNC);
|
||||
std::string funcName = consume(TokenType::IDENTIFIER).value;
|
||||
consume(TokenType::LPAREN);
|
||||
consume(TokenType::RPAREN);
|
||||
consume(TokenType::LBRACE);
|
||||
std::vector<std::unique_ptr<StatementNode>> body;
|
||||
while (!match(TokenType::RBRACE)) {
|
||||
body.push_back(parseStatement());
|
||||
}
|
||||
consume(TokenType::RBRACE);
|
||||
return std::make_unique<FunctionNode>(funcName);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
private:
|
||||
const std::vector<Token>& tokens;
|
||||
size_t pos;
|
||||
|
||||
bool match(TokenType type) {
|
||||
return pos < tokens.size() && tokens[pos].type == type;
|
||||
}
|
||||
|
||||
Token consume(TokenType type) {
|
||||
if (match(type)) {
|
||||
return tokens[pos++];
|
||||
}
|
||||
std::cout << "type: " << (int)type << std::endl;
|
||||
throw std::runtime_error("Unexpected token: expected " + std::to_string(static_cast<int>(type)) +
|
||||
", got " + std::to_string(static_cast<int>(tokens[pos].type)) +
|
||||
" (" + tokens[pos].value + ")");
|
||||
}
|
||||
|
||||
std::unique_ptr<StatementNode> parseStatement() { return nullptr; }
|
||||
};
|
||||
|
||||
int main() {
|
||||
std::string code = R"(
|
||||
|
||||
def MaFonction()
|
||||
var x
|
||||
x = 5 + 3
|
||||
|
||||
|
||||
)";
|
||||
Lexer lexer(code);
|
||||
std::vector<Token> tokens = lexer.tokenize();
|
||||
|
||||
for (const auto& token : tokens) {
|
||||
std::cout << "Token: " << static_cast<int>(token.type) << " (" << token.value << ")\n";
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
Parser parser(tokens);
|
||||
std::unique_ptr<ASTNode> ast = parser.parse();
|
||||
|
||||
|
||||
|
||||
if (ast) {
|
||||
ast->print();
|
||||
|
||||
std::ofstream outFile("output.asm");
|
||||
if (outFile.is_open()) {
|
||||
ast->generateAssembly(outFile);
|
||||
outFile.close();
|
||||
std::cout << "Code assembleur généré dans output.asm" << std::endl;
|
||||
} else {
|
||||
std::cerr << "Erreur lors de l'ouverture du fichier" << std::endl;
|
||||
}
|
||||
} else {
|
||||
std::cerr << "Erreur de parsing" << std::endl;
|
||||
}
|
||||
|
||||
} catch(const std::exception &e) {
|
||||
std::cerr << "Erreur de parsing: " << e.what() << std::endl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -2,6 +2,38 @@
|
|||
|
||||
#include "sys_lib.h"
|
||||
#include "i_story_project.h"
|
||||
#include "base_node.h"
|
||||
#include "connection.h"
|
||||
|
||||
struct AstNode
|
||||
{
|
||||
std::shared_ptr<BaseNode> node; // pointeur vers le noeud en cours
|
||||
|
||||
std::vector<std::shared_ptr<AstNode>> inputs;
|
||||
std::shared_ptr<AstNode> condition; // Pour les boucles et les branchements
|
||||
std::vector<std::shared_ptr<AstNode>> body; // Pour les boucles et les branchements
|
||||
std::shared_ptr<AstNode> elseBody; // Pour les branchements
|
||||
|
||||
std::pair<int, int> position;
|
||||
};
|
||||
|
||||
|
||||
// AST (Arbre de syntaxe abstraite)
|
||||
struct AST {
|
||||
|
||||
std::map<std::string, int> variables; // Stockage des variables (adresses mémoire)
|
||||
std::string assemblyCode;
|
||||
int labelCounter = 0;
|
||||
std::map<std::string, std::shared_ptr<AstNode>> nodeMap;
|
||||
|
||||
// Fonction pour générer un label unique
|
||||
std::string generateLabel(AST& ast) {
|
||||
return "label" + std::to_string(ast.labelCounter++);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
class Compiler
|
||||
{
|
||||
|
|
@ -10,7 +42,110 @@ public:
|
|||
Compiler() = default;
|
||||
~Compiler() = default;
|
||||
|
||||
|
||||
static std::string FileToConstant(const std::string &FileName, const std::string &extension, IStoryProject &project);
|
||||
|
||||
|
||||
// Fonction pour construire l'AST à partir des nœuds et des connexions
|
||||
void buildAST(std::vector<std::shared_ptr<BaseNode>>& nodes, std::vector<std::shared_ptr<Connection>>& connections) {
|
||||
|
||||
m_ast.nodeMap.clear();
|
||||
|
||||
// Créer une map pour accéder aux nœuds par ID
|
||||
int x = 0, y = 0;
|
||||
for (auto& node : nodes) {
|
||||
auto astNode = std::make_shared<AstNode>();
|
||||
|
||||
astNode->position = {0, 0};
|
||||
x += 10; // Espacement horizontal
|
||||
if (x > 50) { // Nouvelle ligne
|
||||
x = 0;
|
||||
y += 5; // Espacement vertical
|
||||
}
|
||||
|
||||
astNode->node = node;
|
||||
m_ast.nodeMap[node->GetId()] = astNode;
|
||||
}
|
||||
|
||||
// Construire les connexions entre les nœuds
|
||||
for (auto& connection : connections) {
|
||||
std::shared_ptr<AstNode> outNode = m_ast.nodeMap[connection->outNodeId];
|
||||
std::shared_ptr<AstNode> inNode = m_ast.nodeMap[connection->inNodeId];
|
||||
inNode->inputs.push_back(outNode); // Ajoute le noeud de sortie en entrée du noeud d'entrée
|
||||
}
|
||||
|
||||
// Gestion des conditions et des corps de boucles/branches
|
||||
/*
|
||||
for(auto& node : nodes) {
|
||||
if (node.type == Node::Type::LOOP || node.type == Node::Type::BRANCH){
|
||||
for (auto& connection : connections) {
|
||||
if (connection.inNodeId == node.id && connection.inPortIndex == 0) { // Condition
|
||||
node.condition = nodeMap[connection.outNodeId];
|
||||
}
|
||||
if (connection.inNodeId == node.id && connection.inPortIndex == 1) { // Body
|
||||
node.body.push_back(nodeMap[connection.outNodeId]);
|
||||
}
|
||||
if (node.type == Node::Type::BRANCH && connection.inNodeId == node.id && connection.inPortIndex == 2) { // ElseBody
|
||||
if(node.elseBody == nullptr) {
|
||||
node.elseBody = new Node(Node::Type::VARIABLE, "dummy"); // Créer un noeud dummy juste pour l'elsebody.
|
||||
node.elseBody->body.push_back(nodeMap[connection.outNodeId]);
|
||||
} else {
|
||||
node.elseBody->body.push_back(nodeMap[connection.outNodeId]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Fonction pour afficher le schéma des nœuds
|
||||
void displayNodeSchema() {
|
||||
|
||||
// Afficher les nœuds
|
||||
for (auto& astNode : m_ast.nodeMap) {
|
||||
auto pos = astNode.second->position;
|
||||
std::cout << "\033[" << pos.second + 1 << ";" << pos.first + 1 << "H"; // Déplacer le curseur
|
||||
std::cout << "[" << astNode.second->node->GetTypeName() << "]";
|
||||
}
|
||||
/*
|
||||
// Afficher les connexions
|
||||
for (auto& connection : connections) {
|
||||
auto outPos = nodePositions[connection.outNodeId];
|
||||
auto inPos = nodePositions[connection.inNodeId];
|
||||
|
||||
// Dessiner une ligne entre les nœuds (simplifié)
|
||||
int startX = outPos.first + 10;
|
||||
int startY = outPos.second + 1;
|
||||
int endX = inPos.first;
|
||||
int endY = inPos.second + 1;
|
||||
|
||||
if (startY == endY) { // Ligne horizontale
|
||||
for (int i = startX; i < endX; ++i) {
|
||||
std::cout << "\033[" << startY << ";" << i + 1 << "H-";
|
||||
}
|
||||
} else { // Ligne verticale + horizontale
|
||||
for (int i = startX; i < startX + (endX - startX) / 2; ++i) {
|
||||
std::cout << "\033[" << startY << ";" << i + 1 << "H-";
|
||||
}
|
||||
for (int i = std::min(startY, endY); i < std::max(startY, endY); ++i) {
|
||||
std::cout << "\033[" << i + 1 << ";" << startX + (endX - startX) / 2 + 1 << "H|";
|
||||
}
|
||||
for (int i = startX + (endX - startX) / 2 + 1; i < endX; ++i) {
|
||||
std::cout << "\033[" << endY << ";" << i + 1 << "H-";
|
||||
}
|
||||
}
|
||||
std::cout << "\033[" << endY << ";" << endX << "H>";
|
||||
}
|
||||
|
||||
std::cout << "\033[" << 100 << ";" << 1 << "H"; // Déplacer le curseur en bas
|
||||
|
||||
*/
|
||||
}
|
||||
|
||||
private:
|
||||
AST m_ast;
|
||||
|
||||
};
|
||||
|
|
|
|||
53
core/story-manager/src/print_node.cpp
Normal file
53
core/story-manager/src/print_node.cpp
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
#include "print_node.h"
|
||||
#include "story_project.h"
|
||||
#include "connection.h"
|
||||
#include "sys_lib.h"
|
||||
#include "compiler.h"
|
||||
|
||||
|
||||
PrintNode::PrintNode(const std::string &type)
|
||||
: BaseNode(type, "Print Node")
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
void PrintNode::Initialize()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
std::string PrintNode::GenerateConstants(IStoryPage &page, IStoryProject &project, int nb_out_conns)
|
||||
{
|
||||
std::string s;
|
||||
|
||||
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
std::string PrintNode::Build(IStoryPage &page, const StoryOptions &options, int nb_out_conns)
|
||||
{
|
||||
std::stringstream ss;
|
||||
|
||||
std::list<std::shared_ptr<Connection>> conns;
|
||||
page.GetNodeConnections(conns, GetId());
|
||||
int i = 0;
|
||||
std::list<std::shared_ptr<Connection>>::iterator c = conns.begin();
|
||||
|
||||
if (conns.size() == 2)
|
||||
{
|
||||
ss << R"(; ---------------------------- )"
|
||||
<< GetTitle()
|
||||
<< " Type: Branch"
|
||||
<< "\n";
|
||||
|
||||
ss << "eq r0, r0, r1\n"
|
||||
<< "skipz r0\n"
|
||||
<< "jump " << BaseNode::GetEntryLabel((*c)->inNodeId);
|
||||
++c;
|
||||
ss << "jump " << BaseNode::GetEntryLabel((*c)->inNodeId);
|
||||
}
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
21
core/story-manager/src/print_node.h
Normal file
21
core/story-manager/src/print_node.h
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include "i_story_manager.h"
|
||||
#include "base_node.h"
|
||||
#include "i_script_node.h"
|
||||
#include "i_story_project.h"
|
||||
|
||||
class PrintNode : public BaseNode
|
||||
{
|
||||
public:
|
||||
PrintNode(const std::string &type);
|
||||
|
||||
virtual void Initialize() override;
|
||||
virtual std::string Build(IStoryPage &page, const StoryOptions &options, int nb_out_conns) override;
|
||||
virtual std::string GenerateConstants(IStoryPage &page, IStoryProject &project, int nb_out_conns) override;
|
||||
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
16
core/story-manager/tests/CMakeLists.txt
Normal file
16
core/story-manager/tests/CMakeLists.txt
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
cmake_minimum_required(VERSION 3.5)
|
||||
|
||||
project(compiler_test LANGUAGES CXX C)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
add_executable(${PROJECT_NAME}
|
||||
main.cpp
|
||||
test_ast.cpp
|
||||
|
||||
../../chip32/chip32_assembler.cpp
|
||||
../../chip32/chip32_vm.c
|
||||
)
|
||||
|
||||
target_include_directories(${PROJECT_NAME} PRIVATE ../../chip32)
|
||||
17966
core/story-manager/tests/catch.hpp
Normal file
17966
core/story-manager/tests/catch.hpp
Normal file
File diff suppressed because it is too large
Load diff
46
core/story-manager/tests/main.cpp
Normal file
46
core/story-manager/tests/main.cpp
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2022 Anthony Rabine
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#define CATCH_CONFIG_MAIN
|
||||
#include "catch.hpp"
|
||||
|
||||
void hexdump(void *ptr, int buflen) {
|
||||
unsigned char *buf = (unsigned char*)ptr;
|
||||
int i, j;
|
||||
for (i=0; i<buflen; i+=16) {
|
||||
printf("%06x: ", i);
|
||||
for (j=0; j<16; j++)
|
||||
if (i+j < buflen)
|
||||
printf("%02x ", buf[i+j]);
|
||||
else
|
||||
printf(" ");
|
||||
printf(" ");
|
||||
for (j=0; j<16; j++)
|
||||
if (i+j < buflen)
|
||||
printf("%c", isprint(buf[i+j]) ? buf[i+j] : '.');
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
82
core/story-manager/tests/test_ast.cpp
Normal file
82
core/story-manager/tests/test_ast.cpp
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2022 Anthony Rabine
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <thread>
|
||||
|
||||
#include "catch.hpp"
|
||||
#include "chip32_assembler.h"
|
||||
#include "chip32_macros.h"
|
||||
#include "compiler.h"
|
||||
#include "branch_node.h"
|
||||
#include "print_node.h"
|
||||
#include "variable_node.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
TEST_CASE( "Check various indentations and typos" ) {
|
||||
|
||||
Compiler compiler;
|
||||
|
||||
auto printNode = std::make_shared<PrintNode>();
|
||||
auto branchNode = std::make_shared<BranchNode>();
|
||||
|
||||
|
||||
std::vector<std::shared_ptr<BaseNode>> nodes;
|
||||
|
||||
nodes.push_back(printNode);
|
||||
nodes.push_back(branchNode);
|
||||
|
||||
std::vector<std::shared_ptr<Connection>> connections;
|
||||
|
||||
auto cn1 = std::make_shared<Connection>();
|
||||
|
||||
// // Création des nœuds
|
||||
// std::vector<Node> nodes = {
|
||||
// Node(Node::Type::VARIABLE, "i", "node_i"),
|
||||
// Node(Node::Type::CONSTANT, 10, "node_10"),
|
||||
// Node(Node::Type::SUBTRACT, "node_subtract"),
|
||||
// Node(Node::Type::CONSTANT, 1, "node_1"),
|
||||
// Node(Node::Type::ADD, "node_add"),
|
||||
// Node(Node::Type::ASSIGN, "i", "node_assign"),
|
||||
// Node(Node::Type::VARIABLE, "conditionVar", "node_condVar"),
|
||||
// Node(Node::Type::CONSTANT, 2, "node_2"),
|
||||
// Node(Node::Type::MULTIPLY, "node_multiply"),
|
||||
// Node(Node::Type::ASSIGN, "i", "node_assign_multiply"),
|
||||
// Node(Node::Type::BRANCH, "node_branch"),
|
||||
// Node(Node::Type::LOOP, "node_loop")
|
||||
// };
|
||||
|
||||
|
||||
|
||||
// Construction de l'AST
|
||||
AST ast = buildAST(nodes, connections);
|
||||
|
||||
|
||||
|
||||
REQUIRE( parseResult == true );
|
||||
|
||||
}
|
||||
Loading…
Reference in a new issue