I think this is exactly what you want, minus the `do:`
import macros
import std/envvars, std/options
type
EnvType = object
m_user: Option[string]
m_icloud_dir: Option[string]
var Env*: EnvType
macro defineEnv*(fieldName, body: untyped): untyped =
let newName = ident("m_" & fieldName.strVal)
return quote do:
proc `fieldName`*(env: var EnvType): string =
if isNone(env.`newName`):
result = `body`
env.`newName` = some result
else:
result = env.`newName`.get
define_env user:
"USER".getEnv
define_env icloud_dir: "/Users/" & Env.user &
"/Library/CloudStorage/Box-Box"
echo Env.user
echo Env.icloud_dir
Run