2014-06-18 03:25:07 -07:00
|
|
|
#include "eo_parser.h"
|
|
|
|
|
2014-06-20 07:07:25 -07:00
|
|
|
#define CASE_LOCK(ls, var, msg) \
|
|
|
|
if (has_##var) \
|
2014-07-01 10:25:17 -07:00
|
|
|
eo_lexer_syntax_error(ls, "double " msg); \
|
2014-06-20 07:07:25 -07:00
|
|
|
has_##var = EINA_TRUE;
|
|
|
|
|
2014-06-20 07:46:00 -07:00
|
|
|
#define PARSE_SECTION \
|
2014-07-02 16:00:02 -07:00
|
|
|
int line, col; \
|
2014-06-20 07:46:00 -07:00
|
|
|
eo_lexer_get(ls); \
|
|
|
|
line = ls->line_number; \
|
2014-07-02 16:00:02 -07:00
|
|
|
col = ls->column; \
|
2014-06-20 07:46:00 -07:00
|
|
|
check_next(ls, '{'); \
|
|
|
|
while (ls->t.token != '}')
|
|
|
|
|
2014-06-18 03:25:07 -07:00
|
|
|
static void
|
|
|
|
error_expected(Eo_Lexer *ls, int token)
|
|
|
|
{
|
|
|
|
char buf[256];
|
|
|
|
char tbuf[256];
|
|
|
|
eo_lexer_token_to_str(token, tbuf);
|
|
|
|
snprintf(buf, sizeof(buf), "'%s' expected", tbuf);
|
|
|
|
eo_lexer_syntax_error(ls, buf);
|
|
|
|
}
|
|
|
|
|
|
|
|
static Eina_Bool
|
|
|
|
test_next(Eo_Lexer *ls, int token)
|
|
|
|
{
|
|
|
|
if (ls->t.token == token)
|
|
|
|
{
|
|
|
|
eo_lexer_get(ls);
|
|
|
|
return EINA_TRUE;
|
|
|
|
}
|
|
|
|
return EINA_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
check(Eo_Lexer *ls, int token)
|
|
|
|
{
|
|
|
|
if (ls->t.token != token)
|
2014-07-01 10:25:17 -07:00
|
|
|
error_expected(ls, token);
|
2014-06-18 03:25:07 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
check_kw(Eo_Lexer *ls, int kw)
|
|
|
|
{
|
|
|
|
if (ls->t.kw != kw)
|
2014-07-01 10:25:17 -07:00
|
|
|
error_expected(ls, TOK_VALUE + kw);
|
2014-06-18 03:25:07 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
check_next(Eo_Lexer *ls, int token)
|
|
|
|
{
|
|
|
|
check(ls, token);
|
|
|
|
eo_lexer_get(ls);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
check_kw_next(Eo_Lexer *ls, int kw)
|
|
|
|
{
|
|
|
|
check_kw(ls, kw);
|
|
|
|
eo_lexer_get(ls);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2014-07-02 16:00:02 -07:00
|
|
|
check_match(Eo_Lexer *ls, int what, int who, int where, int col)
|
2014-06-18 03:25:07 -07:00
|
|
|
{
|
|
|
|
if (!test_next(ls, what))
|
|
|
|
{
|
|
|
|
if (where == ls->line_number)
|
2014-07-01 10:25:17 -07:00
|
|
|
error_expected(ls, what);
|
2014-06-18 03:25:07 -07:00
|
|
|
else
|
|
|
|
{
|
|
|
|
char buf[256];
|
|
|
|
char tbuf[256];
|
|
|
|
char vbuf[256];
|
|
|
|
eo_lexer_token_to_str(what, tbuf);
|
|
|
|
eo_lexer_token_to_str(who , vbuf);
|
|
|
|
snprintf(buf, sizeof(buf),
|
2014-07-22 07:01:09 -07:00
|
|
|
"'%s' expected (to close '%s' at line %d, column %d)",
|
2014-07-02 16:00:02 -07:00
|
|
|
tbuf, vbuf, where, col);
|
2014-06-18 03:25:07 -07:00
|
|
|
eo_lexer_syntax_error(ls, buf);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static Eina_Strbuf *
|
|
|
|
push_strbuf(Eo_Lexer *ls)
|
|
|
|
{
|
|
|
|
Eina_Strbuf *buf = eina_strbuf_new();
|
|
|
|
ls->tmp.str_bufs = eina_list_prepend(ls->tmp.str_bufs, buf);
|
|
|
|
return buf;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
pop_strbuf(Eo_Lexer *ls)
|
|
|
|
{
|
|
|
|
Eina_Strbuf *buf = eina_list_data_get(ls->tmp.str_bufs);
|
|
|
|
eina_strbuf_free(buf);
|
|
|
|
ls->tmp.str_bufs = eina_list_remove_list(ls->tmp.str_bufs, ls->tmp.str_bufs);
|
|
|
|
}
|
|
|
|
|
2014-07-10 06:44:17 -07:00
|
|
|
static Eolian_Type *
|
2014-07-09 03:18:21 -07:00
|
|
|
push_type(Eo_Lexer *ls)
|
|
|
|
{
|
2014-07-10 06:44:17 -07:00
|
|
|
Eolian_Type *def = calloc(1, sizeof(Eolian_Type));
|
2014-07-09 03:18:21 -07:00
|
|
|
ls->tmp.type_defs = eina_list_prepend(ls->tmp.type_defs, def);
|
|
|
|
return def;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
pop_type(Eo_Lexer *ls)
|
|
|
|
{
|
|
|
|
ls->tmp.type_defs = eina_list_remove_list(ls->tmp.type_defs, ls->tmp.type_defs);
|
|
|
|
}
|
|
|
|
|
2014-08-19 08:37:29 -07:00
|
|
|
static Eina_Stringshare *
|
|
|
|
push_str(Eo_Lexer *ls, const char *val)
|
|
|
|
{
|
|
|
|
Eina_Stringshare *shr = eina_stringshare_add(val);
|
|
|
|
ls->tmp.strs = eina_list_prepend(ls->tmp.strs, shr);
|
|
|
|
return shr;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
pop_str(Eo_Lexer *ls)
|
|
|
|
{
|
|
|
|
ls->tmp.strs = eina_list_remove_list(ls->tmp.strs, ls->tmp.strs);
|
|
|
|
}
|
|
|
|
|
2014-08-01 05:59:46 -07:00
|
|
|
static Eina_Bool
|
|
|
|
compare_class_file(const char *fn_ext, const char *fn_noext)
|
|
|
|
{
|
|
|
|
int fnlen = strlen(fn_ext);
|
|
|
|
int cnlen = strlen(fn_noext);
|
|
|
|
if (cnlen != (fnlen - 3))
|
|
|
|
return EINA_FALSE;
|
|
|
|
return !strncmp(fn_noext, fn_ext, cnlen);
|
|
|
|
}
|
|
|
|
|
2014-07-22 07:01:09 -07:00
|
|
|
static void
|
|
|
|
redef_error(Eo_Lexer *ls, Eolian_Type_Type type, Eolian_Type *old)
|
|
|
|
{
|
|
|
|
char buf[256];
|
|
|
|
char fbuf[256] = { '\0' };
|
2014-08-08 07:19:52 -07:00
|
|
|
const char *file = eina_stringshare_ref(ls->filename);
|
|
|
|
if (file != old->base.file)
|
|
|
|
snprintf(fbuf, sizeof(fbuf), " in file '%s'", old->base.file);
|
2014-07-22 07:01:09 -07:00
|
|
|
eina_stringshare_del(file);
|
|
|
|
snprintf(buf, sizeof(buf),
|
|
|
|
"%s '%s' redefined (originally at line %d, column %d%s)",
|
2014-08-11 06:56:50 -07:00
|
|
|
(type == EOLIAN_TYPE_ENUM) ? "enum" : ((type == EOLIAN_TYPE_STRUCT)
|
|
|
|
? "struct" : "type alias"),
|
2014-08-04 07:01:16 -07:00
|
|
|
old->full_name, old->base.line, old->base.column, fbuf);
|
2014-07-22 07:01:09 -07:00
|
|
|
eo_lexer_syntax_error(ls, buf);
|
|
|
|
}
|
|
|
|
|
2014-06-18 03:25:07 -07:00
|
|
|
static Eina_Strbuf *
|
|
|
|
parse_name(Eo_Lexer *ls, Eina_Strbuf *buf)
|
|
|
|
{
|
|
|
|
check(ls, TOK_VALUE);
|
2014-07-21 07:11:19 -07:00
|
|
|
if (eo_lexer_get_c_type(ls->t.kw))
|
|
|
|
eo_lexer_syntax_error(ls, "invalid name");
|
2014-06-18 03:25:07 -07:00
|
|
|
eina_strbuf_reset(buf);
|
|
|
|
for (;;)
|
|
|
|
{
|
2014-07-17 09:16:31 -07:00
|
|
|
eina_strbuf_append(buf, ls->t.value.s);
|
2014-06-18 03:25:07 -07:00
|
|
|
eo_lexer_get(ls);
|
2014-06-20 02:45:55 -07:00
|
|
|
if (ls->t.token != '.') break;
|
2014-06-18 03:25:07 -07:00
|
|
|
eo_lexer_get(ls);
|
2014-06-20 02:45:55 -07:00
|
|
|
eina_strbuf_append(buf, ".");
|
2014-06-18 03:25:07 -07:00
|
|
|
check(ls, TOK_VALUE);
|
2014-07-21 07:11:19 -07:00
|
|
|
if (eo_lexer_get_c_type(ls->t.kw))
|
|
|
|
eo_lexer_syntax_error(ls, "invalid name");
|
2014-06-18 03:25:07 -07:00
|
|
|
}
|
|
|
|
return buf;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Eina_List *
|
|
|
|
parse_name_list(Eo_Lexer *ls)
|
|
|
|
{
|
|
|
|
Eina_Strbuf *buf = push_strbuf(ls);
|
|
|
|
ls->tmp.str_items = NULL;
|
|
|
|
parse_name(ls, buf);
|
|
|
|
ls->tmp.str_items = eina_list_append(ls->tmp.str_items,
|
|
|
|
eina_stringshare_add(eina_strbuf_string_get(buf)));
|
|
|
|
while (test_next(ls, ','))
|
|
|
|
{
|
|
|
|
parse_name(ls, buf);
|
|
|
|
ls->tmp.str_items = eina_list_append(ls->tmp.str_items,
|
|
|
|
eina_stringshare_add(eina_strbuf_string_get(buf)));
|
|
|
|
}
|
|
|
|
pop_strbuf(ls);
|
|
|
|
return ls->tmp.str_items;
|
|
|
|
}
|
|
|
|
|
2014-08-08 07:57:39 -07:00
|
|
|
#define NAMESPACE_PARSE(def, dname) \
|
|
|
|
char *full_name = strdup(dname); \
|
|
|
|
char *name = full_name, *dot = full_name; \
|
|
|
|
def->full_name = dname; \
|
|
|
|
do \
|
|
|
|
{ \
|
|
|
|
dot = strchr(dot, '.'); \
|
|
|
|
if (dot) \
|
|
|
|
{ \
|
|
|
|
*dot = '\0'; \
|
|
|
|
def->namespaces = eina_list_append(def->namespaces, \
|
|
|
|
eina_stringshare_add(name)); \
|
|
|
|
++dot; \
|
|
|
|
name = dot; \
|
|
|
|
} \
|
|
|
|
} \
|
|
|
|
while (dot); \
|
|
|
|
def->name = eina_stringshare_add(name); \
|
|
|
|
free(full_name);
|
|
|
|
|
2014-07-21 07:11:19 -07:00
|
|
|
static void
|
|
|
|
_fill_type_name(Eolian_Type *tp, const char *type_name)
|
|
|
|
{
|
2014-08-08 07:57:39 -07:00
|
|
|
NAMESPACE_PARSE(tp, type_name)
|
2014-07-21 07:11:19 -07:00
|
|
|
}
|
|
|
|
|
2014-08-08 07:57:39 -07:00
|
|
|
static void
|
|
|
|
_fill_variable_name(Eolian_Variable *var, const char *var_name)
|
|
|
|
{
|
|
|
|
NAMESPACE_PARSE(var, var_name)
|
|
|
|
}
|
|
|
|
|
2014-09-11 02:50:48 -07:00
|
|
|
static void
|
|
|
|
_fill_class_name(Eolian_Class *cl, const char *cl_name)
|
|
|
|
{
|
|
|
|
NAMESPACE_PARSE(cl, cl_name)
|
|
|
|
}
|
|
|
|
|
2014-08-08 07:57:39 -07:00
|
|
|
#undef NAMESPACE_PARSE
|
|
|
|
|
2014-07-17 09:16:31 -07:00
|
|
|
static Eolian_Expression *
|
|
|
|
push_expr(Eo_Lexer *ls)
|
|
|
|
{
|
|
|
|
Eolian_Expression *def = calloc(1, sizeof(Eolian_Expression));
|
|
|
|
ls->tmp.expr_defs = eina_list_prepend(ls->tmp.expr_defs, def);
|
|
|
|
return def;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
pop_expr(Eo_Lexer *ls)
|
|
|
|
{
|
|
|
|
ls->tmp.expr_defs = eina_list_remove_list(ls->tmp.expr_defs, ls->tmp.expr_defs);
|
|
|
|
}
|
|
|
|
|
|
|
|
static Eolian_Binary_Operator
|
|
|
|
get_binop_id(int tok)
|
|
|
|
{
|
|
|
|
switch (tok)
|
|
|
|
{
|
2014-07-18 02:47:07 -07:00
|
|
|
case '+': return EOLIAN_BINOP_ADD;
|
|
|
|
case '-': return EOLIAN_BINOP_SUB;
|
|
|
|
case '*': return EOLIAN_BINOP_MUL;
|
|
|
|
case '/': return EOLIAN_BINOP_DIV;
|
|
|
|
case '%': return EOLIAN_BINOP_MOD;
|
2014-07-17 09:16:31 -07:00
|
|
|
|
2014-07-18 02:47:07 -07:00
|
|
|
case TOK_EQ: return EOLIAN_BINOP_EQ;
|
|
|
|
case TOK_NQ: return EOLIAN_BINOP_NQ;
|
2014-07-18 03:48:40 -07:00
|
|
|
case '>' : return EOLIAN_BINOP_GT;
|
|
|
|
case '<' : return EOLIAN_BINOP_LT;
|
2014-07-18 02:47:07 -07:00
|
|
|
case TOK_GE: return EOLIAN_BINOP_GE;
|
|
|
|
case TOK_LE: return EOLIAN_BINOP_LE;
|
2014-07-17 09:16:31 -07:00
|
|
|
|
2014-07-18 02:47:07 -07:00
|
|
|
case TOK_AND: return EOLIAN_BINOP_AND;
|
|
|
|
case TOK_OR : return EOLIAN_BINOP_OR;
|
2014-07-17 09:16:31 -07:00
|
|
|
|
2014-07-18 02:47:07 -07:00
|
|
|
case '&': return EOLIAN_BINOP_BAND;
|
|
|
|
case '|': return EOLIAN_BINOP_BOR;
|
|
|
|
case '^': return EOLIAN_BINOP_BXOR;
|
2014-07-17 09:16:31 -07:00
|
|
|
|
2014-07-18 02:47:07 -07:00
|
|
|
case TOK_LSH: return EOLIAN_BINOP_LSH;
|
|
|
|
case TOK_RSH: return EOLIAN_BINOP_RSH;
|
2014-07-17 09:16:31 -07:00
|
|
|
|
|
|
|
default: return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static Eolian_Unary_Operator
|
|
|
|
get_unop_id(int tok)
|
|
|
|
{
|
|
|
|
switch (tok)
|
|
|
|
{
|
2014-07-18 02:47:07 -07:00
|
|
|
case '-': return EOLIAN_UNOP_UNM;
|
|
|
|
case '+': return EOLIAN_UNOP_UNP;
|
|
|
|
case '!': return EOLIAN_UNOP_NOT;
|
|
|
|
case '~': return EOLIAN_UNOP_BNOT;
|
2014-07-17 09:16:31 -07:00
|
|
|
|
|
|
|
default: return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static const int binprec[] = {
|
|
|
|
8, /* + */
|
|
|
|
8, /* - */
|
|
|
|
9, /* * */
|
|
|
|
9, /* / */
|
|
|
|
9, /* % */
|
|
|
|
|
|
|
|
3, /* == */
|
|
|
|
3, /* != */
|
|
|
|
3, /* > */
|
|
|
|
3, /* < */
|
|
|
|
3, /* >= */
|
|
|
|
3, /* <= */
|
|
|
|
|
|
|
|
2, /* && */
|
|
|
|
1, /* || */
|
|
|
|
|
|
|
|
6, /* & */
|
|
|
|
4, /* | */
|
|
|
|
5, /* ^ */
|
|
|
|
7, /* << */
|
|
|
|
7 /* >> */
|
|
|
|
};
|
|
|
|
|
|
|
|
#define UNARY_PRECEDENCE 10
|
|
|
|
|
|
|
|
static int
|
|
|
|
get_binop_prec(Eolian_Binary_Operator id)
|
|
|
|
{
|
|
|
|
if (id < 0) return -1;
|
|
|
|
return binprec[id];
|
|
|
|
}
|
|
|
|
|
|
|
|
static Eolian_Expression *parse_expr_bin(Eo_Lexer *ls, int min_prec);
|
|
|
|
static Eolian_Expression *parse_expr(Eo_Lexer *ls);
|
|
|
|
|
|
|
|
static Eolian_Expression *
|
|
|
|
parse_expr_simple(Eo_Lexer *ls)
|
|
|
|
{
|
|
|
|
Eolian_Expression *expr;
|
|
|
|
Eolian_Unary_Operator unop = get_unop_id(ls->t.token);
|
|
|
|
if (unop >= 0)
|
|
|
|
{
|
2014-08-06 08:30:42 -07:00
|
|
|
int line = ls->line_number, col = ls->column;
|
2014-07-17 09:16:31 -07:00
|
|
|
Eolian_Expression *exp = parse_expr_bin(ls, UNARY_PRECEDENCE);
|
|
|
|
pop_expr(ls);
|
|
|
|
expr = push_expr(ls);
|
2014-08-08 07:19:52 -07:00
|
|
|
expr->base.file = eina_stringshare_ref(ls->filename);
|
2014-08-06 08:30:42 -07:00
|
|
|
expr->base.line = line;
|
|
|
|
expr->base.column = col;
|
2014-08-22 00:20:53 -07:00
|
|
|
expr->unop = unop;
|
2014-07-17 09:16:31 -07:00
|
|
|
expr->type = EOLIAN_EXPR_UNARY;
|
|
|
|
expr->expr = exp;
|
|
|
|
return expr;
|
|
|
|
}
|
|
|
|
switch (ls->t.token)
|
|
|
|
{
|
|
|
|
case TOK_NUMBER:
|
|
|
|
{
|
2014-08-06 08:30:42 -07:00
|
|
|
int line = ls->line_number, col = ls->column;
|
2014-07-17 09:16:31 -07:00
|
|
|
expr = push_expr(ls);
|
2014-08-08 07:19:52 -07:00
|
|
|
expr->base.file = eina_stringshare_ref(ls->filename);
|
2014-08-06 08:30:42 -07:00
|
|
|
expr->base.line = line;
|
|
|
|
expr->base.column = col;
|
2014-07-17 09:16:31 -07:00
|
|
|
expr->type = ls->t.kw + 1; /* map Numbers from lexer to expr type */
|
|
|
|
expr->value = ls->t.value;
|
|
|
|
eo_lexer_get(ls);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case TOK_STRING:
|
|
|
|
{
|
2014-08-06 08:30:42 -07:00
|
|
|
int line = ls->line_number, col = ls->column;
|
2014-07-17 09:16:31 -07:00
|
|
|
expr = push_expr(ls);
|
2014-08-08 07:19:52 -07:00
|
|
|
expr->base.file = eina_stringshare_ref(ls->filename);
|
2014-08-06 08:30:42 -07:00
|
|
|
expr->base.line = line;
|
|
|
|
expr->base.column = col;
|
2014-07-17 09:16:31 -07:00
|
|
|
expr->type = EOLIAN_EXPR_STRING;
|
|
|
|
expr->value.s = eina_stringshare_ref(ls->t.value.s);
|
|
|
|
eo_lexer_get(ls);
|
|
|
|
break;
|
|
|
|
}
|
2014-08-07 07:15:07 -07:00
|
|
|
case TOK_CHAR:
|
|
|
|
{
|
|
|
|
int line = ls->line_number, col = ls->column;
|
|
|
|
expr = push_expr(ls);
|
2014-08-08 07:19:52 -07:00
|
|
|
expr->base.file = eina_stringshare_ref(ls->filename);
|
2014-08-07 07:15:07 -07:00
|
|
|
expr->base.line = line;
|
|
|
|
expr->base.column = col;
|
|
|
|
expr->type = EOLIAN_EXPR_CHAR;
|
|
|
|
expr->value.c = ls->t.value.c;
|
|
|
|
eo_lexer_get(ls);
|
|
|
|
break;
|
|
|
|
}
|
2014-07-17 09:16:31 -07:00
|
|
|
case TOK_VALUE:
|
|
|
|
{
|
2014-08-06 08:30:42 -07:00
|
|
|
int line = ls->line_number, col = ls->column;
|
2014-07-17 09:16:31 -07:00
|
|
|
switch (ls->t.kw)
|
|
|
|
{
|
|
|
|
case KW_true:
|
|
|
|
case KW_false:
|
|
|
|
{
|
|
|
|
expr = push_expr(ls);
|
|
|
|
expr->type = EOLIAN_EXPR_BOOL;
|
|
|
|
expr->value.b = (ls->t.kw == KW_true);
|
2014-08-07 07:15:07 -07:00
|
|
|
eo_lexer_get(ls);
|
2014-07-17 09:16:31 -07:00
|
|
|
break;
|
2014-08-07 07:15:07 -07:00
|
|
|
}
|
|
|
|
case KW_null:
|
|
|
|
{
|
|
|
|
expr = push_expr(ls);
|
|
|
|
expr->type = EOLIAN_EXPR_NULL;
|
|
|
|
eo_lexer_get(ls);
|
|
|
|
break;
|
|
|
|
}
|
2014-08-12 06:25:53 -07:00
|
|
|
case KW_enum:
|
2014-07-17 09:16:31 -07:00
|
|
|
default:
|
|
|
|
{
|
2014-08-12 05:11:13 -07:00
|
|
|
Eina_Strbuf *buf = push_strbuf(ls);
|
2014-08-12 06:25:53 -07:00
|
|
|
Eolian_Expression_Type tp = EOLIAN_EXPR_NAME;
|
|
|
|
if (ls->t.kw == KW_enum)
|
|
|
|
{
|
|
|
|
eo_lexer_get(ls);
|
|
|
|
tp = EOLIAN_EXPR_ENUM;
|
|
|
|
}
|
2014-07-17 09:16:31 -07:00
|
|
|
expr = push_expr(ls);
|
2014-08-12 06:25:53 -07:00
|
|
|
expr->type = tp;
|
2014-08-12 05:11:13 -07:00
|
|
|
parse_name(ls, buf);
|
|
|
|
expr->value.s = eina_stringshare_add(eina_strbuf_string_get
|
|
|
|
(buf));
|
|
|
|
pop_strbuf(ls);
|
2014-07-17 09:16:31 -07:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2014-08-08 07:19:52 -07:00
|
|
|
expr->base.file = eina_stringshare_ref(ls->filename);
|
2014-08-06 08:30:42 -07:00
|
|
|
expr->base.line = line;
|
|
|
|
expr->base.column = col;
|
2014-08-07 07:15:07 -07:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case '(':
|
|
|
|
{
|
|
|
|
int line = ls->line_number, col = ls->column;
|
|
|
|
eo_lexer_get(ls);
|
|
|
|
expr = parse_expr(ls);
|
|
|
|
check_match(ls, ')', '(', line, col);
|
2014-08-26 19:32:17 -07:00
|
|
|
break;
|
2014-07-17 09:16:31 -07:00
|
|
|
}
|
2014-08-07 07:15:07 -07:00
|
|
|
default:
|
|
|
|
expr = NULL; /* shut up compiler */
|
|
|
|
eo_lexer_syntax_error(ls, "unexpected symbol");
|
|
|
|
break;
|
2014-07-17 09:16:31 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
return expr;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Eolian_Expression *
|
|
|
|
parse_expr_bin(Eo_Lexer *ls, int min_prec)
|
|
|
|
{
|
2014-08-06 08:30:42 -07:00
|
|
|
int line = ls->line_number, col = ls->column;
|
2014-07-17 09:16:31 -07:00
|
|
|
Eolian_Expression *lhs = parse_expr_simple(ls);
|
|
|
|
for (;;)
|
|
|
|
{
|
|
|
|
Eolian_Expression *rhs, *bin;
|
|
|
|
Eolian_Binary_Operator op = get_binop_id(ls->t.token);
|
|
|
|
int prec = get_binop_prec(op);
|
|
|
|
if ((op < 0) || (prec < 0) || (prec < min_prec))
|
|
|
|
break;
|
2014-08-12 08:29:02 -07:00
|
|
|
eo_lexer_get(ls);
|
2014-07-17 09:16:31 -07:00
|
|
|
rhs = parse_expr_bin(ls, prec + 1);
|
|
|
|
pop_expr(ls);
|
|
|
|
pop_expr(ls);
|
|
|
|
bin = push_expr(ls);
|
2014-08-08 07:19:52 -07:00
|
|
|
bin->base.file = eina_stringshare_ref(ls->filename);
|
2014-08-06 08:30:42 -07:00
|
|
|
bin->base.line = line;
|
|
|
|
bin->base.column = col;
|
2014-07-17 09:16:31 -07:00
|
|
|
bin->binop = op;
|
|
|
|
bin->type = EOLIAN_EXPR_BINARY;
|
|
|
|
bin->lhs = lhs;
|
|
|
|
bin->rhs = rhs;
|
|
|
|
lhs = bin;
|
|
|
|
}
|
|
|
|
return lhs;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Eolian_Expression *
|
|
|
|
parse_expr(Eo_Lexer *ls)
|
|
|
|
{
|
|
|
|
return parse_expr_bin(ls, 1);
|
|
|
|
}
|
|
|
|
|
2014-07-10 06:44:17 -07:00
|
|
|
static Eolian_Type *parse_type_void(Eo_Lexer *ls);
|
2014-08-11 06:56:50 -07:00
|
|
|
static Eolian_Type *parse_type_named_void(Eo_Lexer *ls, Eina_Bool allow_named);
|
2014-06-30 15:07:32 -07:00
|
|
|
|
2014-07-10 06:44:17 -07:00
|
|
|
static Eolian_Type *
|
2014-06-30 15:07:32 -07:00
|
|
|
parse_type(Eo_Lexer *ls)
|
|
|
|
{
|
2014-07-22 07:27:11 -07:00
|
|
|
Eolian_Type *ret;
|
|
|
|
eo_lexer_context_push(ls);
|
|
|
|
ret = parse_type_void(ls);
|
2014-06-30 15:07:32 -07:00
|
|
|
if (ret->type == EOLIAN_TYPE_VOID)
|
|
|
|
{
|
2014-07-22 07:27:11 -07:00
|
|
|
eo_lexer_context_restore(ls);
|
2014-06-30 15:07:32 -07:00
|
|
|
eo_lexer_syntax_error(ls, "non-void type expected");
|
|
|
|
}
|
2014-07-22 07:27:11 -07:00
|
|
|
eo_lexer_context_pop(ls);
|
2014-06-30 15:07:32 -07:00
|
|
|
return ret;
|
|
|
|
}
|
2014-06-30 13:52:57 -07:00
|
|
|
|
2014-07-10 06:44:17 -07:00
|
|
|
static Eolian_Type *
|
2014-08-11 06:56:50 -07:00
|
|
|
parse_type_named(Eo_Lexer *ls, Eina_Bool allow_named)
|
2014-07-08 07:44:42 -07:00
|
|
|
{
|
2014-07-22 07:27:11 -07:00
|
|
|
Eolian_Type *ret;
|
|
|
|
eo_lexer_context_push(ls);
|
2014-08-11 06:56:50 -07:00
|
|
|
ret = parse_type_named_void(ls, allow_named);
|
2014-07-08 07:44:42 -07:00
|
|
|
if (ret->type == EOLIAN_TYPE_VOID)
|
|
|
|
{
|
2014-07-22 07:27:11 -07:00
|
|
|
eo_lexer_context_restore(ls);
|
2014-07-08 07:44:42 -07:00
|
|
|
eo_lexer_syntax_error(ls, "non-void type expected");
|
|
|
|
}
|
2014-07-22 07:27:11 -07:00
|
|
|
eo_lexer_context_pop(ls);
|
2014-07-08 07:44:42 -07:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2014-07-10 06:44:17 -07:00
|
|
|
static Eolian_Type *
|
2014-06-30 13:52:57 -07:00
|
|
|
parse_function_type(Eo_Lexer *ls)
|
|
|
|
{
|
2014-07-02 16:00:02 -07:00
|
|
|
int line, col;
|
2014-07-10 06:44:17 -07:00
|
|
|
Eolian_Type *def = push_type(ls);
|
2014-08-22 05:18:17 -07:00
|
|
|
def->type = EOLIAN_TYPE_FUNCTION;
|
2014-08-08 07:19:52 -07:00
|
|
|
def->base.file = eina_stringshare_ref(ls->filename);
|
2014-08-04 07:01:16 -07:00
|
|
|
def->base.line = ls->line_number;
|
|
|
|
def->base.column = ls->column;
|
2014-06-30 13:52:57 -07:00
|
|
|
eo_lexer_get(ls);
|
2014-06-30 14:07:13 -07:00
|
|
|
if (ls->t.kw == KW_void)
|
2014-07-01 10:25:17 -07:00
|
|
|
eo_lexer_get(ls);
|
2014-06-30 14:07:13 -07:00
|
|
|
else
|
2014-07-09 03:18:21 -07:00
|
|
|
{
|
|
|
|
def->ret_type = parse_type_void(ls);
|
|
|
|
pop_type(ls);
|
|
|
|
}
|
2014-06-30 13:52:57 -07:00
|
|
|
line = ls->line_number;
|
2014-07-02 16:00:02 -07:00
|
|
|
col = ls->column;
|
2014-06-30 13:52:57 -07:00
|
|
|
check_next(ls, '(');
|
|
|
|
if (ls->t.token != ')')
|
|
|
|
{
|
|
|
|
def->arguments = eina_list_append(def->arguments, parse_type(ls));
|
2014-07-09 03:18:21 -07:00
|
|
|
pop_type(ls);
|
2014-06-30 13:52:57 -07:00
|
|
|
while (test_next(ls, ','))
|
2014-07-09 03:18:21 -07:00
|
|
|
{
|
|
|
|
def->arguments = eina_list_append(def->arguments, parse_type(ls));
|
|
|
|
pop_type(ls);
|
|
|
|
}
|
2014-06-30 13:52:57 -07:00
|
|
|
}
|
2014-07-02 16:00:02 -07:00
|
|
|
check_match(ls, ')', '(', line, col);
|
2014-06-30 13:52:57 -07:00
|
|
|
return def;
|
|
|
|
}
|
|
|
|
|
2014-07-10 06:44:17 -07:00
|
|
|
static void
|
2014-08-22 08:56:41 -07:00
|
|
|
_struct_field_free(Eolian_Struct_Type_Field *def)
|
2014-07-10 06:44:17 -07:00
|
|
|
{
|
2014-08-07 07:15:07 -07:00
|
|
|
if (def->base.file) eina_stringshare_del(def->base.file);
|
2014-08-22 08:56:41 -07:00
|
|
|
if (def->name) eina_stringshare_del(def->name);
|
2014-07-10 06:44:17 -07:00
|
|
|
database_type_del(def->type);
|
|
|
|
if (def->comment) eina_stringshare_del(def->comment);
|
2014-07-22 02:22:21 -07:00
|
|
|
free(def);
|
2014-07-10 06:44:17 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static Eolian_Type *
|
2014-07-22 06:48:08 -07:00
|
|
|
parse_struct(Eo_Lexer *ls, const char *name, Eina_Bool is_extern,
|
2014-08-19 07:55:31 -07:00
|
|
|
int line, int column, const char *freefunc)
|
2014-07-08 07:02:36 -07:00
|
|
|
{
|
2014-07-22 06:48:08 -07:00
|
|
|
int bline = ls->line_number, bcolumn = ls->column;
|
2014-07-10 06:44:17 -07:00
|
|
|
Eolian_Type *def = push_type(ls);
|
2014-07-15 07:33:22 -07:00
|
|
|
def->is_extern = is_extern;
|
2014-07-21 07:11:19 -07:00
|
|
|
if (name) _fill_type_name(def, name);
|
2014-07-08 08:17:44 -07:00
|
|
|
def->type = EOLIAN_TYPE_STRUCT;
|
2014-07-10 06:44:17 -07:00
|
|
|
def->fields = eina_hash_string_small_new(EINA_FREE_CB(_struct_field_free));
|
2014-08-19 07:55:31 -07:00
|
|
|
def->freefunc = freefunc;
|
2014-08-19 08:37:29 -07:00
|
|
|
pop_str(ls);
|
2014-07-08 07:44:42 -07:00
|
|
|
check_next(ls, '{');
|
2014-07-09 04:48:16 -07:00
|
|
|
if (ls->t.token == TOK_COMMENT)
|
|
|
|
{
|
2014-07-17 09:16:31 -07:00
|
|
|
def->comment = eina_stringshare_ref(ls->t.value.s);
|
2014-07-09 04:48:16 -07:00
|
|
|
eo_lexer_get(ls);
|
|
|
|
}
|
2014-07-08 07:44:42 -07:00
|
|
|
while (ls->t.token != '}')
|
|
|
|
{
|
2014-07-08 08:42:33 -07:00
|
|
|
const char *fname;
|
2014-08-22 08:56:41 -07:00
|
|
|
Eolian_Struct_Type_Field *fdef;
|
2014-07-10 06:44:17 -07:00
|
|
|
Eolian_Type *tp;
|
2014-08-04 07:01:16 -07:00
|
|
|
int fline = ls->line_number, fcol = ls->column;
|
2014-07-08 07:44:42 -07:00
|
|
|
check(ls, TOK_VALUE);
|
2014-07-17 09:16:31 -07:00
|
|
|
if (eina_hash_find(def->fields, ls->t.value.s))
|
2014-07-08 08:17:44 -07:00
|
|
|
eo_lexer_syntax_error(ls, "double field definition");
|
2014-08-22 08:56:41 -07:00
|
|
|
fdef = calloc(1, sizeof(Eolian_Struct_Type_Field));
|
2014-07-17 09:16:31 -07:00
|
|
|
fname = eina_stringshare_ref(ls->t.value.s);
|
2014-08-15 03:07:06 -07:00
|
|
|
eina_hash_add(def->fields, fname, fdef);
|
2014-08-22 08:56:41 -07:00
|
|
|
def->field_list = eina_list_append(def->field_list, fdef);
|
2014-07-08 07:44:42 -07:00
|
|
|
eo_lexer_get(ls);
|
|
|
|
check_next(ls, ':');
|
2014-07-25 06:51:13 -07:00
|
|
|
tp = parse_type(ls);
|
2014-08-08 07:19:52 -07:00
|
|
|
fdef->base.file = eina_stringshare_ref(ls->filename);
|
2014-08-04 07:01:16 -07:00
|
|
|
fdef->base.line = fline;
|
|
|
|
fdef->base.column = fcol;
|
2014-07-09 04:05:56 -07:00
|
|
|
fdef->type = tp;
|
2014-08-22 08:56:41 -07:00
|
|
|
fdef->name = eina_stringshare_ref(fname);
|
2014-07-09 03:18:21 -07:00
|
|
|
pop_type(ls);
|
2014-07-08 07:44:42 -07:00
|
|
|
check_next(ls, ';');
|
|
|
|
if (ls->t.token == TOK_COMMENT)
|
|
|
|
{
|
2014-07-17 09:16:31 -07:00
|
|
|
fdef->comment = eina_stringshare_ref(ls->t.value.s);
|
2014-07-08 07:44:42 -07:00
|
|
|
eo_lexer_get(ls);
|
|
|
|
}
|
|
|
|
}
|
2014-07-22 06:48:08 -07:00
|
|
|
check_match(ls, '}', '{', bline, bcolumn);
|
2014-08-08 07:19:52 -07:00
|
|
|
def->base.file = eina_stringshare_ref(ls->filename);
|
2014-08-04 07:01:16 -07:00
|
|
|
def->base.line = line;
|
|
|
|
def->base.column = column;
|
2014-07-21 03:42:05 -07:00
|
|
|
if (name) database_struct_add(def);
|
2014-07-08 07:44:42 -07:00
|
|
|
return def;
|
2014-07-08 07:02:36 -07:00
|
|
|
}
|
|
|
|
|
2014-08-11 06:56:50 -07:00
|
|
|
static void
|
2014-08-22 08:56:41 -07:00
|
|
|
_enum_field_free(Eolian_Enum_Type_Field *def)
|
2014-08-11 06:56:50 -07:00
|
|
|
{
|
|
|
|
if (def->base.file) eina_stringshare_del(def->base.file);
|
2014-08-22 08:56:41 -07:00
|
|
|
if (def->name) eina_stringshare_del(def->name);
|
2014-08-11 06:56:50 -07:00
|
|
|
database_expr_del(def->value);
|
|
|
|
if (def->comment) eina_stringshare_del(def->comment);
|
|
|
|
free(def);
|
|
|
|
}
|
|
|
|
|
2014-07-10 06:44:17 -07:00
|
|
|
static Eolian_Type *
|
2014-08-11 06:56:50 -07:00
|
|
|
parse_enum(Eo_Lexer *ls, const char *name, Eina_Bool is_extern,
|
|
|
|
int line, int column)
|
|
|
|
{
|
|
|
|
int bline = ls->line_number, bcolumn = ls->column;
|
|
|
|
Eolian_Type *def = push_type(ls);
|
|
|
|
def->is_extern = is_extern;
|
|
|
|
_fill_type_name(def, name);
|
|
|
|
def->type = EOLIAN_TYPE_ENUM;
|
|
|
|
def->fields = eina_hash_string_small_new(EINA_FREE_CB(_enum_field_free));
|
|
|
|
check_next(ls, '{');
|
|
|
|
if (ls->t.token == TOK_COMMENT)
|
|
|
|
{
|
|
|
|
def->comment = eina_stringshare_ref(ls->t.value.s);
|
|
|
|
eo_lexer_get(ls);
|
|
|
|
}
|
|
|
|
if (ls->t.token == TOK_VALUE && ls->t.kw == KW_legacy)
|
|
|
|
{
|
|
|
|
if (eo_lexer_lookahead(ls) == ':')
|
|
|
|
{
|
|
|
|
/* consume keyword */
|
|
|
|
eo_lexer_get(ls);
|
|
|
|
/* consume colon */
|
|
|
|
eo_lexer_get(ls);
|
|
|
|
check(ls, TOK_VALUE);
|
|
|
|
def->legacy = eina_stringshare_ref(ls->t.value.s);
|
|
|
|
eo_lexer_get(ls);
|
|
|
|
check_next(ls, ';');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Eolian_Expression *prev_exp = NULL;
|
|
|
|
for (;;)
|
|
|
|
{
|
|
|
|
const char *fname;
|
2014-08-22 08:56:41 -07:00
|
|
|
Eolian_Enum_Type_Field *fdef;
|
2014-08-11 06:56:50 -07:00
|
|
|
int fline = ls->line_number, fcol = ls->column;
|
|
|
|
check(ls, TOK_VALUE);
|
|
|
|
if (eina_hash_find(def->fields, ls->t.value.s))
|
|
|
|
eo_lexer_syntax_error(ls, "double field definition");
|
2014-08-22 08:56:41 -07:00
|
|
|
fdef = calloc(1, sizeof(Eolian_Enum_Type_Field));
|
2014-08-11 06:56:50 -07:00
|
|
|
fname = eina_stringshare_ref(ls->t.value.s);
|
2014-08-15 03:07:06 -07:00
|
|
|
eina_hash_add(def->fields, fname, fdef);
|
2014-08-22 08:56:41 -07:00
|
|
|
def->field_list = eina_list_append(def->field_list, fdef);
|
2014-08-11 06:56:50 -07:00
|
|
|
eo_lexer_get(ls);
|
|
|
|
fdef->base.file = eina_stringshare_ref(ls->filename);
|
|
|
|
fdef->base.line = fline;
|
|
|
|
fdef->base.column = fcol;
|
2014-08-22 08:56:41 -07:00
|
|
|
fdef->name = eina_stringshare_ref(fname);
|
2014-08-11 06:56:50 -07:00
|
|
|
if (ls->t.token != '=')
|
|
|
|
{
|
|
|
|
if (!prev_exp)
|
|
|
|
{
|
|
|
|
prev_exp = push_expr(ls);
|
|
|
|
prev_exp->base.file = eina_stringshare_ref(ls->filename);
|
|
|
|
prev_exp->base.line = -1;
|
|
|
|
prev_exp->base.column = -1;
|
|
|
|
prev_exp->type = EOLIAN_EXPR_INT;
|
|
|
|
prev_exp->value.i = 0;
|
|
|
|
fdef->value = prev_exp;
|
|
|
|
pop_expr(ls);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ls->expr_mode = EINA_TRUE;
|
|
|
|
eo_lexer_get(ls);
|
|
|
|
fdef->value = parse_expr(ls);
|
|
|
|
ls->expr_mode = EINA_FALSE;
|
|
|
|
if (!prev_exp)
|
|
|
|
prev_exp = fdef->value;
|
|
|
|
pop_expr(ls);
|
|
|
|
}
|
|
|
|
Eina_Bool want_next = (ls->t.token == ',');
|
|
|
|
if (want_next)
|
|
|
|
eo_lexer_get(ls);
|
|
|
|
if (ls->t.token == TOK_COMMENT)
|
|
|
|
{
|
|
|
|
fdef->comment = eina_stringshare_ref(ls->t.value.s);
|
|
|
|
eo_lexer_get(ls);
|
|
|
|
}
|
|
|
|
if (!want_next)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
check_match(ls, '}', '{', bline, bcolumn);
|
|
|
|
def->base.file = eina_stringshare_ref(ls->filename);
|
|
|
|
def->base.line = line;
|
|
|
|
def->base.column = column;
|
2014-08-12 06:25:53 -07:00
|
|
|
if (name) database_enum_add(def);
|
2014-08-11 06:56:50 -07:00
|
|
|
return def;
|
|
|
|
}
|
|
|
|
|
2014-08-19 07:55:31 -07:00
|
|
|
static void
|
|
|
|
parse_struct_attrs(Eo_Lexer *ls, Eina_Bool is_enum, Eina_Bool allow_named,
|
|
|
|
Eina_Bool *is_extern, const char **freefunc)
|
|
|
|
{
|
|
|
|
Eina_Bool has_extern = EINA_FALSE, has_free = EINA_FALSE;
|
|
|
|
*freefunc = NULL;
|
|
|
|
*is_extern = EINA_FALSE;
|
|
|
|
for (;;) switch (ls->t.kw)
|
|
|
|
{
|
|
|
|
case KW_at_extern:
|
|
|
|
CASE_LOCK(ls, extern, "@extern qualifier")
|
|
|
|
if (!allow_named)
|
|
|
|
{
|
|
|
|
if (is_enum)
|
|
|
|
eo_lexer_syntax_error(ls,
|
|
|
|
"only enum declarations can be extern");
|
|
|
|
else
|
|
|
|
eo_lexer_syntax_error(ls,
|
|
|
|
"only named structs can be extern");
|
|
|
|
}
|
|
|
|
eo_lexer_get(ls);
|
|
|
|
*is_extern = EINA_TRUE;
|
|
|
|
break;
|
|
|
|
case KW_at_free:
|
|
|
|
{
|
|
|
|
CASE_LOCK(ls, free, "@free qualifier")
|
|
|
|
if (is_enum)
|
|
|
|
eo_lexer_syntax_error(ls, "enums cannot have @free");
|
|
|
|
eo_lexer_get(ls);
|
|
|
|
int pline = ls->line_number, pcol = ls->column;
|
|
|
|
check_next(ls, '(');
|
|
|
|
check(ls, TOK_VALUE);
|
2014-08-19 08:37:29 -07:00
|
|
|
*freefunc = push_str(ls, ls->t.value.s);
|
2014-08-19 07:55:31 -07:00
|
|
|
eo_lexer_get(ls);
|
|
|
|
check_match(ls, ')', '(', pline, pcol);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-08-26 03:06:54 -07:00
|
|
|
static void
|
|
|
|
_append_dep(Eo_Lexer *ls, const char *fname, const char *name, int line, int col)
|
|
|
|
{
|
|
|
|
Eolian_Dependency *dep = calloc(1, sizeof(Eolian_Dependency));
|
|
|
|
dep->base.file = eina_stringshare_ref(ls->filename);
|
|
|
|
dep->base.line = line;
|
|
|
|
dep->base.column = col;
|
|
|
|
dep->filename = eina_stringshare_add(fname);
|
|
|
|
dep->name = eina_stringshare_add(name);
|
|
|
|
eina_hash_set(_depclasses, ls->filename, eina_list_append((Eina_List*)
|
|
|
|
eina_hash_find(_depclasses, ls->filename), dep));
|
|
|
|
}
|
|
|
|
|
2014-08-11 06:56:50 -07:00
|
|
|
static Eolian_Type *
|
|
|
|
parse_type_named_void(Eo_Lexer *ls, Eina_Bool allow_named)
|
2014-06-26 03:51:08 -07:00
|
|
|
{
|
2014-07-10 06:44:17 -07:00
|
|
|
Eolian_Type *def;
|
2014-07-14 04:11:48 -07:00
|
|
|
const char *ctype;
|
|
|
|
const char *sname = NULL;
|
2014-07-21 07:11:19 -07:00
|
|
|
Eina_Strbuf *buf;
|
2014-08-04 07:01:16 -07:00
|
|
|
int line = ls->line_number, col = ls->column;
|
2014-06-26 03:51:08 -07:00
|
|
|
switch (ls->t.kw)
|
|
|
|
{
|
2014-07-01 10:25:17 -07:00
|
|
|
case KW_const:
|
|
|
|
{
|
2014-08-21 01:25:19 -07:00
|
|
|
int pline, pcol;
|
2014-07-01 10:25:17 -07:00
|
|
|
eo_lexer_get(ls);
|
2014-08-21 01:25:19 -07:00
|
|
|
pline = ls->line_number;
|
|
|
|
pcol = ls->column;
|
2014-07-01 10:25:17 -07:00
|
|
|
check_next(ls, '(');
|
|
|
|
def = parse_type_void(ls);
|
2014-08-08 07:19:52 -07:00
|
|
|
def->base.file = eina_stringshare_ref(ls->filename);
|
2014-08-04 07:01:16 -07:00
|
|
|
def->base.line = line;
|
|
|
|
def->base.column = col;
|
2014-07-01 10:25:17 -07:00
|
|
|
def->is_const = EINA_TRUE;
|
2014-08-21 01:25:19 -07:00
|
|
|
check_match(ls, ')', '(', pline, pcol);
|
2014-07-01 10:25:17 -07:00
|
|
|
goto parse_ptr;
|
|
|
|
}
|
|
|
|
case KW_own:
|
|
|
|
{
|
2014-08-04 07:01:16 -07:00
|
|
|
int pline, pcolumn;
|
2014-07-01 10:25:17 -07:00
|
|
|
eo_lexer_get(ls);
|
2014-08-04 07:01:16 -07:00
|
|
|
pline = ls->line_number;
|
|
|
|
pcolumn = ls->column;
|
2014-07-01 10:25:17 -07:00
|
|
|
check_next(ls, '(');
|
2014-07-22 07:27:11 -07:00
|
|
|
eo_lexer_context_push(ls);
|
2014-07-01 10:25:17 -07:00
|
|
|
def = parse_type_void(ls);
|
|
|
|
if (def->type != EOLIAN_TYPE_POINTER)
|
|
|
|
{
|
2014-07-22 07:27:11 -07:00
|
|
|
eo_lexer_context_restore(ls);
|
2014-07-01 10:25:17 -07:00
|
|
|
eo_lexer_syntax_error(ls, "pointer type expected");
|
|
|
|
}
|
2014-07-22 07:27:11 -07:00
|
|
|
eo_lexer_context_pop(ls);
|
2014-08-08 07:19:52 -07:00
|
|
|
def->base.file = eina_stringshare_ref(ls->filename);
|
2014-08-04 07:01:16 -07:00
|
|
|
def->base.line = line;
|
|
|
|
def->base.column = col;
|
2014-07-01 10:25:17 -07:00
|
|
|
def->is_own = EINA_TRUE;
|
2014-08-04 07:01:16 -07:00
|
|
|
check_match(ls, ')', '(', pline, pcolumn);
|
2014-07-01 10:25:17 -07:00
|
|
|
goto parse_ptr;
|
|
|
|
}
|
2014-08-19 07:55:31 -07:00
|
|
|
case KW_free:
|
|
|
|
{
|
|
|
|
int pline, pcolumn;
|
|
|
|
eo_lexer_get(ls);
|
|
|
|
pline = ls->line_number;
|
|
|
|
pcolumn = ls->column;
|
|
|
|
check_next(ls, '(');
|
|
|
|
eo_lexer_context_push(ls);
|
|
|
|
def = parse_type_void(ls);
|
|
|
|
if (def->type != EOLIAN_TYPE_POINTER)
|
|
|
|
{
|
|
|
|
eo_lexer_context_restore(ls);
|
|
|
|
eo_lexer_syntax_error(ls, "pointer type expected");
|
|
|
|
}
|
|
|
|
eo_lexer_context_pop(ls);
|
|
|
|
check_next(ls, ',');
|
|
|
|
check(ls, TOK_VALUE);
|
|
|
|
def->freefunc = eina_stringshare_ref(ls->t.value.s);
|
|
|
|
eo_lexer_get(ls);
|
|
|
|
def->base.file = eina_stringshare_ref(ls->filename);
|
|
|
|
def->base.line = line;
|
|
|
|
def->base.column = col;
|
|
|
|
check_match(ls, ')', '(', pline, pcolumn);
|
|
|
|
goto parse_ptr;
|
|
|
|
}
|
2014-07-01 10:25:17 -07:00
|
|
|
case KW_struct:
|
2014-08-11 06:56:50 -07:00
|
|
|
case KW_enum:
|
2014-07-25 06:51:13 -07:00
|
|
|
{
|
2014-08-19 07:55:31 -07:00
|
|
|
const char *freefunc;
|
|
|
|
Eina_Bool has_extern;
|
2014-08-11 06:56:50 -07:00
|
|
|
Eina_Bool is_enum = (ls->t.kw == KW_enum);
|
2014-07-25 06:51:13 -07:00
|
|
|
eo_lexer_get(ls);
|
2014-08-19 07:55:31 -07:00
|
|
|
parse_struct_attrs(ls, is_enum, allow_named, &has_extern, &freefunc);
|
|
|
|
if (freefunc && !allow_named)
|
|
|
|
check(ls, '{');
|
2014-08-11 06:56:50 -07:00
|
|
|
if (!is_enum && (ls->t.token == '{'))
|
2014-07-25 06:51:13 -07:00
|
|
|
{
|
2014-08-19 07:55:31 -07:00
|
|
|
if (has_extern)
|
2014-07-25 06:51:13 -07:00
|
|
|
eo_lexer_syntax_error(ls, "extern anonymous struct");
|
2014-08-19 07:55:31 -07:00
|
|
|
return parse_struct(ls, NULL, EINA_FALSE, line, col, freefunc);
|
2014-07-25 06:51:13 -07:00
|
|
|
}
|
|
|
|
buf = push_strbuf(ls);
|
|
|
|
eo_lexer_context_push(ls);
|
|
|
|
line = ls->line_number;
|
|
|
|
col = ls->column;
|
|
|
|
parse_name(ls, buf);
|
2014-08-19 08:37:29 -07:00
|
|
|
sname = push_str(ls, eina_strbuf_string_get(buf));
|
2014-07-25 06:51:13 -07:00
|
|
|
pop_strbuf(ls);
|
|
|
|
/* if we're extern and allow structs, gotta enforce it */
|
2014-08-19 07:55:31 -07:00
|
|
|
if (allow_named && (has_extern || freefunc))
|
2014-07-25 06:51:13 -07:00
|
|
|
check(ls, '{');
|
2014-08-11 06:56:50 -07:00
|
|
|
if (allow_named && ls->t.token == '{')
|
2014-07-25 06:51:13 -07:00
|
|
|
{
|
|
|
|
Eolian_Type *tp = (Eolian_Type*)eina_hash_find(_structs,
|
|
|
|
sname);
|
|
|
|
if (tp)
|
|
|
|
{
|
|
|
|
eo_lexer_context_restore(ls);
|
2014-08-11 06:56:50 -07:00
|
|
|
redef_error(ls, is_enum ? EOLIAN_TYPE_ENUM
|
|
|
|
: EOLIAN_TYPE_STRUCT, tp);
|
2014-07-25 06:51:13 -07:00
|
|
|
}
|
|
|
|
eo_lexer_context_pop(ls);
|
2014-08-19 08:37:29 -07:00
|
|
|
pop_str(ls);
|
2014-08-11 06:56:50 -07:00
|
|
|
if (is_enum)
|
2014-08-19 07:55:31 -07:00
|
|
|
return parse_enum(ls, sname, has_extern, line, col);
|
|
|
|
return parse_struct(ls, sname, has_extern, line, col, freefunc);
|
2014-07-25 06:51:13 -07:00
|
|
|
}
|
|
|
|
eo_lexer_context_pop(ls);
|
|
|
|
def = push_type(ls);
|
2014-08-11 06:56:50 -07:00
|
|
|
def->type = is_enum ? EOLIAN_TYPE_REGULAR_ENUM
|
|
|
|
: EOLIAN_TYPE_REGULAR_STRUCT;
|
2014-08-22 05:28:29 -07:00
|
|
|
def->base.file = eina_stringshare_ref(ls->filename);
|
|
|
|
def->base.line = line;
|
|
|
|
def->base.column = col;
|
2014-08-19 08:37:29 -07:00
|
|
|
pop_str(ls);
|
2014-07-25 06:51:13 -07:00
|
|
|
_fill_type_name(def, sname);
|
|
|
|
goto parse_ptr;
|
|
|
|
}
|
2014-07-01 10:25:17 -07:00
|
|
|
case KW_func:
|
|
|
|
return parse_function_type(ls);
|
|
|
|
default:
|
|
|
|
break;
|
2014-06-26 03:51:08 -07:00
|
|
|
}
|
2014-07-09 03:18:21 -07:00
|
|
|
def = push_type(ls);
|
2014-08-08 07:19:52 -07:00
|
|
|
def->base.file = eina_stringshare_ref(ls->filename);
|
2014-08-04 07:01:16 -07:00
|
|
|
def->base.line = line;
|
|
|
|
def->base.column = col;
|
2014-07-15 09:06:18 -07:00
|
|
|
if (ls->t.kw == KW_void)
|
2014-07-21 07:11:19 -07:00
|
|
|
{
|
|
|
|
def->type = EOLIAN_TYPE_VOID;
|
|
|
|
eo_lexer_get(ls);
|
|
|
|
}
|
2014-06-30 15:07:32 -07:00
|
|
|
else
|
|
|
|
{
|
2014-09-08 06:52:49 -07:00
|
|
|
int tpid = ls->t.kw;
|
2014-07-15 09:06:18 -07:00
|
|
|
def->type = EOLIAN_TYPE_REGULAR;
|
2014-06-30 15:07:32 -07:00
|
|
|
check(ls, TOK_VALUE);
|
|
|
|
ctype = eo_lexer_get_c_type(ls->t.kw);
|
2014-07-21 07:11:19 -07:00
|
|
|
if (ctype)
|
|
|
|
{
|
2014-09-08 06:52:49 -07:00
|
|
|
_fill_type_name(def, eina_stringshare_ref(ls->t.value.s));
|
2014-07-21 07:11:19 -07:00
|
|
|
eo_lexer_get(ls);
|
2014-09-08 06:52:49 -07:00
|
|
|
if (tpid >= KW_accessor)
|
|
|
|
{
|
|
|
|
def->type = EOLIAN_TYPE_COMPLEX;
|
|
|
|
if (ls->t.token == '<')
|
|
|
|
{
|
|
|
|
int bline = ls->line_number, bcol = ls->column;
|
|
|
|
eo_lexer_get(ls);
|
|
|
|
def->subtypes = eina_list_append(def->subtypes,
|
|
|
|
parse_type(ls));
|
|
|
|
pop_type(ls);
|
|
|
|
if (tpid == KW_hash)
|
|
|
|
{
|
|
|
|
check_next(ls, ',');
|
|
|
|
def->subtypes = eina_list_append(def->subtypes,
|
|
|
|
parse_type(ls));
|
|
|
|
pop_type(ls);
|
|
|
|
}
|
|
|
|
check_match(ls, '>', '<', bline, bcol);
|
|
|
|
}
|
|
|
|
}
|
2014-07-21 07:11:19 -07:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2014-08-26 03:06:54 -07:00
|
|
|
int dline = ls->line_number, dcol = ls->column;
|
2014-07-30 07:35:57 -07:00
|
|
|
const char *bnm, *nm;
|
|
|
|
char *fnm;
|
2014-07-21 07:11:19 -07:00
|
|
|
buf = push_strbuf(ls);
|
|
|
|
parse_name(ls, buf);
|
2014-07-30 03:57:11 -07:00
|
|
|
nm = eina_strbuf_string_get(buf);
|
2014-08-08 07:19:52 -07:00
|
|
|
bnm = eina_stringshare_ref(ls->filename);
|
2014-07-30 07:35:57 -07:00
|
|
|
fnm = database_class_to_filename(nm);
|
2014-08-01 05:59:46 -07:00
|
|
|
if (!compare_class_file(bnm, fnm))
|
2014-07-30 03:57:11 -07:00
|
|
|
{
|
2014-07-30 07:35:57 -07:00
|
|
|
const char *fname = eina_hash_find(_filenames, fnm);
|
|
|
|
eina_stringshare_del(bnm);
|
|
|
|
free(fnm);
|
|
|
|
if (fname)
|
2014-07-30 03:57:11 -07:00
|
|
|
{
|
2014-08-26 03:06:54 -07:00
|
|
|
if (!eolian_class_get_by_name(nm))
|
|
|
|
_append_dep(ls, fname, nm, dline, dcol);
|
2014-07-30 07:35:57 -07:00
|
|
|
def->type = EOLIAN_TYPE_CLASS;
|
2014-07-30 03:57:11 -07:00
|
|
|
}
|
|
|
|
}
|
2014-07-30 07:35:57 -07:00
|
|
|
else
|
|
|
|
{
|
|
|
|
eina_stringshare_del(bnm);
|
|
|
|
free(fnm);
|
|
|
|
def->type = EOLIAN_TYPE_CLASS;
|
|
|
|
}
|
2014-07-30 03:57:11 -07:00
|
|
|
_fill_type_name(def, eina_stringshare_add(nm));
|
2014-07-21 07:11:19 -07:00
|
|
|
pop_strbuf(ls);
|
|
|
|
}
|
2014-06-30 15:07:32 -07:00
|
|
|
}
|
2014-06-26 03:51:08 -07:00
|
|
|
parse_ptr:
|
|
|
|
while (ls->t.token == '*')
|
|
|
|
{
|
2014-07-10 06:44:17 -07:00
|
|
|
Eolian_Type *pdef;
|
2014-07-09 03:18:21 -07:00
|
|
|
pop_type(ls);
|
|
|
|
pdef = push_type(ls);
|
2014-08-08 07:19:52 -07:00
|
|
|
pdef->base.file = eina_stringshare_ref(ls->filename);
|
2014-08-04 07:01:16 -07:00
|
|
|
pdef->base.line = ls->line_number;
|
|
|
|
pdef->base.column = ls->column;
|
2014-06-27 06:47:40 -07:00
|
|
|
pdef->base_type = def;
|
|
|
|
pdef->type = EOLIAN_TYPE_POINTER;
|
|
|
|
def = pdef;
|
2014-06-18 03:25:07 -07:00
|
|
|
eo_lexer_get(ls);
|
|
|
|
}
|
2014-06-27 06:47:40 -07:00
|
|
|
return def;
|
2014-06-18 03:25:07 -07:00
|
|
|
}
|
|
|
|
|
2014-07-10 06:44:17 -07:00
|
|
|
static Eolian_Type *
|
2014-07-08 07:02:36 -07:00
|
|
|
parse_type_void(Eo_Lexer *ls)
|
|
|
|
{
|
2014-08-11 06:56:50 -07:00
|
|
|
return parse_type_named_void(ls, EINA_FALSE);
|
2014-07-08 07:02:36 -07:00
|
|
|
}
|
|
|
|
|
2014-07-21 08:53:25 -07:00
|
|
|
static Eolian_Type *
|
2014-06-18 03:25:07 -07:00
|
|
|
parse_typedef(Eo_Lexer *ls)
|
|
|
|
{
|
2014-07-21 08:53:25 -07:00
|
|
|
Eolian_Type *def = push_type(ls);
|
2014-08-19 07:55:31 -07:00
|
|
|
Eina_Bool has_extern;
|
|
|
|
const char *freefunc;
|
2014-07-21 08:53:25 -07:00
|
|
|
Eina_Strbuf *buf;
|
2014-06-18 03:25:07 -07:00
|
|
|
eo_lexer_get(ls);
|
2014-08-19 07:55:31 -07:00
|
|
|
parse_struct_attrs(ls, EINA_FALSE, EINA_TRUE, &has_extern, &freefunc);
|
|
|
|
def->freefunc = freefunc;
|
2014-08-19 08:37:29 -07:00
|
|
|
pop_str(ls);
|
2014-07-21 09:12:35 -07:00
|
|
|
def->type = EOLIAN_TYPE_ALIAS;
|
2014-08-19 07:55:31 -07:00
|
|
|
def->is_extern = has_extern;
|
2014-07-21 08:53:25 -07:00
|
|
|
buf = push_strbuf(ls);
|
2014-07-22 07:27:11 -07:00
|
|
|
eo_lexer_context_push(ls);
|
2014-08-08 07:19:52 -07:00
|
|
|
def->base.file = eina_stringshare_ref(ls->filename);
|
2014-08-04 07:01:16 -07:00
|
|
|
def->base.line = ls->line_number;
|
|
|
|
def->base.column = ls->column;
|
2014-07-21 08:53:25 -07:00
|
|
|
parse_name(ls, buf);
|
|
|
|
_fill_type_name(def, eina_stringshare_add(eina_strbuf_string_get(buf)));
|
2014-07-22 06:48:08 -07:00
|
|
|
Eolian_Type *tp = (Eolian_Type*)eina_hash_find(_aliases, def->full_name);
|
|
|
|
if (tp)
|
2014-07-21 08:53:25 -07:00
|
|
|
{
|
2014-07-22 07:27:11 -07:00
|
|
|
eo_lexer_context_restore(ls);
|
2014-07-22 07:01:09 -07:00
|
|
|
redef_error(ls, EOLIAN_TYPE_ALIAS, tp);
|
2014-07-21 08:53:25 -07:00
|
|
|
}
|
2014-07-22 07:27:11 -07:00
|
|
|
eo_lexer_context_pop(ls);
|
2014-08-08 07:57:39 -07:00
|
|
|
check_next(ls, ':');
|
2014-08-11 06:56:50 -07:00
|
|
|
def->base_type = parse_type_named(ls, EINA_TRUE);
|
2014-07-09 03:18:21 -07:00
|
|
|
pop_type(ls);
|
2014-06-18 03:25:07 -07:00
|
|
|
check_next(ls, ';');
|
2014-07-23 02:57:23 -07:00
|
|
|
if (ls->t.token == TOK_COMMENT)
|
|
|
|
{
|
2014-07-17 09:16:31 -07:00
|
|
|
def->comment = eina_stringshare_ref(ls->t.value.s);
|
2014-07-23 02:57:23 -07:00
|
|
|
eo_lexer_get(ls);
|
|
|
|
}
|
2014-07-21 08:53:25 -07:00
|
|
|
return def;
|
2014-06-18 03:25:07 -07:00
|
|
|
}
|
|
|
|
|
2014-08-08 07:57:39 -07:00
|
|
|
static Eolian_Variable *
|
|
|
|
parse_variable(Eo_Lexer *ls, Eina_Bool global)
|
|
|
|
{
|
2014-09-12 07:01:10 -07:00
|
|
|
Eolian_Variable *def = calloc(1, sizeof(Eolian_Variable));
|
2014-08-19 07:55:31 -07:00
|
|
|
Eina_Bool has_extern = EINA_FALSE;
|
2014-08-08 07:57:39 -07:00
|
|
|
Eina_Strbuf *buf;
|
2014-09-12 07:01:10 -07:00
|
|
|
ls->tmp.var = def;
|
2014-08-08 07:57:39 -07:00
|
|
|
eo_lexer_get(ls);
|
|
|
|
if (ls->t.kw == KW_at_extern)
|
|
|
|
{
|
2014-08-08 08:28:31 -07:00
|
|
|
if (!global)
|
|
|
|
eo_lexer_syntax_error(ls, "extern constant");
|
2014-08-19 07:55:31 -07:00
|
|
|
has_extern = EINA_TRUE;
|
2014-08-08 07:57:39 -07:00
|
|
|
eo_lexer_get(ls);
|
|
|
|
}
|
|
|
|
def->type = global ? EOLIAN_VAR_GLOBAL : EOLIAN_VAR_CONSTANT;
|
2014-08-19 07:55:31 -07:00
|
|
|
def->is_extern = has_extern;
|
2014-08-08 07:57:39 -07:00
|
|
|
buf = push_strbuf(ls);
|
|
|
|
eo_lexer_context_push(ls);
|
|
|
|
def->base.file = eina_stringshare_ref(ls->filename);
|
|
|
|
def->base.line = ls->line_number;
|
|
|
|
def->base.column = ls->column;
|
|
|
|
parse_name(ls, buf);
|
|
|
|
_fill_variable_name(def, eina_stringshare_add(eina_strbuf_string_get(buf)));
|
|
|
|
check_next(ls, ':');
|
|
|
|
def->base_type = parse_type(ls);
|
|
|
|
pop_type(ls);
|
2014-08-19 07:55:31 -07:00
|
|
|
if ((ls->t.token == '=') && !has_extern)
|
2014-08-08 07:57:39 -07:00
|
|
|
{
|
|
|
|
ls->expr_mode = EINA_TRUE;
|
|
|
|
eo_lexer_get(ls);
|
|
|
|
def->value = parse_expr(ls);
|
|
|
|
ls->expr_mode = EINA_FALSE;
|
2014-08-11 06:56:50 -07:00
|
|
|
pop_expr(ls);
|
2014-08-08 07:57:39 -07:00
|
|
|
}
|
|
|
|
check_next(ls, ';');
|
|
|
|
if (ls->t.token == TOK_COMMENT)
|
|
|
|
{
|
|
|
|
def->comment = eina_stringshare_ref(ls->t.value.s);
|
|
|
|
eo_lexer_get(ls);
|
|
|
|
}
|
|
|
|
return def;
|
|
|
|
}
|
|
|
|
|
2014-09-10 08:17:47 -07:00
|
|
|
typedef struct _Eo_Ret_Def
|
|
|
|
{
|
|
|
|
Eolian_Type *type;
|
|
|
|
Eina_Stringshare *comment;
|
|
|
|
Eolian_Expression *default_ret_val;
|
|
|
|
Eina_Bool warn_unused:1;
|
|
|
|
} Eo_Ret_Def;
|
|
|
|
|
2014-06-18 03:25:07 -07:00
|
|
|
static void
|
2014-09-10 08:17:47 -07:00
|
|
|
parse_return(Eo_Lexer *ls, Eo_Ret_Def *ret, Eina_Bool allow_void)
|
2014-06-18 03:25:07 -07:00
|
|
|
{
|
|
|
|
eo_lexer_get(ls);
|
2014-08-07 08:58:45 -07:00
|
|
|
check_next(ls, ':');
|
2014-06-30 15:13:04 -07:00
|
|
|
if (allow_void)
|
2014-07-01 10:25:17 -07:00
|
|
|
ret->type = parse_type_void(ls);
|
2014-06-30 15:13:04 -07:00
|
|
|
else
|
2014-07-01 10:25:17 -07:00
|
|
|
ret->type = parse_type(ls);
|
2014-09-10 08:17:47 -07:00
|
|
|
ret->comment = NULL;
|
|
|
|
ret->default_ret_val = NULL;
|
|
|
|
ret->warn_unused = EINA_FALSE;
|
2014-06-18 03:25:07 -07:00
|
|
|
if (ls->t.token == '(')
|
|
|
|
{
|
2014-07-02 16:00:02 -07:00
|
|
|
int line = ls->line_number, col = ls->column;
|
2014-08-08 03:32:07 -07:00
|
|
|
ls->expr_mode = EINA_TRUE;
|
2014-06-18 03:25:07 -07:00
|
|
|
eo_lexer_get(ls);
|
2014-08-07 07:15:07 -07:00
|
|
|
ret->default_ret_val = parse_expr(ls);
|
2014-08-08 03:32:07 -07:00
|
|
|
ls->expr_mode = EINA_FALSE;
|
2014-07-02 16:00:02 -07:00
|
|
|
check_match(ls, ')', '(', line, col);
|
2014-06-18 03:25:07 -07:00
|
|
|
}
|
|
|
|
if (ls->t.kw == KW_at_warn_unused)
|
|
|
|
{
|
|
|
|
ret->warn_unused = EINA_TRUE;
|
|
|
|
eo_lexer_get(ls);
|
|
|
|
}
|
|
|
|
check_next(ls, ';');
|
|
|
|
if (ls->t.token == TOK_COMMENT)
|
|
|
|
{
|
2014-07-17 09:16:31 -07:00
|
|
|
ret->comment = eina_stringshare_ref(ls->t.value.s);
|
2014-06-18 03:25:07 -07:00
|
|
|
eo_lexer_get(ls);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2014-09-12 05:35:48 -07:00
|
|
|
parse_param(Eo_Lexer *ls, Eina_List **params, Eina_Bool allow_inout,
|
|
|
|
Eina_Bool is_vals)
|
2014-06-18 03:25:07 -07:00
|
|
|
{
|
2014-09-10 06:24:41 -07:00
|
|
|
Eolian_Function_Parameter *par = calloc(1, sizeof(Eolian_Function_Parameter));
|
2014-08-08 07:19:52 -07:00
|
|
|
par->base.file = eina_stringshare_ref(ls->filename);
|
2014-08-04 07:01:16 -07:00
|
|
|
par->base.line = ls->line_number;
|
|
|
|
par->base.column = ls->column;
|
2014-09-12 05:35:48 -07:00
|
|
|
*params = eina_list_append(*params, par);
|
2014-06-18 03:25:07 -07:00
|
|
|
if (allow_inout)
|
|
|
|
{
|
|
|
|
if (ls->t.kw == KW_at_in)
|
|
|
|
{
|
2014-09-10 06:24:41 -07:00
|
|
|
par->param_dir = EOLIAN_IN_PARAM;
|
2014-06-18 03:25:07 -07:00
|
|
|
eo_lexer_get(ls);
|
|
|
|
}
|
|
|
|
else if (ls->t.kw == KW_at_out)
|
|
|
|
{
|
2014-09-10 06:24:41 -07:00
|
|
|
par->param_dir = EOLIAN_OUT_PARAM;
|
2014-06-18 03:25:07 -07:00
|
|
|
eo_lexer_get(ls);
|
|
|
|
}
|
|
|
|
else if (ls->t.kw == KW_at_inout)
|
|
|
|
{
|
2014-09-10 06:24:41 -07:00
|
|
|
par->param_dir = EOLIAN_INOUT_PARAM;
|
2014-06-18 03:25:07 -07:00
|
|
|
eo_lexer_get(ls);
|
|
|
|
}
|
|
|
|
else
|
2014-09-10 06:24:41 -07:00
|
|
|
par->param_dir = EOLIAN_IN_PARAM;
|
2014-06-18 03:25:07 -07:00
|
|
|
}
|
2014-09-10 06:24:41 -07:00
|
|
|
if (par->param_dir == EOLIAN_OUT_PARAM || par->param_dir == EOLIAN_INOUT_PARAM)
|
2014-06-30 15:21:36 -07:00
|
|
|
par->type = parse_type_void(ls);
|
|
|
|
else
|
|
|
|
par->type = parse_type(ls);
|
2014-07-09 03:18:21 -07:00
|
|
|
pop_type(ls);
|
2014-06-18 03:25:07 -07:00
|
|
|
check(ls, TOK_VALUE);
|
2014-07-17 09:16:31 -07:00
|
|
|
par->name = eina_stringshare_ref(ls->t.value.s);
|
2014-06-18 03:25:07 -07:00
|
|
|
eo_lexer_get(ls);
|
2014-09-10 06:24:41 -07:00
|
|
|
if ((is_vals || (par->param_dir == EOLIAN_OUT_PARAM)) && (ls->t.token == '('))
|
2014-09-02 02:47:38 -07:00
|
|
|
{
|
|
|
|
int line = ls->line_number, col = ls->column;
|
|
|
|
ls->expr_mode = EINA_TRUE;
|
|
|
|
eo_lexer_get(ls);
|
|
|
|
par->value = parse_expr(ls);
|
|
|
|
ls->expr_mode = EINA_FALSE;
|
|
|
|
pop_expr(ls);
|
|
|
|
check_match(ls, ')', '(', line, col);
|
|
|
|
}
|
2014-09-10 07:06:12 -07:00
|
|
|
/* XXX: remove this fugly bit - temporary */
|
|
|
|
if (is_vals)
|
|
|
|
{
|
|
|
|
if (ls->t.kw == KW_at_const_get)
|
|
|
|
{
|
|
|
|
par->is_const_on_get = EINA_TRUE;
|
|
|
|
eo_lexer_get(ls);
|
|
|
|
}
|
|
|
|
else if (ls->t.kw == KW_at_const_set)
|
|
|
|
{
|
|
|
|
par->is_const_on_set = EINA_TRUE;
|
|
|
|
eo_lexer_get(ls);
|
|
|
|
}
|
|
|
|
}
|
2014-06-18 03:25:07 -07:00
|
|
|
if (ls->t.kw == KW_at_nonull)
|
|
|
|
{
|
|
|
|
par->nonull = EINA_TRUE;
|
|
|
|
eo_lexer_get(ls);
|
|
|
|
}
|
|
|
|
check_next(ls, ';');
|
|
|
|
if (ls->t.token == TOK_COMMENT)
|
|
|
|
{
|
2014-09-10 06:24:41 -07:00
|
|
|
par->description = eina_stringshare_ref(ls->t.value.s);
|
2014-06-18 03:25:07 -07:00
|
|
|
eo_lexer_get(ls);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2014-09-12 05:30:24 -07:00
|
|
|
parse_legacy(Eo_Lexer *ls, const char **out)
|
2014-06-18 03:25:07 -07:00
|
|
|
{
|
|
|
|
eo_lexer_get(ls);
|
2014-08-07 08:58:45 -07:00
|
|
|
check_next(ls, ':');
|
2014-06-18 03:25:07 -07:00
|
|
|
check(ls, TOK_VALUE);
|
2014-09-12 05:30:24 -07:00
|
|
|
*out = eina_stringshare_ref(ls->t.value.s);
|
2014-06-18 03:25:07 -07:00
|
|
|
eo_lexer_get(ls);
|
|
|
|
check_next(ls, ';');
|
|
|
|
}
|
|
|
|
|
2014-09-10 07:53:20 -07:00
|
|
|
static void
|
2014-09-10 08:58:29 -07:00
|
|
|
parse_accessor(Eo_Lexer *ls, Eolian_Function *prop)
|
2014-06-18 03:25:07 -07:00
|
|
|
{
|
2014-07-02 16:00:02 -07:00
|
|
|
int line, col;
|
2014-08-18 06:51:03 -07:00
|
|
|
Eina_Bool has_return = EINA_FALSE, has_legacy = EINA_FALSE,
|
|
|
|
has_eo = EINA_FALSE;
|
2014-09-10 07:53:20 -07:00
|
|
|
Eina_Bool is_get = (ls->t.kw == KW_get);
|
|
|
|
if (is_get)
|
|
|
|
{
|
2014-09-10 08:58:29 -07:00
|
|
|
if (prop->base.file)
|
|
|
|
eina_stringshare_del(prop->base.file);
|
2014-09-10 07:53:20 -07:00
|
|
|
prop->base.file = eina_stringshare_ref(ls->filename);
|
|
|
|
prop->base.line = ls->line_number;
|
|
|
|
prop->base.column = ls->column;
|
2014-09-10 08:17:47 -07:00
|
|
|
if (prop->type == EOLIAN_PROP_SET)
|
|
|
|
prop->type = EOLIAN_PROPERTY;
|
|
|
|
else
|
|
|
|
prop->type = EOLIAN_PROP_GET;
|
2014-09-10 07:53:20 -07:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
prop->set_base.file = eina_stringshare_ref(ls->filename);
|
|
|
|
prop->set_base.line = ls->line_number;
|
|
|
|
prop->set_base.column = ls->column;
|
2014-09-10 08:17:47 -07:00
|
|
|
if (prop->type == EOLIAN_PROP_GET)
|
|
|
|
prop->type = EOLIAN_PROPERTY;
|
|
|
|
else
|
|
|
|
prop->type = EOLIAN_PROP_SET;
|
2014-09-10 07:53:20 -07:00
|
|
|
}
|
2014-06-18 03:25:07 -07:00
|
|
|
eo_lexer_get(ls);
|
|
|
|
line = ls->line_number;
|
2014-07-02 16:00:02 -07:00
|
|
|
col = ls->column;
|
2014-06-18 03:25:07 -07:00
|
|
|
check_next(ls, '{');
|
|
|
|
if (ls->t.token == TOK_COMMENT)
|
|
|
|
{
|
2014-09-10 07:53:20 -07:00
|
|
|
if (is_get)
|
2014-09-10 08:17:47 -07:00
|
|
|
prop->get_description = eina_stringshare_ref(ls->t.value.s);
|
2014-09-10 07:53:20 -07:00
|
|
|
else
|
2014-09-10 08:17:47 -07:00
|
|
|
prop->set_description = eina_stringshare_ref(ls->t.value.s);
|
2014-06-18 03:25:07 -07:00
|
|
|
eo_lexer_get(ls);
|
|
|
|
}
|
2014-07-01 10:25:17 -07:00
|
|
|
for (;;) switch (ls->t.kw)
|
2014-06-18 03:25:07 -07:00
|
|
|
{
|
2014-07-01 10:25:17 -07:00
|
|
|
case KW_return:
|
|
|
|
CASE_LOCK(ls, return, "return")
|
2014-09-10 08:17:47 -07:00
|
|
|
Eo_Ret_Def ret;
|
|
|
|
parse_return(ls, &ret, is_get);
|
|
|
|
pop_type(ls);
|
|
|
|
if (ret.default_ret_val) pop_expr(ls);
|
2014-09-10 07:53:20 -07:00
|
|
|
if (is_get)
|
2014-09-10 08:17:47 -07:00
|
|
|
{
|
|
|
|
prop->get_ret_type = ret.type;
|
|
|
|
prop->get_return_comment = ret.comment;
|
|
|
|
prop->get_ret_val = ret.default_ret_val;
|
|
|
|
prop->get_return_warn_unused = ret.warn_unused;
|
|
|
|
}
|
2014-09-10 07:53:20 -07:00
|
|
|
else
|
2014-09-10 08:17:47 -07:00
|
|
|
{
|
|
|
|
prop->set_ret_type = ret.type;
|
|
|
|
prop->set_return_comment = ret.comment;
|
|
|
|
prop->set_ret_val = ret.default_ret_val;
|
|
|
|
prop->set_return_warn_unused = ret.warn_unused;
|
|
|
|
}
|
2014-07-01 10:25:17 -07:00
|
|
|
break;
|
|
|
|
case KW_legacy:
|
|
|
|
CASE_LOCK(ls, legacy, "legacy name")
|
2014-09-10 07:53:20 -07:00
|
|
|
if (is_get)
|
2014-09-12 05:30:24 -07:00
|
|
|
parse_legacy(ls, &prop->get_legacy);
|
2014-09-10 07:53:20 -07:00
|
|
|
else
|
2014-09-12 05:30:24 -07:00
|
|
|
parse_legacy(ls, &prop->set_legacy);
|
2014-07-01 10:25:17 -07:00
|
|
|
break;
|
2014-08-18 06:51:03 -07:00
|
|
|
case KW_eo:
|
|
|
|
CASE_LOCK(ls, eo, "eo name")
|
|
|
|
eo_lexer_get(ls);
|
|
|
|
check_next(ls, ':');
|
|
|
|
check_kw_next(ls, KW_null);
|
|
|
|
check_next(ls, ';');
|
2014-09-10 07:53:20 -07:00
|
|
|
if (is_get)
|
|
|
|
prop->get_only_legacy = EINA_TRUE;
|
|
|
|
else
|
|
|
|
prop->set_only_legacy = EINA_TRUE;
|
2014-08-18 06:51:03 -07:00
|
|
|
break;
|
2014-07-01 10:25:17 -07:00
|
|
|
default:
|
2014-09-10 07:06:12 -07:00
|
|
|
goto end;
|
2014-06-18 03:25:07 -07:00
|
|
|
}
|
|
|
|
end:
|
2014-07-02 16:00:02 -07:00
|
|
|
check_match(ls, '}', '{', line, col);
|
2014-06-18 03:25:07 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2014-09-12 05:35:48 -07:00
|
|
|
parse_params(Eo_Lexer *ls, Eina_List **params, Eina_Bool allow_inout,
|
|
|
|
Eina_Bool is_vals)
|
2014-06-18 03:25:07 -07:00
|
|
|
{
|
2014-09-12 05:35:48 -07:00
|
|
|
PARSE_SECTION parse_param(ls, params, allow_inout, is_vals);
|
2014-07-02 16:00:02 -07:00
|
|
|
check_match(ls, '}', '{', line, col);
|
2014-06-18 03:25:07 -07:00
|
|
|
}
|
|
|
|
|
2014-09-10 08:58:29 -07:00
|
|
|
static void
|
|
|
|
_interface_virtual_set(Eo_Lexer *ls, Eolian_Function *foo_id)
|
|
|
|
{
|
|
|
|
if (ls->tmp.kls->type != EOLIAN_CLASS_INTERFACE)
|
|
|
|
return;
|
|
|
|
|
2014-09-11 02:29:48 -07:00
|
|
|
if (foo_id->type == EOLIAN_PROP_GET || foo_id->type == EOLIAN_METHOD)
|
2014-09-10 08:58:29 -07:00
|
|
|
foo_id->get_virtual_pure = EINA_TRUE;
|
|
|
|
else if (foo_id->type == EOLIAN_PROP_SET)
|
|
|
|
foo_id->set_virtual_pure = EINA_TRUE;
|
2014-09-11 02:29:48 -07:00
|
|
|
else if (foo_id->type == EOLIAN_PROPERTY)
|
2014-09-10 08:58:29 -07:00
|
|
|
foo_id->get_virtual_pure = foo_id->set_virtual_pure = EINA_TRUE;
|
|
|
|
}
|
|
|
|
|
2014-06-18 03:25:07 -07:00
|
|
|
static void
|
|
|
|
parse_property(Eo_Lexer *ls)
|
|
|
|
{
|
2014-07-02 16:00:02 -07:00
|
|
|
int line, col;
|
2014-09-10 08:58:29 -07:00
|
|
|
Eolian_Function *prop = NULL;
|
2014-07-24 04:05:12 -07:00
|
|
|
Eina_Bool has_get = EINA_FALSE, has_set = EINA_FALSE,
|
|
|
|
has_keys = EINA_FALSE, has_values = EINA_FALSE,
|
2014-09-01 08:02:40 -07:00
|
|
|
has_protected = EINA_FALSE, has_class = EINA_FALSE;
|
2014-09-10 08:58:29 -07:00
|
|
|
prop = calloc(1, sizeof(Eolian_Function));
|
2014-08-08 07:19:52 -07:00
|
|
|
prop->base.file = eina_stringshare_ref(ls->filename);
|
2014-08-04 07:01:16 -07:00
|
|
|
prop->base.line = ls->line_number;
|
|
|
|
prop->base.column = ls->column;
|
2014-09-12 05:25:26 -07:00
|
|
|
ls->tmp.kls->properties = eina_list_append(ls->tmp.kls->properties, prop);
|
2014-07-22 08:35:54 -07:00
|
|
|
check(ls, TOK_VALUE);
|
2014-07-17 09:16:31 -07:00
|
|
|
prop->name = eina_stringshare_ref(ls->t.value.s);
|
2014-07-22 08:35:54 -07:00
|
|
|
eo_lexer_get(ls);
|
2014-07-24 04:05:12 -07:00
|
|
|
for (;;) switch (ls->t.kw)
|
2014-06-18 03:25:07 -07:00
|
|
|
{
|
2014-07-24 04:05:12 -07:00
|
|
|
case KW_at_protected:
|
|
|
|
CASE_LOCK(ls, protected, "protected qualifier")
|
2014-06-30 15:17:05 -07:00
|
|
|
prop->scope = EOLIAN_SCOPE_PROTECTED;
|
2014-06-18 03:25:07 -07:00
|
|
|
eo_lexer_get(ls);
|
2014-07-24 04:05:12 -07:00
|
|
|
break;
|
|
|
|
case KW_at_class:
|
|
|
|
CASE_LOCK(ls, class, "class qualifier");
|
|
|
|
prop->is_class = EINA_TRUE;
|
2014-07-24 06:01:33 -07:00
|
|
|
eo_lexer_get(ls);
|
|
|
|
break;
|
2014-07-24 04:05:12 -07:00
|
|
|
default:
|
|
|
|
goto body;
|
2014-06-18 03:25:07 -07:00
|
|
|
}
|
2014-07-24 04:05:12 -07:00
|
|
|
body:
|
2014-06-18 03:25:07 -07:00
|
|
|
line = ls->line_number;
|
2014-07-02 16:00:02 -07:00
|
|
|
col = ls->column;
|
2014-06-18 03:25:07 -07:00
|
|
|
check_next(ls, '{');
|
2014-08-06 04:38:40 -07:00
|
|
|
if (ls->t.token == TOK_COMMENT)
|
|
|
|
{
|
|
|
|
/* just consume the comment for now */
|
|
|
|
eo_lexer_get(ls);
|
|
|
|
}
|
2014-07-01 10:25:17 -07:00
|
|
|
for (;;) switch (ls->t.kw)
|
2014-06-18 03:25:07 -07:00
|
|
|
{
|
2014-07-01 10:25:17 -07:00
|
|
|
case KW_get:
|
|
|
|
CASE_LOCK(ls, get, "get definition")
|
2014-09-10 07:53:20 -07:00
|
|
|
parse_accessor(ls, prop);
|
2014-07-01 10:25:17 -07:00
|
|
|
break;
|
|
|
|
case KW_set:
|
|
|
|
CASE_LOCK(ls, set, "set definition")
|
2014-09-10 07:53:20 -07:00
|
|
|
parse_accessor(ls, prop);
|
2014-07-01 10:25:17 -07:00
|
|
|
break;
|
|
|
|
case KW_keys:
|
|
|
|
CASE_LOCK(ls, keys, "keys definition")
|
2014-09-12 05:35:48 -07:00
|
|
|
parse_params(ls, &prop->keys, EINA_FALSE, EINA_FALSE);
|
2014-07-01 10:25:17 -07:00
|
|
|
break;
|
|
|
|
case KW_values:
|
|
|
|
CASE_LOCK(ls, values, "values definition")
|
2014-09-12 05:35:48 -07:00
|
|
|
parse_params(ls, &prop->params, EINA_FALSE, EINA_TRUE);
|
2014-07-01 10:25:17 -07:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
goto end;
|
2014-06-18 03:25:07 -07:00
|
|
|
}
|
|
|
|
end:
|
2014-07-02 16:00:02 -07:00
|
|
|
check_match(ls, '}', '{', line, col);
|
2014-09-10 08:46:34 -07:00
|
|
|
if (!has_get && !has_set)
|
|
|
|
prop->type = EOLIAN_PROPERTY;
|
2014-09-10 08:58:29 -07:00
|
|
|
_interface_virtual_set(ls, prop);
|
2014-06-18 03:25:07 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
parse_method(Eo_Lexer *ls, Eina_Bool ctor)
|
|
|
|
{
|
2014-07-02 16:00:02 -07:00
|
|
|
int line, col;
|
2014-09-11 02:29:48 -07:00
|
|
|
Eolian_Function *meth = NULL;
|
2014-06-18 03:25:07 -07:00
|
|
|
Eina_Bool has_const = EINA_FALSE, has_params = EINA_FALSE,
|
2014-07-22 09:13:24 -07:00
|
|
|
has_return = EINA_FALSE, has_legacy = EINA_FALSE,
|
2014-07-24 05:01:47 -07:00
|
|
|
has_protected = EINA_FALSE, has_class = EINA_FALSE,
|
2014-09-01 08:02:40 -07:00
|
|
|
has_eo = EINA_FALSE;
|
2014-09-11 02:29:48 -07:00
|
|
|
meth = calloc(1, sizeof(Eolian_Function));
|
|
|
|
meth->type = EOLIAN_METHOD;
|
2014-08-08 07:19:52 -07:00
|
|
|
meth->base.file = eina_stringshare_ref(ls->filename);
|
2014-08-04 07:01:16 -07:00
|
|
|
meth->base.line = ls->line_number;
|
|
|
|
meth->base.column = ls->column;
|
2014-09-12 05:25:26 -07:00
|
|
|
ls->tmp.kls->methods = eina_list_append(ls->tmp.kls->methods, meth);
|
2014-06-18 03:25:07 -07:00
|
|
|
if (ctor)
|
|
|
|
{
|
|
|
|
if (ls->t.token != TOK_VALUE)
|
2014-07-01 10:25:17 -07:00
|
|
|
eo_lexer_syntax_error(ls, "expected method name");
|
2014-07-17 09:16:31 -07:00
|
|
|
meth->name = eina_stringshare_ref(ls->t.value.s);
|
2014-06-18 03:25:07 -07:00
|
|
|
eo_lexer_get(ls);
|
2014-07-24 04:58:29 -07:00
|
|
|
for (;;) switch (ls->t.kw)
|
|
|
|
{
|
|
|
|
case KW_at_protected:
|
|
|
|
CASE_LOCK(ls, protected, "protected qualifier")
|
|
|
|
meth->scope = EOLIAN_SCOPE_PROTECTED;
|
|
|
|
eo_lexer_get(ls);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
goto body;
|
|
|
|
}
|
2014-06-18 03:25:07 -07:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2014-07-22 08:35:54 -07:00
|
|
|
check(ls, TOK_VALUE);
|
2014-07-17 09:16:31 -07:00
|
|
|
meth->name = eina_stringshare_ref(ls->t.value.s);
|
2014-07-22 08:35:54 -07:00
|
|
|
eo_lexer_get(ls);
|
2014-07-22 09:13:24 -07:00
|
|
|
for (;;) switch (ls->t.kw)
|
2014-06-18 03:25:07 -07:00
|
|
|
{
|
2014-07-22 09:13:24 -07:00
|
|
|
case KW_at_protected:
|
|
|
|
CASE_LOCK(ls, protected, "protected qualifier")
|
2014-06-30 15:17:05 -07:00
|
|
|
meth->scope = EOLIAN_SCOPE_PROTECTED;
|
2014-06-18 03:25:07 -07:00
|
|
|
eo_lexer_get(ls);
|
2014-07-22 09:13:24 -07:00
|
|
|
break;
|
|
|
|
case KW_at_const:
|
|
|
|
CASE_LOCK(ls, const, "const qualifier")
|
2014-09-11 02:29:48 -07:00
|
|
|
meth->obj_is_const = EINA_TRUE;
|
2014-07-22 09:13:24 -07:00
|
|
|
eo_lexer_get(ls);
|
|
|
|
break;
|
2014-07-24 04:05:12 -07:00
|
|
|
case KW_at_class:
|
|
|
|
CASE_LOCK(ls, class, "class qualifier");
|
|
|
|
meth->is_class = EINA_TRUE;
|
2014-07-24 05:01:47 -07:00
|
|
|
eo_lexer_get(ls);
|
|
|
|
break;
|
2014-07-22 09:13:24 -07:00
|
|
|
default:
|
|
|
|
goto body;
|
2014-06-18 03:25:07 -07:00
|
|
|
}
|
|
|
|
}
|
2014-07-22 09:13:24 -07:00
|
|
|
body:
|
2014-06-18 03:25:07 -07:00
|
|
|
line = ls->line_number;
|
2014-07-02 16:00:02 -07:00
|
|
|
col = ls->column;
|
2014-06-18 03:25:07 -07:00
|
|
|
check_next(ls, '{');
|
|
|
|
if (ls->t.token == TOK_COMMENT)
|
|
|
|
{
|
2014-09-11 02:29:48 -07:00
|
|
|
meth->get_description = eina_stringshare_ref(ls->t.value.s);
|
2014-06-18 03:25:07 -07:00
|
|
|
eo_lexer_get(ls);
|
|
|
|
}
|
2014-07-01 10:25:17 -07:00
|
|
|
for (;;) switch (ls->t.kw)
|
2014-06-18 03:25:07 -07:00
|
|
|
{
|
2014-07-01 10:25:17 -07:00
|
|
|
case KW_return:
|
|
|
|
CASE_LOCK(ls, return, "return")
|
2014-09-10 08:17:47 -07:00
|
|
|
Eo_Ret_Def ret;
|
|
|
|
parse_return(ls, &ret, EINA_FALSE);
|
|
|
|
pop_type(ls);
|
|
|
|
if (ret.default_ret_val) pop_expr(ls);
|
2014-09-11 02:29:48 -07:00
|
|
|
meth->get_ret_type = ret.type;
|
|
|
|
meth->get_return_comment = ret.comment;
|
|
|
|
meth->get_ret_val = ret.default_ret_val;
|
|
|
|
meth->get_return_warn_unused = ret.warn_unused;
|
2014-07-01 10:25:17 -07:00
|
|
|
break;
|
|
|
|
case KW_legacy:
|
|
|
|
CASE_LOCK(ls, legacy, "legacy name")
|
2014-09-12 05:30:24 -07:00
|
|
|
parse_legacy(ls, &meth->get_legacy);
|
2014-07-01 10:25:17 -07:00
|
|
|
break;
|
2014-08-18 06:51:03 -07:00
|
|
|
case KW_eo:
|
|
|
|
CASE_LOCK(ls, eo, "eo name")
|
|
|
|
eo_lexer_get(ls);
|
|
|
|
check_next(ls, ':');
|
|
|
|
check_kw_next(ls, KW_null);
|
|
|
|
check_next(ls, ';');
|
2014-09-11 02:29:48 -07:00
|
|
|
meth->get_only_legacy = EINA_TRUE;
|
2014-08-18 06:51:03 -07:00
|
|
|
break;
|
2014-07-01 10:25:17 -07:00
|
|
|
case KW_params:
|
|
|
|
CASE_LOCK(ls, params, "params definition")
|
2014-09-12 05:35:48 -07:00
|
|
|
parse_params(ls, &meth->params, EINA_TRUE, EINA_FALSE);
|
2014-07-01 10:25:17 -07:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
goto end;
|
2014-06-18 03:25:07 -07:00
|
|
|
}
|
|
|
|
end:
|
2014-07-02 16:00:02 -07:00
|
|
|
check_match(ls, '}', '{', line, col);
|
2014-09-11 02:29:48 -07:00
|
|
|
_interface_virtual_set(ls, meth);
|
2014-06-18 03:25:07 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2014-06-20 04:24:10 -07:00
|
|
|
parse_implement(Eo_Lexer *ls, Eina_Bool iface)
|
2014-06-18 03:25:07 -07:00
|
|
|
{
|
|
|
|
Eina_Strbuf *buf = NULL;
|
2014-07-10 07:23:06 -07:00
|
|
|
Eolian_Implement *impl = NULL;
|
2014-09-11 03:18:48 -07:00
|
|
|
int iline = ls->line_number, icol = ls->column;
|
2014-06-20 04:24:10 -07:00
|
|
|
if (iface)
|
2014-07-01 10:25:17 -07:00
|
|
|
check_kw(ls, KW_class);
|
2014-06-18 03:25:07 -07:00
|
|
|
if (ls->t.kw == KW_class)
|
|
|
|
{
|
|
|
|
eo_lexer_get(ls);
|
2014-06-20 02:45:55 -07:00
|
|
|
check_next(ls, '.');
|
2014-06-18 03:25:07 -07:00
|
|
|
if (ls->t.kw == KW_destructor)
|
|
|
|
{
|
2014-09-11 03:18:48 -07:00
|
|
|
ls->tmp.kls->class_dtor_enable = EINA_TRUE;
|
2014-06-18 03:25:07 -07:00
|
|
|
eo_lexer_get(ls);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
check_kw_next(ls, KW_constructor);
|
2014-09-11 03:18:48 -07:00
|
|
|
ls->tmp.kls->class_ctor_enable = EINA_TRUE;
|
2014-06-18 03:25:07 -07:00
|
|
|
}
|
|
|
|
check_next(ls, ';');
|
|
|
|
return;
|
|
|
|
}
|
2014-09-11 03:18:48 -07:00
|
|
|
impl = calloc(1, sizeof(Eolian_Implement));
|
|
|
|
impl->base.file = eina_stringshare_ref(ls->filename);
|
|
|
|
impl->base.line = iline;
|
|
|
|
impl->base.column = icol;
|
2014-09-12 05:25:26 -07:00
|
|
|
ls->tmp.kls->implements = eina_list_append(ls->tmp.kls->implements, impl);
|
2014-08-29 06:33:56 -07:00
|
|
|
switch (ls->t.kw)
|
|
|
|
{
|
|
|
|
case KW_at_virtual:
|
|
|
|
impl->is_virtual = EINA_TRUE;
|
|
|
|
eo_lexer_get(ls);
|
|
|
|
break;
|
|
|
|
case KW_at_auto:
|
|
|
|
impl->is_auto = EINA_TRUE;
|
|
|
|
eo_lexer_get(ls);
|
|
|
|
break;
|
|
|
|
case KW_at_empty:
|
|
|
|
impl->is_empty = EINA_TRUE;
|
|
|
|
eo_lexer_get(ls);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (ls->t.token == '.')
|
2014-06-18 03:25:07 -07:00
|
|
|
{
|
2014-08-29 06:33:56 -07:00
|
|
|
if (!impl->is_virtual && !impl->is_auto && !impl->is_empty)
|
|
|
|
goto fullclass;
|
2014-06-20 02:45:55 -07:00
|
|
|
check_next(ls, '.');
|
2014-06-18 03:25:07 -07:00
|
|
|
if ((ls->t.token != TOK_VALUE) || (ls->t.kw == KW_get || ls->t.kw == KW_set))
|
2014-07-01 10:25:17 -07:00
|
|
|
eo_lexer_syntax_error(ls, "name expected");
|
2014-09-01 07:53:35 -07:00
|
|
|
if (impl->is_virtual)
|
|
|
|
impl->full_name = eina_stringshare_ref(ls->t.value.s);
|
|
|
|
else
|
|
|
|
impl->full_name = eina_stringshare_printf(".%s", ls->t.value.s);
|
2014-06-18 03:25:07 -07:00
|
|
|
eo_lexer_get(ls);
|
2014-06-20 02:45:55 -07:00
|
|
|
if (ls->t.token == '.')
|
2014-06-18 03:25:07 -07:00
|
|
|
{
|
|
|
|
eo_lexer_get(ls);
|
|
|
|
if (ls->t.kw == KW_set)
|
|
|
|
{
|
2014-08-29 03:40:29 -07:00
|
|
|
impl->is_prop_set = EINA_TRUE;
|
2014-06-18 03:25:07 -07:00
|
|
|
eo_lexer_get(ls);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
check_kw_next(ls, KW_get);
|
2014-08-29 03:40:29 -07:00
|
|
|
impl->is_prop_get = EINA_TRUE;
|
2014-06-18 03:25:07 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
check_next(ls, ';');
|
|
|
|
return;
|
|
|
|
}
|
2014-08-29 06:33:56 -07:00
|
|
|
fullclass:
|
2014-06-18 03:25:07 -07:00
|
|
|
if ((ls->t.token != TOK_VALUE) || (ls->t.kw == KW_get || ls->t.kw == KW_set))
|
2014-07-01 10:25:17 -07:00
|
|
|
eo_lexer_syntax_error(ls, "class name expected");
|
2014-08-29 03:40:29 -07:00
|
|
|
buf = push_strbuf(ls);
|
2014-07-17 09:16:31 -07:00
|
|
|
eina_strbuf_append(buf, ls->t.value.s);
|
2014-06-18 03:25:07 -07:00
|
|
|
eo_lexer_get(ls);
|
2014-06-20 02:45:55 -07:00
|
|
|
check_next(ls, '.');
|
2014-06-18 03:25:07 -07:00
|
|
|
if ((ls->t.token != TOK_VALUE) || (ls->t.kw == KW_get || ls->t.kw == KW_set))
|
2014-07-01 10:25:17 -07:00
|
|
|
eo_lexer_syntax_error(ls, "name or constructor/destructor expected");
|
2014-06-18 03:25:07 -07:00
|
|
|
for (;;)
|
|
|
|
{
|
|
|
|
switch (ls->t.kw)
|
|
|
|
{
|
2014-07-01 10:25:17 -07:00
|
|
|
case KW_constructor:
|
|
|
|
case KW_destructor:
|
2014-08-29 07:06:48 -07:00
|
|
|
eina_strbuf_append_char(buf, '.');
|
|
|
|
eina_strbuf_append(buf, eo_lexer_keyword_str_get(ls->t.kw));
|
|
|
|
eo_lexer_get(ls);
|
|
|
|
goto end;
|
2014-07-01 10:25:17 -07:00
|
|
|
case KW_get:
|
2014-08-29 07:06:48 -07:00
|
|
|
impl->is_prop_get = EINA_TRUE;
|
|
|
|
eo_lexer_get(ls);
|
|
|
|
goto end;
|
2014-07-01 10:25:17 -07:00
|
|
|
case KW_set:
|
2014-08-29 07:06:48 -07:00
|
|
|
impl->is_prop_set = EINA_TRUE;
|
2014-07-01 10:25:17 -07:00
|
|
|
eo_lexer_get(ls);
|
|
|
|
goto end;
|
|
|
|
default:
|
|
|
|
break;
|
2014-06-18 03:25:07 -07:00
|
|
|
}
|
2014-08-29 07:06:48 -07:00
|
|
|
eina_strbuf_append_char(buf, '.');
|
2014-06-18 03:25:07 -07:00
|
|
|
check(ls, TOK_VALUE);
|
2014-07-17 09:16:31 -07:00
|
|
|
eina_strbuf_append(buf, ls->t.value.s);
|
2014-06-18 03:25:07 -07:00
|
|
|
eo_lexer_get(ls);
|
2014-06-20 02:45:55 -07:00
|
|
|
if (ls->t.token != '.') break;
|
2014-06-18 03:25:07 -07:00
|
|
|
eo_lexer_get(ls);
|
|
|
|
}
|
|
|
|
end:
|
|
|
|
check_next(ls, ';');
|
2014-07-10 07:23:06 -07:00
|
|
|
impl->full_name = eina_stringshare_add(eina_strbuf_string_get(buf));
|
2014-06-18 03:25:07 -07:00
|
|
|
pop_strbuf(ls);
|
|
|
|
}
|
|
|
|
|
2014-09-01 07:35:50 -07:00
|
|
|
static void
|
|
|
|
parse_constructor(Eo_Lexer *ls)
|
|
|
|
{
|
|
|
|
Eina_Strbuf *buf = NULL;
|
|
|
|
Eolian_Constructor *ctor = NULL;
|
2014-09-03 01:27:09 -07:00
|
|
|
ctor = calloc(1, sizeof(Eolian_Constructor));
|
2014-09-01 07:35:50 -07:00
|
|
|
ctor->base.file = eina_stringshare_ref(ls->filename);
|
|
|
|
ctor->base.line = ls->line_number;
|
|
|
|
ctor->base.column = ls->column;
|
2014-09-12 05:25:26 -07:00
|
|
|
ls->tmp.kls->constructors = eina_list_append(ls->tmp.kls->constructors, ctor);
|
2014-09-01 07:35:50 -07:00
|
|
|
if (ls->t.token == '.')
|
|
|
|
{
|
|
|
|
check_next(ls, '.');
|
|
|
|
if (ls->t.token != TOK_VALUE)
|
|
|
|
eo_lexer_syntax_error(ls, "name expected");
|
2014-09-11 03:18:48 -07:00
|
|
|
ctor->full_name = eina_stringshare_printf("%s.%s",
|
|
|
|
ls->tmp.kls->full_name,
|
|
|
|
ls->t.value.s);
|
2014-09-01 07:35:50 -07:00
|
|
|
eo_lexer_get(ls);
|
|
|
|
check_next(ls, ';');
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
check(ls, TOK_VALUE);
|
|
|
|
buf = push_strbuf(ls);
|
|
|
|
eina_strbuf_append(buf, ls->t.value.s);
|
|
|
|
eo_lexer_get(ls);
|
|
|
|
check_next(ls, '.');
|
|
|
|
check(ls, TOK_VALUE);
|
|
|
|
for (;;)
|
|
|
|
{
|
|
|
|
eina_strbuf_append_char(buf, '.');
|
|
|
|
check(ls, TOK_VALUE);
|
|
|
|
eina_strbuf_append(buf, ls->t.value.s);
|
|
|
|
eo_lexer_get(ls);
|
|
|
|
if (ls->t.token != '.') break;
|
|
|
|
eo_lexer_get(ls);
|
|
|
|
}
|
|
|
|
check_next(ls, ';');
|
|
|
|
ctor->full_name = eina_stringshare_add(eina_strbuf_string_get(buf));
|
|
|
|
pop_strbuf(ls);
|
|
|
|
}
|
|
|
|
|
2014-06-18 03:25:07 -07:00
|
|
|
static void
|
|
|
|
parse_event(Eo_Lexer *ls)
|
|
|
|
{
|
2014-07-10 07:31:01 -07:00
|
|
|
Eolian_Event *ev = calloc(1, sizeof(Eolian_Event));
|
2014-08-08 07:19:52 -07:00
|
|
|
ev->base.file = eina_stringshare_ref(ls->filename);
|
2014-08-04 07:01:16 -07:00
|
|
|
ev->base.line = ls->line_number;
|
|
|
|
ev->base.column = ls->column;
|
2014-07-16 06:43:40 -07:00
|
|
|
Eina_Strbuf *buf = push_strbuf(ls);
|
2014-09-12 05:25:26 -07:00
|
|
|
ls->tmp.kls->events = eina_list_append(ls->tmp.kls->events, ev);
|
2014-06-18 03:25:07 -07:00
|
|
|
check(ls, TOK_VALUE);
|
2014-07-17 09:16:31 -07:00
|
|
|
eina_strbuf_append(buf, ls->t.value.s);
|
2014-06-18 03:25:07 -07:00
|
|
|
eo_lexer_get(ls);
|
2014-07-16 06:43:40 -07:00
|
|
|
while (ls->t.token == ',')
|
|
|
|
{
|
|
|
|
eo_lexer_get(ls);
|
|
|
|
check(ls, TOK_VALUE);
|
|
|
|
eina_strbuf_append_char(buf, ',');
|
2014-07-17 09:16:31 -07:00
|
|
|
eina_strbuf_append(buf, ls->t.value.s);
|
2014-07-16 06:43:40 -07:00
|
|
|
eo_lexer_get(ls);
|
|
|
|
}
|
|
|
|
ev->name = eina_stringshare_add(eina_strbuf_string_get(buf));
|
|
|
|
pop_strbuf(ls);
|
2014-08-13 03:53:33 -07:00
|
|
|
if (ls->t.kw == KW_at_private)
|
|
|
|
{
|
|
|
|
ev->scope = EOLIAN_SCOPE_PRIVATE;
|
|
|
|
eo_lexer_get(ls);
|
|
|
|
}
|
|
|
|
else if (ls->t.kw == KW_at_protected)
|
|
|
|
{
|
|
|
|
ev->scope = EOLIAN_SCOPE_PROTECTED;
|
|
|
|
eo_lexer_get(ls);
|
|
|
|
}
|
2014-07-15 15:50:34 -07:00
|
|
|
if (ls->t.token == ':')
|
2014-06-18 03:25:07 -07:00
|
|
|
{
|
|
|
|
eo_lexer_get(ls);
|
2014-07-11 03:47:37 -07:00
|
|
|
ev->type = parse_type(ls);
|
|
|
|
pop_type(ls);
|
2014-06-18 03:25:07 -07:00
|
|
|
}
|
|
|
|
check(ls, ';');
|
2014-07-16 06:43:40 -07:00
|
|
|
eo_lexer_get(ls);
|
2014-06-18 03:25:07 -07:00
|
|
|
if (ls->t.token == TOK_COMMENT)
|
|
|
|
{
|
2014-07-17 09:16:31 -07:00
|
|
|
ev->comment = eina_stringshare_ref(ls->t.value.s);
|
2014-07-16 06:43:40 -07:00
|
|
|
eo_lexer_get(ls);
|
2014-06-18 03:25:07 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
parse_methods(Eo_Lexer *ls)
|
|
|
|
{
|
2014-09-12 05:25:26 -07:00
|
|
|
PARSE_SECTION parse_method(ls, EINA_FALSE);
|
2014-07-02 16:00:02 -07:00
|
|
|
check_match(ls, '}', '{', line, col);
|
2014-06-18 03:25:07 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
parse_properties(Eo_Lexer *ls)
|
|
|
|
{
|
2014-09-12 05:25:26 -07:00
|
|
|
PARSE_SECTION parse_property(ls);
|
2014-07-02 16:00:02 -07:00
|
|
|
check_match(ls, '}', '{', line, col);
|
2014-06-18 03:25:07 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2014-06-20 04:24:10 -07:00
|
|
|
parse_implements(Eo_Lexer *ls, Eina_Bool iface)
|
2014-06-18 03:25:07 -07:00
|
|
|
{
|
2014-09-12 05:25:26 -07:00
|
|
|
PARSE_SECTION parse_implement(ls, iface);
|
2014-07-02 16:00:02 -07:00
|
|
|
check_match(ls, '}', '{', line, col);
|
2014-06-18 03:25:07 -07:00
|
|
|
}
|
|
|
|
|
2014-09-01 07:35:50 -07:00
|
|
|
static void
|
|
|
|
parse_constructors(Eo_Lexer *ls)
|
|
|
|
{
|
2014-09-12 05:25:26 -07:00
|
|
|
PARSE_SECTION parse_constructor(ls);
|
2014-09-01 07:35:50 -07:00
|
|
|
check_match(ls, '}', '{', line, col);
|
|
|
|
}
|
|
|
|
|
2014-06-18 03:25:07 -07:00
|
|
|
static void
|
|
|
|
parse_events(Eo_Lexer *ls)
|
|
|
|
{
|
2014-07-02 16:00:02 -07:00
|
|
|
int line, col;
|
2014-06-18 03:25:07 -07:00
|
|
|
eo_lexer_get(ls);
|
|
|
|
line = ls->line_number;
|
2014-07-02 16:00:02 -07:00
|
|
|
col = ls->column;
|
2014-06-18 03:25:07 -07:00
|
|
|
check(ls, '{');
|
2014-07-16 06:43:40 -07:00
|
|
|
eo_lexer_get(ls);
|
2014-06-18 03:25:07 -07:00
|
|
|
while (ls->t.token != '}')
|
2014-09-12 05:25:26 -07:00
|
|
|
parse_event(ls);
|
2014-07-02 16:00:02 -07:00
|
|
|
check_match(ls, '}', '{', line, col);
|
2014-06-18 03:25:07 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2014-08-27 07:38:28 -07:00
|
|
|
parse_class_body(Eo_Lexer *ls, Eolian_Class_Type type)
|
2014-06-18 03:25:07 -07:00
|
|
|
{
|
|
|
|
Eina_Bool has_legacy_prefix = EINA_FALSE,
|
|
|
|
has_eo_prefix = EINA_FALSE,
|
|
|
|
has_data = EINA_FALSE,
|
|
|
|
has_properties = EINA_FALSE,
|
|
|
|
has_methods = EINA_FALSE,
|
|
|
|
has_implements = EINA_FALSE,
|
2014-09-01 07:35:50 -07:00
|
|
|
has_constructors = EINA_FALSE,
|
2014-06-18 03:25:07 -07:00
|
|
|
has_events = EINA_FALSE;
|
|
|
|
if (ls->t.token == TOK_COMMENT)
|
|
|
|
{
|
2014-09-11 02:37:41 -07:00
|
|
|
ls->tmp.kls->description = eina_stringshare_ref(ls->t.value.s);
|
2014-06-18 03:25:07 -07:00
|
|
|
eo_lexer_get(ls);
|
|
|
|
}
|
2014-07-18 09:29:25 -07:00
|
|
|
if (type == EOLIAN_CLASS_INTERFACE)
|
|
|
|
{
|
|
|
|
ls->tmp.kls->data_type = eina_stringshare_add("null");
|
|
|
|
}
|
2014-07-01 10:25:17 -07:00
|
|
|
for (;;) switch (ls->t.kw)
|
2014-06-18 03:25:07 -07:00
|
|
|
{
|
2014-07-01 10:25:17 -07:00
|
|
|
case KW_legacy_prefix:
|
|
|
|
CASE_LOCK(ls, legacy_prefix, "legacy prefix definition")
|
|
|
|
eo_lexer_get(ls);
|
|
|
|
check_next(ls, ':');
|
|
|
|
check(ls, TOK_VALUE);
|
2014-07-17 09:16:31 -07:00
|
|
|
ls->tmp.kls->legacy_prefix = eina_stringshare_ref(ls->t.value.s);
|
2014-07-01 10:25:17 -07:00
|
|
|
eo_lexer_get(ls);
|
|
|
|
check_next(ls, ';');
|
|
|
|
break;
|
|
|
|
case KW_eo_prefix:
|
|
|
|
CASE_LOCK(ls, eo_prefix, "eo prefix definition")
|
|
|
|
eo_lexer_get(ls);
|
|
|
|
check_next(ls, ':');
|
|
|
|
check(ls, TOK_VALUE);
|
2014-07-17 09:16:31 -07:00
|
|
|
ls->tmp.kls->eo_prefix = eina_stringshare_ref(ls->t.value.s);
|
2014-07-01 10:25:17 -07:00
|
|
|
eo_lexer_get(ls);
|
|
|
|
check_next(ls, ';');
|
|
|
|
break;
|
|
|
|
case KW_data:
|
2014-07-18 09:29:25 -07:00
|
|
|
if (type == EOLIAN_CLASS_INTERFACE) return;
|
2014-07-01 10:25:17 -07:00
|
|
|
CASE_LOCK(ls, data, "data definition")
|
|
|
|
eo_lexer_get(ls);
|
2014-07-16 07:33:11 -07:00
|
|
|
check_next(ls, ':');
|
|
|
|
check(ls, TOK_VALUE);
|
2014-07-17 09:16:31 -07:00
|
|
|
ls->tmp.kls->data_type = eina_stringshare_ref(ls->t.value.s);
|
2014-07-01 10:25:17 -07:00
|
|
|
eo_lexer_get(ls);
|
|
|
|
check_next(ls, ';');
|
|
|
|
break;
|
|
|
|
case KW_properties:
|
|
|
|
CASE_LOCK(ls, properties, "properties definition")
|
|
|
|
parse_properties(ls);
|
|
|
|
break;
|
|
|
|
case KW_methods:
|
|
|
|
CASE_LOCK(ls, methods, "methods definition")
|
|
|
|
parse_methods(ls);
|
|
|
|
break;
|
|
|
|
case KW_implements:
|
|
|
|
CASE_LOCK(ls, implements, "implements definition")
|
|
|
|
parse_implements(ls, type == EOLIAN_CLASS_INTERFACE);
|
|
|
|
break;
|
2014-09-01 07:35:50 -07:00
|
|
|
case KW_constructors:
|
|
|
|
if (type == EOLIAN_CLASS_INTERFACE || type == EOLIAN_CLASS_MIXIN)
|
|
|
|
return;
|
|
|
|
CASE_LOCK(ls, constructors, "constructors definition")
|
|
|
|
parse_constructors(ls);
|
|
|
|
break;
|
2014-07-01 10:25:17 -07:00
|
|
|
case KW_events:
|
|
|
|
CASE_LOCK(ls, events, "events definition")
|
|
|
|
parse_events(ls);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
return;
|
2014-06-18 03:25:07 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2014-08-27 07:38:28 -07:00
|
|
|
parse_class(Eo_Lexer *ls, Eolian_Class_Type type)
|
2014-06-18 03:25:07 -07:00
|
|
|
{
|
2014-07-30 03:57:11 -07:00
|
|
|
const char *bnm;
|
|
|
|
char *fnm;
|
|
|
|
Eina_Bool same;
|
2014-07-02 16:00:02 -07:00
|
|
|
int line, col;
|
2014-06-18 03:25:07 -07:00
|
|
|
Eina_Strbuf *buf = push_strbuf(ls);
|
2014-09-11 02:50:48 -07:00
|
|
|
ls->tmp.kls = calloc(1, sizeof(Eolian_Class));
|
2014-08-08 07:19:52 -07:00
|
|
|
ls->tmp.kls->base.file = eina_stringshare_ref(ls->filename);
|
2014-08-04 07:01:16 -07:00
|
|
|
ls->tmp.kls->base.line = ls->line_number;
|
|
|
|
ls->tmp.kls->base.column = ls->column;
|
2014-06-18 03:25:07 -07:00
|
|
|
eo_lexer_get(ls);
|
|
|
|
ls->tmp.kls->type = type;
|
2014-07-30 07:51:08 -07:00
|
|
|
eo_lexer_context_push(ls);
|
2014-06-18 03:25:07 -07:00
|
|
|
parse_name(ls, buf);
|
2014-08-08 07:19:52 -07:00
|
|
|
bnm = eina_stringshare_ref(ls->filename);
|
2014-07-30 03:57:11 -07:00
|
|
|
fnm = database_class_to_filename(eina_strbuf_string_get(buf));
|
2014-08-01 05:59:46 -07:00
|
|
|
same = compare_class_file(bnm, fnm);
|
2014-07-30 03:57:11 -07:00
|
|
|
eina_stringshare_del(bnm);
|
|
|
|
free(fnm);
|
|
|
|
if (!same)
|
2014-07-30 07:51:08 -07:00
|
|
|
{
|
|
|
|
eo_lexer_context_restore(ls);
|
|
|
|
eo_lexer_syntax_error(ls, "class and file names differ");
|
|
|
|
}
|
|
|
|
eo_lexer_context_pop(ls);
|
2014-09-11 02:58:09 -07:00
|
|
|
_fill_class_name(ls->tmp.kls, eina_stringshare_add(eina_strbuf_string_get
|
|
|
|
(buf)));
|
2014-06-18 03:25:07 -07:00
|
|
|
pop_strbuf(ls);
|
2014-06-19 08:30:18 -07:00
|
|
|
if (ls->t.token != '{')
|
2014-06-18 03:25:07 -07:00
|
|
|
{
|
2014-06-19 08:30:18 -07:00
|
|
|
line = ls->line_number;
|
2014-07-02 16:00:02 -07:00
|
|
|
col = ls->column;
|
2014-06-19 08:30:18 -07:00
|
|
|
check_next(ls, '(');
|
|
|
|
if (ls->t.token != ')')
|
|
|
|
{
|
|
|
|
ls->tmp.kls->inherits = parse_name_list(ls);
|
|
|
|
ls->tmp.str_items = NULL;
|
|
|
|
}
|
2014-07-02 16:00:02 -07:00
|
|
|
check_match(ls, ')', '(', line, col);
|
2014-06-18 03:25:07 -07:00
|
|
|
}
|
|
|
|
line = ls->line_number;
|
2014-07-02 16:00:02 -07:00
|
|
|
col = ls->column;
|
2014-06-18 03:25:07 -07:00
|
|
|
check_next(ls, '{');
|
2014-08-27 07:38:28 -07:00
|
|
|
parse_class_body(ls, type);
|
2014-07-02 16:00:02 -07:00
|
|
|
check_match(ls, '}', '{', line, col);
|
2014-06-18 03:25:07 -07:00
|
|
|
}
|
|
|
|
|
2014-07-30 03:57:11 -07:00
|
|
|
static Eina_Bool
|
2014-06-24 05:45:51 -07:00
|
|
|
parse_unit(Eo_Lexer *ls, Eina_Bool eot)
|
2014-06-18 03:25:07 -07:00
|
|
|
{
|
|
|
|
switch (ls->t.kw)
|
|
|
|
{
|
2014-07-01 10:25:17 -07:00
|
|
|
case KW_abstract:
|
|
|
|
if (eot) goto def;
|
2014-08-27 07:38:28 -07:00
|
|
|
parse_class(ls, EOLIAN_CLASS_ABSTRACT);
|
2014-07-01 10:25:17 -07:00
|
|
|
goto found_class;
|
|
|
|
case KW_class:
|
|
|
|
if (eot) goto def;
|
2014-08-27 07:38:28 -07:00
|
|
|
parse_class(ls, EOLIAN_CLASS_REGULAR);
|
2014-07-01 10:25:17 -07:00
|
|
|
goto found_class;
|
|
|
|
case KW_mixin:
|
|
|
|
if (eot) goto def;
|
2014-08-27 07:38:28 -07:00
|
|
|
parse_class(ls, EOLIAN_CLASS_MIXIN);
|
2014-07-01 10:25:17 -07:00
|
|
|
goto found_class;
|
|
|
|
case KW_interface:
|
|
|
|
if (eot) goto def;
|
2014-08-27 07:38:28 -07:00
|
|
|
parse_class(ls, EOLIAN_CLASS_INTERFACE);
|
2014-07-01 10:25:17 -07:00
|
|
|
goto found_class;
|
|
|
|
case KW_type:
|
|
|
|
{
|
2014-07-21 08:53:25 -07:00
|
|
|
database_type_add(parse_typedef(ls));
|
|
|
|
pop_type(ls);
|
2014-06-20 06:38:57 -07:00
|
|
|
break;
|
2014-07-01 10:25:17 -07:00
|
|
|
}
|
2014-08-08 07:57:39 -07:00
|
|
|
case KW_const:
|
|
|
|
case KW_var:
|
|
|
|
{
|
|
|
|
database_var_add(parse_variable(ls, ls->t.kw == KW_var));
|
2014-09-12 07:01:10 -07:00
|
|
|
ls->tmp.var = NULL;
|
2014-08-08 07:57:39 -07:00
|
|
|
break;
|
|
|
|
}
|
2014-07-08 07:02:36 -07:00
|
|
|
case KW_struct:
|
2014-08-11 06:56:50 -07:00
|
|
|
case KW_enum:
|
2014-07-08 07:02:36 -07:00
|
|
|
{
|
2014-08-11 06:56:50 -07:00
|
|
|
Eina_Bool is_enum = (ls->t.kw == KW_enum);
|
2014-07-08 07:44:42 -07:00
|
|
|
const char *name;
|
2014-07-22 07:27:11 -07:00
|
|
|
int line, col;
|
2014-07-22 06:48:08 -07:00
|
|
|
Eolian_Type *tp;
|
2014-08-19 07:55:31 -07:00
|
|
|
Eina_Bool has_extern;
|
|
|
|
const char *freefunc;
|
2014-07-21 07:11:19 -07:00
|
|
|
Eina_Strbuf *buf;
|
2014-07-08 07:02:36 -07:00
|
|
|
eo_lexer_get(ls);
|
2014-08-19 07:55:31 -07:00
|
|
|
parse_struct_attrs(ls, is_enum, EINA_TRUE, &has_extern, &freefunc);
|
2014-07-21 07:11:19 -07:00
|
|
|
buf = push_strbuf(ls);
|
2014-07-22 07:27:11 -07:00
|
|
|
eo_lexer_context_push(ls);
|
2014-07-21 08:53:25 -07:00
|
|
|
line = ls->line_number;
|
|
|
|
col = ls->column;
|
2014-07-21 07:11:19 -07:00
|
|
|
parse_name(ls, buf);
|
2014-07-22 06:48:08 -07:00
|
|
|
name = eina_stringshare_add(eina_strbuf_string_get(buf));
|
2014-08-11 06:56:50 -07:00
|
|
|
tp = (Eolian_Type*)eina_hash_find(is_enum ? _enums
|
|
|
|
: _structs, name);
|
2014-07-22 06:48:08 -07:00
|
|
|
if (tp)
|
2014-07-21 08:53:25 -07:00
|
|
|
{
|
2014-07-22 06:48:08 -07:00
|
|
|
eina_stringshare_del(name);
|
2014-07-22 07:27:11 -07:00
|
|
|
eo_lexer_context_restore(ls);
|
2014-08-11 06:56:50 -07:00
|
|
|
redef_error(ls, is_enum ? EOLIAN_TYPE_ENUM
|
|
|
|
: EOLIAN_TYPE_STRUCT, tp);
|
2014-07-21 08:53:25 -07:00
|
|
|
}
|
2014-07-22 07:27:11 -07:00
|
|
|
eo_lexer_context_pop(ls);
|
2014-07-21 07:11:19 -07:00
|
|
|
pop_strbuf(ls);
|
2014-08-13 08:43:18 -07:00
|
|
|
if (ls->t.token == ';')
|
|
|
|
{
|
|
|
|
Eolian_Type *def = push_type(ls);
|
2014-08-19 07:55:31 -07:00
|
|
|
def->is_extern = has_extern;
|
2014-08-13 08:43:18 -07:00
|
|
|
def->type = EOLIAN_TYPE_STRUCT_OPAQUE;
|
2014-08-19 07:55:31 -07:00
|
|
|
def->freefunc = freefunc;
|
2014-08-19 08:37:29 -07:00
|
|
|
pop_str(ls);
|
2014-08-13 08:43:18 -07:00
|
|
|
_fill_type_name(def, name);
|
|
|
|
eo_lexer_get(ls);
|
|
|
|
if (ls->t.token == TOK_COMMENT)
|
|
|
|
{
|
|
|
|
def->comment = eina_stringshare_ref(ls->t.value.s);
|
|
|
|
eo_lexer_get(ls);
|
|
|
|
}
|
|
|
|
def->base.file = eina_stringshare_ref(ls->filename);
|
|
|
|
def->base.line = line;
|
|
|
|
def->base.column = col;
|
|
|
|
database_struct_add(def);
|
|
|
|
pop_type(ls);
|
|
|
|
break;
|
|
|
|
}
|
2014-08-11 06:56:50 -07:00
|
|
|
if (is_enum)
|
2014-08-19 07:55:31 -07:00
|
|
|
parse_enum(ls, name, has_extern, line, col);
|
2014-08-11 06:56:50 -07:00
|
|
|
else
|
2014-08-19 07:55:31 -07:00
|
|
|
parse_struct(ls, name, has_extern, line, col, freefunc);
|
2014-07-09 03:18:21 -07:00
|
|
|
pop_type(ls);
|
2014-07-08 17:31:49 -07:00
|
|
|
break;
|
2014-07-08 07:02:36 -07:00
|
|
|
}
|
2014-07-01 10:25:17 -07:00
|
|
|
def:
|
|
|
|
default:
|
|
|
|
eo_lexer_syntax_error(ls, "invalid token");
|
|
|
|
break;
|
2014-06-18 03:25:07 -07:00
|
|
|
}
|
2014-07-30 03:57:11 -07:00
|
|
|
return EINA_FALSE;
|
2014-06-20 06:38:57 -07:00
|
|
|
found_class:
|
2014-09-11 03:48:38 -07:00
|
|
|
ls->tmp.classes = eina_list_append(ls->tmp.classes, ls->tmp.kls);
|
2014-06-20 06:38:57 -07:00
|
|
|
ls->tmp.kls = NULL;
|
2014-07-30 03:57:11 -07:00
|
|
|
return EINA_TRUE;
|
2014-06-18 03:25:07 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2014-06-24 05:45:51 -07:00
|
|
|
parse_chunk(Eo_Lexer *ls, Eina_Bool eot)
|
2014-06-18 03:25:07 -07:00
|
|
|
{
|
2014-07-16 08:06:04 -07:00
|
|
|
while (ls->t.token >= 0)
|
2014-07-30 03:57:11 -07:00
|
|
|
/* set eot to EINA_TRUE so that we only allow parsing of one class */
|
|
|
|
if (parse_unit(ls, eot))
|
|
|
|
eot = EINA_TRUE;
|
2014-06-18 03:25:07 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
Eina_Bool
|
2014-06-24 05:45:51 -07:00
|
|
|
eo_parser_walk(Eo_Lexer *ls, Eina_Bool eot)
|
2014-06-18 03:25:07 -07:00
|
|
|
{
|
2014-06-19 04:02:46 -07:00
|
|
|
if (!setjmp(ls->err_jmp))
|
2014-06-18 03:25:07 -07:00
|
|
|
{
|
2014-06-24 05:45:51 -07:00
|
|
|
parse_chunk(ls, eot);
|
2014-06-18 03:25:07 -07:00
|
|
|
return EINA_TRUE;
|
|
|
|
}
|
|
|
|
return EINA_FALSE;
|
|
|
|
}
|
|
|
|
|