Initial commit of dem beast./plot.py
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