Этот документ — ориентир для переноса движка OneScript (C#) на TypeScript. Он описывает слои оригинала и то, куда они лягут в нашем репозитории.
Источник: reference/OneScript/docs/developer_docs.md.
OneScript — открытая реализация языка, совместимого с 1С/BSL, поверх стековой виртуальной машины. Конвейер исполнения:
исходный код (.osjs / <one-script>)
→ лексер (LexicalAnalysis)
→ препроцессор (#Если / #Область / #Использовать)
→ загрузчик импортов (файлы из #Использовать → модуль/класс)
→ парсер (SyntaxAnalysis → AST)
→ компилятор (CompilerFrontend → байткод)
→ стековая ВМ (MachineInstance / StackMachineExecutor)
→ стандартная библиотека (глобальные контексты)
Преобразует исходник в токены и AST. Максимально независимый слой.
LexicalAnalysis/*— лексер: состоянияString/Number/Comment/PreprocessorDirective.SyntaxAnalysis/*— парсер и AST (ModuleNode,MethodNode,CallNode,*LoopNode,BinaryOperationNode/UnaryOperationNodeи др.), препроцессор (PreprocessingLexer,PreprocessorHandlers, обработчики директив).- Диагностика:
CodeError,ErrorPositionInfo,SyntaxErrorException.
Объектный каркас значений BSL, контексты, отражение.
Values/*—BslValueи производные (строки/числа/дата/Null/Undefined/Type), ссылки на значения, сравнения и преобразования.Contexts/*— атрибутыContextClass/ContextMethod/ContextProperty, построителиBsl*Info, отражение классов.Compilation/Binding/*— таблицы символов и привязка имён.
Стековая виртуальная машина и компилятор для неё.
Compiler/*—CompilerFrontend,StackMachineCodeGenerator(байткод).Machine/*—MachineInstance/StackMachineExecutor(командный цикл, стек, кадры, исключения, итераторы),ExecutionContext,BuiltinFunctions.Hosting/*,ScriptingEngine.cs— фасад движка, DI, загрузка сборок.
Стандартные прикладные классы BSL: массивы, строки, файлы, сеть, фоновые задания
(src/stdlib/tasks/) и т.д. Глобальные функции вроде Сообщить/Message
(вывод в console.log) и Приостановить/Sleep (кооперативная пауза).
Двуязычные псевдонимы: РусИмя/EngName.
Консольный хост для запуска .osjs-скриптов и встраивание движка в приложения.
.os тоже принимается (общая грамматика BSL), но это чужой формат — см.
specs/013-osjs-format.
Браузерное исполнение: регистрация <one-script>, запуск кода из содержимого
элемента. Вывод Сообщить() идёт через стандартную библиотеку в console.log.
Упрощённый аналог библиотек OneScript: #Использовать "<файл>" загружает модуль
(синглтон с экспортными членами) или класс (ПриСозданииОбъекта, создание через
Новый). Кеш импорта живёт на время run(); запись loading создаётся до
исполнения тела, поэтому циклы не зацикливаются. Платформенное чтение источников
изолировано: src/node/module-source.ts (fs/path) и src/browser/module-source.ts
(fetch/URL); ядро получает готовую карту исходников. Загрузчик сохраняется в
GlobalContext, поэтому ЗагрузитьСценарийИзСтроки использует тот же кеш и разрешение
путей; Node дополнительно умеет лениво читать файл через loadSource.
exec/eval интерпретатора — генераторы: на точке приостановки они отдают Promise,
а драйвер drive() до первого yield исполняет всё синхронно и возвращает обычное
значение. Поэтому скрипт без ожиданий остаётся синхронным, а Приостановить и ожидания
фоновых заданий делают исполнение асинхронным. gen.throw доставляет отказ в точку
yield, поэтому Попытка/Исключение и сигналы Возврат/Прервать/Перейти работают
без переписывания.
Фоновые задания — кооперативные логические потоки в одном JS-потоке: общий модульный
контекст (методы, переменные, ЭтотОбъект), у каждого задания свой Ctx (ошибка,
текущее задание) и срез квантов (TimeSlicer + yieldToHost), чтобы страница не
замирала. Реестр заданий повторяет порядок/вытеснение эталона; менеджер доступен как
глобальное ФоновыеЗадания, а run() после тела скрипта дожидается активных заданий
через GlobalContext.flushAsync.
Асинх/Ждать — контекстные ключевые слова: парсер распознаёт их только в позиции
модификатора метода и унарного оператора (вне async-контекста это обычные идентификаторы).
Вызов async-метода сразу создаёт Обещание и запускает тело через drive() до первой
приостановки; результат/ошибка кэшируются в Обещании, а Ждать приостанавливает текущий
генератор до settle. Ошибка до первой приостановки не бросается вызывающему, а попадает в
Обещание. Необработанные ошибки откладываются и уходят в хук окружения
(console.error/stderr). GlobalContext учитывает незавершённые Обещания, и общий
flushAsync ждёт и фоновые задания, и Обещания, поэтому <one-script>/CLI не теряют
отложенный вывод и ошибки; при отсутствии работы запуск остаётся синхронным.
Язык и стандартная библиотека переносятся по спецификациям specs/; реализованы
001, 008, 009, 010, 011, 012 (см. сводку в docs/status.md).