More About Subcode

Subcode with Parameters

One of the main purpose of subcode is to avoid code duplication. However, we often find ourselves writing similar code that are not exactly the same, in which case, the subcode need to carry parameters.

To define a subcode with parameter, simply append the parameter list after the name of the subcode. If there are multiple parameters, simply seperate them with commas:

subcode: A(name)
    Hello, $(name)

subcode: B(firstname, lastname)
    Hello, $(firstname) $(lastname)!

Inside the subcode, the parameters are refferred exactly the same way as macros. When we call the subcode with parameters, we need to append the values of the parameters:

page: t
    $call A, Hui
    $call A "friend"
    $call A  you again!

    $call B, Hui, Zhou

This will compile into:

Hello, Hui
Hello, "friend"
Hello, you again!
Hello, Hui Zhou!

As we seen here, the parameters are sepearated from name of the subcode by either a comma or simply spaces. The comma and spaces will be stripped in passing the parameter. Every thing except comma or trailing spaces are included in the parameter value. This is much more flexible than function parameter passing in a typical programming language and it is even much more flexible than typical macro systems.

What if sometime we really need to pass parameters with comma in it? First of all, if the parameter is delimited by quote or bracket, MyDef is intelligent enough to recognize it, you can direct use it:

subcode: A(name)
    Hello, $(name)

page: t
    $call A, "Zhou, Hui"
    $call A, 'Zhou,', Hui
    $call A, (Zhou, Hui)

This will be compile into:

Hello, "Zhou, Hui"
Hello, 'Zhou,' Hui
Hello, (Zhou, Hui)

However, if you try:

subcode: A(name)
    Hello, $(name)

page: t
    $call A, Zhou, Hui
$ make
mydef_page t.def out/t.txt
PAGE: t
    [t.def:6] Code A parameter mismatch (0 + 2) != 1. [pline:Zhou, Hui]
  --> [out/t.txt]

$ cat out/t.txt
Hello, Zhou

MyDef complains and omits the second parameter. So what if you really want to pass in unquoted comma as a single parameter? One solution is to tell MyDef that "subcode: A" only accepts single parameter:

subcode: A(@name)
    Hello, $(name)

page: t
    $call A, Zhou, Hui
$ make
mydef_page t.def out/t.txt
PAGE: t
  --> [out/t.txt]
$ cat out/t.txt
Hello, Zhou, Hui

As you wished and no complaints. In fact, you can force any last parameter to be single:

subcode: A(greeting, @name)
    $(greeting), $(name)

page: t
    $call A, Hello, Zhou, Hui

It works, but to some it is getting uncomfortable. MyDef uses '@' in some other places as well to force a meaning, as well as supress complaining. We admit it is a bit ugly, but hopefully you will not use it often.

When the parameter is being used inside the subcode definition, it is also taken quite literally without any restrictions:

subcode: print(v)
    print "variable \$$(v) = $$(v)\n"

subcode: print_v(v)
    print "variable \$(v) = $(v)\n"

subcode: call_print(subname, v)
    $call $(subname), $(v)

page: t
    $call print, v
    $call print_v, $v
    $call call_print, print_v, $v

This will compile into:

print "variable \$v = $v\n"
print "variable \$v = $v\n"
print "variable \$v = $v\n"

It even works with nested macros:

macros:
    name1: Alice
    name2: Bob

subcode: A(idx)
    Hello, $(name$(idx))

page: t
    $call A, 1
    $call A, 2

And the compiled output:

Hello, Alice
Hello, Bob

results matching ""

    No results matching ""