108 lines
2.5 KiB
C
108 lines
2.5 KiB
C
#include "../float.h"
|
|
|
|
#include <blue/core/bstr.h>
|
|
#include <mie/attribute/attribute-definition.h>
|
|
#include <mie/attribute/attribute.h>
|
|
#include <mie/ctx.h>
|
|
#include <mie/dialect/builtin.h>
|
|
#include <mie/dialect/dialect.h>
|
|
#include <mie/macros.h>
|
|
#include <mie/parse/parser.h>
|
|
#include <mie/print/printer.h>
|
|
|
|
static enum mie_status print(
|
|
const struct mie_attribute *value, struct mie_printer *out)
|
|
{
|
|
const struct mie_float *float_val = (const struct mie_float *)value;
|
|
const struct float_type *float_ty
|
|
= (const struct float_type *)float_val->f_type;
|
|
if (!(out->p_flags & MIE_PRINT_F_ABBREVIATED)) {
|
|
b_stream_write_string(out->p_stream, "#builtin.float<", NULL);
|
|
}
|
|
|
|
switch (float_ty->f_width) {
|
|
case MIE_FLOAT_32:
|
|
b_stream_write_fmt(
|
|
out->p_stream, NULL, "%f : f%zu", float_val->f_val.v_32,
|
|
float_ty->f_width);
|
|
break;
|
|
case MIE_FLOAT_64:
|
|
b_stream_write_fmt(
|
|
out->p_stream, NULL, "%lf : f%zu",
|
|
float_val->f_val.v_64, float_ty->f_width);
|
|
break;
|
|
default:
|
|
b_stream_write_fmt(
|
|
out->p_stream, NULL, "NaN : f%zu", float_ty->f_width);
|
|
break;
|
|
}
|
|
|
|
if (!(out->p_flags & MIE_PRINT_F_ABBREVIATED)) {
|
|
b_stream_write_string(out->p_stream, ">", NULL);
|
|
}
|
|
|
|
return MIE_SUCCESS;
|
|
}
|
|
|
|
static enum mie_status parse(
|
|
struct mie_parser *ctx, const struct mie_attribute **out)
|
|
{
|
|
double value = 0;
|
|
struct mie_file_span span;
|
|
|
|
if (!mie_parser_parse_float(ctx, &value, &span)) {
|
|
return MIE_ERR_BAD_SYNTAX;
|
|
}
|
|
|
|
if (!mie_parser_parse_symbol(ctx, MIE_SYM_COLON)) {
|
|
return MIE_ERR_BAD_SYNTAX;
|
|
}
|
|
|
|
const struct mie_type *type = NULL;
|
|
if (!mie_parser_parse_type(ctx, &type)) {
|
|
return MIE_ERR_BAD_SYNTAX;
|
|
}
|
|
|
|
size_t width = mie_float_type_get_width(type);
|
|
if (width == (size_t)-1) {
|
|
return MIE_ERR_BAD_SYNTAX;
|
|
}
|
|
|
|
struct mie_attribute *v
|
|
= mie_ctx_get_float(mie_parser_get_mie_ctx(ctx), value, width);
|
|
if (!v) {
|
|
return MIE_ERR_NO_MEMORY;
|
|
}
|
|
|
|
*out = v;
|
|
return MIE_SUCCESS;
|
|
}
|
|
|
|
bool mie_float_get_value(const struct mie_attribute *attrib, double *out)
|
|
{
|
|
if (!mie_attribute_check_name(attrib, "builtin", "float")) {
|
|
return false;
|
|
}
|
|
|
|
const struct mie_float *v = (const struct mie_float *)attrib;
|
|
|
|
switch (mie_float_type_get_width(v->f_type)) {
|
|
case MIE_FLOAT_32:
|
|
*out = v->f_val.v_32;
|
|
break;
|
|
case MIE_FLOAT_64:
|
|
*out = v->f_val.v_64;
|
|
break;
|
|
default:
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
MIE_ATTRIBUTE_DEFINITION_BEGIN(mie_builtin_float, "float")
|
|
MIE_ATTRIBUTE_DEFINITION_STRUCT(struct mie_float);
|
|
MIE_ATTRIBUTE_DEFINITION_PRINT(print);
|
|
MIE_ATTRIBUTE_DEFINITION_PARSE(parse);
|
|
MIE_ATTRIBUTE_DEFINITION_END()
|