Decimal128 objects and related

This uses the Intel library for 3 classes of precision

Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
This commit is contained in:
Christophe de Dinechin 2022-10-14 13:21:24 +02:00
parent 5ebfe20527
commit 644e7954b7
18 changed files with 867 additions and 25 deletions

View file

@ -44,16 +44,28 @@ C_INCLUDES += -Isrc -Iinc
# C sources
C_SOURCES +=
# Floating point sizes
DECIMAL_SIZES=32 64
DECIMAL_SOURCES=$(DECIMAL_SIZES:%=src/decimal-%.cc)
# C++ sources
CXX_SOURCES += \
src/main.cc \
src/menu.cc \
src/util.cc \
src/runtime.cc \
src/object.cc \
src/integer.cc \
CXX_SOURCES += \
src/main.cc \
src/menu.cc \
src/util.cc \
src/settings.cc \
src/runtime.cc \
src/object.cc \
src/integer.cc \
src/decimal128.cc \
$(DECIMAL_SOURCES) \
src/rplstring.cc
# Generate the sized variants of decimal128
src/decimal-%.cc: src/decimal128.cc src/decimal-%.h
sed -e s/decimal128.h/decimal-$*.h/g -e s/128/$*/g $< > $@
src/decimal-%.h: src/decimal128.h
sed -e s/128/$*/g -e s/leb$*/leb128/g $< > $@
# ASM sources
#ASM_SOURCES += src/xxx.s
@ -181,6 +193,7 @@ $(TARGET).pgm: $(BUILD)/$(TARGET).elf Makefile
$(SIZE) $<
wc -c $@
$(OBJECTS): $(DECIMAL_SOURCES)
$(BUILD)/%.hex: $(BUILD)/%.elf | $(BUILD)
$(HEX) $< $@

View file

@ -2623,13 +2623,13 @@ BID_EXTERN_C _IDEC_round _IDEC_glbround; // initialized to BID_ROUNDING_TO_NEARE
px _RND_MODE_PARAM _EXC_FLAGS_PARAM
_EXC_MASKS_PARAM _EXC_INFO_PARAM);
BID_EXTERN_C void bid32_from_string (BID_UINT32 * pres, char *ps
BID_EXTERN_C void bid32_from_string (BID_UINT32 * pres, const char *ps
_RND_MODE_PARAM _EXC_FLAGS_PARAM
_EXC_MASKS_PARAM _EXC_INFO_PARAM);
BID_EXTERN_C void bid32_to_string (char *ps, BID_UINT32 * px
_EXC_FLAGS_PARAM
_EXC_MASKS_PARAM _EXC_INFO_PARAM);
BID_EXTERN_C void bid64_from_string (BID_UINT64 * pres, char *ps
BID_EXTERN_C void bid64_from_string (BID_UINT64 * pres, const char *ps
_RND_MODE_PARAM _EXC_FLAGS_PARAM
_EXC_MASKS_PARAM _EXC_INFO_PARAM);
BID_EXTERN_C void bid64_to_string (char *ps, BID_UINT64 * px

View file

@ -34,8 +34,12 @@ SOURCES += \
../src/menu.cc \
../src/main.cc \
../src/util.cc \
../src/settings.cc \
../src/object.cc \
../src/integer.cc \
../src/decimal128.cc \
../src/decimal-64.cc \
../src/decimal-32.cc \
../src/runtime.cc \
../src/rplstring.cc

174
src/decimal-32.cc Normal file
View file

@ -0,0 +1,174 @@
// ****************************************************************************
// decimal32.cc DB48X project
// ****************************************************************************
//
// File Description:
//
// Implementation of decimal floating point using Intel's library
//
//
//
//
//
//
//
//
// ****************************************************************************
// (C) 2022 Christophe de Dinechin <christophe@dinechin.org>
// This software is licensed under the terms outlined in LICENSE.txt
// ****************************************************************************
// This file is part of DB48X.
//
// DB48X is free software: you can redistribute it and/or modify
// it under the terms outlined in the LICENSE.txt file
//
// DB48X is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// ****************************************************************************
#include "decimal-32.h"
#include "runtime.h"
#include "settings.h"
#include <bid_conf.h>
#include <bid_functions.h>
#include <cstdio>
OBJECT_HANDLER_BODY(decimal32)
// ----------------------------------------------------------------------------
// Handle commands for decimal32s
// ----------------------------------------------------------------------------
{
switch(cmd)
{
case EVAL:
// Decimal32 values evaluate as self
rt.push(obj);
return 0;
case SIZE:
return ptrdiff(payload, obj) + sizeof(bid32);
case PARSE:
{
parser *p = (parser *) arg;
return parse(p->begin, &p->end, &p->output, rt);
}
case RENDER:
{
renderer *r = (renderer *) arg;
return obj->render(r->begin, r->end, rt);
}
default:
// Check if anyone else knows how to deal with it
return DELEGATE(object);
}
}
OBJECT_PARSER_BODY(decimal32)
// ----------------------------------------------------------------------------
// Try to parse this as an decimal32
// ----------------------------------------------------------------------------
{
cstring p = begin;
// Skip leading sign
if (*p == '+' || *p == '-')
p++;
// Skip digits
cstring digits = p;
while (*p >= '0' && *p <= '9')
p++;
// If we had no digits, check for special names or exit
if (p == digits)
{
if (strncasecmp(p, "infinity", sizeof("infinity") - 1) != 0 &&
strncasecmp(p, "NaN", sizeof("NaN") - 1) != 0)
return SKIP;
}
// Check decimal dot
char *decimal = nullptr;
if (*p == '.' || *p == ',')
{
decimal = (char *) p++;
while (*p >= '0' && *p <= '9')
p++;
}
// Check exponent
char *exponent = nullptr;
if (*p == 'e' || *p == 'E' || *p == Settings.exponentChar)
{
exponent = (char *) p++;
if (*p == '+' || *p == '-')
p++;
cstring expval = p;
while (*p >= '0' && *p <= '9')
p++;
if (p == expval)
{
rt.error("Malformed exponent");
return ERROR;
}
}
// Patch the input to the BID library
char dot = '.';
if (decimal)
{
dot = *decimal;
*decimal = '.';
}
char exp = 'e';
if (exponent)
{
exp = *exponent;
*exponent = 'e';
}
// Parse the number
if (end)
*end = p;
if (out)
*out = rt.make<decimal32>(ID_decimal32, begin);
// Restore the patched input
if (decimal)
*decimal = dot;
if (exponent)
*exponent = exp;
return OK;
}
OBJECT_RENDERER_BODY(decimal32)
// ----------------------------------------------------------------------------
// Render the decimal32 into the given string buffer
// ----------------------------------------------------------------------------
{
// Align the value
bid32 num = value();
// Render in a separate buffer to avoid overflows
char buffer[50];
bid32_to_string(buffer, &num);
// Adjust special characters
for (char *p = buffer; *p && p < buffer + sizeof(buffer); p++)
if (*p == 'e' || *p == 'E')
*p = Settings.exponentChar;
else if (*p == '.')
*p = Settings.decimalDot;
// And return it to the caller
return snprintf(begin, end - begin, "%s", buffer);
}

71
src/decimal-32.h Normal file
View file

@ -0,0 +1,71 @@
#ifndef DECIMAL32_H
#define DECIMAL32_H
// ****************************************************************************
// decimal32.h DB48X project
// ****************************************************************************
//
// File Description:
//
// Real numbers in decimal32 representation
//
//
//
//
//
//
//
//
// ****************************************************************************
// (C) 2022 Christophe de Dinechin <christophe@dinechin.org>
// This software is licensed under the terms outlined in LICENSE.txt
// ****************************************************************************
// This file is part of DB48X.
//
// DB48X is free software: you can redistribute it and/or modify
// it under the terms outlined in the LICENSE.txt file
//
// DB48X is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// ****************************************************************************
#include "object.h"
#include <bid_conf.h>
#include <bid_functions.h>
#include <cstring>
struct decimal32 : object
// ----------------------------------------------------------------------------
// Floating-point numbers in 32-bit decimal32 representation
// ----------------------------------------------------------------------------
{
typedef BID_UINT32 bid32;
decimal32(cstring value, id type = ID_decimal32): object(type)
{
bid32 num;
bid32_from_string(&num, value);
byte *p = payload();
memcpy(p, &num, sizeof(num));
}
static size_t required_memory(id i, cstring value)
{
return leb128size(i) + sizeof(bid32);
}
bid32 value()
{
bid32 result;
byte *p = payload();
memcpy(&result, p, sizeof(result));
return result;
}
OBJECT_HANDLER(decimal32);
OBJECT_PARSER(decimal32);
OBJECT_RENDERER(decimal32);
};
#endif // DECIMAL32_H

174
src/decimal-64.cc Normal file
View file

@ -0,0 +1,174 @@
// ****************************************************************************
// decimal64.cc DB48X project
// ****************************************************************************
//
// File Description:
//
// Implementation of decimal floating point using Intel's library
//
//
//
//
//
//
//
//
// ****************************************************************************
// (C) 2022 Christophe de Dinechin <christophe@dinechin.org>
// This software is licensed under the terms outlined in LICENSE.txt
// ****************************************************************************
// This file is part of DB48X.
//
// DB48X is free software: you can redistribute it and/or modify
// it under the terms outlined in the LICENSE.txt file
//
// DB48X is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// ****************************************************************************
#include "decimal-64.h"
#include "runtime.h"
#include "settings.h"
#include <bid_conf.h>
#include <bid_functions.h>
#include <cstdio>
OBJECT_HANDLER_BODY(decimal64)
// ----------------------------------------------------------------------------
// Handle commands for decimal64s
// ----------------------------------------------------------------------------
{
switch(cmd)
{
case EVAL:
// Decimal64 values evaluate as self
rt.push(obj);
return 0;
case SIZE:
return ptrdiff(payload, obj) + sizeof(bid64);
case PARSE:
{
parser *p = (parser *) arg;
return parse(p->begin, &p->end, &p->output, rt);
}
case RENDER:
{
renderer *r = (renderer *) arg;
return obj->render(r->begin, r->end, rt);
}
default:
// Check if anyone else knows how to deal with it
return DELEGATE(object);
}
}
OBJECT_PARSER_BODY(decimal64)
// ----------------------------------------------------------------------------
// Try to parse this as an decimal64
// ----------------------------------------------------------------------------
{
cstring p = begin;
// Skip leading sign
if (*p == '+' || *p == '-')
p++;
// Skip digits
cstring digits = p;
while (*p >= '0' && *p <= '9')
p++;
// If we had no digits, check for special names or exit
if (p == digits)
{
if (strncasecmp(p, "infinity", sizeof("infinity") - 1) != 0 &&
strncasecmp(p, "NaN", sizeof("NaN") - 1) != 0)
return SKIP;
}
// Check decimal dot
char *decimal = nullptr;
if (*p == '.' || *p == ',')
{
decimal = (char *) p++;
while (*p >= '0' && *p <= '9')
p++;
}
// Check exponent
char *exponent = nullptr;
if (*p == 'e' || *p == 'E' || *p == Settings.exponentChar)
{
exponent = (char *) p++;
if (*p == '+' || *p == '-')
p++;
cstring expval = p;
while (*p >= '0' && *p <= '9')
p++;
if (p == expval)
{
rt.error("Malformed exponent");
return ERROR;
}
}
// Patch the input to the BID library
char dot = '.';
if (decimal)
{
dot = *decimal;
*decimal = '.';
}
char exp = 'e';
if (exponent)
{
exp = *exponent;
*exponent = 'e';
}
// Parse the number
if (end)
*end = p;
if (out)
*out = rt.make<decimal64>(ID_decimal64, begin);
// Restore the patched input
if (decimal)
*decimal = dot;
if (exponent)
*exponent = exp;
return OK;
}
OBJECT_RENDERER_BODY(decimal64)
// ----------------------------------------------------------------------------
// Render the decimal64 into the given string buffer
// ----------------------------------------------------------------------------
{
// Align the value
bid64 num = value();
// Render in a separate buffer to avoid overflows
char buffer[50];
bid64_to_string(buffer, &num);
// Adjust special characters
for (char *p = buffer; *p && p < buffer + sizeof(buffer); p++)
if (*p == 'e' || *p == 'E')
*p = Settings.exponentChar;
else if (*p == '.')
*p = Settings.decimalDot;
// And return it to the caller
return snprintf(begin, end - begin, "%s", buffer);
}

71
src/decimal-64.h Normal file
View file

@ -0,0 +1,71 @@
#ifndef DECIMAL64_H
#define DECIMAL64_H
// ****************************************************************************
// decimal64.h DB48X project
// ****************************************************************************
//
// File Description:
//
// Real numbers in decimal64 representation
//
//
//
//
//
//
//
//
// ****************************************************************************
// (C) 2022 Christophe de Dinechin <christophe@dinechin.org>
// This software is licensed under the terms outlined in LICENSE.txt
// ****************************************************************************
// This file is part of DB48X.
//
// DB48X is free software: you can redistribute it and/or modify
// it under the terms outlined in the LICENSE.txt file
//
// DB48X is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// ****************************************************************************
#include "object.h"
#include <bid_conf.h>
#include <bid_functions.h>
#include <cstring>
struct decimal64 : object
// ----------------------------------------------------------------------------
// Floating-point numbers in 64-bit decimal64 representation
// ----------------------------------------------------------------------------
{
typedef BID_UINT64 bid64;
decimal64(cstring value, id type = ID_decimal64): object(type)
{
bid64 num;
bid64_from_string(&num, value);
byte *p = payload();
memcpy(p, &num, sizeof(num));
}
static size_t required_memory(id i, cstring value)
{
return leb128size(i) + sizeof(bid64);
}
bid64 value()
{
bid64 result;
byte *p = payload();
memcpy(&result, p, sizeof(result));
return result;
}
OBJECT_HANDLER(decimal64);
OBJECT_PARSER(decimal64);
OBJECT_RENDERER(decimal64);
};
#endif // DECIMAL64_H

174
src/decimal128.cc Normal file
View file

@ -0,0 +1,174 @@
// ****************************************************************************
// decimal128.cc DB48X project
// ****************************************************************************
//
// File Description:
//
// Implementation of decimal floating point using Intel's library
//
//
//
//
//
//
//
//
// ****************************************************************************
// (C) 2022 Christophe de Dinechin <christophe@dinechin.org>
// This software is licensed under the terms outlined in LICENSE.txt
// ****************************************************************************
// This file is part of DB48X.
//
// DB48X is free software: you can redistribute it and/or modify
// it under the terms outlined in the LICENSE.txt file
//
// DB48X is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// ****************************************************************************
#include "decimal128.h"
#include "runtime.h"
#include "settings.h"
#include <bid_conf.h>
#include <bid_functions.h>
#include <cstdio>
OBJECT_HANDLER_BODY(decimal128)
// ----------------------------------------------------------------------------
// Handle commands for decimal128s
// ----------------------------------------------------------------------------
{
switch(cmd)
{
case EVAL:
// Decimal128 values evaluate as self
rt.push(obj);
return 0;
case SIZE:
return ptrdiff(payload, obj) + sizeof(bid128);
case PARSE:
{
parser *p = (parser *) arg;
return parse(p->begin, &p->end, &p->output, rt);
}
case RENDER:
{
renderer *r = (renderer *) arg;
return obj->render(r->begin, r->end, rt);
}
default:
// Check if anyone else knows how to deal with it
return DELEGATE(object);
}
}
OBJECT_PARSER_BODY(decimal128)
// ----------------------------------------------------------------------------
// Try to parse this as an decimal128
// ----------------------------------------------------------------------------
{
cstring p = begin;
// Skip leading sign
if (*p == '+' || *p == '-')
p++;
// Skip digits
cstring digits = p;
while (*p >= '0' && *p <= '9')
p++;
// If we had no digits, check for special names or exit
if (p == digits)
{
if (strncasecmp(p, "infinity", sizeof("infinity") - 1) != 0 &&
strncasecmp(p, "NaN", sizeof("NaN") - 1) != 0)
return SKIP;
}
// Check decimal dot
char *decimal = nullptr;
if (*p == '.' || *p == ',')
{
decimal = (char *) p++;
while (*p >= '0' && *p <= '9')
p++;
}
// Check exponent
char *exponent = nullptr;
if (*p == 'e' || *p == 'E' || *p == Settings.exponentChar)
{
exponent = (char *) p++;
if (*p == '+' || *p == '-')
p++;
cstring expval = p;
while (*p >= '0' && *p <= '9')
p++;
if (p == expval)
{
rt.error("Malformed exponent");
return ERROR;
}
}
// Patch the input to the BID library
char dot = '.';
if (decimal)
{
dot = *decimal;
*decimal = '.';
}
char exp = 'e';
if (exponent)
{
exp = *exponent;
*exponent = 'e';
}
// Parse the number
if (end)
*end = p;
if (out)
*out = rt.make<decimal128>(ID_decimal128, begin);
// Restore the patched input
if (decimal)
*decimal = dot;
if (exponent)
*exponent = exp;
return OK;
}
OBJECT_RENDERER_BODY(decimal128)
// ----------------------------------------------------------------------------
// Render the decimal128 into the given string buffer
// ----------------------------------------------------------------------------
{
// Align the value
bid128 num = value();
// Render in a separate buffer to avoid overflows
char buffer[50];
bid128_to_string(buffer, &num);
// Adjust special characters
for (char *p = buffer; *p && p < buffer + sizeof(buffer); p++)
if (*p == 'e' || *p == 'E')
*p = Settings.exponentChar;
else if (*p == '.')
*p = Settings.decimalDot;
// And return it to the caller
return snprintf(begin, end - begin, "%s", buffer);
}

71
src/decimal128.h Normal file
View file

@ -0,0 +1,71 @@
#ifndef DECIMAL128_H
#define DECIMAL128_H
// ****************************************************************************
// decimal128.h DB48X project
// ****************************************************************************
//
// File Description:
//
// Real numbers in decimal128 representation
//
//
//
//
//
//
//
//
// ****************************************************************************
// (C) 2022 Christophe de Dinechin <christophe@dinechin.org>
// This software is licensed under the terms outlined in LICENSE.txt
// ****************************************************************************
// This file is part of DB48X.
//
// DB48X is free software: you can redistribute it and/or modify
// it under the terms outlined in the LICENSE.txt file
//
// DB48X is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// ****************************************************************************
#include "object.h"
#include <bid_conf.h>
#include <bid_functions.h>
#include <cstring>
struct decimal128 : object
// ----------------------------------------------------------------------------
// Floating-point numbers in 128-bit decimal128 representation
// ----------------------------------------------------------------------------
{
typedef BID_UINT128 bid128;
decimal128(cstring value, id type = ID_decimal128): object(type)
{
bid128 num;
bid128_from_string(&num, value);
byte *p = payload();
memcpy(p, &num, sizeof(num));
}
static size_t required_memory(id i, cstring value)
{
return leb128size(i) + sizeof(bid128);
}
bid128 value()
{
bid128 result;
byte *p = payload();
memcpy(&result, p, sizeof(result));
return result;
}
OBJECT_HANDLER(decimal128);
OBJECT_PARSER(decimal128);
OBJECT_RENDERER(decimal128);
};
#endif // DECIMAL128_H

View file

@ -37,11 +37,9 @@ ID(bin_integer)
ID(dec_integer)
// ID(real)
// ID(real32)
// ID(decimal32)
// ID(decimal64)
// ID(decimal128)
ID(decimal32)
ID(decimal64)
ID(decimal128)
//ID(add)
//ID(sub)

View file

@ -58,7 +58,7 @@ OBJECT_HANDLER_BODY(integer)
default:
// Check if anyone else knows how to deal with it
return SKIP;
return DELEGATE(object);
}
}

View file

@ -4,7 +4,7 @@
//
// File Description:
//
//
// The DB48X main RPL loop
//
//
//
@ -33,14 +33,15 @@
#include "menu.h"
#include "num.h"
#include "rpl.h"
#include "settings.h"
#include "util.h"
#include <algorithm>
#include <cctype>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <dmcp.h>
using std::min;
@ -306,7 +307,7 @@ void disp_stack_line(char *s, int a, int cpl)
}
char *t = strchr(s, expchar);
if (t)
*t = exponent_char; // Special 'E'
*t = Settings.exponentChar; // Special 'E'
}

View file

@ -30,6 +30,9 @@
#include "object.h"
#include "integer.h"
#include "decimal128.h"
#include "decimal-64.h"
#include "decimal-32.h"
#include "rplstring.h"
#include "runtime.h"
@ -88,8 +91,7 @@ OBJECT_HANDLER_BODY(object)
"<Unknown object %p>", obj);
}
default:
rt.error("Invalid command for default object");
return ERROR;
return SKIP;
}
}

View file

@ -208,7 +208,7 @@ struct object
#define OBJECT_RENDERER(type) \
intptr_t render(char *begin, cstring end, runtime &rt = RT)
#define OBJECT_RENDERER_BODY(type) \
#define OBJECT_RENDERER_BODY(type) \
intptr_t type::render(char *begin, cstring end, runtime &rt)
OBJECT_RENDERER(object);
@ -233,6 +233,9 @@ struct object
object *payload)
OBJECT_HANDLER_NO_ID(object);
#define DELEGATE(base) \
base::handle(rt, cmd, arg, obj, payload)
static cstring name(id i)
// ------------------------------------------------------------------------
// Return the name for a given ID

View file

@ -63,7 +63,7 @@ OBJECT_HANDLER_BODY(string)
default:
// Check if anyone else knows how to deal with it
return SKIP;
return DELEGATE(object);
}
}

32
src/settings.cc Normal file
View file

@ -0,0 +1,32 @@
// ****************************************************************************
// settings.cc DB48X project
// ****************************************************************************
//
// File Description:
//
// Representation of settings
//
//
//
//
//
//
//
//
// ****************************************************************************
// (C) 2022 Christophe de Dinechin <christophe@dinechin.org>
// This software is licensed under the terms outlined in LICENSE.txt
// ****************************************************************************
// This file is part of DB48X.
//
// DB48X is free software: you can redistribute it and/or modify
// it under the terms outlined in the LICENSE.txt file
//
// DB48X is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// ****************************************************************************
#include "settings.h"
settings Settings;

55
src/settings.h Normal file
View file

@ -0,0 +1,55 @@
#ifndef SETTINGS_H
#define SETTINGS_H
// ****************************************************************************
// settings.h DB48X project
// ****************************************************************************
//
// File Description:
//
// List of system-wide settings
//
//
//
//
//
//
//
//
// ****************************************************************************
// (C) 2022 Christophe de Dinechin <christophe@dinechin.org>
// This software is licensed under the terms outlined in LICENSE.txt
// ****************************************************************************
// This file is part of DB48X.
//
// DB48X is free software: you can redistribute it and/or modify
// it under the terms outlined in the LICENSE.txt file
//
// DB48X is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// ****************************************************************************
#include <types.h>
struct settings
// ----------------------------------------------------------------------------
// Internal representation of settings
// ----------------------------------------------------------------------------
{
settings()
: precision(32),
displayed(0),
decimalDot('.'),
exponentChar(0x98) // The special mini-'E'
{}
uint precision; // Internal precision for numbers
uint displayed; // Number of displayed digits
char decimalDot; // Character used for decimal separator
char exponentChar; // The character used to represent exponents
};
extern settings Settings;
#endif // SETTINGS_H

View file

@ -48,8 +48,7 @@ typedef const char *cstring;
typedef const char *utf8;
typedef unsigned utf8code;
enum { exponent_char = 0x98 };
#define UNUSED(var) ((void *) &(var))
// Indicate that an argument may be unused
#define UNUSED(x) ((void) &x)
#endif // TYPES_H