// Generated by Bisonc++ V6.03.00 on Thu, 05 Mar 2020 17:53:53 +0100

#ifndef Parser_h_included
#define Parser_h_included

#include "parserbase.h"

#include "../exprtype/exprtype.h"
#include "../scanner/scanner.h"
#include "../functions/functions.h"
#include "../symtab/symtab.h"
#include "../stringstore/stringstore.h"

class Parser: public ParserBase
{
    // $insert scannerobject
    Scanner d_scanner;

    Functions d_functions;
    Symtab d_symtab;

    ExprType d_type;                    // last received type specification

    SemVal d_initCode;                  // global initialization code

    uint16_t d_breakOK = 0;             // (nested) break/continue is OK
    int d_token;                        // token produced by lex()

    public:
        Parser(char const *input);
        int parse();

        Scanner const &scanner() const;                         // all: .f
        Functions const &functions() const;
        Symtab const &symtab() const;

    private:
        SemVal variable(std::string const &name);
        SemVal defineVar(SemVal &lhs, SemVal &expr);

        void functionHead();
        void functionDefined(SemVal &body);

        SemVal functionReturn(SemVal &expr) const;
        SemVal function(std::string const &name, Args &&args) const;

        SemVal index(SemVal &lhs, SemVal &rhs) const;

        SemVal shiftOrPrint(SemVal &lhs, 
                            Opcode::Byte opcode, SemVal &rhs) const;

                                                                    // .f (ih)
        SemVal binary(SemVal &lhs, Opcode::Byte opcode, SemVal &rhs) const;


        SemVal ifStmnt(Args &cond, SemVal &trueStmnt, SemVal &falseStmnt);
        SemVal forStmnt(Args &&init, SemVal &cond, Args &&inc, SemVal &stmnt);

        SemVal exprStmnt(SemVal &expr) const;
                                                        // also handles exit()
        SemVal returnStmnt(Tokens::Tokens_ token, SemVal &expr) const;
    
        SemVal checkBreakOK() const;
        SemVal breakStmnt() const;
        SemVal continueStmnt() const;

        SemVal pushPrint(SemVal &expr) const;   // handle (f)printf insertions

        void push();                    // pushes symtab and SemVal's pushDead
        void pop();                     // pops the previous level

        static SemVal catStatements(SemVal &stmnts, SemVal &stmnt);
        static void semValPopPush();    // reset SemVal's deadCode stack

    // Parser's own members:

        void error();                   // called on (syntax) errors
        int lex();                      // returns the next token from the
                                        // lexical scanner. 
        void print();                   // use, e.g., d_token, d_loc
        void exceptionHandler(std::exception const &exc);


    // support functions for parse():
        void executeAction_(int ruleNr);
        void errorRecovery_();
        void nextCycle_();
        void nextToken_();
        void print_();
};

#include "scanner.f"
#include "functions.f"
#include "symtab.f"

#endif
