200 lines
5.7 KiB
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()
|