-
Notifications
You must be signed in to change notification settings - Fork 13
Home
Welcome to the MetaScript wiki! For now, the wiki contains a few non-trivial insights on writing meta.
//? if (NODE)
buffer.writeInt8(offset, value);
//? else
view.setInt8(value, offset);
This will actually work without using curly braces as long as there is just one line following, because each source line is wrapped by a dedicated write(...)
call, resulting in the following meta program:
if (NODE)
write('buffer.writeInt8(offset, value);\n');
else
write('view.setInt8(value, offset);\n');
The MetaScript compiler makes sure to retain any white spaces and line breaks with one important exception: If a meta line or block, which is not a ?=
expression, is the only contents of a line, the entire line will be skipped. Let's modify the example from above to demonstrate why this is useful:
if (true) {
//? if (NODE)
buffer.writeInt8(offset, value);
//? else
view.setInt8(value, offset);
}
The result of the above will not contain any white spaces or new lines where the meta statements are, like for NODE=true
:
if (true) {
buffer.writeInt8(offset, value);
}
Which looks much cleaner.
If you explicitly require indentation, you may use either a ?=
expression, the __
variable or even call the indent(str:string, indent:string|number):string
utility manually. Example:
// This will be indented (it's a ?= expression):
//?= 'var i=0;'
// Just like this (it uses manual indentation):
//? write(indent('var j=0;\n', 4));
// Or this (it prepends __):
//? write(__+'var k=0;\n');
// But this will not:
//? write('var k=0;\n');
Results in:
// This will be indented (it's a ?= expression):
var i=0;
// Just like this (it uses manual indentation):
var j=0;
// Or this (it prepends __):
var k=0;
// But this will not:
var k=0;
When inspecting the generated meta program, you will notice that the variable __
is used quite frequently. It stores the indentation level of the last meta block processed. For example ...
//? if (NODE)
//? include("node-stuff.js");
//? else
//? include("browser-stuff.js");
... will indent the contents of the included files by ' ' (four spaces), just like before //?
, while ...
/*? if (NODE)
include("node-stuff.js");
else
include("browser-stuff.js"); */
will not, just like before /*?
. When creating custom utility functions, it's of course safe to use this variable on your own.
Custom macros and utility functions will work only inside of the file they have been declared in. If you want them to be visible to included files as well, it's necessary to define them globally (without var
):
main source file:
//? include("macros.js");
...
//? assertOffset('offset');
...
macros.js:
//? assertOffset = function(varname) {
if (/*?= varname */ < 0 || /*?= varname */ > this.capacity()) {
throw(new RangeError("Illegal /*?= varname */"));
}
//? }