From e682867537a75b04cf47eae9961c74e18edc12d4 Mon Sep 17 00:00:00 2001 From: Andrew Ray Date: Mon, 8 Jul 2024 22:43:53 -0700 Subject: [PATCH] Updating readme --- README.md | 76 ++++++++++++++++++++++++++++++++++++++++----- package.json | 2 +- src/parser/scope.ts | 1 - 3 files changed, 70 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index ae51fd0..c9068cf 100644 --- a/README.md +++ b/README.md @@ -427,20 +427,82 @@ visitors. ### Utility Functions -Rename all the variables in a program: +#### Rename variables / identifiers in a program + +You can rename bindings (aka variables), functions, and types (aka structs) with `renameBindings`, `renameFunctions`, and `renameTypes` respectively. + +The signature for these methods generally looks like: + +```ts +const renameBindings = ( + // The scope to rename the bindings in. ast.scopes[0] is the global scope. + // Passing this ast.scopes[0] renames all global variables + bindings: ScopeIndex, + // The rename function. This is called once per scope entry with the original + // name in the scope, to generate the renamed variable. + mangle: (name: string) => string +// The renameX() functions do two things: +// 1. Each function *mutates* the AST to rename identifiers in place. +// 2. It *returns* an *immutable* new ScopeIndex where the scope referneces +// themselves are renamed. +// If you want your ast.scopes array to stay in sync with your AST, you need to +// re-assign it to the output of the functions! See examples below. +): ScopeIndex +``` ```typescript import { renameBindings, renameFunctions, renameTypes } from '@shaderfrog/glsl-parser/utils'; -// ... parse an ast... +// Suffix top level variables with _x, and update the scope +ast.scopes[0] = renameBindings(ast.scopes[0], (name) => `${name}_x`); -// Suffix top level variables with _x -// TODO UPDATE THIS -renameBindings(ast.scopes[0], (name, node) => `${name}_x`); // Suffix function names with _x -renameFunctions(ast.scopes[0], (name, node) => `${name}_x`); +ast.scopes[0] = renameFunctions(ast.scopes[0], (name) => `${name}_x`); + // Suffix struct names and usages (including constructors) with _x -renameTypes(ast.scopes[0], (name, node) => `${name}_x`); +ast.scopes[0] = renameTypes(ast.scopes[0], (name) => `${name}_x`); +``` + +There are also functions to rename only one variable/identifier in a given +scope. Use these if you know specifically which variable you want to rename. + +```typescript +import { renameBinding, renameFunction, renameType } from '@shaderfrog/glsl-parser/utils'; + +// Replace all instances of "oldVar" with "newVar" (in the global scope) +ast.scopes[0].bindings.newVar = renameBinding( + ast.scopes[0].bindings.oldVar, + 'newVar', +); +// You need to manually delete the old scope entry if you want the scope to stay +// in sync with your program AST +delete ast.scopes[0].bindings.oldVar; + +// Rename a specific function +ast.scopes[0].functions.newFn = renameFunction( + ast.scopes[0].functions.oldFn, + 'newFn', +); +delete ast.scopes[0].functions.oldFn; + +// Rename a specific type/struct +ast.scopes[0].functions.newType = renametype( + ast.scopes[0].functions.oldType, + 'newType', +); +delete ast.scopes[0].functions.oldType; +``` + +#### Debugging utility functions + +The parser also exports some debugging functions, useful for logging information +about the AST. + +```ts +import { debugScopes } from '@shaderfrog/glsl-parser/parser/utils'; + +// Print a condensed representation of the AST scopes to the console +debugScopes(ast); ``` ## What are "parsing" and "preprocessing"? diff --git a/package.json b/package.json index eb4665a..b891e8f 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "engines": { "node": ">=16" }, - "version": "5.0.0-beta.3", + "version": "5.0.0-beta.4", "type": "module", "description": "A GLSL ES 1.0 and 3.0 parser and preprocessor that can preserve whitespace and comments", "scripts": { diff --git a/src/parser/scope.ts b/src/parser/scope.ts index 15b0bd5..87b9b87 100644 --- a/src/parser/scope.ts +++ b/src/parser/scope.ts @@ -118,7 +118,6 @@ export const functionDeclarationSignature = ( const quantifiers = specifier.quantifier || []; const parameterTypes = proto?.parameters?.map(({ specifier, quantifier }) => { - // todo: saving place on putting quantifiers here const quantifiers = // vec4[1][2] param specifier.quantifier ||