Scope of expressions returned from @generated functions

So I want to create models that have a similar calculation graph but differ in small aspects.
Each model is represented as a struct with matching dispatches for function calc.
To demonstrate what I have so far, I created the following script:

#file: demonstration.jl
abstract type AbstractT end

""" concreteT1 and concreteT2 have different parameter sets """
struct concreteT1 <: AbstractT

struct concreteT2 <: AbstractT

""" the function body into which expressions have to be inserted via 
expression ex_de """
macro calc_body(ex_de)
    return esc(quote

    a = ob.a
    b = ob.b
    c = ob.c

    d,e = $ex_de

    d += 1
    e += 2

    return a + b / (d*e)

""" calc shall be able to be called with both concreteT1 and concreteT2"""
function calc(ob::AbstractT)

""" expressions which can be inserted into calc_body """
macro de1()
    return esc(:((0, 0)))

macro de2()
    return esc(:((a/b, a*b*p)))

""" these functions decide, with type information about ob, which expression 
will be inserted into calc_body during a call to calc(AbstractT)"""
@generated function inserted_expression(ob::concreteT1)
    return @de1

@generated function inserted_expression(ob::concreteT2)
    return @de2

function main()

    """ works as expected """
    ob = concreteT1(1, 2, 3) 
    """ UndefVarError will be thrown when trying to access a 
    (that should be known inside calc_body)"""
    #ob = concreteT2(1, 2, 3, 4) 

    result = calc(ob)


So far, only calc(concreteT1) works, but not calc(concreteT2). An UndefVarError is thrown when trying to access variable “a” that, from my point of view, should be known within calc_body, where the returned expression from macro de2 is inserted.

I tried to esc() the returned expression from inserted_expression(concreteT2) but I it wouldn’t help either…

Why am I not just using functions instead of trying to generate functions?
I would like to be able to access every temporary variable known in calc_body and not think about what exactly goes into the code which calculates “d” and “e”.

Why am I not just moving the content from de2 to inserted_expression(concreteT2)?
In reality, calc_body can be modified at multiple points, not just with “ex_de”. If I then add concreteT3 that shares “ex_de” with concreteT1, but has another “ex_xy” (just an example), i want to reuse the expression that the existing macro de1 already returns.

I hope that I could make clear what my question is: Why do I get the UndefVarError? Can i change my code so that “a” will be known in the expression that de2 returns?

I am also open to criticism regarding my architecture itself.