init here

This commit is contained in:
2025-11-26 21:32:41 +03:00
commit 33c97acade
91 changed files with 9155 additions and 0 deletions

View File

@@ -0,0 +1,296 @@
модуль джесон
импорт "стд::строки"
импорт "исх/массивы"
импорт "исх/спринтф"
// да, это тоже цифры. просто поверьте
пусть цифры = массивы.Строки["1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "-", "+"]
тип ДжесонТокен = класс {
}
фн (токен: ДжесонТокен) в строку(): Строка {
вернуть "пустой токен. где вы его взяли вообще?"
}
тип ДжесонТокены = []ДжесонТокен
фн массив токенов в строку(токены: ДжесонТокены): Строка {
пусть рез := ""
цикл [номер]токен среди токены {
рез := строки.собрать(рез, токен.в строку())
}
вернуть рез
}
тип ТокенФигурнаяСкобка = класс(ДжесонТокен) {
закрывающая: Лог := ложь
}
фн (токен: ТокенФигурнаяСкобка) в строку(): Строка {
если токен.закрывающая {
вернуть "}"
} иначе {
вернуть "{"
}
}
тип ТокенКвадратнаяСкобка = класс(ДжесонТокен) {
закрывающая: Лог := ложь
}
фн (токен: ТокенКвадратнаяСкобка) в строку(): Строка {
если токен.закрывающая {
вернуть "]"
} иначе {
вернуть "["
}
}
тип ТокенЗапятая = класс(ДжесонТокен) {
}
фн (токен: ТокенЗапятая) в строку(): Строка {
вернуть ","
}
тип ТокенДвоеточие = класс(ДжесонТокен) {
}
фн (токен: ТокенДвоеточие) в строку(): Строка {
вернуть ":"
}
тип ТокенЧисло = класс(ДжесонТокен) {
значение: Цел64 := 0
}
фн (токен: ТокенЧисло) в строку(): Строка {
вернуть спринтф.ф("$цел", токен.значение)
}
тип ТокенСтрока = класс(ДжесонТокен) {
значение: Строка := ""
}
фн (токен: ТокенСтрока) в строку(): Строка {
пусть строка := строки.заменить все(токен.значение, "\\", "\\\\")
строка := строки.заменить все(строка, "\"", "\\\"")
вернуть спринтф.ф("\"$стр\"", строка)
}
тип ТокенБульБуль = класс(ДжесонТокен) {
значение: Лог := ложь
}
фн (токен: ТокенБульБуль) в строку(): Строка {
если токен.значение {
вернуть "true"
} иначе {
вернуть "false"
}
}
фн съесть символ(стр := Строка, ошибка := Строка): Строка {
пусть символ = посмотреть но не трогать(стр, ошибка)
если ошибка # "" { вернуть "" }
стр := строки.извлечь(стр, 1, длина(стр(:Строка8)) - 1)
вернуть символ
}
фн съесть конкретный символ(стр := Строка, ожидаемый символ: Строка, ошибка := Строка): Строка {
пусть символ = посмотреть конкретный символ но не трогать(стр, ожидаемый символ, ошибка)
если ошибка # "" { вернуть "" }
стр := строки.извлечь(стр, 1, длина(стр(:Строка8)) - 1)
вернуть символ
}
фн посмотреть но не трогать(стр := Строка, ошибка := Строка): Строка {
если длина(стр) = 0 {
ошибка := "нежданный конец строки"
вернуть ""
}
пусть символ := строки.извлечь(стр, 0, 1)
вернуть символ
}
фн посмотреть конкретный символ но не трогать (стр := Строка, ожидаемый символ: Строка, ошибка := Строка): Строка {
если длина(стр) = 0 {
ошибка := спринтф.ф("нежданный конец строки, ожидался символ '$символ'", ожидаемый символ)
вернуть ""
}
пусть символ = строки.извлечь(стр, 0, 1)
если символ # ожидаемый символ {
ошибка := спринтф.ф("ожидался символ '$стр', а пришёл '$символ'", ожидаемый символ, символ)
вернуть ""
}
вернуть символ
}
фн читать число(стр := Строка, ошибка := Строка): Цел64 {
пусть число := ""
пока истина {
пусть символ = посмотреть но не трогать(стр, ошибка)
если ошибка # "" { вернуть 0 }
пусть является цифрой := ложь
пусть является знаком := ложь
цикл [номер]цифра среди цифры {
если символ = цифра {
является цифрой := истина
прервать
}
}
если является цифрой {
число := строки.собрать(число, символ)
стр := строки.извлечь(стр, 1, длина(стр(:Строка8)) - 1)
} иначе {
если длина(число) = 0 {
ошибка := спринтф.ф("ожидалось число, а пришёл '$символ'", символ)
вернуть 0
}
пусть целое := 0
пусть номер байта зачем он тебе нужен вообще глупая машина := 0
пусть мне повезло = строки.извлечь цел(число, номер байта зачем он тебе нужен вообще глупая машина, целое)
если ~мне повезло {
ошибка := спринтф.ф("ошибка преобразования числа '$число'", число)
}
вернуть целое
}
}
вернуть 0
}
фн читать строку(стр := Строка, ошибка := Строка): Строка {
съесть конкретный символ(стр, "\"", ошибка)
если ошибка # "" { вернуть "" }
пусть экран := ложь
пусть строка := ""
пока истина {
пусть символ = съесть символ(стр, ошибка)
если ошибка # "" { вернуть "" }
если символ = "\\" {
экран := ~экран
} иначе если символ = "\"" & ~экран {
вернуть строка
} иначе {
экран := ложь
строка := строки.собрать(строка, символ)
}
}
вернуть строка
}
фн читать буль буль(стр := Строка, ошибка := Строка): Лог {
пусть истинаСтр = "true"
пусть ложьСтр = "false"
если строки.есть префикс(стр, истинаСтр) {
стр := строки.извлечь(стр, длина(истинаСтр(:Строка8)), длина(стр(:Строка8)) - длина(истинаСтр(:Строка8)))
вернуть истина
} иначе если строки.есть префикс(стр, ложьСтр) {
стр := строки.извлечь(стр, длина(ложьСтр(:Строка8)), длина(стр(:Строка8)) - длина(ложьСтр(:Строка8)))
вернуть ложь
} иначе {
пусть символ = посмотреть но не трогать(стр, ошибка)
если ошибка # "" { вернуть ложь }
ошибка := спринтф.ф("ожидалось 'true' или 'false', а пришёл '$символ'", символ)
вернуть ложь
}
}
фн токенизировать(стр: Строка, ошибка := Строка): ДжесонТокены {
пусть токены = ДжесонТокены[]
пусть сколько открыто := 0
пока истина {
если длина(стр) = 0 & сколько открыто = 0 {
прервать
}
пусть символ = посмотреть но не трогать(стр, ошибка)
если ошибка # "" { вернуть ДжесонТокены[] }
пусть является цифрой := ложь
цикл [номер]цифра среди цифры {
если символ = цифра {
является цифрой := истина
прервать
}
}
если символ = " " | символ = "\n" | символ = "\r" | символ = "\t" {
стр := строки.извлечь(стр, 1, длина(стр(:Строка8)) - 1)
} иначе если символ = "{" {
стр := строки.извлечь(стр, 1, длина(стр(:Строка8)) - 1)
токены.добавить(ТокенФигурнаяСкобка{закрывающая: ложь})
сколько открыто := сколько открыто + 1
} иначе если символ = "}" {
стр := строки.извлечь(стр, 1, длина(стр(:Строка8)) - 1)
токены.добавить(ТокенФигурнаяСкобка{закрывающая: истина})
сколько открыто := сколько открыто - 1
} иначе если символ = "[" {
стр := строки.извлечь(стр, 1, длина(стр(:Строка8)) - 1)
токены.добавить(ТокенКвадратнаяСкобка{закрывающая: ложь})
} иначе если символ = "]" {
стр := строки.извлечь(стр, 1, длина(стр(:Строка8)) - 1)
токены.добавить(ТокенКвадратнаяСкобка{закрывающая: истина})
} иначе если символ = "," {
стр := строки.извлечь(стр, 1, длина(стр(:Строка8)) - 1)
токены.добавить(ТокенЗапятая{})
} иначе если символ = ":" {
стр := строки.извлечь(стр, 1, длина(стр(:Строка8)) - 1)
токены.добавить(ТокенДвоеточие{})
} иначе если является цифрой {
пусть число = читать число(стр, ошибка)
если ошибка # "" { вернуть ДжесонТокены[] }
токены.добавить(ТокенЧисло{значение: число})
} иначе если символ = "\"" {
пусть строка = читать строку(стр, ошибка)
если ошибка # "" { вернуть ДжесонТокены[] }
токены.добавить(ТокенСтрока{значение: строка})
} иначе если символ = "t" | символ = "f" {
пусть буль = читать буль буль(стр, ошибка)
если ошибка # "" { вернуть ДжесонТокены[] }
токены.добавить(ТокенБульБуль{значение: буль})
} иначе {
ошибка := спринтф.ф("внезапный символ '$стр'", символ)
вернуть ДжесонТокены[]
}
}
вернуть токены
}

View File

@@ -0,0 +1,259 @@
модуль джесон
импорт "исх/строка"
импорт "исх/спринтф"
фн парсить массив(токены: ДжесонТокены, старт: Цел64, использовано токенов := Цел64, ошибка := Строка): ДжесонМногоЗначений {
пусть массив = ДжесонМногоЗначений{значения: ДжесонЗначения[]}
пусть текущий индекс := старт
если текущий индекс >= длина(токены) {
ошибка := "неожиданный конец, ожидалась ["
вернуть ДжесонМногоЗначений{}
}
пусть токен := токены[текущий индекс]
выбор пусть т: тип токен {
когда ТокенКвадратнаяСкобка:
если т.закрывающая {
ошибка := спринтф.ф("ожидалась [, а получен $стр", токен.в строку())
вернуть ДжесонМногоЗначений{}
} иначе {
текущий индекс++
}
другое
ошибка := спринтф.ф("ожидалась [, а получен $стр", токен.в строку())
вернуть ДжесонМногоЗначений{}
}
пока текущий индекс < длина(токены) {
токен := токены[текущий индекс]
пусть значение: ДжесонЗначение := ДжесонЗначение{}
выбор пусть т: тип токен {
когда ТокенСтрока:
значение := ДжесонСтрока{значение: т.значение}
текущий индекс++
когда ТокенЧисло:
значение := ДжесонЧисло{значение: т.значение}
текущий индекс++
когда ТокенБульБуль:
значение := ДжесонЛог{значение: т.значение}
текущий индекс++
когда ТокенКвадратнаяСкобка:
если т.закрывающая {
текущий индекс++
использовано токенов := текущий индекс - старт
вернуть массив
} иначе {
ошибка := спринтф.ф("ожидалась значение или ], а получен $стр", токен.в строку())
вернуть ДжесонМногоЗначений{}
}
когда ТокенФигурнаяСкобка:
если ~т.закрывающая {
пусть использовано := 0
значение := парсить объект(токены, текущий индекс, использовано, ошибка)
если ошибка # "" { вернуть ДжесонМногоЗначений{} }
текущий индекс := текущий индекс + использовано
}
другое
ошибка := спринтф.ф("неожиданное значение: $стр", токен.в строку())
вернуть ДжесонМногоЗначений{}
}
массив.значения.добавить(значение)
если текущий индекс >= длина(токены) {
ошибка := "неожиданный конец, ожидался , или ]"
вернуть ДжесонМногоЗначений{}
}
токен := токены[текущий индекс]
выбор пусть т: тип токен {
когда ТокенКвадратнаяСкобка:
если т.закрывающая {
текущий индекс++
использовано токенов := текущий индекс - старт
вернуть массив
} иначе {
ошибка := спринтф.ф("ожидалась , или ], а получен $стр", токен.в строку())
вернуть ДжесонМногоЗначений{}
}
когда ТокенЗапятая:
текущий индекс++
другое
ошибка := спринтф.ф("ожидалась , или ], а получен $стр", токен.в строку())
вернуть ДжесонМногоЗначений{}
}
}
ошибка := "неожиданный конец во время парсинга массива"
вернуть ДжесонМногоЗначений{}
}
фн парсить объект(токены: ДжесонТокены, старт: Цел64, использовано токенов := Цел64, ошибка := Строка): ДжесонОбъект {
пусть объект = ДжесонОбъект{}
пусть текущий индекс := старт
если текущий индекс >= длина(токены) {
ошибка := "неожиданный конец, ожидалось {"
вернуть ДжесонОбъект{}
}
пусть токен := токены[текущий индекс]
выбор пусть т: тип токен {
когда ТокенФигурнаяСкобка:
если т.закрывающая {
ошибка := спринтф.ф("ожидалась {, а получен $стр", токен.в строку())
вернуть ДжесонОбъект{}
} иначе {
текущий индекс++
}
другое
ошибка := спринтф.ф("ожидалась {, а получен $стр", токен.в строку())
вернуть ДжесонОбъект{}
}
пока текущий индекс < длина(токены) {
токен := токены[текущий индекс]
пусть ключ := ""
выбор пусть т: тип токен {
когда ТокенСтрока:
ключ := т.значение
текущий индекс++
когда ТокенФигурнаяСкобка:
если т.закрывающая {
текущий индекс++
использовано токенов := текущий индекс - старт
вернуть объект
} иначе {
ошибка := спринтф.ф("ожидалась строка (ключ), а получен $стр", токен.в строку())
вернуть ДжесонОбъект{}
}
другое
ошибка := спринтф.ф("ожидалась строка (ключ), а получен $стр", токен.в строку())
вернуть ДжесонОбъект{}
}
если текущий индекс >= длина(токены) {
ошибка := "неожиданный конец, ожидалось :"
вернуть ДжесонОбъект{}
}
токен := токены[текущий индекс]
выбор пусть т: тип токен {
когда ТокенДвоеточие:
текущий индекс++
другое
ошибка := спринтф.ф("ожидался :, а получен $стр", токен.в строку())
вернуть ДжесонОбъект{}
}
если текущий индекс >= длина(токены) {
ошибка := "неожиданный конец, ожидалось значение"
вернуть ДжесонОбъект{}
}
токен := токены[текущий индекс]
пусть значение: ДжесонЗначение := ДжесонЗначение{}
выбор пусть т: тип токен {
когда ТокенСтрока:
значение := ДжесонСтрока{значение: т.значение}
текущий индекс++
когда ТокенЧисло:
значение := ДжесонЧисло{значение: т.значение}
текущий индекс++
когда ТокенБульБуль:
значение := ДжесонЛог{значение: т.значение}
текущий индекс++
когда ТокенФигурнаяСкобка:
если ~т.закрывающая {
пусть использовано := 0
значение := парсить объект(токены, текущий индекс, использовано, ошибка)
если ошибка # "" { вернуть ДжесонОбъект{} }
текущий индекс := текущий индекс + использовано
} иначе {
ошибка := спринтф.ф("ожидалось значение, а получен $стр", токен.в строку())
вернуть ДжесонОбъект{}
}
когда ТокенКвадратнаяСкобка:
если т.закрывающая {
ошибка := спринтф.ф("ожидалось значение, а получен $стр", токен.в строку())
вернуть ДжесонОбъект{}
} иначе {
пусть использовано := 0
значение := парсить массив(токены, текущий индекс, использовано, ошибка)
если ошибка # "" { вернуть ДжесонОбъект{} }
текущий индекс := текущий индекс + использовано
}
другое
ошибка := спринтф.ф("неожиданное значение: $стр", токен.в строку())
вернуть ДжесонОбъект{}
}
объект.значения.добавить(ДжесонКлючЗначение{ключ: ключ, значение: значение})
если текущий индекс >= длина(токены) {
ошибка := "неожиданный конец, ожидался , или }"
вернуть ДжесонОбъект{}
}
токен := токены[текущий индекс]
выбор пусть т: тип токен {
когда ТокенЗапятая:
текущий индекс++
когда ТокенФигурнаяСкобка:
если т.закрывающая {
текущий индекс++
использовано токенов := текущий индекс - старт
вернуть объект
} иначе {
ошибка := спринтф.ф("ожидалась , или }, а получен $стр", токен.в строку())
вернуть ДжесонОбъект{}
}
другое
ошибка := спринтф.ф("ожидалась , или }, а получен $стр", токен.в строку())
вернуть ДжесонОбъект{}
}
}
ошибка := "неожиданный конец во время парсинга объекта"
вернуть ДжесонОбъект{}
}
фн парсить токены(токены: ДжесонТокены, ошибка := Строка): ДжесонОбъект {
пусть использовано токенов := 0
вернуть парсить объект(токены, 0, использовано токенов, ошибка)
}
фн парсить*(строка: Строка, ошибка := Строка): ДжесонОбъект {
пусть токены = токенизировать(строка, ошибка)
если ошибка # "" {
вернуть ДжесонОбъект{}
}
пусть объект = парсить токены(токены, ошибка)
если ошибка # "" {
вернуть ДжесонОбъект{}
}
вернуть объект
}
фн сериализовать*(объект: ДжесонОбъект): Строка {
вернуть массив токенов в строку(объект.в токены())
}

View File

@@ -0,0 +1,205 @@
модуль джесон
импорт "исх/строка"
импорт "исх/спринтф"
тип ДжесонЗначение* = класс {
}
фн (значение: ДжесонЗначение) в строку*(): Строка {
вернуть "пустое значение"
}
фн (значение: ДжесонЗначение) в токены(): ДжесонТокены {
авария("попытка преобразовать в токены базовое значение")
}
фн (значение: ДжесонЗначение) пустое*(): Лог {
вернуть истина
}
фн (значение: ДжесонЗначение) строка*(): мб Строка {
вернуть пусто
}
фн (значение: ДжесонЗначение) число*(): мб ДжесонЧисло {
вернуть пусто
}
тип ДжесонЗначения* = []ДжесонЗначение
тип ДжесонСтрока* = класс(ДжесонЗначение) {
значение*: Строка := ""
}
фн (строка: ДжесонСтрока) в строку*(): Строка {
вернуть спринтф.ф("\"$стр\"", строка.значение)
}
фн (строка: ДжесонСтрока) в токены(): ДжесонТокены {
вернуть ДжесонТокены[ТокенСтрока{значение: строка.значение}]
}
фн (строка: ДжесонСтрока) пустое*(): Лог {
вернуть ложь
}
фн (строка: ДжесонСтрока) строка*(): мб Строка {
вернуть строка.значение
}
тип ДжесонЧисло* = класс(ДжесонЗначение) {
значение*: Цел64 := 0
}
фн (число: ДжесонЧисло) в строку*(): Строка {
вернуть спринтф.ф("$цел", число.значение)
}
фн (число: ДжесонЧисло) в токены(): ДжесонТокены {
вернуть ДжесонТокены[ТокенЧисло{значение: число.значение}]
}
фн (число: ДжесонЧисло) пустое*(): Лог {
вернуть ложь
}
фн (число: ДжесонЧисло) число*(): мб ДжесонЧисло {
вернуть число
}
тип ДжесонЛог* = класс(ДжесонЗначение) {
значение*: Лог := ложь
}
фн (лог: ДжесонЛог) в строку*(): Строка {
если лог.значение {
вернуть "истина"
}
вернуть "ложб"
}
фн (лог: ДжесонЛог) в токены(): ДжесонТокены {
вернуть ДжесонТокены[ТокенБульБуль{значение: лог.значение}]
}
фн (лог: ДжесонЛог) пустое*(): Лог {
вернуть ложь
}
тип ДжесонМногоЗначений* = класс(ДжесонЗначение) {
значения*: ДжесонЗначения = ДжесонЗначения[]
}
фн (значения: ДжесонМногоЗначений) в строку*(): Строка {
пусть выходная строка := ""
цикл [номер]значение среди значения.значения {
если номер > 0 {
выходная строка := спринтф.ф("$стр, ", выходная строка)
}
выходная строка := строка.собрать(выходная строка, значение.в строку())
}
вернуть спринтф.ф("[$стр]", выходная строка)
}
фн (значения: ДжесонМногоЗначений) в токены(): ДжесонТокены {
пусть токены = ДжесонТокены[ТокенКвадратнаяСкобка{закрывающая: ложь}]
цикл [номер]значение среди значения.значения {
если номер > 0 {
токены.добавить(ТокенЗапятая{})
}
токены.добавить(значение.в токены()...)
}
токены.добавить(ТокенКвадратнаяСкобка{закрывающая: истина})
вернуть токены
}
фн (значения: ДжесонМногоЗначений) пустое*(): Лог {
вернуть длина(значения.значения) = 0
}
тип ДжесонОбъект* = класс(ДжесонЗначение) {
значения*: ДжесонКлючЗначения := ДжесонКлючЗначения[]
}
фн (объект: ДжесонОбъект) в строку*(): Строка {
пусть выходная строка := ""
цикл [номер]значение среди объект.значения {
если номер > 0 {
выходная строка := спринтф.ф("$стр,\n", выходная строка)
} иначе {
выходная строка := спринтф.ф("\n$стр", выходная строка)
}
выходная строка := строка.собрать(выходная строка, спринтф.ф("\"$стр\": $стр", значение.ключ, значение.значение.в строку()))
}
вернуть спринтф.ф("{$стр\n}", выходная строка)
}
фн (объект: ДжесонОбъект) в токены(): ДжесонТокены {
пусть токены = ДжесонТокены[ТокенФигурнаяСкобка{закрывающая: ложь}]
цикл [номер]значение среди объект.значения {
если номер > 0 {
токены.добавить(ТокенЗапятая{})
}
токены.добавить(ТокенСтрока{значение: значение.ключ})
токены.добавить(ТокенДвоеточие{})
токены.добавить(значение.значение.в токены()...)
}
токены.добавить(ТокенФигурнаяСкобка{закрывающая: истина})
вернуть токены
}
фн (объект: ДжесонОбъект) пустое*(): Лог {
вернуть ложь
}
фн (объект: ДжесонОбъект) получить*(ключ: Строка): ДжесонЗначение {
пусть количество = длина(объект.значения)
пусть ай := количество - 1
пока ай >= 0 {
пусть значение = объект.значения[ай]
если значение.ключ = ключ {
вернуть значение.значение
}
ай := ай - 1
}
вернуть ДжесонЗначение{}
}
фн (объект: ДжесонОбъект) вставить*(ключ: Строка, новое значение: ДжесонЗначение) {
цикл [номер]значение среди объект.значения {
если значение.ключ = ключ {
объект.значения[номер].значение := новое значение
вернуть
}
}
объект.значения.добавить(ДжесонКлючЗначение{ключ: ключ, значение: новое значение})
}
тип ДжесонКлючЗначение* = класс {
ключ*: Строка := ""
значение*: ДжесонЗначение := позже
}
тип ДжесонКлючЗначения* = []ДжесонКлючЗначение