#include "value.h" #include "lib/commons.h" #include "lib/type.h" #include "program.h" void value_init(value_t* value, type_t* type, int line) { assert(value); assert(type); value->type = type; value->line = line; } value_t* value_new_clone(value_t* value) { assert(value); value_t* clone = malloc(sizeof(value_t)); value_init(clone, value->type, value->line); clone->value = value->value; if (value->type->kind == TYPE_STR) { clone->value.str = strdup(value->value.str); } if (value->type->kind == TYPE_FUN) { clone->value.fun = fun_new_clone(value->value.fun); } return clone; } void value_free(value_t* value) { assert(value); assert(value->type); if (value->type->kind == TYPE_STR) { free(value->value.str); value->value.str = NULL; } if (value->type->kind == TYPE_FUN) { fun_free(value->value.fun); free(value->value.fun); value->value.fun = NULL; } } int value_eq(value_t* value, value_t* rhs) { if (!type_eq(value->type, rhs->type)) { return 0; } switch (value->type->kind) { case TYPE_NUM: { return value->value.num == rhs->value.num; } break; case TYPE_BOOL: { return value->value.bool == rhs->value.bool; } break; case TYPE_STR: { return strcmp(value->value.str, rhs->value.str) == 0; } break; case TYPE_FUN: { return value->value.fun == rhs->value.fun; } break; case TYPE_REF: { return value->value.ref == rhs->value.ref; } break; default: { fprintf(stderr, "Cannot compare value of type '%s'.\n", TypeKindStr[value->type->kind]); abort(); }; } return 0; } size_t value_str(value_t* value, char* buffer, size_t size) { assert(value); assert(buffer); switch (value->type->kind) { case TYPE_NUM: return snprintf(buffer, size, "%lf", value->value.num); break; case TYPE_BOOL: return snprintf(buffer, size, "%s", value->value.bool ? "true" : "false"); break; case TYPE_STR: return snprintf(buffer, size, "\"%s\"", value->value.str); break; case TYPE_FUN: return snprintf(buffer, size, "[fun]"); break; case TYPE_REF: return snprintf(buffer, size, "[ref %d]", (int) value->value.ref); break; default: { fprintf(stderr, "Cannot stringify unknown value of type '%s'.\n", TypeKindStr[value->type->kind]); abort(); }; } }