Commit e02ea2ef authored by Guillaume Charifi's avatar Guillaume Charifi

compiler/parser: Parse class.

parent bcc1c808
......@@ -1488,6 +1488,133 @@ failed:
return -1;
}
static int class_dtor(struct bm_ast_node *node)
{
destroy_type(&node->data.as_class.type);
return 0;
}
static int class_debug_data(const struct bm_ast_node *node, int indent_lvl)
{
const struct bm_ast_node_data_class *data = &node->data.as_class;
wprintf(L",\n%*ls\"class_type\": \"", indent_lvl * 2, L"");
debug_type(&data->type);
wprintf(L"\",\n%*ls\"annotations\": ", indent_lvl * 2, L"");
debug_annotation_mask(data->annotations, indent_lvl);
wprintf(L",\n%*ls\"visibility\": \"%ls\"", indent_lvl * 2, L"", debug_visibility(data->visibility));
return 0;
}
static int parse_class(struct parser_ctx *ctx, unsigned long *cur_tok_id)
{
int result;
unsigned long i = *cur_tok_id;
struct bm_ast_node nclass;
struct bm_ast_node props;
struct bm_ast_node methods;
parser_node_init(&nclass, BM_AST_NODE_CLASS);
nclass.dtor = class_dtor;
nclass.debug_data = class_debug_data;
parser_node_init_unknown(&props);
parser_node_init_unknown(&methods);
nclass.data.as_class.annotations = ctx->cur_annotations;
nclass.data.as_class.visibility = parser_visibility_from_token_type(ctx->in->tokens[i].type);
if (nclass.data.as_class.visibility == BM_AST_VISIBILITY_INVAL)
goto failed;
i++;
if (ctx->in->tokens[i].type != BM_TOK_CLASS)
goto failed;
i++;
result = parse_type(ctx, &i, &nclass.data.as_class.type);
if (result < 0)
goto failed;
if (buffer_get_line_count(&nclass.data.as_class.type.class_path.seqs) > 0)
goto failed;
parser_ignore_newlines(ctx, &i);
if (ctx->in->tokens[i].type != BM_TOK_CURLY_BRACKET_OPEN)
goto failed;
i++;
parser_ignore_newlines_or_semicolons(ctx, &i);
while (i < ctx->in->nb_tokens)
{
unsigned long i_backup = i;
struct bm_ast_node prop;
result = parse_prop(ctx, &i, &prop);
if (result < 0)
break;
if (ctx->in->tokens[i].type != BM_TOK_NEWLINE
&& ctx->in->tokens[i].type != BM_TOK_SEMICOLON
&& ctx->in->tokens[i].type != BM_TOK_CURLY_BRACKET_CLOSE)
{
parser_node_destroy(&prop);
i = i_backup;
break;
}
parser_node_append_child(&props, &prop);
if (ctx->in->tokens[i].type == BM_TOK_CURLY_BRACKET_CLOSE)
break;
i++;
parser_ignore_newlines_or_semicolons(ctx, &i);
}
while (i < ctx->in->nb_tokens)
{
struct bm_ast_node method;
result = parse_method(ctx, &i, &method, &nclass.data.as_class.type);
if (result < 0)
break;
parser_node_append_child(&methods, &method);
if (ctx->in->tokens[i].type != BM_TOK_NEWLINE
&& ctx->in->tokens[i].type != BM_TOK_SEMICOLON)
break;
i++;
parser_ignore_newlines_or_semicolons(ctx, &i);
}
if (ctx->in->tokens[i].type != BM_TOK_CURLY_BRACKET_CLOSE)
goto failed;
i++;
parser_node_set_child(&nclass, BM_AST_NODE_CLASS_CHILD_PROPS, &props);
parser_node_set_child(&nclass, BM_AST_NODE_CLASS_CHILD_METHODS, &methods);
parser_node_append_child(&ctx->ast.classes, &nclass);
ctx->cur_annotations = 0;
*cur_tok_id = i;
return 0;
failed:
parser_node_destroy(&props);
parser_node_destroy(&methods);
parser_node_destroy(&nclass);
return -1;
}
static int proto_dtor(struct bm_ast_node *node)
{
destroy_decl_func(&node->data.as_proto.decl);
......@@ -1689,11 +1816,11 @@ int parser(struct lexer_output *in, struct bm_ast *out)
#if 0
result = parse_cenum(&ctx);
#endif
/* Must also handle abstract and final */
if (result < 0)
result = parse_class(&ctx);
result = parse_class(&ctx, &cur_tok_id);
#if 0
if (result < 0)
result = parse_enum(&ctx);
#endif
......@@ -1748,6 +1875,10 @@ int parser_debug_ast(struct bm_ast *ast)
parser_node_debug(&ast->aliases, 1);
wprintf(L",\n");
wprintf(L" \"classes\": ");
parser_node_debug(&ast->classes, 1);
wprintf(L",\n");
wprintf(L" \"funcs\": ");
parser_node_debug(&ast->funcs, 1);
wprintf(L",\n");
......@@ -1764,6 +1895,7 @@ int parser_debug_ast(struct bm_ast *ast)
int parser_destroy(struct bm_ast *ast)
{
parser_node_destroy(&ast->aliases);
parser_node_destroy(&ast->classes);
parser_node_destroy(&ast->funcs);
parser_node_destroy(&ast->interfaces);
parser_node_destroy(&ast->package);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment