Движок OneScript (язык 1С/BSL), переписанный на TypeScript. Работает в Node и браузере.
Оригинал (эталон) — reference/OneScript/ (C#), не коммитится.
Формат наших скриптов — .osjs (OneScriptJS, браузер). .os — чужой формат
ванильного C#-OneScript для бэкенда: движок его исполняет (общая грамматика BSL, эталонный
корпус — внутренний регресс), но не блокирует и не переименовывает. Решение и границы —
specs/013-osjs-format/spec.md.
- Перенос по старому плану T1–T49 закрыт: язык, стандартная библиотека, браузерная
интеграция (DOM, события, декларативные
data-os-*), xUnit-раннер и прогон эталонных тестов. pnpm typecheck✓,pnpm test✓ — 520 тестов (66 файлов Vitest).- Текущая ветка —
master. - Прогон
reference/OneScript/tests/*.os: 18/66 файлов проходят целиком; ошибка разбора осталась одна (annotations.os);events.osразбирается, но падает наПодключитьСценарий(спека 004). - Старый
docs/plan.mdудалён: незавершённые работы вынесены в спецификацииspecs/; спеки 001, 008, 009, 010, 011, 012 и 013 реализованы, 002, 003, 005, 006, 007 — пока только spec.
src/lexer (токены) → src/parser (AST + препроцессор #) → src/runtime
(values, scope+Ref, context, async (MaybePromise/drive/кванты), interpreter
на генераторах с синхронным быстрым путём, enum, object, type, error-info,
runner) → src/stdlib (global-context, collections, strings, math, bitwise, json,
types, enums, format, tasks/фоновые задания) → src/browser/onescript.ts (<one-script>)
и src/node/ (cli, context, files) → src/testing (xUnit-раннер).
Сборка: dist/onescript.js (браузер, IIFE), dist/node/index.{js,cjs,d.ts} (библиотека),
dist/cli.mjs (CLI).
- Язык: переменные,
если/иначеесли/иначе, циклы (Для/Пока/Для Каждого,Прервать/Продолжить), процедуры/функции (Знач/по ссылке), исключения,Перейти/метки, аннотации, тернарный?(),Новый, препроцессор#. - Структура модуля:
#Использовать→Перем→ методы → исполняемый код; импорт после кода — ошибка. ЛокальныеПерем— в начале метода; объявления после кода и вложенные методы — ошибка разбора (как вDefaultBslParser). Контекст операторов тоже проверяется:Возврат— только в методе (в функции со значением, в процедуре без),Прервать/Продолжить— только в цикле,ВызватьИсключение;— только в блокеИсключение. - Импорт файлов:
#Использовать "<файл>"— модули-синглтоны с экспортными членами и классы (ПриСозданииОбъекта,Новый), кеш наrun()и защита от циклов; Node читает через fs, браузер — через fetch по URL. Работает и изЗагрузитьСценарийИзСтроки(относительно имени/текущего сценария). - Значения/типы: числа, строки, булево, даты,
Null/Неопределено,Тип/ТипЗнч, перечисления (НаправлениеПоиска,СтатусСообщения,ХешФункция,ЦветКонсоли,КодировкаТекста,СпециальнаяПапка,ТипДиска,НаправлениеСортировки,СпособКодированияСтроки) иСимволы. - Коллекции:
Массив(многомерный),Структура,Соответствие(+ фиксированные),СписокЗначений,ТаблицаЗначений,ДеревоЗначений. - Двоичные данные:
БуферДвоичныхДанных,ДвоичныеДанные(hex/Base64/строка, BOM). - Система:
СистемнаяИнформация,УникальныйИдентификатор, переменные среды,ПустаяСтрока. РегулярноеВыражение(совпадения/группы/имена в нумерации .NET).ГенераторСлучайныхЧисел(диапазон uint32, воспроизводимость по seed).- Сценарии:
ЗагрузитьСценарийИзСтроки,ЗагрузитьСценарий(файл, Node),ТекущийСценарий,СтартовыйСценарий(типСценарий). Powв decimal-точности 1С (29 значащих цифр для целой степени).- Валидация смещений
ПобитовыйСдвиг*; методы тест-контекста (ПодробныеОписанияОшибок,ИмяВременногоФайла,ТестПровален,ПроверитьТип). - Динамическое исполнение:
Выполнить(оператор) иВычислить(функция) в текущей области видимости;1/0→ «Деление на ноль»; переменнаяДля … По …после цикла = «по + 1»;НСтризвлекает язык изru='…';en='…'. - BSL-события (спека 001):
ДобавитьОбработчик/УдалитьОбработчик(+AddHandler/RemoveHandler),ВызватьСобытие/RaiseEvent,ЭтотОбъект/ThisObject; реестр подписок общий для исполнения, локальная и объектная формы обработчика, порядок подписки и дедупликация, диагностика «Ожидается имя события»/«Ожидается имя обработчика события»/«Метод объекта не обнаружен». - Браузер (Фаза 7): объект
Документ, события DOM из BSL (Элемент.НаСобытие(Имя, Код), объектСобытие), декларативныеdata-os-*— только в браузерной сборке,src/stdlibостаётся Node-совместимым. - Лексер: многострочные литералы с продолжением
|. - stdlib:
Сообщить(со статусом), строковые, математические, поразрядные (uint32), JSON,Формат(число/дата), файловые (Node:ЧтениеТекста/ЗаписьТекста/ОбъединитьПути),asserts(Ожидаем.Что(…).Равно(…)+ сравнения/ЭтоНе/ИмеетДлину/Существует/Содержит), динамическийНовый(Тип, …), двоичные данные (БуферДвоичныхДанных,ДвоичныеДанные, hex/Base64/строка). - Парсер:
Перем a, b, c;(сЭкспорт), пропущенные аргументыf(,23), конкатенация смежных строк"a" "b",ВызватьИсключение;(перевыброс), конец блока как терминатор оператора без;, ключевые литералы как имена свойств (Структура.Истина), пустые операторы;;. - Тестирование: xUnit-раннер
runTests(ЮнитТестированиесПроверить*). - HTTP-клиент (спека 010):
HTTPСоединение/HTTPConnection,HTTPЗапрос/HTTPRequest,HTTPОтвет/HTTPResponseс методами эталона (GET/POST/PUT/DELETE/PATCH/HEAD и произвольный метод), basic-auth, кодировки тела, gzip-нормализация. Вызовы синхронные: в браузере — синхронный XHR, в Node — дочерний процесс сfetch; прокси, SSL-сертификаты, файловое тело и потоки — вне scope. - Фоновые задания (спека 011): глобальное
ФоновыеЗадания/BackgroundJobs(МенеджерФоновыхЗаданий),ФоновоеЗадание, перечислениеСостояниеФоновогоЗадания, методыВыполнить/Очистить/ОжидатьВсе/ОжидатьЛюбое/ОжидатьЗавершенияЗадач/ПолучитьФоновыеЗадания/ПолучитьТекущее, глобальнаяПриостановить/Sleep. Модель кооперативная: задания — логические потоки в одном JS-потоке с общим состоянием модуля; переключение в точках ожидания и по квантам (~10 мс), поэтому страница не блокируется. Настоящего параллелизма CPU,ТекущийПоток,БлокировкаРесурсаи изоляции данных потоков нет (осознанное расхождение с эталонными потоками C#). Async-рантайм (генераторный интерпретатор с синхронным быстрым путём) стал фундаментом дляАсинх/Ждать. - Асинхронные методы (спека 012):
Асинх/AsyncпередПроцедура/Функция,Ждать/Awaitи непрозрачноеОбещание/Promise. Синтаксис/диагностика — из парсера эталона, семантика — 1C:Enterprise 8.3.18+: вызов async-функции/процедуры сразу возвращаетОбещание,Ждатьдаёт результат или бросает ошибку в точке ожидания, повторное ожидание кэшируется, параметры — по значению, ошибки до первой приостановки сохраняются вОбещании, необработанные — уходят вconsole.error/stderr. Хост дожидается async-тела и всехОбещаний(flush). Осознанные расхождения: рантайм реализован (в эталоне только разбор);Ждатьразрешён в теле модуля; async-процедура тоже возвращаетОбещание.
| Спека | Тема | Состояние |
|---|---|---|
001-bsl-event-handlers |
BSL-события: ДобавитьОбработчик/УдалитьОбработчик, ВызватьСобытие, ЭтотОбъект |
реализовано |
002-nested-annotations |
Вложенные и именованные аннотации (парсер) | spec |
003-date-precision |
Точность и арифметика дат 1С (1/10000 с) | spec |
004-script-attach |
ПодключитьСценарий / ЗагрузитьСценарий из файла |
spec; ЗагрузитьСценарий (US3) реализован |
005-system-settings |
config.os: ОбновитьНастройкиСистемы / ПолучитьЗначениеСистемнойНастройки |
spec |
006-dynamic-names |
Разрешение имён в Выполнить/Вычислить («Неизвестный символ») |
spec |
007-browser-playwright |
Приёмка в реальном браузере (Playwright) | spec |
008-use-directive |
#Использовать "<файл>": модули и классы из файлов |
реализовано |
009-module-structure |
Порядок секций модуля и контекст операторов (паритет парсера) | реализовано |
010-http-client |
HTTP-клиент BSL: HTTPСоединение/HTTPЗапрос/HTTPОтвет |
реализовано |
011-background-jobs |
Фоновые задания: ФоновыеЗадания, ФоновоеЗадание, Приостановить (кооперативная модель) |
реализовано |
012-async-await |
Асинхронные методы: Асинх/Ждать, Обещание (поверх фоновых заданий) |
реализовано |
013-osjs-format |
Формат .osjs — отделение от ванильного OneScript; .os — чужой формат, не блокируется |
реализовано |
Для незавершённых спек следующий шаг — /speckit-plan или /speckit-tasks в её каталоге;
реализованы 001, 008, 009, 010, 011, 012 и 013.
Следующая запланированная работа — редакторные инструменты для .osjs: подсветка,
линтер/диагностика и language server (возможно, отдельный плагин VS Code). Анализ и план
не начаты; заметка с контекстом договорённостей — в
specs/013-osjs-format/spec.md (раздел «Следующая работа»).
annotations.os— после спеки 002 перестанет падать на разборе, но чтение аннотаций требуетРефлектор(вне scope 002).events.os— требует 004 (ПодключитьСценарий, самоподключение файла): 8 сценариев событий уже воспроизведены вtests/events.test.ts(спека 001), полный прогон файла отложен до 004.#Использовать(спека 008) импортирует только файлы: поиск библиотек по имени (lib.config, версии,OSCRIPT_LIB) не поддерживается;#Использовать assertsостаётся no-op.ЗагрузитьСценарийИзСтрокирезолвит импорты (Node — с чтением с диска, браузер — только из предзагруженных источников).eval.os:ТестДолжен_ПроверитьРаботоспособностьВПодключенныхСценарияхтребует#Использовать/библиотеки (спека 008 покрывает импорт файлов; поиск библиотек по имени остаётся вне scope), остальные — 004 (ЗагрузитьСценарийреализован) и Node-контекст (ОбъединитьПути).date-behavior.os— заблокирован JSON/XML-подсистемами (ЗаписьJSON/ЧтениеJSONкак объекты,XMLСтрока,ФорматДатыJSON), часовыми поясами иЗначениеЗаполнено(вне 003).- Вне старого плана и спецификаций (нужны отдельные спеки):
ТекстовыйДокумент,ЧасовойПояс,ХешированиеДанных,КвалификаторыЧисла/КвалификаторыСтроки,ЗначениеЗаполнено,ПолучитьИмяВременногоФайла; объектныеЗаписьJSON/ЧтениеJSON(сейчас функции с одним аргументом);Формат:ЧГс кастомными размерами,ДП/ДД. - Процессы, COM, XML, прокси/SSL-сертификаты и файловые тела HTTP — вне scope первой очереди; HTTP-клиент реализован в спеке 010.
- Асинхронность языка (
Асинх/Ждать,Обещание) реализована (спека 012), но без отмены, таймаутов ожидания иКогдаВсе/КогдаЛюбой; async-конструкторы, async-обработчики событий с ожиданием, async-импорт модулей и async HTTP (fetch) — вне scope. Job, нацеленный на async-метод, получаетОбещаниекакРезультати не ждёт его. - Фоновые задания: нет отмены, приоритетов и настоящего параллелизма;
Приостановитьи ожидания — единственные точки переключения основного скрипта; импортируемые модули рекомендуется держать синхронными; xUnit-раннер не поддерживает тесты с приостановкой (shortcut).