#include "parse.h" #include #include #include #include struct constpool_parser_state { struct parser_state s_base; unsigned int s_prev_token; enum ivy_assembler_pval_type s_current_pval_type; union { struct ivy_selector *sel; struct ivy_ident *ident; struct ivy_asm_token *tok; } s_current_pval_val; bool s_current_index_set; unsigned int s_current_index; }; static enum ivy_status parse_linefeed(struct ivy_asm_parser *ctx, struct ivy_asm_token *tok) { struct constpool_parser_state *state = (struct constpool_parser_state *)asm_parser_get_state(ctx); struct ivy_bin_constpool_table_entry entry = {0}; state->s_prev_token = IVY_ASM_TOK_LINEFEED; if (!state->s_current_index_set) { /* no index set */ return IVY_OK; } struct ivy_asm_token *tmp = NULL; switch (state->s_current_pval_type) { case IVY_ASM_PVAL_IDENT: entry.e_type = b_i32_htob(IVY_CONSTPOOL_TABLE_IDENT); entry.e_ex_handle = b_i32_htob(ivy_assembler_put_pval(ctx->p_assembler, IVY_ASM_PVAL_IDENT, state->s_current_index, state->s_base.s_previous_value)); ivy_ident_destroy(state->s_base.s_previous_value); break; case IVY_ASM_PVAL_ATOM: tmp = state->s_base.s_previous_value; entry.e_type = b_i32_htob(IVY_CONSTPOOL_TABLE_ATOM); entry.e_ex_handle = b_i32_htob(ivy_assembler_put_pval(ctx->p_assembler, IVY_ASM_PVAL_ATOM, state->s_current_index, tmp->t_str)); ivy_asm_token_destroy(tmp); break; case IVY_ASM_PVAL_SINT: entry.e_type = b_i32_htob(IVY_CONSTPOOL_TABLE_INT); entry.e_int = b_i32_htob(state->s_current_pval_val.tok->t_int.v); break; case IVY_ASM_PVAL_UINT: entry.e_type = b_i32_htob(IVY_CONSTPOOL_TABLE_UINT); entry.e_int = b_i32_htob(state->s_current_pval_val.tok->t_int.uv); break; case IVY_ASM_PVAL_SELECTOR: entry.e_type = b_i32_htob(IVY_CONSTPOOL_TABLE_SELECTOR); entry.e_ex_handle = b_i32_htob(ivy_assembler_put_pval(ctx->p_assembler, IVY_ASM_PVAL_SELECTOR, state->s_current_index, state->s_base.s_previous_value)); ivy_selector_destroy(state->s_base.s_previous_value); break; case IVY_ASM_PVAL_STRING: tmp = state->s_current_pval_val.tok; entry.e_type = b_i32_htob(IVY_CONSTPOOL_TABLE_STRING); entry.e_ex_handle = b_i32_htob(ivy_assembler_put_pval(ctx->p_assembler, IVY_ASM_PVAL_STRING, state->s_current_index, tmp->t_str)); ivy_asm_token_destroy(tmp); break; default: return IVY_ERR_BAD_SYNTAX; } state->s_current_index = 0; state->s_current_index_set = false; state->s_current_pval_type = IVY_ASM_PVAL_NONE; state->s_base.s_previous_value = NULL; return IVY_OK; } static enum ivy_status parse_int( struct ivy_asm_parser *ctx, struct ivy_asm_token *tok) { struct constpool_parser_state *state = (struct constpool_parser_state *)asm_parser_get_state(ctx); if (state->s_prev_token == IVY_ASM_SYM_COLON) { /* this is a const value. */ state->s_current_pval_type = IVY_ASM_PVAL_UINT; state->s_current_pval_val.tok = tok; state->s_prev_token = IVY_ASM_TOK_INT; return IVY_OK; } if (!state->s_current_index_set) { state->s_current_index = tok->t_int.uv; state->s_current_index_set = true; state->s_prev_token = IVY_ASM_TOK_INT; return IVY_OK; } /* not sure what this is but we aren't expecting it. */ return IVY_ERR_BAD_SYNTAX; } static enum ivy_status parse_colon( struct ivy_asm_parser *ctx, struct ivy_asm_token *tok) { struct constpool_parser_state *state = (struct constpool_parser_state *)asm_parser_get_state(ctx); if (state->s_prev_token != IVY_ASM_TOK_INT) { /* not expected at this time */ return IVY_ERR_BAD_SYNTAX; } state->s_prev_token = IVY_ASM_SYM_COLON; return IVY_OK; } static enum ivy_status parse_string( struct ivy_asm_parser *ctx, struct ivy_asm_token *tok) { struct constpool_parser_state *state = (struct constpool_parser_state *)asm_parser_get_state(ctx); if (state->s_prev_token != IVY_ASM_SYM_COLON) { return IVY_ERR_BAD_SYNTAX; } state->s_current_pval_type = IVY_ASM_PVAL_STRING; state->s_current_pval_val.tok = tok; state->s_prev_token = IVY_ASM_TOK_STRING; return IVY_OK; } static enum ivy_status parse_atom( struct ivy_asm_parser *ctx, struct ivy_asm_token *tok) { struct constpool_parser_state *state = (struct constpool_parser_state *)asm_parser_get_state(ctx); if (state->s_prev_token != IVY_ASM_SYM_COLON) { return IVY_ERR_BAD_SYNTAX; } state->s_current_pval_type = IVY_ASM_PVAL_ATOM; state->s_current_pval_val.tok = tok; state->s_prev_token = IVY_ASM_KW_ATOM; return IVY_OK; } static enum ivy_status parse_kw_ident( struct ivy_asm_parser *ctx, struct ivy_asm_token *tok) { struct constpool_parser_state *state = (struct constpool_parser_state *)asm_parser_get_state(ctx); if (state->s_prev_token != IVY_ASM_SYM_COLON) { return IVY_ERR_BAD_SYNTAX; } state->s_current_pval_type = IVY_ASM_PVAL_IDENT; state->s_current_pval_val.tok = tok; state->s_prev_token = IVY_ASM_KW_IDENT; return IVY_OK; } static enum ivy_status parse_selector( struct ivy_asm_parser *ctx, struct ivy_asm_token *tok) { struct constpool_parser_state *state = (struct constpool_parser_state *)asm_parser_get_state(ctx); if (state->s_prev_token != IVY_ASM_SYM_COLON) { return IVY_ERR_BAD_SYNTAX; } state->s_current_pval_type = IVY_ASM_PVAL_SELECTOR; state->s_prev_token = IVY_ASM_KW_SELECTOR; return IVY_OK; } static enum ivy_status parse_end( struct ivy_asm_parser *ctx, struct ivy_asm_token *tok) { struct constpool_parser_state *state = (struct constpool_parser_state *)asm_parser_get_state(ctx); if (state->s_current_index_set) { return IVY_ERR_BAD_SYNTAX; } asm_parser_pop_state(ctx, NULL); return IVY_OK; } static enum ivy_status parse_left_paren( struct ivy_asm_parser *ctx, struct ivy_asm_token *tok) { struct constpool_parser_state *state = (struct constpool_parser_state *)asm_parser_get_state(ctx); switch (state->s_prev_token) { case IVY_ASM_KW_SELECTOR: asm_parser_push_state(ctx, ASM_PARSER_SELECTOR); break; case IVY_ASM_KW_IDENT: asm_parser_push_state(ctx, ASM_PARSER_IDENT); break; case IVY_ASM_KW_ATOM: asm_parser_push_state(ctx, ASM_PARSER_ATOM); break; default: return IVY_ERR_BAD_SYNTAX; } return IVY_OK; } static void init_state(struct ivy_asm_parser *ctx, struct parser_state *state) { ivy_assembler_begin_scope(ctx->p_assembler, IVY_ASM_SCOPE_CONSTPOOL, NULL); } static void finish_state(struct ivy_asm_parser *ctx, struct parser_state *state) { ivy_assembler_end_scope(ctx->p_assembler); } struct parser_state_type constpool_parser_state_type = { .n_init_state = init_state, .n_finish_state = finish_state, .n_state_size = sizeof(struct constpool_parser_state), .n_token_parsers = { TOK_PARSER(INT, parse_int), TOK_PARSER(STRING, parse_string), TOK_PARSER(LINEFEED, parse_linefeed), }, .n_symbol_parsers = { SYM_PARSER(COLON, parse_colon), SYM_PARSER(LEFT_PAREN, parse_left_paren), }, .n_keyword_parsers = { KW_PARSER(IDENT, parse_kw_ident), KW_PARSER(SELECTOR, parse_selector), KW_PARSER(ATOM, parse_atom), KW_PARSER(END, parse_end), } };