From fd3a5344b3389455c44b6210d5deb4e868561031 Mon Sep 17 00:00:00 2001 From: falsycat Date: Tue, 22 Dec 2020 00:00:00 +0000 Subject: [PATCH] Allows parser to resolve struct member types. --- TODO.TXT | 4 ++-- biner.y | 61 ++++++++++++++++++++++++++++++++++++-------------------- main.c | 13 +++++++++++- tree.c | 14 +++++++++++++ tree.h | 44 ++++++++++++++++++++++++++++++++++------ 5 files changed, 105 insertions(+), 31 deletions(-) diff --git a/TODO.TXT b/TODO.TXT index 98d9bc6..6ae426e 100644 --- a/TODO.TXT +++ b/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 diff --git a/biner.y b/biner.y index 29d1428..eee970b 100644 --- a/biner.y +++ b/biner.y @@ -51,7 +51,9 @@ unwrap_struct_member_ref_( %token INTEGER; %type decl_list decl -%type struct_body struct_member struct_member_type struct_member_reference +%type struct_member_list struct_member +%type struct_member_type array_struct_member_type unqualified_struct_member_type +%type struct_member_reference %type 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 - : 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, - .qualifier = BINER_TREE_STRUCT_MEMBER_TYPE_QUALIFIER_NONE, - }; + : 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; } - | IDENT '[' expr ']' { + ; + +unqualified_struct_member_type + : IDENT { $$ = 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, - }; + 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; + } } ; @@ -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; } diff --git a/main.c b/main.c index bd60d22..cca323c 100644 --- a/main.c +++ b/main.c @@ -18,7 +18,18 @@ 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(" %s\n", zone + member->name); + 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); } decl = (const biner_tree_decl_t*) (zone + decl->prev); diff --git a/tree.c b/tree.c index a4ab2cf..310e3e5 100644 --- a/tree.c +++ b/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) { diff --git a/tree.h b/tree.h index 03051d5..86efd68 100644 --- a/tree.h +++ b/tree.h @@ -1,9 +1,12 @@ #pragma once +#include #include +#include #include #include #include +#include #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