/*
CLASS {Statement}, ABSTRACT, RECURSIVE, UNTESTED :

IMPORT: {Type}, {Function}, {Expression} ;
IMPORT: {Assignment}, {For}, {Case} ; //, {Local} ; 

*/

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using AL4Compiler.Statements;

namespace AL4Compiler
{
    public class Statement
    {
        /*
        
        ENUM {work|flow}:
			'ASSIGN|MENT',
			'APPEND|_TO_ARRAY_OR_STR',
			'OUTPUT|_TO_CONSOLE',
			'INPUT|_FROM_CONSOLE',
			'BREAK|_LOOP', 
			'CONTINUE', 
			'NEXT|_INDEX_AND_CONTINUE', 
			'RETURN|_FROM_FUNCTION',
			'CASE|_BLOCK',
			'ELSE|_CASE', 
			'LIMIT|_TIME_FUN_LOOP',
			'LOCAL|_BLOCK',
			'FOR|_LOOP',  
			'PUSH|_VARIABLE',
			'STOP|_EXECUTION',
			'CALL_NATIVE|_FUNCTION_IN_INTERPRETATOR',
			'ASSERT|ION',
			'DEBUG|_BLOCK',
			'COMMENT|_SEPARATOR'.
        */
        public enum Workflow { ASSIGNMENT, APPEND, OUTPUT, INPUT,
            BREAK, CONTINUE,
            RETURN, CASE, ELSE, FOR, FOREVER, PUSH, STOP, ASSERT, DEBUG, 
            COMMENT_BLOCK };

        /*
        {Fun}           Function_|where_statement_is_from_, INIT
        INT				Level|_of_statements_block, INIT
        
        {work}          Work|flow
        {Statement}     Block_|nested_[]
        STR		Starting_bracket
        INT             Line|_in_source INDEXING (STR, INT) , INIT
        INT				Pos|ition_in_line //, INIT
        --------------------------- 'optimization'
        INT		Index_in_fun|ction
        --------------------------- 'debug'
        STR             Inline_index|_assigned_to_inlining_function_statements
        INT             Total_stmt
        ------------------------------------- 'for operation CALL_NATIVE'
        INT				Native_f|unction_index_to_call
        
        CONSTRUCT:
			Total_stmt = Function_.Compiler.Total_st
			Function_.Compiler.Total_st += 1 .
        */

        public Workflow Work;
        public List<Statement> Block_ = new List<Statement>();
        public int Line;

        private static int TOTAL_stmt_index;
        public int Stmt_index;

        public Statement()
        {
            Stmt_index = ++TOTAL_stmt_index;
            if (Stmt_index == 3390)
            { }
        }

        /*
        
        METHOD Is_jump|ing_always ==> BOOL, RECURSIVE :
            CASE Work IN ['BREAK', 'CONTINUE', 'RETURN'] ?
                   RESULT = TRUE ==> ;
            CASE Work == 'CASE' ?
                 CASE Block_[*].Work != 'ELSE' && (
                     THIS.{Case}.Condition.Type_expr.Kind != 'ENUM')
                     ?
                     ==> ;
                 FOR c IN Block_[] :
                     CASE !c.Block_[*].Is_jump ? ==> ;
                 ;
                 RESULT = TRUE ; .
                 
METHOD Has_function_calls ==> BOOL, RECURSIVE :
	CASE Work ?
	['ASSIGN', 'APPEND', 'PUSH', 'OUTPUT', 'INPUT']: 
		RESULT = THIS.{Assign}.Dest.Has_function_calls
		RESULT ||= THIS.{Assign}.Source.Has_function_calls
		
	['CASE', 'LIMIT', 'LOCAL']: 
	    RESULT = THIS.{Case}.Condition.Has_function_calls
	
	['FOR']:
		RESULT = THIS.{For}.Array.Has_function_calls
		RESULT ||= THIS.{For}.Range1.Has_function_calls
		RESULT ||= THIS.{For}.Range2.Has_function_calls
		
	['CALL_NATIVE']: RESULT= TRUE
	
	['BREAK', 'NEXT', 'CONTINUE', 'RETURN', 'ELSE', 'STOP', 'ASSERT',
	 'DEBUG', 'COMMENT']: NONE 
	;
	CASE RESULT ? ==> ;
	FOR b IN THIS.Block_[] :
	    RESULT = b.Has_function_calls
	    CASE RESULT ? ==> ;
	; .
        */
        public bool Is_jump()
        {
            if (Work == Statement.Workflow.BREAK ||
                Work == Statement.Workflow.CONTINUE ||
                Work == Statement.Workflow.RETURN) return true;
            if (Work == Statement.Workflow.CASE)
            {
                if (Block_.Count > 0 && Block_[Block_.Count - 1].Work != Statement.Workflow.ELSE &&
                   ((Case)this).Condition != null && ((Case)this).Condition.Type_expr().Kind != Type.Kind_type.ENUM)
                    return false;
                foreach (Statement c in Block_)
                {
                    if (c.Block_.Count > 0 && !c.Block_[c.Block_.Count - 1].Is_jump()) return false;
                }
                return true;
            }
            return false;
        }
    }
}

/*

METHOD Test_output|_statement_CASE_only_yet //, DEBUG
	:
	<< "------------------- " Total_stmt.Str " Work == " Work.Name #NL
	STR in|put_d_u_m_m_y
	CASE THIS.{Case} != NONE && THIS.{Case}.Condition != NONE ?
	     THIS.{Case}.Condition.Test_output("  ") ;
	>> in 
	.
	     


 
END
*/

