<commit_before>//
//  orbit/ast/ast_printer.c
//  Orbit - AST
//
//  Created by <NAME> on 2017-09-26.
//  Copyright © 2017 <NAME>. All rights reserved.
//
#include <stdio.h>
#include <orbit/ast/ast.h>

static void ast_printReturn(FILE* out, int depth) {
    fputs("\n", out);
    for(int i = 0; i < depth; ++i) {
        fputs("   ", out);
    }
    fputs("|", out);
}

static void ast_printToken(FILE* out, OCToken token) {
    fputs("`", out);
    const char* current = token.start;
    for(uint64_t i = 0; i < token.length; ++i) {
        fputc(*(current++), out);
    }
    fputs("`", out);
    //fprintf(out, "`%*.s`", (int)token->length, token->start);
}

static void ast_printNode(FILE* out, const char* prefix, AST* ast, int depth) {
    if(ast == NULL) { return; }
    ast_printReturn(out, depth);
    fprintf(out, "_%s", prefix);
    
    switch(ast->type) {
    case AST_LIST:
        ast_printNode(out, "", ast->list.head, depth+1);
        break;
        
    case AST_CONDITIONAL:
        fprintf(out, "conditional");
        ast_printNode(out, "condition:", ast->conditionalStmt.condition, depth+1);
        ast_printNode(out, "if-body:", ast->conditionalStmt.ifBody, depth+1);
        ast_printNode(out, "else-body:", ast->conditionalStmt.elseBody, depth+1);
        break;
    
    case AST_FOR_IN:
        fprintf(out, "for-in ");
        ast_printToken(out, ast->forInLoop.variable);
        ast_printNode(out, "collection:", ast->forInLoop.collection, depth+1);
        ast_printNode(out, "body:", ast->forInLoop.body, depth+1);
        break;
    
    case AST_WHILE:
        fprintf(out, "while");
        ast_printNode(out, "condition:", ast->whileLoop.condition, depth+1);
        ast_printNode(out, "body:", ast->whileLoop.body, depth+1);
        break;
    
    case AST_BREAK:
        fprintf(out, "break");
        break;
        
    case AST_CONTINUE:
        fprintf(out, "continue");
        break;
        
    case AST_RETURN:
        fprintf(out, "return");
        ast_printNode(out, "value:", ast->returnStmt.returnValue, depth+1);
        break;
    
    // DECLARATIONS
    case AST_DECL_MODULE:
        fprintf(out, "module-decl `%s`", ast->moduleDecl.symbol);
        ast_printNode(out, "body:", ast->moduleDecl.body, depth+1);
        break;
    
    case AST_DECL_FUNC:
        fprintf(out, "func-decl ");
        ast_printToken(out, ast->funcDecl.symbol);
        ast_printNode(out, "params:", ast->funcDecl.params, depth+1);
        ast_printNode(out, "returns:", ast->funcDecl.returnType, depth+1);
        ast_printNode(out, "body:", ast->funcDecl.body, depth+1);
        break;
    
    case AST_DECL_VAR:
        fprintf(out, "var-decl ");
        ast_printToken(out, ast->varDecl.symbol);
        ast_printNode(out, "type:", ast->varDecl.typeAnnotation, depth+1);
        break;
    
    case AST_DECL_STRUCT:
        fprintf(out, "usertype-decl");
        ast_printToken(out, ast->structDecl.symbol);
        ast_printNode(out, "constructor:", ast->structDecl.constructor, depth+1);
        ast_printNode(out, "destructor:", ast->structDecl.destructor, depth+1);
        ast_printNode(out, "members:", ast->structDecl.fields, depth+1);
        break;
        
    // EXPRESSIONS
    case AST_EXPR_UNARY:
        ast_printToken(out, ast->unaryExpr.operator);
        ast_printNode(out, "", ast->unaryExpr.rhs, depth+1);
        break;
    
    case AST_EXPR_BINARY:
        ast_printToken(out, ast->binaryExpr.operator);
        ast_printNode(out, "", ast->binaryExpr.lhs, depth+1);
        ast_printNode(out, "", ast->binaryExpr.rhs, depth+1);
        break;
    
    case AST_EXPR_CALL:
        fprintf(out, "call ");
        ast_printNode(out, "symbol:", ast->callExpr.symbol, depth+1);
        ast_printNode(out, "params:", ast->callExpr.params, depth+1);
        break;
        
    case AST_EXPR_SUBSCRIPT:
        fprintf(out, "subscript ");
        ast_printNode(out, "symbol:", ast->subscriptExpr.symbol, depth+1);
        ast_printNode(out, "subscript:", ast->subscriptExpr.subscript, depth+1);
        break;
    
    case AST_EXPR_CONSTANT:
        fprintf(out, "constant ");
        ast_printToken(out, ast->constantExpr.symbol);
        break;
    
    case AST_EXPR_NAME:
        fprintf(out, "symbol ");
        ast_printToken(out, ast->nameExpr.symbol);
        break;
    
    case AST_TYPEEXPR_SIMPLE:
        fprintf(out, "type ");
        ast_printToken(out, ast->simpleType.symbol);
        break;
        
    case AST_TYPEEXPR_FUNC:
        fprintf(out, "func-type");
        ast_printNode(out, "returns:", ast->funcType.returnType, depth+1);
        ast_printNode(out, "params:", ast->funcType.params, depth+1);
        break;
        
    case AST_TYPEEXPR_ARRAY:
        fprintf(out, "array-type");
        ast_printNode(out, "elements:", ast->arrayType.elementType, depth+1);
        break;
        
    case AST_TYPEEXPR_MAP:
        fprintf(out, "map-type");
        ast_printNode(out, "keys:", ast->mapType.keyType, depth+1);
        ast_printNode(out, "elements:", ast->mapType.elementType, depth+1);
        break;
    }
    
    ast_printNode(out, "", ast->next, depth);
}

void ast_print(FILE* out, AST* ast) {
    ast_printNode(out, "", ast, 0);
    fputs("\n\n", out);
}<commit_msg>Improve legibility of the AST dump slightly<commit_after>//
//  orbit/ast/ast_printer.c
//  Orbit - AST
//
//  Created by <NAME> on 2017-09-26.
//  Copyright © 2017 <NAME>. All rights reserved.
//
#include <stdio.h>
#include <stdbool.h>
#include <orbit/ast/ast.h>

static void ast_printReturn(FILE* out, int depth, bool last) {
    fputs("\n", out);
    for(int i = 0; i < depth; ++i) {
        fputs("  ", out);
    }
    fputs((last ? "`-" : "|-"), out);
}

static void ast_printToken(FILE* out, OCToken token) {
    fputs("'", out);
    const char* current = token.start;
    for(uint64_t i = 0; i < token.length; ++i) {
        fputc(*(current++), out);
    }
    fputs("'", out);
}

static void ast_printNode(FILE* out, AST* ast, int depth, bool last) {
    if(ast == NULL) { return; }
    ast_printReturn(out, depth, last);
    
    switch(ast->type) {
    case AST_LIST:
        fputs("NodeList", out);
        ast_printNode(out, ast->list.head, depth+1, false);
        break;
        
    case AST_CONDITIONAL:
        fputs("IfStmt", out);
        ast_printNode(out, ast->conditionalStmt.condition, depth+1, false);
        ast_printNode(out, ast->conditionalStmt.ifBody, depth+1, false);
        ast_printNode(out, ast->conditionalStmt.elseBody, depth+1, true);
        break;
    
    case AST_FOR_IN:
        fputs("ForInStmt", out);
        ast_printToken(out, ast->forInLoop.variable);
        ast_printNode(out, ast->forInLoop.collection, depth+1, false);
        ast_printNode(out, ast->forInLoop.body, depth+1, true);
        break;
    
    case AST_WHILE:
        fputs("WhileStmt", out);
        ast_printNode(out, ast->whileLoop.condition, depth+1, false);
        ast_printNode(out, ast->whileLoop.body, depth+1, true);
        break;
    
    case AST_BREAK:
        fputs("BreakStmt", out);
        break;
        
    case AST_CONTINUE:
        fputs("ContinueStmt", out);
        break;
        
    case AST_RETURN:
        fputs("ReturnStmt", out);
        ast_printNode(out, ast->returnStmt.returnValue, depth+1, true);
        break;
    
    // DECLARATIONS
    case AST_DECL_MODULE:
        fprintf(out, "ModuleDecl `%s`", ast->moduleDecl.symbol);
        ast_printNode(out, ast->moduleDecl.body, depth+1, true);
        break;
    
    case AST_DECL_FUNC:
        fputs("FuncDecl", out);
        ast_printToken(out, ast->funcDecl.symbol);
        ast_printNode(out, ast->funcDecl.params, depth+1, false);
        ast_printNode(out, ast->funcDecl.returnType, depth+1, false);
        ast_printNode(out, ast->funcDecl.body, depth+1, true);
        break;
    
    case AST_DECL_VAR:
        fputs("VarDecl", out);
        ast_printToken(out, ast->varDecl.symbol);
        ast_printNode(out, ast->varDecl.typeAnnotation, depth+1, true);
        break;
    
    case AST_DECL_STRUCT:
        fputs("CompoundTypeDecl", out);
        ast_printToken(out, ast->structDecl.symbol);
        ast_printNode(out, ast->structDecl.constructor, depth+1, false);
        ast_printNode(out, ast->structDecl.destructor, depth+1, false);
        ast_printNode(out, ast->structDecl.fields, depth+1, true);
        break;
        
    // EXPRESSIONS
    case AST_EXPR_UNARY:
        fputs("UnaryOperatorExpr ", out);
        ast_printToken(out, ast->unaryExpr.operator);
        ast_printNode(out, ast->unaryExpr.rhs, depth+1, true);
        break;
    
    case AST_EXPR_BINARY:
        fputs("BinaryOperatorExpr ", out);
        ast_printToken(out, ast->binaryExpr.operator);
        ast_printNode(out, ast->binaryExpr.lhs, depth+1, false);
        ast_printNode(out, ast->binaryExpr.rhs, depth+1, true);
        break;
    
    case AST_EXPR_CALL:
        fputs("CallExpr", out);
        ast_printNode(out, ast->callExpr.symbol, depth+1, false);
        ast_printNode(out, ast->callExpr.params, depth+1, true);
        break;
        
    case AST_EXPR_SUBSCRIPT:
        fputs("SubscriptExpr", out);
        ast_printNode(out, ast->subscriptExpr.symbol, depth+1, false);
        ast_printNode(out, ast->subscriptExpr.subscript, depth+1, true);
        break;
    
    case AST_EXPR_CONSTANT:
        fputs("ConstantExpr ", out);
        ast_printToken(out, ast->constantExpr.symbol);
        break;
    
    case AST_EXPR_NAME:
        fputs("NameRefExpr ", out);
        ast_printToken(out, ast->nameExpr.symbol);
        break;
    
    case AST_TYPEEXPR_SIMPLE:
        fputs("TypeExpr", out);
        ast_printToken(out, ast->simpleType.symbol);
        break;
        
    case AST_TYPEEXPR_FUNC:
        fputs("FuncTypeExpr", out);
        ast_printNode(out, ast->funcType.returnType, depth+1, false);
        ast_printNode(out, ast->funcType.params, depth+1, true);
        break;
        
    case AST_TYPEEXPR_ARRAY:
        fputs("ArrayTypeExpr", out);
        ast_printNode(out, ast->arrayType.elementType, depth+1, false);
        break;
        
    case AST_TYPEEXPR_MAP:
        fputs("MapTypeExpr", out);
        ast_printNode(out, ast->mapType.keyType, depth+1, false);
        ast_printNode(out, ast->mapType.elementType, depth+1, true);
        break;
    }
    
    ast_printNode(out, ast->next, depth, false);
}

void ast_print(FILE* out, AST* ast) {
    ast_printNode(out, ast, 0, false);
    fputs("\n\n", out);
}
{'fraction_non_alphanumeric': 0.14637391882900866, 'fraction_numerical': 0.008744415930044673, 'mean_word_length': 2.6021910304690175, 'pattern_counts': {'":': 0, '<': 16, '<?xml version=': 0, '>': 96, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5593428', 'n_tokens_mistral': 3654, 'n_tokens_neox': 3583, 'n_words': 675}