diff --git a/mie/include/mie/parse/parse.h b/mie/include/mie/parse/parse.h index e4d219d..b433c54 100644 --- a/mie/include/mie/parse/parse.h +++ b/mie/include/mie/parse/parse.h @@ -22,6 +22,7 @@ struct mie_op_arg; struct mie_op_attribute; struct mie_op_successor; struct mie_register; +struct mie_value; MIE_API struct mie_parser *mie_parser_create( struct mie_ctx *ctx, struct mie_lex *lex); @@ -38,6 +39,10 @@ MIE_API bool mie_parser_check_type(struct mie_parser *ctx, enum mie_token_type t MIE_API bool mie_parser_check_symbol( struct mie_parser *ctx, enum mie_token_symbol sym); +MIE_API bool mie_parser_parse_int( + struct mie_parser *ctx, long long *out, struct mie_file_span *loc); +MIE_API bool mie_parser_parse_float( + struct mie_parser *ctx, double *out, struct mie_file_span *loc); MIE_API bool mie_parser_parse_word( struct mie_parser *ctx, b_string *out, struct mie_file_span *loc); MIE_API bool mie_parser_parse_instname( @@ -61,6 +66,7 @@ MIE_API bool mie_parser_parse_string( MIE_API bool mie_parser_parse_keyword(struct mie_parser *ctx, const char *kw); MIE_API bool mie_parser_parse_symbol( struct mie_parser *ctx, enum mie_token_symbol sym); +MIE_API bool mie_parser_parse_linefeed(struct mie_parser *ctx); MIE_API bool mie_parser_parse_type( struct mie_parser *ctx, const struct mie_type **out); @@ -74,6 +80,11 @@ MIE_API bool mie_parser_parse_operand( MIE_API bool mie_parser_parse_operand_list( struct mie_parser *ctx, MIE_VECTOR_REF_PARAM(struct mie_op_arg, out)); +MIE_API bool mie_parser_parse_parameter( + struct mie_parser *ctx, struct mie_op_arg *out); +MIE_API bool mie_parser_parse_parameter_list( + struct mie_parser *ctx, MIE_VECTOR_REF_PARAM(struct mie_op_arg, out)); + MIE_API bool mie_parser_parse_unknown_keyword(struct mie_parser *ctx, b_string *out); MIE_API bool mie_parser_parse_unknown_symbol( struct mie_parser *ctx, enum mie_token_symbol sym); @@ -89,6 +100,12 @@ MIE_API bool mie_parser_parse_region( struct mie_parser *ctx, struct mie_region *region); MIE_API bool mie_parser_parse_region_list( struct mie_parser *ctx, MIE_VECTOR_REF_PARAM(struct mie_region, out)); +MIE_API bool mie_parser_parse_anonymous_block( + struct mie_parser *ctx, struct mie_name_map *names, + struct mie_block *block); +MIE_API bool mie_parser_parse_block( + struct mie_parser *ctx, struct mie_name_map *names, + struct mie_block *block); MIE_API bool mie_parser_parse_attribute( struct mie_parser *ctx, struct mie_op_attribute *attrib); @@ -103,5 +120,6 @@ MIE_API bool mie_parser_parse_successor_list( MIE_API bool mie_parser_parse_module(struct mie_parser *ctx, struct mie_module *mod); MIE_API bool mie_parser_parse_op( struct mie_parser *ctx, struct mie_name_map *names, struct mie_op *dest); +MIE_API bool mie_parser_parse_value(struct mie_parser *ctx, struct mie_value **dest); #endif diff --git a/mie/include/mie/parse/token.h b/mie/include/mie/parse/token.h index 9d82b41..5fec578 100644 --- a/mie/include/mie/parse/token.h +++ b/mie/include/mie/parse/token.h @@ -14,7 +14,7 @@ enum mie_token_type { MIE_TOK_NONE = 0, MIE_TOK_LINEFEED = 0x0001u, MIE_TOK_INT = 0x0002u, - MIE_TOK_DOUBLE = 0x0004u, + MIE_TOK_FLOAT = 0x0004u, MIE_TOK_SYMBOL = 0x0008u, MIE_TOK_STRING = 0x0010u, /* single words, not dot-delimited */ @@ -42,7 +42,7 @@ enum mie_token_type { enum mie_token_value_type { MIE_TOK_V_NONE = 0, MIE_TOK_V_INT, - MIE_TOK_V_DOUBLE, + MIE_TOK_V_FLOAT, MIE_TOK_V_STRING, MIE_TOK_V_SYMBOL, }; @@ -83,7 +83,7 @@ struct mie_token { char *tok_str; enum mie_token_symbol tok_sym; long long tok_int; - double tok_double; + double tok_float; }; }; diff --git a/mie/parse/lex.c b/mie/parse/lex.c index 858d686..734d3bc 100644 --- a/mie/parse/lex.c +++ b/mie/parse/lex.c @@ -404,7 +404,7 @@ static enum mie_status push_int(struct mie_lex *lex, unsigned long long v) return push_token(lex, tok); } -static enum mie_status push_double(struct mie_lex *lex, double v) +static enum mie_status push_float(struct mie_lex *lex, double v) { struct mie_token *tok = malloc(sizeof *tok); if (!tok) { @@ -413,9 +413,9 @@ static enum mie_status push_double(struct mie_lex *lex, double v) memset(tok, 0x0, sizeof *tok); - tok->tok_type = MIE_TOK_DOUBLE; - tok->tok_value_type = MIE_TOK_V_DOUBLE; - tok->tok_double = v; + tok->tok_type = MIE_TOK_FLOAT; + tok->tok_value_type = MIE_TOK_V_FLOAT; + tok->tok_float = v; return push_token(lex, tok); } @@ -541,7 +541,7 @@ static enum mie_status read_number(struct mie_lex *lex, bool negate) v *= -1; } - return push_double(lex, v); + return push_float(lex, v); } else { unsigned long long v = strtoull(s, &ep, base); diff --git a/mie/parse/parse.c b/mie/parse/parse.c index 41458fb..73c30e3 100644 --- a/mie/parse/parse.c +++ b/mie/parse/parse.c @@ -1,6 +1,7 @@ #include #include #include +#include #include #include #include @@ -10,13 +11,21 @@ #include #include #include +#include struct mie_parser { struct mie_ctx *p_ctx; struct mie_lex *p_lex; enum mie_status p_status; + b_string *s_tmp; }; +static b_string *get_temp_string(struct mie_parser *parser) +{ + b_string_clear(parser->s_tmp); + return parser->s_tmp; +} + struct mie_parser *mie_parser_create(struct mie_ctx *ctx, struct mie_lex *lex) { struct mie_parser *out = malloc(sizeof *out); @@ -26,6 +35,12 @@ struct mie_parser *mie_parser_create(struct mie_ctx *ctx, struct mie_lex *lex) memset(out, 0x0, sizeof *out); + out->s_tmp = b_string_create(); + if (!out->s_tmp) { + free(out); + return NULL; + } + out->p_ctx = ctx; out->p_lex = lex; out->p_status = MIE_SUCCESS; @@ -35,6 +50,10 @@ struct mie_parser *mie_parser_create(struct mie_ctx *ctx, struct mie_lex *lex) void mie_parser_destroy(struct mie_parser *ctx) { + if (ctx->s_tmp) { + b_string_unref(ctx->s_tmp); + } + free(ctx); } @@ -85,6 +104,48 @@ bool mie_parser_advance(struct mie_parser *ctx) return mie_lex_get_status(ctx->p_lex) == MIE_SUCCESS; } +bool mie_parser_parse_int( + struct mie_parser *ctx, long long *out, struct mie_file_span *loc) +{ + if (!mie_parser_check_type(ctx, MIE_TOK_INT)) { + return false; + } + + struct mie_token *tok = mie_lex_peek(ctx->p_lex); + if (tok->tok_value_type != MIE_TOK_V_INT) { + return false; + } + + if (loc) { + mie_file_span_init(loc, tok); + } + + *out = tok->tok_int; + mie_lex_advance(ctx->p_lex); + return true; +} + +bool mie_parser_parse_float( + struct mie_parser *ctx, double *out, struct mie_file_span *loc) +{ + if (!mie_parser_check_type(ctx, MIE_TOK_FLOAT)) { + return false; + } + + struct mie_token *tok = mie_lex_peek(ctx->p_lex); + if (tok->tok_value_type != MIE_TOK_V_FLOAT) { + return false; + } + + if (loc) { + mie_file_span_init(loc, tok); + } + + *out = tok->tok_float; + mie_lex_advance(ctx->p_lex); + return true; +} + #define TOKEN_PARSER(name, id) \ bool mie_parser_parse_##name( \ struct mie_parser *ctx, b_string *out, struct mie_file_span *loc) \ @@ -93,7 +154,16 @@ bool mie_parser_advance(struct mie_parser *ctx) return false; \ } \ struct mie_token *tok = mie_lex_peek(ctx->p_lex); \ - b_string_append_cstr(out, tok->tok_str); \ + switch (tok->tok_value_type) { \ + case MIE_TOK_V_STRING: \ + b_string_append_cstr(out, tok->tok_str); \ + break; \ + case MIE_TOK_V_INT: \ + b_string_append_cstrf(out, "%lld", tok->tok_int); \ + break; \ + default: \ + return false; \ + } \ if (loc) { \ mie_file_span_init(loc, tok); \ } \ @@ -123,13 +193,23 @@ bool mie_parser_parse_symbol(struct mie_parser *ctx, enum mie_token_symbol sym) return true; } +bool mie_parser_parse_linefeed(struct mie_parser *ctx) +{ + struct mie_token *tok = mie_lex_peek(ctx->p_lex); + if (tok->tok_type != MIE_TOK_LINEFEED) { + return false; + } + + mie_lex_advance(ctx->p_lex); + return true; +} + static bool parse_builtin_type_name( struct mie_parser *ctx, const struct mie_type **out) { - b_string *name = b_string_create(); + b_string *name = get_temp_string(ctx); struct mie_file_span loc; if (!mie_parser_parse_word(ctx, name, &loc)) { - b_string_unref(name); return false; } @@ -189,10 +269,9 @@ static bool parse_builtin_type_name( static bool parse_type_name(struct mie_parser *ctx, const struct mie_type **out) { - b_string *name = b_string_create(); + b_string *name = get_temp_string(ctx); struct mie_file_span loc; if (!mie_parser_parse_typename(ctx, name, &loc)) { - b_string_unref(name); return false; } @@ -354,7 +433,7 @@ MIE_API bool mie_parser_parse_function_type( bool mie_parser_parse_operand(struct mie_parser *ctx, struct mie_op_arg *out) { memset(out, 0x0, sizeof *out); - b_string *str = b_string_create(); + b_string *str = get_temp_string(ctx); bool result = false; struct mie_file_span loc; @@ -368,7 +447,6 @@ bool mie_parser_parse_operand(struct mie_parser *ctx, struct mie_op_arg *out) result = true; } - b_string_unref(str); return result; } @@ -421,6 +499,82 @@ bool mie_parser_parse_operand_list( return true; } +bool mie_parser_parse_parameter(struct mie_parser *ctx, struct mie_op_arg *out) +{ + memset(out, 0x0, sizeof *out); + b_string *str = get_temp_string(ctx); + + struct mie_file_span loc; + if (mie_parser_parse_vregname(ctx, str, &loc)) { + out->arg_unresolved.reg_name = b_string_steal(str); + out->arg_unresolved.reg_flags = MIE_REGISTER_F_VIRTUAL; + } else if (mie_parser_parse_mregname(ctx, str, &loc)) { + out->arg_unresolved.reg_name = b_string_steal(str); + out->arg_unresolved.reg_flags = MIE_REGISTER_F_MACHINE; + } else { + return false; + } + + if (!mie_parser_parse_symbol(ctx, MIE_SYM_COLON)) { + return false; + } + + if (!mie_parser_parse_type(ctx, &out->arg_unresolved.reg_type)) { + return false; + } + + return true; +} + +bool mie_parser_parse_parameter_list( + struct mie_parser *ctx, MIE_VECTOR_REF_PARAM(struct mie_op_arg, out)) +{ + bool ok = false; + struct mie_op_arg *operand = NULL; + + struct mie_token *tok = mie_parser_peek(ctx); + enum mie_token_type type = MIE_TOKEN_TYPE(tok); + if (type != MIE_TOK_VREGNAME && type != MIE_TOK_MREGNAME) { + return false; + } + + operand = mie_vector_ref_emplace_back(out); + if (!operand) { + return false; + } + + if (!mie_parser_parse_parameter(ctx, operand)) { + return false; + } + + while (1) { + tok = mie_parser_peek(ctx); + + if (!MIE_TOKEN_IS_SYMBOL(tok, MIE_SYM_COMMA)) { + break; + } + + mie_parser_advance(ctx); + tok = mie_parser_peek(ctx); + type = MIE_TOKEN_TYPE(tok); + + if (type != MIE_TOK_VREGNAME && type != MIE_TOK_MREGNAME) { + return false; + } + + operand = mie_vector_ref_emplace_back(out); + if (!operand) { + return false; + } + + if (!mie_parser_parse_parameter(ctx, operand)) { + return false; + } + } + + return true; +} + bool mie_parser_parse_register( struct mie_parser *ctx, struct mie_name_map *names, struct mie_register *out) { @@ -439,14 +593,26 @@ bool mie_parser_parse_register( return false; } - if (!mie_name_map_put( - names, &out->reg_name, tok->tok_str, MIE_NAME_MAP_F_STRICT)) { - return false; + struct mie_name *name = NULL; + b_string *tmp = get_temp_string(ctx); + switch (tok->tok_value_type) { + case MIE_TOK_V_STRING: + name = mie_name_map_put( + names, &out->reg_name, tok->tok_str, MIE_NAME_MAP_F_STRICT); + break; + case MIE_TOK_V_INT: + b_string_append_cstrf(tmp, "%lld", tok->tok_int); + name = mie_name_map_put( + names, &out->reg_name, b_string_ptr(tmp), + MIE_NAME_MAP_F_STRICT); + break; + default: + break; } mie_parser_advance(ctx); - return true; + return name != NULL; } bool mie_parser_parse_register_list( @@ -527,6 +693,35 @@ bool mie_parser_parse_module(struct mie_parser *ctx, struct mie_module *mod) bool mie_parser_parse_region(struct mie_parser *ctx, struct mie_region *region) { + region->r_names = mie_name_map_create(NULL); + + if (!mie_parser_parse_symbol(ctx, MIE_SYM_LEFT_BRACE)) { + return false; + } + + mie_parser_parse_linefeed(ctx); + struct mie_block *block = NULL; + + if (mie_parser_peek_type(ctx) != MIE_TOK_BLOCKNAME) { + block = mie_vector_emplace_back(region->r_blocks); + + if (!mie_parser_parse_anonymous_block(ctx, region->r_names, block)) { + return false; + } + } + + while (1) { + if (mie_parser_parse_symbol(ctx, MIE_SYM_RIGHT_BRACE)) { + break; + } + + block = mie_vector_emplace_back(region->r_blocks); + + if (!mie_parser_parse_block(ctx, region->r_names, block)) { + return false; + } + } + return true; } @@ -562,28 +757,269 @@ bool mie_parser_parse_region_list( return true; } +bool mie_parser_parse_anonymous_block( + struct mie_parser *ctx, struct mie_name_map *names, struct mie_block *block) +{ + mie_parser_parse_linefeed(ctx); + + struct mie_op *op = mie_vector_emplace_back(block->b_ops); + if (!mie_parser_parse_op(ctx, names, op)) { + return false; + } + + mie_parser_parse_linefeed(ctx); + + while (1) { + if (mie_parser_peek_type(ctx) == MIE_TOK_BLOCKNAME) { + break; + } + + if (mie_parser_peek_symbol(ctx) == MIE_SYM_RIGHT_BRACE) { + break; + } + + struct mie_op *op = mie_vector_emplace_back(block->b_ops); + if (!mie_parser_parse_op(ctx, names, op)) { + return false; + } + + if (!mie_parser_parse_linefeed(ctx)) { + return false; + } + } + + return true; +} + +static bool parse_block_parameters( + struct mie_parser *ctx, struct mie_name_map *names, struct mie_block *block) +{ + if (!mie_parser_parse_symbol(ctx, MIE_SYM_LEFT_PAREN)) { + return false; + } + + MIE_VECTOR_DEFINE(struct mie_op_arg, block_params); + + if (!mie_parser_parse_parameter_list(ctx, MIE_VECTOR_REF(block_params))) { + return false; + } + + if (!mie_parser_parse_symbol(ctx, MIE_SYM_RIGHT_PAREN) + || !mie_parser_parse_symbol(ctx, MIE_SYM_COLON) + || !mie_parser_parse_linefeed(ctx)) { + mie_vector_destroy(block_params, NULL); + return false; + } + + for (size_t i = 0; i < MIE_VECTOR_COUNT(block_params); i++) { + struct mie_register *param_reg + = mie_vector_emplace_back(block->b_params); + param_reg->reg_flags = block_params.items[i].arg_unresolved.reg_flags + | MIE_REGISTER_F_BLOCK_PARAM; + param_reg->reg_type = block_params.items[i].arg_unresolved.reg_type; + param_reg->reg_block = block; + if (!mie_name_map_put( + names, ¶m_reg->reg_name, + block_params.items[i].arg_unresolved.reg_name, + MIE_NAME_MAP_F_STRICT)) { + return false; + } + } + + return true; +} + +bool mie_parser_parse_block( + struct mie_parser *ctx, struct mie_name_map *names, struct mie_block *block) +{ + b_string *str = get_temp_string(ctx); + struct mie_file_span span; + + if (!mie_parser_parse_blockname(ctx, str, &span)) { + return false; + } + + if (!mie_name_map_put( + names, &block->b_name, b_string_ptr(str), + MIE_NAME_MAP_F_STRICT)) { + return false; + } + + if (mie_parser_peek_symbol(ctx) == MIE_SYM_LEFT_PAREN + && !parse_block_parameters(ctx, names, block)) { + return false; + } + + if (!mie_parser_parse_symbol(ctx, MIE_SYM_COLON) + || !mie_parser_parse_linefeed(ctx)) { + return false; + } + + while (1) { + if (mie_parser_peek_type(ctx) == MIE_TOK_BLOCKNAME) { + break; + } + + if (mie_parser_peek_symbol(ctx) == MIE_SYM_RIGHT_BRACE) { + break; + } + + struct mie_op *op = mie_vector_emplace_back(block->b_ops); + if (!mie_parser_parse_op(ctx, names, op)) { + return false; + } + + if (!mie_parser_parse_linefeed(ctx)) { + return false; + } + } + + return true; +} + bool mie_parser_parse_attribute( struct mie_parser *ctx, struct mie_op_attribute *attrib) { - return false; + b_string *str = get_temp_string(ctx); + struct mie_file_span span; + if (!mie_parser_parse_word(ctx, str, &span)) { + return false; + } + + attrib->attrib_name = b_string_steal(str); + + if (!mie_parser_parse_symbol(ctx, MIE_SYM_EQUAL)) { + return false; + } + + struct mie_value *value = NULL; + if (!mie_parser_parse_value(ctx, &value)) { + return false; + } + + attrib->attrib_value = value; + + return true; } bool mie_parser_parse_attribute_list( struct mie_parser *ctx, MIE_VECTOR_REF_PARAM(struct mie_op_attribute, out)) { - return false; + bool ok = false; + struct mie_op_attribute *attrib = NULL; + + attrib = mie_vector_ref_emplace_back(out); + if (!attrib) { + return false; + } + + if (!mie_parser_parse_attribute(ctx, attrib)) { + return false; + } + + while (1) { + const struct mie_token *tok = mie_parser_peek(ctx); + + if (!MIE_TOKEN_IS_SYMBOL(tok, MIE_SYM_COMMA)) { + break; + } + + mie_parser_advance(ctx); + mie_parser_parse_linefeed(ctx); + + attrib = mie_vector_ref_emplace_back(out); + if (!attrib) { + return false; + } + + if (!mie_parser_parse_attribute(ctx, attrib)) { + return false; + } + } + + return true; } -bool mie_parser_parse_successor( - struct mie_parser *ctx, struct mie_op_successor *successor) +bool mie_parser_parse_successor(struct mie_parser *ctx, struct mie_op_successor *out) { + memset(out, 0x0, sizeof *out); + b_string *str = get_temp_string(ctx); + bool result = false; + struct mie_file_span span; + + if (!mie_parser_parse_blockname(ctx, str, &span)) { + return false; + } + + out->s_block_name = b_string_steal(str); + + if (!mie_parser_parse_symbol(ctx, MIE_SYM_COLON)) { + return true; + } + + if (!mie_parser_parse_symbol(ctx, MIE_SYM_LEFT_PAREN)) { + goto fail; + } + + if (!mie_parser_parse_parameter_list(ctx, MIE_VECTOR_REF(out->s_args))) { + goto fail; + } + + if (!mie_parser_parse_symbol(ctx, MIE_SYM_RIGHT_PAREN)) { + goto fail; + } + + return true; + +fail: + if (out->s_block_name) { + free(out->s_block_name); + out->s_block_name = NULL; + } + + if (MIE_VECTOR_MAX(out->s_args) > 0) { + mie_vector_destroy(out->s_args, NULL); + } + return false; } bool mie_parser_parse_successor_list( struct mie_parser *ctx, MIE_VECTOR_REF_PARAM(struct mie_op_successor, out)) { - return false; + bool ok = false; + struct mie_op_successor *successor = NULL; + + successor = mie_vector_ref_emplace_back(out); + if (!successor) { + return false; + } + + if (!mie_parser_parse_successor(ctx, successor)) { + return false; + } + + while (1) { + const struct mie_token *tok = mie_parser_peek(ctx); + + if (!MIE_TOKEN_IS_SYMBOL(tok, MIE_SYM_COMMA)) { + break; + } + + mie_parser_advance(ctx); + mie_parser_parse_linefeed(ctx); + + successor = mie_vector_ref_emplace_back(out); + if (!successor) { + return false; + } + + if (!mie_parser_parse_successor(ctx, successor)) { + return false; + } + } + + return true; } static bool parse_custom_op( @@ -595,21 +1031,20 @@ static bool parse_custom_op( static bool parse_generic_op( struct mie_parser *ctx, struct mie_name_map *names, struct mie_op *dest) { - b_string *str = b_string_create(); + b_string *str = get_temp_string(ctx); struct mie_file_span loc; if (!mie_parser_parse_opname(ctx, str, &loc)) { - b_string_unref(str); return false; } dest->op_name = b_string_steal(str); - b_string_unref(str); if (!mie_parser_parse_symbol(ctx, MIE_SYM_LEFT_PAREN)) { return false; } - if (!mie_parser_parse_operand_list(ctx, MIE_VECTOR_REF(dest->op_args))) { + if (mie_parser_peek_symbol(ctx) != MIE_SYM_RIGHT_PAREN + && !mie_parser_parse_operand_list(ctx, MIE_VECTOR_REF(dest->op_args))) { return false; } @@ -617,6 +1052,30 @@ static bool parse_generic_op( return false; } + if (mie_parser_parse_symbol(ctx, MIE_SYM_LEFT_BRACKET)) { + mie_parser_parse_linefeed(ctx); + if (!mie_parser_parse_successor_list( + ctx, MIE_VECTOR_REF(dest->op_successors))) { + return false; + } + + if (!mie_parser_parse_symbol(ctx, MIE_SYM_RIGHT_BRACKET)) { + return false; + } + } + + if (mie_parser_parse_symbol(ctx, MIE_SYM_LEFT_PAREN)) { + mie_parser_parse_linefeed(ctx); + if (!mie_parser_parse_region_list( + ctx, MIE_VECTOR_REF(dest->op_regions))) { + return false; + } + + if (!mie_parser_parse_symbol(ctx, MIE_SYM_RIGHT_PAREN)) { + return false; + } + } + if (mie_parser_parse_symbol(ctx, MIE_SYM_LEFT_BRACKET)) { if (!mie_parser_parse_successor_list( ctx, MIE_VECTOR_REF(dest->op_successors))) { @@ -721,3 +1180,101 @@ bool mie_parser_parse_op( return false; } } + +static bool parse_string(struct mie_parser *ctx, struct mie_value **dest) +{ + b_string *str = get_temp_string(ctx); + struct mie_file_span span; + if (!mie_parser_parse_string(ctx, str, &span)) { + return false; + } + + struct mie_value *v = mie_ctx_get_string(ctx->p_ctx, b_string_ptr(str)); + + if (!v) { + return false; + } + + *dest = v; + return true; +} + +static bool parse_int(struct mie_parser *ctx, struct mie_value **dest) +{ + long long value = 0; + struct mie_file_span span; + + if (!mie_parser_parse_int(ctx, &value, &span)) { + return false; + } + + if (!mie_parser_parse_symbol(ctx, MIE_SYM_COLON)) { + return false; + } + + const struct mie_type *type = NULL; + if (!mie_parser_parse_type(ctx, &type)) { + return false; + } + + size_t width = mie_arith_int_type_get_width(type); + if (width == (size_t)-1) { + return false; + } + + struct mie_value *v = mie_ctx_get_int(ctx->p_ctx, value, width); + if (!v) { + return false; + } + + *dest = v; + return true; +} + +static bool parse_float(struct mie_parser *ctx, struct mie_value **dest) +{ + double value = 0; + struct mie_file_span span; + + if (!mie_parser_parse_float(ctx, &value, &span)) { + return false; + } + + if (!mie_parser_parse_symbol(ctx, MIE_SYM_COLON)) { + return false; + } + + const struct mie_type *type = NULL; + if (!mie_parser_parse_type(ctx, &type)) { + return false; + } + + size_t width = mie_arith_float_type_get_width(type); + if (width == (size_t)-1) { + return false; + } + + struct mie_value *v = mie_ctx_get_float(ctx->p_ctx, value, width); + if (!v) { + return false; + } + + *dest = v; + return true; +} + +bool mie_parser_parse_value(struct mie_parser *ctx, struct mie_value **dest) +{ + enum mie_token_type type = mie_parser_peek_type(ctx); + + switch (type) { + case MIE_TOK_STRING: + return parse_string(ctx, dest); + case MIE_TOK_INT: + return parse_int(ctx, dest); + case MIE_TOK_FLOAT: + return parse_float(ctx, dest); + default: + return false; + } +} diff --git a/mie/parse/token.c b/mie/parse/token.c index 9103b2e..1046631 100644 --- a/mie/parse/token.c +++ b/mie/parse/token.c @@ -23,7 +23,7 @@ const char *mie_token_type_to_string(enum mie_token_type type) ENUM_STR(MIE_TOK_NONE); ENUM_STR(MIE_TOK_LINEFEED); ENUM_STR(MIE_TOK_INT); - ENUM_STR(MIE_TOK_DOUBLE); + ENUM_STR(MIE_TOK_FLOAT); ENUM_STR(MIE_TOK_SYMBOL); ENUM_STR(MIE_TOK_WORD); ENUM_STR(MIE_TOK_NAME);