/*****************************************************************************
*   "Irit" - the 3d (not only polygonal) solid modeller.		     *
*									     *
* Written by:  Gershon Elber				Ver 0.2, Mar. 1990   *
******************************************************************************
*   General, local to module, definitions for the Input Parser module.	     *
*   Note this module actually consists of InptPrsr/InptEval/OverLoad modules.*
*****************************************************************************/

#ifndef	INPT_PRSR_LH
#define	INPT_PRSR_LH

/* #define DEBUG        Print some intermediate results (InptPrsr/InptEval). */

#define MAX_PARSER_STACK	500	     /* Depth of expression nesting. */

typedef enum {
    POLY_EXPR =     0x0001,
    NUMERIC_EXPR =  0x0002,
    POINT_EXPR	=   0x0004,
    VECTOR_EXPR	=   0x0008,
    PLANE_EXPR	=   0x0010,
    MATRIX_EXPR	=   0x0020,
    CURVE_EXPR =    0x0040,
    SURFACE_EXPR =  0x0080,
    STRING_EXPR	=   0x0100,
    OLST_EXPR =     0x0200,
    CTLPT_EXPR =    0x0400,

    NO_EXPR =       0x1000,
    POLY_CURVE_EXPR = POLY_EXPR | CURVE_EXPR,
    GEOM_EXPR =     POLY_EXPR | CURVE_EXPR | SURFACE_EXPR,
    OLST_GEOM_EXPR = OLST_EXPR | GEOM_EXPR,
    ANY_EXPR =      POLY_EXPR | NUMERIC_EXPR | POINT_EXPR | VECTOR_EXPR |
    		    PLANE_EXPR | MATRIX_EXPR | CURVE_EXPR | SURFACE_EXPR |
		    STRING_EXPR | OLST_EXPR | CTLPT_EXPR,

    ERROR_EXPR =    0x4000
} IritExprType;

/*****************************************************************************
* The expression parse tree node definition:				     *
*****************************************************************************/
typedef	struct ParseTree {
    struct ParseTree *Right, *Left;
    int NodeKind;
    IPObjectStruct *PObj;
    struct UserDefinedFuncDefType *UserFunc;
} ParseTree;

/* See also IPObjectStruct structure for the different object possible: */
#define IS_POLY_NODE(Node)	((Node) -> PObj -> ObjType == IP_OBJ_POLY)
#define IS_NUM_NODE(Node)	((Node) -> PObj -> ObjType == IP_OBJ_NUMERIC)
#define IS_PT_NODE(Node)	((Node) -> PObj -> ObjType == IP_OBJ_POINT)
#define IS_VEC_NODE(Node)	((Node) -> PObj -> ObjType == IP_OBJ_VECTOR)
#define IS_PLANE_NODE(Node)	((Node) -> PObj -> ObjType == IP_OBJ_PLANE)
#define IS_CTLPT_NODE(Node)	((Node) -> PObj -> ObjType == IP_OBJ_CTLPT)
#define IS_MAT_NODE(Node)	((Node) -> PObj -> ObjType == IP_OBJ_MATRIX)
#define IS_STR_NODE(Node)	((Node) -> PObj -> ObjType == IP_OBJ_STRING)
#define IS_OLST_NODE(Node)	((Node) -> PObj -> ObjType == IP_OBJ_LIST_OBJ)
#define IS_CRV_NODE(Node)	((Node) -> PObj -> ObjType == IP_OBJ_CURVE)
#define IS_SRF_NODE(Node)	((Node) -> PObj -> ObjType == IP_OBJ_SURFACE)

/*****************************************************************************
* The include file stack - nesting is allowed up to FILE_STACK_SIZE.	     *
*****************************************************************************/
typedef struct FileStackStruct {
    char Name[FILE_NAME_LEN];
    FILE *f;
} FileStackStruct;

#define FILE_STACK_SIZE	10

/*****************************************************************************
* Function entry table looks like this (for table see InptPrsr.c module):    *
*****************************************************************************/
#define FUNC_NAME_LEN	31			    /* 10 + NULL terminator. */
#define FUNC_MAX_PARAM	5	    /* Max. of all the function types below. */
#define ANY_PARAM_NUM	127

typedef struct FuncTableType {
    char FuncName[FUNC_NAME_LEN];
    int FuncToken;
    void (*Func)();
    ByteType NumOfParam;
    IritExprType ParamObjType[FUNC_MAX_PARAM];
    IritExprType RetType;
} FuncTableType;

typedef struct NumFuncTableType {
    char FuncName[FUNC_NAME_LEN];
    int FuncToken;
    double (*Func)();
    ByteType NumOfParam;
    IritExprType ParamObjType[FUNC_MAX_PARAM];
    IritExprType RetType;
} NumFuncTableType;

typedef struct ObjFuncTableType {
    char FuncName[FUNC_NAME_LEN];
    int FuncToken;
    IPObjectStruct *(*Func)();
    ByteType NumOfParam;
    IritExprType ParamObjType[FUNC_MAX_PARAM];
    IritExprType RetType;
} ObjFuncTableType;

typedef struct GenFuncTableType {
    char FuncName[FUNC_NAME_LEN];
    int FuncToken;
    void (*Func)();
    ByteType NumOfParam;
    IritExprType ParamObjType[FUNC_MAX_PARAM];
    IritExprType RetType;
} GenFuncTableType;

typedef struct ConstantTableType {
    char FuncName[FUNC_NAME_LEN];
    RealType Value;
} ConstantTableType;

typedef struct UserDefinedFuncDefType {
    struct UserDefinedFuncDefType *Pnext;
    char FuncName[FUNC_NAME_LEN];
    int IsFunction;
    int NumParams;
    IPObjectStruct *Params;
    IPObjectStruct *LocalVars;
    ParseTree *Body;
} UserDefinedFuncDefType;

/* The followings are defined in the InptEval.c module and are globals so   */
/* InptPrsr.c module will be able to access them...			    */
extern NumFuncTableType NumFuncTable[];
extern int NumFuncTableSize;
extern ObjFuncTableType ObjFuncTable[];
extern int ObjFuncTableSize;
extern GenFuncTableType GenFuncTable[];
extern int GenFuncTableSize;
extern ConstantTableType ConstantTable[];
extern int ConstantTableSize;
extern UserDefinedFuncDefType *UserDefinedFuncList;

/*****************************************************************************
* Tokens used in the expression	to tree	conversion and tree definition.	     *
*****************************************************************************/

#define	TOKENERROR  0
#define TOKEN_NONE  1

/* Warning - changing the order of these constants, needs updating the order */
/* of them, in the tables in the begining of InptPrsr.c & OverLoad.c modules.*/

typedef enum {
    USERFUNCDEF = 90,		       /* Function and procedure definition. */
    USERPROCDEF,
    USERINSTDEF
} UserDefinedFuncType;

#define USER_FUNC	0
#define IS_USER_FUNCTION(Token)		(Token >= USERFUNCDEF && \
					 Token <= USERINSTDEF)

typedef enum {				   /* Real value returned functions. */
    ARCCOS = 100,
    ARCSIN,
    ARCTAN2,
    ARCTAN,
    COS,
    EXP,
    FABS,
    LN,
    LOG,
    SIN,
    SQRT,
    TAN,
    CPOLY,
    AREA,
    VOLUME,
    TIME,
    LISTSIZE,
    THISOBJ
} RealValueFuncType;

#define NUM_FUNC    100
#define NUM_FUNC_OFFSET	100
#define IS_NUM_FUNCTION(Token)		(Token >= 100 && Token < 200)

typedef enum {				       /* Object returned Functions. */
    POINT = 200,
    VECTOR,
    PLANE,
    CTLPT,
    ROTX,
    ROTY,
    ROTZ,
    TRANS,
    SCALE,
    BOX,
    GBOX,
    CONE,
    CONE2,
    CYLIN,
    SPHERE,
    TORUS,
    CIRCPOLY,
    POLY,
    CROSSEC,
    SURFREV,
    EXTRUDE,
    LIST,
    LOAD,
    CONVEX,
    SBEZIER,
    CBEZIER,
    SBSPLINE,
    CBSPLINE,
    SEVAL,
    CEVAL,
    STANGENT,
    CTANGENT,
    SNORMAL,
    SDIVIDE,
    CDIVIDE,
    SREGION,
    CREGION,
    SREFINE,
    CREFINE,
    SRAISE,
    CRAISE,
    CSURFACE,
    CMESH,
    NTH,
    GPOLYGON,
    GPOLYLINE,
    CIRCLE,
    ARC,
    RULEDSRF,
    BOOLSUM,
    BOOLONE,
    SFROMCRVS,
    SWEEPSRF,
    OFFSET,
    AOFFSET,
    COERCE,
    CEDITPT,
    SEDITPT,
    MERGEPOLY,
    SMORPH,
    BZR2BSP,
    BSP2BZR,
    SMERGE,
    CDERIVE,
    SDERIVE,
    SNRMLSRF,
    SYMBPROD,
    SYMBDPROD,
    SYMBCPROD,
    SYMBSUM,
    SYMBDIFF,
    HOMOMAT,
    CINFLECT,
    CCRVTR,
    CZEROS,
    CEXTREMES,
    CCINTER,
    NIL,
    COORD,
    COMPOSE,
    PRISA,
    CRVPTDIST,
    CRVLNDIST,
    ADAPISO,
    PDOMAIN
} ObjValueFuncType;

#define OBJ_FUNC    200
#define OBJ_FUNC_OFFSET	200
#define IS_OBJ_FUNCTION(Token)		(Token >= 200 && Token < 300)

typedef enum {		   /* General Functions/No value returned functions. */
    EXIT = 300,
    VIEWOBJ,
    CHDIR,
    INCLUDE,
    SAVE,
    FREEOBJ,
    PAUSE,
    IFCOND,
    FORLOOP,
    PRHELP,
    VARLIST,
    SYSTEM,
    LOGFILE,
    COLOR,
    SNOC,
    ATTRIB,
    FFCOMPAT,
    IRITPRINT,
    COMMENT = 399
} GenValueFuncType;

#define GEN_FUNC    300
#define GEN_FUNC_OFFSET	300
#define IS_GEN_FUNCTION(Token)		(Token >= 300 && Token < 400)

#define IS_FUNCTION(Token)              (Token >= 90 && Token < 400)
#define IS_NO_PARAM_FUNC(Token)		(Token == EXIT || Token == VARLIST || \
					 Token == NIL)

typedef enum {						       /* Operators. */
    PLUS = 400,
    MINUS,
    MULT,
    DIV,
    POWER,
    UNARMINUS,
    EQUAL,
    COMMA,
    COLON,
    SEMICOLON,
    CMP_EQUAL,
    CMP_NOTEQUAL,
    CMP_LSEQUAL,
    CMP_GTEQUAL,
    CMP_GREAT,
    CMP_LESS,
    BOOL_AND,
    BOOL_OR,
    BOOL_NOT,

    OPENPARA = 430,					     /* Paranthesis. */
    CLOSPARA,

    NUMBER = 450,					    /* Numeric Data. */
    PARAMETER,					 /* Point on new/old object. */
    STRING,		     /* Sequence of characters within double quotes. */

    TOKENSTART = 490,
    TOKENEND
} GenericTokenType;

#define OPERATORS   400
#define OPERATORS_OFFSET	400

extern char IPGlblCharData[INPUT_LINE_LEN];   /* Used for both parse & eval. */
extern InptPrsrEvalErrType IPGlblEvalError;	 /* Global used by EvalTree. */

/*****************************************************************************
*   The local function (static) prototypes:				     *
*   Note that if DEBUG is defined for the preprocessor, few more function    *
* become available:							     *
*   Also note that some of the routines are defined globals as both the      *
* InptPrsr.c and InptEval.c modules needs them.				     *
*****************************************************************************/

ParseTree *ExprMalloc(void);
void ExprFree(ParseTree *Ptr);
void UpdateCharError(char *StrMsg, int Token);
void FileInclude(char *FileName);
IritExprType InptPrsrTypeCheck(ParseTree *Root, int Level);   /* Type check. */
ParseTree *InptPrsrEvalTree(ParseTree *Root, int Level);   /* Evaluate tree. */
void InptPrsrFreeTree(ParseTree *Root);			   /* Free all tree. */
void InptPrsrPrintTree(ParseTree *Root, char *str);	      /* print it... */
ParseTree *InptPrsrCopyTree(ParseTree *Root);			 /* Copy it. */
ParseTree *InptEvalFetchParameter(ParseTree *Root, int i, int n);
int InptEvalCountNumParameters(ParseTree *Root);

void InptEvalPrintHelp(char *HelpHeader);
ParseTree *InptEvalCompareObject(ParseTree *Root,
				 ParseTree *Left, ParseTree *Right,
				 InptPrsrEvalErrType *IError, char *CError);
void InptEvalIfCondition(ParseTree *Cond,
			 ParseTree *CondTrue, ParseTree *CondFalse);
void InptEvalForLoop(ParseTree *PStart, ParseTree *PInc, ParseTree *PEnd,
							 ParseTree *PBody);
IPObjectStruct *InptEvalGenObjectList(ParseTree *PObjParams);
IPObjectStruct *InptEvalCtlPtFromParams(ParseTree *PObjParams);
void InptEvalDefineFunc(ParseTree *FuncDef);
ParseTree *InptEvalUserFunc(ParseTree *Root, ParseTree *Params[]);

#endif	/* INPT_PRSR_LH */
