fix #1468 #6 #1329: Реализация оператора Перейти / Goto#1665
fix #1468 #6 #1329: Реализация оператора Перейти / Goto#1665Diversus23 wants to merge 2 commits intoEvilBeaver:developfrom
Conversation
…а Перейти / Goto в компиляторе стековой машины
📝 WalkthroughWalkthroughImplements label and goto code generation in the StackMachineCodeGenerator: adds private types for label/pending-goto tracking, emits/paches jumps (forward and backward), enforces target validation with block-stack context, and reports label-related compiler errors; includes C# and OneScript tests. Changes
Sequence DiagramsequenceDiagram
participant Parser
participant CodeGen as Code Generator
participant LabelReg as Label Registry
participant BlockCtx as Block Context Stack
participant PendingQ as Pending Gotos Queue
participant Finalizer
Parser->>CodeGen: visit goto node
CodeGen->>LabelReg: lookup label (case-insensitive)
alt label found
CodeGen->>BlockCtx: determine exit/cleanup ops for scopes crossed
BlockCtx-->>CodeGen: cleanup actions (StopIterator/PopTmp/ExitTry)
CodeGen->>CodeGen: emit cleanup ops
CodeGen->>CodeGen: emit Jmp to target index
else label not found (forward)
CodeGen->>PendingQ: record PendingGoto (blockStack, tryNesting, metadata)
CodeGen->>CodeGen: emit placeholder jump/cleanup slots
end
Parser->>CodeGen: visit label node
CodeGen->>LabelReg: register label with codeIndex and block context
CodeGen->>PendingQ: find pending gotos matching label
alt pending matches exist
PendingQ->>CodeGen: patch placeholder cleanup and Jmp arguments
PendingQ-->>CodeGen: remove resolved entries
end
Parser->>Finalizer: finalize module/method
Finalizer->>PendingQ: if pending entries remain
alt unresolved pending goto
PendingQ->>CodeGen: emit UndefinedLabel errors
end
Finalizer->>LabelReg: clear label registry
Finalizer->>PendingQ: clear pending queue
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
Ой-вей.. Вот это новости! |
Я почему-то так и предполагал, что будет такая реакция. В реальной жизни GOTO нафиг не нужен :) Но все просто, мне нужен свой обфускатор в 1С (я как-то давно делал issue, но сейчас вернулся к этому вопросу). Без меток я не могу полноценно реализовать такой функционал (все тестирую через oscript) |
| private int _tryNestingCount; | ||
| private int _blockIdCounter; | ||
|
|
||
| private const string BlockWhile = "while"; |
There was a problem hiding this comment.
А чего не сделать это enum-ом? Быстрее же будет, да и правильнее вроде как... Есть тайный смысл в использовании именно строки?
There was a problem hiding this comment.
Тайного смысла нет. По идее да, enum-всегда будет быстрее. Окей, принято.
|
|
||
| var currentStack = SnapshotBlockStack(); | ||
|
|
||
| // Reserve cleanup slots for loops (innermost to outermost) |
There was a problem hiding this comment.
Конечно помогала :)
Сейчас мне кажется все идет к тому, что это будет неотъемлемая часть рабочего процесса.
|
Native специально не трогал, так как этот режим сделан для скорости работы и вряд ли там это нужно в принципе. |
There was a problem hiding this comment.
Actionable comments posted: 1
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 1faae9f3-4f9e-4561-83a5-888b5d137b3b
📒 Files selected for processing (2)
src/ScriptEngine/Compiler/CodeGeneratorPrivateTypes.cssrc/ScriptEngine/Compiler/StackMachineCodeGenerator.cs
✅ Files skipped from review due to trivial changes (1)
- src/ScriptEngine/Compiler/CodeGeneratorPrivateTypes.cs
Реализация кодогенерации и валидации оператора
Перейти/Gotoв компиляторе стековой машины.Исправил для #1329, #1468, #6
Лексер и парсер уже поддерживали синтаксис меток и оператора
Перейти, но оба бэкенда компиляции бросалиNotSupportedException. Данный PR реализует полную поддержку в stack-machine backend.Что реализовано
VisitGotoNode/VisitLabelNodeвStackMachineCodeGenerator— генерацияJmpдля переходов вперёд и назад, с forward-reference fixup через существующий паттернDUMMY_ADDRESSStopIteratorпри выходе изДля Каждого,PopTmpпри выходе изДляExitTryпри выходе из try-блоков (включая вложенные, tryDiff > 1)~меткаи~Меткассылаются на одну метку (как и остальные идентификаторы BSL)Ограничения
#native) — не поддержан, остаётсяNotSupportedException.Тестирование
GotoCodeGenerationTests.cs): переходы вперёд/назад, выход из циклов/if/try/except, вложенные try, очистка итераторов, валидация (вход в блоки, sibling-блоки одного типа, дубликаты, несуществующие метки, утечка между методами, регистронезависимость)tests/goto.os): рантайм-проверки поведения (переменные, эмуляция цикла через goto, repeat/until, выход из вложенных циклов, выход из try)Изменённые файлы
src/ScriptEngine/Compiler/CompilerErrors.cs— 3 метода ошибокsrc/ScriptEngine/Compiler/CodeGeneratorPrivateTypes.cs—LabelInfo,PendingGotosrc/ScriptEngine/Compiler/StackMachineCodeGenerator.cs— реализация goto/labelsrc/Tests/OneScript.Core.Tests/GotoCodeGenerationTests.cs— C#-тестыtests/goto.os— BSL-тестыSummary by CodeRabbit