teapot-spreadsheet/src/common/scanner.h

186 lines
4.4 KiB
C

#ifndef SCANNER_H
#define SCANNER_H
#include <math.h>
#include <sys/types.h>
#include <stdbool.h>
#include "func.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
#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 int Location[3]; /* NOTE: Locations are passed by REFERENCE not value */
/* I.e., to accept a Location argument, declare the parameter to be of type
const Location*
*/
typedef enum { X=0, Y=1, Z=2, HYPER} Dimensions;
#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];
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
#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
#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; should this be token.h ?*/
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;
} 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);
Token *scan_ident(char **s);
Token *scan_integer(char **s);
Token *scan_flt(char **s);
Token **scan(char **s);
void cleartoken(Token* tok);
#ifdef __cplusplus
}
#endif
#endif