mie: parse: implement parsing of regions, block, attributes, and values
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include <mie/ctx.h>
|
||||
#include <mie/dialect/arith.h>
|
||||
#include <mie/dialect/dialect.h>
|
||||
#include <mie/ir/block.h>
|
||||
#include <mie/ir/module.h>
|
||||
#include <mie/ir/op.h>
|
||||
#include <mie/ir/region.h>
|
||||
@@ -10,13 +11,21 @@
|
||||
#include <mie/parse/token.h>
|
||||
#include <mie/type/function.h>
|
||||
#include <mie/type/type-definition.h>
|
||||
#include <mie/vector.h>
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user