func (p *Parser) selectEnumerable(v *oop.Val, tk obj.Token, s interface{}) *oop.Val {
	switch v.Type {
	case oop.List:
		return selectList(v, s)
	case oop.Map:
		return selectMap(tk, v, s)
	case oop.String:
		return selectString(v, s)
	}
	return nil  
}
Select elements of enumerable object.
package parser
import (
	"fmt"
	"math"
	"math/big"
	"strings"
	"github.com/fract-lang/fract/oop"
	"github.com/fract-lang/fract/pkg/fract"
	"github.com/fract-lang/fract/pkg/obj"
)
func compareValues(operator string, left, right oop.Val) bool {
	if left.Type != right.Type &&
		(left.Type == oop.String || right.Type == oop.String) {
		return false
	}
	switch operator {
	case "==":
		return left.Equals(right)
	case "!=":
		return left.NotEquals(right)
	case ">":
		return left.Greater(right)
	case "<":
		return left.Less(right)
	case ">=":
		return left.GreaterEquals(right)
	case "<=":
		return left.LessEquals(right)
	}
	return false  
}
func compare(left, right oop.Val, operator obj.Token) bool {
	if operator.Val == "in" {
		if !right.IsEnum() {
			fract.IPanic(operator, obj.ValuePanic,
				"Value is should be enumerable!")
		}
		switch right.Type {
		case oop.List:
			leftStr := left.String()
			for _, elem := range *right.Data.(*oop.ListType) {
				if strings.Contains(elem.String(), leftStr) {
					return true
				}
			}
			return false
		case oop.Map:
			_, ok := (*right.Data.(*oop.MapType))[left]
			return ok
		}
		if left.Type == oop.List {
			rightStr := right.String()
			for _, elem := range *left.Data.(*oop.ListType) {
				if elem.Type != oop.String {
					fract.IPanic(operator, obj.ValuePanic,
						"All values is not string!")
				}
				if strings.Contains(rightStr, elem.String()) {
					return true
				}
			}
		} else {
			if right.Type != oop.String {
				fract.IPanic(operator, obj.ValuePanic,
					"All datas is not string!")
			}
			if strings.Contains(right.String(), left.String()) {
				return true
			}
		}
		return false
	}
	return compareValues(operator.Val, left, right)
}
func (p *Parser) prococessCondition(tokens []obj.Token) bool {
	trueVal := oop.Val{Data: true, Type: oop.Bool}
	orParts := conditionalProcessAST(tokens, "||")
	for orIndex, or := range orParts {
		andParts := conditionalProcessAST(or, "&&")
		if len(andParts) > 1 {
			var cont bool
			for _, and := range andParts {
				index, operator := findConditionOperator(and)
				if index == -1 {
					operator.Val = "=="
					if !compare(*p.processValTokens(and), trueVal, operator) {
						if orIndex == len(orParts)-1 {
							return false
						}
						cont = true
						break
					}
					continue
				}
				if index == 0 {
					fract.IPanic(and[0], obj.SyntaxPanic,
						"Comparison values are missing!")
				} else if index == len(and)-1 {
					fract.IPanic(and[len(and)-1], obj.SyntaxPanic,
						"Comparison values are missing!")
				}
				if !compare(
					*p.processValTokens(and[:index]),
					*p.processValTokens(and[index+1:]),
					operator) {
					if orIndex == len(orParts)-1 {
						return false
					}
					cont = true
					break
				}
			}
			if cont {
				continue
			}
			return true
		}
		index, operator := findConditionOperator(or)
		if index == -1 {
			operator.Val = "=="
			if compare(*p.processValTokens(or), trueVal, operator) {
				return true
			}
			continue
		}
		if index == 0 {
			fract.IPanic(or[0], obj.SyntaxPanic,
				"Comparison values are missing!")
		} else if index == len(or)-1 {
			fract.IPanic(or[len(or)-1], obj.SyntaxPanic,
				"Comparison values are missing!")
		}
		if compare(
			*p.processValTokens(or[:index]),
			*p.processValTokens(or[index+1:]),
			operator) {
			return true
		}
	}
	return false
}
func arithmetic(tk obj.Token, val oop.Val) float64 {
	switch val.Type {
	case oop.Func,
		oop.Package,
		oop.StructDef,
		oop.ClassDef,
		oop.ClassIns,
		oop.None:
		fract.IPanic(tk, obj.ArithmeticPanic,
			"\""+val.String()+"\" is not compatible with arithmetic processes!")
	case oop.Map:
		fract.IPanic(tk, obj.ArithmeticPanic,
			"\"object.map\" is not compatible with arithmetic processes!")
	case oop.StructIns:
		fract.IPanic(tk, obj.ArithmeticPanic,
			"\"object.structins\" is not compatible with arithmetic processes!")
	case oop.Pointer:
		fract.IPanic(tk, obj.ArithmeticPanic,
			"\"pointer\" is not compatible with arithmetic processes!")
	case oop.Bool:
		if val.Data.(bool) {
			return 1
		}
		return 0
	}
	return val.Data.(float64)
}
type arithmeticProcess struct {
	left     []obj.Token
	leftVal  oop.Val
	right    []obj.Token
	rightVal oop.Val
	operator obj.Token
}
func (p arithmeticProcess) solveString() oop.Val {
	if p.leftVal.Type != p.rightVal.Type {
		fract.IPanic(p.operator, obj.ArithmeticPanic, "Invalid data types!")
	}
	val := oop.Val{Type: oop.String}
	switch p.operator.Val {
	case "+":
		val.Data = p.leftVal.String() + p.rightVal.String()
	default:
		fract.IPanic(p.operator, obj.ArithmeticPanic,
			"This operator is not defined for string types!")
	}
	return val
}
func (p arithmeticProcess) solveBothList() oop.Val {
	leftLen := p.leftVal.Len()
	rightLen := p.rightVal.Len()
	val := oop.Val{Type: oop.List}
	if leftLen == 0 {
		val.Data = p.rightVal.Data
		return val
	} else if rightLen == 0 {
		val.Data = p.leftVal.Data
		return val
	}
	if leftLen != rightLen && leftLen != 1 && rightLen != 1 {
		fract.IPanic(p.right[0], obj.ArithmeticPanic,
			"List element count is not one or equals to first list!")
	}
	for index, elem := range *p.leftVal.Data.(*oop.ListType) {
		var right oop.Val
		if rightLen == 1 {
			right = (*p.rightVal.Data.(*oop.ListType))[0]
		} else {
			right = (*p.rightVal.Data.(*oop.ListType))[index]
		}
		if elem.Type == oop.List || right.Type == oop.List {
			proc := arithmeticProcess{
				left:     p.left,
				right:    p.right,
				operator: p.operator,
			}
			if elem.Type == oop.List {
				proc.leftVal = oop.Val{Data: elem.Data, Type: oop.List}
			} else {
				proc.leftVal = elem
			}
			if right.Type == oop.List {
				proc.rightVal = oop.Val{Data: right.Data, Type: oop.List}
			} else {
				proc.rightVal = right
			}
			(*p.leftVal.Data.(*oop.ListType))[index] = readyData(p, oop.Val{
				Data: proc.solve().Data,
				Type: oop.List,
			})
			continue
		}
		(*p.leftVal.Data.(*oop.ListType))[index] = readyData(p, oop.Val{
			Data: solveArithmeticProcess(p.operator,
				arithmetic(p.operator, elem), right.Data.(float64)),
			Type: oop.Int,
		})
	}
	val.Data = p.leftVal.Data
	return val
}
func (p arithmeticProcess) solveOneSideList() oop.Val {
	leftLen := p.leftVal.Len()
	rightLen := p.rightVal.Len()
	val := oop.Val{Type: oop.List}
	if p.leftVal.Type == oop.List && leftLen == 0 {
		val.Data = p.rightVal.Data
		return val
	} else if p.rightVal.Type == oop.List && rightLen == 0 {
		val.Data = p.leftVal.Data
		return val
	}
	left, right := p.leftVal, p.rightVal
	if left.Type != oop.List {
		left, right = right, left
	}
	arith := arithmetic(p.operator, right)
	for i, elem := range *left.Data.(*oop.ListType) {
		if elem.Type == oop.List {
			(*left.Data.(*oop.ListType))[i] = readyData(p, arithmeticProcess{
				left:     p.left,
				leftVal:  right,
				right:    p.right,
				rightVal: elem,
				operator: p.operator,
			}.solve())
			continue
		}
		(*left.Data.(*oop.ListType))[i] = readyData(p, oop.Val{
			Data: solveArithmeticProcess(p.operator,
				arithmetic(p.operator, elem), arith),
			Type: oop.Int,
		})
	}
	return left
}
func (p arithmeticProcess) solve() oop.Val {
	switch {
	case p.leftVal.Len() != 0 && p.leftVal.Type == oop.String ||
		p.rightVal.Len() != 0 && p.rightVal.Type == oop.String:
		return p.solveString()
	case p.leftVal.Type == oop.List && p.rightVal.Type == oop.List:
		return p.solveBothList()
	case p.leftVal.Type == oop.List || p.rightVal.Type == oop.List:
		return p.solveOneSideList()
	}
	return readyData(p, oop.Val{
		Data: solveArithmeticProcess(p.operator,
			arithmetic(p.operator, p.leftVal),
			arithmetic(p.operator, p.rightVal)),
		Type: oop.Int,
	})
}
func solveArithmeticProcess(operator obj.Token, left, right float64) float64 {
	switch operator.Val {
	case "+":
		return left + right
	case "-":
		return left - right
	case "*":
		return left * right
	case "/":
		if left == 0 || right == 0 {
			fract.Panic(operator, obj.DivideByZeroPanic, "Divide by zero!")
		}
		return left / right
	case "|":
		return float64(int(left) | int(right))
	case "&":
		return float64(int(left) & int(right))
	case "^":
		return float64(int(left) ^ int(right))
	case "**":
		return math.Pow(left, right)
	case "%":
		return math.Mod(left, right)
	case "<<":
		if right < 0 {
			fract.IPanic(operator, obj.ArithmeticPanic,
				"Shifter is cannot should be negative!")
		}
		return float64(int(left) << int(right))
	case ">>":
		if right < 0 {
			fract.IPanic(operator, obj.ArithmeticPanic,
				"Shifter is cannot should be negative!")
		}
		return float64(int(left) >> int(right))
	case "&^":
		return float64(uint64(left) &^ uint64(right))
	default:
		fract.IPanic(operator, obj.SyntaxPanic, "Operator is invalid!")
	}
	return 0  
}
func readyData(process arithmeticProcess, val oop.Val) oop.Val {
	if process.leftVal.Type == oop.String ||
		process.rightVal.Type == oop.String {
		val.Type = oop.String
	} else if process.operator.Val == "/" ||
		process.leftVal.Type == oop.Float ||
		process.rightVal.Type == oop.Float {
		val.Type = oop.Float
	}
	return val
}
func selectList(v *oop.Val, s interface{}) *oop.Val {
	return &(*v.Data.(*oop.ListType))[s.(int)]
}
func selectMap(tk obj.Token, v *oop.Val, s interface{}) *oop.Val {
	m := *v.Data.(*oop.MapType)
	val, ok := m[s.(oop.Val)]
	if !ok {
		fract.IPanic(tk, obj.ValuePanic, "Key is not exists!")
	}
	return &val
}
func selectString(v *oop.Val, s interface{}) *oop.Val {
	return &oop.Val{
		Data: string(v.String()[s.(int)]),
		Type: oop.String,
	}
}