// ============================================================================ // saQut Compiler — AST Analizi ve Sembol Toplayıcı // ============================================================================ // // DİZİN: src/json.hpp // KATMAN: Tüm katmanlardan sonra — AST'yi tüketir // BAĞIMLI: AST (src/parser/ast.hpp) // KULLANAN: main.cpp // // AMAÇ: // 1. AST üzerinde analiz yap (düğüm sayısı, derinlik, tip dağılımı) // 2. Sembolleri topla (fonksiyon isimleri, dönüş tipleri, değişkenler) // // NOT: JSON serileştirme ASTNode::toJson() tarafından yapılır. // Bu dosya sadece analiz ve sembol toplama işlemlerini içerir. // Yeni bir AST düğümü eklendiğinde buraya dokunmak gerekmez. // // ============================================================================ #ifndef SAQUT_JSON #define SAQUT_JSON #include #include #include #include #include "parser/ast.hpp" // ============================================================================ // astKindName — ASTKind enum'unu string'e çevir (analiz çıktısı için) // ============================================================================ inline const char* astKindName(ASTKind k) { switch (k) { case ASTKind::Program: return "Program"; case ASTKind::FunctionDecl: return "FunctionDecl"; case ASTKind::Block: return "Block"; case ASTKind::VariableDecl: return "VariableDecl"; case ASTKind::BinaryExpression: return "BinaryExpression"; case ASTKind::UnaryExpression: return "UnaryExpression"; case ASTKind::Literal: return "Literal"; case ASTKind::Identifier: return "Identifier"; case ASTKind::Postfix: return "Postfix"; case ASTKind::IfStatement: return "IfStatement"; case ASTKind::ForStatement: return "ForStatement"; case ASTKind::WhileStatement: return "WhileStatement"; case ASTKind::DoWhileStatement: return "DoWhileStatement"; case ASTKind::ReturnStatement: return "ReturnStatement"; case ASTKind::BreakStatement: return "BreakStatement"; case ASTKind::ContinueStatement: return "ContinueStatement"; case ASTKind::ExpressionStatement: return "ExpressionStatement"; case ASTKind::Call: return "Call"; case ASTKind::MemberAccess: return "MemberAccess"; case ASTKind::IndexExpression: return "IndexExpression"; case ASTKind::StructDecl: return "StructDecl"; default: return "Unknown"; } } // ============================================================================ // AST → JSON (ince sarmalayıcı — asıl iş ASTNode::toJson()'da) // ============================================================================ inline std::string astToJson(ASTNode* node, int depth = 0) { if (!node) return "null"; return node->toJson(depth); } // ============================================================================ // AST Analizi // ============================================================================ struct AstAnalysis { int totalNodes = 0; int maxDepth = 0; int functionCount = 0; int variableCount = 0; int ifCount = 0; int loopCount = 0; // for + while + do-while std::map nodeTypeCounts; }; inline void analyzeRecursive(ASTNode* node, int currentDepth, AstAnalysis& a) { if (!node) return; a.totalNodes++; if (currentDepth > a.maxDepth) a.maxDepth = currentDepth; const char* name = astKindName(node->kind); a.nodeTypeCounts[name]++; switch (node->kind) { case ASTKind::FunctionDecl: a.functionCount++; break; case ASTKind::VariableDecl: a.variableCount++; break; case ASTKind::IfStatement: a.ifCount++; break; case ASTKind::WhileStatement: case ASTKind::ForStatement: case ASTKind::DoWhileStatement: a.loopCount++; break; default: break; } // Tüm çocukları gez switch (node->kind) { case ASTKind::Program: case ASTKind::FunctionDecl: case ASTKind::Block: { for (auto* child : node->getChildren()) analyzeRecursive(child, currentDepth + 1, a); break; } case ASTKind::VariableDecl: { auto* vd = (VariableDeclNode*)node; if (vd->initExpr) analyzeRecursive(vd->initExpr, currentDepth + 1, a); break; } case ASTKind::BinaryExpression: { auto* bin = (BinaryExpressionNode*)node; if (bin->Left) analyzeRecursive(bin->Left, currentDepth + 1, a); if (bin->Right) analyzeRecursive(bin->Right, currentDepth + 1, a); break; } case ASTKind::Postfix: { auto* pf = (PostfixNode*)node; if (pf->operand) analyzeRecursive(pf->operand, currentDepth + 1, a); break; } case ASTKind::IfStatement: { auto* ifn = (IfStatementNode*)node; if (ifn->condition) analyzeRecursive(ifn->condition, currentDepth + 1, a); if (ifn->thenBranch) analyzeRecursive(ifn->thenBranch, currentDepth + 1, a); if (ifn->elseBranch) analyzeRecursive(ifn->elseBranch, currentDepth + 1, a); break; } case ASTKind::WhileStatement: { auto* ws = (WhileStatementNode*)node; if (ws->condition) analyzeRecursive(ws->condition, currentDepth + 1, a); if (ws->body) analyzeRecursive(ws->body, currentDepth + 1, a); break; } case ASTKind::ForStatement: { auto* fs = (ForStatementNode*)node; if (fs->init) analyzeRecursive(fs->init, currentDepth + 1, a); if (fs->condition) analyzeRecursive(fs->condition, currentDepth + 1, a); if (fs->update) analyzeRecursive(fs->update, currentDepth + 1, a); if (fs->body) analyzeRecursive(fs->body, currentDepth + 1, a); break; } case ASTKind::DoWhileStatement: { auto* dw = (DoWhileStatementNode*)node; if (dw->body) analyzeRecursive(dw->body, currentDepth + 1, a); if (dw->condition) analyzeRecursive(dw->condition, currentDepth + 1, a); break; } case ASTKind::ReturnStatement: { auto* rs = (ReturnStatementNode*)node; if (rs->value) analyzeRecursive(rs->value, currentDepth + 1, a); break; } case ASTKind::ExpressionStatement: { auto* es = (ExpressionStatementNode*)node; if (es->expression) analyzeRecursive(es->expression, currentDepth + 1, a); break; } case ASTKind::Call: { auto* call = (CallExpressionNode*)node; if (call->callee) analyzeRecursive(call->callee, currentDepth + 1, a); for (auto* arg : call->arguments) analyzeRecursive(arg, currentDepth + 1, a); break; } case ASTKind::MemberAccess: { auto* ma = (MemberAccessNode*)node; if (ma->object) analyzeRecursive(ma->object, currentDepth + 1, a); break; } case ASTKind::IndexExpression: { auto* ie = (IndexExpressionNode*)node; if (ie->object) analyzeRecursive(ie->object, currentDepth + 1, a); if (ie->index) analyzeRecursive(ie->index, currentDepth + 1, a); break; } case ASTKind::StructDecl: { for (auto* child : node->getChildren()) analyzeRecursive(child, currentDepth + 1, a); break; } default: break; // Literal, Identifier, Break, Continue — yaprak düğüm } } inline AstAnalysis analyzeAst(ASTNode* root) { AstAnalysis a; analyzeRecursive(root, 0, a); return a; } inline std::string analysisToJson(const AstAnalysis& a) { std::ostringstream ss; ss << " \"totalNodes\": " << a.totalNodes << ",\n" << " \"maxDepth\": " << a.maxDepth << ",\n" << " \"functionCount\": " << a.functionCount << ",\n" << " \"variableCount\": " << a.variableCount << ",\n" << " \"ifCount\": " << a.ifCount << ",\n" << " \"loopCount\": " << a.loopCount << ",\n" << " \"nodeTypes\": {\n"; bool first = true; for (auto& [name, count] : a.nodeTypeCounts) { if (!first) ss << ",\n"; ss << " \"" << name << "\": " << count; first = false; } ss << "\n }"; return ss.str(); } // ============================================================================ // Sembol Toplayıcı // ============================================================================ struct SymbolEntry { std::string name; std::string kind; // "function" veya "variable" std::string type; // Dönüş tipi veya değişken tipi }; inline void collectSymbolsRecursive(ASTNode* node, std::vector& symbols) { if (!node) return; // Sadece FunctionDecl ve VariableDecl toplanır — diğerleri gezilir if (node->kind == ASTKind::FunctionDecl) { auto* fn = (FunctionDeclNode*)node; symbols.push_back({fn->name, "function", fn->returnType}); } else if (node->kind == ASTKind::StructDecl) { auto* st = (StructDeclNode*)node; symbols.push_back({st->name, "struct", ""}); } else if (node->kind == ASTKind::VariableDecl) { auto* vd = (VariableDeclNode*)node; symbols.push_back({vd->name, "variable", vd->varType}); } // Çocukları gez switch (node->kind) { case ASTKind::Program: case ASTKind::FunctionDecl: case ASTKind::Block: for (auto* child : node->getChildren()) collectSymbolsRecursive(child, symbols); break; case ASTKind::VariableDecl: { auto* vd = (VariableDeclNode*)node; if (vd->initExpr) collectSymbolsRecursive(vd->initExpr, symbols); break; } case ASTKind::BinaryExpression: { auto* bin = (BinaryExpressionNode*)node; if (bin->Left) collectSymbolsRecursive(bin->Left, symbols); if (bin->Right) collectSymbolsRecursive(bin->Right, symbols); break; } case ASTKind::Postfix: { auto* pf = (PostfixNode*)node; if (pf->operand) collectSymbolsRecursive(pf->operand, symbols); break; } case ASTKind::IfStatement: { auto* ifn = (IfStatementNode*)node; if (ifn->condition) collectSymbolsRecursive(ifn->condition, symbols); if (ifn->thenBranch) collectSymbolsRecursive(ifn->thenBranch, symbols); if (ifn->elseBranch) collectSymbolsRecursive(ifn->elseBranch, symbols); break; } case ASTKind::WhileStatement: { auto* ws = (WhileStatementNode*)node; if (ws->condition) collectSymbolsRecursive(ws->condition, symbols); if (ws->body) collectSymbolsRecursive(ws->body, symbols); break; } case ASTKind::ForStatement: { auto* fs = (ForStatementNode*)node; if (fs->init) collectSymbolsRecursive(fs->init, symbols); if (fs->condition) collectSymbolsRecursive(fs->condition, symbols); if (fs->update) collectSymbolsRecursive(fs->update, symbols); if (fs->body) collectSymbolsRecursive(fs->body, symbols); break; } case ASTKind::DoWhileStatement: { auto* dw = (DoWhileStatementNode*)node; if (dw->body) collectSymbolsRecursive(dw->body, symbols); if (dw->condition) collectSymbolsRecursive(dw->condition, symbols); break; } case ASTKind::ReturnStatement: { auto* rs = (ReturnStatementNode*)node; if (rs->value) collectSymbolsRecursive(rs->value, symbols); break; } case ASTKind::ExpressionStatement: { auto* es = (ExpressionStatementNode*)node; if (es->expression) collectSymbolsRecursive(es->expression, symbols); break; } case ASTKind::Call: { auto* call = (CallExpressionNode*)node; if (call->callee) collectSymbolsRecursive(call->callee, symbols); for (auto* arg : call->arguments) collectSymbolsRecursive(arg, symbols); break; } case ASTKind::MemberAccess: { auto* ma = (MemberAccessNode*)node; if (ma->object) collectSymbolsRecursive(ma->object, symbols); break; } case ASTKind::IndexExpression: { auto* ie = (IndexExpressionNode*)node; if (ie->object) collectSymbolsRecursive(ie->object, symbols); if (ie->index) collectSymbolsRecursive(ie->index, symbols); break; } case ASTKind::StructDecl: { for (auto* child : node->getChildren()) collectSymbolsRecursive(child, symbols); break; } default: break; } } inline std::vector collectSymbols(ASTNode* root) { std::vector symbols; collectSymbolsRecursive(root, symbols); return symbols; } #endif // SAQUT_JSON