{"id":27283922,"url":"https://github.com/purplesyringa/batchbuilder","last_synced_at":"2026-07-02T15:07:50.537Z","repository":{"id":119468887,"uuid":"121290055","full_name":"purplesyringa/BatchBuilder","owner":"purplesyringa","description":"Transpiler from Batch to Batch written completely in Batch","archived":false,"fork":false,"pushed_at":"2018-03-15T18:36:15.000Z","size":60,"stargazers_count":4,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-11T18:54:26.819Z","etag":null,"topics":["abnormal-programming","batch","build","cmd","dos","transpile","windows"],"latest_commit_sha":null,"homepage":null,"language":"Batchfile","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/purplesyringa.png","metadata":{"files":{"readme":"readme-ru.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2018-02-12T19:14:56.000Z","updated_at":"2024-12-19T10:03:16.000Z","dependencies_parsed_at":null,"dependency_job_id":"64bf200b-605d-4469-9256-8dbc7bde3acd","html_url":"https://github.com/purplesyringa/BatchBuilder","commit_stats":null,"previous_names":["purplesyringa/batchbuilder"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/purplesyringa/BatchBuilder","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/purplesyringa%2FBatchBuilder","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/purplesyringa%2FBatchBuilder/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/purplesyringa%2FBatchBuilder/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/purplesyringa%2FBatchBuilder/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/purplesyringa","download_url":"https://codeload.github.com/purplesyringa/BatchBuilder/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/purplesyringa%2FBatchBuilder/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35052083,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-02T02:00:06.368Z","response_time":173,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["abnormal-programming","batch","build","cmd","dos","transpile","windows"],"created_at":"2025-04-11T18:47:02.286Z","updated_at":"2026-07-02T15:07:50.529Z","avatar_url":"https://github.com/purplesyringa.png","language":"Batchfile","funding_links":[],"categories":[],"sub_categories":[],"readme":"# BatchBuilder v1.0\n(c) 2018 Ivanq\n\n**BatchBuilder - система сборки BAT/CMD файлов.**\n\n\n## Пример использования\n\nНачальные действия:\n1. Копируем build.cmd и папку compiler куда-нибудь (например, в batch_test).\n2. Создаем папку src и кидаем в нее файл entry.cmd. entry.cmd - ваш BAT.\n\nПосле изменений:\n1. Запускаем build.cmd.\n2. Появляется папку dist со скриптом bootstrap.cmd, запускаем его.\n\n\n## Настройка \"под себя\"\n\nДля управления BatchBuilder в папке src можно создать файл build.ini. Имеются следующие опции:\n\n1. `entry=\u003cfilename\u003e`\n   Значение по умолчанию: `entry.cmd`\n\n   Скрипт, который будет запускаться при старте.\n\n2. `delete_compiled=yes/no`\n   Значение по умолчанию: `yes`\n\n   Удалять ли скомпилированные BAT-файлы. Если выбрано no, скомпилированный код будет храниться в папке `compiler\\compiled`.\n\n3. `compile_if=\u003crules\u003e`\n   Значение по умолчанию: `batch ~-4 .cmd,batch ~-4 .bat`\n\n   Определяет, какие файлы будут обработаны компилятором BatchBuilder.\n\n   Набор правил разделяется запятой. Сами же правила (`~-4 .cmd` и `~-4 .bat`) делятся на имя компилятора (`batch`), ключ (`~-4`) и значение (`.cmd` и `.bat`).\n\n   Если ключ начинается с тильды (~), а следующее за ней число - отрицательное (-4), то будут учитываться последние -n знаков (4). Если число положительное, будут учитываться все знаки, кроме первых n. Затем знаки сравниваются со значением.\n\n   Если ключ не начинается с тильды, то это правило замены. Например, ключ a=b означает \"заменить все a на b и затем сравнить со значением\".\n\n   Пример:\n    `batch ~-4 .cmd,batch ~-4 .bat`\n    Обрабатывать файлы, у которых последние 4 символа - .cmd или .bat (то есть, имеют расширение cmd или bat), компилятором batch.\n\n   Пример:\n    `batch o=a hello.bat`\n    Обрабатывать файлы, имя которых равно hello.bat или hella.bat, компилятором batch.\n\n4. `packed=\u003cyes/no/local\u003e`\n   Значение по умолчанию: `yes`\n\n   Определяет, должен ли BatchBuilder упаковывать проект в один файл.\n\n   В случае, если значение - no, будет создан файл bootstrap.cmd и папка contents, содержащая откомпилированные скрипты, и при запуске папка contents будет скопирована в %TEMP%.\n\n   Если значение - local, будут также созданы файл bootstrap.cmd и папка contents, однако скрипт будет запущен из директории contents, а не %TEMP%.\n\n   Если же значение - yes, файл bootstrap.cmd будет содержать распаковщик и сам архив, и скрипт будет запущен из %TEMP%.\n\n\n## Компилятор BatchBuilder\n\nДля упрощения работы BatchBuilder представляет возможность создания модулей. Модуль - обычный BAT-файл. Пример модуля:\n\n```\n+------------------------------------------------+\n| hi.bat                                         |\n+------------------------------------------------+\n| export say_hello                               |\n|  echo Hello                                    |\n| end export                                     |\n+------------------------------------------------+\n```\n\nСохраним его в папку src. Теперь напишем скрипт, использующий say_hello:\n\n```\n+------------------------------------------------+\n| entry.cmd                                      |\n+------------------------------------------------+\n| import say_hello                               |\n+------------------------------------------------+\n```\n\nКомпилятор BatchBuilder заменит \"import say_hello\" на вызов \"echo Hello\".\n\n\n## Аргументы методов\n\nПри вызове `import say_hello` мы могли передать дополнительные данные - например, имя:\n\n```\n+------------------------------------------------+\n| entry.cmd                                      |\n+------------------------------------------------+\n| import say_hello Kirill                        |\n| import say_hello Vanya                         |\n+------------------------------------------------+\n```\n\nВ таком случае первое переданное значение будет доступно как %1, второе - как %2 и так далее.\n\n```\n+------------------------------------------------+\n| hi.bat                                         |\n+------------------------------------------------+\n| export say_hello                               |\n|  echo Hello, %1!                               |\n| end export                                     |\n+------------------------------------------------+\n```\n\nТакже можно указать имя для некоторых параметров, тогда `%1`, `%2` и т.д. будут означать \"1/2 параметры после \":\n\n```\n+------------------------------------------------+\n| hi.bat                                         |\n+------------------------------------------------+\n| export say_hello name                          |\n|  echo Hello, %name%!                           |\n| end export                                     |\n+------------------------------------------------+\n```\n\n\nМодули могут быть полезны для выполнения рутинных операция, например, запроса на удаление папки.\n\n```\n+------------------------------------------------+\n| delete.cmd                                     |\n+------------------------------------------------+\n| export delete_dir dir                          |\n|  set /p agree=Do you want to delete %dir%?     |\n|  if \"%agree%\" == \"yes\" (                       |\n|   rmdir /S /Q %1                               |\n|  )                                             |\n| end export                                     |\n+------------------------------------------------+\n```\n\n```\n+------------------------------------------------+\n| entry.cmd                                      |\n+------------------------------------------------+\n| import delete_dir Documents                    |\n| import delete_dir Desktop                      |\n| import delete_dir Pictures                     |\n| import delete_dir Music                        |\n+------------------------------------------------+\n```\n\n\n## Возврат значений\n\nКомпилятор \"batch\" BatchBuilder также поддерживает оператор `return` внутри блоков `export` для возврата значения из метода. Для получения возвращенного значения можно использовать оператор `import -\u003e variable command`.\n\n```\n+------------------------------------------------+\n| delete.cmd                                     |\n+------------------------------------------------+\n| export ask q                                   |\n|  set /p result=%q%?                            |\n|  return %result%                               |\n| end export                                     |\n|                                                |\n| export delete_dir                              |\n|  import -\u003e agree ask \"Delete %1\"               |\n|  if \"%agree%\" == \"yes\" (                       |\n|   rmdir /S /Q %1                               |\n|  )                                             |\n| end export                                     |\n+------------------------------------------------+\n```\n\n\n## Глобальные переменные\n\nПо умолчанию переменные, определенные внутри одной функции, недоступны из другой функции или вызова рекурсии этой же функции.\n\n```\n+------------------------------------------------+\n| local_vars.cmd                                 |\n+------------------------------------------------+\n| export a                                       |\n|  echo Enter A                                  |\n|  import b                                      |\n|  echo Read local variable my_var from A        |\n|  echo my_var=%my_var%                          |\n|  echo Exit A                                   |\n| end export                                     |\n|                                                |\n| export b                                       |\n|  echo Enter B                                  |\n|  echo Set local variable my_var                |\n|  set my_var=hello                              |\n|  echo Read local variable my_var from B        |\n|  echo my_var=%my_var%                          |\n|  echo Exit B                                   |\n| end export                                     |\n|                                                |\n| import a                                       |\n+------------------------------------------------+\n| Enter A                                        |\n| Enter B                                        |\n| Set local variable my_var                      |\n| Read local variable my_var from B              |\n| my_var=hello                                   |\n| Exit B                                         |\n| Read local variable my_var from A              |\n| my_var=                                        |\n| Exit A                                         |\n+------------------------------------------------+\n```\n\nОднако, иногда необходимо пробросить переменную во все функции. Для этого используется ключевое слово `global`.\n\n```\n+------------------------------------------------+\n| global_vars.cmd                                |\n+------------------------------------------------+\n| export a                                       |\n|  echo Enter A                                  |\n|  import b                                      |\n|  echo Read global variable my_var from A       |\n|  echo my_var=%my_var%                          |\n|  echo Exit A                                   |\n| end export                                     |\n|                                                |\n| export b                                       |\n|  echo Enter B                                  |\n|  echo Set global variable my_var               |\n|  global my_var=hello                           |\n|  echo Read global variable my_var from B       |\n|  echo my_var=%my_var%                          |\n|  echo Exit B                                   |\n| end export                                     |\n|                                                |\n| import a                                       |\n+------------------------------------------------+\n| Enter A                                        |\n| Enter B                                        |\n| Set global variable my_var                     |\n| Read global variable my_var from B             |\n| my_var=hello                                   |\n| Exit B                                         |\n| Read global variable my_var from A             |\n| my_var=hello                                   |\n| Exit A                                         |\n+------------------------------------------------+\n```\n\n\n## Директивы экспорта\n\nПеред командой `export` может идти команда вида `@directive \u003csomething\u003e`, что означает установку директивы `@something` для текущей функции. Можно устанавливать сразу несколько директив, например: `@directive \u003csomething\u003e \u003csomething2\u003e`.\n\n1. `@safe_recursion`\n\n   По умолчанию при вызове функции происходит создание нового контекста для того, чтобы локальные переменные одной функции не были видны из другой. Для ускорения используются команды `setlocal` и `endlocal`. Однако, `setlocal` имеет определенный уровень глубины вызова.\n\n   Если необходим большой уровень рекурсии, имеет смысл использовать директиву `@safe_recursion`, которая сохраняет и восстанавливает переменные через файлы, а не `setlocal` и `endlocal`. Однако, `@safe_recursion` может сильно замедлить программу.\n\n2. `@follow_local`\n\n   Для упрощения работы с переменными все локальные переменные caller'а удаляются, а после выполнения восстанавливаются. Например:\n\n```\n+------------------------------------------------+\n| non_local.cmd                                  |\n+------------------------------------------------+\n| export a                                       |\n|  echo Enter A                                  |\n|  echo Set my_var=hello                         |\n|  set my_var=hello                              |\n|  import b                                      |\n|  echo Exit A                                   |\n| end export                                     |\n|                                                |\n| export b                                       |\n|  echo Enter B                                  |\n|  echo Read local variable my_var               |\n|  echo my_var=%my_var%                          |\n|  echo Exit B                                   |\n| end export                                     |\n|                                                |\n| import a                                       |\n+------------------------------------------------+\n| Enter A                                        |\n| Set my_var=hello                               |\n| Enter B                                        |\n| Read local variable my_var                     |\n| my_var=                                        |\n| Exit B                                         |\n| Exit A                                         |\n+------------------------------------------------+\n```\n\n   Однако, для ускорения вызовов рекурсии имеет смысл использовать директиву `@follow_local`, если не учитываются пустые переменные:\n\n```\n+------------------------------------------------+\n| local.cmd                                      |\n+------------------------------------------------+\n| export a                                       |\n|  echo Enter A                                  |\n|  echo Set my_var=hello                         |\n|  set my_var=hello                              |\n|  import b                                      |\n|  echo Exit A                                   |\n| end export                                     |\n|                                                |\n| @directive follow_local                        |\n| export b                                       |\n|  echo Enter B                                  |\n|  echo Read local variable my_var               |\n|  echo my_var=%my_var%                          |\n|  echo Exit B                                   |\n| end export                                     |\n|                                                |\n| import a                                       |\n+------------------------------------------------+\n| Enter A                                        |\n| Set my_var=hello                               |\n| Enter B                                        |\n| Read local variable my_var                     |\n| my_var=hello                                   |\n| Exit B                                         |\n| Exit A                                         |\n+------------------------------------------------+\n```\n\n   Наибольшее ускорение можно получить, если использовать `@follow_local` и unsafe-рекурсию.\n\n\n## Классы и объекты\n\nКомпилятор \"batch\" поддерживает систему классов. Для того, чтобы создать класс, используется пара `class`/`end class`:\n\n```\n+------------------------------------------------+\n| class.cmd                                      |\n+------------------------------------------------+\n| class ClassTest                                |\n| end class                                      |\n+------------------------------------------------+\n```\n\nМетоды можно создавать при помощи слова `export`:\n\n```\n+------------------------------------------------+\n| class.cmd                                      |\n+------------------------------------------------+\n| class ClassTest                                |\n|  export say_hello                              |\n|   echo Hello, %1!                              |\n|  end export                                    |\n|  export say_bye                                |\n|   echo Bye, %1!                                |\n|  end export                                    |\n| end class                                      |\n+------------------------------------------------+\n```\n\nДля создания класса используется слово `new`, а вызов происходит через полученный инстанс:\n\n```\n+------------------------------------------------+\n| class.cmd                                      |\n+------------------------------------------------+\n| echo Create ClassTest and put it to my_class   |\n| new -\u003e my_class ClassTest                      |\n|                                                |\n| echo Call say_hello and then say_bye           |\n| import %my_class%.say_hello Ivan               |\n| import %my_class%.say_bye Ivan                 |\n+------------------------------------------------+\n```\n\nСтоит отметить, что объекты создаются в куче, то есть, они не привязаны к имени инстанса. Таким образом, объекты можно передавать по ссылке.\n\n```\n+------------------------------------------------+\n| reference_class.cmd                            |\n+------------------------------------------------+\n| export by_reference                            |\n|  echo Inside: %1                               |\n| end export                                     |\n|                                                |\n| new -\u003e my_class ClassTest                      |\n| echo Outside: %my_class%                       |\n| import by_reference %my_class%                 |\n+------------------------------------------------+\n| Outside: __instance_343654654__                |\n| Inside: __instance_343654654__                 |\n+------------------------------------------------+\n```\n\n\n## Поля классов\n\nВнутри методов доступна переменная `%this%`, указывающая на текущий инстанс:\n\n```\n+------------------------------------------------+\n| class.cmd                                      |\n+------------------------------------------------+\n| class ClassTest                                |\n|  export save                                   |\n|   set \"%this%.data=%~1\"                        |\n|   echo Saved %~1                               |\n|  end export                                    |\n|                                                |\n|  export load                                   |\n|   call set \"data=%%%this%.data%%\"              |\n|   return %data%                                |\n|  end export                                    |\n|                                                |\n|  export echo                                   |\n|   import -\u003e data %this%.load                   |\n|   echo Loaded %data%                           |\n|  end export                                    |\n| end class                                      |\n|                                                |\n| new -\u003e instance ClassTest                      |\n| import %instance%.save One                     |\n| import %instance%.echo                         |\n+------------------------------------------------+\n| Saved One                                      |\n| Loaded One                                     |\n+------------------------------------------------+\n```\n\n\n## Магические методы\n\nИногда возникает необходимость обрабатывать нестандартные операции, без вызова `import`. Для этого можно определить магические методы.\n\n1. `magic_init`\n\n   Вызывается, когда создается объект при помощи оператора `new`. В метод `magic_init` можно передать параметры через оператор `new`:\n\n```\n+------------------------------------------------+\n| magic.cmd                                      |\n+------------------------------------------------+\n| class ClassTest                                |\n|  export magic_init                             |\n|   echo Created %~1                             |\n|  end export                                    |\n| end class                                      |\n|                                                |\n| new -\u003e instance ClassTest \"for test\"           |\n+------------------------------------------------+\n| Created for test                               |\n+------------------------------------------------+\n```\n\n\n## Рабочие примеры\n\nС BatchBuilder поставляются примеры, названные как src-admin, src-alert и так далее. Для их запуска переименуйте папку в src, запустите build.cmd, а затем dist\\bootstrap.cmd.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpurplesyringa%2Fbatchbuilder","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpurplesyringa%2Fbatchbuilder","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpurplesyringa%2Fbatchbuilder/lists"}