128 lines
2.5 KiB
C
128 lines
2.5 KiB
C
#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();
|
|
};
|
|
}
|
|
}
|