Scopes

In MyDef, all macros live in a series of nested scopes. On the very top is the global scope. Macros that are defined under "macros:" block lives in global scope. Next is the page scope. Page attributes live in page scope. Followed is the chain of scopes defined by each subcode starting at "subcode: main".

We can also dynamically create macros with the scope.

subcode: A
    $(set:name=Hui)
    Hello, $(name)!

The set macros are effective throughout the remainder of the subcode as well as all the subcodes being called with in.

subcode: A
    $(set:name=Hui)
    Hello, $(name)!
    $call B

subcode: B
    Bye, $(name)!

In addition to explicit subcode scope, preprocessing directive "$(for:...)" will also create new scope implicitly. However, "$(if:...)" does not create new scopes. So:

subcode: A(name)
    $(if:name=Hui)
        $(set:greeting=Hi)
    $(else)
        $(set:greeting=Hello)
    $(greeting), $(name)!

page: t
    $call A, Hui

will output "Hi, Hui!". However,

page: t
    $(for:i in 1-3)
        $(set:name=Hui_$(i))
        Set $(name).
    $(if:name)
        Hi, $(name)!
    $(else)
        No name here!

will compile to

Set Hui_1.
Set Hui_2.
Set Hui_3.
No name here!

An interesting question is: what scope should the block under "&call" be?

subcode: A
    $(set:name=A)
    BLOCK
    in subcode A: name = $(name)

page: t                      
    &call A
        in BLOCK: name=$(name)
        $(set:name=page t)

And if we compile, we get:

in BLOCK: name=A
in subcode A: name = page t

Apparently, the block under "&call" is the same as the subcode itself.

In addition to "$(set:...)" to create or reset macros at current scope, if we want to set/reset macros at one scope higher, we could use "$(export:...)":

subcode: A
    $(export:name=A)

page: t                      
    $call A
    Hello, $(name)!

This will compile into:

Hello, A!

if we want export a macro in the current scope to a higher scope, we can simply use "$(export:name)".

subcode: A
    $(set:name=A)
    $(export:name)

page: t                      
    $call A
    Hello, $(name)!

If we want to directly set macros at global scope, we could use "$(setmacro:...)".

subcode: AA
    $(setmacro:name=A)

subcode: A
    $call AA

page: t
    $call A
    Hello, $(name)!

results matching ""

    No results matching ""