///|
fn preprocess_emit_pipeline_item(
item : WgslDirectiveScanItem,
shader_defs : Map[String, ShaderDefValue],
import_state : WgslImportSubstitutionState,
used_imports : Array[ImportDefWithOffset],
scope : Scope,
) -> String raise PreprocessError {
let offset = item.start()
match item.kind() {
GlslVersion(version) => {
if version != "440" && version != "450" {
raise GlslInvalidVersion(offset)
}
preprocess_emit_scanned_item(
BlankTrivia,
item,
shader_defs,
import_state,
used_imports,
)
}
Directive(directive) => {
let (is_scope, _) = preprocess_check_scope_directive(
shader_defs,
directive,
Some(scope),
offset,
)
if is_scope ||
(
directive.has_required_tail_separator() &&
(directive.kind() == DefineImportPath || directive.kind() == Define)
) {
return preprocess_emit_scanned_item(
BlankTrivia,
item,
shader_defs,
import_state,
used_imports,
)
}
if scope.active() &&
directive.has_required_tail_separator() &&
directive.kind() == Import {
import_state.declare_imports(item.source().cleaned_text()) catch {
Parse(message, item_offset) =>
raise ImportParseError(message, offset + item_offset)
}
return preprocess_emit_scanned_item(
BlankTrivia,
item,
shader_defs,
import_state,
used_imports,
)
}
if scope.active() {
preprocess_emit_scanned_item(
RewriteActiveSource,
item,
shader_defs,
import_state,
used_imports,
)
} else {
preprocess_emit_scanned_item(
BlankTrivia,
item,
shader_defs,
import_state,
used_imports,
)
}
}
Source =>
if scope.active() {
preprocess_emit_scanned_item(
RewriteActiveSource,
item,
shader_defs,
import_state,
used_imports,
)
} else {
preprocess_emit_scanned_item(
BlankTrivia,
item,
shader_defs,
import_state,
used_imports,
)
}
}
}
///|
pub fn Preprocessor::preprocess(
_self : Preprocessor,
source : String,
shader_defs : Map[String, ShaderDefValue],
) -> PreprocessOutput raise PreprocessError {
let import_state = WgslImportSubstitutionState::default()
let used_imports : Array[ImportDefWithOffset] = []
let scope = Scope()
let mut final_string = ""
for item in parse_wgsl_directive_scan_items(source) {
final_string = final_string +
preprocess_emit_pipeline_item(
item, shader_defs, import_state, used_imports, scope,
)
}
scope.finish(utf8_byte_length(source))
PreprocessOutput(final_string, used_imports)
}