From cd2a86435e5e413630e0ab0caa48d900e49ea275 Mon Sep 17 00:00:00 2001 From: hachem Date: Sat, 19 Sep 2026 16:20:14 +0200 Subject: feat: tuples baby --- eval.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 55 insertions(+), 10 deletions(-) (limited to 'eval.c') diff --git a/eval.c b/eval.c index 170b122..d19d029 100644 --- a/eval.c +++ b/eval.c @@ -118,10 +118,53 @@ static int evaluate_value(struct Machine* machine, const struct Node* node, int6 return 1; } +// writes what a type looks like when emitted. true when it does not fit +static bool render(const struct Type* type, char* buffer, size_t size) +{ + int written = 0; + switch (type->kind) + { + case KIND_VOID: written = snprintf(buffer, size, "%s", ""); break; + case KIND_INT32: written = snprintf(buffer, size, "int32_t"); break; + case KIND_BYTE: written = snprintf(buffer, size, "byte"); break; + case KIND_SIZE: written = snprintf(buffer, size, "size_t"); break; + case KIND_ARRAY: + written = snprintf(buffer, size, "array[%" PRId64 "]", type->number); + break; + case KIND_CHAR: written = snprintf(buffer, size, "char"); break; + case KIND_CHAR_CONSTANT: written = snprintf(buffer, size, "%c", (char)type->number); break; + case KIND_VALUE: written = snprintf(buffer, size, "%" PRId64, type->number); break; + case KIND_TUPLE: written = snprintf(buffer, size, "%s", type->text); break; + } + + return written < 0 || (size_t)written >= size; +} + +// a tuple says everything its elements say, in order +static int evaluate_tuple(struct Machine* machine, const struct Node* node, struct Type* out) +{ + out->kind = KIND_TUPLE; + size_t used = 0; + for (const struct Node* element = node->first; element != NULL; element = element->next) + { + struct Type inner; + if (evaluate_type(machine, element, &inner)) + return 1; + + if (render(&inner, out->text + used, sizeof out->text - used)) + return complain(node, "that tuple is too much to say in one breath"); + + used = strlen(out->text); + } + + return 0; +} + static int evaluate_type(struct Machine* machine, const struct Node* node, struct Type* out) { out->kind = KIND_VOID; out->number = 0; + out->text[0] = '\0'; struct Type element; bool truth = false; switch (node->kind) @@ -131,6 +174,7 @@ static int evaluate_type(struct Machine* machine, const struct Node* node, struc case TYPE_BYTE: out->kind = KIND_BYTE; return 0; case TYPE_SIZE: out->kind = KIND_SIZE; return 0; case TYPE_CHAR: out->kind = KIND_CHAR; return 0; + case TYPE_TUPLE: return evaluate_tuple(machine, node, out); case TYPE_CHAR_CONSTANT: if (evaluate_value(machine, node->first, &out->number)) return 1; @@ -162,7 +206,8 @@ static int evaluate_type(struct Machine* machine, const struct Node* node, struc static bool same_type(const struct Type* left, const struct Type* right) { - return left->kind == right->kind && left->number == right->number; + return left->kind == right->kind && left->number == right->number && + strcmp(left->text, right->text) == 0; } static int evaluate_condition(struct Machine* machine, const struct Node* node, bool* out) @@ -248,18 +293,18 @@ static enum RunStatus emit(struct Machine* machine, const struct Node* node) if (evaluate_type(machine, node->first, &type)) return RUN_FAILED; - switch (type.kind) + // void says nothing, not even a newline. everything else says its piece and ends the line + if (type.kind == KIND_VOID) + return RUN_DONE; + + char text[TEXT_LENGTH_MAX + 1]; + if (render(&type, text, sizeof text)) { - case KIND_VOID: break; - case KIND_INT32: (void)printf("int32_t\n"); break; - case KIND_BYTE: (void)printf("byte\n"); break; - case KIND_SIZE: (void)printf("size_t\n"); break; - case KIND_ARRAY: (void)printf("array[%" PRId64 "]\n", type.number); break; - case KIND_CHAR: (void)printf("char\n"); break; - case KIND_CHAR_CONSTANT: (void)printf("%c\n", (char)type.number); break; - case KIND_VALUE: (void)printf("%" PRId64 "\n", type.number); break; + (void)complain(node, "that is too much to say in one breath"); + return RUN_FAILED; } + (void)printf("%s\n", text); return RUN_DONE; } -- cgit v1.3