// 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 списЛит []*мЛит.Литера списЛитКоммент []*мЛит.Литера } // НовМодуль -- возвращает новый модуль 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 литера.Знач() == ";" { // Возможно имя закончилось if имяПоиск != сам.имя { return мФорм.Errorf("Модуль.найтиНачало(): имя('%v')!=имя_модуля('%v')", имяПоиск, сам.имя) } } 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 }