ADD: array types better representation.

main
bog 2023-08-24 14:29:13 +02:00
parent c2e9880c99
commit 73cd8e0c4a
7 changed files with 185 additions and 40 deletions

View File

@ -22,8 +22,8 @@ void compile_node(compiler* self, node* root, program* prog)
cstatic cs; cstatic cs;
cstatic_init(&cs); cstatic_init(&cs);
int lhs = cstatic_resolve(&cs, root->children.data[0]); int lhs = cstatic_resolve_base_type(&cs, root->children.data[0]);
int rhs = cstatic_resolve(&cs, root->children.data[1]); int rhs = cstatic_resolve_base_type(&cs, root->children.data[1]);
cstatic_free(&cs); cstatic_free(&cs);
@ -49,8 +49,8 @@ void compile_node(compiler* self, node* root, program* prog)
cstatic cs; cstatic cs;
cstatic_init(&cs); cstatic_init(&cs);
int lhs = cstatic_resolve(&cs, root->children.data[0]); int lhs = cstatic_resolve_base_type(&cs, root->children.data[0]);
int rhs = cstatic_resolve(&cs, root->children.data[1]); int rhs = cstatic_resolve_base_type(&cs, root->children.data[1]);
cstatic_free(&cs); cstatic_free(&cs);
@ -195,7 +195,7 @@ void compile_number(compiler* self, node* root, program* prog,
cstatic cs; cstatic cs;
cstatic_init(&cs); cstatic_init(&cs);
int ty = cstatic_resolve(&cs, root); int ty = cstatic_resolve_base_type(&cs, root);
switch (ty) switch (ty)
{ {

View File

@ -11,74 +11,102 @@ void cstatic_free(cstatic* self)
assert(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(self);
assert(ast); assert(ast);
if (ast->type == NODE_MUL) if (ast->type == NODE_MUL)
{ {
int lhs = cstatic_resolve(self, ast->children.data[0]); int lhs = cstatic_resolve_base_type(self, ast->children.data[0]);
int rhs = cstatic_resolve(self, ast->children.data[1]); int rhs = cstatic_resolve_base_type(self, ast->children.data[1]);
if (lhs == TY_STRING || rhs == TY_STRING) if (lhs == TY_STRING || rhs == TY_STRING)
{ {
return TY_STRING; return cstatic_new_type(self, TY_STRING);
} }
} }
if (ast->type == NODE_INTEGER) if (ast->type == NODE_INTEGER)
{ {
return TY_INTEGER; return cstatic_new_type(self, TY_INTEGER);
} }
else if (ast->type == NODE_FLOAT) else if (ast->type == NODE_FLOAT)
{ {
return TY_FLOAT; return cstatic_new_type(self, TY_FLOAT);
} }
else if (ast->type == NODE_ADD) else if (ast->type == NODE_ADD)
{ {
int lhs = cstatic_resolve(self, ast->children.data[0]); int lhs = cstatic_resolve_base_type(self, ast->children.data[0]);
int rhs = cstatic_resolve(self, ast->children.data[1]); int rhs = cstatic_resolve_base_type(self, ast->children.data[1]);
if (lhs == TY_STRING && rhs == TY_STRING) 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) else if (ast->type == NODE_STRING)
{ {
return TY_STRING; return cstatic_new_type(self, TY_STRING);
} }
else if (ast->type == NODE_ARRAY) 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 else if (ast->type == NODE_BOOLEAN
|| ast->type == NODE_EQ || ast->type == NODE_EQ
|| ast->type == NODE_NE) || ast->type == NODE_NE)
{ {
return TY_BOOLEAN; return cstatic_new_type(self, TY_BOOLEAN);
} }
else else
{ {
for (size_t i=0; i<ast->children.size; i++) for (size_t i=0; i<ast->children.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;
} }
} }
} }
return TY_NIL; return NULL;
} }
int cstatic_check(cstatic* self, node* ast, char* msg, size_t size) 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) if (ast->type == NODE_ARRAY)
{ {
assert(ast->children.size > 0); 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; i<ast->children.size; i++) for (size_t i=1; i<ast->children.size; i++)
{ {
@ -112,11 +140,13 @@ int cstatic_check(cstatic* self, node* ast, char* msg, size_t size)
msg, msg,
size, size,
ty, ty,
TYPE_END NULL
); );
if (!status) if (!status)
{ {
type_free(ty);
free(ty);
return status; return status;
} }
} }
@ -127,8 +157,8 @@ int cstatic_check(cstatic* self, node* ast, char* msg, size_t size)
// String Operations // String Operations
if (ast->type == NODE_ADD) if (ast->type == NODE_ADD)
{ {
int lhs = cstatic_resolve(self, ast->children.data[0]); int lhs = cstatic_resolve_base_type(self, ast->children.data[0]);
int rhs = cstatic_resolve(self, ast->children.data[1]); int rhs = cstatic_resolve_base_type(self, ast->children.data[1]);
if (lhs == rhs && lhs == TY_STRING) 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) if (ast->type == NODE_MUL)
{ {
int lhs = cstatic_resolve(self, ast->children.data[0]); int lhs = cstatic_resolve_base_type(self, ast->children.data[0]);
int rhs = cstatic_resolve(self, ast->children.data[1]); int rhs = cstatic_resolve_base_type(self, ast->children.data[1]);
if ((lhs == TY_STRING && rhs == TY_INTEGER) if ((lhs == TY_STRING && rhs == TY_INTEGER)
|| (lhs == TY_INTEGER && rhs == TY_STRING)) || (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 else if (ast->type == NODE_ASSERT
|| ast->type == NODE_NOT) || ast->type == NODE_NOT)
{ {
int status = cstatic_check_type(self, int status = cstatic_check_type_base(self,
ast->children.data[0], ast->children.data[0],
msg, msg,
size, size,
@ -197,7 +227,7 @@ int cstatic_check(cstatic* self, node* ast, char* msg, size_t size)
return status; return status;
} }
status = cstatic_check_type(self, status = cstatic_check_type_base(self,
ast->children.data[0], ast->children.data[0],
msg, msg,
size, size,
@ -213,7 +243,7 @@ int cstatic_check(cstatic* self, node* ast, char* msg, size_t size)
else if (ast->type == NODE_UADD else if (ast->type == NODE_UADD
|| ast->type == NODE_USUB) || ast->type == NODE_USUB)
{ {
int status = cstatic_check_type(self, int status = cstatic_check_type_base(self,
ast->children.data[0], ast->children.data[0],
msg, msg,
size, size,
@ -245,7 +275,7 @@ int cstatic_check(cstatic* self, node* ast, char* msg, size_t size)
return status; return status;
} }
status = cstatic_check_type(self, status = cstatic_check_type_base(self,
ast->children.data[0], ast->children.data[0],
msg, msg,
size, size,
@ -262,6 +292,67 @@ int cstatic_check(cstatic* self, node* ast, char* msg, size_t size)
} }
int cstatic_check_type(cstatic* self, node* lhs, int cstatic_check_type(cstatic* self, node* lhs,
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; i<TY_TYPE_COUNT; i++)
{
all_types[i] = NULL;
}
size_t i = 0;
while (rhs != NULL)
{
all_types[i] = rhs;
if (type_equals(left, rhs))
{
va_end(args);
type_free(left);
free(left);
return 1;
}
rhs = va_arg(args, type*);
i++;
}
va_end(args);
size_t sz = snprintf(msg, size, "E(%d): type mismatch, got '", lhs->lineno);
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, ...) char* msg, size_t size, int types, ...)
{ {
assert(self); assert(self);
@ -273,7 +364,7 @@ int cstatic_check_type(cstatic* self, node* lhs,
va_start(args, types); va_start(args, types);
int rhs = types; int rhs = types;
int left = cstatic_resolve(self, lhs); int left = cstatic_resolve_base_type(self, lhs);
int all_types[TY_TYPE_COUNT]; int all_types[TY_TYPE_COUNT];
memset(all_types, TYPE_END, TY_TYPE_COUNT * sizeof(int)); 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(lhs);
assert(rhs); assert(rhs);
int left = cstatic_resolve(self, lhs); int left = cstatic_resolve_base_type(self, lhs);
int right = cstatic_resolve(self, rhs); int right = cstatic_resolve_base_type(self, rhs);
if (left != right) if (left != right)
{ {

View File

@ -3,6 +3,7 @@
#include "commons.h" #include "commons.h"
#include "node.h" #include "node.h"
#include "type.h"
#define TYPE_END (-1) #define TYPE_END (-1)
@ -13,10 +14,16 @@ typedef struct {
void cstatic_init(cstatic* self); void cstatic_init(cstatic* self);
void cstatic_free(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(cstatic* self, node* ast, char* msg, size_t size);
int cstatic_check_type(cstatic* self, node* lhs, int cstatic_check_type(cstatic* self, node* lhs,
char* msg, size_t size, type* types, ...);
int cstatic_check_type_base(cstatic* self, node* lhs,
char* msg, size_t size, int types, ...); char* msg, size_t size, int types, ...);
int cstatic_check_same_type(cstatic* self, node* lhs, node* rhs, int cstatic_check_same_type(cstatic* self, node* lhs, node* rhs,

View File

@ -6,11 +6,26 @@ void type_init(type* self, int base_type)
{ {
assert(self); assert(self);
self->base_type = base_type; 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) void type_free(type* self)
{ {
assert(self); assert(self);
if (self->array_type != NULL)
{
type_free(self->array_type);
free(self->array_type);
}
} }
type* type_new_clone(type* self) type* type_new_clone(type* self)
@ -20,6 +35,11 @@ type* type_new_clone(type* self)
type* clone = malloc(sizeof(type)); type* clone = malloc(sizeof(type));
type_init(clone, self->base_type); type_init(clone, self->base_type);
if (self->array_type)
{
clone->array_type = type_new_clone(self->array_type);
}
return clone; return clone;
} }
@ -28,11 +48,34 @@ int type_equals(type* self, type* rhs)
assert(self); assert(self);
assert(rhs); assert(rhs);
return self->base_type == rhs->base_type; 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;
} }
size_t type_str(type* self, char* buffer, size_t size) size_t type_str(type* self, char* buffer, size_t size)
{ {
assert(self); 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;
} }

View File

@ -20,9 +20,11 @@ extern char const* TypesStr[];
typedef struct type { typedef struct type {
int base_type; int base_type;
struct type* array_type;
} type; } type;
void type_init(type* self, int base_type); void type_init(type* self, int base_type);
void type_init_array(type* self, type* array_type);
void type_free(type* self); void type_free(type* self);
type* type_new_clone(type* self); type* type_new_clone(type* self);

View File

@ -51,8 +51,9 @@ void value_init_array(value* self, array* arr, int lineno)
self->val.array_val = array_new_clone(arr); self->val.array_val = array_new_clone(arr);
self->lineno = lineno; self->lineno = lineno;
self->type = malloc(sizeof(type)); self->type = malloc(sizeof(type));
type_init(self->type, TY_ARRAY); type_init_array(self->type, arr->type);
} }
void value_free(value* self) void value_free(value* self)

View File

@ -1,2 +1,3 @@
[] []
[1 2 3 "4"] [1 2 3 "4"]
[ [0 1] ["0" "1"] ]