Allows parser to resolve struct member types.

This commit is contained in:
falsycat 2020-12-22 00:00:00 +00:00
parent 5f375dff74
commit fd3a5344b3
5 changed files with 105 additions and 31 deletions

View File

@ -1,7 +1,7 @@
X parser X parser
X error handling (compiler message) X error handling (compiler message)
user-defined type resolving X user-defined type resolving
make enum for generic types X make enum for generic types
location for each declarations location for each declarations
expression resolving expression resolving
enum support enum support

55
biner.y
View File

@ -51,7 +51,9 @@ unwrap_struct_member_ref_(
%token <i> INTEGER; %token <i> INTEGER;
%type <ptr> decl_list decl %type <ptr> decl_list decl
%type <ptr> struct_body struct_member struct_member_type struct_member_reference %type <ptr> struct_member_list struct_member
%type <ptr> struct_member_type array_struct_member_type unqualified_struct_member_type
%type <ptr> struct_member_reference
%type <ptr> expr add_expr mul_expr operand %type <ptr> expr add_expr mul_expr operand
%start decl_list %start decl_list
@ -73,7 +75,7 @@ decl_list
; ;
decl decl
: STRUCT IDENT '{' struct_body '}' ';' { : STRUCT IDENT '{' struct_member_list '}' ';' {
if (find_decl_by_name_($2) != 0) { if (find_decl_by_name_($2) != 0) {
yyerrorf("duplicated declaration of '%s'", ref(char, $2)); yyerrorf("duplicated declaration of '%s'", ref(char, $2));
YYABORT; YYABORT;
@ -88,11 +90,11 @@ decl
} }
; ;
struct_body struct_member_list
: struct_member { : struct_member {
$$ = ctx.last_member = $1; $$ = ctx.last_member = $1;
} }
| struct_body struct_member { | struct_member_list struct_member {
ref(biner_tree_struct_member_t, $2)->prev = $1; ref(biner_tree_struct_member_t, $2)->prev = $1;
$$ = ctx.last_member = $2; $$ = ctx.last_member = $2;
} }
@ -114,25 +116,40 @@ struct_member
; ;
struct_member_type struct_member_type
: array_struct_member_type
| unqualified_struct_member_type
;
array_struct_member_type
: unqualified_struct_member_type '[' expr ']' {
$$ = $1;
biner_tree_struct_member_type_t* t =
ref(biner_tree_struct_member_type_t, $$);
t->qualifier = BINER_TREE_STRUCT_MEMBER_TYPE_QUALIFIER_DYNAMIC_ARRAY;
t->expr = $3;
}
;
unqualified_struct_member_type
: IDENT { : IDENT {
/* TODO: upgrade generic type to user-defined type. */
$$ = alloc_(biner_tree_struct_member_type_t); $$ = alloc_(biner_tree_struct_member_type_t);
*ref(biner_tree_struct_member_type_t, $$) = biner_tree_struct_member_type_t* t =
(biner_tree_struct_member_type_t) { ref(biner_tree_struct_member_type_t, $$);
.kind = BINER_TREE_STRUCT_MEMBER_TYPE_KIND_GENERIC, *t = (biner_tree_struct_member_type_t) {
.generic = $1,
.qualifier = BINER_TREE_STRUCT_MEMBER_TYPE_QUALIFIER_NONE, .qualifier = BINER_TREE_STRUCT_MEMBER_TYPE_QUALIFIER_NONE,
}; };
const biner_zone_ptr(biner_tree_decl_t) decl = find_decl_by_name_($1);
if (decl == 0) {
if (!biner_tree_struct_member_type_name_unstringify(
&t->name, ref(char, $1))) {
yyerrorf("unknown type '%s'", ref(char, $1));
YYABORT;
}
} else {
t->name = BINER_TREE_STRUCT_MEMBER_TYPE_NAME_USER_DECL;
t->decl = decl;
} }
| IDENT '[' expr ']' {
$$ = alloc_(biner_tree_struct_member_type_t);
*ref(biner_tree_struct_member_type_t, $$) =
(biner_tree_struct_member_type_t) {
.kind = BINER_TREE_STRUCT_MEMBER_TYPE_KIND_GENERIC,
.generic = $1,
.qualifier = BINER_TREE_STRUCT_MEMBER_TYPE_QUALIFIER_DYNAMIC_ARRAY,
.expr = $3,
};
} }
; ;
@ -254,7 +271,7 @@ find_child_struct_member_by_name_(
const biner_tree_struct_member_type_t* t = const biner_tree_struct_member_type_t* t =
ref(biner_tree_struct_member_type_t, m->type); ref(biner_tree_struct_member_type_t, m->type);
if (t->kind != BINER_TREE_STRUCT_MEMBER_TYPE_KIND_USER_DEFINED) { if (t->name != BINER_TREE_STRUCT_MEMBER_TYPE_NAME_USER_DECL) {
yyerrorf("typeof '%s' is not user-defined", ref(char, m->name)); yyerrorf("typeof '%s' is not user-defined", ref(char, m->name));
return 0; return 0;
} }

11
main.c
View File

@ -18,6 +18,17 @@ int main(void) {
const biner_tree_struct_member_t* member = const biner_tree_struct_member_t* member =
(const biner_tree_struct_member_t*) (zone + decl->member); (const biner_tree_struct_member_t*) (zone + decl->member);
while ((uintptr_t) member != (uintptr_t) zone) { while ((uintptr_t) member != (uintptr_t) zone) {
printf(" ");
const biner_tree_struct_member_type_t* type =
(const biner_tree_struct_member_type_t*) (zone + member->type);
if (type->name == BINER_TREE_STRUCT_MEMBER_TYPE_NAME_USER_DECL) {
const biner_tree_decl_t* decl =
(const biner_tree_decl_t*) (zone + type->decl);
printf("%8s ", zone + decl->name);
} else {
printf("%8s ",
biner_tree_struct_member_type_name_string_map[type->name]);
}
printf("%s\n", zone + member->name); printf("%s\n", zone + member->name);
member = (const biner_tree_struct_member_t*) (zone + member->prev); member = (const biner_tree_struct_member_t*) (zone + member->prev);
} }

14
tree.c
View File

@ -12,6 +12,20 @@
#include "generated/biner.y.h" #include "generated/biner.y.h"
const char* const biner_tree_struct_member_type_name_string_map
[BINER_TREE_STRUCT_MEMBER_TYPE_NAME_MAX_] = {
[BINER_TREE_STRUCT_MEMBER_TYPE_NAME_UINT8] = "uint8_t",
[BINER_TREE_STRUCT_MEMBER_TYPE_NAME_UINT16] = "uint16_t",
[BINER_TREE_STRUCT_MEMBER_TYPE_NAME_UINT32] = "uint32_t",
[BINER_TREE_STRUCT_MEMBER_TYPE_NAME_UINT64] = "uint64_t",
[BINER_TREE_STRUCT_MEMBER_TYPE_NAME_INT8] = "int8_t",
[BINER_TREE_STRUCT_MEMBER_TYPE_NAME_INT16] = "int16_t",
[BINER_TREE_STRUCT_MEMBER_TYPE_NAME_INT32] = "int32_t",
[BINER_TREE_STRUCT_MEMBER_TYPE_NAME_INT64] = "int64_t",
[BINER_TREE_STRUCT_MEMBER_TYPE_NAME_FLOAT32] = "float",
[BINER_TREE_STRUCT_MEMBER_TYPE_NAME_FLOAT64] = "double",
};
biner_tree_parse_context_t biner_tree_parse_context_ = {0}; biner_tree_parse_context_t biner_tree_parse_context_ = {0};
const uint8_t* biner_tree_parse(FILE* fp) { const uint8_t* biner_tree_parse(FILE* fp) {

44
tree.h
View File

@ -1,9 +1,12 @@
#pragma once #pragma once
#include <assert.h>
#include <stdatomic.h> #include <stdatomic.h>
#include <stdbool.h>
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
#include <stdio.h> #include <stdio.h>
#include <string.h>
#include "./zone.h" #include "./zone.h"
@ -34,10 +37,24 @@ typedef struct biner_tree_expr_t {
}; };
} biner_tree_expr_t; } biner_tree_expr_t;
typedef enum biner_tree_struct_member_type_kind_t { typedef enum biner_tree_struct_member_type_name_t {
BINER_TREE_STRUCT_MEMBER_TYPE_KIND_GENERIC, BINER_TREE_STRUCT_MEMBER_TYPE_NAME_UINT8,
BINER_TREE_STRUCT_MEMBER_TYPE_KIND_USER_DEFINED, BINER_TREE_STRUCT_MEMBER_TYPE_NAME_UINT16,
} biner_tree_struct_member_type_kind_t; BINER_TREE_STRUCT_MEMBER_TYPE_NAME_UINT32,
BINER_TREE_STRUCT_MEMBER_TYPE_NAME_UINT64,
BINER_TREE_STRUCT_MEMBER_TYPE_NAME_INT8,
BINER_TREE_STRUCT_MEMBER_TYPE_NAME_INT16,
BINER_TREE_STRUCT_MEMBER_TYPE_NAME_INT32,
BINER_TREE_STRUCT_MEMBER_TYPE_NAME_INT64,
BINER_TREE_STRUCT_MEMBER_TYPE_NAME_FLOAT32,
BINER_TREE_STRUCT_MEMBER_TYPE_NAME_FLOAT64,
BINER_TREE_STRUCT_MEMBER_TYPE_NAME_USER_DECL,
BINER_TREE_STRUCT_MEMBER_TYPE_NAME_MAX_,
} biner_tree_struct_member_type_name_t;
extern const char* const biner_tree_struct_member_type_name_string_map
[BINER_TREE_STRUCT_MEMBER_TYPE_NAME_MAX_];
typedef enum biner_tree_struct_member_type_qualifier_t { typedef enum biner_tree_struct_member_type_qualifier_t {
BINER_TREE_STRUCT_MEMBER_TYPE_QUALIFIER_NONE, BINER_TREE_STRUCT_MEMBER_TYPE_QUALIFIER_NONE,
@ -46,9 +63,8 @@ typedef enum biner_tree_struct_member_type_qualifier_t {
} biner_tree_struct_member_type_qualifier_t; } biner_tree_struct_member_type_qualifier_t;
typedef struct biner_tree_struct_member_type_t { typedef struct biner_tree_struct_member_type_t {
biner_tree_struct_member_type_kind_t kind; biner_tree_struct_member_type_name_t name;
union { union {
biner_zone_ptr(char) generic;
biner_zone_ptr(biner_tree_decl_t) decl; biner_zone_ptr(biner_tree_decl_t) decl;
}; };
@ -104,6 +120,22 @@ typedef struct biner_tree_parse_context_t {
extern biner_tree_parse_context_t biner_tree_parse_context_; extern biner_tree_parse_context_t biner_tree_parse_context_;
static inline bool biner_tree_struct_member_type_name_unstringify(
biner_tree_struct_member_type_name_t* name,
const char* str) {
assert(name != NULL);
assert(str != NULL);
for (size_t i = 0; i < BINER_TREE_STRUCT_MEMBER_TYPE_NAME_MAX_; ++i) {
const char* item = biner_tree_struct_member_type_name_string_map[i];
if (item != NULL && strcmp(str, item) == 0) {
*name = (biner_tree_struct_member_type_name_t) i;
return true;
}
}
return false;
}
const uint8_t* const uint8_t*
biner_tree_parse( biner_tree_parse(
FILE* fp FILE* fp