forked from enlightenment/efl
eolian: fix type parsing
I reorganized what's allowed and what is not a bit, particularly, strictened the rules for named structs and loosened the rules for anonymous structs, and refined them for void types. It should be all correct now.
This commit is contained in:
parent
5bdbf4dbb5
commit
ae1ff34dd6
|
@ -214,8 +214,7 @@ _fill_type_name(Eolian_Type *tp, const char *type_name)
|
||||||
}
|
}
|
||||||
|
|
||||||
static Eolian_Type *parse_type_void(Eo_Lexer *ls);
|
static Eolian_Type *parse_type_void(Eo_Lexer *ls);
|
||||||
static Eolian_Type *parse_type_struct(Eo_Lexer *ls, Eina_Bool allow_struct,
|
static Eolian_Type *parse_type_struct_void(Eo_Lexer *ls, Eina_Bool allow_struct);
|
||||||
Eina_Bool allow_anon);
|
|
||||||
|
|
||||||
static Eolian_Type *
|
static Eolian_Type *
|
||||||
parse_type(Eo_Lexer *ls)
|
parse_type(Eo_Lexer *ls)
|
||||||
|
@ -233,12 +232,11 @@ parse_type(Eo_Lexer *ls)
|
||||||
}
|
}
|
||||||
|
|
||||||
static Eolian_Type *
|
static Eolian_Type *
|
||||||
parse_type_struct_nonvoid(Eo_Lexer *ls, Eina_Bool allow_struct,
|
parse_type_struct(Eo_Lexer *ls, Eina_Bool allow_struct)
|
||||||
Eina_Bool allow_anon)
|
|
||||||
{
|
{
|
||||||
Eolian_Type *ret;
|
Eolian_Type *ret;
|
||||||
eo_lexer_context_push(ls);
|
eo_lexer_context_push(ls);
|
||||||
ret = parse_type_struct(ls, allow_struct, allow_anon);
|
ret = parse_type_struct_void(ls, allow_struct);
|
||||||
if (ret->type == EOLIAN_TYPE_VOID)
|
if (ret->type == EOLIAN_TYPE_VOID)
|
||||||
{
|
{
|
||||||
eo_lexer_context_restore(ls);
|
eo_lexer_context_restore(ls);
|
||||||
|
@ -314,7 +312,7 @@ parse_struct(Eo_Lexer *ls, const char *name, Eina_Bool is_extern,
|
||||||
fname = eina_stringshare_ref(ls->t.value);
|
fname = eina_stringshare_ref(ls->t.value);
|
||||||
eo_lexer_get(ls);
|
eo_lexer_get(ls);
|
||||||
check_next(ls, ':');
|
check_next(ls, ':');
|
||||||
tp = parse_type_struct_nonvoid(ls, EINA_TRUE, EINA_FALSE);
|
tp = parse_type(ls);
|
||||||
fdef = calloc(1, sizeof(Eolian_Struct_Field));
|
fdef = calloc(1, sizeof(Eolian_Struct_Field));
|
||||||
fdef->type = tp;
|
fdef->type = tp;
|
||||||
eina_hash_add(def->fields, fname, fdef);
|
eina_hash_add(def->fields, fname, fdef);
|
||||||
|
@ -335,7 +333,7 @@ parse_struct(Eo_Lexer *ls, const char *name, Eina_Bool is_extern,
|
||||||
}
|
}
|
||||||
|
|
||||||
static Eolian_Type *
|
static Eolian_Type *
|
||||||
parse_type_struct(Eo_Lexer *ls, Eina_Bool allow_struct, Eina_Bool allow_anon)
|
parse_type_struct_void(Eo_Lexer *ls, Eina_Bool allow_struct)
|
||||||
{
|
{
|
||||||
Eolian_Type *def;
|
Eolian_Type *def;
|
||||||
const char *ctype;
|
const char *ctype;
|
||||||
|
@ -375,56 +373,52 @@ parse_type_struct(Eo_Lexer *ls, Eina_Bool allow_struct, Eina_Bool allow_anon)
|
||||||
goto parse_ptr;
|
goto parse_ptr;
|
||||||
}
|
}
|
||||||
case KW_struct:
|
case KW_struct:
|
||||||
eo_lexer_get(ls);
|
{
|
||||||
if (allow_struct)
|
Eina_Bool is_extern = EINA_FALSE;
|
||||||
{
|
int line, col;
|
||||||
Eina_Bool is_extern = EINA_FALSE;
|
eo_lexer_get(ls);
|
||||||
int line, col;
|
if (ls->t.kw == KW_at_extern)
|
||||||
if (ls->t.kw == KW_at_extern)
|
{
|
||||||
{
|
if (!allow_struct)
|
||||||
is_extern = EINA_TRUE;
|
eo_lexer_syntax_error(ls, "only named structs can be extern");
|
||||||
eo_lexer_get(ls);
|
is_extern = EINA_TRUE;
|
||||||
}
|
eo_lexer_get(ls);
|
||||||
if (allow_anon && ls->t.token == '{')
|
}
|
||||||
{
|
if (ls->t.token == '{')
|
||||||
if (is_extern)
|
{
|
||||||
eo_lexer_syntax_error(ls, "extern anonymous struct");
|
if (is_extern)
|
||||||
return parse_struct(ls, NULL, EINA_FALSE, 0, 0);
|
eo_lexer_syntax_error(ls, "extern anonymous struct");
|
||||||
}
|
return parse_struct(ls, NULL, EINA_FALSE, 0, 0);
|
||||||
/* todo: see typedef */
|
}
|
||||||
buf = push_strbuf(ls);
|
buf = push_strbuf(ls);
|
||||||
eo_lexer_context_push(ls);
|
eo_lexer_context_push(ls);
|
||||||
line = ls->line_number;
|
line = ls->line_number;
|
||||||
col = ls->column;
|
col = ls->column;
|
||||||
parse_name(ls, buf);
|
parse_name(ls, buf);
|
||||||
sname = eina_stringshare_add(eina_strbuf_string_get(buf));
|
sname = eina_stringshare_add(eina_strbuf_string_get(buf));
|
||||||
pop_strbuf(ls);
|
pop_strbuf(ls);
|
||||||
if (ls->t.token == '{')
|
/* if we're extern and allow structs, gotta enforce it */
|
||||||
{
|
if (allow_struct && is_extern)
|
||||||
Eolian_Type *tp = (Eolian_Type*)eina_hash_find(_structs,
|
check(ls, '{');
|
||||||
sname);
|
if (allow_struct && ls->t.token == '{')
|
||||||
if (tp)
|
{
|
||||||
{
|
Eolian_Type *tp = (Eolian_Type*)eina_hash_find(_structs,
|
||||||
eina_stringshare_del(sname);
|
sname);
|
||||||
eo_lexer_context_restore(ls);
|
if (tp)
|
||||||
redef_error(ls, EOLIAN_TYPE_STRUCT, tp);
|
{
|
||||||
}
|
eina_stringshare_del(sname);
|
||||||
eo_lexer_context_pop(ls);
|
eo_lexer_context_restore(ls);
|
||||||
return parse_struct(ls, sname, is_extern, line, col);
|
redef_error(ls, EOLIAN_TYPE_STRUCT, tp);
|
||||||
}
|
}
|
||||||
eo_lexer_context_pop(ls);
|
eo_lexer_context_pop(ls);
|
||||||
}
|
return parse_struct(ls, sname, is_extern, line, col);
|
||||||
else
|
}
|
||||||
{
|
eo_lexer_context_pop(ls);
|
||||||
buf = push_strbuf(ls);
|
def = push_type(ls);
|
||||||
parse_name(ls, buf);
|
def->type = EOLIAN_TYPE_REGULAR_STRUCT;
|
||||||
sname = eina_stringshare_add(eina_strbuf_string_get(buf));
|
_fill_type_name(def, sname);
|
||||||
pop_strbuf(ls);
|
goto parse_ptr;
|
||||||
}
|
}
|
||||||
def = push_type(ls);
|
|
||||||
def->type = EOLIAN_TYPE_REGULAR_STRUCT;
|
|
||||||
_fill_type_name(def, sname);
|
|
||||||
goto parse_ptr;
|
|
||||||
case KW_func:
|
case KW_func:
|
||||||
return parse_function_type(ls);
|
return parse_function_type(ls);
|
||||||
default:
|
default:
|
||||||
|
@ -485,7 +479,7 @@ parse_ptr:
|
||||||
static Eolian_Type *
|
static Eolian_Type *
|
||||||
parse_type_void(Eo_Lexer *ls)
|
parse_type_void(Eo_Lexer *ls)
|
||||||
{
|
{
|
||||||
return parse_type_struct(ls, EINA_FALSE, EINA_FALSE);
|
return parse_type_struct_void(ls, EINA_FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Eolian_Type *
|
static Eolian_Type *
|
||||||
|
@ -518,7 +512,7 @@ parse_typedef(Eo_Lexer *ls)
|
||||||
eo_lexer_context_pop(ls);
|
eo_lexer_context_pop(ls);
|
||||||
def->file = get_filename(ls);
|
def->file = get_filename(ls);
|
||||||
(void)!!test_next(ls, ':');
|
(void)!!test_next(ls, ':');
|
||||||
def->base_type = parse_type_struct_nonvoid(ls, EINA_TRUE, EINA_TRUE);
|
def->base_type = parse_type_struct(ls, EINA_TRUE);
|
||||||
pop_type(ls);
|
pop_type(ls);
|
||||||
check_next(ls, ';');
|
check_next(ls, ';');
|
||||||
if (ls->t.token == TOK_COMMENT)
|
if (ls->t.token == TOK_COMMENT)
|
||||||
|
@ -586,7 +580,7 @@ parse_param(Eo_Lexer *ls, Eina_Bool allow_inout)
|
||||||
else
|
else
|
||||||
par->way = EOLIAN_IN_PARAM;
|
par->way = EOLIAN_IN_PARAM;
|
||||||
}
|
}
|
||||||
if (par->way == EOLIAN_OUT_PARAM)
|
if (par->way == EOLIAN_OUT_PARAM || par->way == EOLIAN_INOUT_PARAM)
|
||||||
par->type = parse_type_void(ls);
|
par->type = parse_type_void(ls);
|
||||||
else
|
else
|
||||||
par->type = parse_type(ls);
|
par->type = parse_type(ls);
|
||||||
|
|
Loading…
Reference in New Issue