feat: add initial plot.py module with beast visualization logic

This commit introduces the core plotting module for the beast project, including
the initial implementation of data visualization functions and chart generation
utilities. The module provides the foundational structure for rendering beast-related
metrics and graphical outputs.
This commit is contained in:
2025-12-02 05:54:32 +00:00
commit f9c7a0fa78
58 changed files with 9092 additions and 0 deletions
+200
View File
@@ -0,0 +1,200 @@
#define _POSIX_C_SOURCE 200809L
#include "ir.h"
#include "../runtime/labeltable.h"
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
RavaInstructionList_t* rava_instruction_list_create() {
RavaInstructionList_t *list = calloc(1, sizeof(RavaInstructionList_t));
list->capacity = 16;
list->instructions = malloc(sizeof(RavaInstruction_t) * list->capacity);
list->count = 0;
list->next_label_id = 1;
return list;
}
void rava_instruction_list_destroy(RavaInstructionList_t *list) {
if (!list) return;
free(list->instructions);
free(list);
}
void rava_instruction_list_add(RavaInstructionList_t *list, RavaInstruction_t instr) {
if (list->count >= list->capacity) {
list->capacity *= 2;
list->instructions = realloc(list->instructions,
sizeof(RavaInstruction_t) * list->capacity);
}
list->instructions[list->count++] = instr;
}
int rava_instruction_list_new_label(RavaInstructionList_t *list) {
return list->next_label_id++;
}
RavaMethod_t* rava_method_create(const char *name, RavaType_t *return_type) {
RavaMethod_t *method = calloc(1, sizeof(RavaMethod_t));
method->name = strdup(name);
method->return_type = return_type;
method->param_types = NULL;
method->param_count = 0;
method->local_count = 0;
method->instructions = rava_instruction_list_create();
method->label_table = NULL;
return method;
}
void rava_method_destroy(RavaMethod_t *method) {
if (!method) return;
free(method->name);
free(method->param_types);
rava_instruction_list_destroy(method->instructions);
if (method->label_table) {
rava_labeltable_destroy(method->label_table);
}
free(method);
}
RavaClass_t* rava_class_create(const char *name) {
RavaClass_t *class = calloc(1, sizeof(RavaClass_t));
class->name = strdup(name);
class->superclass = NULL;
class->methods = NULL;
class->method_count = 0;
class->method_capacity = 0;
return class;
}
void rava_class_destroy(RavaClass_t *class) {
if (!class) return;
free(class->name);
free(class->superclass);
for (size_t i = 0; i < class->method_count; i++) {
rava_method_destroy(class->methods[i]);
}
free(class->methods);
free(class);
}
void rava_class_add_method(RavaClass_t *class, RavaMethod_t *method) {
if (class->method_count >= class->method_capacity) {
size_t new_capacity = class->method_capacity == 0 ? 4 : class->method_capacity * 2;
class->methods = realloc(class->methods, sizeof(RavaMethod_t*) * new_capacity);
class->method_capacity = new_capacity;
}
class->methods[class->method_count++] = method;
}
RavaProgram_t* rava_program_create() {
RavaProgram_t *program = calloc(1, sizeof(RavaProgram_t));
program->classes = NULL;
program->class_count = 0;
program->class_capacity = 0;
return program;
}
void rava_program_destroy(RavaProgram_t *program) {
if (!program) return;
for (size_t i = 0; i < program->class_count; i++) {
rava_class_destroy(program->classes[i]);
}
free(program->classes);
free(program);
}
void rava_program_add_class(RavaProgram_t *program, RavaClass_t *class) {
if (program->class_count >= program->class_capacity) {
size_t new_capacity = program->class_capacity == 0 ? 4 : program->class_capacity * 2;
program->classes = realloc(program->classes, sizeof(RavaClass_t*) * new_capacity);
program->class_capacity = new_capacity;
}
program->classes[program->class_count++] = class;
}
static const char* _rava_opcode_name(RavaOpCode_e opcode) {
switch (opcode) {
case RAVA_OP_NOP: return "NOP";
case RAVA_OP_LOAD_CONST: return "LOAD_CONST";
case RAVA_OP_LOAD_LOCAL: return "LOAD_LOCAL";
case RAVA_OP_STORE_LOCAL: return "STORE_LOCAL";
case RAVA_OP_ADD: return "ADD";
case RAVA_OP_SUB: return "SUB";
case RAVA_OP_MUL: return "MUL";
case RAVA_OP_DIV: return "DIV";
case RAVA_OP_MOD: return "MOD";
case RAVA_OP_NEG: return "NEG";
case RAVA_OP_EQ: return "EQ";
case RAVA_OP_NE: return "NE";
case RAVA_OP_LT: return "LT";
case RAVA_OP_LE: return "LE";
case RAVA_OP_GT: return "GT";
case RAVA_OP_GE: return "GE";
case RAVA_OP_JUMP: return "JUMP";
case RAVA_OP_JUMP_IF_TRUE: return "JUMP_IF_TRUE";
case RAVA_OP_JUMP_IF_FALSE: return "JUMP_IF_FALSE";
case RAVA_OP_LABEL: return "LABEL";
case RAVA_OP_CALL: return "CALL";
case RAVA_OP_CALL_STATIC: return "CALL_STATIC";
case RAVA_OP_RETURN: return "RETURN";
case RAVA_OP_RETURN_VOID: return "RETURN_VOID";
case RAVA_OP_NEW: return "NEW";
case RAVA_OP_NEW_ARRAY: return "NEW_ARRAY";
case RAVA_OP_ARRAY_LENGTH: return "ARRAY_LENGTH";
case RAVA_OP_LOAD_ARRAY: return "LOAD_ARRAY";
case RAVA_OP_STORE_ARRAY: return "STORE_ARRAY";
case RAVA_OP_POP: return "POP";
case RAVA_OP_DUP: return "DUP";
case RAVA_OP_PRINT: return "PRINT";
case RAVA_OP_PRINTLN: return "PRINTLN";
default: return "UNKNOWN";
}
}
void rava_ir_print(RavaProgram_t *program) {
if (!program) return;
printf("IR Program (%zu classes)\n", program->class_count);
printf("================================================================================\n\n");
for (size_t i = 0; i < program->class_count; i++) {
RavaClass_t *class = program->classes[i];
printf("Class: %s\n", class->name);
for (size_t j = 0; j < class->method_count; j++) {
RavaMethod_t *method = class->methods[j];
printf(" Method: %s (locals: %d)\n", method->name, method->local_count);
for (size_t k = 0; k < method->instructions->count; k++) {
RavaInstruction_t *instr = &method->instructions->instructions[k];
printf(" %04zu %-15s", k, _rava_opcode_name(instr->opcode));
switch (instr->opcode) {
case RAVA_OP_LOAD_CONST:
printf(" %lld", (long long)instr->operand.int_value);
break;
case RAVA_OP_LOAD_LOCAL:
case RAVA_OP_STORE_LOCAL:
printf(" [%d]", instr->operand.var.index);
break;
case RAVA_OP_LABEL:
case RAVA_OP_JUMP:
case RAVA_OP_JUMP_IF_TRUE:
case RAVA_OP_JUMP_IF_FALSE:
printf(" L%d", instr->operand.label_id);
break;
case RAVA_OP_CALL_STATIC:
printf(" %s.%s",
instr->operand.call.class_name,
instr->operand.call.method_name);
break;
default:
break;
}
printf("\n");
}
printf("\n");
}
}
}