A pip-installable version of Apple's gyb
python-based templating tool, along with Apple's line-directive
utility to map output lines to template lines. To install:
pip install gyb
For help (assuming that the pip installed binaries path is in your PATH
):
gyb -h
To use:
gyb file.ext.gyb -o file.ext
For details, see this great blog post.
A GYB template consists of the following elements:
- Literal text which is inserted directly into the output
%%
or$$
in literal text, which insert literal '%' and '$' symbols respectively.- Substitutions of the form
${<python-expression>}
. The Python expression is converted to a string and the result is inserted into the output. - Python code delimited by
%{...}%
. Typically used to inject definitions (functions, classes, variable bindings) into the evaluation context of the template. Common indentation is stripped, so you can add as much indentation to the beginning of this code as you like - Lines beginning with optional whitespace followed by a single '%' and Python code. %-lines allow you to nest other constructs inside them. To close a level of nesting, use the
%end
construct. - Lines beginning with optional whitespace and followed by a single '%' and the token "end", which close open constructs in %-lines.
Create implementations of all the math operators:
% for op,f in zip('+-*/', 'add sub mul div'.split()):
public static func ${op} (lhs:Self, rhs:Self ) -> Self { return lhs.${f}( rhs) }
% end
Define a variable:
%{ types = ('Float', 'Double') }%
(Thanks to Dave Abrahams for the following explanation and examples.)
#sourceLocation
is a directive used by tools like the Swift
compiler and debugger to adjust the lines reported in diagnostics and to
determine what source you see when you're stepping. #sourceLocation
corresponds to #line
in C/C++ which is inserted by code generators like
Lex/Flex/Yacc/Bison so that you deal with the actual code you wrote and not the
generated result. For dealing with errors in the Swift generated by your gyb
source it's important that your tools can take you to the right line in your
.gyb file rather than in generated .swift file. If you don't have such a tool,
manually indirecting through the generated code is tedious, but at least it's
possible since gyb leaves #sourceLocation
information behind.
But Swift's #sourceLocation
directive is suboptimal for the purposes of the
freeform code generation done with gyb because it can only appear between
grammatically-complete declarations and statements (or something like that). So
instead of inserting #sourceLocation
directives, gyb inserts // ###sourceLocation
comments (by default---it's tunable). This line-directive
tool remaps file and line information in the output of your swift compiler (or
whatever tool you are using to process generated source---gyb is not
swift-specific) so that the error points to the right place in the .gyb
source. You invoke it as follows:
line-directive <generated-sources> -- <compilation command>
e.g., if you have foo.swift.gyb, bar.swift.gyb, and baz.swift, instead of
gyb foo.swift.gyb -o foo.swift
gyb bar.swift.gyb -o bar.swift
swiftc foo.swift bar.swift baz.swift
You do this:
gyb foo.swift.gyb -o foo.swift
gyb bar.swift.gyb -o bar.swift
line-directive foo.swift bar.swift -- swiftc foo.swift bar.swift baz.swift