Allows parser to resolve struct member types.
This commit is contained in:
parent
5f375dff74
commit
fd3a5344b3
4
TODO.TXT
4
TODO.TXT
@ -1,7 +1,7 @@
|
||||
X parser
|
||||
X error handling (compiler message)
|
||||
user-defined type resolving
|
||||
make enum for generic types
|
||||
X user-defined type resolving
|
||||
X make enum for generic types
|
||||
location for each declarations
|
||||
expression resolving
|
||||
enum support
|
||||
|
55
biner.y
55
biner.y
@ -51,7 +51,9 @@ unwrap_struct_member_ref_(
|
||||
%token <i> INTEGER;
|
||||
|
||||
%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
|
||||
|
||||
%start decl_list
|
||||
@ -73,7 +75,7 @@ decl_list
|
||||
;
|
||||
|
||||
decl
|
||||
: STRUCT IDENT '{' struct_body '}' ';' {
|
||||
: STRUCT IDENT '{' struct_member_list '}' ';' {
|
||||
if (find_decl_by_name_($2) != 0) {
|
||||
yyerrorf("duplicated declaration of '%s'", ref(char, $2));
|
||||
YYABORT;
|
||||
@ -88,11 +90,11 @@ decl
|
||||
}
|
||||
;
|
||||
|
||||
struct_body
|
||||
struct_member_list
|
||||
: struct_member {
|
||||
$$ = ctx.last_member = $1;
|
||||
}
|
||||
| struct_body struct_member {
|
||||
| struct_member_list struct_member {
|
||||
ref(biner_tree_struct_member_t, $2)->prev = $1;
|
||||
$$ = ctx.last_member = $2;
|
||||
}
|
||||
@ -114,25 +116,40 @@ struct_member
|
||||
;
|
||||
|
||||
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 {
|
||||
/* TODO: upgrade generic type to user-defined type. */
|
||||
$$ = 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,
|
||||
biner_tree_struct_member_type_t* t =
|
||||
ref(biner_tree_struct_member_type_t, $$);
|
||||
*t = (biner_tree_struct_member_type_t) {
|
||||
.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 =
|
||||
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));
|
||||
return 0;
|
||||
}
|
||||
|
11
main.c
11
main.c
@ -18,6 +18,17 @@ int main(void) {
|
||||
const biner_tree_struct_member_t* member =
|
||||
(const biner_tree_struct_member_t*) (zone + decl->member);
|
||||
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);
|
||||
member = (const biner_tree_struct_member_t*) (zone + member->prev);
|
||||
}
|
||||
|
14
tree.c
14
tree.c
@ -12,6 +12,20 @@
|
||||
|
||||
#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};
|
||||
|
||||
const uint8_t* biner_tree_parse(FILE* fp) {
|
||||
|
44
tree.h
44
tree.h
@ -1,9 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdatomic.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "./zone.h"
|
||||
|
||||
@ -34,10 +37,24 @@ typedef struct biner_tree_expr_t {
|
||||
};
|
||||
} biner_tree_expr_t;
|
||||
|
||||
typedef enum biner_tree_struct_member_type_kind_t {
|
||||
BINER_TREE_STRUCT_MEMBER_TYPE_KIND_GENERIC,
|
||||
BINER_TREE_STRUCT_MEMBER_TYPE_KIND_USER_DEFINED,
|
||||
} biner_tree_struct_member_type_kind_t;
|
||||
typedef enum biner_tree_struct_member_type_name_t {
|
||||
BINER_TREE_STRUCT_MEMBER_TYPE_NAME_UINT8,
|
||||
BINER_TREE_STRUCT_MEMBER_TYPE_NAME_UINT16,
|
||||
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 {
|
||||
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;
|
||||
|
||||
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 {
|
||||
biner_zone_ptr(char) generic;
|
||||
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_;
|
||||
|
||||
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*
|
||||
biner_tree_parse(
|
||||
FILE* fp
|
||||
|
Loading…
Reference in New Issue
Block a user