Я использую Reflection.Emit для создания парсера математических выражений (например, 2+2
). Класс принимает выражение infix (например, 2+2
), превращает его в постфиксное выражение (например, 2 2 +
), а затем другой класс компилирует это постфиксное выражение в IL и создает DynamicMethod
. Оттуда выражение можно оценить так, как если бы оно было создано во время компиляции с одинаковой скоростью.Вызвать метод, используя экземпляр MethodInfo в стеке, используя Reflection.Emit
Этот компилятор поддерживает неявное умножение, так что-то вроде x(2 + 2)
вычисляется как x * (2 + 2)
Сейчас я пытаюсь реализовать определяемые пользователем функции (например, f(x)
). Проблема возникает, когда я пытаюсь различать неявное умножение, как показано выше, и определенные пользователем функции. Например, если пользователь вводит x(5)
, как узнать, хотят ли они умножить x
на 5
или вызвать функцию x
с аргументом 5
?
Чтобы решить эту проблему, в предыдущем случае компилятор вставляет в поток IL if
. Он вызывает функцию, чтобы определить, определена ли функция с идентификатором x
. Если есть, то он вставляет экземпляр MethodInfo
в стек через переменную out
и локальную.
Мой фактический вопрос заключается в возможности выполнить метод с использованием экземпляра MethodInfo
в стеке, который эквивалентен по скорости вызову IlGenerator.Emit(OpCodes.Call, MethodInfo)
во время компиляции?
Спасибо.
Рекомендация по дизайну: Сделать умножение явным или иметь другой синтаксис вызова функции. Наличие неоднозначного синтаксиса приводит к ошибкам/трудно идентифицировать ошибки пользователя. Вы знаете, что стандартная арифметическая нотация сосет, или вы не удосужились конвертировать в постфикс, и это одна из причин :) –