#ifndef INCLUDED_SEMVAL_
#define INCLUDED_SEMVAL_

#include "../../rss/rss.h"

#include "private"

#define YYSTYPE SemVal

SemVal SVzero(void);                // e_null (0) initialized SemVal
SemVal SVint(int value);            // e_int | e_const value. 

                                    // e_int from atoi(char const *)
                                    // or e_str from stringIdx. e_list
                                    // initializations by series of 
SemVal SVtype(ExprType type, ...);// strings                            (0.c)

    // SemVal initialized with function argument arg (arg grabbed and
    // converted to code by svSemVal3   
SemVal SVarg(SemVal *arg);          //      ARG CONVERTED TO CODE   (0.c)

SemVal SVmove(SemVal *src);

void svDestroy(SemVal *sp);         // sets *sp to SVzero()

void svBool2int(SemVal *sv);

void svGrabFalse(unsigned **list, unsigned *len, SemVal *sv);
void svSetFalse(SemVal *sv, unsigned *list, unsigned len);

void svPtrSwap(SemVal **one, SemVal **two);
void svSwapTrueFalse(SemVal *sv);

void svPopVar(SemVal *sv);              // patch an op_pop_var instruction
                                        // into the code

int8_t const *svCode(SemVal const *sv);

                                        // return a pointer to the idx-th 
                                        // SemVal in sv's Semval argument
                                        // structure 
SemVal const *svArg(SemVal const *sv, unsigned idx);            // 1.c

unsigned svCodeLength(SemVal const *sv);

    // see ../parser/README.args
    // arg is grabbed, converted to code, and added to sv's argument structure 
    // returning the new structure
SemVal smvAddArg(SemVal *sv, SemVal *arg);      // ARGS CONVERTED TO CODE
                                        
    // Each of the args of the SemVal argument structure is converted to code
    // (pushing their values on the (icm_exec) run-time stack), 
    // destroying args and returning the SemVal argument structure containing
    // the arguments converted to code.
SemVal smvArgs2code(SemVal *args);           
                                      
    // change sv so that its expression value is pushed on the 
    // (icm-exec) stack: this function generates code 
void svPushStack(SemVal *sv);

    // append the code of count arguments, in reversed order, appending
    // the code of the SemVals of the args structure are destroyed, args
    // itself isn't. 
    // The SemVals at args must already have been converted to code
void svPushArgsSubset(SemVal *sv, SemVal *args, unsigned begin, 
                                                unsigned count);

    // shortcut of the previous function, appending the code of all args
    // in reversed order to sv
    // the args structure is destroyed.
void svPushArgs(SemVal *sv, SemVal *args);


    // returns args1's args + arg2's args (both destroyed)
    // e1 and e2 must already contain code pushing their values on the run-time
    // (icm-exec) stack.
SemVal smvJoinArgs(SemVal *args1, SemVal *args2);

void svCatenate(SemVal *e1, SemVal *e2);    // return e1's code | e2's code
                                            // (e2 destroyed)

    // returns sv's code to which opcode and its argument(s) are appended
void svAddCode(SemVal *sv, Opcode opcode, ...);

void svRmJmpZero(SemVal *sv);

void svPatchupTrue(SemVal *sv, int pos);
void svPatchupFalse(SemVal *sv, int pos);
void svPatchupContinue(SemVal *sv, int pos);

void svSetType(SemVal *sv, ExprType type);
void svSetValue(SemVal *sv, int value);

ExprType svType(SemVal const *sv);          //                          1.c
int      svValue(SemVal const *sv);

                                    // returns sv's type & oredExp.
unsigned svTestType(SemVal const *sv, unsigned oredExprTypeValues);


void svShow(SemVal const *sv);       // show sv to stderr

int svCopyVar();                    // 1 if op_copy_var was the last opcode

#endif
