/****************************************************************************
**
*W  exprs.h                     GAP source                   Martin Schönert
**
**
*Y  Copyright (C)  1996,  Lehrstuhl D für Mathematik,  RWTH Aachen,  Germany
*Y  (C) 1998 School Math and Comp. Sci., University of St Andrews, Scotland
*Y  Copyright (C) 2002 The GAP Group
**
**  This file declares the functions of the expressions package.
**
**  The expressions  package is the  part  of the interpreter  that evaluates
**  expressions to their values and prints expressions.
*/

#ifndef libGAP_GAP_EXPRS_H
#define libGAP_GAP_EXPRS_H


/****************************************************************************
**
*F  OBJ_REFLVAR(<expr>) . . . . . . . . . . . value of a reference to a local
**
**  'OBJ_REFLVAR'  returns  the value of  the reference  to a  local variable
**  <expr>.
*/
#ifdef  NO_LVAR_CHECKS
#define libGAP_OBJ_REFLVAR(expr)       \
                        libGAP_OBJ_LVAR( libGAP_LVAR_REFLVAR( (expr) ) )
#endif
#ifndef NO_LVAR_CHECKS

#ifdef libGAP_SYS_IS_64_BIT
#define libGAP_OFFSET_REFLVAR(expr)  (((expr)*2)+10)
#else
#define libGAP_OFFSET_REFLVAR(expr)  ((expr) + 5)
#endif

#define libGAP_OBJ_REFLVAR(expr)       \
                        (*(libGAP_Obj*)(((char*)libGAP_TLS(libGAP_PtrLVars))+libGAP_OFFSET_REFLVAR(expr)) != 0 ? \
                         *(libGAP_Obj*)(((char*)libGAP_TLS(libGAP_PtrLVars))+libGAP_OFFSET_REFLVAR(expr)) : \
                         libGAP_ObjLVar( libGAP_LVAR_REFLVAR( expr ) ) )
#endif


/****************************************************************************
**
*F  OBJ_INTEXPR(<expr>) . . . . . . . . . . .  value of an integer expression
**
**  'OBJ_INTEXPR' returns the (immediate)  integer  value of the  (immediate)
**  integer expression <expr>.
**
**  'OBJ_INTEXPR(<expr>)'  should  be 'OBJ_INT(INT_INTEXPR(<expr>))', but for
**  performance  reasons we implement  it   as '(Obj)(<expr>)'.  This is   of
**  course    highly  dependent  on    (immediate)  integer   expressions and
**  (immediate) integer values having the same representation.
*/

#ifndef libGAP_SYS_IS_64_BIT
#define libGAP_OBJ_INTEXPR(expr)       \
                        ((libGAP_Obj)(libGAP_Int)(libGAP_Int4)(expr))
#else
#define libGAP_OBJ_INTEXPR(expr)       \
                        (libGAP_INTOBJ_INT(libGAP_INT_INTEXPR((expr))))
#endif

/****************************************************************************
**
*F  EVAL_EXPR(<expr>) . . . . . . . . . . . . . . . .  evaluate an expression
**
**  'EVAL_EXPR' evaluates the expression <expr>.
**
**  'EVAL_EXPR' returns the value of <expr>.
**
**  'EVAL_EXPR'  causes  the   evaluation of   <expr> by  dispatching  to the
**  evaluator, i.e., to  the function that evaluates  expressions of the type
**  of <expr>.
**
**  Note that 'EVAL_EXPR' does not use 'TNUM_EXPR', since it also handles the
**  two special cases that 'TNUM_EXPR' handles.
*/
#define libGAP_EVAL_EXPR(expr) \
                        (libGAP_IS_REFLVAR(expr) ? libGAP_OBJ_REFLVAR(expr) : \
                         (libGAP_IS_INTEXPR(expr) ? libGAP_OBJ_INTEXPR(expr) : \
                          (*libGAP_EvalExprFuncs[ libGAP_TNUM_STAT(expr) ])( expr ) ))


/****************************************************************************
**
*V  EvalExprFuncs[<type>]  . . . . . evaluator for expressions of type <type>
**
**  'EvalExprFuncs'  is the dispatch table   that contains for  every type of
**  expressions a pointer  to the  evaluator  for expressions of this   type,
**  i.e., the function that should be  called to evaluate expressions of this
**  type.
*/
extern  libGAP_Obj             (* libGAP_EvalExprFuncs [256]) ( libGAP_Expr expr );


/****************************************************************************
**
*F  EVAL_BOOL_EXPR(<expr>)  . . . . evaluate an expression to a boolean value
**
**  'EVAL_BOOL_EXPR' evaluates   the expression  <expr> and  checks  that the
**  value is either  'true' or 'false'.  If the  expression does not evaluate
**  to 'true' or 'false', then an error is signalled.
**
**  'EVAL_BOOL_EXPR' returns the  value of <expr> (which  is either 'true' or
**  'false').
*/
#define libGAP_EVAL_BOOL_EXPR(expr) \
                        ( (*libGAP_EvalBoolFuncs[ libGAP_TNUM_EXPR( expr ) ])( expr ) )


/****************************************************************************
**
*V  EvalBoolFuncs[<type>] . . boolean evaluator for expression of type <type>
**
**  'EvalBoolFuncs'  is  the dispatch table that  contains  for every type of
**  expression a pointer to a boolean evaluator for expressions of this type,
**  i.e., a pointer to  a function which  is  guaranteed to return a  boolean
**  value that should be called to evaluate expressions of this type.
*/
extern  libGAP_Obj             (* libGAP_EvalBoolFuncs [256]) ( libGAP_Expr expr );


/****************************************************************************
**
*F  PrintExpr(<expr>) . . . . . . . . . . . . . . . . . . print an expression
**
**  'PrintExpr' prints the expression <expr>.
*/
extern  void            libGAP_PrintExpr (
            libGAP_Expr                expr );


extern void libGAP_PrintRecExpr1 ( libGAP_Expr expr ); /* needed for printing
                                          function calls with options */

/****************************************************************************
**
*V  PrintExprFuncs[<type>]  . .  printing function for objects of type <type>
**
**  'PrintExprFuncs' is the dispatching table that contains for every type of
**  expressions a pointer to the printer for expressions  of this type, i.e.,
**  the function that should be called to print expressions of this type.
*/
extern  void            (* libGAP_PrintExprFuncs [256] ) ( libGAP_Expr expr );


/****************************************************************************
**

*F * * * * * * * * * * * * * initialize package * * * * * * * * * * * * * * *
*/


/****************************************************************************
**

*F  InitInfoExprs() . . . . . . . . . . . . . . . . . table of init functions
*/
libGAP_StructInitInfo * libGAP_InitInfoExprs ( void );


#endif // GAP_EXPRS_H

/****************************************************************************
**

*E  exprs.c . . . . . . . . . . . . . . . . . . . . . . . . . . . . ends here
*/
