parseMaterial function
Reads source as one material.
A .f3dmat holds one block of the material language, first, and
after it only compute blocks, which are the kernel language's
(ComputeKernel.parseAll reads them, and skips the first block). The
optional f3dmat <N> line, and the kernel language's kernel <N> after
it, come before the first block. Anything else after it — a second
material, a fullscreen, a word nobody reads — is refused with where
it starts, rather than dropped without a word.
Implementation
MaterialProgram parseMaterial(String source) {
// The whole source where the first block never closes, which the parser
// then refuses in its own words.
final end = _blockEnd(source) ?? source.length;
final List<ExpressionToken> tokens;
try {
tokens = tokenizeExpression(
source.substring(0, end),
syntax: materialSyntax,
);
} on ExpressionSyntaxException catch (error, stack) {
Error.throwWithStackTrace(
MaterialSyntaxException(error.message, error.line, error.column),
stack,
);
}
final program = _Parser(tokens).parseMaterial();
_checkAfterFirstBlock(source, end);
return program;
}