#include "value.h" void value_init_num(value_t* self, double num, int line) { assert(self); self->data.num = num; self->type = TYPE_NUM; self->line = line; } void value_init_new_tuple(value_t* self, vec_t* values, int line) { assert(self); assert(values); self->data.tuple = values; self->type = TYPE_TUPLE; self->line = line; } value_t* value_new_clone(value_t* self) { assert(self); value_t* value = malloc(sizeof(value_t)); switch (self->type) { case TYPE_NUM: { value_init_num(value, self->data.num, self->line); } break; case TYPE_TUPLE: { vec_t* vec = malloc(sizeof(vec_t)); vec_init(vec); for (size_t i=0; idata.tuple->size; i++) { vec_push( vec, value_new_clone(self->data.tuple->data[i]) ); } value_init_new_tuple(value, vec, self->line); } break; default: { free(value); fprintf(stderr, "cannot clone value of type '%s'\n", TypeStr[self->type]); abort(); } break; } return value; } void value_free(value_t* self) { if (self->type == TYPE_TUPLE) { vec_free_elements(self->data.tuple, (void*) value_free); vec_free(self->data.tuple); free(self->data.tuple); } } size_t value_str(value_t* self, char* buffer, size_t size) { assert(self); assert(buffer); size_t sz = 0; switch (self->type) { case TYPE_NUM: { sz += snprintf(buffer + sz, size - sz, "%lf", self->data.num); } break; case TYPE_TUPLE: { sz += snprintf(buffer + sz, size - sz, "("); for (size_t i=0; i < self->data.tuple->size; i++) { if (i > 0) { sz += snprintf(buffer + sz, size - sz, ", "); } sz += value_str(self->data.tuple->data[i], buffer + sz, size - sz); } sz += snprintf(buffer + sz, size - sz, ")"); } break; default: assert(0); } return sz; } int value_equals(value_t* self, value_t* rhs) { assert(self); assert(rhs); if (self->type != rhs->type) { return 0; } switch (self->type) { case TYPE_NUM: { return self->data.num == rhs->data.num; } break; case TYPE_TUPLE: { if (self->data.tuple->size != rhs->data.tuple->size) { return 0; } for (size_t i=0; idata.tuple->size; i++) { if (!value_equals( self->data.tuple->data[i], rhs->data.tuple->data[i] )) { return 0; } } return 1; } break; default: { fprintf( stderr, "cannot test equality on value of type '%s'\n", TypeStr[self->type]); abort(); } break; } }