Is it possible to "execute" the `ExprSyntax` tree to compute a double value?

something like this:

(lldb) po argument
├─leftOperand: TupleExprSyntax
│ ├─leftParen: leftParen
│ ├─elements: LabeledExprListSyntax
│ │ ╰─[0]: LabeledExprSyntax
│ │   ╰─expression: InfixOperatorExprSyntax
│ │     ├─leftOperand: IntegerLiteralExprSyntax
│ │     │ ╰─literal: integerLiteral("11")
│ │     ├─operator: BinaryOperatorExprSyntax
│ │     │ ╰─operator: binaryOperator("-")
│ │     ╰─rightOperand: IntegerLiteralExprSyntax
│ │       ╰─literal: integerLiteral("45")
│ ╰─rightParen: rightParen
├─operator: BinaryOperatorExprSyntax
│ ╰─operator: binaryOperator("*")
╰─rightOperand: MemberAccessExprSyntax
  ├─base: DeclReferenceExprSyntax
  │ ╰─baseName: identifier("Double")
  ├─period: period
  ╰─declName: DeclReferenceExprSyntax
    ╰─baseName: identifier("pi")

This is a Double expression with only litteral double (with or without decimal point) and static values from Double like Double.pi.

How to calculate the value of what the ExprSyntax to a Double?

IIUC, this isn’t generally possible — if you run it on an older x86 machine, it’ll do all the intermediate computations in 80-bit precision rather than 64-bit, for example, which could lead to a different final result than if you had computed it on an ARM or x86-64 machine. Remember that macros are evaluated on the host, not the target, which may be different architectures.


It could still be useful when there's no need to have exactly matching results between the host and the target platforms.

1 Like

On any platform you realistically have to care about Swift running on, they'll have IEEE-754 semantics these days, so that's not a problem. The bigger problem right now with evaluating code in macros is that they don't really get enough semantic information from the compiler to do so, since you only get the AST but not any type information. There also isn't any way to get function bodies for functions called in the expression, so outside of an allow-list of functions your evaluator supports, you wouldn't yet be able to evaluate any unknown function calls or operators that appear in the expression.