Этот вопрос касается построения пользовательских деревьев выражений в .NET с использованием операторов, найденных в C # (или любом другом языке). Я задаю вопрос вместе с некоторой справочной информацией.
Для моего управляемого двухфазного 64-битного ассемблера мне нужна поддержка выражений. Например, кто-то может захотеть собрать:
mystring: DB 'hello, world'
TIMES 64-$+mystring DB ' '
Выражение 64 - $ + mystring
должно быть не строкой, а фактическим допустимым выражением с преимуществами синтаксиса и проверки типов и IntelliSense в VS, что-то вроде строки:
64 - Reference.CurrentOffset + new Reference("mystring");
Это выражение не вычисляется при построении. Вместо этого он оценивается позже в контексте моего ассемблера (когда он определяет смещения символов и тому подобное). Платформа .NET (начиная с .NET 3.5) обеспечивает поддержку деревьев выражений, и мне кажется, что она идеально подходит для такого рода выражений, которые вычисляются позже или где-то еще.
Но я не знаю, как обеспечить что я могу использовать синтаксис C # (используя +,
var expression = AssemblerExpression.Subtract(64,
AssemblerExpression.Add(AssemblerExpression.CurrentOffset(),
AssemblerExpression.Reference("mystring")))
Как бы вы это сделали?
Примечание: мне нужно дерево выражения, чтобы иметь возможность преобразовывать выражение в приемлемое настраиваемое строковое представление и в то же время иметь возможность оценивать это в момент времени, отличный от его определения.
Объяснение моего примера: 64 - $ + mystring
. $
- это текущее смещение, поэтому это конкретное число, которое заранее неизвестно (но известно во время оценки). mystring
- это символ, который может быть известен или не известен во время оценки (например, когда он еще не определен). Вычитание константы C из символа S аналогично S + -C
. Вычитание двух символов S0 и S1 ( S1 - S0
) дает целочисленную разницу между значениями двух символов.
Однако этот вопрос на самом деле не о том, как вычислять выражения ассемблера, а больше о как оценить любое выражение, в котором есть пользовательские классы (для таких вещей, как символы и $
в примере), и как по-прежнему гарантировать, что оно может быть красиво напечатано с использованием некоторого посетителя (таким образом, сохраняя дерево). А поскольку в .NET framework есть свои деревья выражений и посетителей, было бы неплохо использовать их, если это возможно.