Files
Toy/source/toy_value.c
Kayne Ruse 3148a56ce0 Added simple assignment, read more
I was coding earlier this week, but my brain was so foggy I ended up not
knowing what I was doing. After a few days break, I've cleaned up the
mess, which took hours.

Changes:
* Variables can be assigned
* Added new value types as placeholders
* Added 'compare' and 'assign' to the AST
* Added duplicate opcode
* Added functions to copy and free values
* Max name length is 255 chars
* Compound assigns are squeezed into one word

To be completed:

* Tests for this commit's changes
* Compound assignments
* Variable access
2024-10-25 22:48:24 +11:00

164 lines
3.8 KiB
C

#include "toy_value.h"
#include "toy_console_colors.h"
#include "toy_print.h"
#include "toy_string.h"
#include <stdio.h>
#include <stdlib.h>
bool Toy_private_isTruthy(Toy_Value value) {
//null is an error
if (TOY_VALUE_IS_NULL(value)) {
Toy_error(TOY_CC_ERROR "ERROR: 'null' is neither true nor false\n" TOY_CC_RESET);
}
//only 'false' is falsy
if (TOY_VALUE_IS_BOOLEAN(value)) {
return TOY_VALUE_AS_BOOLEAN(value);
}
//anything else is truthy
return true;
}
bool Toy_private_isEqual(Toy_Value left, Toy_Value right) {
//temp check
if (right.type > TOY_VALUE_STRING) {
Toy_error(TOY_CC_ERROR "ERROR: Unknown types in value equality comparison\n" TOY_CC_RESET);
}
switch(left.type) {
case TOY_VALUE_NULL:
return TOY_VALUE_IS_NULL(right);
case TOY_VALUE_BOOLEAN:
return TOY_VALUE_IS_BOOLEAN(right) && TOY_VALUE_AS_BOOLEAN(left) == TOY_VALUE_AS_BOOLEAN(right);
case TOY_VALUE_INTEGER:
if (TOY_VALUE_AS_INTEGER(right)) {
return TOY_VALUE_AS_INTEGER(left) == TOY_VALUE_AS_INTEGER(right);
}
if (TOY_VALUE_AS_FLOAT(right)) {
return TOY_VALUE_AS_INTEGER(left) == TOY_VALUE_AS_FLOAT(right);
}
return false;
case TOY_VALUE_FLOAT:
if (TOY_VALUE_AS_FLOAT(right)) {
return TOY_VALUE_AS_FLOAT(left) == TOY_VALUE_AS_FLOAT(right);
}
if (TOY_VALUE_AS_INTEGER(right)) {
return TOY_VALUE_AS_FLOAT(left) == TOY_VALUE_AS_INTEGER(right);
}
return false;
case TOY_VALUE_STRING:
if (TOY_VALUE_IS_STRING(right)) {
return Toy_compareStrings(TOY_VALUE_AS_STRING(left), TOY_VALUE_AS_STRING(right)) == 0;
}
return false;
case TOY_VALUE_ARRAY:
case TOY_VALUE_TABLE:
case TOY_VALUE_FUNCTION:
case TOY_VALUE_OPAQUE:
case TOY_VALUE_TYPE:
case TOY_VALUE_ANY:
case TOY_VALUE_UNKNOWN:
Toy_error(TOY_CC_ERROR "ERROR: Unknown types in value equality comparison\n" TOY_CC_RESET);
}
return 0;
}
//hash util
static unsigned int hashUInt(unsigned int x) {
x = ((x >> 16) ^ x) * 0x45d9f3b;
x = ((x >> 16) ^ x) * 0x45d9f3b;
x = (x >> 16) ^ x;
return x;
}
unsigned int Toy_hashValue(Toy_Value value) {
switch(value.type) {
case TOY_VALUE_NULL:
return 0;
case TOY_VALUE_BOOLEAN:
return TOY_VALUE_AS_BOOLEAN(value) ? 1 : 0;
case TOY_VALUE_INTEGER:
return hashUInt(TOY_VALUE_AS_INTEGER(value));
case TOY_VALUE_FLOAT:
return hashUInt( *((int*)(&TOY_VALUE_AS_FLOAT(value))) );
case TOY_VALUE_STRING:
return Toy_hashString(TOY_VALUE_AS_STRING(value));
case TOY_VALUE_ARRAY:
case TOY_VALUE_TABLE:
case TOY_VALUE_FUNCTION:
case TOY_VALUE_OPAQUE:
case TOY_VALUE_TYPE:
case TOY_VALUE_ANY:
case TOY_VALUE_UNKNOWN:
Toy_error(TOY_CC_ERROR "ERROR: Can't hash an unknown type\n" TOY_CC_RESET);
}
return 0;
}
Toy_Value Toy_copyValue(Toy_Value value) {
switch(value.type) {
case TOY_VALUE_NULL:
case TOY_VALUE_BOOLEAN:
case TOY_VALUE_INTEGER:
case TOY_VALUE_FLOAT:
return value;
case TOY_VALUE_STRING: {
Toy_String* string = TOY_VALUE_AS_STRING(value);
return TOY_VALUE_FROM_STRING(Toy_copyString(string));
}
case TOY_VALUE_ARRAY:
case TOY_VALUE_TABLE:
case TOY_VALUE_FUNCTION:
case TOY_VALUE_OPAQUE:
case TOY_VALUE_TYPE:
case TOY_VALUE_ANY:
case TOY_VALUE_UNKNOWN:
Toy_error(TOY_CC_ERROR "ERROR: Can't copy an unknown type\n" TOY_CC_RESET);
}
//dummy return
return TOY_VALUE_FROM_NULL();
}
void Toy_freeValue(Toy_Value value) {
switch(value.type) {
case TOY_VALUE_NULL:
case TOY_VALUE_BOOLEAN:
case TOY_VALUE_INTEGER:
case TOY_VALUE_FLOAT:
break;
case TOY_VALUE_STRING: {
Toy_String* string = TOY_VALUE_AS_STRING(value);
Toy_freeString(string);
break;
}
case TOY_VALUE_ARRAY:
case TOY_VALUE_TABLE:
case TOY_VALUE_FUNCTION:
case TOY_VALUE_OPAQUE:
case TOY_VALUE_TYPE:
case TOY_VALUE_ANY:
case TOY_VALUE_UNKNOWN:
Toy_error(TOY_CC_ERROR "ERROR: Can't free an unknown type\n" TOY_CC_RESET);
}
}