#ifndef SCANNER_H #define SCANNER_H #include #include #include #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