модуль строки осторожно импорт "стд/юникод" /* формат-аргумента : ‘%’ уточнение? ‘вид’ ; вид : 'v' | 'd' | 'x' | 's' | '%' // 'f' | 'g' ; СДЕЛАН: 'v' */ //!! временно фн строка*(с: Строка) @внеш("имя":"print_string") фн символ*(с: Символ) @внеш("имя":"print_symbol") фн цел64*(ц: Цел64) @внеш("имя":"print_int64") фн слово64*(ц: Слово64) @внеш("имя":"print_word64") фн кс*() @внеш("имя":"println") тип Символы = []Символ тип Разборщик = класс { сб: Сборщик = позже формат: Символы = позже №-сим := 0 кол-во := 0 // формат аргумент: норм := истина ошибка := "" вид := 'v' } фн (сб: Сборщик) ф*(фс: Строка, список: ...*) { пусть р = Разборщик{сб: сб, формат: фс(:Символы) } р.кол-во := длина(р.формат) пусть №-арг := 0 пока р.следующий() { если №-арг >= длина(список) { авария("не достаточно аргументов") } // учесть ширину и точность из аргументов р.добавить аргумент(тег(список[№-арг]), нечто(список[№-арг])) №-арг++ } если №-арг < длина(список) { авария("слишком много аргументов") } } //=== добавление аргументов фн (р: Разборщик) добавить аргумент(аргТ: Слово64, арг: Слово64) { надо р.норм иначе { р.сб.добавить символ('*') р.сб.добавить строку(р.ошибка) р.сб.добавить символ('*') вернуть } когда р.вид { есть 'v': р.добавить нечто(аргТ, арг) иначе авария("не сделано") } } // Способ не задан, формат по умолчанию фн (р: Разборщик) добавить нечто(аргТ: Слово64, арг: Слово64) { когда аргТ { есть тег(Цел64): р.добавить целое10(арг(:осторожно Цел64)) есть тег(Слово64): р.добавить число10(арг, ложь) есть тег(Символ), тег(Символ): р.добавить строку("0x"); р.добавить число16(арг) есть тег(Строка): р.добавить строку(арг(:осторожно Строка)) иначе р.сб.добавить строку(" *не сделано: тег "); р.добавить число16(аргТ) } } фн (р: Разборщик) добавить строку(ст: Строка) { // TODO: обработать уточнение р.сб.добавить строку(ст) } фн (р: Разборщик) добавить целое10(ц: Цел64) { р.добавить число10(ц(:осторожно Слово64), ц < 0) } фн (р: Разборщик) добавить число10(к: Слово64, нег: Лог) { если нег { к := -к } пусть б := Байты[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,] //21 шт, достаточно для Max(Слово64) + знак пусть № := длина(б) пока истина { пусть ост := к % 10(:Слово64) к := к / 10(:Слово64) №-- б[№] := ( ост + '0'(:Слово64))(:Байт) если к = 0(:Слово64) { прервать } } // TODO: обработать уточнение если нег { №-- б[№] := '-'(:Байт) } // все символы однобайтовые р.сб.число-символов := р.сб.число-символов + длина(б) - № пока № < длина(б) { //TODO: не оптимально, сделать slice или что-то еще, чтобы добавить все сразу р.сб.байты.добавить(б[№]) №++ } } // маска, сдвиги? фн (р: Разборщик) добавить число16(к: Слово64) { пусть б := Байты[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,] //17 шт, достаточно для Max(Слово64) пусть № := длина(б) пока истина { пусть ост := к % 16(:Слово64) к := к / 16(:Слово64) №-- если ост < 0xA { б[№] := ( ост + '0'(:Слово64))(:Байт) } иначе { б[№] := ( ост - 0xA + 'A'(:Слово64))(:Байт) } если к = 0(:Слово64) { прервать } } // TODO: обработать уточнение // все символы однобайтовые р.сб.число-символов := р.сб.число-символов + длина(б) - № пока № < длина(б) { //TODO: не оптимально, сделать slice или что-то еще, чтобы добавить все сразу р.сб.байты.добавить(б[№]) №++ } } //=== разбор форматной строки фн (р: Разборщик) следующий(): Лог { пока р.№-сим < р.кол-во { надо р.формат[р.№-сим] # 0(:Символ) иначе авария("0x0 в форматной строке") //строка("'"); символ(р.формат[р.№-сим]); кс() если р.формат[р.№-сим] = '%' { если р.задание() { вернуть истина } } р.сб.добавить символ(р.формат[р.№-сим]) р.№-сим++ } вернуть ложь } фн (р: Разборщик) задание(): Лог { //строка("!задание"); кс() р.№-сим++ если р.формат[р.№-сим] = '%' { вернуть ложь } р.норм := истина р.уточнение() р.взять вид() вернуть истина } фн (р: Разборщик) взять вид() { надо р.№-сим < р.кол-во иначе { р.ошибка := "формат оборван" р.норм := ложь вернуть } р.вид := р.формат[р.№-сим] р.№-сим++ когда р.вид { есть 'v', 'd', 'x', 's': // ок иначе р.ошибка := "неизвестный формат" р.норм := ложь } } фн (р: Разборщик) уточнение() { //строка("!уточнение"); кс() }