Я работаю над интерпретатором script, который мне удалось получить в рабочем состоянии. Он имеет компилятор, который анализирует script и генерирует байт-код, и виртуальную машину, которая выполняет байт-код.
В основе интерпретатора лежит цикл с гигантским выражением case
, который выглядит примерно так:
case CurrentOpcode.Operation of
OP_1: DoOp1(CurrentOpcode);
OP_2: DoOp2(CurrentOpcode);
...
OP_N: DoOpN(CurrentOpcode);
end;
Профилирование говорит мне, что по какой-то причине мое выполнение script проводит значительное количество времени внутри этого оператора case
, что кажется мне странным, поэтому я ищу способ его оптимизации. Очевидное решение, так как все операционные функции в основном имеют одну и ту же подпись, заключается в создании массива указателей методов, индексированных по значению опкода Operation
. Но Operation
объявляется как enum, и было бы неплохо объявить это как массив const, чтобы, если я добавлю больше кодов операций в будущем, компилятор может напомнить мне об обновлении массива.
Так как указатель метода хранит состояние времени выполнения (ссылка Self
на объект, с которым он работает,), я не могу создать массив const указателей методов. (В любом случае это не будет хорошей идеей, так как вполне вероятно, что в итоге я буду работать одновременно с несколькими script.) Но методы - это просто синтаксический сахар. Что-то вроде:
procedure TMyObject.DoSomething(x, y: integer);
действительно означает:
procedure TMyObject_DoSomething(Self: TMyObject; x, y: integer);
Итак, я должен иметь возможность объявить тип указателя функции в последней форме и назначить его таким образом, а затем мне просто нужно явно передать Self
в качестве первого параметра при его вызове. Но компилятору это не нравится.
type TOpcodeProc = procedure (Self: TScriptVM; Opcode: TOpcode);
const OPCODE: TOpcodeProc = TScriptVM.DoOp1;
[DCC Error]: E2009 Incompatible types: 'regular procedure and method pointer'
Я пробовал разные варианты, чтобы попытаться собрать его, но все они дают ошибки. Есть ли способ получить это для компиляции?