roza/lib/value.c

143 lines
2.9 KiB
C
Raw Normal View History

2023-12-09 17:24:41 +00:00
#include "value.h"
2023-12-20 19:54:58 +00:00
#include "lib/commons.h"
#include "lib/type.h"
#include "program.h"
2023-12-09 17:24:41 +00:00
2023-12-11 17:01:22 +00:00
void value_init(value_t* value, type_t* type, int line)
2023-12-09 17:24:41 +00:00
{
assert(value);
assert(type);
value->type = type;
2023-12-11 17:01:22 +00:00
value->line = line;
2023-12-09 17:24:41 +00:00
}
2023-12-23 20:17:12 +00:00
value_t* value_new_clone(value_t* value)
{
assert(value);
value_t* clone = malloc(sizeof(value_t));
value_init(clone, value->type, value->line);
if (value->type->kind == TYPE_STR)
{
clone->value.str = strdup(value->value.str);
}
2023-12-24 19:24:41 +00:00
else if (value->type->kind == TYPE_NUM)
{
clone->value.num = value->value.num;
}
else if (value->type->kind == TYPE_FUN)
2023-12-23 20:17:12 +00:00
{
clone->value.fun = fun_new_clone(value->value.fun);
}
2023-12-24 19:24:41 +00:00
else if (value->type->kind == TYPE_REF)
{
clone->value.ref = value->value.ref;
}
else if (value->type->kind == TYPE_BOOL)
{
clone->value.bool = value->value.bool;
}
else
{
fprintf(stderr, "Cannot clone value of unknown type '%s'.",
TypeKindStr[value->type->kind]);
abort();
}
2023-12-23 20:17:12 +00:00
return clone;
}
2023-12-09 17:24:41 +00:00
void value_free(value_t* value)
{
assert(value);
2023-12-20 19:54:58 +00:00
assert(value->type);
2023-12-10 03:49:28 +00:00
if (value->type->kind == TYPE_STR)
{
free(value->value.str);
2023-12-20 19:54:58 +00:00
value->value.str = NULL;
}
if (value->type->kind == TYPE_FUN)
{
fun_free(value->value.fun);
free(value->value.fun);
value->value.fun = NULL;
2023-12-10 03:49:28 +00:00
}
2023-12-09 17:24:41 +00:00
}
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;
2023-12-09 21:59:24 +00:00
case TYPE_BOOL: {
return value->value.bool == rhs->value.bool;
} break;
2023-12-10 03:49:28 +00:00
case TYPE_STR: {
return strcmp(value->value.str, rhs->value.str) == 0;
} break;
2023-12-20 19:54:58 +00:00
case TYPE_FUN: {
return value->value.fun == rhs->value.fun;
} break;
2023-12-23 20:17:12 +00:00
case TYPE_REF: {
return value->value.ref == rhs->value.ref;
} break;
2023-12-09 17:24:41 +00:00
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;
2023-12-09 21:59:24 +00:00
case TYPE_BOOL:
return snprintf(buffer, size, "%s", value->value.bool ? "true" : "false");
break;
2023-12-10 03:49:28 +00:00
case TYPE_STR:
return snprintf(buffer, size, "\"%s\"", value->value.str);
break;
2023-12-20 19:54:58 +00:00
case TYPE_FUN:
return snprintf(buffer, size, "[fun]");
break;
2023-12-23 20:17:12 +00:00
case TYPE_REF:
return snprintf(buffer, size, "[ref %d]", (int) value->value.ref);
break;
2023-12-09 21:59:24 +00:00
default: {
fprintf(stderr, "Cannot stringify unknown value of type '%s'.\n",
TypeKindStr[value->type->kind]);
abort();
};
2023-12-09 17:24:41 +00:00
}
}