From 0b44732961117fa81bf17db13b3cb008b7ac919f Mon Sep 17 00:00:00 2001 From: bog Date: Thu, 24 Aug 2023 23:28:45 +0200 Subject: [PATCH] ADD: type literals. --- src/compiler.c | 68 +++++++++++++++++++++++++++++ src/compiler.h | 2 + src/cstatic.c | 5 +++ src/lex.l | 8 ++++ src/node.h | 2 +- src/parser.y | 100 +++++++++++++++++++++++++++++++++---------- src/type.h | 1 + src/value.c | 34 ++++++++++++++- src/value.h | 2 + tests/test_types.wuz | 13 ++++++ 10 files changed, 210 insertions(+), 25 deletions(-) create mode 100644 tests/test_types.wuz diff --git a/src/compiler.c b/src/compiler.c index 1857e75..a0cf42d 100644 --- a/src/compiler.c +++ b/src/compiler.c @@ -86,6 +86,24 @@ void compile_node(compiler* self, node* root, program* prog) compile_number(self, root, prog, OP_IADD, OP_FADD); } } + else if (root->type == NODE_TYPE) + { + type* ty = compile_get_type(self, root); + + + value val; + value_init_type(&val, + ty, + root->lineno); + + size_t idx = program_add_pool(prog, &val); + program_add_instr(prog, OP_PUSH, idx); + + type_free(ty); + free(ty); + + value_free(&val); + } else if (root->type == NODE_BOOLEAN) { value val; @@ -208,6 +226,56 @@ void compile_children(compiler* self, node* root, program* prog) } } +type* compile_get_type(compiler* self, node* root) +{ + assert(self); + assert(root); + type* ty = malloc(sizeof(type)); + + if (strcmp(root->value, "int") == 0) + { + type_init(ty, TY_INTEGER); + } + + else if (strcmp(root->value, "float") == 0) + { + type_init(ty, TY_FLOAT); + } + + else if (strcmp(root->value, "str") == 0) + { + type_init(ty, TY_STRING); + } + + else if (strcmp(root->value, "bool") == 0) + { + type_init(ty, TY_BOOLEAN); + } + + else if (strcmp(root->value, "array") == 0) + { + type_init(ty, TY_ARRAY); + } + + else + { + fprintf(stderr, + "E(%d): cannot compile unknown type '%s'.'\n", + root->lineno, + root->value); + } + + for (size_t i=0; ichildren.size; i++) + { + type* sub = compile_get_type(self, root->children.data[i]); + type_add_sub_type(ty, sub); + type_free(sub); + free(sub); + } + + return ty; +} + void compile_number(compiler* self, node* root, program* prog, int integer_op, int float_op) diff --git a/src/compiler.h b/src/compiler.h index 835fcfd..eed284a 100644 --- a/src/compiler.h +++ b/src/compiler.h @@ -15,6 +15,8 @@ void compiler_free(compiler* self); void compile_node(compiler* self, node* root, program* prog); void compile_children(compiler* self, node* root, program* prog); +type* compile_get_type(compiler* self, node* root); + void compile_number(compiler* self, node* root, program* prog, int integer_op, int float_op); diff --git a/src/cstatic.c b/src/cstatic.c index e219d0c..55b0cf2 100644 --- a/src/cstatic.c +++ b/src/cstatic.c @@ -105,6 +105,11 @@ type* cstatic_resolve_new(cstatic* self, node* ast) return cstatic_new_type(self, TY_STRING); } + else if (ast->type == NODE_TYPE) + { + return cstatic_new_type(self, TY_TYPE); + } + else if (ast->type == NODE_ARRAY) { assert(ast->children.size > 0); diff --git a/src/lex.l b/src/lex.l index 4db3e1d..9e50740 100644 --- a/src/lex.l +++ b/src/lex.l @@ -13,13 +13,21 @@ BOOLEAN true|false INTEGER -?[0-9]+ FLOAT -?[0-9]+\.[0-9]+ STRING \"[^"]*\" +TYPE (int|float|bool|str|array) %% {COMMENT} {} "\n" { line++; } {WHITESPACES} {} +{TYPE} { + yylval.str = str_new(yytext); + return TYPE; +} + "assert" { return ASSERT; } +"<" { return LT; } +">" { return GT; } "," { return COMMA; } "+" { return ADD; } "-" { return SUB; } diff --git a/src/node.h b/src/node.h index 7e73ca0..51bc777 100644 --- a/src/node.h +++ b/src/node.h @@ -4,7 +4,7 @@ #define NODE_TYPE(G) \ G(NODE_PROG), \ G(NODE_BOOLEAN), G(NODE_INTEGER), G(NODE_FLOAT), \ - G(NODE_STRING), \ + G(NODE_STRING), G(NODE_TYPE), \ G(NODE_AND), G(NODE_OR), G(NODE_NOT), \ G(NODE_EQ), G(NODE_NE), \ G(NODE_ASSERT), \ diff --git a/src/parser.y b/src/parser.y index 0abcd5c..c9d3514 100644 --- a/src/parser.y +++ b/src/parser.y @@ -22,18 +22,21 @@ }; %left ASSERT -%token BOOLEAN INTEGER FLOAT STRING -%type expr exprs prog array arrays builtins -%type expr_list +%token LT GT +%token TYPE BOOLEAN INTEGER FLOAT STRING +%type expr exprs prog array builtins +%type expr_list type type_list %left EQ NE %left AND %left OR -%left ADD SUB +%left ADD +%left SUB %left MUL DIV MOD %left POW %left NOT %token OPAR CPAR OSQUARE CSQUARE COMMA +%type expr_unop %% prog: @@ -47,10 +50,17 @@ prog: | exprs { node* n = malloc(sizeof(node)); node_init(n, NODE_PROG, "", line); + size_t const SZ = $1; + node* all[SZ]; - for (size_t i=0; i<$1; i++) + for (size_t i=0; itype, arr->type); } +void value_init_type(value* self, type* ty, int lineno) +{ + assert(self); + assert(ty); + + self->val.type_val = type_new_clone(ty); + self->lineno = lineno; + self->type = malloc(sizeof(type)); + type_init(self->type, TY_TYPE); +} + void value_free(value* self) { assert(self); + if (self->type->base_type == TY_TYPE + && self->val.type_val != NULL) + { + type_free(self->val.type_val); + free(self->val.type_val); + self->val.type_val = NULL; + } + if (self->type->base_type == TY_STRING && self->val.string != NULL) { @@ -92,6 +111,11 @@ value* value_new_clone(value* self) clone->val.string = str_new(self->val.string); } + if (self->type->base_type == TY_TYPE) + { + clone->val.type_val = type_new_clone(self->val.type_val); + } + if (self->type->base_type == TY_ARRAY) { clone->val.array_val = array_new_clone(self->val.array_val); @@ -133,6 +157,11 @@ int value_equals(value* self, value* rhs) return strcmp(self->val.string, rhs->val.string) == 0; } + if (self->type->base_type == TY_TYPE) + { + return type_equals(self->val.type_val, rhs->val.type_val); + } + if (self->type->base_type == TY_ARRAY) { return array_equals(self->val.array_val, rhs->val.array_val); @@ -167,8 +196,11 @@ size_t value_str(value* self, char* buffer, size_t size) case TY_INTEGER: return snprintf(buffer, size, "%d", self->val.integer); + case TY_TYPE: + return type_str(self->val.type_val, buffer, size); + default: { - fprintf(stderr, "E: unknown value"); + fprintf(stderr, "E: cannot stringify unknown value"); exit(-1); } } diff --git a/src/value.h b/src/value.h index f100302..901c2dd 100644 --- a/src/value.h +++ b/src/value.h @@ -14,6 +14,7 @@ typedef struct { float real_float; char* string; array* array_val; + type* type_val; } val; } value; @@ -22,6 +23,7 @@ void value_init_integer(value* self, int integer, int lineno); void value_init_float(value* self, float real_float, int lineno); void value_init_string(value* self, char* string, int lineno); void value_init_array(value* self, array* arr, int lineno); +void value_init_type(value* self, type* ty, int lineno); void value_free(value* self); diff --git a/tests/test_types.wuz b/tests/test_types.wuz new file mode 100644 index 0000000..2485eb7 --- /dev/null +++ b/tests/test_types.wuz @@ -0,0 +1,13 @@ +assert int == int +assert float == float +assert str == str +assert bool == bool +assert array == array +assert array> == array> + +assert int != float +assert float != str +assert str != bool +assert bool != int +assert array != array +assert array> != array