Macros templating
@define¶
Creates a named definition in the current environment. These definitions can then be used inline in your script for substitution. By creating a named definition using a group of shards, you can reduce repeating huge chunks of code and improve readability.
@define(hello-define {
Msg("Hello")
Msg("World")
})
@wire(wire1 {
@hello-define
} Looped: false)
[wire1] Hello
[wire1] World
@template¶
Similar to @define
, creates a named definition that accepts arguments. This definition can then be used inline in your script for substitution any number of times.
@template(hello-template [message] {
Msg(message)
})
@wire(wire1 {
@hello-template("Hello")
@hello-template("Worldie")
} Looped: false)
[wire1] Hello
[wire1] Worldie
@ast¶
Generates an AST JSON string from the provided shards code block. Usually used for @macro
@wire(wire1 {
@ast({Msg("Hello")}) | Log
} Looped: false)
{"shs":[[{"sh":{"name":"Msg","params":[{"str":"Hello"}]},"line_info":{"line":29,"column":9,"file":2809170343}}]]}
@macro¶
Creates a reusable code block, with argument substitution
While very similar, there are subtle differences between @macro
and @template
. @macro
produces an AST JSON, which is then parsed/evaluated and then injected into the programme. While @template
only performs parameter substitution at runtime. Hence, only @macro
can compute a variable-length program at compile time while @template
is more geared towards dynamic substitution of arguments.
- Has the following parameters
Parameter | Type | Description |
---|---|---|
Name | Identifier | The macro’s name. |
Args | Sequence | A list of identifiers representing arguments. |
Shards | Shards block | The sequence of shards code form the macro body. Must return a sequence |
-
The
Shards
parameter for@macro
must output an AST JSON.@macro
will throw and error otherwise. -
@macro
can be used to generate an expression or generate a shards code pipeline.
@macro(macro1 [v] {
v >= hello
" World!" | AppendTo(hello)
[[{const: {str: hello}}]] | ToJson
})
@wire(wire1 {
1
Log(@macro1("Hello"))
} Looped: false)
[wire1] Hello World!: 1
@macro(my-macro [n] {
Sequence(pipelines)
Repeat({
{
sh: {
name: "Msg"
params: [{str: "Hello"}]
}
} >> pipelines
} Times: n)
[pipelines] | ToJson | Log
})
@wire(wire1 {
@my-macro(3)
} Looped: false)
[wire1] Hello
[wire1] Hello
[wire1] Hello
- When using
@macro
to generate a pipeline of shards code, the value for theShards
parameter needs to be an AST JSON written in a specific format. You can either write it manually or use@ast
to quickly convert a block of shards code into the required format.
@macro(my-macro-1 [] {
Sequence(pipelines)
Repeat({
{
sh: {
name: "Msg"
params: [{str: "Hello1"}]
}
} >> pipelines
} Times: n)
[pipelines] | ToJson | Log
})
@macro(my-macro2 [] {
@ast({
Msg("Hello2")
}) | FromJson | ExpectTable | Take("shs") | ToJson
})
@wire(wire1 {
@my-macro1()
@my-macro2()
} Looped: false)
[wire1] Hello1
[wire1] Hello2
@macro
is also useful for generating and injecting a different code block into your program depending on a specified condition.
@macro(macro-condition [cond] {
Sequence(pipelines)
cond | If(
Predicate: Is(true)
Then: {
@ast({Msg("Hello")})
}
Else: {
@ast({
1 | Math.Add(2) | Log("World")
})
}
) | FromJson | ExpectTable | Take("shs") | ToJson
})
@wire(wire1 {
@macro-condition(true)
@macro-condition(false)
} Looped: false)
[wire1] Hello
[wire1] World: 3