Adds conditional switching feature.
This commit is contained in:
parent
b4957586e4
commit
e34d4ca1a8
2
TODO.TXT
2
TODO.TXT
@ -6,7 +6,7 @@ X constant resolving in expression
|
|||||||
X check if an expression is static/dynamic
|
X check if an expression is static/dynamic
|
||||||
X enum support
|
X enum support
|
||||||
X constant support
|
X constant support
|
||||||
conditional switching support
|
X conditional switching support
|
||||||
union support
|
union support
|
||||||
transpiler for C
|
transpiler for C
|
||||||
release 1.0.0
|
release 1.0.0
|
||||||
|
7
biner.l
7
biner.l
@ -24,6 +24,11 @@ H [0-9A-Fa-f]
|
|||||||
"//".* count_();
|
"//".* count_();
|
||||||
[/][*][^*]*[*]+([^*/][^*]*[*]+)*[/] count_(); /* TODO: detect unterminated comment */
|
[/][*][^*]*[*]+([^*/][^*]*[*]+)*[/] count_(); /* TODO: detect unterminated comment */
|
||||||
|
|
||||||
|
"==" { count_(); return EQUAL; }
|
||||||
|
"!=" { count_(); return NEQUAL; }
|
||||||
|
"<=" { count_(); return LESS_EQUAL; }
|
||||||
|
">=" { count_(); return GREATER_EQUAL; }
|
||||||
|
|
||||||
"const" { count_(); return CONST; }
|
"const" { count_(); return CONST; }
|
||||||
"enum" { count_(); return ENUM; }
|
"enum" { count_(); return ENUM; }
|
||||||
"struct" { count_(); return STRUCT; }
|
"struct" { count_(); return STRUCT; }
|
||||||
@ -33,7 +38,7 @@ H [0-9A-Fa-f]
|
|||||||
{D}+ { yylval.i = parse_int_(10); count_(); return INTEGER; }
|
{D}+ { yylval.i = parse_int_(10); count_(); return INTEGER; }
|
||||||
0[xX]{H}+ { yylval.i = parse_int_(16); count_(); return INTEGER; }
|
0[xX]{H}+ { yylval.i = parse_int_(16); count_(); return INTEGER; }
|
||||||
|
|
||||||
[\+\-\*\/\=\.\(\)[\]\{\}\;\,] { count_(); return yytext[0]; }
|
[\+\-\*\/\!\=\<\>\.\(\)[\]\{\}\;\,] { count_(); return yytext[0]; }
|
||||||
|
|
||||||
(.|\n) count_();
|
(.|\n) count_();
|
||||||
|
|
||||||
|
98
biner.y
98
biner.y
@ -42,6 +42,13 @@ find_enum_member_by_name_(
|
|||||||
biner_zone_ptr(char) name
|
biner_zone_ptr(char) name
|
||||||
);
|
);
|
||||||
|
|
||||||
|
static inline biner_zone_ptr(biner_tree_struct_member_t)
|
||||||
|
create_struct_member_(
|
||||||
|
biner_zone_ptr(biner_tree_expr_t) condition,
|
||||||
|
biner_zone_ptr(biner_tree_struct_member_type_t) type,
|
||||||
|
biner_zone_ptr(char) name
|
||||||
|
);
|
||||||
|
|
||||||
static inline bool
|
static inline bool
|
||||||
unstringify_struct_member_type_name_(
|
unstringify_struct_member_type_name_(
|
||||||
biner_tree_struct_member_type_name_t* name,
|
biner_tree_struct_member_type_name_t* name,
|
||||||
@ -83,6 +90,7 @@ resolve_constant_(
|
|||||||
uintptr_t ptr;
|
uintptr_t ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
%token EQUAL NEQUAL LESS_EQUAL GREATER_EQUAL
|
||||||
%token CONST ENUM STRUCT
|
%token CONST ENUM STRUCT
|
||||||
%token <ptr> IDENT
|
%token <ptr> IDENT
|
||||||
%token <i> INTEGER;
|
%token <i> INTEGER;
|
||||||
@ -91,7 +99,7 @@ resolve_constant_(
|
|||||||
%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
|
||||||
%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 add_expr mul_expr operand
|
%type <ptr> expr compare_expr add_expr mul_expr unary_expr operand
|
||||||
|
|
||||||
%start decl_list
|
%start decl_list
|
||||||
|
|
||||||
@ -170,20 +178,12 @@ struct_member_list
|
|||||||
|
|
||||||
struct_member
|
struct_member
|
||||||
: struct_member_type IDENT ';' {
|
: struct_member_type IDENT ';' {
|
||||||
if (resolve_constant_($2) != 0) {
|
$$ = create_struct_member_(0, $1, $2);
|
||||||
yyerrorf("duplicated symbol name, '%s'", ref(char, $2));
|
if ($$ == 0) YYABORT;
|
||||||
YYABORT;
|
|
||||||
}
|
}
|
||||||
if (find_struct_member_by_name_(ctx.last_struct, $2) != 0) {
|
| '(' expr ')' struct_member_type IDENT ';' {
|
||||||
yyerrorf("duplicated struct member of '%s'", ref(char, $2));
|
$$ = create_struct_member_($2, $4, $5);
|
||||||
YYABORT;
|
if ($$ == 0) YYABORT;
|
||||||
}
|
|
||||||
$$ = alloc_(biner_tree_struct_member_t);
|
|
||||||
*ref(biner_tree_struct_member_t, $$) =
|
|
||||||
(biner_tree_struct_member_t) {
|
|
||||||
.type = $1,
|
|
||||||
.name = $2,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
@ -229,7 +229,29 @@ unqualified_struct_member_type
|
|||||||
;
|
;
|
||||||
|
|
||||||
expr
|
expr
|
||||||
: add_expr { $$ = $1; }
|
: compare_expr
|
||||||
|
;
|
||||||
|
|
||||||
|
compare_expr
|
||||||
|
: add_expr
|
||||||
|
| compare_expr EQUAL add_expr {
|
||||||
|
$$ = create_operator_($1, BINER_TREE_EXPR_TYPE_OPERATOR_EQUAL, $3);
|
||||||
|
}
|
||||||
|
| compare_expr NEQUAL add_expr {
|
||||||
|
$$ = create_operator_($1, BINER_TREE_EXPR_TYPE_OPERATOR_NEQUAL, $3);
|
||||||
|
}
|
||||||
|
| compare_expr '>' add_expr {
|
||||||
|
$$ = create_operator_($1, BINER_TREE_EXPR_TYPE_OPERATOR_GREATER, $3);
|
||||||
|
}
|
||||||
|
| compare_expr '<' add_expr {
|
||||||
|
$$ = create_operator_($1, BINER_TREE_EXPR_TYPE_OPERATOR_LESS, $3);
|
||||||
|
}
|
||||||
|
| compare_expr GREATER_EQUAL add_expr {
|
||||||
|
$$ = create_operator_($1, BINER_TREE_EXPR_TYPE_OPERATOR_GREATER_EQUAL, $3);
|
||||||
|
}
|
||||||
|
| compare_expr LESS_EQUAL add_expr {
|
||||||
|
$$ = create_operator_($1, BINER_TREE_EXPR_TYPE_OPERATOR_LESS_EQUAL, $3);
|
||||||
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
add_expr
|
add_expr
|
||||||
@ -243,15 +265,22 @@ add_expr
|
|||||||
;
|
;
|
||||||
|
|
||||||
mul_expr
|
mul_expr
|
||||||
: operand
|
: unary_expr
|
||||||
| mul_expr '*' operand {
|
| mul_expr '*' unary_expr {
|
||||||
$$ = create_operator_($1, BINER_TREE_EXPR_TYPE_OPERATOR_MUL, $3);
|
$$ = create_operator_($1, BINER_TREE_EXPR_TYPE_OPERATOR_MUL, $3);
|
||||||
}
|
}
|
||||||
| mul_expr '/' operand {
|
| mul_expr '/' unary_expr {
|
||||||
$$ = create_operator_($1, BINER_TREE_EXPR_TYPE_OPERATOR_DIV, $3);
|
$$ = create_operator_($1, BINER_TREE_EXPR_TYPE_OPERATOR_DIV, $3);
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
unary_expr
|
||||||
|
: operand
|
||||||
|
| '!' operand {
|
||||||
|
$$ = create_operator_($2, BINER_TREE_EXPR_TYPE_OPERATOR_NOT, 0);
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
operand
|
operand
|
||||||
: INTEGER {
|
: INTEGER {
|
||||||
$$ = alloc_(biner_tree_expr_t);
|
$$ = alloc_(biner_tree_expr_t);
|
||||||
@ -295,13 +324,15 @@ operand
|
|||||||
yyerrorf("unknown member '%s'", ref(char, $3));
|
yyerrorf("unknown member '%s'", ref(char, $3));
|
||||||
YYABORT;
|
YYABORT;
|
||||||
}
|
}
|
||||||
$$ = alloc_(biner_tree_struct_member_reference_t);
|
biner_zone_ptr(biner_tree_struct_member_reference_t) r =
|
||||||
*ref(biner_tree_struct_member_reference_t, $$) =
|
alloc_(biner_tree_struct_member_reference_t);
|
||||||
|
*ref(biner_tree_struct_member_reference_t, r) =
|
||||||
(biner_tree_struct_member_reference_t) {
|
(biner_tree_struct_member_reference_t) {
|
||||||
.member = m,
|
.member = m,
|
||||||
.prev = expr->r,
|
.prev = expr->r,
|
||||||
};
|
};
|
||||||
expr->r = $$;
|
expr->r = r;
|
||||||
|
$$ = $1;
|
||||||
/* A shared expression such as constant cannot have a reference to member.
|
/* A shared expression such as constant cannot have a reference to member.
|
||||||
* So modification of the expression doesn't cause any side effects.
|
* So modification of the expression doesn't cause any side effects.
|
||||||
*/
|
*/
|
||||||
@ -344,6 +375,29 @@ static inline biner_zone_ptr(biner_tree_decl_t) find_decl_by_name_(
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline biner_zone_ptr(biner_tree_struct_member_t) create_struct_member_(
|
||||||
|
biner_zone_ptr(biner_tree_expr_t) condition,
|
||||||
|
biner_zone_ptr(biner_tree_struct_member_type_t) type,
|
||||||
|
biner_zone_ptr(char) name) {
|
||||||
|
if (resolve_constant_(name) != 0) {
|
||||||
|
yyerrorf("duplicated symbol name, '%s'", ref(char, name));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (find_struct_member_by_name_(ctx.last_struct, name) != 0) {
|
||||||
|
yyerrorf("duplicated struct member of '%s'", ref(char, name));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
const biner_zone_ptr(biner_tree_struct_member_t) ret =
|
||||||
|
alloc_(biner_tree_struct_member_t);
|
||||||
|
*ref(biner_tree_struct_member_t, ret) =
|
||||||
|
(biner_tree_struct_member_t) {
|
||||||
|
.type = type,
|
||||||
|
.condition = condition,
|
||||||
|
.name = name,
|
||||||
|
};
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static inline biner_zone_ptr(biner_tree_expr_t) find_enum_member_by_name_(
|
static inline biner_zone_ptr(biner_tree_expr_t) find_enum_member_by_name_(
|
||||||
biner_zone_ptr(biner_tree_enum_member_t) tail_member,
|
biner_zone_ptr(biner_tree_enum_member_t) tail_member,
|
||||||
biner_zone_ptr(char) name) {
|
biner_zone_ptr(char) name) {
|
||||||
@ -424,7 +478,7 @@ static inline biner_zone_ptr(biner_tree_expr_t) create_operator_(
|
|||||||
biner_zone_ptr(biner_tree_expr_t) expr = alloc_(biner_tree_expr_t);
|
biner_zone_ptr(biner_tree_expr_t) expr = alloc_(biner_tree_expr_t);
|
||||||
*ref(biner_tree_expr_t, expr) = (biner_tree_expr_t) {
|
*ref(biner_tree_expr_t, expr) = (biner_tree_expr_t) {
|
||||||
.type = type,
|
.type = type,
|
||||||
.dynamic = lexpr->dynamic || rexpr->dynamic,
|
.dynamic = (l && lexpr->dynamic) || (r && rexpr->dynamic),
|
||||||
.operands = {l, r},
|
.operands = {l, r},
|
||||||
};
|
};
|
||||||
return expr;
|
return expr;
|
||||||
|
7
main.c
7
main.c
@ -39,7 +39,12 @@ static inline void print_struct_(
|
|||||||
printf("%8s ",
|
printf("%8s ",
|
||||||
biner_tree_struct_member_type_name_string_map[type->name]);
|
biner_tree_struct_member_type_name_string_map[type->name]);
|
||||||
}
|
}
|
||||||
printf("%s\n", zone + member->name);
|
if (member->condition == 0) {
|
||||||
|
printf("%s", zone + member->name);
|
||||||
|
} else {
|
||||||
|
printf("(%s)", zone + member->name);
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
member = (const biner_tree_struct_member_t*) (zone + member->prev);
|
member = (const biner_tree_struct_member_t*) (zone + member->prev);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
9
tree.h
9
tree.h
@ -19,6 +19,13 @@ typedef struct biner_tree_decl_t biner_tree_decl_t;
|
|||||||
typedef enum biner_tree_expr_type_t {
|
typedef enum biner_tree_expr_type_t {
|
||||||
BINER_TREE_EXPR_TYPE_OPERAND_INTEGER,
|
BINER_TREE_EXPR_TYPE_OPERAND_INTEGER,
|
||||||
BINER_TREE_EXPR_TYPE_OPERAND_REFERENCE,
|
BINER_TREE_EXPR_TYPE_OPERAND_REFERENCE,
|
||||||
|
BINER_TREE_EXPR_TYPE_OPERATOR_EQUAL,
|
||||||
|
BINER_TREE_EXPR_TYPE_OPERATOR_NEQUAL,
|
||||||
|
BINER_TREE_EXPR_TYPE_OPERATOR_GREATER_EQUAL,
|
||||||
|
BINER_TREE_EXPR_TYPE_OPERATOR_LESS_EQUAL,
|
||||||
|
BINER_TREE_EXPR_TYPE_OPERATOR_GREATER,
|
||||||
|
BINER_TREE_EXPR_TYPE_OPERATOR_LESS,
|
||||||
|
BINER_TREE_EXPR_TYPE_OPERATOR_NOT,
|
||||||
BINER_TREE_EXPR_TYPE_OPERATOR_ADD,
|
BINER_TREE_EXPR_TYPE_OPERATOR_ADD,
|
||||||
BINER_TREE_EXPR_TYPE_OPERATOR_SUB,
|
BINER_TREE_EXPR_TYPE_OPERATOR_SUB,
|
||||||
BINER_TREE_EXPR_TYPE_OPERATOR_MUL,
|
BINER_TREE_EXPR_TYPE_OPERATOR_MUL,
|
||||||
@ -79,7 +86,7 @@ typedef struct biner_tree_struct_member_type_t {
|
|||||||
typedef struct biner_tree_struct_member_t {
|
typedef struct biner_tree_struct_member_t {
|
||||||
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_struct_member_t) prev;
|
biner_zone_ptr(biner_tree_struct_member_t) prev;
|
||||||
} biner_tree_struct_member_t;
|
} biner_tree_struct_member_t;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user