@wgslx/wgslx
Advanced tools
Comparing version 0.0.5 to 0.0.6
import { Token } from './token'; | ||
export declare function postprocess(token: Token): any; | ||
export declare function postprocess(token: Token, compact?: boolean): string; | ||
export declare function minify(token: Token): void; | ||
export declare function generateSourceMap(token: Token, file?: string, sourceRoot?: string): string; |
@@ -8,4 +8,4 @@ "use strict"; | ||
const util_1 = require("./util"); | ||
function postprocess(token) { | ||
let text = token.toString(); | ||
function postprocess(token, compact) { | ||
let text = token.toString(compact); | ||
text = text.replaceAll(util_1.TEMPLATE_START, '<').replaceAll(util_1.TEMPLATE_END, '>'); | ||
@@ -12,0 +12,0 @@ return text; |
@@ -123,3 +123,5 @@ export declare const translationUnit: import("./rules").SymbolRule; | ||
export declare const globalDirectiveExtended: import("./rules").SymbolRule; | ||
export declare const includeDirective: import("./rules").SymbolRule; | ||
export declare const includePath: import("./rules").SymbolRule; | ||
export declare const importDirective: import("./rules").SymbolRule; | ||
export declare const importPath: import("./rules").SymbolRule; | ||
export declare const translationUnitImport: import("./rules").SymbolRule; | ||
export declare const globalDirectiveImport: import("./rules").SymbolRule; |
@@ -5,3 +5,3 @@ "use strict"; | ||
exports.continueStatement = exports.breakIfStatement = exports.breakStatement = exports.whileStatement = exports.forUpdate = exports.forInit = exports.forHeader = exports.forStatement = exports.loopStatement = exports.caseSelector = exports.caseSelectors = exports.defaultAloneClause = exports.caseClause = exports.switchClause = exports.switchBody = exports.switchStatement = exports.elseClause = exports.elseIfClause = exports.ifClause = exports.ifStatement = exports.decrementStatement = exports.incrementStatement = exports.compoundAssignmentOperator = exports.assignmentStatement = exports.compoundStatement = exports.expression = exports.bitwiseExpression = exports.binaryXorExpression = exports.binaryAndExpression = exports.binaryOrExpression = exports.shortCircuitOrExpression = exports.shortCircuitAndExpression = exports.relationalExpression = exports.shiftExpression = exports.additiveOperator = exports.additiveExpression = exports.multiplicativeOperator = exports.multiplicativeExpression = exports.coreLhsExpression = exports.lhsExpression = exports.singularExpression = exports.unaryExpression = exports.componentOrSwizzleSpecifier = exports.expressionCommaList = exports.argumentExpressionList = exports.parenExpression = exports.callPhrase = exports.callExpression = exports.primaryExpression = exports.globalValueDecl = void 0; | ||
exports.includePath = exports.includeDirective = exports.globalDirectiveExtended = exports.translationUnitExtended = exports.swizzleName = exports.severityControlName = exports.identPatternToken = exports.softwareExtensionName = exports.enableExtensionName = exports.softwareExtensionList = exports.requiresDirective = exports.enableExtensionList = exports.enableDirective = exports.param = exports.paramList = exports.functionHeader = exports.functionDecl = exports.variableUpdatingStatement = exports.statement = exports.constAssertStatement = exports.funcCallStatement = exports.returnStatement = exports.continuingCompoundStatement = exports.continuingStatement = void 0; | ||
exports.globalDirectiveImport = exports.translationUnitImport = exports.importPath = exports.importDirective = exports.globalDirectiveExtended = exports.translationUnitExtended = exports.swizzleName = exports.severityControlName = exports.identPatternToken = exports.softwareExtensionName = exports.enableExtensionName = exports.softwareExtensionList = exports.requiresDirective = exports.enableExtensionList = exports.enableDirective = exports.param = exports.paramList = exports.functionHeader = exports.functionDecl = exports.variableUpdatingStatement = exports.statement = exports.constAssertStatement = exports.funcCallStatement = exports.returnStatement = exports.continuingCompoundStatement = exports.continuingStatement = void 0; | ||
const rules_1 = require("./rules"); | ||
@@ -260,7 +260,11 @@ const TEMPLATE_ARGS_START = '❬'; | ||
exports.globalDirectiveExtended = (0, rules_1.symbol)('global_directive_extended'); | ||
exports.includeDirective = (0, rules_1.symbol)('include_directive'); | ||
exports.includePath = (0, rules_1.symbol)('include_path'); | ||
exports.importDirective = (0, rules_1.symbol)('import_directive'); | ||
exports.importPath = (0, rules_1.symbol)('import_path'); | ||
exports.translationUnitImport = (0, rules_1.symbol)('translation_unit_import'); | ||
exports.globalDirectiveImport = (0, rules_1.symbol)('global_directive_import'); | ||
exports.translationUnitExtended.set((0, rules_1.union)((0, rules_1.sequence)((0, rules_1.star)(exports.globalDirectiveExtended), (0, rules_1.star)(exports.globalDecl)))); | ||
exports.globalDirectiveExtended.set((0, rules_1.union)(exports.diagnosticDirective, exports.enableDirective, exports.requiresDirective, exports.includeDirective)); | ||
exports.includeDirective.set((0, rules_1.union)((0, rules_1.sequence)('import', exports.includePath, ';'))); | ||
exports.includePath.set((0, rules_1.union)(/"[^*"/>:|?]+"/)); | ||
exports.globalDirectiveExtended.set((0, rules_1.union)(exports.diagnosticDirective, exports.enableDirective, exports.requiresDirective, exports.importDirective)); | ||
exports.importDirective.set((0, rules_1.union)((0, rules_1.sequence)('import', exports.importPath, ';'))); | ||
exports.importPath.set((0, rules_1.union)(/"[^*"<>:|?\\]+"/)); | ||
exports.translationUnitImport.set((0, rules_1.union)((0, rules_1.sequence)((0, rules_1.star)(exports.globalDirectiveImport), (0, rules_1.star)(exports.globalDecl)))); | ||
exports.globalDirectiveImport.set((0, rules_1.union)(exports.importDirective)); |
@@ -17,2 +17,3 @@ export interface TokenJson { | ||
symbol?: string; | ||
grouping?: string; | ||
source?: string; | ||
@@ -22,3 +23,2 @@ destination?: string; | ||
maybe: boolean; | ||
hasSymbol(symbol: string): boolean | "" | undefined; | ||
clone(): Token; | ||
@@ -25,0 +25,0 @@ toObject(): TokenJson; |
@@ -8,2 +8,3 @@ "use strict"; | ||
symbol; | ||
grouping; | ||
source; | ||
@@ -13,13 +14,16 @@ destination; | ||
maybe = false; | ||
hasSymbol(symbol) { | ||
return this.symbol && this.symbol.includes(symbol); | ||
} | ||
clone() { | ||
const token = new Token(); | ||
token.text = this.text; | ||
token.symbol = this.symbol; | ||
token.source = this.source; | ||
token.destination = this.destination; | ||
token.children = this.children; | ||
token.maybe = this.maybe; | ||
if (this.text) | ||
token.text = this.text; | ||
if (this.symbol) | ||
token.symbol = this.symbol; | ||
if (this.source) | ||
token.source = this.source; | ||
if (this.destination) | ||
token.destination = this.destination; | ||
if (this.children) | ||
token.children = this.children; | ||
if (this.maybe) | ||
token.maybe = this.maybe; | ||
return token; | ||
@@ -63,3 +67,3 @@ } | ||
token.children = children; | ||
if (symbol !== undefined) { | ||
if (symbol) { | ||
token.symbol = symbol; | ||
@@ -76,3 +80,4 @@ } | ||
parent.children = [token]; | ||
parent.symbol = symbol; | ||
if (symbol) | ||
parent.symbol = symbol; | ||
return parent; | ||
@@ -79,0 +84,0 @@ } |
import { SymbolRule } from './rules'; | ||
import { Token } from './token'; | ||
type FlexSymbol = string | SymbolRule; | ||
type FlexSymbol = string | SymbolRule | Token; | ||
export declare function symbolEquals(left: FlexSymbol, right: FlexSymbol): boolean; | ||
export declare function assertType(token: Token, symbol: FlexSymbol): void; | ||
@@ -5,0 +6,0 @@ export declare function ofType(...symbols: FlexSymbol[]): (token: Token) => boolean; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.traverse = exports.childrenOfType = exports.ofType = exports.assertType = void 0; | ||
exports.traverse = exports.childrenOfType = exports.ofType = exports.assertType = exports.symbolEquals = void 0; | ||
const token_1 = require("./token"); | ||
function symbolName(symbol) { | ||
@@ -8,2 +9,5 @@ if (typeof symbol === 'string') { | ||
} | ||
if (symbol instanceof token_1.Token) { | ||
return symbol.symbol ?? ''; | ||
} | ||
return symbol.symbol; | ||
@@ -14,4 +18,13 @@ } | ||
} | ||
function symbolEquals(left, right) { | ||
const leftName = symbolName(left); | ||
const rightName = symbolName(right); | ||
if (leftName === '' || rightName === '') { | ||
return false; | ||
} | ||
return leftName === rightName; | ||
} | ||
exports.symbolEquals = symbolEquals; | ||
function assertType(token, symbol) { | ||
if (!token.hasSymbol(symbolName(symbol))) { | ||
if (token.symbol !== symbolName(symbol)) { | ||
throw new Error('Type'); | ||
@@ -36,3 +49,11 @@ } | ||
} | ||
return token.children.filter(ofType(...symbols)); | ||
const predicate = ofType(...symbols); | ||
return token.children.flatMap((child) => { | ||
if (child.symbol) { | ||
return predicate(child) ? [child] : []; | ||
} | ||
else { | ||
return childrenOfType(child, symbols); | ||
} | ||
}); | ||
} | ||
@@ -39,0 +60,0 @@ exports.childrenOfType = childrenOfType; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.compileWgslx = exports.DEFAULT_WGSLX_OPTIONS = void 0; | ||
const postprocess_1 = require("./postprocess"); | ||
const preprocess_1 = require("./preprocess"); | ||
const syntax_1 = require("./syntax"); | ||
const traversal_1 = require("./traversal"); | ||
exports.DEFAULT_WGSLX_OPTIONS = Object.freeze({ | ||
sourceMap: false, | ||
mode: 'wgslx', | ||
whitespace: 'tokens', | ||
}); | ||
function tokenizeFile(source, filePath, rootSymbol) { | ||
source = (0, preprocess_1.preprocess)(source); | ||
const token = rootSymbol.matchAll(source, filePath); | ||
if (!token) { | ||
throw new Error('Failed to parse'); | ||
} | ||
return token; | ||
} | ||
class ImportContext { | ||
resolved = new Set(); | ||
importResolver; | ||
constructor(importResolver, baseFilePath) { | ||
this.importResolver = importResolver; | ||
this.resolved.add(baseFilePath); | ||
} | ||
import(currentFilePath, importStatementPath) { | ||
const importFilePath = this.importResolver.resolveFilePath(currentFilePath, importStatementPath); | ||
if (this.resolved.has(importFilePath)) { | ||
return null; | ||
} | ||
this.resolved.add(importFilePath); | ||
const importSource = this.importResolver.readSource(importFilePath); | ||
const token = tokenizeFile(importSource, importFilePath, syntax_1.translationUnitImport); | ||
if (!token) { | ||
throw new Error('Failed to parse'); | ||
} | ||
const directives = []; | ||
const declarations = []; | ||
for (let i = 0; i < token.children.length; i++) { | ||
if (!(0, traversal_1.symbolEquals)(token.children[i], syntax_1.globalDirectiveImport)) { | ||
declarations.push(token.children[i]); | ||
continue; | ||
} | ||
const directive = token.children[i]; | ||
for (let j = 0; j < directive.children.length; j++) { | ||
const importStatement = directive.children[j]; | ||
if ((0, traversal_1.symbolEquals)(importStatement, syntax_1.importDirective)) { | ||
const importPath = importStatement.children[1].text; | ||
const importToken = this.import(importFilePath, importPath); | ||
if (importToken) { | ||
declarations.push(...importToken.children); | ||
} | ||
} | ||
} | ||
} | ||
token.children = [...declarations]; | ||
return token; | ||
} | ||
} | ||
function compileWgslx(source, filePath, options) { | ||
const opts = { ...exports.DEFAULT_WGSLX_OPTIONS, ...options }; | ||
if (opts.mode === 'wgsl') { | ||
const token = tokenizeFile(source, filePath, syntax_1.translationUnit); | ||
return (0, postprocess_1.postprocess)(token, opts.whitespace === 'none'); | ||
} | ||
const rootToken = tokenizeFile(source, filePath, syntax_1.translationUnitExtended); | ||
const globalDirectives = (0, traversal_1.childrenOfType)(rootToken, [syntax_1.globalDirectiveExtended]); | ||
const nonImportGlobalDirectives = []; | ||
const globalDeclarations = (0, traversal_1.childrenOfType)(rootToken, [syntax_1.globalDecl]); | ||
for (const directive of globalDirectives) { | ||
if (!directive.children) { | ||
nonImportGlobalDirectives.push(directive); | ||
continue; | ||
} | ||
for (let i = 0; i < directive.children.length; i++) { | ||
const importStatement = directive.children[i]; | ||
if (!(0, traversal_1.symbolEquals)(importStatement, syntax_1.importDirective)) { | ||
nonImportGlobalDirectives.push(importStatement); | ||
continue; | ||
} | ||
if (!opts.importResolver) { | ||
throw new Error('Import resolver is required'); | ||
} | ||
const importContext = new ImportContext(opts.importResolver, filePath); | ||
if (!importStatement.children || importStatement.children.length < 2) { | ||
throw new Error('Expected children'); | ||
} | ||
const importLiteral = importStatement.children[1].text.substring(1, importStatement.children[1].text.length - 1); | ||
const importRoot = importContext.import(filePath, importLiteral); | ||
if (!importRoot) { | ||
throw new Error('Failed to import'); | ||
} | ||
const importDeclarations = (0, traversal_1.childrenOfType)(importRoot, [syntax_1.globalDecl]); | ||
nonImportGlobalDirectives.unshift(...importDeclarations); | ||
} | ||
} | ||
rootToken.children = [...nonImportGlobalDirectives, ...globalDeclarations]; | ||
return (0, postprocess_1.postprocess)(rootToken, opts.whitespace === 'none'); | ||
} | ||
exports.compileWgslx = compileWgslx; |
{ | ||
"name": "@wgslx/wgslx", | ||
"version": "0.0.5", | ||
"version": "0.0.6", | ||
"description": "Extended WebGPU shading language tools", | ||
@@ -5,0 +5,0 @@ "keywords": [ |
import * as fs from 'fs'; | ||
import * as path from 'path' | ||
import * as path from 'path'; | ||
@@ -8,7 +8,7 @@ const syntaxPath = path.resolve(__dirname, './syntax.bnf'); | ||
const syntax = fs.readFileSync(syntaxPath, { encoding: 'utf8' }); | ||
const syntaxExtended = fs.readFileSync(syntaxExtendedPath, { encoding: 'utf8' }); | ||
const syntax = fs.readFileSync(syntaxPath, {encoding: 'utf8'}); | ||
const syntaxExtended = fs.readFileSync(syntaxExtendedPath, {encoding: 'utf8'}); | ||
// Write output. | ||
let data = `// GENREATED FILE. DO NOT EDIT. RUN \`npm run generate\` | ||
let data = `// GENERATED FILE. DO NOT EDIT. RUN \`npm run generate\` | ||
@@ -29,10 +29,10 @@ import { maybe, sequence, star, symbol, union } from "./rules"; | ||
` | ||
`; | ||
function camel(underscore: string): string { | ||
if (underscore.startsWith('_')) { | ||
return underscore.substring(1).toUpperCase(); | ||
} | ||
if (underscore.startsWith('_')) { | ||
return underscore.substring(1).toUpperCase(); | ||
} | ||
return underscore.replace(/_[a-z]/g, c => c.substring(1).toUpperCase()); | ||
return underscore.replace(/_[a-z]/g, (c) => c.substring(1).toUpperCase()); | ||
} | ||
@@ -43,75 +43,74 @@ | ||
function line(tokens: string[], start = 0): string { | ||
const out: string[] = []; | ||
const out: string[] = []; | ||
let i: number; | ||
for (i = start; i < tokens.length && tokens[i] != ')'; i++) { | ||
const token = tokens[i]; | ||
let i: number; | ||
for (i = start; i < tokens.length && tokens[i] != ')'; i++) { | ||
const token = tokens[i]; | ||
if (token.startsWith('\'')) { | ||
out.push(token); | ||
continue; | ||
} | ||
if (token.startsWith("'")) { | ||
out.push(token); | ||
continue; | ||
} | ||
if (token.startsWith('/')) { | ||
out.push(token); | ||
continue; | ||
} | ||
if (token.startsWith('/')) { | ||
out.push(token); | ||
continue; | ||
} | ||
const identifier = token.match(/^[a-z_]+$/); | ||
if (identifier) { | ||
const variable = camel(token); | ||
if (variable !== 'DISAMBIGUATE_TEMPLATE') { | ||
out.push(camel(token)); | ||
} | ||
continue; | ||
} | ||
const identifier = token.match(/^[a-z_]+$/); | ||
if (identifier) { | ||
const variable = camel(token); | ||
if (variable !== 'DISAMBIGUATE_TEMPLATE') { | ||
out.push(camel(token)); | ||
} | ||
continue; | ||
} | ||
if (token === '*') { | ||
out[out.length - 1] = `star(${out[out.length - 1]})`; | ||
continue; | ||
} | ||
if (token === '*') { | ||
out[out.length - 1] = `star(${out[out.length - 1]})`; | ||
continue; | ||
} | ||
if (token === '?') { | ||
out[out.length - 1] = `maybe(${out[out.length - 1]})`; | ||
} | ||
if (token === '?') { | ||
out[out.length - 1] = `maybe(${out[out.length - 1]})`; | ||
} | ||
if (token === '(') { | ||
out.push(line(tokens, ++i)); | ||
continue; | ||
} | ||
if (token === '(') { | ||
out.push(line(tokens, ++i)); | ||
continue; | ||
} | ||
tokens.splice(start, i - start); | ||
} | ||
tokens.splice(start, i - start); | ||
if (out.length === 1) { | ||
return out[0]; | ||
} | ||
return `sequence(${out.join(', ')})`; | ||
if (out.length === 1) { | ||
return out[0]; | ||
} | ||
return `sequence(${out.join(', ')})`; | ||
} | ||
function process(syntax: string) { | ||
const declaration: string[] = []; | ||
const implementation: string[] = []; | ||
const declaration: string[] = []; | ||
const implementation: string[] = []; | ||
let ruleMatch = RULE_REGEX.exec(syntax); | ||
while (ruleMatch) { | ||
const identifier = ruleMatch[1]; | ||
const variable = camel(identifier); | ||
let ruleMatch = RULE_REGEX.exec(syntax); | ||
while (ruleMatch) { | ||
const identifier = ruleMatch[1]; | ||
const variable = camel(identifier); | ||
declaration.push(`export const ${variable} = symbol('${identifier}');`); | ||
declaration.push(`export const ${variable} = symbol('${identifier}');`); | ||
const lines = ruleMatch[2].split('\n|').map((s) => s.trim()); | ||
const rules = lines.map((l) => { | ||
const r = l.split(/\s/); | ||
return line(r); | ||
}); | ||
const lines = ruleMatch[2].split('\n|').map(s => s.trim()); | ||
const rules = lines | ||
.map(l => { | ||
const r = l.split(/\s/); | ||
return line(r); | ||
}) | ||
implementation.push( | ||
`${variable}.set(union(\n\t${rules.join(',\n\t')},\n));` | ||
); | ||
ruleMatch = RULE_REGEX.exec(syntax); | ||
} | ||
implementation.push(`${variable}.set(union(\n\t${rules.join(',\n\t')},\n));`) | ||
ruleMatch = RULE_REGEX.exec(syntax); | ||
}; | ||
data += ` | ||
data += ` | ||
// DECLARATIONS | ||
@@ -122,4 +121,3 @@ ${declaration.join('\n')} | ||
${implementation.join('\n\n')} | ||
` | ||
`; | ||
} | ||
@@ -130,2 +128,2 @@ | ||
fs.writeFileSync(outputPath, data); | ||
fs.writeFileSync(outputPath, data); |
@@ -18,4 +18,4 @@ import { | ||
export function postprocess(token: Token) { | ||
let text = token.toString(); | ||
export function postprocess(token: Token, compact?: boolean): string { | ||
let text = token.toString(compact); | ||
@@ -22,0 +22,0 @@ // Remove placeholder template strings. |
1021
src/syntax.ts
@@ -1,4 +0,4 @@ | ||
// GENREATED FILE. DO NOT EDIT. RUN `npm run generate` | ||
// GENERATED FILE. DO NOT EDIT. RUN `npm run generate` | ||
import {maybe, sequence, star, symbol, union} from './rules'; | ||
import { maybe, sequence, star, symbol, union } from "./rules"; | ||
@@ -17,2 +17,3 @@ // CONSTANTS | ||
// DECLARATIONS | ||
@@ -76,5 +77,3 @@ export const translationUnit = symbol('translation_unit'); | ||
export const expressionCommaList = symbol('expression_comma_list'); | ||
export const componentOrSwizzleSpecifier = symbol( | ||
'component_or_swizzle_specifier' | ||
); | ||
export const componentOrSwizzleSpecifier = symbol('component_or_swizzle_specifier'); | ||
export const unaryExpression = symbol('unary_expression'); | ||
@@ -99,5 +98,3 @@ export const singularExpression = symbol('singular_expression'); | ||
export const assignmentStatement = symbol('assignment_statement'); | ||
export const compoundAssignmentOperator = symbol( | ||
'compound_assignment_operator' | ||
); | ||
export const compoundAssignmentOperator = symbol('compound_assignment_operator'); | ||
export const incrementStatement = symbol('increment_statement'); | ||
@@ -126,5 +123,3 @@ export const decrementStatement = symbol('decrement_statement'); | ||
export const continuingStatement = symbol('continuing_statement'); | ||
export const continuingCompoundStatement = symbol( | ||
'continuing_compound_statement' | ||
); | ||
export const continuingCompoundStatement = symbol('continuing_compound_statement'); | ||
export const returnStatement = symbol('return_statement'); | ||
@@ -150,604 +145,600 @@ export const funcCallStatement = symbol('func_call_statement'); | ||
// IMPLEMENTATIONS | ||
translationUnit.set(union(sequence(star(globalDirective), star(globalDecl)))); | ||
translationUnit.set(union( | ||
sequence(star(globalDirective), star(globalDecl)), | ||
)); | ||
globalDirective.set( | ||
union(diagnosticDirective, enableDirective, requiresDirective) | ||
); | ||
globalDirective.set(union( | ||
diagnosticDirective, | ||
enableDirective, | ||
requiresDirective, | ||
)); | ||
globalDecl.set( | ||
union( | ||
';', | ||
sequence(globalVariableDecl, ';'), | ||
sequence(globalValueDecl, ';'), | ||
sequence(typeAliasDecl, ';'), | ||
structDecl, | ||
functionDecl, | ||
sequence(constAssertStatement, ';') | ||
) | ||
); | ||
globalDecl.set(union( | ||
';', | ||
sequence(globalVariableDecl, ';'), | ||
sequence(globalValueDecl, ';'), | ||
sequence(typeAliasDecl, ';'), | ||
structDecl, | ||
functionDecl, | ||
sequence(constAssertStatement, ';'), | ||
)); | ||
boolLiteral.set(union('true', 'false')); | ||
boolLiteral.set(union( | ||
'true', | ||
'false', | ||
)); | ||
intLiteral.set(union(decimalIntLiteral, hexIntLiteral)); | ||
intLiteral.set(union( | ||
decimalIntLiteral, | ||
hexIntLiteral, | ||
)); | ||
decimalIntLiteral.set(union(/0[iu]?/, /[1-9][0-9]*[iu]?/)); | ||
decimalIntLiteral.set(union( | ||
/0[iu]?/, | ||
/[1-9][0-9]*[iu]?/, | ||
)); | ||
hexIntLiteral.set(union(/0[xX][0-9a-fA-F]+[iu]?/)); | ||
hexIntLiteral.set(union( | ||
/0[xX][0-9a-fA-F]+[iu]?/, | ||
)); | ||
floatLiteral.set(union(decimalFloatLiteral, hexFloatLiteral)); | ||
floatLiteral.set(union( | ||
decimalFloatLiteral, | ||
hexFloatLiteral, | ||
)); | ||
decimalFloatLiteral.set( | ||
union( | ||
/0[fh]/, | ||
/[1-9][0-9]*[fh]/, | ||
/[0-9]*\.[0-9]+([eE][+-]?[0-9]+)?[fh]?/, | ||
/[0-9]+\.[0-9]*([eE][+-]?[0-9]+)?[fh]?/, | ||
/[0-9]+[eE][+-]?[0-9]+[fh]?/ | ||
) | ||
); | ||
decimalFloatLiteral.set(union( | ||
/0[fh]/, | ||
/[1-9][0-9]*[fh]/, | ||
/[0-9]*\.[0-9]+([eE][+-]?[0-9]+)?[fh]?/, | ||
/[0-9]+\.[0-9]*([eE][+-]?[0-9]+)?[fh]?/, | ||
/[0-9]+[eE][+-]?[0-9]+[fh]?/, | ||
)); | ||
hexFloatLiteral.set( | ||
union( | ||
/0[xX][0-9a-fA-F]*\.[0-9a-fA-F]+([pP][+-]?[0-9]+[fh]?)?/, | ||
/0[xX][0-9a-fA-F]+\.[0-9a-fA-F]*([pP][+-]?[0-9]+[fh]?)?/, | ||
/0[xX][0-9a-fA-F]+[pP][+-]?[0-9]+[fh]?/ | ||
) | ||
); | ||
hexFloatLiteral.set(union( | ||
/0[xX][0-9a-fA-F]*\.[0-9a-fA-F]+([pP][+-]?[0-9]+[fh]?)?/, | ||
/0[xX][0-9a-fA-F]+\.[0-9a-fA-F]*([pP][+-]?[0-9]+[fh]?)?/, | ||
/0[xX][0-9a-fA-F]+[pP][+-]?[0-9]+[fh]?/, | ||
)); | ||
diagnosticDirective.set(union(sequence('diagnostic', diagnosticControl, ';'))); | ||
diagnosticDirective.set(union( | ||
sequence('diagnostic', diagnosticControl, ';'), | ||
)); | ||
literal.set(union(intLiteral, floatLiteral, boolLiteral)); | ||
literal.set(union( | ||
intLiteral, | ||
floatLiteral, | ||
boolLiteral, | ||
)); | ||
ident.set(union(identPatternToken)); | ||
ident.set(union( | ||
identPatternToken, | ||
)); | ||
memberIdent.set(union(identPatternToken)); | ||
memberIdent.set(union( | ||
identPatternToken, | ||
)); | ||
diagnosticNameToken.set(union(identPatternToken)); | ||
diagnosticNameToken.set(union( | ||
identPatternToken, | ||
)); | ||
diagnosticRuleName.set( | ||
union( | ||
diagnosticNameToken, | ||
sequence(diagnosticNameToken, '.', diagnosticNameToken) | ||
) | ||
); | ||
diagnosticRuleName.set(union( | ||
diagnosticNameToken, | ||
sequence(diagnosticNameToken, '.', diagnosticNameToken), | ||
)); | ||
templateList.set( | ||
union(sequence(TEMPLATE_ARGS_START, templateArgCommaList, TEMPLATE_ARGS_END)) | ||
); | ||
templateList.set(union( | ||
sequence(TEMPLATE_ARGS_START, templateArgCommaList, TEMPLATE_ARGS_END), | ||
)); | ||
templateArgCommaList.set( | ||
union( | ||
sequence( | ||
templateArgExpression, | ||
star(sequence(',', templateArgExpression)), | ||
maybe(',') | ||
) | ||
) | ||
); | ||
templateArgCommaList.set(union( | ||
sequence(templateArgExpression, star(sequence(',', templateArgExpression)), maybe(',')), | ||
)); | ||
templateArgExpression.set(union(expression)); | ||
templateArgExpression.set(union( | ||
expression, | ||
)); | ||
alignAttr.set(union(sequence('@', 'align', '(', expression, maybe(','), ')'))); | ||
alignAttr.set(union( | ||
sequence('@', 'align', '(', expression, maybe(','), ')'), | ||
)); | ||
bindingAttr.set( | ||
union(sequence('@', 'binding', '(', expression, maybe(','), ')')) | ||
); | ||
bindingAttr.set(union( | ||
sequence('@', 'binding', '(', expression, maybe(','), ')'), | ||
)); | ||
builtinAttr.set( | ||
union(sequence('@', 'builtin', '(', builtinValueName, maybe(','), ')')) | ||
); | ||
builtinAttr.set(union( | ||
sequence('@', 'builtin', '(', builtinValueName, maybe(','), ')'), | ||
)); | ||
builtinValueName.set(union(identPatternToken)); | ||
builtinValueName.set(union( | ||
identPatternToken, | ||
)); | ||
constAttr.set(union(sequence('@', 'const'))); | ||
constAttr.set(union( | ||
sequence('@', 'const'), | ||
)); | ||
diagnosticAttr.set(union(sequence('@', 'diagnostic', diagnosticControl))); | ||
diagnosticAttr.set(union( | ||
sequence('@', 'diagnostic', diagnosticControl), | ||
)); | ||
groupAttr.set(union(sequence('@', 'group', '(', expression, maybe(','), ')'))); | ||
groupAttr.set(union( | ||
sequence('@', 'group', '(', expression, maybe(','), ')'), | ||
)); | ||
idAttr.set(union(sequence('@', 'id', '(', expression, maybe(','), ')'))); | ||
idAttr.set(union( | ||
sequence('@', 'id', '(', expression, maybe(','), ')'), | ||
)); | ||
interpolateAttr.set( | ||
union( | ||
sequence('@', 'interpolate', '(', interpolateTypeName, maybe(','), ')'), | ||
sequence( | ||
'@', | ||
'interpolate', | ||
'(', | ||
interpolateTypeName, | ||
',', | ||
interpolateSamplingName, | ||
maybe(','), | ||
')' | ||
) | ||
) | ||
); | ||
interpolateAttr.set(union( | ||
sequence('@', 'interpolate', '(', interpolateTypeName, maybe(','), ')'), | ||
sequence('@', 'interpolate', '(', interpolateTypeName, ',', interpolateSamplingName, maybe(','), ')'), | ||
)); | ||
interpolateTypeName.set(union(identPatternToken)); | ||
interpolateTypeName.set(union( | ||
identPatternToken, | ||
)); | ||
interpolateSamplingName.set(union(identPatternToken)); | ||
interpolateSamplingName.set(union( | ||
identPatternToken, | ||
)); | ||
invariantAttr.set(union(sequence('@', 'invariant'))); | ||
invariantAttr.set(union( | ||
sequence('@', 'invariant'), | ||
)); | ||
locationAttr.set( | ||
union(sequence('@', 'location', '(', expression, maybe(','), ')')) | ||
); | ||
locationAttr.set(union( | ||
sequence('@', 'location', '(', expression, maybe(','), ')'), | ||
)); | ||
mustUseAttr.set(union(sequence('@', 'must_use'))); | ||
mustUseAttr.set(union( | ||
sequence('@', 'must_use'), | ||
)); | ||
sizeAttr.set(union(sequence('@', 'size', '(', expression, maybe(','), ')'))); | ||
sizeAttr.set(union( | ||
sequence('@', 'size', '(', expression, maybe(','), ')'), | ||
)); | ||
workgroupSizeAttr.set( | ||
union( | ||
sequence('@', 'workgroup_size', '(', expression, maybe(','), ')'), | ||
sequence( | ||
'@', | ||
'workgroup_size', | ||
'(', | ||
expression, | ||
',', | ||
expression, | ||
maybe(','), | ||
')' | ||
), | ||
sequence( | ||
'@', | ||
'workgroup_size', | ||
'(', | ||
expression, | ||
',', | ||
expression, | ||
',', | ||
expression, | ||
maybe(','), | ||
')' | ||
) | ||
) | ||
); | ||
workgroupSizeAttr.set(union( | ||
sequence('@', 'workgroup_size', '(', expression, maybe(','), ')'), | ||
sequence('@', 'workgroup_size', '(', expression, ',', expression, maybe(','), ')'), | ||
sequence('@', 'workgroup_size', '(', expression, ',', expression, ',', expression, maybe(','), ')'), | ||
)); | ||
vertexAttr.set(union(sequence('@', 'vertex'))); | ||
vertexAttr.set(union( | ||
sequence('@', 'vertex'), | ||
)); | ||
fragmentAttr.set(union(sequence('@', 'fragment'))); | ||
fragmentAttr.set(union( | ||
sequence('@', 'fragment'), | ||
)); | ||
computeAttr.set(union(sequence('@', 'compute'))); | ||
computeAttr.set(union( | ||
sequence('@', 'compute'), | ||
)); | ||
attribute.set( | ||
union( | ||
sequence('@', identPatternToken, maybe(argumentExpressionList)), | ||
alignAttr, | ||
bindingAttr, | ||
builtinAttr, | ||
constAttr, | ||
diagnosticAttr, | ||
groupAttr, | ||
idAttr, | ||
interpolateAttr, | ||
invariantAttr, | ||
locationAttr, | ||
mustUseAttr, | ||
sizeAttr, | ||
workgroupSizeAttr, | ||
vertexAttr, | ||
fragmentAttr, | ||
computeAttr | ||
) | ||
); | ||
attribute.set(union( | ||
sequence('@', identPatternToken, maybe(argumentExpressionList)), | ||
alignAttr, | ||
bindingAttr, | ||
builtinAttr, | ||
constAttr, | ||
diagnosticAttr, | ||
groupAttr, | ||
idAttr, | ||
interpolateAttr, | ||
invariantAttr, | ||
locationAttr, | ||
mustUseAttr, | ||
sizeAttr, | ||
workgroupSizeAttr, | ||
vertexAttr, | ||
fragmentAttr, | ||
computeAttr, | ||
)); | ||
diagnosticControl.set( | ||
union( | ||
sequence('(', severityControlName, ',', diagnosticRuleName, maybe(','), ')') | ||
) | ||
); | ||
diagnosticControl.set(union( | ||
sequence('(', severityControlName, ',', diagnosticRuleName, maybe(','), ')'), | ||
)); | ||
structDecl.set(union(sequence('struct', ident, structBodyDecl))); | ||
structDecl.set(union( | ||
sequence('struct', ident, structBodyDecl), | ||
)); | ||
structBodyDecl.set( | ||
union( | ||
sequence( | ||
'{', | ||
structMember, | ||
star(sequence(',', structMember)), | ||
maybe(','), | ||
'}' | ||
) | ||
) | ||
); | ||
structBodyDecl.set(union( | ||
sequence('{', structMember, star(sequence(',', structMember)), maybe(','), '}'), | ||
)); | ||
structMember.set( | ||
union(sequence(star(attribute), memberIdent, ':', typeSpecifier)) | ||
); | ||
structMember.set(union( | ||
sequence(star(attribute), memberIdent, ':', typeSpecifier), | ||
)); | ||
typeAliasDecl.set(union(sequence('alias', ident, '=', typeSpecifier))); | ||
typeAliasDecl.set(union( | ||
sequence('alias', ident, '=', typeSpecifier), | ||
)); | ||
typeSpecifier.set(union(templateElaboratedIdent)); | ||
typeSpecifier.set(union( | ||
templateElaboratedIdent, | ||
)); | ||
templateElaboratedIdent.set(union(sequence(ident, maybe(templateList)))); | ||
templateElaboratedIdent.set(union( | ||
sequence(ident, maybe(templateList)), | ||
)); | ||
variableOrValueStatement.set( | ||
union( | ||
variableDecl, | ||
sequence(variableDecl, '=', expression), | ||
sequence('let', optionallyTypedIdent, '=', expression), | ||
sequence('const', optionallyTypedIdent, '=', expression) | ||
) | ||
); | ||
variableOrValueStatement.set(union( | ||
variableDecl, | ||
sequence(variableDecl, '=', expression), | ||
sequence('let', optionallyTypedIdent, '=', expression), | ||
sequence('const', optionallyTypedIdent, '=', expression), | ||
)); | ||
variableDecl.set( | ||
union(sequence('var', maybe(templateList), optionallyTypedIdent)) | ||
); | ||
variableDecl.set(union( | ||
sequence('var', maybe(templateList), optionallyTypedIdent), | ||
)); | ||
optionallyTypedIdent.set( | ||
union(sequence(ident, maybe(sequence(':', typeSpecifier)))) | ||
); | ||
optionallyTypedIdent.set(union( | ||
sequence(ident, maybe(sequence(':', typeSpecifier))), | ||
)); | ||
globalVariableDecl.set( | ||
union( | ||
sequence(star(attribute), variableDecl, maybe(sequence('=', expression))) | ||
) | ||
); | ||
globalVariableDecl.set(union( | ||
sequence(star(attribute), variableDecl, maybe(sequence('=', expression))), | ||
)); | ||
globalValueDecl.set( | ||
union( | ||
sequence('const', optionallyTypedIdent, '=', expression), | ||
sequence( | ||
star(attribute), | ||
'override', | ||
optionallyTypedIdent, | ||
maybe(sequence('=', expression)) | ||
) | ||
) | ||
); | ||
globalValueDecl.set(union( | ||
sequence('const', optionallyTypedIdent, '=', expression), | ||
sequence(star(attribute), 'override', optionallyTypedIdent, maybe(sequence('=', expression))), | ||
)); | ||
primaryExpression.set( | ||
union(templateElaboratedIdent, callExpression, literal, parenExpression) | ||
); | ||
primaryExpression.set(union( | ||
templateElaboratedIdent, | ||
callExpression, | ||
literal, | ||
parenExpression, | ||
)); | ||
callExpression.set(union(callPhrase)); | ||
callExpression.set(union( | ||
callPhrase, | ||
)); | ||
callPhrase.set( | ||
union(sequence(templateElaboratedIdent, argumentExpressionList)) | ||
); | ||
callPhrase.set(union( | ||
sequence(templateElaboratedIdent, argumentExpressionList), | ||
)); | ||
parenExpression.set(union(sequence('(', expression, ')'))); | ||
parenExpression.set(union( | ||
sequence('(', expression, ')'), | ||
)); | ||
argumentExpressionList.set( | ||
union(sequence('(', maybe(expressionCommaList), ')')) | ||
); | ||
argumentExpressionList.set(union( | ||
sequence('(', maybe(expressionCommaList), ')'), | ||
)); | ||
expressionCommaList.set( | ||
union(sequence(expression, star(sequence(',', expression)), maybe(','))) | ||
); | ||
expressionCommaList.set(union( | ||
sequence(expression, star(sequence(',', expression)), maybe(',')), | ||
)); | ||
componentOrSwizzleSpecifier.set( | ||
union( | ||
sequence('[', expression, ']', maybe(componentOrSwizzleSpecifier)), | ||
sequence('.', memberIdent, maybe(componentOrSwizzleSpecifier)), | ||
sequence('.', swizzleName, maybe(componentOrSwizzleSpecifier)) | ||
) | ||
); | ||
componentOrSwizzleSpecifier.set(union( | ||
sequence('[', expression, ']', maybe(componentOrSwizzleSpecifier)), | ||
sequence('.', memberIdent, maybe(componentOrSwizzleSpecifier)), | ||
sequence('.', swizzleName, maybe(componentOrSwizzleSpecifier)), | ||
)); | ||
unaryExpression.set( | ||
union( | ||
singularExpression, | ||
sequence('-', unaryExpression), | ||
sequence('!', unaryExpression), | ||
sequence('~', unaryExpression), | ||
sequence('*', unaryExpression), | ||
sequence('&', unaryExpression) | ||
) | ||
); | ||
unaryExpression.set(union( | ||
singularExpression, | ||
sequence('-', unaryExpression), | ||
sequence('!', unaryExpression), | ||
sequence('~', unaryExpression), | ||
sequence('*', unaryExpression), | ||
sequence('&', unaryExpression), | ||
)); | ||
singularExpression.set( | ||
union(sequence(primaryExpression, maybe(componentOrSwizzleSpecifier))) | ||
); | ||
singularExpression.set(union( | ||
sequence(primaryExpression, maybe(componentOrSwizzleSpecifier)), | ||
)); | ||
lhsExpression.set( | ||
union( | ||
sequence(coreLhsExpression, maybe(componentOrSwizzleSpecifier)), | ||
sequence('*', lhsExpression), | ||
sequence('&', lhsExpression) | ||
) | ||
); | ||
lhsExpression.set(union( | ||
sequence(coreLhsExpression, maybe(componentOrSwizzleSpecifier)), | ||
sequence('*', lhsExpression), | ||
sequence('&', lhsExpression), | ||
)); | ||
coreLhsExpression.set(union(ident, sequence('(', lhsExpression, ')'))); | ||
coreLhsExpression.set(union( | ||
ident, | ||
sequence('(', lhsExpression, ')'), | ||
)); | ||
multiplicativeExpression.set( | ||
union( | ||
unaryExpression, | ||
sequence(multiplicativeExpression, multiplicativeOperator, unaryExpression) | ||
) | ||
); | ||
multiplicativeExpression.set(union( | ||
unaryExpression, | ||
sequence(multiplicativeExpression, multiplicativeOperator, unaryExpression), | ||
)); | ||
multiplicativeOperator.set(union('*', '/', '%')); | ||
multiplicativeOperator.set(union( | ||
'*', | ||
'/', | ||
'%', | ||
)); | ||
additiveExpression.set( | ||
union( | ||
multiplicativeExpression, | ||
sequence(additiveExpression, additiveOperator, multiplicativeExpression) | ||
) | ||
); | ||
additiveExpression.set(union( | ||
multiplicativeExpression, | ||
sequence(additiveExpression, additiveOperator, multiplicativeExpression), | ||
)); | ||
additiveOperator.set(union('+', '-')); | ||
additiveOperator.set(union( | ||
'+', | ||
'-', | ||
)); | ||
shiftExpression.set( | ||
union( | ||
additiveExpression, | ||
sequence(unaryExpression, SHIFT_LEFT, unaryExpression), | ||
sequence(unaryExpression, SHIFT_RIGHT, unaryExpression) | ||
) | ||
); | ||
shiftExpression.set(union( | ||
additiveExpression, | ||
sequence(unaryExpression, SHIFT_LEFT, unaryExpression), | ||
sequence(unaryExpression, SHIFT_RIGHT, unaryExpression), | ||
)); | ||
relationalExpression.set( | ||
union( | ||
shiftExpression, | ||
sequence(shiftExpression, LESS_THAN, shiftExpression), | ||
sequence(shiftExpression, GREATER_THAN, shiftExpression), | ||
sequence(shiftExpression, LESS_THAN_EQUAL, shiftExpression), | ||
sequence(shiftExpression, GREATER_THAN_EQUAL, shiftExpression), | ||
sequence(shiftExpression, '==', shiftExpression), | ||
sequence(shiftExpression, '!=', shiftExpression) | ||
) | ||
); | ||
relationalExpression.set(union( | ||
shiftExpression, | ||
sequence(shiftExpression, LESS_THAN, shiftExpression), | ||
sequence(shiftExpression, GREATER_THAN, shiftExpression), | ||
sequence(shiftExpression, LESS_THAN_EQUAL, shiftExpression), | ||
sequence(shiftExpression, GREATER_THAN_EQUAL, shiftExpression), | ||
sequence(shiftExpression, '==', shiftExpression), | ||
sequence(shiftExpression, '!=', shiftExpression), | ||
)); | ||
shortCircuitAndExpression.set( | ||
union( | ||
relationalExpression, | ||
sequence(shortCircuitAndExpression, '&&', relationalExpression) | ||
) | ||
); | ||
shortCircuitAndExpression.set(union( | ||
relationalExpression, | ||
sequence(shortCircuitAndExpression, '&&', relationalExpression), | ||
)); | ||
shortCircuitOrExpression.set( | ||
union( | ||
relationalExpression, | ||
sequence(shortCircuitOrExpression, '||', relationalExpression) | ||
) | ||
); | ||
shortCircuitOrExpression.set(union( | ||
relationalExpression, | ||
sequence(shortCircuitOrExpression, '||', relationalExpression), | ||
)); | ||
binaryOrExpression.set( | ||
union(unaryExpression, sequence(binaryOrExpression, '|', unaryExpression)) | ||
); | ||
binaryOrExpression.set(union( | ||
unaryExpression, | ||
sequence(binaryOrExpression, '|', unaryExpression), | ||
)); | ||
binaryAndExpression.set( | ||
union(unaryExpression, sequence(binaryAndExpression, '&', unaryExpression)) | ||
); | ||
binaryAndExpression.set(union( | ||
unaryExpression, | ||
sequence(binaryAndExpression, '&', unaryExpression), | ||
)); | ||
binaryXorExpression.set( | ||
union(unaryExpression, sequence(binaryXorExpression, '^', unaryExpression)) | ||
); | ||
binaryXorExpression.set(union( | ||
unaryExpression, | ||
sequence(binaryXorExpression, '^', unaryExpression), | ||
)); | ||
bitwiseExpression.set( | ||
union( | ||
sequence(binaryAndExpression, '&', unaryExpression), | ||
sequence(binaryOrExpression, '|', unaryExpression), | ||
sequence(binaryXorExpression, '^', unaryExpression) | ||
) | ||
); | ||
bitwiseExpression.set(union( | ||
sequence(binaryAndExpression, '&', unaryExpression), | ||
sequence(binaryOrExpression, '|', unaryExpression), | ||
sequence(binaryXorExpression, '^', unaryExpression), | ||
)); | ||
expression.set( | ||
union( | ||
relationalExpression, | ||
sequence(shortCircuitOrExpression, '||', relationalExpression), | ||
sequence(shortCircuitAndExpression, '&&', relationalExpression), | ||
bitwiseExpression | ||
) | ||
); | ||
expression.set(union( | ||
relationalExpression, | ||
sequence(shortCircuitOrExpression, '||', relationalExpression), | ||
sequence(shortCircuitAndExpression, '&&', relationalExpression), | ||
bitwiseExpression, | ||
)); | ||
compoundStatement.set( | ||
union(sequence(star(attribute), '{', star(statement), '}')) | ||
); | ||
compoundStatement.set(union( | ||
sequence(star(attribute), '{', star(statement), '}'), | ||
)); | ||
assignmentStatement.set( | ||
union( | ||
sequence(lhsExpression, '=', expression), | ||
sequence(lhsExpression, compoundAssignmentOperator, expression), | ||
sequence('_', '=', expression) | ||
) | ||
); | ||
assignmentStatement.set(union( | ||
sequence(lhsExpression, '=', expression), | ||
sequence(lhsExpression, compoundAssignmentOperator, expression), | ||
sequence('_', '=', expression), | ||
)); | ||
compoundAssignmentOperator.set( | ||
union( | ||
'+=', | ||
'-=', | ||
'*=', | ||
'/=', | ||
'%=', | ||
'&=', | ||
'|=', | ||
'^=', | ||
SHIFT_RIGHT_ASSIGN, | ||
SHIFT_LEFT_ASSIGN | ||
) | ||
); | ||
compoundAssignmentOperator.set(union( | ||
'+=', | ||
'-=', | ||
'*=', | ||
'/=', | ||
'%=', | ||
'&=', | ||
'|=', | ||
'^=', | ||
SHIFT_RIGHT_ASSIGN, | ||
SHIFT_LEFT_ASSIGN, | ||
)); | ||
incrementStatement.set(union(sequence(lhsExpression, '++'))); | ||
incrementStatement.set(union( | ||
sequence(lhsExpression, '++'), | ||
)); | ||
decrementStatement.set(union(sequence(lhsExpression, '--'))); | ||
decrementStatement.set(union( | ||
sequence(lhsExpression, '--'), | ||
)); | ||
ifStatement.set( | ||
union( | ||
sequence(star(attribute), ifClause, star(elseIfClause), maybe(elseClause)) | ||
) | ||
); | ||
ifStatement.set(union( | ||
sequence(star(attribute), ifClause, star(elseIfClause), maybe(elseClause)), | ||
)); | ||
ifClause.set(union(sequence('if', expression, compoundStatement))); | ||
ifClause.set(union( | ||
sequence('if', expression, compoundStatement), | ||
)); | ||
elseIfClause.set(union(sequence('else', 'if', expression, compoundStatement))); | ||
elseIfClause.set(union( | ||
sequence('else', 'if', expression, compoundStatement), | ||
)); | ||
elseClause.set(union(sequence('else', compoundStatement))); | ||
elseClause.set(union( | ||
sequence('else', compoundStatement), | ||
)); | ||
switchStatement.set( | ||
union(sequence(star(attribute), 'switch', expression, switchBody)) | ||
); | ||
switchStatement.set(union( | ||
sequence(star(attribute), 'switch', expression, switchBody), | ||
)); | ||
switchBody.set(union(sequence(star(attribute), '{', switchClause, '}'))); | ||
switchBody.set(union( | ||
sequence(star(attribute), '{', switchClause, '}'), | ||
)); | ||
switchClause.set(union(caseClause, defaultAloneClause)); | ||
switchClause.set(union( | ||
caseClause, | ||
defaultAloneClause, | ||
)); | ||
caseClause.set( | ||
union(sequence('case', caseSelectors, maybe(':'), compoundStatement)) | ||
); | ||
caseClause.set(union( | ||
sequence('case', caseSelectors, maybe(':'), compoundStatement), | ||
)); | ||
defaultAloneClause.set( | ||
union(sequence('default', maybe(':'), compoundStatement)) | ||
); | ||
defaultAloneClause.set(union( | ||
sequence('default', maybe(':'), compoundStatement), | ||
)); | ||
caseSelectors.set( | ||
union(sequence(caseSelector, star(sequence(',', caseSelector)), maybe(','))) | ||
); | ||
caseSelectors.set(union( | ||
sequence(caseSelector, star(sequence(',', caseSelector)), maybe(',')), | ||
)); | ||
caseSelector.set(union('default', expression)); | ||
caseSelector.set(union( | ||
'default', | ||
expression, | ||
)); | ||
loopStatement.set( | ||
union( | ||
sequence( | ||
star(attribute), | ||
'loop', | ||
star(attribute), | ||
'{', | ||
star(statement), | ||
maybe(continuingStatement), | ||
'}' | ||
) | ||
) | ||
); | ||
loopStatement.set(union( | ||
sequence(star(attribute), 'loop', star(attribute), '{', star(statement), maybe(continuingStatement), '}'), | ||
)); | ||
forStatement.set( | ||
union( | ||
sequence(star(attribute), 'for', '(', forHeader, ')', compoundStatement) | ||
) | ||
); | ||
forStatement.set(union( | ||
sequence(star(attribute), 'for', '(', forHeader, ')', compoundStatement), | ||
)); | ||
forHeader.set( | ||
union(sequence(maybe(forInit), ';', maybe(expression), ';', maybe(forUpdate))) | ||
); | ||
forHeader.set(union( | ||
sequence(maybe(forInit), ';', maybe(expression), ';', maybe(forUpdate)), | ||
)); | ||
forInit.set( | ||
union(variableOrValueStatement, variableUpdatingStatement, funcCallStatement) | ||
); | ||
forInit.set(union( | ||
variableOrValueStatement, | ||
variableUpdatingStatement, | ||
funcCallStatement, | ||
)); | ||
forUpdate.set(union(variableUpdatingStatement, funcCallStatement)); | ||
forUpdate.set(union( | ||
variableUpdatingStatement, | ||
funcCallStatement, | ||
)); | ||
whileStatement.set( | ||
union(sequence(star(attribute), 'while', expression, compoundStatement)) | ||
); | ||
whileStatement.set(union( | ||
sequence(star(attribute), 'while', expression, compoundStatement), | ||
)); | ||
breakStatement.set(union('break')); | ||
breakStatement.set(union( | ||
'break', | ||
)); | ||
breakIfStatement.set(union(sequence('break', 'if', expression, ';'))); | ||
breakIfStatement.set(union( | ||
sequence('break', 'if', expression, ';'), | ||
)); | ||
continueStatement.set(union('continue')); | ||
continueStatement.set(union( | ||
'continue', | ||
)); | ||
continuingStatement.set( | ||
union(sequence('continuing', continuingCompoundStatement)) | ||
); | ||
continuingStatement.set(union( | ||
sequence('continuing', continuingCompoundStatement), | ||
)); | ||
continuingCompoundStatement.set( | ||
union( | ||
sequence( | ||
star(attribute), | ||
'{', | ||
star(statement), | ||
maybe(breakIfStatement), | ||
'}' | ||
) | ||
) | ||
); | ||
continuingCompoundStatement.set(union( | ||
sequence(star(attribute), '{', star(statement), maybe(breakIfStatement), '}'), | ||
)); | ||
returnStatement.set(union(sequence('return', maybe(expression)))); | ||
returnStatement.set(union( | ||
sequence('return', maybe(expression)), | ||
)); | ||
funcCallStatement.set(union(callPhrase)); | ||
funcCallStatement.set(union( | ||
callPhrase, | ||
)); | ||
constAssertStatement.set(union(sequence('const_assert', expression))); | ||
constAssertStatement.set(union( | ||
sequence('const_assert', expression), | ||
)); | ||
statement.set( | ||
union( | ||
';', | ||
sequence(returnStatement, ';'), | ||
ifStatement, | ||
switchStatement, | ||
loopStatement, | ||
forStatement, | ||
whileStatement, | ||
sequence(funcCallStatement, ';'), | ||
sequence(variableOrValueStatement, ';'), | ||
sequence(breakStatement, ';'), | ||
sequence(continueStatement, ';'), | ||
sequence('discard', ';'), | ||
sequence(variableUpdatingStatement, ';'), | ||
compoundStatement, | ||
sequence(constAssertStatement, ';') | ||
) | ||
); | ||
statement.set(union( | ||
';', | ||
sequence(returnStatement, ';'), | ||
ifStatement, | ||
switchStatement, | ||
loopStatement, | ||
forStatement, | ||
whileStatement, | ||
sequence(funcCallStatement, ';'), | ||
sequence(variableOrValueStatement, ';'), | ||
sequence(breakStatement, ';'), | ||
sequence(continueStatement, ';'), | ||
sequence('discard', ';'), | ||
sequence(variableUpdatingStatement, ';'), | ||
compoundStatement, | ||
sequence(constAssertStatement, ';'), | ||
)); | ||
variableUpdatingStatement.set( | ||
union(assignmentStatement, incrementStatement, decrementStatement) | ||
); | ||
variableUpdatingStatement.set(union( | ||
assignmentStatement, | ||
incrementStatement, | ||
decrementStatement, | ||
)); | ||
functionDecl.set( | ||
union(sequence(star(attribute), functionHeader, compoundStatement)) | ||
); | ||
functionDecl.set(union( | ||
sequence(star(attribute), functionHeader, compoundStatement), | ||
)); | ||
functionHeader.set( | ||
union( | ||
sequence( | ||
'fn', | ||
ident, | ||
'(', | ||
maybe(paramList), | ||
')', | ||
maybe(sequence('->', star(attribute), templateElaboratedIdent)) | ||
) | ||
) | ||
); | ||
functionHeader.set(union( | ||
sequence('fn', ident, '(', maybe(paramList), ')', maybe(sequence('->', star(attribute), templateElaboratedIdent))), | ||
)); | ||
paramList.set(union(sequence(param, star(sequence(',', param)), maybe(',')))); | ||
paramList.set(union( | ||
sequence(param, star(sequence(',', param)), maybe(',')), | ||
)); | ||
param.set(union(sequence(star(attribute), ident, ':', typeSpecifier))); | ||
param.set(union( | ||
sequence(star(attribute), ident, ':', typeSpecifier), | ||
)); | ||
enableDirective.set(union(sequence('enable', enableExtensionList, ';'))); | ||
enableDirective.set(union( | ||
sequence('enable', enableExtensionList, ';'), | ||
)); | ||
enableExtensionList.set( | ||
union( | ||
sequence( | ||
enableExtensionName, | ||
star(sequence(',', enableExtensionName)), | ||
maybe(',') | ||
) | ||
) | ||
); | ||
enableExtensionList.set(union( | ||
sequence(enableExtensionName, star(sequence(',', enableExtensionName)), maybe(',')), | ||
)); | ||
requiresDirective.set(union(sequence('requires', softwareExtensionList, ';'))); | ||
requiresDirective.set(union( | ||
sequence('requires', softwareExtensionList, ';'), | ||
)); | ||
softwareExtensionList.set( | ||
union( | ||
sequence( | ||
softwareExtensionName, | ||
star(sequence(',', softwareExtensionName)), | ||
maybe(',') | ||
) | ||
) | ||
); | ||
softwareExtensionList.set(union( | ||
sequence(softwareExtensionName, star(sequence(',', softwareExtensionName)), maybe(',')), | ||
)); | ||
enableExtensionName.set(union(identPatternToken)); | ||
enableExtensionName.set(union( | ||
identPatternToken, | ||
)); | ||
softwareExtensionName.set(union(identPatternToken)); | ||
softwareExtensionName.set(union( | ||
identPatternToken, | ||
)); | ||
identPatternToken.set( | ||
union(/([_\p{XID_Start}][\p{XID_Continue}]+)|([\p{XID_Start}])/u) | ||
); | ||
identPatternToken.set(union( | ||
/([_\p{XID_Start}][\p{XID_Continue}]+)|([\p{XID_Start}])/u, | ||
)); | ||
severityControlName.set(union(identPatternToken)); | ||
severityControlName.set(union( | ||
identPatternToken, | ||
)); | ||
swizzleName.set( | ||
union( | ||
/[rgba]/, | ||
/[rgba][rgba]/, | ||
/[rgba][rgba][rgba]/, | ||
/[rgba][rgba][rgba][rgba]/, | ||
/[xyzw]/, | ||
/[xyzw][xyzw]/, | ||
/[xyzw][xyzw][xyzw]/, | ||
/[xyzw][xyzw][xyzw][xyzw]/ | ||
) | ||
); | ||
swizzleName.set(union( | ||
/[rgba]/, | ||
/[rgba][rgba]/, | ||
/[rgba][rgba][rgba]/, | ||
/[rgba][rgba][rgba][rgba]/, | ||
/[xyzw]/, | ||
/[xyzw][xyzw]/, | ||
/[xyzw][xyzw][xyzw]/, | ||
/[xyzw][xyzw][xyzw][xyzw]/, | ||
)); | ||
@@ -757,21 +748,33 @@ // DECLARATIONS | ||
export const globalDirectiveExtended = symbol('global_directive_extended'); | ||
export const includeDirective = symbol('include_directive'); | ||
export const includePath = symbol('include_path'); | ||
export const importDirective = symbol('import_directive'); | ||
export const importPath = symbol('import_path'); | ||
export const translationUnitImport = symbol('translation_unit_import'); | ||
export const globalDirectiveImport = symbol('global_directive_import'); | ||
// IMPLEMENTATIONS | ||
translationUnitExtended.set( | ||
union(sequence(star(globalDirectiveExtended), star(globalDecl))) | ||
); | ||
translationUnitExtended.set(union( | ||
sequence(star(globalDirectiveExtended), star(globalDecl)), | ||
)); | ||
globalDirectiveExtended.set( | ||
union( | ||
diagnosticDirective, | ||
enableDirective, | ||
requiresDirective, | ||
includeDirective | ||
) | ||
); | ||
globalDirectiveExtended.set(union( | ||
diagnosticDirective, | ||
enableDirective, | ||
requiresDirective, | ||
importDirective, | ||
)); | ||
includeDirective.set(union(sequence('import', includePath, ';'))); | ||
importDirective.set(union( | ||
sequence('import', importPath, ';'), | ||
)); | ||
includePath.set(union(/"[^*"/>:|?]+"/)); | ||
importPath.set(union( | ||
/"[^*"<>:|?\\]+"/, | ||
)); | ||
translationUnitImport.set(union( | ||
sequence(star(globalDirectiveImport), star(globalDecl)), | ||
)); | ||
globalDirectiveImport.set(union( | ||
importDirective, | ||
)); |
@@ -27,2 +27,5 @@ /** Json representation of the token. */ | ||
/** The method of grouping */ | ||
grouping?: string; | ||
source?: string; | ||
@@ -36,14 +39,10 @@ | ||
hasSymbol(symbol: string) { | ||
return this.symbol && this.symbol.includes(symbol); | ||
} | ||
clone(): Token { | ||
const token = new Token(); | ||
token.text = this.text; | ||
token.symbol = this.symbol; | ||
token.source = this.source; | ||
token.destination = this.destination; | ||
token.children = this.children; // shallow | ||
token.maybe = this.maybe; | ||
if (this.text) token.text = this.text; | ||
if (this.symbol) token.symbol = this.symbol; | ||
if (this.source) token.source = this.source; | ||
if (this.destination) token.destination = this.destination; | ||
if (this.children) token.children = this.children; // shallow | ||
if (this.maybe) token.maybe = this.maybe; | ||
return token; | ||
@@ -92,13 +91,5 @@ } | ||
static group(children: Token[], symbol?: string): Token { | ||
// if (children.length === 1) { | ||
// const token = children[0]; | ||
// if (symbol !== undefined) { | ||
// Token.symbol(token, symbol); | ||
// } | ||
// return token; | ||
// } | ||
const token = new Token(); | ||
token.children = children; | ||
if (symbol !== undefined) { | ||
if (symbol) { | ||
token.symbol = symbol; | ||
@@ -117,3 +108,3 @@ } | ||
parent.children = [token]; | ||
parent.symbol = symbol; | ||
if (symbol) parent.symbol = symbol; | ||
return parent; | ||
@@ -120,0 +111,0 @@ } |
import {SymbolRule} from './rules'; | ||
import {Token} from './token'; | ||
type FlexSymbol = string | SymbolRule; | ||
type FlexSymbol = string | SymbolRule | Token; | ||
@@ -10,2 +10,7 @@ function symbolName(symbol: FlexSymbol): string { | ||
} | ||
if (symbol instanceof Token) { | ||
return symbol.symbol ?? ''; | ||
} | ||
return symbol.symbol; | ||
@@ -18,4 +23,15 @@ } | ||
export function symbolEquals(left: FlexSymbol, right: FlexSymbol): boolean { | ||
const leftName = symbolName(left); | ||
const rightName = symbolName(right); | ||
if (leftName === '' || rightName === '') { | ||
return false; | ||
} | ||
return leftName === rightName; | ||
} | ||
export function assertType(token: Token, symbol: FlexSymbol) { | ||
if (!token.hasSymbol(symbolName(symbol))) { | ||
if (token.symbol !== symbolName(symbol)) { | ||
throw new Error('Type'); | ||
@@ -41,3 +57,11 @@ } | ||
return token.children.filter(ofType(...symbols)); | ||
const predicate = ofType(...symbols); | ||
return token.children.flatMap((child) => { | ||
if (child.symbol) { | ||
return predicate(child) ? [child] : []; | ||
} else { | ||
return childrenOfType(child, symbols); | ||
} | ||
}); | ||
} | ||
@@ -44,0 +68,0 @@ |
@@ -1,5 +0,6 @@ | ||
import {join} from 'path'; | ||
import {join, resolve, basename, dirname} from 'path'; | ||
import {readFileSync} from 'fs'; | ||
import {Syntax, postprocess, preprocess} from '../src'; | ||
import {ImportResolver, compileWgslx} from '../src/wgslx'; | ||
@@ -21,6 +22,36 @@ function testFile(inPath: string, outPath: string) { | ||
const TEST_RESOLVER: ImportResolver = { | ||
resolveFilePath: (baseFilePath: string, importStatementPath: string) => { | ||
const baseDirectory = dirname(baseFilePath); | ||
return resolve(baseDirectory, importStatementPath); | ||
}, | ||
readSource: (filePath: string) => { | ||
const fullPath = resolve(__dirname, filePath); | ||
const input = readFileSync(fullPath, 'utf-8'); | ||
return input; | ||
}, | ||
}; | ||
function testWgslx(inPath: string, outPath: string) { | ||
const inFullPath = join(__dirname, inPath); | ||
const outFullPath = join(__dirname, outPath); | ||
const input = readFileSync(inFullPath, 'utf-8'); | ||
const output = readFileSync(outFullPath, 'utf-8'); | ||
const generated = compileWgslx(input, inFullPath, { | ||
mode: 'wgslx', | ||
importResolver: TEST_RESOLVER, | ||
}); | ||
expect(generated).toEqual(output); | ||
} | ||
describe('data', () => { | ||
test('placeholder', () => { | ||
test('basic', () => { | ||
testFile('data/basic.wgsl', 'data/basic-out.wgsl'); | ||
}); | ||
test('multifile', () => { | ||
testWgslx('data/multifile.wgslx', 'data/multifile-out.wgsl'); | ||
}); | ||
}); |
@@ -193,2 +193,77 @@ import {inspect} from 'util'; | ||
}); | ||
// test('bitwise', () => { | ||
// const context = Context.from('a ^ b & c', 'file'); | ||
// const cursor = Cursor(0); | ||
// const match = expression.match(cursor, context); | ||
// //expect(match?.cursor).toEqual(Cursor(3)); | ||
// expect(match?.token?.toString()).toEqual('a ^ b & c'); | ||
// expect(match?.token?.toObject()).toEqual( | ||
// node( | ||
// [ | ||
// 'expression', | ||
// 'relational_expression', | ||
// 'shift_expression', | ||
// 'additive_expression', | ||
// ], | ||
// node( | ||
// [ | ||
// 'additive_expression', | ||
// 'multiplicative_expression', | ||
// 'unary_expression', | ||
// 'singular_expression', | ||
// ], | ||
// node( | ||
// ['primary_expression', 'template_elaborated_ident', 'ident'], | ||
// leaf('ident_pattern_token', 'a', '0:0:file') | ||
// ), | ||
// { | ||
// symbol: 'component_or_swizzle_specifier', | ||
// children: [ | ||
// leaf('[', '0:1:file'), | ||
// node( | ||
// [ | ||
// 'expression', | ||
// 'relational_expression', | ||
// 'shift_expression', | ||
// 'additive_expression', | ||
// 'multiplicative_expression', | ||
// 'unary_expression', | ||
// 'singular_expression', | ||
// 'primary_expression', | ||
// 'literal', | ||
// 'int_literal', | ||
// ], | ||
// leaf('decimal_int_literal', '4', '0:2:file') | ||
// ), | ||
// leaf(']', '0:3:file'), | ||
// ], | ||
// } | ||
// ), | ||
// leaf('additive_operator', '+', '0:5:file'), | ||
// node( | ||
// [ | ||
// 'multiplicative_expression', | ||
// 'unary_expression', | ||
// 'singular_expression', | ||
// ], | ||
// node( | ||
// ['primary_expression', 'template_elaborated_ident', 'ident'], | ||
// leaf('ident_pattern_token', 'b', '0:7:file') | ||
// ), | ||
// { | ||
// symbol: 'component_or_swizzle_specifier', | ||
// children: [ | ||
// leaf('.', '0:8:file'), | ||
// { | ||
// symbol: 'member_ident', | ||
// children: [leaf('ident_pattern_token', 'xyz', '0:9:file')], | ||
// }, | ||
// ], | ||
// } | ||
// ) | ||
// ) | ||
// ); | ||
// }); | ||
}); | ||
@@ -195,0 +270,0 @@ |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
200398
61
4915