From 73cd8e0c4a2f4753dc8666151791c5655cbd146c Mon Sep 17 00:00:00 2001 From: bog Date: Thu, 24 Aug 2023 14:29:13 +0200 Subject: [PATCH] ADD: array types better representation. --- src/compiler.c | 10 +-- src/cstatic.c | 151 +++++++++++++++++++++++++++++++++-------- src/cstatic.h | 11 ++- src/type.c | 47 ++++++++++++- src/type.h | 2 + src/value.c | 3 +- tests/err_ty_array.wuz | 1 + 7 files changed, 185 insertions(+), 40 deletions(-) diff --git a/src/compiler.c b/src/compiler.c index 509608f..3399725 100644 --- a/src/compiler.c +++ b/src/compiler.c @@ -22,8 +22,8 @@ void compile_node(compiler* self, node* root, program* prog) cstatic cs; cstatic_init(&cs); - int lhs = cstatic_resolve(&cs, root->children.data[0]); - int rhs = cstatic_resolve(&cs, root->children.data[1]); + int lhs = cstatic_resolve_base_type(&cs, root->children.data[0]); + int rhs = cstatic_resolve_base_type(&cs, root->children.data[1]); cstatic_free(&cs); @@ -49,8 +49,8 @@ void compile_node(compiler* self, node* root, program* prog) cstatic cs; cstatic_init(&cs); - int lhs = cstatic_resolve(&cs, root->children.data[0]); - int rhs = cstatic_resolve(&cs, root->children.data[1]); + int lhs = cstatic_resolve_base_type(&cs, root->children.data[0]); + int rhs = cstatic_resolve_base_type(&cs, root->children.data[1]); cstatic_free(&cs); @@ -195,7 +195,7 @@ void compile_number(compiler* self, node* root, program* prog, cstatic cs; cstatic_init(&cs); - int ty = cstatic_resolve(&cs, root); + int ty = cstatic_resolve_base_type(&cs, root); switch (ty) { diff --git a/src/cstatic.c b/src/cstatic.c index 2377732..82fc217 100644 --- a/src/cstatic.c +++ b/src/cstatic.c @@ -11,74 +11,102 @@ void cstatic_free(cstatic* self) assert(self); } -int cstatic_resolve(cstatic* self, node* ast) +type* cstatic_new_type(cstatic* self, int base_type) +{ + assert(self); + type* ty = malloc(sizeof(type)); + type_init(ty, base_type); + return ty; +} + +int cstatic_resolve_base_type(cstatic* self, node* ast) +{ + assert(self); + type* ty = cstatic_resolve_new(self, ast); + int res = ty->base_type; + type_free(ty); + free(ty); + + return res; +} + +type* cstatic_resolve_new(cstatic* self, node* ast) { assert(self); assert(ast); if (ast->type == NODE_MUL) { - int lhs = cstatic_resolve(self, ast->children.data[0]); - int rhs = cstatic_resolve(self, ast->children.data[1]); + int lhs = cstatic_resolve_base_type(self, ast->children.data[0]); + int rhs = cstatic_resolve_base_type(self, ast->children.data[1]); if (lhs == TY_STRING || rhs == TY_STRING) { - return TY_STRING; + return cstatic_new_type(self, TY_STRING); } } if (ast->type == NODE_INTEGER) { - return TY_INTEGER; + return cstatic_new_type(self, TY_INTEGER); } else if (ast->type == NODE_FLOAT) { - return TY_FLOAT; + return cstatic_new_type(self, TY_FLOAT); } else if (ast->type == NODE_ADD) { - int lhs = cstatic_resolve(self, ast->children.data[0]); - int rhs = cstatic_resolve(self, ast->children.data[1]); + int lhs = cstatic_resolve_base_type(self, ast->children.data[0]); + int rhs = cstatic_resolve_base_type(self, ast->children.data[1]); if (lhs == TY_STRING && rhs == TY_STRING) { - return TY_STRING; + return cstatic_new_type(self, TY_STRING); } - return lhs; + return cstatic_new_type(self, lhs); } else if (ast->type == NODE_STRING) { - return TY_STRING; + return cstatic_new_type(self, TY_STRING); } else if (ast->type == NODE_ARRAY) { - return TY_ARRAY; + assert(ast->children.size > 0); + type* child = cstatic_resolve_new(self, ast->children.data[0]); + + type* ty = malloc(sizeof(type)); + type_init_array(ty, child); + + type_free(child); + free(child); + + return ty; } else if (ast->type == NODE_BOOLEAN || ast->type == NODE_EQ || ast->type == NODE_NE) { - return TY_BOOLEAN; + return cstatic_new_type(self, TY_BOOLEAN); } else { for (size_t i=0; ichildren.size; i++) { - int ty = cstatic_resolve(self, ast->children.data[i]); + type* ty = cstatic_resolve_new(self, ast->children.data[i]); - if (ty != TY_NIL) + if (ty != NULL) { return ty; } } } - return TY_NIL; + return NULL; } int cstatic_check(cstatic* self, node* ast, char* msg, size_t size) @@ -102,7 +130,7 @@ int cstatic_check(cstatic* self, node* ast, char* msg, size_t size) if (ast->type == NODE_ARRAY) { assert(ast->children.size > 0); - int ty = cstatic_resolve(self, ast->children.data[0]); + type* ty = cstatic_resolve_new(self, ast->children.data[0]); for (size_t i=1; ichildren.size; i++) { @@ -112,11 +140,13 @@ int cstatic_check(cstatic* self, node* ast, char* msg, size_t size) msg, size, ty, - TYPE_END + NULL ); if (!status) { + type_free(ty); + free(ty); return status; } } @@ -127,8 +157,8 @@ int cstatic_check(cstatic* self, node* ast, char* msg, size_t size) // String Operations if (ast->type == NODE_ADD) { - int lhs = cstatic_resolve(self, ast->children.data[0]); - int rhs = cstatic_resolve(self, ast->children.data[1]); + int lhs = cstatic_resolve_base_type(self, ast->children.data[0]); + int rhs = cstatic_resolve_base_type(self, ast->children.data[1]); if (lhs == rhs && lhs == TY_STRING) @@ -139,8 +169,8 @@ int cstatic_check(cstatic* self, node* ast, char* msg, size_t size) if (ast->type == NODE_MUL) { - int lhs = cstatic_resolve(self, ast->children.data[0]); - int rhs = cstatic_resolve(self, ast->children.data[1]); + int lhs = cstatic_resolve_base_type(self, ast->children.data[0]); + int rhs = cstatic_resolve_base_type(self, ast->children.data[1]); if ((lhs == TY_STRING && rhs == TY_INTEGER) || (lhs == TY_INTEGER && rhs == TY_STRING)) @@ -169,7 +199,7 @@ int cstatic_check(cstatic* self, node* ast, char* msg, size_t size) else if (ast->type == NODE_ASSERT || ast->type == NODE_NOT) { - int status = cstatic_check_type(self, + int status = cstatic_check_type_base(self, ast->children.data[0], msg, size, @@ -197,7 +227,7 @@ int cstatic_check(cstatic* self, node* ast, char* msg, size_t size) return status; } - status = cstatic_check_type(self, + status = cstatic_check_type_base(self, ast->children.data[0], msg, size, @@ -213,7 +243,7 @@ int cstatic_check(cstatic* self, node* ast, char* msg, size_t size) else if (ast->type == NODE_UADD || ast->type == NODE_USUB) { - int status = cstatic_check_type(self, + int status = cstatic_check_type_base(self, ast->children.data[0], msg, size, @@ -245,7 +275,7 @@ int cstatic_check(cstatic* self, node* ast, char* msg, size_t size) return status; } - status = cstatic_check_type(self, + status = cstatic_check_type_base(self, ast->children.data[0], msg, size, @@ -262,7 +292,68 @@ int cstatic_check(cstatic* self, node* ast, char* msg, size_t size) } int cstatic_check_type(cstatic* self, node* lhs, - char* msg, size_t size, int types, ...) + char* msg, size_t size, type* types, ...) +{ + assert(self); + assert(lhs); + char aze[512]; + node_str(lhs, aze, 512); + + va_list args; + va_start(args, types); + type* rhs = types; + + type* left = cstatic_resolve_new(self, lhs); + + type* all_types[TY_TYPE_COUNT]; + + for (int i=0; ilineno); + sz += type_str(left, msg + sz, size - sz); + + sz += snprintf(msg + sz, size - sz, "', expected: \n"); + + size_t j = 0; + + while (all_types[j] != NULL) + { + sz += snprintf(msg + sz, size - sz, "\t - "); + sz += type_str(all_types[j], msg + sz, size - sz); + sz += snprintf(msg + sz, size - sz, "\n"); + j++; + } + + type_free(left); + free(left); + return 0; +} + +int cstatic_check_type_base(cstatic* self, node* lhs, + char* msg, size_t size, int types, ...) { assert(self); assert(lhs); @@ -273,7 +364,7 @@ int cstatic_check_type(cstatic* self, node* lhs, va_start(args, types); int rhs = types; - int left = cstatic_resolve(self, lhs); + int left = cstatic_resolve_base_type(self, lhs); int all_types[TY_TYPE_COUNT]; memset(all_types, TYPE_END, TY_TYPE_COUNT * sizeof(int)); @@ -320,8 +411,8 @@ int cstatic_check_same_type(cstatic* self, node* lhs, node* rhs, assert(lhs); assert(rhs); - int left = cstatic_resolve(self, lhs); - int right = cstatic_resolve(self, rhs); + int left = cstatic_resolve_base_type(self, lhs); + int right = cstatic_resolve_base_type(self, rhs); if (left != right) { diff --git a/src/cstatic.h b/src/cstatic.h index 1b00c1e..c5962ed 100644 --- a/src/cstatic.h +++ b/src/cstatic.h @@ -3,6 +3,7 @@ #include "commons.h" #include "node.h" +#include "type.h" #define TYPE_END (-1) @@ -13,11 +14,17 @@ typedef struct { void cstatic_init(cstatic* self); void cstatic_free(cstatic* self); -int cstatic_resolve(cstatic* self, node* ast); +type* cstatic_new_type(cstatic* self, int base_type); +int cstatic_resolve_base_type(cstatic* self, node* ast); + +type* cstatic_resolve_new(cstatic* self, node* ast); int cstatic_check(cstatic* self, node* ast, char* msg, size_t size); int cstatic_check_type(cstatic* self, node* lhs, - char* msg, size_t size, int types, ...); + char* msg, size_t size, type* types, ...); + +int cstatic_check_type_base(cstatic* self, node* lhs, + char* msg, size_t size, int types, ...); int cstatic_check_same_type(cstatic* self, node* lhs, node* rhs, char* msg, size_t size); diff --git a/src/type.c b/src/type.c index 556c045..333be75 100644 --- a/src/type.c +++ b/src/type.c @@ -6,11 +6,26 @@ void type_init(type* self, int base_type) { assert(self); self->base_type = base_type; + self->array_type = NULL; +} + +void type_init_array(type* self, type* array_type) +{ + assert(self); + assert(array_type); + type_init(self, TY_ARRAY); + self->array_type = type_new_clone(array_type); } void type_free(type* self) { assert(self); + + if (self->array_type != NULL) + { + type_free(self->array_type); + free(self->array_type); + } } type* type_new_clone(type* self) @@ -20,6 +35,11 @@ type* type_new_clone(type* self) type* clone = malloc(sizeof(type)); type_init(clone, self->base_type); + if (self->array_type) + { + clone->array_type = type_new_clone(self->array_type); + } + return clone; } @@ -27,12 +47,35 @@ int type_equals(type* self, type* rhs) { assert(self); assert(rhs); + + if (self->base_type != rhs->base_type) + { + return 0; + } + + if (self->base_type == TY_ARRAY) + { + assert(self->array_type); + assert(rhs->array_type); + return type_equals(self->array_type, rhs->array_type); + } + + return 1; - return self->base_type == rhs->base_type; } size_t type_str(type* self, char* buffer, size_t size) { assert(self); - return snprintf(buffer, size, "%s", TypesStr[self->base_type]); + size_t sz = snprintf(buffer, size, "%s", + TypesStr[self->base_type] + strlen("TY_")); + + if (self->base_type == TY_ARRAY) + { + sz += snprintf(buffer + sz, size - sz, "<"); + sz += type_str(self->array_type, buffer + sz, size - sz); + sz += snprintf(buffer + sz, size - sz, ">"); + } + + return sz; } diff --git a/src/type.h b/src/type.h index a7029c3..47015be 100644 --- a/src/type.h +++ b/src/type.h @@ -20,9 +20,11 @@ extern char const* TypesStr[]; typedef struct type { int base_type; + struct type* array_type; } type; void type_init(type* self, int base_type); +void type_init_array(type* self, type* array_type); void type_free(type* self); type* type_new_clone(type* self); diff --git a/src/value.c b/src/value.c index f871433..d0c5c7a 100644 --- a/src/value.c +++ b/src/value.c @@ -51,8 +51,9 @@ void value_init_array(value* self, array* arr, int lineno) self->val.array_val = array_new_clone(arr); self->lineno = lineno; + self->type = malloc(sizeof(type)); - type_init(self->type, TY_ARRAY); + type_init_array(self->type, arr->type); } void value_free(value* self) diff --git a/tests/err_ty_array.wuz b/tests/err_ty_array.wuz index 9b22710..e143c3f 100644 --- a/tests/err_ty_array.wuz +++ b/tests/err_ty_array.wuz @@ -1,2 +1,3 @@ [] [1 2 3 "4"] +[ [0 1] ["0" "1"] ]