#ifndef __AST__STATEMENT_H
#define __AST__STATEMENT_H

#include <iostream>
#include <vector>
class Type;
class ArithmeticExpression;
class BooleanExpression;
class LValue;
class RValue;


class Statement
{
    public:
        virtual ~Statement() = 0;
        virtual void dump(std::ostream& os, int depth) = 0;
};

class Block : public Statement
{
    public:
        std::vector<Statement*>* statements;

        Block(std::vector<Statement*>* statements);
        ~Block();
        void dump(std::ostream& os, int depth) override;
};

class VarDeclaration : public Statement
{
    public:
        Type* type;
        std::string* name;
        RValue* value;

        VarDeclaration(Type* type, std::string* name, RValue* value);
        ~VarDeclaration();
        void dump(std::ostream& os, int depth) override;
};

class Assignment : public Statement
{
    public:
        LValue* lvalue;
        RValue* rvalue;

        Assignment(LValue* lvalue, RValue* rvalue);
        ~Assignment();
        void dump(std::ostream& os, int depth) override;
};

class Input : public Statement
{
    public:
        LValue* lvalue;

        Input(LValue* lvalue);
        ~Input();
        void dump(std::ostream& os, int depth) override;
};

class Output : public Statement
{
    public:
        RValue* rvalue;

        Output(RValue* rvalue);
        ~Output();
        void dump(std::ostream& os, int depth) override;
};

class IfThenElse : public Statement
{
    public:
        BooleanExpression* condition;
        Statement* thenCase;
        Statement* elseCase;

        IfThenElse(BooleanExpression* condition, Statement* thenCase, Statement* elseCase);
        ~IfThenElse();
        void dump(std::ostream& os, int depth) override;
};

class WhileLoop : public Statement
{
    public:
        BooleanExpression* condition;
        Statement* body;

        WhileLoop(BooleanExpression* condition, Statement* body);
        ~WhileLoop();
        void dump(std::ostream& os, int depth) override;
};


#endif
