# coding:utf8
"""
Содержит тип для разбора констант.
"""

if True:
	from пакОберон.пакКомпилятор.пакСущность.пакСлово import тСлово
	from пакОберон.пакКомпилятор.пакСущность.пакКонстанта import тКонстанта
	from пакОберон.пакКомпилятор.пакСущность.пакОшибка import тОшибка

class тКонстПоле:
	def __init__(сам, пОберон, пДанные):
		сам.__оберон = пОберон
		сам.__конс = пОберон.конс
		сам.__конс.Отладить("тКонстПоле.__init__()")

		сам.ош = тОшибка(пОберон, "тКонстПоле")

		if пДанные['секция'] != "CONST":
			стрСообщ = "Использование типа не в своей секции, секцйия=" + пДанные['секция']
			сам.ош.Внутр("__init__()", стрСообщ)
			return
		сам.слова_секции : dict = пДанные['слова']
		сам.__имя : str = "" # имя константы
		сам.__имя_слово : тСлово = None
		сам.__бЭкспорт : bool = False
		сам.__бЭкспорт_слово : тСлово = None
		сам.__выраж :dict = {} # Выражение для вычисления константы

		if сам.__Имя_Проверить():
			сам.ош.Внутр("__init__()", "При проверке имени константы")
			return
		if сам.__Экспорт_Проверить():
			сам.ош.Внутр("__init__()", "При проверке экспорта")
			return
		сам.__Проверить_Равно()
		сам.__Выраж_Заполнить()

		парам = {}
		парам['слово']     = сам.__имя_слово
		парам['бЭкспорт']  = сам.__бЭкспорт
		парам['выраж']     = сам.__выраж
		парам['модуль_имя']= пДанные['модуль_имя']
		сам.__конст = тКонстанта(пОберон, парам)
		if сам.__конст.ош.бВнутр:
			сам.ош.Внутр("__init__()", "При создании тКонстанта")
			return

	def __Имя_Проверить(сам)->bool:
		"""
		Выясняет правильность имени константы.
		"""
		слово_имя = сам.слова_секции[0]
		#имя = слово_имя.Проверить()
		if type(сам.__имя) == None:
			стрОш = "Имя константы уже присвоено" + сам.__имя.стрИсх
			сам.ош.Исх("__Имя_Проверить()", стрОш)
			return True
		if слово_имя.ЕслиИмя_Строго():
			сам.__имя = слово_имя.строка
			сам.__имя_слово = слово_имя
			сам.__СловаСекции_Обрезать()
			return False
		else:
			if not слово_имя.ЕслиИмя():
				стрСообщ = "Имя поля должно быть допустимым именем" + слово_имя.стрИсх
				сам.ош.Исх("__Имя_Проверить()", стрСообщ)
				return True

	def __Экспорт_Проверить(сам)->bool:
		"""
		Проверяет является ли константа экспортируемой.
		"""
		слово_экспорт = сам.слова_секции[0]
		if type(сам.__бЭкспорт_слово) == None:
			стрОщ = "Экспорт уже присвоен"+сам.__бЭкспорт_слово.стрИсх
			сам.ош.Исх("__Экспорт_Проверить()", стрОщ)
			return True
		if слово_экспорт.род == тСлово.кУмножить: # есть экспорт
			сам.__бЭкспорт = True
			сам.__бЭкспорт_слово = слово_экспорт
			сам.__СловаСекции_Обрезать()
			return False
		elif слово_экспорт.род == тСлово.кРавно:
			return False # это определение константы, дальше присвоение
		else:
			сам.ош.Исх("__Экспорт_Проверить()", "Символ экспорта допустим '*' или '='" + слово_экспорт.стрИсх)
			return

	def __Проверить_Равно(сам):
		"""
		Проверяет литеру равно в константах.
		"""
		слово_равно = сам.слова_секции[0]
		if слово_равно.род == тСлово.кРавно: # есть уравнивание
			сам.__СловаСекции_Обрезать()
		else:
			сам.ош.Исх("__Проверить_Равно()", "Литера приравнивания должен быть '='" + слово_равно.стрИсх)
			return

	def __Выраж_Заполнить(сам):
		"""
		Пока не встретится ";" -- заполнять выражение
		"""
		слово_равно = сам.слова_секции[0]
		while not (слово_равно.род == тСлово.кТочкаЗапятая):
			сам.__СловаСекции_Обрезать()
			сам.__выраж[len(сам.__выраж)] = слово_равно
			слово_равно = сам.слова_секции[0]
		сам.__СловаСекции_Обрезать() # Откидываем завершающий разделитель

	def __СловаСекции_Обрезать(сам):
		"""
		Уменьшает слова секции на 1 с головы.
		"""
		новый_список = {}
		for ключ in range(1, len(сам.слова_секции)):
			новый_список[ключ-1]=сам.слова_секции[ключ]
		сам.слова_секции = {}
		сам.слова_секции = новый_список

	def Паспорт_Печать(сам):
		"""
		Печает паспорт константы со всеми атрибутами
		"""
		сам.__конс.Печать("\n+ Константа: "+сам.__имя)
		if сам.__бЭкспорт:
			сам.__конс.Печать("|   бЭкспорт=", сам.__бЭкспорт)
		if len(сам.__выраж) > 0:
			строка = ""
			for ключ in сам.__выраж:
				строка += " " +сам.__выраж[ключ].строка
			сам.__конс.Печать("|   Выраж ="+строка)
		сам.__конс.Печать("+"+"-"*35)

	@property
	def имя(сам)->str:
		return сам.__имя

	@property
	def бЭкспорт(сам)->bool:
		return сам.__бЭкспорт

	@property
	def выраж(сам):
		"""
		Возвращает список слов для анализа константы
		"""
		return сам.__выраж

	@property
	def конст(сам):
		return сам.__конст
