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 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
55
biner.y
@ -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
11
main.c
@ -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
14
tree.c
@ -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
44
tree.h
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user