| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115 |
- // package module -- тип модуля для компилятора
- package module
- import (
- мФорм "fmt"
- мЛог "log"
- мОс "os"
- мСтр "strings"
- мЛит "p78git.ddns.net/svi/odeft/internal/module/litera"
- мАлиас "p78git.ddns.net/svi/odeft/pkg/alias"
- мКонст "p78git.ddns.net/svi/odeft/pkg/cons"
- )
- // Модуль -- тип модуля для компилятора
- type Модуль struct {
- имя string
- имяФайла string
- списЛит []*мЛит.Литера
- списЛитКоммент []*мЛит.Литера
- }
- // НовМодуль -- возвращает новый модуль
- func НовМодуль(имяФайла string) (*Модуль, error) {
- if имяФайла == "" {
- return nil, мФорм.Errorf("НовМодуль(): имя файла модуля пустое")
- }
- списИмяФайла := мСтр.Split(имяФайла, "/")
- имя := списИмяФайла[len(списИмяФайла)-1]
- if имя == "" {
- return nil, мФорм.Errorf("НовМодуль(): имя модуля пустое")
- }
- if !мСтр.HasSuffix(имяФайла, ".ou") {
- return nil, мФорм.Errorf("НовМодуль(): имя файла модуля(%v) имеет неправильное окончание", имяФайла)
- }
- имя = мСтр.TrimSuffix(имя, ".ou")
- сам := &Модуль{
- имяФайла: имяФайла,
- имя: имя,
- списЛит: []*мЛит.Литера{},
- списЛитКоммент: []*мЛит.Литера{},
- }
- if ош := сам.файлПрочитать(); ош != nil {
- return nil, мФорм.Errorf("НовМодуль(): при чтении файла, ош=\n\t%w", ош)
- }
- if ош := сам.найтиНачало(); ош != nil {
- return nil, мФорм.Errorf("НовМодуль(): при поиске начала модуля ('%v'), ош=\n\t%w", сам.имя, ош)
- }
- return сам, nil
- }
- // Ищет в литерах начало модуля
- func (сам *Модуль) найтиНачало() error {
- { // Поиск начала имени модуля
- адр := -1
- словоКонтр := []rune("модуль ")
- еслиНайдено := false
- for {
- if len(сам.списЛит) == 0 {
- break
- }
- адр++
- литера := сам.списЛит[0]
- сам.списЛит = сам.списЛит[1:]
- if литера.Тип() != мКонст.Буква {
- сам.списЛитКоммент = append(сам.списЛитКоммент, литера)
- сам.списЛит = сам.списЛит[1:]
- continue
- }
- if литера.Знач() == мАлиас.Литера(словоКонтр[0]) {
- словоКонтр = словоКонтр[1:]
- if len(словоКонтр) == 0 {
- мЛог.Printf("Модуль.найтиНачало(): начало модуля найдено")
- еслиНайдено = true
- break
- }
- continue
- }
- словоКонтр = []rune("модуль ")
- }
- if !еслиНайдено {
- return мФорм.Errorf("Модуль.найтиНачало(): не найдено начало модуля")
- }
- }
- { // Теперь определить наличие разделителя
- имяПоиск := мАлиас.Литера("")
- for {
- литера := сам.списЛит[0]
- if литера.Тип() != мКонст.Буква {
- return мФорм.Errorf("Модуль.найтиНачало(): за ключевым словом 'модуль' нет имени модуля")
- }
- имяПоиск += литера.Знач()
- сам.списЛит = сам.списЛит[1:]
- }
- }
- }
- // Читает текст исходного файла
- func (сам *Модуль) файлПрочитать() error {
- бинДанные, ош := мОс.ReadFile(сам.имяФайла)
- if ош != nil {
- return мФорм.Errorf("Модуль.файлПрочитать(): при чтении файла(`%v`), ош=\n\t%w", сам.имяФайла, ош)
- }
- стрДанные := string(бинДанные)
- for _, _руна := range стрДанные {
- руна, ош := мЛит.НовЛитера(мАлиас.Литера(_руна))
- if ош != nil {
- return мФорм.Errorf("Модуль.файлПрочитать(): при создании руны(`%v`), ош=\n\t%w", string(_руна), ош)
- }
- сам.списЛит = append(сам.списЛит, руна)
- }
- мЛог.Printf("Модуль.файлПрочитать(): всего рун в модуле '%v' = %v\n", сам.имя, len(сам.списЛит))
- return nil
- }
|