Files
mie/mie/dialect/arith/op/constant.c

200 lines
5.7 KiB
C

#include <mie/attribute/attribute.h>
#include <mie/dialect/arith.h>
#include <mie/dialect/builtin.h>
#include <mie/dialect/dialect.h>
#include <mie/ir/emit.h>
#include <mie/ir/op-definition.h>
#include <mie/ir/op.h>
#include <mie/macros.h>
#include <mie/parse/parser.h>
#include <mie/print/printer.h>
#include <mie/type/type.h>
static enum mie_status print(struct mie_printer *printer, const struct mie_op *op)
{
const struct mie_attribute *value
= mie_attribute_map_get(&op->op_attrib, "value");
if (!value) {
return MIE_SUCCESS;
}
const struct mie_type *type = NULL;
if (mie_attribute_check_name(value, "builtin", "int")) {
const struct mie_int *i = (const struct mie_int *)value;
b_stream_write_fmt(
printer->p_stream, NULL, " %lld : ", i->i_val.v_small);
type = i->i_type;
} else if (mie_attribute_check_name(value, "builtin", "float")) {
const struct mie_float *f = (const struct mie_float *)value;
double d;
mie_float_get_value(value, &d);
b_stream_write_fmt(printer->p_stream, NULL, " %g : ", d);
type = f->f_type;
} else {
return MIE_SUCCESS;
}
mie_printer_print_type(printer, type);
return MIE_SUCCESS;
}
static enum mie_status parse_int(
struct mie_parser *parser, long long i, struct mie_file_span *loc,
struct mie_op *out)
{
if (!mie_parser_parse_symbol(parser, MIE_SYM_COLON)) {
mie_parser_report_unexpected_token(
parser, MIE_SYM_COLON, "arithmetic constant type");
return MIE_ERR_BAD_SYNTAX;
}
const struct mie_type *type = NULL;
struct mie_file_span type_span;
if (!mie_parser_parse_type(
parser, "arithmetic constant type", &type, &type_span)) {
mie_parser_report_unexpected_token(
parser, MIE_TOK_TYPENAME, "arithmetic constant type");
return MIE_ERR_BAD_SYNTAX;
}
struct mie_attribute *value = NULL;
if (mie_type_is(type, "builtin", "int")) {
value = mie_ctx_get_int(
mie_parser_get_mie_ctx(parser), i,
mie_int_type_get_width(type));
} else if (mie_type_is(type, "builtin", "index")) {
value = mie_ctx_get_index(mie_parser_get_mie_ctx(parser), i);
} else {
mie_parser_report_error_simple(
parser, "arith", MIE_ARITH_E_INVALID_INTEGER_TYPE,
MIE_ARITH_MSG_EXPECTED_INTEGER_TYPE, &type_span);
}
if (MIE_VECTOR_COUNT(out->op_result) != 1) {
mie_parser_report_error_simple(
parser, "builtin",
MIE_BUILTIN_E_INCORRECT_NUMBER_OF_RESULTS,
MIE_BUILTIN_MSG_OP_EXPECTS_X_RESULTS, &type_span);
return MIE_ERR_BAD_SYNTAX;
}
mie_attribute_map_put(
&out->op_attrib, "value", value, MIE_ATTRMAP_F_REPLACE);
out->op_result.items[0].reg_type = type;
return MIE_SUCCESS;
}
static enum mie_status parse_float(
struct mie_parser *parser, double d, struct mie_file_span *loc,
struct mie_op *out)
{
if (!mie_parser_parse_symbol(parser, MIE_SYM_COLON)) {
mie_parser_report_unexpected_token(
parser, MIE_SYM_COLON, "arithmetic constant type");
return MIE_ERR_BAD_SYNTAX;
}
const struct mie_type *type = NULL;
struct mie_file_span type_span;
if (!mie_parser_parse_type(
parser, "arithmetic constant type", &type, &type_span)) {
mie_parser_report_unexpected_token(
parser, MIE_TOK_TYPENAME, "arithmetic constant type");
return MIE_ERR_BAD_SYNTAX;
}
struct mie_attribute *value = NULL;
if (mie_type_is(type, "builtin", "float")) {
value = mie_ctx_get_float(
mie_parser_get_mie_ctx(parser), d,
mie_float_type_get_width(type));
} else {
mie_parser_report_error_simple(
parser, "arith", MIE_ARITH_E_INVALID_FLOAT_TYPE,
MIE_ARITH_MSG_EXPECTED_FLOAT_TYPE, &type_span);
return MIE_ERR_BAD_SYNTAX;
}
if (MIE_VECTOR_COUNT(out->op_result) != 1) {
mie_parser_report_error_simple(
parser, "builtin",
MIE_BUILTIN_E_INCORRECT_NUMBER_OF_RESULTS,
MIE_BUILTIN_MSG_OP_EXPECTS_X_RESULTS, &type_span);
return MIE_ERR_BAD_SYNTAX;
}
mie_attribute_map_put(
&out->op_attrib, "value", value, MIE_ATTRMAP_F_REPLACE);
out->op_result.items[0].reg_type = type;
return MIE_SUCCESS;
}
static enum mie_status parse(
struct mie_parser *parser, struct mie_parser_scope *scope,
struct mie_op *out)
{
double d;
long long i;
struct mie_file_span span;
if (mie_parser_parse_int(parser, &i, &span)) {
return parse_int(parser, i, &span, out);
} else if (mie_parser_parse_float(parser, &d, &span)) {
return parse_float(parser, d, &span, out);
} else {
struct mie_parser_item required[] = {
MIE_PARSE_ITEM_TOKEN(MIE_TOK_INT),
MIE_PARSE_ITEM_TOKEN(MIE_TOK_FLOAT),
MIE_PARSE_ITEM_NONE,
};
mie_parser_report_unexpected_token_v(
parser, required, "arithmetic constant");
return MIE_ERR_BAD_SYNTAX;
}
}
struct mie_register *mie_arith_constant_i_put(
struct mie_emitter *e, long long value, const char *name)
{
struct mie_op *op = mie_emitter_put_op(e, "arith", "constant", NULL, 0);
const struct mie_type *ty
= mie_ctx_get_int_type(mie_emitter_get_ctx(e), 32);
struct mie_register *result = mie_op_add_result(op, ty);
mie_emitter_put_name(e, &result->reg_name, name);
struct mie_attribute *val
= mie_ctx_get_int(mie_emitter_get_ctx(e), value, 32);
mie_attribute_map_put(&op->op_attrib, "value", val, MIE_ATTRMAP_F_REPLACE);
return result;
}
struct mie_register *mie_arith_constant_f_put(
struct mie_emitter *e, long long value, const char *name)
{
struct mie_op *op = mie_emitter_put_op(e, "arith", "constant", NULL, 0);
const struct mie_type *ty
= mie_ctx_get_int_type(mie_emitter_get_ctx(e), 32);
struct mie_register *result = mie_op_add_result(op, ty);
mie_emitter_put_name(e, &result->reg_name, name);
struct mie_attribute *val
= mie_ctx_get_float(mie_emitter_get_ctx(e), value, 32);
mie_attribute_map_put(&op->op_attrib, "value", val, MIE_ATTRMAP_F_REPLACE);
return result;
}
MIE_OP_DEFINITION_BEGIN(mie_arith_constant, "constant")
MIE_OP_DEFINITION_PRINT(print);
MIE_OP_DEFINITION_PARSE(parse);
MIE_OP_DEFINITION_END()