moon_wesl

A WESL module compiler for MoonBit backed by WGSL Core.

wesl
wgsl
shader
moon add Milky2018/moon_wesl@0.17.0
Download zip
Author
Version
0.17.0
License
Apache-2.0
Last updated
26 days ago
Downloads
183

Dependencies

README

#moon_wesl

Milky2018/moon_wesl is the WESL extension module maintained in the moonbit-community/moon_wgsl workspace. It provides a MoonBit library for compiling WESL shader modules into one emitted source string.

This package was extracted from mgstudio and preserves the former mgstudio/wesl root-package surface for downstream users. The public API is intentionally small and centered on:

  • ModulePath for module naming and relative import semantics
  • Resolver for loading source from any backing store
  • EscapeMangler for turning module-local names into emitted global symbols
  • CompileOptions for import resolution, stripping, lowering, and feature flags
  • compile(...) and Wesl::compile(...) as the main entry points

#Features

  • Resolves WESL import statements across modules
  • Supports @publish import ... re-exports
  • Evaluates @if(...), @else if (...), and @else conditional blocks
  • Strips unused declarations, rooted at shader entry points or explicit keep lists
  • Optionally lowers top-level alias and const declarations into plain emitted code
  • Delegates official WGSL parsing and semantic validation of emitted source to Milky2018/wgsl; WESL itself owns only extension and assembly semantics
  • Lets callers provide source code from memory, files, asset systems, or editor buffers through the Resolver trait

#Install

Add the module dependency first:

moon add Milky2018/moon_wesl

Then import the package in moon.pkg:

import { "Milky2018/moon_wesl", }

#Quick Start

///|
test {
let resolver = @moon_wesl.VirtualResolver::new()
let util_path = @moon_wesl.ModulePath::from_path("/shaders/util.wesl")
let root_path = @moon_wesl.ModulePath::from_path(
"/shaders/custom_material.wesl",
)

resolver.add_module(
util_path, "fn make_polka_dots(v: f32) -> f32 {\n @if(PARTY_MODE) {\n return v * 2.0;\n } @else {\n return v;\n }\n}\n",
)
resolver.add_module(
root_path, "import super::util::make_polka_dots;\n@fragment\nfn fragment(v: f32) -> f32 {\n return make_polka_dots(v);\n}\n",
)

let features = @moon_wesl.Features::default()
features.set_feature("PARTY_MODE", Enable)
let options = {
..@moon_wesl.CompileOptions::default(),
lower: true,
features,
}

let result = try! @moon_wesl.compile(
root_path,
resolver,
@moon_wesl.EscapeMangler::default(),
options,
)
inspect(result.to_string().contains("@fragment"), content="true")
}

The result contains the final emitted syntax tree in result.syntax; call result.to_string() for the WGSL text. Loaded module order is available in result.modules.

#Migration from 0.1.x

Version 0.17.0 moves official WGSL parsing and semantic validation to Milky2018/wgsl. The former public validate_wgsl(...) helper has been removed. Code that validates standalone WGSL should parse it with @ir.parse_wgsl_module_to_ir(...) and validate the result with @ir.validate_wgsl_ir_module(...) from Milky2018/wgsl/ir. Normal compile(...) users do not need to change calls: validation remains enabled by default and now runs through WGSL Core after WESL assembly.

The published module does not read environment variables, scan directories, or write artifacts. Feed source text through a Resolver, then pass CompileResult::to_string() to the filesystem, asset, editor, or build-system adapter owned by the application. The repository's workspace-only tools/wesl_io package is the reference filesystem adapter.

#Core Concepts

#ModulePath

ModulePath models the Bevy-style module naming scheme used by WESL imports. You can construct one from a filesystem-like path or parse the textual WESL form directly.

Examples:

  • ModulePath::from_path("/shaders/custom_material.wesl") -> package::shaders::custom_material
  • ModulePath::from_path("./util.wesl") -> self::util
  • ModulePath::from_path("../shared/noise.wesl") -> super::shared::noise
  • parse_module_path("package::shaders::util")

ModulePath::join_path(...) applies relative-import semantics, so a parent module can resolve self::... and super::... child paths without duplicating that logic in callers.

#Resolver

The compiler itself is storage-agnostic. It only requires a type that can map a ModulePath to source text:

///|
pub(open) trait Resolver {
fn resolve_source(Self, @moon_wesl.ModulePath) -> String raise @moon_wesl.ResolveError
}

The library ships with VirtualResolver, an in-memory implementation that is useful for tests, generated modules, editor integrations, and asset pipelines.

If you need to load shaders from disk, a game asset database, or another source of truth, implement Resolver in your own package and use ModulePath::to_path_string() to map module names back to your storage format.

#EscapeMangler

WESL modules are emitted into a flat output string, so imported declarations need stable global names. EscapeMangler converts (module path, item name) into emitted identifiers that preserve origin information and avoid collisions.

By default, declarations in the root module keep their original names. Dependencies are mangled automatically. Set mangle_root: true in a CompileOptions::default() record update if you want the root module to be mangled as well.

#Compilation Model

compile(...) performs four main steps:

  1. Load the root module through Resolver and parse top-level items and imports.
  2. Recursively resolve imports and compute the reachable declaration set.
  3. Emit modules in dependency order while rewriting imported identifiers to mangled global names.
  4. Optionally lower top-level alias and const declarations when lower is true.

When stripping is enabled, the root set is determined by:

  • functions annotated with @fragment, @vertex, or @compute
  • any declarations named by the keep field
  • all root declarations if keep_root is true

const_assert items are also scanned so their referenced declarations remain reachable.

#CompileOptions

CompileOptions::default() returns:

  • imports = true
  • condcomp = true
  • strip = true
  • lower = false
  • lazy_resolution = true
  • mangle_root = false
  • keep_root = false
  • keep = None
  • features = {}

Override only the fields you need. MoonBit record updates place the base first, for example { ..CompileOptions::default(), lower: true }.

Field behavior:

FieldDefaultMeaning
importstrueParse and resolve import statements. If disabled, import declarations are ignored instead of resolved.
condcomptrueEvaluate @if / @else if / @else blocks using the features map.
striptrueEmit only reachable declarations instead of the full transitive module closure.
lowerfalseRemove top-level alias and const declarations by textual substitution.
lazy_resolutiontrueWhen stripping is enabled, avoid eagerly loading imports that are never used.
mangle_rootfalseMangle declarations from the root module too.
keep_rootfalseKeep every declaration in the root module when stripping is enabled.
keepNoneKeep a specific set of root declarations even if they are not entry points.
features{}Configure conditional compilation; start from Features::default() and call set_feature.

#Re-exports and Visibility

The compiler distinguishes between ordinary imports and public re-exports:

  • import super::util::foo; makes foo available only inside the current module
  • @publish import super::util::foo; allows other modules to import foo through the current module

Attempting to re-export a private import raises WeslCompileError::Private. Missing symbols raise WeslCompileError::MissingDecl, and missing modules are reported through WeslCompileError::Resolve(...).

#Errors

The public error surface is:

  • ModulePathParseError for invalid textual module paths
  • ResolveError for source-loading failures
  • WeslCompileError for compile-time failures, including:
    • parse errors in WESL source
    • invalid conditional expressions
    • duplicate local declarations or import aliases
    • missing declarations in imported modules
    • private re-export attempts

Each error type exposes message() for user-facing diagnostics.

#Scope and Current Behavior

This package currently focuses on the mechanics required to compose WESL modules:

  • module-path resolution
  • import parsing
  • public re-export handling
  • conditional compilation
  • reachability-based stripping
  • symbol mangling
  • simple lowering of top-level aliases and constants
  • scalar/vector EvalResult::to_buffer() for i32, u32, and f32
  • minimal CPU execution for simple entrypoints, including scalar pipeline overrides, builtin and user-defined @location input parameters, struct field reads, vector swizzles, vector/array/matrix indexing, basic if / else and while control flow, for loops, loop/continuing/break if, switch selection, scalar/vector/struct/array/matrix resource buffers, and runtime array length queries, field/index/component storage resource writeback, and return buffers
  • filesystem package scanning and artifact generation

The parser and syntax layer are materially richer than the original text-oriented implementation, but this package is still not a full source-level port of wgsl-parse, wgsl-types, semantic lowering, or the complete CPU execution model.

#Design Constraints

moon_wesl is intended to remain a pure computation library:

  • no runtime dependency on graphics backends or platform SDKs
  • no requirement to embed or link wgpu, GPU drivers, window systems, or engine-specific runtimes
  • no platform-coupled execution model in the core package

Vendored Bevy and WGPU fixtures in the test suite are treated as compatibility corpora only. They are used to improve parser, compiler, and validation behavior, not as a signal that this package should depend on Bevy, WGPU, or any other platform/runtime integration layer.

#Repository Layout

#Development

Useful commands while working on the library:

moon test -v moon info moon fmt

#License

Apache-2.0.

#
ModulePreprocessor

pub(open) trait ModulePreprocessor {
fn preprocess_module(Self, ModulePath, TranslationUnit) -> TranslationUnit raise ResolveError
}

#
Resolver

pub(open) trait Resolver {
fn resolve_source(Self, ModulePath) -> String raise ResolveError
fn resolve_module(Self, ModulePath) -> TranslationUnit raise ResolveError = _
fn display_name(Self, ModulePath) -> String? = _
}

#
SourceMap

pub(open) trait SourceMap {
fn get_decl(Self, String) -> (ModulePath, String)?
fn get_source(Self, ModulePath) -> String?
fn get_display_name(Self, ModulePath) -> String?
fn get_default_source(Self) -> String? = _
fn unmangle_text(Self, String) -> String = _
}

#
ModulePathParseError

pub(all) suberror ModulePathParseError {
Empty
MisplacedPackage
MisplacedSelf
MisplacedSuper
}

#
ModulePathParseError::message

fn ModulePathParseError::message(self : ModulePathParseError) -> String

#
ResolveError

pub(all) suberror ResolveError {
ModuleNotFound(ModulePath, String)
Error(String)
}

#
ResolveError::message

fn ResolveError::message(self : ResolveError) -> String

#
ValidateError

pub(all) suberror ValidateError {
UndefinedSymbol(String)
ParamCount(String, Int, Int)
NotCallable(String)
Duplicate(String)
Cycle(String, String)
}

#
ValidateError::message

fn ValidateError::message(self : ValidateError) -> String

#
WeslCompileError

pub(all) suberror WeslCompileError {
Resolve(ResolveError)
Parse(String)
Validation(String)
Validate(ValidateError)
InvalidExpression(String)
DuplicateSymbol(String)
CircularDecl(String)
MissingDecl(ModulePath, String)
Private(String, ModulePath)
}

#
WeslCompileError::diagnostic

fn WeslCompileError::diagnostic(self : WeslCompileError) -> Diagnostic

#
WeslCompileError::message

fn WeslCompileError::message(self : WeslCompileError) -> String

#
WeslDiagnosticError

pub(all) suberror WeslDiagnosticError {
Diagnostic(Diagnostic)
}

#
WeslDiagnosticError::message

fn WeslDiagnosticError::message(self : WeslDiagnosticError) -> String

#
AliasDeclaration

pub(all) struct AliasDeclaration {
name : String
target : String?
target_type : TypeExpression?
} derive(Eq,
Debug
)

#
AssignmentOperator

pub(all) enum AssignmentOperator {
Equal
PlusEqual
MinusEqual
TimesEqual
DivisionEqual
ModuloEqual
AndEqual
OrEqual
XorEqual
ShiftLeftAssign
ShiftRightAssign
} derive(Eq,
Debug
)

#
AssignmentStatement

pub(all) struct AssignmentStatement {
operator : AssignmentOperator
lhs : Expression
rhs : Expression
} derive(Eq,
Debug
)

#
Attribute

pub(all) struct Attribute {
name : String
arguments : String?
argument_exprs : Array[Expression]
condition_expr : CondExpression?
span : SyntaxSpan
} derive(Eq,
Debug
)

#
BasicSourceMap

pub struct BasicSourceMap {
root : ModulePath
mappings :
HashMap
[String, (ModulePath, String)]
sources :
HashMap
[ModulePath, (String?, String)]
default_source : String?
} derive(
Debug
)

#
BasicSourceMap::add_decl

fn BasicSourceMap::add_decl(self : BasicSourceMap, decl : String, path : ModulePath, item : String) -> Unit

#
BasicSourceMap::add_source

fn BasicSourceMap::add_source(self : BasicSourceMap, file : ModulePath, name : String?, source : String) -> Unit

#
BasicSourceMap::default

#
BasicSourceMap::get_decl

fn BasicSourceMap::get_decl(self : BasicSourceMap, decl : String) -> (ModulePath, String)?

#
BasicSourceMap::get_default_source

fn BasicSourceMap::get_default_source(self : BasicSourceMap) -> String?

#
BasicSourceMap::get_display_name

fn BasicSourceMap::get_display_name(self : BasicSourceMap, path : ModulePath) -> String?

#
BasicSourceMap::get_source

fn BasicSourceMap::get_source(self : BasicSourceMap, path : ModulePath) -> String?

#
BasicSourceMap::new

#
BasicSourceMap::set_default_source

fn BasicSourceMap::set_default_source(self : BasicSourceMap, source : String) -> Unit

#
BasicSourceMap::unmangle_identifier

fn BasicSourceMap::unmangle_identifier(self : BasicSourceMap, mangled : String) -> String?

#
BasicSourceMap::unmangle_text

fn BasicSourceMap::unmangle_text(self : BasicSourceMap, text : String) -> String

#
BinaryOperator

pub(all) enum BinaryOperator {
ShortCircuitOr
ShortCircuitAnd
BitwiseOr
BitwiseXor
BitwiseAnd
Equality
Inequality
LessThan
LessThanEqual
GreaterThan
GreaterThanEqual
ShiftLeft
ShiftRight
Addition
Subtraction
Multiplication
Division
Remainder
} derive(Eq,
Debug
)

#
BlockStatement

pub(all) struct BlockStatement {
body : FunctionBody
} derive(Eq,
Debug
)

#
CodegenModule

pub struct CodegenModule {
name : String
source : String
submodules : Array[CodegenModule]
} derive(Eq,
Debug
)

#
CodegenModule::add_submodule

fn CodegenModule::add_submodule(self : CodegenModule, submodule : CodegenModule) -> Unit

#
CodegenModule::new

fn CodegenModule::new(name : String, source : String) -> CodegenModule

#
CodegenModule::with_submodules

fn CodegenModule::with_submodules(self : CodegenModule, submodules : Array[CodegenModule]) -> CodegenModule

#
CodegenPkg

pub struct CodegenPkg {
crate_name : String
root : CodegenModule
dependencies : Array[CodegenPkg]
} derive(Eq,
Debug
)

#
CodegenPkg::add_dependency

fn CodegenPkg::add_dependency(self : CodegenPkg, dependency : CodegenPkg) -> Unit

#
CodegenPkg::new

fn CodegenPkg::new(crate_name : String, root : CodegenModule) -> CodegenPkg

#
CodegenPkg::with_dependencies

fn CodegenPkg::with_dependencies(self : CodegenPkg, dependencies : Array[CodegenPkg]) -> CodegenPkg

#
CompileOptions

pub(all) struct CompileOptions {
imports : Bool
condcomp : Bool
generics : Bool
strip : Bool
lower : Bool
validate : Bool
lazy_resolution : Bool
mangle_root : Bool
keep : Array[String]?
keep_root : Bool
features : Features
}

#
CompileOptions::default

#
CompileResult

pub struct CompileResult {
syntax : TranslationUnit
sourcemap : BasicSourceMap?
modules : Array[ModulePath]
} derive(
Debug
)

#
CompileResult::default

fn CompileResult::default() -> CompileResult

#
CompileResult::eval

fn CompileResult::eval(self : CompileResult, source : String) -> EvalResult raise WeslCompileError

#
CompileResult::exec

fn CompileResult::exec(self : CompileResult, entrypoint : String, inputs : Inputs, resources : Array[ResourceBinding], overrides : Array[OverrideValue]) -> ExecResult raise WeslCompileError

#
CompileResult::has_sourcemap

fn CompileResult::has_sourcemap(self : CompileResult) -> Bool

#
CompileResult::to_string

fn CompileResult::to_string(self : CompileResult) -> String

#
CompileResult::unmangle_text

fn CompileResult::unmangle_text(self : CompileResult, text : String) -> String

#
CondCompPreprocessor

pub struct CondCompPreprocessor {
features : Features
}

#
CondCompPreprocessor::new

#
CondExpression

pub(all) enum CondExpression {
Literal(Bool)
Feature(String)
Not(CondExpression)
And(CondExpression, CondExpression)
Or(CondExpression, CondExpression)
} derive(Eq,
Debug
)

#
ConstAssertDeclaration

pub(all) struct ConstAssertDeclaration {
assertion : String
assertion_expr : Expression
} derive(Eq,
Debug
)

#
ConstDeclaration

pub(all) struct ConstDeclaration {
name : String
type_text : String?
type_expr : TypeExpression?
initializer : String?
initializer_expr : Expression?
} derive(Eq,
Debug
)

#
ContinuingStatement

pub(all) struct ContinuingStatement {
body : FunctionBody
} derive(Eq,
Debug
)

#
ControlStatement

pub(all) enum ControlStatement {
Block(BlockStatement)
If(IfStatement)
Switch(SwitchStatement)
Loop(LoopStatement)
For(ForStatement)
While(WhileStatement)
Continuing(ContinuingStatement)
} derive(Eq,
Debug
)

#
Diagnostic

pub(all) struct Diagnostic {
error : WeslCompileError
detail : DiagnosticDetail
}

#
Diagnostic::display_origin

fn Diagnostic::display_origin(self : Diagnostic) -> String

#
Diagnostic::display_short_origin

fn Diagnostic::display_short_origin(self : Diagnostic) -> String?

#
Diagnostic::infer_span_from_message

fn Diagnostic::infer_span_from_message(self : Diagnostic) -> Diagnostic

#
Diagnostic::message

fn Diagnostic::message(self : Diagnostic) -> String

#
Diagnostic::new

#
Diagnostic::to_string

fn Diagnostic::to_string(self : Diagnostic) -> String

#
Diagnostic::unmangle_with_mangler

fn Diagnostic::unmangle_with_mangler(self : Diagnostic, mangler : ManglerKind) -> Diagnostic

#
Diagnostic::unmangle_with_sourcemap

fn[S : SourceMap] Diagnostic::unmangle_with_sourcemap(self : Diagnostic, sourcemap : S) -> Diagnostic

#
Diagnostic::with_declaration

fn Diagnostic::with_declaration(self : Diagnostic, declaration : String) -> Diagnostic

#
Diagnostic::with_module_path

fn Diagnostic::with_module_path(self : Diagnostic, path : ModulePath, display_name : String?) -> Diagnostic

#
Diagnostic::with_output

fn Diagnostic::with_output(self : Diagnostic, output : String) -> Diagnostic

#
Diagnostic::with_source

fn Diagnostic::with_source(self : Diagnostic, source : String) -> Diagnostic

#
Diagnostic::with_sourcemap

fn[S : SourceMap] Diagnostic::with_sourcemap(self : Diagnostic, sourcemap : S) -> Diagnostic

#
Diagnostic::with_span

fn Diagnostic::with_span(self : Diagnostic, span : SourceSpan) -> Diagnostic

#
Diagnostic::with_syntax_span

fn Diagnostic::with_syntax_span(self : Diagnostic, span : SyntaxSpan) -> Diagnostic

#
DiagnosticDetail

pub(all) struct DiagnosticDetail {
source : String?
output : String?
module_path : ModulePath?
display_name : String?
declaration : String?
span : SourceSpan?
message : String?
} derive(Eq,
Debug
)

#
DiagnosticDetail::default

#
DiagnosticDirectiveDeclaration

pub(all) struct DiagnosticDirectiveDeclaration {
arguments : Array[String]
severity : String?
rule_name : String?
} derive(Eq,
Debug
)

#
EnableDirectiveDeclaration

pub(all) struct EnableDirectiveDeclaration {
names : Array[String]
} derive(Eq,
Debug
)

#
EscapeMangler

pub struct EscapeMangler {
}

#
EscapeMangler::default

fn EscapeMangler::default() -> EscapeMangler

#
EscapeMangler::mangle

fn EscapeMangler::mangle(_self : EscapeMangler, path : ModulePath, item : String) -> String

#
EscapeMangler::unmangle

fn EscapeMangler::unmangle(_self : EscapeMangler, mangled : String) -> (ModulePath, String)?

#
EvalResult

pub(all) struct EvalResult {
value : String
buffer : Bytes?
} derive(Eq,
Debug
)

#
EvalResult::to_buffer

fn EvalResult::to_buffer(self : EvalResult) -> Bytes?

#
EvalResult::to_string

fn EvalResult::to_string(self : EvalResult) -> String

#
ExecResult

pub(all) struct ExecResult {
value : String?
buffer : Bytes?
resources : Array[ResourceBinding]
} derive(Eq,
Debug
)

#
ExecResult::resource

fn ExecResult::resource(self : ExecResult, group : Int, binding : Int) -> ResourceBinding?

#
ExecResult::return_value

fn ExecResult::return_value(self : ExecResult) -> String?

#
ExecResult::to_buffer

fn ExecResult::to_buffer(self : ExecResult) -> Bytes?

#
ExecResult::to_string

fn ExecResult::to_string(self : ExecResult) -> String

#
Expression

pub(all) enum Expression {
Literal(String)
Bool(Bool)
TypeOrIdentifier(TypeExpression)
Parenthesized(Expression)
NamedComponent(Expression, String)
Indexing(Expression, Expression)
Unary(UnaryOperator, Expression)
Binary(BinaryOperator, Expression, Expression)
FunctionCall(FunctionCallExpression)
} derive(Eq,
Debug
)

#
Feature

pub(all) enum Feature {
Enable
Disable
Keep
Error
} derive(Eq,
Debug
)

#
Feature::default

fn Feature::default() -> Feature

#
Feature::from_bool

fn Feature::from_bool(value : Bool) -> Feature

#
Features

pub(all) struct Features {
default : Feature
flags :
HashMap
[String, Feature]
}

#
Features::default

fn Features::default() -> Features

#
Features::set_feature

fn Features::set_feature(self : Features, name : String, value : Feature) -> Unit

#
ForInitializer

pub(all) enum ForInitializer {
Declaration(StatementDeclaration)
Assignment(AssignmentStatement)
Expression(Expression)
} derive(Eq,
Debug
)

#
ForStatement

pub(all) struct ForStatement {
initializer : ForInitializer?
condition : Expression?
update : ForUpdate?
body : FunctionBody
} derive(Eq,
Debug
)

#
ForUpdate

pub(all) enum ForUpdate {
Assignment(AssignmentStatement)
Increment(Expression)
Decrement(Expression)
Expression(Expression)
} derive(Eq,
Debug
)

#
FunctionBody

pub(all) struct FunctionBody {
statements : Array[Statement]
} derive(Eq,
Debug
)

#
FunctionCallExpression

pub(all) struct FunctionCallExpression {
callee : TypeExpression
arguments : Array[Expression]
} derive(Eq,
Debug
)

#
FunctionDeclaration

pub(all) struct FunctionDeclaration {
name : String
generic_parameters : String?
parameters : Array[FunctionParameter]
return_type : String?
return_type_expr : TypeExpression?
return_attributes : Array[Attribute]
body : FunctionBody
} derive(Eq,
Debug
)

#
FunctionParameter

pub(all) struct FunctionParameter {
name : String
type_text : String
type_expr : TypeExpression
attributes : Array[Attribute]
} derive(Eq,
Debug
)

#
GlobalDeclaration

pub(all) struct GlobalDeclaration {
header : GlobalDeclarationHeader
attributes : Array[Attribute]
source : String
span : SyntaxSpan
} derive(Eq,
Debug
)

#
GlobalDeclarationHeader

pub(all) enum GlobalDeclarationHeader {
Function(FunctionDeclaration)
Struct(StructDeclaration)
Alias(AliasDeclaration)
Const(ConstDeclaration)
Override(OverrideDeclaration)
Let(LetDeclaration)
Var(VarDeclaration)
ConstAssert(ConstAssertDeclaration)
EnableDirective(EnableDirectiveDeclaration)
RequiresDirective(RequiresDirectiveDeclaration)
DiagnosticDirective(DiagnosticDirectiveDeclaration)
Other
} derive(Eq,
Debug
)

#
IdentityPreprocessor

pub struct IdentityPreprocessor {
}

#
IdentityPreprocessor::new

#
IfStatement

pub(all) struct IfStatement {
condition : Expression
body : FunctionBody
else_body : FunctionBody?
} derive(Eq,
Debug
)

#
ImportNode

pub(all) struct ImportNode {
path_segments : Array[String]
rename : String?
children : Array[ImportNode]
} derive(Eq,
Debug
)

#
ImportStatement

pub(all) struct ImportStatement {
span : SyntaxSpan
attributes : Array[Attribute]
entries : Array[ImportNode]
source : String
} derive(Eq,
Debug
)

#
ImportStatement::source_text

fn ImportStatement::source_text(self : ImportStatement) -> String

#
ImportedName

pub(all) struct ImportedName {
export_module_path : ModulePath?
export_name : String?
namespace_path : ModulePath
local_name : String
} derive(Eq,
Debug
)

#
Inputs

pub(all) struct Inputs {
vertex_index : Int?
instance_index : Int?
position : Array[Double]?
front_facing : Bool?
sample_index : Int?
sample_mask : Int?
local_invocation_id : Array[Int]?
local_invocation_index : Int?
global_invocation_id : Array[Int]?
workgroup_id : Array[Int]?
num_workgroups : Array[Int]?
subgroup_invocation_id : Int?
subgroup_size : Int?
subgroup_id : Int?
num_subgroups : Int?
primitive_index : Int?
view_index : Int?
user_defined : Array[UserInput]
} derive(Eq,
Debug
)

#
Inputs::new_zero_initialized

fn Inputs::new_zero_initialized() -> Inputs

#
LetDeclaration

pub(all) struct LetDeclaration {
name : String
type_text : String?
type_expr : TypeExpression?
initializer : String?
initializer_expr : Expression?
} derive(Eq,
Debug
)

#
LoopStatement

pub(all) struct LoopStatement {
body : FunctionBody
} derive(Eq,
Debug
)

#
ManglerKind

pub(all) enum ManglerKind {
Escape
Hash
Unicode
None
} derive(Eq,
Debug
)

#
ManglerKind::default

fn ManglerKind::default() -> ManglerKind

#
ManglerKind::mangle

fn ManglerKind::mangle(self : ManglerKind, path : ModulePath, item : String) -> String

#
ManglerKind::unmangle

fn ManglerKind::unmangle(self : ManglerKind, mangled : String) -> (ModulePath, String)?

#
ModuleItemRef

type ModuleItemRef derive(Eq,
Debug
)

#
ModulePath

pub(all) struct ModulePath {
origin : PathOrigin
components : Array[String]
} derive(Eq, Hash,
Debug
)

#
ModulePath::first

fn ModulePath::first(self : ModulePath) -> String?

#
ModulePath::from_path

fn ModulePath::from_path(path : String) -> ModulePath

#
ModulePath::is_package

fn ModulePath::is_package(self : ModulePath) -> Bool

#
ModulePath::is_relative

fn ModulePath::is_relative(self : ModulePath) -> Bool

#
ModulePath::is_root

fn ModulePath::is_root(self : ModulePath) -> Bool

#
ModulePath::join

fn ModulePath::join(self : ModulePath, suffix : Array[String]) -> ModulePath

#
ModulePath::join_path

fn ModulePath::join_path(self : ModulePath, suffix : ModulePath) -> ModulePath

#
ModulePath::last

fn ModulePath::last(self : ModulePath) -> String?

#
ModulePath::new

fn ModulePath::new(origin : PathOrigin, components : Array[String]) -> ModulePath

#
ModulePath::new_root

fn ModulePath::new_root() -> ModulePath

#
ModulePath::push

fn ModulePath::push(self : ModulePath, item : String) -> Unit

#
ModulePath::starts_with

fn ModulePath::starts_with(self : ModulePath, prefix : ModulePath) -> Bool

#
ModulePath::to_path_string

fn ModulePath::to_path_string(self : ModulePath) -> String

#
ModulePath::to_string

fn ModulePath::to_string(self : ModulePath) -> String

#
NoResolver

pub struct NoResolver {
}

#
NoResolver::default

fn NoResolver::default() -> NoResolver

#
NoResolver::new

fn NoResolver::new() -> NoResolver

#
NoSourceMap

pub struct NoSourceMap {
}

#
NoSourceMap::default

fn NoSourceMap::default() -> NoSourceMap

#
NoSourceMap::new

#
OverrideDeclaration

pub(all) struct OverrideDeclaration {
name : String
type_text : String?
type_expr : TypeExpression?
initializer : String?
initializer_expr : Expression?
} derive(Eq,
Debug
)

#
OverrideValue

pub(all) struct OverrideValue {
name : String
value : String
} derive(Eq,
Debug
)

#
PathOrigin

pub(all) enum PathOrigin {
Absolute
Relative(Int)
Package(String)
} derive(Eq, Hash,
Debug
)

#
Pkg

pub(all) struct Pkg {
crate_name : String
root : CodegenModule
dependencies : Array[CodegenPkg]
}

#
Pkg::codegen

fn Pkg::codegen(self : Pkg) -> String

#
Pkg::to_codegen_pkg

fn Pkg::to_codegen_pkg(self : Pkg) -> CodegenPkg

#
Pkg::validate

fn Pkg::validate(self : Pkg) -> Pkg raise WeslCompileError

#
PkgBuilder

pub struct PkgBuilder {
name : String
dependencies : Array[CodegenPkg]
}

#
PkgBuilder::add_package

fn PkgBuilder::add_package(self : PkgBuilder, pkg : CodegenPkg) -> PkgBuilder

#
PkgBuilder::add_packages

fn PkgBuilder::add_packages(self : PkgBuilder, pkgs : Array[CodegenPkg]) -> PkgBuilder

#
PkgBuilder::build

fn PkgBuilder::build(self : PkgBuilder, root : CodegenModule) -> Pkg

#
PkgBuilder::new

fn PkgBuilder::new(name : String) -> PkgBuilder

#
PkgResolver

pub struct PkgResolver {
packages : Array[CodegenPkg]
}

#
PkgResolver::add_package

fn PkgResolver::add_package(self : PkgResolver, pkg : CodegenPkg) -> Unit

#
PkgResolver::default

fn PkgResolver::default() -> PkgResolver

#
PkgResolver::new

#
Preprocessor

pub struct Preprocessor[R, P] {
resolver : R
preprocess : P
}

impl Resolver for Preprocessor[R, P]

#
Preprocessor::new

fn[R, P] Preprocessor::new(resolver : R, preprocess : P) -> Preprocessor[R, P]

#
RequiresDirectiveDeclaration

pub(all) struct RequiresDirectiveDeclaration {
names : Array[String]
} derive(Eq,
Debug
)

#
ResourceBinding

pub(all) struct ResourceBinding {
group : Int
binding : Int
kind : String
data : Bytes
} derive(Eq,
Debug
)

#
Router

pub struct Router {
// private fields
}

impl Resolver for Router

#
Router::default

fn Router::default() -> Router

#
Router::mount_fallback_resolver

fn Router::mount_fallback_resolver(self : Router, resolver : VirtualResolver) -> Unit

#
Router::mount_pkg_resolver

fn Router::mount_pkg_resolver(self : Router, prefix : ModulePath, resolver : PkgResolver) -> Unit

#
Router::mount_resolver

fn Router::mount_resolver(self : Router, prefix : ModulePath, resolver : VirtualResolver) -> Unit

#
Router::mount_standard_resolver

fn Router::mount_standard_resolver(self : Router, prefix : ModulePath, resolver : StandardResolver) -> Unit

#
Router::new

fn Router::new() -> Router

#
SourceMapper

pub struct SourceMapper[R] {
root : ModulePath
resolver : R
mangler : ManglerKind
sourcemap : BasicSourceMap
}

#
SourceMapper::finish

fn[R] SourceMapper::finish(self : SourceMapper[R]) -> BasicSourceMap

#
SourceMapper::mangle

fn[R] SourceMapper::mangle(self : SourceMapper[R], path : ModulePath, item : String) -> String

#
SourceMapper::mangler

fn[R] SourceMapper::mangler(self : SourceMapper[R]) -> ManglerKind

#
SourceMapper::new

fn[R] SourceMapper::new(root : ModulePath, resolver : R, mangler : ManglerKind) -> SourceMapper[R]

#
SourceMapper::sourcemap

fn[R] SourceMapper::sourcemap(self : SourceMapper[R]) -> BasicSourceMap

#
SourceMapper::unmangle

fn[R] SourceMapper::unmangle(self : SourceMapper[R], mangled : String) -> (ModulePath, String)?

#
SourcePosition

pub(all) struct SourcePosition {
line : Int
column : Int
offset : Int
} derive(Eq,
Debug
)

#
SourcePosition::new

fn SourcePosition::new(line : Int, column : Int, offset : Int) -> SourcePosition

#
SourceSpan

pub(all) struct SourceSpan {
start : SourcePosition
end : SourcePosition
} derive(Eq,
Debug
)

#
SourceSpan::from_line_range

fn SourceSpan::from_line_range(source : String, start_line : Int, end_line : Int) -> SourceSpan

#
SourceSpan::new

#
StandardResolver

pub struct StandardResolver {
pkg : PkgResolver
modules : VirtualResolver
constants :
HashMap
[String, Double]
}

#
StandardResolver::add_constant

fn StandardResolver::add_constant(self : StandardResolver, name : String, value : Double) -> Unit

#
StandardResolver::add_module

fn StandardResolver::add_module(self : StandardResolver, path : ModulePath, source : String) -> Unit

#
StandardResolver::add_package

fn StandardResolver::add_package(self : StandardResolver, pkg : CodegenPkg) -> Unit

#
StandardResolver::generate_constant_module

fn StandardResolver::generate_constant_module(self : StandardResolver) -> String

#
StandardResolver::new

#
Statement

pub(all) struct Statement {
kind : StatementKind
source : String
expression : Expression?
declaration : StatementDeclaration?
assignment : AssignmentStatement?
update_expression : Expression?
control : ControlStatement?
attributes : Array[Attribute]
} derive(Eq,
Debug
)

#
StatementDeclaration

pub(all) struct StatementDeclaration {
kind : StatementDeclarationKind
name : String?
template_arguments : String?
type_text : String?
type_expr : TypeExpression?
initializer : String?
initializer_expr : Expression?
} derive(Eq,
Debug
)

#
StatementDeclarationKind

pub(all) enum StatementDeclarationKind {
Const
Let
Var
} derive(Eq,
Debug
)

#
StatementKind

pub(all) enum StatementKind {
Empty
Block
Return
Discard
If
Switch
Loop
For
While
Continuing
Break
Continue
BreakIf
ConstAssert
Const
Let
Var
Assignment
CompoundAssignment
Increment
Decrement
Call
Other
} derive(Eq,
Debug
)

#
StructDeclaration

pub(all) struct StructDeclaration {
name : String
members : Array[StructMember]
} derive(Eq,
Debug
)

#
StructMember

pub(all) struct StructMember {
name : String
type_text : String
type_expr : TypeExpression
attributes : Array[Attribute]
} derive(Eq,
Debug
)

#
SwitchCase

pub(all) struct SwitchCase {
selectors : Array[Expression]
is_default : Bool
body : FunctionBody
attributes : Array[Attribute]
} derive(Eq,
Debug
)

#
SwitchStatement

pub(all) struct SwitchStatement {
selector : Expression
cases : Array[SwitchCase]
} derive(Eq,
Debug
)

#
SyntaxSpan

pub(all) struct SyntaxSpan {
start_line : Int
end_line : Int
} derive(Eq,
Debug
)

#
TranslationUnit

pub(all) struct TranslationUnit {
imports : Array[ImportStatement]
global_declarations : Array[GlobalDeclaration]
} derive(Eq,
Debug
)

#
TranslationUnit::default

#
TranslationUnit::to_string

fn TranslationUnit::to_string(self : TranslationUnit) -> String

#
TypeExpression

pub(all) struct TypeExpression {
path : Array[String]
ident : String
template_text : String?
template_args : Array[TypeTemplateArgument]
} derive(Eq,
Debug
)

#
TypeTemplateArgument

pub(all) enum TypeTemplateArgument {
Type(TypeExpression)
Literal(String)
} derive(Eq,
Debug
)

#
UnaryOperator

pub(all) enum UnaryOperator {
Negation
LogicalNegation
BitwiseComplement
Indirection
AddressOf
} derive(Eq,
Debug
)

#
UserInput

pub(all) struct UserInput {
location : Int
value : UserInputValue
} derive(Eq,
Debug
)

#
UserInputValue

pub(all) enum UserInputValue {
Bool(Bool)
I32(Int)
U32(Int)
F32(Double)
I32Vector(Array[Int])
U32Vector(Array[Int])
F32Vector(Array[Double])
} derive(Eq,
Debug
)

#
VarDeclaration

pub(all) struct VarDeclaration {
name : String?
template_arguments : String?
type_text : String?
type_expr : TypeExpression?
initializer : String?
initializer_expr : Expression?
} derive(Eq,
Debug
)

#
VirtualResolver

pub struct VirtualResolver {
files :
HashMap
[ModulePath, String]
}

#
VirtualResolver::add_module

fn VirtualResolver::add_module(self : VirtualResolver, path : ModulePath, source : String) -> Unit

#
VirtualResolver::add_translation_unit

fn VirtualResolver::add_translation_unit(self : VirtualResolver, path : ModulePath, translation_unit : TranslationUnit) -> Unit

#
VirtualResolver::default

#
VirtualResolver::get_module

fn VirtualResolver::get_module(self : VirtualResolver, path : ModulePath) -> String raise ResolveError

#
VirtualResolver::modules

fn VirtualResolver::modules(self : VirtualResolver) -> Array[(ModulePath, String)]

#
VirtualResolver::new

#
Wesl

pub struct Wesl[R] {
options : CompileOptions
use_sourcemap : Bool
resolver : R
mangler : ManglerKind
}

#
Wesl::add_constant

fn Wesl::add_constant(self : Wesl[StandardResolver], name : String, value : Double) -> Wesl[StandardResolver]

#
Wesl::add_constants

fn Wesl::add_constants(self : Wesl[StandardResolver], constants : Array[(String, Double)]) -> Wesl[StandardResolver]

#
Wesl::add_module

fn Wesl::add_module(self : Wesl[StandardResolver], path : ModulePath, source : String) -> Wesl[StandardResolver]

#
Wesl::add_package

fn Wesl::add_package(self : Wesl[StandardResolver], pkg : CodegenPkg) -> Wesl[StandardResolver]

#
Wesl::add_packages

fn Wesl::add_packages(self : Wesl[StandardResolver], pkgs : Array[CodegenPkg]) -> Wesl[StandardResolver]

#
Wesl::compile

fn[R : Resolver] Wesl::compile(self : Wesl[R], root : ModulePath) -> CompileResult raise WeslCompileError

#
Wesl::compile_diagnostic

fn[R : Resolver] Wesl::compile_diagnostic(self : Wesl[R], root : ModulePath) -> CompileResult raise WeslDiagnosticError

#
Wesl::keep_all_entrypoints

fn[R] Wesl::keep_all_entrypoints(self : Wesl[R]) -> Wesl[R]

#
Wesl::keep_declarations

fn[R] Wesl::keep_declarations(self : Wesl[R], keep : Array[String]) -> Wesl[R]

#
Wesl::new

fn Wesl::new() -> Wesl[StandardResolver]

#
Wesl::new_barebones

fn Wesl::new_barebones() -> Wesl[NoResolver]

#
Wesl::new_experimental

fn Wesl::new_experimental() -> Wesl[StandardResolver]

#
Wesl::new_virtual

fn Wesl::new_virtual(resolver : VirtualResolver) -> Wesl[VirtualResolver]

#
Wesl::resolver

fn[R] Wesl::resolver(self : Wesl[R]) -> R

#
Wesl::set_custom_resolver

fn[R, CustomResolver] Wesl::set_custom_resolver(self : Wesl[R], resolver : CustomResolver) -> Wesl[CustomResolver]

#
Wesl::set_feature

fn[R] Wesl::set_feature(self : Wesl[R], feature : String, value : Feature) -> Wesl[R]

#
Wesl::set_features

fn[R] Wesl::set_features(self : Wesl[R], features : Array[(String, Feature)]) -> Wesl[R]

#
Wesl::set_mangler

fn[R] Wesl::set_mangler(self : Wesl[R], kind : ManglerKind) -> Wesl[R]

#
Wesl::set_missing_feature_behavior

fn[R] Wesl::set_missing_feature_behavior(self : Wesl[R], value : Feature) -> Wesl[R]

#
Wesl::set_options

fn[R] Wesl::set_options(self : Wesl[R], options : CompileOptions) -> Wesl[R]

#
Wesl::unset_feature

fn[R] Wesl::unset_feature(self : Wesl[R], feature : String) -> Wesl[R]

#
Wesl::use_condcomp

fn[R] Wesl::use_condcomp(self : Wesl[R], value : Bool) -> Wesl[R]

#
Wesl::use_generics

fn[R] Wesl::use_generics(self : Wesl[R], value : Bool) -> Wesl[R]

#
Wesl::use_imports

fn[R] Wesl::use_imports(self : Wesl[R], value : Bool) -> Wesl[R]

#
Wesl::use_lower

fn[R] Wesl::use_lower(self : Wesl[R], value : Bool) -> Wesl[R]

#
Wesl::use_sourcemap

fn[R] Wesl::use_sourcemap(self : Wesl[R], value : Bool) -> Wesl[R]

#
Wesl::use_stripping

fn[R] Wesl::use_stripping(self : Wesl[R], value : Bool) -> Wesl[R]

#
WhileStatement

pub(all) struct WhileStatement {
condition : Expression
body : FunctionBody
} derive(Eq,
Debug
)

#
compile

fn[R : Resolver] compile(root : ModulePath, resolver : R, _mangler : EscapeMangler, options : CompileOptions) -> CompileResult raise WeslCompileError

#
compile_diagnostic

fn[R : Resolver] compile_diagnostic(root : ModulePath, resolver : R, _mangler : EscapeMangler, options : CompileOptions) -> CompileResult raise WeslDiagnosticError

#
compile_sourcemap

fn[R : Resolver] compile_sourcemap(root : ModulePath, resolver : R, _mangler : EscapeMangler, options : CompileOptions) -> CompileResult raise WeslCompileError

#
compile_sourcemap_diagnostic

fn[R : Resolver] compile_sourcemap_diagnostic(root : ModulePath, resolver : R, _mangler : EscapeMangler, options : CompileOptions) -> CompileResult raise WeslDiagnosticError

#
eval_const

fn eval_const(source : String, target_expr : String) -> EvalResult raise WeslCompileError

#
eval_str

fn eval_str(source : String) -> EvalResult raise WeslCompileError

#
parse_global_declarations

fn parse_global_declarations(source : String) -> Array[GlobalDeclaration] raise WeslCompileError

#
parse_module_path

fn parse_module_path(text : String) -> ModulePath raise ModulePathParseError

#
parse_translation_unit

fn parse_translation_unit(current_path : ModulePath, source : String, parse_imports : Bool) -> TranslationUnit raise WeslCompileError

#
validate_wesl

fn validate_wesl(unit : TranslationUnit) -> Unit raise WeslCompileError