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:
+200
@@ -0,0 +1,200 @@
|
||||
#define _POSIX_C_SOURCE 200809L
|
||||
#include "types.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
RavaType_t* rava_type_create_primitive(RavaTypeKind_e kind) {
|
||||
RavaType_t *type = calloc(1, sizeof(RavaType_t));
|
||||
type->kind = kind;
|
||||
|
||||
switch (kind) {
|
||||
case RAVA_TYPE_VOID: type->name = strdup("void"); break;
|
||||
case RAVA_TYPE_BOOLEAN: type->name = strdup("boolean"); break;
|
||||
case RAVA_TYPE_BYTE: type->name = strdup("byte"); break;
|
||||
case RAVA_TYPE_SHORT: type->name = strdup("short"); break;
|
||||
case RAVA_TYPE_INT: type->name = strdup("int"); break;
|
||||
case RAVA_TYPE_LONG: type->name = strdup("long"); break;
|
||||
case RAVA_TYPE_CHAR: type->name = strdup("char"); break;
|
||||
case RAVA_TYPE_FLOAT: type->name = strdup("float"); break;
|
||||
case RAVA_TYPE_DOUBLE: type->name = strdup("double"); break;
|
||||
default: type->name = strdup("unknown"); break;
|
||||
}
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
RavaType_t* rava_type_create_class(const char *class_name) {
|
||||
RavaType_t *type = calloc(1, sizeof(RavaType_t));
|
||||
type->kind = RAVA_TYPE_CLASS;
|
||||
type->name = strdup(class_name);
|
||||
type->data.class_type.class_name = strdup(class_name);
|
||||
return type;
|
||||
}
|
||||
|
||||
RavaType_t* rava_type_create_array(RavaType_t *element_type, int dimensions) {
|
||||
RavaType_t *type = calloc(1, sizeof(RavaType_t));
|
||||
type->kind = RAVA_TYPE_ARRAY;
|
||||
type->data.array.element_type = element_type;
|
||||
type->data.array.dimensions = dimensions;
|
||||
|
||||
char buffer[256];
|
||||
snprintf(buffer, sizeof(buffer), "%s", rava_type_to_string(element_type));
|
||||
for (int i = 0; i < dimensions; i++) {
|
||||
strcat(buffer, "[]");
|
||||
}
|
||||
type->name = strdup(buffer);
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
void rava_type_destroy(RavaType_t *type) {
|
||||
if (!type) return;
|
||||
|
||||
free(type->name);
|
||||
|
||||
if (type->kind == RAVA_TYPE_ARRAY) {
|
||||
rava_type_destroy(type->data.array.element_type);
|
||||
} else if (type->kind == RAVA_TYPE_CLASS) {
|
||||
free(type->data.class_type.class_name);
|
||||
}
|
||||
|
||||
free(type);
|
||||
}
|
||||
|
||||
RavaType_t* rava_type_from_name(const char *type_name) {
|
||||
if (strcmp(type_name, "void") == 0) return rava_type_create_primitive(RAVA_TYPE_VOID);
|
||||
if (strcmp(type_name, "boolean") == 0) return rava_type_create_primitive(RAVA_TYPE_BOOLEAN);
|
||||
if (strcmp(type_name, "byte") == 0) return rava_type_create_primitive(RAVA_TYPE_BYTE);
|
||||
if (strcmp(type_name, "short") == 0) return rava_type_create_primitive(RAVA_TYPE_SHORT);
|
||||
if (strcmp(type_name, "int") == 0) return rava_type_create_primitive(RAVA_TYPE_INT);
|
||||
if (strcmp(type_name, "long") == 0) return rava_type_create_primitive(RAVA_TYPE_LONG);
|
||||
if (strcmp(type_name, "char") == 0) return rava_type_create_primitive(RAVA_TYPE_CHAR);
|
||||
if (strcmp(type_name, "float") == 0) return rava_type_create_primitive(RAVA_TYPE_FLOAT);
|
||||
if (strcmp(type_name, "double") == 0) return rava_type_create_primitive(RAVA_TYPE_DOUBLE);
|
||||
|
||||
return rava_type_create_class(type_name);
|
||||
}
|
||||
|
||||
bool rava_type_is_primitive(RavaType_t *type) {
|
||||
return type->kind >= RAVA_TYPE_VOID && type->kind <= RAVA_TYPE_DOUBLE;
|
||||
}
|
||||
|
||||
bool rava_type_is_numeric(RavaType_t *type) {
|
||||
return type->kind >= RAVA_TYPE_BYTE && type->kind <= RAVA_TYPE_DOUBLE;
|
||||
}
|
||||
|
||||
bool rava_type_is_integral(RavaType_t *type) {
|
||||
return type->kind >= RAVA_TYPE_BYTE && type->kind <= RAVA_TYPE_CHAR;
|
||||
}
|
||||
|
||||
bool rava_type_is_floating(RavaType_t *type) {
|
||||
return type->kind == RAVA_TYPE_FLOAT || type->kind == RAVA_TYPE_DOUBLE;
|
||||
}
|
||||
|
||||
bool rava_type_is_reference(RavaType_t *type) {
|
||||
return type->kind == RAVA_TYPE_CLASS ||
|
||||
type->kind == RAVA_TYPE_ARRAY ||
|
||||
type->kind == RAVA_TYPE_NULL;
|
||||
}
|
||||
|
||||
bool rava_type_equals(RavaType_t *a, RavaType_t *b) {
|
||||
if (!a || !b) return false;
|
||||
if (a->kind != b->kind) return false;
|
||||
|
||||
if (a->kind == RAVA_TYPE_ARRAY) {
|
||||
return a->data.array.dimensions == b->data.array.dimensions &&
|
||||
rava_type_equals(a->data.array.element_type, b->data.array.element_type);
|
||||
}
|
||||
|
||||
if (a->kind == RAVA_TYPE_CLASS) {
|
||||
return strcmp(a->data.class_type.class_name, b->data.class_type.class_name) == 0;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool rava_type_is_assignable_to(RavaType_t *from, RavaType_t *to) {
|
||||
if (!from || !to) return false;
|
||||
|
||||
if (rava_type_equals(from, to)) return true;
|
||||
|
||||
if (from->kind == RAVA_TYPE_NULL && rava_type_is_reference(to)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (rava_type_is_numeric(from) && rava_type_is_numeric(to)) {
|
||||
int from_rank = from->kind - RAVA_TYPE_BYTE;
|
||||
int to_rank = to->kind - RAVA_TYPE_BYTE;
|
||||
return from_rank <= to_rank;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool rava_type_is_castable_to(RavaType_t *from, RavaType_t *to) {
|
||||
if (rava_type_is_assignable_to(from, to)) return true;
|
||||
|
||||
if (rava_type_is_numeric(from) && rava_type_is_numeric(to)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (rava_type_is_reference(from) && rava_type_is_reference(to)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool _is_string_type(RavaType_t *type) {
|
||||
return type->kind == RAVA_TYPE_CLASS &&
|
||||
type->data.class_type.class_name &&
|
||||
strcmp(type->data.class_type.class_name, "String") == 0;
|
||||
}
|
||||
|
||||
RavaType_t* rava_type_binary_result(RavaType_t *left, RavaType_t *right) {
|
||||
if (!left || !right) return NULL;
|
||||
|
||||
if (_is_string_type(left) || _is_string_type(right)) {
|
||||
return rava_type_create_class("String");
|
||||
}
|
||||
|
||||
if (!rava_type_is_numeric(left) || !rava_type_is_numeric(right)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (left->kind == RAVA_TYPE_DOUBLE || right->kind == RAVA_TYPE_DOUBLE) {
|
||||
return rava_type_create_primitive(RAVA_TYPE_DOUBLE);
|
||||
}
|
||||
|
||||
if (left->kind == RAVA_TYPE_FLOAT || right->kind == RAVA_TYPE_FLOAT) {
|
||||
return rava_type_create_primitive(RAVA_TYPE_FLOAT);
|
||||
}
|
||||
|
||||
if (left->kind == RAVA_TYPE_LONG || right->kind == RAVA_TYPE_LONG) {
|
||||
return rava_type_create_primitive(RAVA_TYPE_LONG);
|
||||
}
|
||||
|
||||
return rava_type_create_primitive(RAVA_TYPE_INT);
|
||||
}
|
||||
|
||||
RavaType_t* rava_type_unary_result(RavaType_t *operand) {
|
||||
if (!operand) return NULL;
|
||||
|
||||
if (!rava_type_is_numeric(operand)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (operand->kind == RAVA_TYPE_BYTE ||
|
||||
operand->kind == RAVA_TYPE_SHORT ||
|
||||
operand->kind == RAVA_TYPE_CHAR) {
|
||||
return rava_type_create_primitive(RAVA_TYPE_INT);
|
||||
}
|
||||
|
||||
return rava_type_create_primitive(operand->kind);
|
||||
}
|
||||
|
||||
const char* rava_type_to_string(RavaType_t *type) {
|
||||
if (!type) return "null";
|
||||
return type->name;
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
#ifndef RAVA_TYPES_H
|
||||
#define RAVA_TYPES_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
typedef enum {
|
||||
RAVA_TYPE_VOID,
|
||||
RAVA_TYPE_BOOLEAN,
|
||||
RAVA_TYPE_BYTE,
|
||||
RAVA_TYPE_SHORT,
|
||||
RAVA_TYPE_INT,
|
||||
RAVA_TYPE_LONG,
|
||||
RAVA_TYPE_CHAR,
|
||||
RAVA_TYPE_FLOAT,
|
||||
RAVA_TYPE_DOUBLE,
|
||||
RAVA_TYPE_CLASS,
|
||||
RAVA_TYPE_INTERFACE,
|
||||
RAVA_TYPE_ARRAY,
|
||||
RAVA_TYPE_NULL,
|
||||
RAVA_TYPE_UNKNOWN
|
||||
} RavaTypeKind_e;
|
||||
|
||||
typedef struct RavaType_t RavaType_t;
|
||||
|
||||
struct RavaType_t {
|
||||
RavaTypeKind_e kind;
|
||||
char *name;
|
||||
|
||||
union {
|
||||
struct {
|
||||
RavaType_t *element_type;
|
||||
int dimensions;
|
||||
} array;
|
||||
|
||||
struct {
|
||||
char *class_name;
|
||||
} class_type;
|
||||
} data;
|
||||
};
|
||||
|
||||
RavaType_t* rava_type_create_primitive(RavaTypeKind_e kind);
|
||||
RavaType_t* rava_type_create_class(const char *class_name);
|
||||
RavaType_t* rava_type_create_array(RavaType_t *element_type, int dimensions);
|
||||
void rava_type_destroy(RavaType_t *type);
|
||||
|
||||
RavaType_t* rava_type_from_name(const char *type_name);
|
||||
bool rava_type_is_primitive(RavaType_t *type);
|
||||
bool rava_type_is_numeric(RavaType_t *type);
|
||||
bool rava_type_is_integral(RavaType_t *type);
|
||||
bool rava_type_is_floating(RavaType_t *type);
|
||||
bool rava_type_is_reference(RavaType_t *type);
|
||||
|
||||
bool rava_type_equals(RavaType_t *a, RavaType_t *b);
|
||||
bool rava_type_is_assignable_to(RavaType_t *from, RavaType_t *to);
|
||||
bool rava_type_is_castable_to(RavaType_t *from, RavaType_t *to);
|
||||
|
||||
RavaType_t* rava_type_binary_result(RavaType_t *left, RavaType_t *right);
|
||||
RavaType_t* rava_type_unary_result(RavaType_t *operand);
|
||||
|
||||
const char* rava_type_to_string(RavaType_t *type);
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user