ADD: type literals.

main
bog 2023-08-24 23:28:45 +02:00
parent 7a4e71bf14
commit 0b44732961
10 changed files with 210 additions and 25 deletions

View File

@ -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; i<root->children.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)

View File

@ -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);

View File

@ -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);

View File

@ -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; }

View File

@ -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), \

View File

@ -22,18 +22,21 @@
};
%left ASSERT
%token <str> BOOLEAN INTEGER FLOAT STRING
%type <n_children> expr exprs prog array arrays builtins
%type <n_children> expr_list
%token LT GT
%token <str> TYPE BOOLEAN INTEGER FLOAT STRING
%type <n_children> expr exprs prog array builtins
%type <n_children> 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 <n_children> 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; i<SZ; i++)
{
node_add_child(n, stack_pop());
all[i] = stack_pop();
}
for (size_t i=0; i<SZ; i++)
{
node_add_child(n, all[SZ - 1 - i]);
}
stack_push(n);
@ -105,23 +115,10 @@ expr:
$$ = 1;
}
| ADD expr {
node *n = malloc(sizeof(node));
node_init(n, NODE_UADD, "", line);
node_add_child(n, stack_pop());
stack_push(n);
$$ = 1;
}
| SUB expr {
node *n = malloc(sizeof(node));
node_init(n, NODE_USUB, "", line);
node_add_child(n, stack_pop());
stack_push(n);
$$ = 1;
}
| expr_unop {}
| expr ADD expr {
| expr ADD expr{
node *n = malloc(sizeof(node));
node_init(n, NODE_ADD, "", line);
node* rhs = stack_pop();
@ -143,6 +140,7 @@ expr:
$$ = 1;
}
| expr MUL expr {
node *n = malloc(sizeof(node));
node_init(n, NODE_MUL, "", line);
@ -246,9 +244,65 @@ expr:
;
builtins:
expr_unop:
ADD expr {
node *n = malloc(sizeof(node));
node_init(n, NODE_UADD, "", line);
node_add_child(n, stack_pop());
stack_push(n);
$$ = 1;
}
STRING {
| SUB expr {
node *n = malloc(sizeof(node));
node_init(n, NODE_USUB, "", line);
node_add_child(n, stack_pop());
stack_push(n);
$$ = 1;
}
;
type_list:
type { $$ = $1; }
| type_list COMMA type { $$ = $1 + $3; }
;
type:
TYPE LT type_list GT {
node* n = malloc(sizeof(node));
node_init(n, NODE_TYPE, $1, line);
free($1);
size_t const SZ = $3;
node* all[SZ];
for (size_t i=0; i<SZ; i++)
{
all[i] = stack_pop();
}
for (size_t i=0; i<SZ; i++)
{
node_add_child(n, all[SZ - 1 - i]);
}
stack_push(n);
$$ = 1;
}
| TYPE {
node* n = malloc(sizeof(node));
node_init(n, NODE_TYPE, $1, line);
free($1);
stack_push(n);
$$ = 1;
}
;
builtins:
type {}
| STRING {
node* n = malloc(sizeof(node));
size_t const SZ = strlen($1);
char str[SZ - 2];

View File

@ -10,6 +10,7 @@
G(TY_FLOAT), \
G(TY_STRING), \
G(TY_ARRAY), \
G(TY_TYPE), \
G(TY_TYPE_COUNT)
enum Types {

View File

@ -56,10 +56,29 @@ void value_init_array(value* self, array* arr, int lineno)
type_init_array(self->type, 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);
}
}

View File

@ -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);

13
tests/test_types.wuz Normal file
View File

@ -0,0 +1,13 @@
assert int == int
assert float == float
assert str == str
assert bool == bool
assert array<int> == array<int>
assert array<array<int>> == array<array<int>>
assert int != float
assert float != str
assert str != bool
assert bool != int
assert array<float> != array<int>
assert array<array<int>> != array<int>