teapot-spreadsheet/src/common/token.h

196 lines
4.9 KiB
C

#ifndef TOKEN_H
#define TOKEN_H
#include <float.h>
#include <stdbool.h>
#include "func.h"
#include "style.h"
#ifdef __cplusplus
extern "C" {
#endif
/* TO PRESERVE ABILITY TO READ OLD SAVE FILES, ONLY ADD ITEMS AT END */
typedef enum {
EMPTY
#ifndef __cplusplus
, STRING, FLOAT, INT, OPERATOR, LIDENT, FIDENT, LOCATION, EEK,
FUNCALL, BOOL, STYLE
#endif
} Type;
#define MAX_TYPE_NAME_LENGTH 16
extern const char *Type_Name[];
typedef enum
{
PLUS, MINUS, MUL, DIV, OP, CP, COMMA,
LT, /* Take care with the macros just below */
LE, GE, GT, ISEQUAL, ABOUTEQ, NE,
POW, MOD, LAND, LOR
} Operator;
#define MAX_OP_NAME_LENGTH 3
#define IS_RELATION_OP(op) (((op)>= LT) && ((op)<=NE))
extern const char *Op_Name[];
typedef enum { X=0, Y=1, Z=2, HYPER} Dimensions;
typedef int CoordT;
#define COORD_MIN INT_MIN
#define COORD_MAX INT_MAX
typedef CoordT Location[HYPER];
/* NOTE: Locations are passed by REFERENCE not value */
#define OLOCATION(loc) ((void)memset(loc, 0, sizeof(Location)))
#define IN_OCTANT(loc) (loc[X]>=0 && loc[Y]>=0 && loc[Z]>=0)
#define LOCATION_GETS(la,lb) ((void)memcpy(la, lb, sizeof(Location)))
#define SAME_LOC(la,lb) (memcmp(la,lb,sizeof(Location))==0)
#define LOCATION_SUB(la,lb) (la)[X]-=(lb)[X], (la)[Y]-=(lb)[Y], (la)[Z]-=(lb)[Z]
#define LOCATION_ADD(la,lb) (la)[X]+=(lb)[X], (la)[Y]+=(lb)[Y], (la)[Z]+=(lb)[Z]
#define LOCATION_LT(la,lb) (la[X]<lb[X] && la[Y]<lb[Y] && la[Z]<lb[Z])
#define LOCATION_LEQ(la,lb) ((la)[X]<=(lb)[X] && (la)[Y]<=(lb)[Y] && (la)[Z]<=(lb)[Z])
bool loc_in_box(const Location test,
const Location b, const Location c);
typedef struct
{
FunctionIdentifier fident;
int argc;
Token *argv;
} FunctionCall;
#define FLT_LONG_DOUBLE
#ifdef FLT_LONG_DOUBLE
typedef long double FltT;
/* To switch the internal type used to store a floating value, it is
supposed to suffice to redefine all of the following macros:
*/
#define FLT_T_STD_FMT "%.*Lf"
#define FLT_T_SCI_FMT "%.*Le"
#define FLT_T_CPT_FMT "%.*Lg"
#define FLT_T_HEX_FMT "%La"
#define FLT_T_DIG LDBL_DIG
#define FLTEPS LDBL_EPSILON
#define FLTMX LDBL_MAX
#define STRTOFLT strtold
#define ABSFLT fabsl
#define LOGFLT logl
#define LOG2FLT log2l
#define LOG10FLT log10l
#define SQRTFLT sqrtl
#define POWFLT powl
#define FMODFLT fmodl
#define MODFFLT modfl
#define SINFLT sinl
#define COSFLT cosl
#define TANFLT tanl
#define SINHFLT sinhl
#define COSHFLT coshl
#define TANHFLT tanhl
#define ASINFLT asinl
#define ACOSFLT acosl
#define ATANFLT atanl
#define FLOORFLT floorl
#define CEILFLT ceill
#define ROUNDFLT rintl
#define TRUNCFLT truncl
#define LDEXP_FLT ldexpl
#else
typedef double FltT;
/* To switch the internal type used to store a floating value, it is
supposed to suffice to redefine all of the following macros:
*/
#define FLT_T_STD_FMT "%.*f"
#define FLT_T_SCI_FMT "%.*e"
#define FLT_T_CPT_FMT "%.*g"
#define FLT_T_HEX_FMT "%a"
#define FLT_T_DIG DBL_DIG
#define FLTEPS DBL_EPSILON
#define FLTMX DBL_MAX
#define STRTOFLT strtod
#define ABSFLT fabs
#define LOGFLT log
#define LOG2FLT log2
#define LOG10FLT log10
#define SQRTFLT sqrt
#define POWFLT pow
#define FMODFLT fmod
#define MODFFLT modf
#define SINFLT sin
#define COSFLT cos
#define TANFLT tan
#define SINHFLT sinh
#define COSHFLT cosh
#define TANHFLT tanh
#define ASINFLT asin
#define ACOSFLT acos
#define ATANFLT atan
#define FLOORFLT floor
#define CEILFLT ceil
#define ROUNDFLT rint
#define TRUNCFLT trunc
#define LDEXP_FLT ldexp
#endif
typedef long long IntT;
/* To switch the internal type used to store an integer value, it is
supposed to suffice to redefine all of the following macros and typedefs.
*/
typedef unsigned long long UIntT;
#define INT_T_FMT "%lld"
#define STRTOINT strtoll
/* This one depends on both the floating point and integer types */
#ifdef FLT_LONG_DOUBLE
#define ROUNDFLTINT llrintl
#else
#define ROUNDFLTINT llrint
#endif
/* End of subtype definitions */
/* The main type defined here */
typedef struct Token_struc
{
Type type;
union
{
char *string;
FltT flt;
IntT integer;
Operator op;
char *lident;
FunctionIdentifier fident;
Location location;
FunctionCall funcall;
char *err;
bool bl;
Style style;
} u;
} Token;
#define NULLTOKEN ((Token*)0)
#define EMPTY_TVEC ((Token**)0)
#define TOKISNUM(t) ((t).type == INT || (t).type == FLOAT || (t).type == EMPTY)
bool tok_matches(const Token *l, const Token *r);
Token duperror(Token* tok, const char* erro);
void cleartoken(Token* tok);
typedef enum {DIRECT_STRING, QUOTE_STRING} StringFormat;
typedef enum {TRUNCATED_ERROR, VERBOSE_ERROR, RESTORE_ERROR} ErrorFormat;
size_t printtok(char *dest, size_t size, size_t field_width, StringFormat sf,
FloatFormat ff, PrecisionLevel digits, ErrorFormat ef,
const Token *tok);
const char *dbgprint(const Token *tok); /* for use in debugging */
void print(char *s, size_t size, size_t chars, StringFormat sf, FloatFormat ff,
PrecisionLevel digits, Token **n);
#ifdef __cplusplus
}
#endif
#endif