feat: implemented variant_from_str, Drop, and Mirror

This commit is contained in:
Sara 2024-01-25 09:58:00 +01:00
parent aec965f3f6
commit 1d919fef38
2 changed files with 77 additions and 0 deletions

69
core/src/variant.c Normal file
View file

@ -0,0 +1,69 @@
#include "variant.h"
#include "debug.h"
impl_Drop_for(Variant,
destroy_variant
)
START_REFLECT(Variant)
REFLECT_TYPECLASS(Variant, Drop)
END_REFLECT(Variant)
Variant variant_from_str(const char* str) {
size_t length = strlen(str);
if(isdigit(str[0])) {
// variant is a number
// convert to double
return NumberVariant(atof(str));
} else if(str[0] == '"') {
// variant should be a string
// format: "<content>"
// copy the input string without the quotes
size_t result_length = strfirst(str+1, str+length, '"');
char* string = malloc(result_length);
strncpy(string, str+1, result_length-1);
string[result_length] = '\0';
return StringVariant(string, result_length);
} else if(strncmp(str, "Vector(", 7) == 0) {
// variant is a vector
// format: Vector(<x>, <y>)
// get the location of the brackets
long close_bracket = strfirst(str, str + length, ')');
if(close_bracket == -1) goto variant_from_str_err;
char buf[24]; buf[23] = '\0';
// copy what is within the brackets
// 7 is the number of characters in "Vector(", which should be skipped
strncpy(buf, str + 7, close_bracket - 7);
length = strlen(buf);
long comma_ind = strfirst(buf, buf+length, ',');
if(comma_ind == -1) goto variant_from_str_err;
// split the string at the comma by inserting a null terminator
buf[comma_ind] = '\0';
return VectorVariant(MakeVector(atof(buf), atof(buf + comma_ind + 1)));
}
variant_from_str_err:
return UndefinedVariant();
}
void destroy_variant(Variant* self) {
destroy_contained(self);
free(self);
}
void destroy_contained(Variant* self) {
switch(self->type) {
default: break;
case Variant_String:
if(self->as_string != NULL)
free(self->as_string);
break;
case Variant_Object:
if(TC_MIRRORS(self->as_object, Drop)) {
Drop drop = TC_CAST(self->as_object, Drop);
drop.tc->drop(drop.data);
} else {
LOG_ERROR("Deallocating Object Variant that does not mirror Drop, pointer will be orphaned");
}
break;
}
}

View file

@ -2,6 +2,7 @@
#define _fencer_variant_h #define _fencer_variant_h
#include "vmath.h" #include "vmath.h"
#include "drop.h"
#include "mirror.h" #include "mirror.h"
typedef enum VariantType { typedef enum VariantType {
@ -23,10 +24,17 @@ typedef struct Variant {
}; };
} Variant; } Variant;
extern Variant variant_from_str(const char* str);
extern void destroy_variant(Variant* self);
extern void destroy_contained(Variant* self);
#define NumberVariant(Value_) (Variant){.type = Variant_Number, .as_number = Value_} #define NumberVariant(Value_) (Variant){.type = Variant_Number, .as_number = Value_}
#define VectorVariant(Value_) (Variant){.type = Variant_Vector, .as_vector = Value_} #define VectorVariant(Value_) (Variant){.type = Variant_Vector, .as_vector = Value_}
#define ObjectVariant(Value_) (Variant){.type = Variant_Object, .as_object = Value_} #define ObjectVariant(Value_) (Variant){.type = Variant_Object, .as_object = Value_}
#define StringVariant(Value_, BufSize_) (Variant){.type = Variant_String, .as_string = Value_, .string_size = BufSize_} #define StringVariant(Value_, BufSize_) (Variant){.type = Variant_String, .as_string = Value_, .string_size = BufSize_}
#define UndefinedVariant() (Variant){.type = Variant_Undefined } #define UndefinedVariant() (Variant){.type = Variant_Undefined }
decl_typeclass_impl(Drop, Variant);
decl_typeclass_impl(Mirror, Variant);
#endif // !_fencer_variant_h #endif // !_fencer_variant_h