Adds union feature.

This commit is contained in:
falsycat 2020-12-26 00:00:00 +00:00
parent e34d4ca1a8
commit b96fbb6eb2
5 changed files with 43 additions and 18 deletions

View File

@ -7,6 +7,6 @@ X check if an expression is static/dynamic
X enum support X enum support
X constant support X constant support
X conditional switching support X conditional switching support
union support X union support
transpiler for C transpiler for C
release 1.0.0 release 1.0.0

View File

@ -32,6 +32,7 @@ H [0-9A-Fa-f]
"const" { count_(); return CONST; } "const" { count_(); return CONST; }
"enum" { count_(); return ENUM; } "enum" { count_(); return ENUM; }
"struct" { count_(); return STRUCT; } "struct" { count_(); return STRUCT; }
"union" { count_(); return UNION; }
{I}({I}|{D})* { yylval.ptr = strnew_(); count_(); return IDENT; } {I}({I}|{D})* { yylval.ptr = strnew_(); count_(); return IDENT; }

47
biner.y
View File

@ -91,13 +91,13 @@ resolve_constant_(
} }
%token EQUAL NEQUAL LESS_EQUAL GREATER_EQUAL %token EQUAL NEQUAL LESS_EQUAL GREATER_EQUAL
%token CONST ENUM STRUCT %token CONST ENUM STRUCT UNION
%token <ptr> IDENT %token <ptr> IDENT
%token <i> INTEGER; %token <i> INTEGER;
%type <ptr> decl_list decl %type <ptr> decl_list decl
%type <ptr> enum_member_list enum_member %type <ptr> enum_member_list enum_member
%type <ptr> struct_member_list struct_member %type <ptr> struct_member_list struct_member union_member_list union_member
%type <ptr> struct_member_type array_struct_member_type unqualified_struct_member_type %type <ptr> struct_member_type array_struct_member_type unqualified_struct_member_type
%type <ptr> expr compare_expr add_expr mul_expr unary_expr operand %type <ptr> expr compare_expr add_expr mul_expr unary_expr operand
@ -167,21 +167,48 @@ enum_member
; ;
struct_member_list struct_member_list
: struct_member { : struct_member ';' {
$$ = ctx.last_struct = $1; $$ = ctx.last_struct = $1;
} }
| struct_member_list struct_member { | struct_member_list struct_member ';' {
ref(biner_tree_struct_member_t, $2)->prev = $1;
$$ = ctx.last_struct = $2; $$ = ctx.last_struct = $2;
biner_tree_struct_member_t* list = ref(biner_tree_struct_member_t, $1);
const size_t index = list->index + 1;
biner_zone_ptr(biner_tree_struct_member_t) itr = $2;
while (itr) {
biner_tree_struct_member_t* m = ref(biner_tree_struct_member_t, itr);
m->index = index;
itr = m->prev;
if (itr == 0) m->prev = $1;
}
}
;
union_member_list
: union_member ';' {
$$ = $1;
}
| union_member_list union_member ';' {
$$ = $2;
ref(biner_tree_struct_member_t, $2)->prev = $1;
} }
; ;
struct_member struct_member
: struct_member_type IDENT ';' { : union_member
| UNION '{' union_member_list '}' {
$$ = $3;
}
;
union_member
: struct_member_type IDENT {
$$ = create_struct_member_(0, $1, $2); $$ = create_struct_member_(0, $1, $2);
if ($$ == 0) YYABORT; if ($$ == 0) YYABORT;
} }
| '(' expr ')' struct_member_type IDENT ';' { | '(' expr ')' struct_member_type IDENT {
$$ = create_struct_member_($2, $4, $5); $$ = create_struct_member_($2, $4, $5);
if ($$ == 0) YYABORT; if ($$ == 0) YYABORT;
} }
@ -214,7 +241,6 @@ unqualified_struct_member_type
*t = (biner_tree_struct_member_type_t) { *t = (biner_tree_struct_member_type_t) {
.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); const biner_zone_ptr(biner_tree_decl_t) decl = find_decl_by_name_($1);
if (decl == 0) { if (decl == 0) {
if (!unstringify_struct_member_type_name_(&t->name, $1)) { if (!unstringify_struct_member_type_name_(&t->name, $1)) {
@ -359,8 +385,9 @@ static inline biner_zone_ptr(biner_tree_decl_t) create_decl_(
.type = type, .type = type,
.body = body, .body = body,
}; };
ctx.last_decl = decl; ctx.last_decl = decl;
ctx.last_body = 0; ctx.last_enum = 0;
ctx.last_struct = 0;
return decl; return decl;
} }

2
main.c
View File

@ -28,7 +28,7 @@ static inline void print_struct_(
const biner_tree_struct_member_t* member = const biner_tree_struct_member_t* member =
(const biner_tree_struct_member_t*) (zone + decl->struct_); (const biner_tree_struct_member_t*) (zone + decl->struct_);
while ((uintptr_t) member != (uintptr_t) zone) { while ((uintptr_t) member != (uintptr_t) zone) {
printf(" "); printf(" %2zu ", member->index);
const biner_tree_struct_member_type_t* type = const biner_tree_struct_member_type_t* type =
(const biner_tree_struct_member_type_t*) (zone + member->type); (const biner_tree_struct_member_type_t*) (zone + member->type);
if (type->name == BINER_TREE_STRUCT_MEMBER_TYPE_NAME_USER_DECL) { if (type->name == BINER_TREE_STRUCT_MEMBER_TYPE_NAME_USER_DECL) {

9
tree.h
View File

@ -84,6 +84,7 @@ typedef struct biner_tree_struct_member_type_t {
} biner_tree_struct_member_type_t; } biner_tree_struct_member_type_t;
typedef struct biner_tree_struct_member_t { typedef struct biner_tree_struct_member_t {
size_t index;
biner_zone_ptr(char) name; biner_zone_ptr(char) name;
biner_zone_ptr(biner_tree_struct_member_type_t) type; biner_zone_ptr(biner_tree_struct_member_type_t) type;
biner_zone_ptr(biner_tree_expr_t) condition; biner_zone_ptr(biner_tree_expr_t) condition;
@ -135,12 +136,8 @@ typedef struct biner_tree_parse_context_t {
biner_zone_ptr(biner_tree_root_t) root; biner_zone_ptr(biner_tree_root_t) root;
biner_zone_ptr(biner_tree_decl_t) last_decl; biner_zone_ptr(biner_tree_decl_t) last_decl;
union { biner_zone_ptr(biner_tree_struct_member_t) last_struct;
biner_zone_ptr(void) last_body; biner_zone_ptr(biner_tree_enum_member_t) last_enum;
biner_zone_ptr(biner_tree_struct_member_t) last_struct;
biner_zone_ptr(biner_tree_enum_member_t) last_enum;
};
} biner_tree_parse_context_t; } 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_;